8000 extmod/modussl_mbedtls: Implement SSLContext. · micropython/micropython@f0f5546 · GitHub
[go: up one dir, main page]

Skip to content

Commit f0f5546

Browse files
committed
extmod/modussl_mbedtls: Implement SSLContext.
This implements ssl.ctx_init() and SSLContext methods: - get_ciphers() - set_ciphers() - load_cadata() - load_certchain() - wrap_socket() ssl.MBEDTLS_VERSION Signed-off-by: Carlos Gil <carlosgilglez@gmail.com>
1 parent 963e599 commit f0f5546

File tree

9 files changed

+804
-1
lines changed

9 files changed

+804
-1
lines changed

extmod/modussl_mbedtls.c

Lines changed: 421 additions & 1 deletion
Large diffs are not rendered by default.

extmod/ssl/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .ssl import *

extmod/ssl/manifest.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
freeze(".", ("ssl.py",))

extmod/ssl/ssl.py

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
from ussl import *
2+
import ussl as _ussl
3+
4+
# constants
5+
PROTOCOL_TLS_CLIENT = const(0)
6+
PROTOCOL_TLS_SERVER = const(1)
7+
8+
9+
class SSLContext:
10+
def __init__(self, protocol):
11+
# protocol is PROTOCOL_TLS_CLIENT or PROTOCOL_TLS_SERVER
12+
self._protocol = protocol
13+
self._verify_mode = CERT_NONE
14+
self._check_hostname = False
15+
if protocol == PROTOCOL_TLS_CLIENT:
16+
self.verify_mode = CERT_REQUIRED
17+
self.check_hostname = True
18+
self.key = None
19+
self.cert = None
20+
self.cadata = None
21+
self.ctx = _ussl.ctx_init()
22+
# PRE-ALLOCATE CONTEXT(key,cert) and SSL socket BUFFERS e.g. from (ussl) ?
23+
# self.ssl_buffer_sock = _ussl.context_allocate_buffer()
24+
# initiate context so we can get/set ciphers? :
25+
# self._ctx = _ussl.context_init()
26+
#
27+
28+
@property
29+
def protocol(self):
30+
return self._protocol
31+
32+
@property
33+
def check_hostname(self):
34+
return self._check_hostname
35+
36+
@check_hostname.setter
37+
def check_hostname(self, value):
38+
assert type(value) == bool
39+
40+
if value is True and not self.verify_mode:
41+
self.verify_mode = CERT_REQUIRED
42+
43+
self._check_hostname = value
44+
45+
@property
46+
def verify_mode(self):
47+
return self._verify_mode
48+
49+
@verify_mode.setter
50+
def verify_mode(self, value):
51+
assert value in (CERT_NONE, CERT_OPTIONAL, CERT_REQUIRED)
52+
if not self.check_hostname:
53+
self._verify_mode = value
54+
55+
def reset(self, server=True):
56+
self.ctx = _ussl.ctx_init()
57+
if server:
58+
self.ctx.load_certchain(key=self.key, cert=self.cert)
59+
else:
60+
self.ctx.load_cadata(self.cadata)
61+
62+
def load_cert_chain(self, certfile, keyfile=None):
63+
# load certificate/key from a file, is possible to use memoryview to
64+
# save RAM?
65+
if isinstance(certfile, bytes):
66+
self.cert = certfile
67+
else:
68+
with open(certfile, "rb") as cert:
69+
self.cert = cert.read()
70+
if keyfile:
71+
if isinstance(keyfile, bytes):
72+
self.key = keyfile
73+
else:
74+
with open(keyfile, "rb") as key:
75+
self.key = key.read()
76+
77+
self.ctx.load_certchain(key=self.key, cert=self.cert)
78+
79+
def load_default_certs(self):
80+
pass # not sure how/if implement this
81+
82+
def load_verify_locations(self, cafile=None, capath=None, cadata=None):
83+
if cafile:
84+
with open(cafile, "rb") as ca_cert:
85+
self.cadata = ca_cert.read()
86+
if capath:
87+
pass ## not implemented, it needs to concatenate multiple files
88+
89+
if cadata:
90+
self.cadata = cadata
91+
92+
self.ctx.load_cadata(self.cadata)
93+
94+
def get_ciphers(self):
95+
return self.ctx.get_ciphers()
96+
97+
def set_ciphers(self, ciphersuite):
98+
return self.ctx.set_ciphers(ciphersuite)
99+
100+
def wrap_socket(
101+
self, sock, server_side=False, do_handshake_on_connect=True, server_hostname=None
102+
):
103+
104+
if self.check_hostname and server_hostname is None:
105+
raise ValueError("check_hostname requires server_hostname")
106+
# to be substituted by e.g. _ussl._context_wrap_socket in modussl_mbedtls.c ?:
107+
# _ussl._context_wrap_socket(*args, **kargs)
108+
return self.ctx.wrap_socket(
109+
sock,
110+
server_side=server_side,
111+
cert_reqs=self.verify_mode,
112+
server_hostname=server_hostname,
113+
do_handshake=do_handshake_on_connect,
114+
)

ports/unix/variants/manifest.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1+
freeze_as_mpy("$(MPY_DIR)/extmod/ssl", "ssl.py")
12
freeze_as_mpy("$(MPY_DIR)/tools", "upip.py")
23
freeze_as_mpy("$(MPY_DIR)/tools", "upip_utarfile.py", opt=3)

ports/unix/variants/standard/mpconfigvariant.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,5 @@
4242
#define MICROPY_PY_URE_SUB (0)
4343
#define MICROPY_PY_URANDOM_EXTRA_FUNCS (0)
4444
#define MICROPY_PY_FRAMEBUF (0)
45+
46+

tests/multi_net/ssl_context_rsa.py

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
# Simple test creating an SSL connection and transferring some data
2+
# This test won't run under CPython because CPython doesn't have key/cert
3+
4+
try:
5+
import ubinascii as binascii, usocket as socket
6+
import ssl
7+
except ImportError:
8+
print("SKIP")
9+
raise SystemExit
10+
11+
PORT = 8000
12+
13+
14+
# This self-signed key/cert pair is randomly generated and to be used for
15+
# testing/demonstration only. You should always generate your own key/cert.
16+
17+
# To generate a new self-signed key/cert pair with openssl do:
18+
# $ openssl req -x509 -newkey rsa:4096 -keyout rsa_key.pem -out rsa_cert.pem -days 365 -node
19+
#
20+
# Convert them to DER format:
21+
# $ openssl rsa -in rsa_key.pem -out rsa_key.der -outform DER
22+
# $ openssl x509 -in rsa_cert.pem -out rsa_key.der -outform DER
23+
#
24+
# Then convert to hex format, eg using binascii.hexlify(data).
25+
26+
cert = binascii.unhexlify(
27+
b"308205d7308203bfa003020102020900bc63b48a700c3d49300d06092a864886f70d01010b050030"
28+
b"8181310b3009060355040613024155310c300a06035504080c03466f6f310c300a06035504070c03"
29+
b"42617231143012060355040a0c0b4d6963726f507974686f6e310c300a060355040b0c03666f6f31"
30+
b"16301406035504030c0d657370686f6d652e6c6f63616c311a301806092a864886f70d010901160b"
31+
b"666f6f406261722e636f6d301e170d3232303731323138303031335a170d32333037313231383030"
32+
b"31335a308181310b3009060355040613024155310c300a06035504080c03466f6f310c300a060355"
33+
b"04070c0342617231143012060355040a0c0b4d6963726f507974686f6e310c300a060355040b0c03"
34+
b"666f6f3116301406035504030c0d657370686f6d652e6c6f63616c311a301806092a864886f70d01"
35+
b"0901160b666f6f406261722e636f6d30820222300d06092a864886f70d01010105000382020f0030"
36+
b"82020a0282020100ce3c0f730ab34432ce605ab44d4ac0aafd8a6243133eab0dcc9d444ab7d9ff66"
37+
b"a6815a101d2d3cbd72140afc34f8c3caedce16e9528350f3e0e56343f248507d82e41b51abb515cb"
38+
b"f60e5a619f2dbca8684d174c3b0951e2c7ba576c7fb06453a3597755810a6a4c45eb0925c855ab53"
39+
b"7785df46bf29145871330ff0641a101a24f0830c20bae865ba8bb32606caac4555812acf19f59553"
40+
b"349ce70fb7ff63512f0444f8f41b973183eabf9679903087c6cd69dc3adcbe754dd0207ea57c50e9"
41+
b"2d800bce6258d1618bb749d3fc01239b6d1af6d3f9cada3acbb312a1d85a59cfabd28b2e572c56a4"
42+
b"818ce170ca2b781a04749c6239206c64ad9e057484143a4c52bdef6189c46405c1a9642489cb640a"
43+
b"937adfc2687578dfa2b40ebafa05213642a1ccbc265557cd40de53324cff1bfba6f5c215f657b8f9"
44+
b"f2260ab6293625d0e203bba975bc7ac6dff3e604c9b0d2a2a4ba5941c0dc8d2e0e9439c56447b404"
45+
b"8c0e6cfb03517742ff6f7c2140a05954aa1e29247d1ae8bfd7db0db8dd45d095710fb78284ede285"
46+
b"0fc0c21235406af83e6044addf9385316403e2a25442b9ffbfc7b01c6c9292e5a3531e6a48496c01"
47+
b"6de1373334a52f01b7c6a0ece1261936788d2161c53a8985a0946d6d319225b230d96d055ea4692f"
48+
b"eb71fdaf4b775ac9fbc38e1b943e6617cf61d33e930ab288a3ea4730b4f2784a8018e0dfc8a11e73"
49+
b"0203010001a350304e301d0603551d0e04160414bc6048fe3cd278257e8b7c90dedbbce8369b20b8"
50+
b"301f0603551d23041830168014bc6048fe3cd278257e8b7c90dedbbce8369b20b8300c0603551d13"
51+
b"040530 F438 030101ff300d06092a864886f70d01010b0500038202010009238354b43379a3d2b56e928c"
52+
b"ac8ea28e2c01cf8148e54c0bbd4055e2e57d578697d1e2c392f1fe3bc9211d4f27ed1be631e7547a"
53+
b"6390d7f121a9e20a195fdda73f755188b16cf39714924a9686dd7cc749421335038c0640c2c6b15d"
54+
b"f44d74d94a97285ee2a7b075ccc9d9d632e2a5906030cf59bde14ab10660b7cf47ec9d7ae2f35963"
55+
b"454f76735a3dac12a4a4c907183e9ccf3e07d59484c182e67edc7c35ce15c7e1072fae8c9965a126"
56+
b"1a1f31147d4af8d1ebf8ee7c142badfe67e31fb324a79a29bc94e89370b70d8cf7cd2b2aa427a49f"
57+
b"77849891e7c4d5911f6fda52733a3c169b0188c2d9918f296dd8e234f8962f0db5e47c6159448045"
58+
b"4e2d9a5850d4c696a0fb3b66534a4591c49dda8cc6f1b0008c625aa5e0091ecfbd51d9715c60b85e"
59+
b"4e89d4a6cfabb2acdf81518eb61403b8f8767c5c00216f730e08f22959dff695a081cc726c4ab35a"
60+
b"e3f6538a231f831a6e91206f3b691a94bdf95343ec02ef7aac42da2a70846cd5f13dd2955a5f1737"
61+
b"a4c3c6c03b041d334c1dadd1e305f07c83b4b4e0509ec1d23e95f820290942eaaf8bea304cd5a505"
62+
b"8fc0d4624ff1ffe1348e7bc54c756a12acb258eb5e7426fb062a82b88ec274c9c13b3eff8b010947"
63+
b"62e166f490cd25b14e762db708785859a337d8fd0008fe602a90e2933cded3359e98ce3fbc041208"
64+
b"66bd4d96d6b6f7f53def854d40021196b7a06b"
65+
)
66+
67+
key = binascii.unhexlify(
68+
b"308209290201000282020100ce3c0f730ab34432ce605ab44d4ac0aafd8a6243133eab0dcc9d444a"
69+
b"b7d9ff66a6815a101d2d3cbd72140afc34f8c3caedce16e9528350f3e0e56343f248507d82e41b51"
70+
b"abb515cbf60e5a619f2dbca8684d174c3b0951e2c7ba576c7fb06453a3597755810a6a4c45eb0925"
71+
b"c855ab537785df46bf29145871330ff0641a101a24f0830c20bae865ba8bb32606caac4555812acf"
72+
b"19f59553349ce70fb7ff63512f0444f8f41b973183eabf9679903087c6cd69dc3adcbe754dd0207e"
73+
b"a57c50e92d800bce6258d1618bb749d3fc01239b6d1af6d3f9cada3acbb312a1d85a59cfabd28b2e"
74+
b"572c56a4818ce170ca2b781a04749c6239206c64ad9e057484143a4c52bdef6189c46405c1a96424"
75+
b"89cb640a937adfc2687578dfa2b40ebafa05213642a1ccbc265557cd40de53324cff1bfba6f5c215"
76+
b"f657b8f9f2260ab6293625d0e203bba975bc7ac6dff3e604c9b0d2a2a4ba5941c0dc8d2e0e9439c5"
77+
b"6447b4048c0e6cfb03517742ff6f7c2140a05954aa1e29247d1ae8bfd7db0db8dd45d095710fb782"
78+
b"84ede2850fc0c21235406af83e6044addf9385316403e2a25442b9ffbfc7b01c6c9292e5a3531e6a"
79+
b"48496c016de1373334a52f01b7c6a0ece1261936788d2161c53a8985a0946d6d319225b230d96d05"
80+
b"5ea4692feb71fdaf4b775ac9fbc38e1b943e6617cf61d33e930ab288a3ea4730b4f2784a8018e0df"
81+
b"c8a11e73020301000102820201008efa0e8fe81c2e2cb6ed10152dfca4242750581d3e6b54f56524"
82+
b"a6a2d2613cf2727efcec6cfddebd4c285f1148bc2a2936c28919cb0da502dea8c92fe2f9856bee61"
83+
b"ac1aebdac838b5e66f7c7c799df07716f30ef362dbb5485884a180c8ce5539cb1db35699dce5f217"
84+
b"27295d811f1ce7a115111c1823b5c90ce880f5352872a7a76282f6f1fd8a015136ab274c3d30783d"
85+
b"eb6ad7096e33d826eafdf7c70398d5eab4d28f91cd3913c69c7a7ade9ef692b9f8292959be64dec4"
86+
b"6ab2c291b41a6464004b5ddd4b93bfe41b37eedeef4ba2d16dcbb9c28b96f57fb96c20ed4a9471ff"
87+
b"ae643b254f100f8c9702b5f67af6369e8d887f285e5d520c5aa5d3a79e5de96432e6d2e3dea68e58"
88+
b"208c075fb119c6d3d4149b7e1247208d6b337c70272befc41d57f278618f1a82de337173346dc135"
89+
b"4d80a7c9075af99dbb2a14733c06b71600c6677a6bb28c0e4fc63db622228047a2cb7474dc8141c3"
90+
b"5f3a597c3e2bca9911d28eb9fd1a0c915e9f9c1cfd643d4fd8cac867f215380168ec37b8cfa28564"
91+
b"e6288ab04a7d67ca44b4c8375214a7ffaa1e6be92c4b138fcfd6beaba251b31a50a6e2ef241c9554"
92+
b"a1dc710b4acb63e749f5849e53d3f4915c6eb2a9a009bab04e932841ab34ae29eb000a08777d6399"
93+
b"169c2dc3d7952df5bc2d06e90a32139c6a2793d3817e4feadac2ccac554d383a8d41569140c29168"
94+
b"89220d3a5e410282010100fd603d18feef7aac61bda3b674a57ab38748bcde5c3efdba2279638f8e"
95+
b"a413cc26b9dda0375c116a8798a295b2c283aaaad7cca0dbd9bb3322a9a815f6d0aa5fc4f9aff8fb"
96+
b"da8ff914091ede7aefdb07a119c9b2e2b2bda776ac497060b8e88a82eb20c62f26f343566697726e"
97+
b"71aa46fd4efad6f42fc8a478856324d72cbf5eb3918317162d6fc2cfd775969a2077759fa2c8220d"
98+
b"acdc2ebb03ec39feed3f2b415449cbf40a7126bcf01d1068e3a45ec01181f2c68d7e05b4720bfe4a"
99+
b"308e1648123c91214a5f8dfce58727c4cd9396a8b403b733a717449b2f1970db97a3b8467271ffa6"
100+
b"e8c7cc9e2e1c0f789284ae9efe77eaac01131463c9c1329a1ba3530282010100d05ed6ab9b9fbdf7"
101+
b"a0f5f91f68dc3bac5789332d6ece46103fb1ef109fc972fdc99edf3107a23d66d1cdfe6bdddfd1bb"
102+
b"3952ccd10b5c20ad1b3e0aa6a51271ecf3a7ef2a65e029f5d77f238d1235b52a9dca3451c165d70a"
103+
b"99cbaea5c610e5455979696db769191e7cf2db21f641959e4ba1c5c0aae260c724962b6ac2621d92"
104+
b"e9df7adeb82b522d37b42cb454003bbe60d9915bf7737aeccf88c7ed1263a22f431a734e61fe7173"
105+
b"a937ddf76ad2a79994c05238defc15f6846858e9edf27ae2a567c7c5c735ea5d2fbef65a2195bc05"
106+
b"d82cbf06a477b29c84c92e8054c2bb25d8c6f19d43ef5fd1fce13c2cdbc361c39baec37b399200b3"
107+
b"2d4a6798ba0b546102820101008e41492c4e7daff7368d1d6c64034067a94dca5461a0301e201add"
108+
b"2e0d5ccb8cb435685bfa98e362572cf8236a10d191b187a568aee688b6c60050d1bc181d7fd57c86"
109+
b"33195bf5b7576b637c6fb358dae8b52ccc15815affb99e334137dcb91a833475db2f4004164b5d20"
110+
b"2c6c1bbf094a50dc7e70ec9f0ed067bb6944b1e7e3c897aaecfc53984add1c4ff5b525034cf3ca95"
111+
b"e8a09aeba804f1c7e02be391b2bc641166c3e654eef5e72dba37d98f406f3fa520e41f2ea10f5574"
112+
b"ac5984f75145378fefbfac1d07fff3f234fec698d55e746b1da18f6f7de24ec84ed7cb446d428820"
113+
b"bef33c00693e6a0ef114b5d66e9fefa8ee059238df1ac37c87e7841ae7028201000721a7d139c34e"
114+
b"da21cd295894db2cc3aa3f4cdc1a35bf1a2143f2bdabea56202f7d5b802f15b36a4875f76633b2cc"
115+
b"57cf0f71691a2d6e04deb0d1e68031d06a5eb079b406c6944910b60e3e6ec81dca369a4c0e1c4363"
116+
b"07bed9c4c171b4f453da4b187ba3d25a04bc1c07b9f2d6adcb3c256e4238d7049eec36a387c4dd5c"
117+
b"cbc16b5fa62dc175cf8c5f83442cb7d153a3b6ee8daa3b6e929a4bc123f1042df1d6271a992d2b6b"
118+
b"309d33074ac7822c304a72069e61ab590915e10862013dd24cdd825ec8fb17724cfc2c59fc1db825"
119+
b"3641fece0ee9241b9dd5c198f0d575d0b7ebe26b3489b5b09edc3bcd366fd3110e83ce886c383d31"
120+
b"feefe6e302cc2345210282010008f77a33d0081e9be3c1b1ac8b8e0eebb72df2eb69b95d2ed74935"
121+
b"b9dab8e17023cc38465354023c5183b51a6a20288fbb2181172be1c2fdb8b444419454e5b37f7f3b"
122+
b"df11e28cf4746b25534eb62f7e87bbbf28eda37024368b3897fbc661b40a93e04a183db9219c04a8"
123+
b"7643edf5d8b5dbfe3d424e91d558d5e3e2fa02ce1984ee69fb8518470eee2e7db0e1df5ac4571f78"
124+
b"a7a2529bc1fef5e32d46994869a8d8cc47869e174d84e7976be8ebb88f2ccb71a603a8bdb06af3eb"
125+
b"2ddbd62082f40d7987e47f2e321eb5eb2a28fefab263409f89dc97ebc723a1b751418cdd3ea684ba"
126+
b"8b17a330a306a6fbcf51ba83563aed85a4f886fff1a22423748d83798c"
127+
)
128+
129+
# Server
130+
def instance0():
131+
132+
multitest.globals(IP=multitest.get_network_ip())
133+
s = socket.socket()
134+
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
135+
s.bind(socket.getaddrinfo("0.0.0.0", PORT)[0][-1])
136+
s.listen(1)
137+
multitest.next()
138+
s2, _ = s.accept()
139+
server_ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
140+
server_ctx.load_cert_chain(cert, keyfile=key)
141+
s2 = server_ctx.wrap_socket(s2, server_side=True)
142+
print(s2.read(16))
143+
s2.write(b"server to client")
144+
s2.close()
145+
s.close()
146+
147+
148+
# Client
149+
def instance1():
150+
multitest.next()
151+
s = socket.socket()
152+
s.connect(socket.getaddrinfo(IP, PORT)[0][-1])
153+
client_ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
154+
client_ctx.load_verify_locations(cadata=cert)
155+
s = client_ctx.wrap_socket(s, server_hostname="esphome.local")
156+
s.write(b"client to server")
157+
print(s.read(16))
158+
s.close()
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
--- instance0 ---
2+
b'client to server'
3+
--- instance1 ---
4+
b'server to client'
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import socket
2+
import ssl
3+
4+
try:
5+
import ubinascii as binascii
6+
except:
7+
import binascii
8+
try:
9+
import usocket as socket
10+
except:
11+
import socket
12+
13+
# This certificate was obtained from micropython.org using openssl:
14+
# $ openssl s_client -showcerts -connect micropython.org:443 </dev/null 2>/dev/null
15+
# The certificate is from Let's Encrypt:
16+
# 1 s:/C=US/O=Let's Encrypt/CN=R3
17+
# i:/C=US/O=Internet Security Research Group/CN=ISRG Root X1
18+
# Validity
19+
# Not Before: Sep 4 00:00:00 2020 GMT
20+
# Not After : Sep 15 16:00:00 2025 GMT
21+
# Copy PEM content to a file (certmpy.pem) and convert to DER e.g.
22+
# $ openssl x509 -in certmpy.pem -out certmpy.der -outform DER
23+
# Then convert to hex format, eg using binascii.hexlify(data).
24+
25+
ca_cert_chain = binascii.unhexlify(
26+
b"30820516308202fea003020102021100912b084acf0c18a753f6d62e25a75f5a300d06092a864886"
27+
b"f70d01010b0500304f310b300906035504061302555331293027060355040a1320496e7465726e65"
28+
b"742053656375726974792052657365617263682047726f7570311530130603550403130c49535247"
29+
b"20526f6f74205831301e170d3230303930343030303030305a170d3235303931353136303030305a"
30+
b"3032310b300906035504061302555331163014060355040a130d4c6574277320456e637279707431"
31+
b"0b300906035504031302523330820122300d06092a864886f70d01010105000382010f003082010a"
32+
b"0282010100bb021528ccf6a094d30f12ec8d5592c3f882f199a67a4288a75d26aab52bb9c54cb1af"
33+
b"8e6bf975c8a3d70f4794145535578c9ea8a23919f5823c42a94e6ef53bc32edb8dc0b05cf35938e7"
34+
b"edcf69f05a0b1bbec094242587fa3771b313e71cace19befdbe43b45524596a9c153ce34c852eeb5"
35+
b"aeed8fde6070e2a554abb66d0e97a540346b2bd3bc66eb66347cfa6b8b8f572999f830175dba726f"
36+
b"fb81c5add286583d17c7e709bbf12bf786dcc1da715dd446e3ccad25c188bc60677566b3f118f7a2"
37+
b"5ce653ff3a88b647a5ff1318ea9809773f9d53f9cf01e5f5a6701714af63a4ff99b3939ddc53a706"
38+
b"fe48851da169ae2575bb13cc5203f5ed51a18bdb150203010001a382010830820104300e0603551d"
39+
b"0f0101ff040403020186301d0603551d250416301406082b0601050507030206082b060105050703"
40+
b"0130120603551d130101ff040830060101ff020100301d0603551d0e04160414142eb317b75856cb"
41+
b"ae500940e61faf9d8b14c2c6301f0603551d2304183016801479b459e67bb6e5e40173800888c81a"
42+
b"58f6e99b6e303206082b0601050507010104263024302206082b060105050730028616687474703a"
43+
b"2f2f78312e692e6c656e63722e6f72672f30270603551d1f0420301e301ca01aa018861668747470"
44+
b"3a2f2f78312e632e6c656e63722e6f72672f30220603551d20041b30193008060667810c01020130"
45+
b"0d060b2b0601040182df13010101300d06092a864886f70d01010b0500038202010085ca4e473ea3"
46+
b"f7854485bcd56778b29863ad754d1e963d336572542d81a0eac3edf820bf5fccb77000b76e3bf65e"
47+
b"94dee4209fa6ef8bb203e7a2b5163c91ceb4ed3902e77c258a47e6656e3f46f4d9f0ce942bee54ce"
48+
b"12bc8c274bb8c1982fa2afcd71914a08b7c8b8237b042d08f908573e83d904330a472178098227c3"
49+
b"2ac89bb9ce5cf264c8c0be79c04f8e6d440c5e92bb2ef78b10e1e81d4429db5920ed63b921f81226"
50+
b"949357a01d6504c10a22ae100d4397a1181f7ee0e08637b55ab1bd30bf876e2b2aff214e1b05c3f5"
51+
b"1897f05eacc3a5b86af02ebc3b33b9ee4bdeccfce4af840b863fc0554336f668e136176a8e99d1ff"
52+
b"a540a734b7c0d063393539756ef2ba76c89302e9a94b6c17ce0c02d9bd81fb9fb768d40665b3823d"
53+
b"7753f88e7903ad0a3107752a43d8559772c4290ef7c45d4ec8ae468430d7f2855f18a179bbe75e70"
54+
b"8b07e18693c3b98fdc6171252aafdfed255052688b92dce5d6b5e3da7dd0876c842131ae82f5fbb9"
55+
b"abc889173de14ce5380ef6bd2bbd968114ebd5db3d20a77e59d3e2f858f95bb848cdfe5c4f1629fe"
56+
b"1e5523afc811b08dea7c9390172ffdaca20947463ff0e9b0b7ff284d6832d6675e1e69a393b8f59d"
57+
b"8b2f0bd25243a66f3257654d3281df3853855d7e5d6629eab8dde495b5cdb5561242cdc44ec62538"
58+
b"44506decce005518fee94964d44eca979cb45bc073a8abb847c2"
59+
)
60+
61+
62+
def main(use_stream=True):
63+
64+
context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
65+
66+
# context.verify_mode = ssl.CERT_REQUIRED # enabled by default with
67+
# PROTOCOL_TLS_CLIENT
68+
69+
assert context.verify_mode == ssl.CERT_REQUIRED
70+
71+
# context.check_hostname = True # enabled by default with
72+
# PROTOCOL_TLS_CLIENT
73+
# print(context.get_ciphers())
74+
75+
# context.load_verify_locations(cafile='certmpy.der') # not sure how to
76+
# implement a external file
77+
# in a testd
78+
# context.ctx.set_ciphers('TLS-RSA-WITH-AES-256-CBC-SHA')
79+
context.load_verify_locations(cadata=ca_cert_chain)
80+
81+
context.load_default_certs() # not implemented in MicroPython just a mock, needed
82+
# in CPython to load issuer CA too,
83+
# otherwise verification fails.
84+
85+
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
86+
addr = socket.getaddrinfo("micropython.org", 443)[0][-1]
87+
88+
# CPython can wrap the socket even if not connected yet.
89+
# ssl_sock = context.wrap_socket(s, server_hostname='micropython.org')
90+
# ssl_sock.connect(addr)
91+
92+
# MicroPython needs to connect first, CPython can do this too.
93+
s.connect(addr)
94+
ssl_sock = context.wrap_socket(s, server_hostname="micropython.org")
95+
ssl_sock.write(b"GET / HTTP/1.0\r\n\r\n")
96+
print(ssl_sock.read(17))
97+
# print(ssl_sock.cipher())
98+
# print(ssl_sock.getpeercert(True))
99+
ssl_sock.close()
100+
101+
102+
main()

0 commit comments

Comments
 (0)
0