fix: enable DTLS peer verification against Samsung OCF Root CA
Bundle certs/ocf_root_ca.pem as samsung_appliance/ocf_root_ca.pem and switch from SSL.VERIFY_NONE to SSL.VERIFY_PEER. The appliance's server certificate must now chain to the Samsung Electronics OCF Root CA, closing the ARP-spoof / MITM attack surface on the local network. .gitignore: carve out explicit exception for the bundled public CA cert.
This commit is contained in:
@@ -9,6 +9,9 @@ certs/
|
||||
*.p12
|
||||
*.pfx
|
||||
*.key
|
||||
|
||||
# Exception: bundled Samsung OCF Root CA (public cert, no key material)
|
||||
!samsung_appliance/ocf_root_ca.pem
|
||||
token.txt
|
||||
|
||||
# Python artifacts
|
||||
|
||||
+5
-13
@@ -5,20 +5,12 @@ not malicious code — the repo is safe to run. Fix before exposing to untrusted
|
||||
|
||||
---
|
||||
|
||||
## 1. DTLS Certificate Verification Disabled
|
||||
## 1. DTLS Certificate Verification Disabled ✅ RESOLVED
|
||||
|
||||
**File:** `samsung_appliance/coap_dtls.py:228`
|
||||
**Severity:** High | **Category:** Authentication Bypass / Crypto
|
||||
|
||||
The DTLS context uses `SSL.VERIFY_NONE` with a lambda that accepts any certificate.
|
||||
The bridge does not verify the appliance's identity.
|
||||
|
||||
**Exploit:** LAN attacker ARP-spoofs the appliance IP, presents a self-signed cert,
|
||||
and either poisons state payloads (e.g. fake oven temp) or intercepts/drops commands.
|
||||
|
||||
**Fix:** Use `SSL.VERIFY_PEER` + `ctx.load_verify_locations()` pointing to the Samsung
|
||||
CA cert already on disk. The `@SECLEVEL=0` SHA-1 workaround can coexist with peer
|
||||
verification — `VERIFY_NONE` is not required for it.
|
||||
`certs/ocf_root_ca.pem` (Samsung Electronics OCF Root CA) bundled at
|
||||
`samsung_appliance/ocf_root_ca.pem`. `coap_dtls.py` now uses
|
||||
`SSL.VERIFY_PEER` + `ctx.load_verify_locations(_OCF_ROOT_CA)`.
|
||||
ARP-spoof mitigation: the appliance's cert must chain to the Samsung OCF Root CA.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -23,9 +23,12 @@ import socket
|
||||
import struct
|
||||
import threading
|
||||
import time
|
||||
from pathlib import Path
|
||||
|
||||
from OpenSSL import SSL
|
||||
|
||||
_OCF_ROOT_CA = str(Path(__file__).parent / 'ocf_root_ca.pem')
|
||||
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -226,7 +229,8 @@ class DtlsCoapSession:
|
||||
"""DTLS handshake. Blocks up to HANDSHAKE_TIMEOUT_S. Raises
|
||||
ConnectionError / TimeoutError on failure."""
|
||||
ctx = SSL.Context(SSL.DTLS_METHOD)
|
||||
ctx.set_verify(SSL.VERIFY_NONE, lambda *_: True)
|
||||
ctx.load_verify_locations(_OCF_ROOT_CA)
|
||||
ctx.set_verify(SSL.VERIFY_PEER, lambda conn, cert, err, depth, ok: ok)
|
||||
ctx.set_cipher_list(b'ECDHE-ECDSA-AES128-GCM-SHA256')
|
||||
ctx.use_certificate_chain_file(self.cert_path)
|
||||
ctx.use_privatekey_file(self.key_path)
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICXTCCAgGgAwIBAgIBATAMBggqhkjOPQQDAgUAMGsxKDAmBgNVBAMTH1NhbXN1
|
||||
bmcgRWxlY3Ryb25pY3MgT0NGIFJvb3QgQ0ExFDASBgNVBAsTC09DRiBSb290IENB
|
||||
MRwwGgYDVQQKExNTYW1zdW5nIEVsZWN0cm9uaWNzMQswCQYDVQQGEwJLUjAgFw0x
|
||||
NjExMjQwMjU1MTFaGA8yMDY5MTIzMTE0NTk1OVowazEoMCYGA1UEAxMfU2Ftc3Vu
|
||||
ZyBFbGVjdHJvbmljcyBPQ0YgUm9vdCBDQTEUMBIGA1UECxMLT0NGIFJvb3QgQ0Ex
|
||||
HDAaBgNVBAoTE1NhbXN1bmcgRWxlY3Ryb25pY3MxCzAJBgNVBAYTAktSMFkwEwYH
|
||||
KoZIzj0CAQYIKoZIzj0DAQcDQgAEYsf/Kx+sUFBQESbuytTDPwLPIe0X/8/B1L7b
|
||||
3abxE9w0gQZAfI8WYUkKfNfP7HXh1M5SCnOkfwWraltGOKTeX6OBkTCBjjAOBgNV
|
||||
HQ8BAf8EBAMCAcYwMgYDVR0fBCswKTAnoCWgI4YhaHR0cDovL3Byb2RjYS5zYW1z
|
||||
dW5naW90cy5jb20vY3JsMA8GA1UdEwEB/wQFMAMBAf8wNwYIKwYBBQUHAQEEKzAp
|
||||
MCcGCCsGAQUFBzABhhtodHRwOi8vb2NzcC5zYW1zdW5naW90cy5jb20wDAYIKoZI
|
||||
zj0EAwIFAANIADBFAiARY9aSE30q31q5v8B4sJczBqOp7AsD9o8ZIuNmH7IwSwIh
|
||||
ALfR56jcXoFis/nDx0tQ2xTI/f0b7F6tWPqj2vyKQeNR
|
||||
-----END CERTIFICATE-----
|
||||
Reference in New Issue
Block a user