Skip to content

extmod/modussl_mbedtls.c: Add missing args and constants to ssl module. #8252

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion docs/library/ssl.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ facilities for network sockets, both client-side and server-side.
Functions
---------

.. function:: ssl.wrap_socket(sock, server_side=False, keyfile=None, certfile=None, cert_reqs=CERT_NONE, ca_certs=None, do_handshake=True)
.. function:: ssl.wrap_socket(sock, server_side=False, keyfile=None, certfile=None, cert_reqs=CERT_NONE, cadata=None, server_hostname=None, do_handshake=True)

Takes a `stream` *sock* (usually socket.socket instance of ``SOCK_STREAM`` type),
and returns an instance of ssl.SSLSocket, which wraps the underlying stream in
Expand All @@ -31,6 +31,16 @@ Functions
until it completes. Note that in AXTLS the handshake can be deferred until the first
read or write but it then blocks until completion.

- *cert_reqs* determines whether the peer (server or client) must present a valid certificate.
Note that for mbedtls based ports, ``ssl.CERT_NONE`` and ``ssl.CERT_OPTIONAL`` will not
validate any certificate, only ``ssl.CERT_REQUIRED`` will.

- *cadata* is the CA certificate chain (in *DER* format) that will validate the peer's certificate.

- *server_hostname* determines which hostname to connect to, allowing the server
to present the proper certificate (this is known as Server Name Indication (SNI))


Depending on the underlying module implementation in a particular
:term:`MicroPython port`, some or all keyword arguments above may be not supported.

Expand Down
26 changes: 25 additions & 1 deletion extmod/modussl_mbedtls.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ struct ssl_args {
mp_arg_val_t cert;
mp_arg_val_t server_side;
mp_arg_val_t server_hostname;
mp_arg_val_t cert_reqs;
mp_arg_val_t cadata;
mp_arg_val_t do_handshake;
};

Expand Down Expand Up @@ -191,7 +193,10 @@ STATIC mp_obj_ssl_socket_t *socket_new(mp_obj_t sock, struct ssl_args *args) {
goto cleanup;
}

mbedtls_ssl_conf_authmode(&o->conf, MBEDTLS_SSL_VERIFY_NONE);

mbedtls_ssl_conf_authmode(&o->conf, args->cert_reqs.u_int);


mbedtls_ssl_conf_rng(&o->conf, mbedtls_ctr_drbg_random, &o->ctr_drbg);
#ifdef MBEDTLS_DEBUG_C
mbedtls_ssl_conf_dbg(&o->conf, mbedtls_debug, NULL);
Expand Down Expand Up @@ -237,6 +242,20 @@ STATIC mp_obj_ssl_socket_t *socket_new(mp_obj_t sock, struct ssl_args *args) {
}
}

if (args->cadata.u_obj != mp_const_none) {
size_t cacert_len;
const byte *cacert = (const byte *)mp_obj_str_get_data(args->cadata.u_obj, &cacert_len);
// len should include terminating null
ret = mbedtls_x509_crt_parse(&o->cacert, cacert, cacert_len + 1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently only DER format is supported. And in such a case I think this function only parses the first DER in the buffer and will ignore anything after that.

To support a chain of DERs we would need to have a custom DER parser, or at least one that could tell the length of a DER so it could call mbedtls_x509_crt_parse_der() multiple times, once for each DER in the chain.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, I've just checked out mbedtls_x509_crt_parse() documentation:

Parse one DER-encoded or one or more concatenated PEM-encoded certificates and add them to the chained list.
....
The buffer holding the certificate data in PEM or DER format. For certificates in PEM encoding, this may be a concatenation of multiple certificates; for DER encoding, the buffer must comprise exactly one certificate.

And mbedtls_x509_crt_parse_der():

Parse a single DER formatted certificate and add it to the end of the provided chained list.

Which seems like a concatenated DER-encoded certificates file does not exist.

custom DER parser, or at least one that could tell the length of a DER so it could call mbedtls_x509_crt_parse_der() multiple times, once for each DER in the chain

I guess you could parse multiple files/buffers calling mbedtls_x509_crt_parse_der() multiple times, but from a single file I don't think is possible, you would need to add a header with the sizes or some delimiters like PEM.

Probably is better to support PEM-encoding or make it multiple files/list of buffers than a single "chain DER file".
In any case I think this fits better in SSLContext.load_verify_locations, right?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's solve this problem later on, as part of SSLContext. For now what is done in this PR is a good start, and a subset of what we could eventually support (either PEM or list/tuple/concat'd DER).

if (ret != 0) {
ret = MBEDTLS_ERR_X509_BAD_INPUT_DATA; // use general error for all cert errors
goto cleanup;
}

mbedtls_ssl_conf_ca_chain(&o->conf, &o->cacert, NULL);

}

if (args->do_handshake.u_bool) {
while ((ret = mbedtls_ssl_handshake(&o->ssl)) != 0) {
if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
Expand Down Expand Up @@ -395,6 +414,8 @@ STATIC mp_obj_t mod_ssl_wrap_socket(size_t n_args, const mp_obj_t *pos_args, mp_
{ MP_QSTR_cert, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} },
{ MP_QSTR_server_side, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
{ MP_QSTR_server_hostname, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} },
{ MP_QSTR_cert_reqs, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = MBEDTLS_SSL_VERIFY_NONE}},
{ MP_QSTR_cadata, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} },
{ MP_QSTR_do_handshake, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} },
};

Expand All @@ -412,6 +433,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_ssl_wrap_socket_obj, 1, mod_ssl_wrap_socke
STATIC const mp_rom_map_elem_t mp_module_ssl_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ussl) },
{ MP_ROM_QSTR(MP_QSTR_wrap_socket), MP_ROM_PTR(&mod_ssl_wrap_socket_obj) },
{ MP_ROM_QSTR(MP_QSTR_CERT_NONE), MP_ROM_INT(MBEDTLS_SSL_VERIFY_NONE) },
{ MP_ROM_QSTR(MP_QSTR_CERT_OPTIONAL), MP_ROM_INT(MBEDTLS_SSL_VERIFY_OPTIONAL) },
{ MP_ROM_QSTR(MP_QSTR_CERT_REQUIRED), MP_ROM_INT(MBEDTLS_SSL_VERIFY_REQUIRED) },
};

STATIC MP_DEFINE_CONST_DICT(mp_module_ssl_globals, mp_module_ssl_globals_table);
Expand Down
150 changes: 150 additions & 0 deletions tests/multi_net/ssl_cert_rsa.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
# Simple test creating an SSL connection and transferring some data
# This test won't run under CPython because it requires key/cert

try:
import ubinascii as binascii, usocket as socket, ussl as ssl
except ImportError:
print("SKIP")
raise SystemExit

PORT = 8000


# This self-signed key/cert pair is randomly generated and to be used for
# testing/demonstration only. You should always generate your own key/cert.

# To generate a new self-signed key/cert pair with openssl do:
# $ openssl req -x509 -newkey rsa:4096 -keyout rsa_key.pem -out rsa_cert.pem -days 365 -node

# Convert them to DER format:
# $ openssl rsa -in rsa_key.pem -out rsa_key.der -outform DER
# $ openssl x509 -in rsa_cert.pem -out rsa_key.der -outform DER

cert = binascii.unhexlify(
b"308205d7308203bfa003020102020900bc63b48a700c3d49300d06092a864886f70d01010b050030"
b"8181310b3009060355040613024155310c300a06035504080c03466f6f310c300a06035504070c03"
b"42617231143012060355040a0c0b4d6963726f507974686f6e310c300a060355040b0c03666f6f31"
b"16301406035504030c0d657370686f6d652e6c6f63616c311a301806092a864886f70d010901160b"
b"666f6f406261722e636f6d301e170d3232303731323138303031335a170d32333037313231383030"
b"31335a308181310b3009060355040613024155310c300a06035504080c03466f6f310c300a060355"
b"04070c0342617231143012060355040a0c0b4d6963726f507974686f6e310c300a060355040b0c03"
b"666f6f3116301406035504030c0d657370686f6d652e6c6f63616c311a301806092a864886f70d01"
b"0901160b666f6f406261722e636f6d30820222300d06092a864886f70d01010105000382020f0030"
b"82020a0282020100ce3c0f730ab34432ce605ab44d4ac0aafd8a6243133eab0dcc9d444ab7d9ff66"
b"a6815a101d2d3cbd72140afc34f8c3caedce16e9528350f3e0e56343f248507d82e41b51abb515cb"
b"f60e5a619f2dbca8684d174c3b0951e2c7ba576c7fb06453a3597755810a6a4c45eb0925c855ab53"
b"7785df46bf29145871330ff0641a101a24f0830c20bae865ba8bb32606caac4555812acf19f59553"
b"349ce70fb7ff63512f0444f8f41b973183eabf9679903087c6cd69dc3adcbe754dd0207ea57c50e9"
b"2d800bce6258d1618bb749d3fc01239b6d1af6d3f9cada3acbb312a1d85a59cfabd28b2e572c56a4"
b"818ce170ca2b781a04749c6239206c64ad9e057484143a4c52bdef6189c46405c1a9642489cb640a"
b"937adfc2687578dfa2b40ebafa05213642a1ccbc265557cd40de53324cff1bfba6f5c215f657b8f9"
b"f2260ab6293625d0e203bba975bc7ac6dff3e604c9b0d2a2a4ba5941c0dc8d2e0e9439c56447b404"
b"8c0e6cfb03517742ff6f7c2140a05954aa1e29247d1ae8bfd7db0db8dd45d095710fb78284ede285"
b"0fc0c21235406af83e6044addf9385316403e2a25442b9ffbfc7b01c6c9292e5a3531e6a48496c01"
b"6de1373334a52f01b7c6a0ece1261936788d2161c53a8985a0946d6d319225b230d96d055ea4692f"
b"eb71fdaf4b775ac9fbc38e1b943e6617cf61d33e930ab288a3ea4730b4f2784a8018e0dfc8a11e73"
b"0203010001a350304e301d0603551d0e04160414bc6048fe3cd278257e8b7c90dedbbce8369b20b8"
b"301f0603551d23041830168014bc6048fe3cd278257e8b7c90dedbbce8369b20b8300c0603551d13"
b"040530030101ff300d06092a864886f70d01010b0500038202010009238354b43379a3d2b56e928c"
b"ac8ea28e2c01cf8148e54c0bbd4055e2e57d578697d1e2c392f1fe3bc9211d4f27ed1be631e7547a"
b"6390d7f121a9e20a195fdda73f755188b16cf39714924a9686dd7cc749421335038c0640c2c6b15d"
b"f44d74d94a97285ee2a7b075ccc9d9d632e2a5906030cf59bde14ab10660b7cf47ec9d7ae2f35963"
b"454f76735a3dac12a4a4c907183e9ccf3e07d59484c182e67edc7c35ce15c7e1072fae8c9965a126"
b"1a1f31147d4af8d1ebf8ee7c142badfe67e31fb324a79a29bc94e89370b70d8cf7cd2b2aa427a49f"
b"77849891e7c4d5911f6fda52733a3c169b0188c2d9918f296dd8e234f8962f0db5e47c6159448045"
b"4e2d9a5850d4c696a0fb3b66534a4591c49dda8cc6f1b0008c625aa5e0091ecfbd51d9715c60b85e"
b"4e89d4a6cfabb2acdf81518eb61403b8f8767c5c00216f730e08f22959dff695a081cc726c4ab35a"
b"e3f6538a231f831a6e91206f3b691a94bdf95343ec02ef7aac42da2a70846cd5f13dd2955a5f1737"
b"a4c3c6c03b041d334c1dadd1e305f07c83b4b4e0509ec1d23e95f820290942eaaf8bea304cd5a505"
b"8fc0d4624ff1ffe1348e7bc54c756a12acb258eb5e7426fb062a82b88ec274c9c13b3eff8b010947"
b"62e166f490cd25b14e762db708785859a337d8fd0008fe602a90e2933cded3359e98ce3fbc041208"
b"66bd4d96d6b6f7f53def854d40021196b7a06b"
)

key = binascii.unhexlify(
b"308209290201000282020100ce3c0f730ab34432ce605ab44d4ac0aafd8a6243133eab0dcc9d444a"
b"b7d9ff66a6815a101d2d3cbd72140afc34f8c3caedce16e9528350f3e0e56343f248507d82e41b51"
b"abb515cbf60e5a619f2dbca8684d174c3b0951e2c7ba576c7fb06453a3597755810a6a4c45eb0925"
b"c855ab537785df46bf29145871330ff0641a101a24f0830c20bae865ba8bb32606caac4555812acf"
b"19f59553349ce70fb7ff63512f0444f8f41b973183eabf9679903087c6cd69dc3adcbe754dd0207e"
b"a57c50e92d800bce6258d1618bb749d3fc01239b6d1af6d3f9cada3acbb312a1d85a59cfabd28b2e"
b"572c56a4818ce170ca2b781a04749c6239206c64ad9e057484143a4c52bdef6189c46405c1a96424"
b"89cb640a937adfc2687578dfa2b40ebafa05213642a1ccbc265557cd40de53324cff1bfba6f5c215"
b"f657b8f9f2260ab6293625d0e203bba975bc7ac6dff3e604c9b0d2a2a4ba5941c0dc8d2e0e9439c5"
b"6447b4048c0e6cfb03517742ff6f7c2140a05954aa1e29247d1ae8bfd7db0db8dd45d095710fb782"
b"84ede2850fc0c21235406af83e6044addf9385316403e2a25442b9ffbfc7b01c6c9292e5a3531e6a"
b"48496c016de1373334a52f01b7c6a0ece1261936788d2161c53a8985a0946d6d319225b230d96d05"
b"5ea4692feb71fdaf4b775ac9fbc38e1b943e6617cf61d33e930ab288a3ea4730b4f2784a8018e0df"
b"c8a11e73020301000102820201008efa0e8fe81c2e2cb6ed10152dfca4242750581d3e6b54f56524"
b"a6a2d2613cf2727efcec6cfddebd4c285f1148bc2a2936c28919cb0da502dea8c92fe2f9856bee61"
b"ac1aebdac838b5e66f7c7c799df07716f30ef362dbb5485884a180c8ce5539cb1db35699dce5f217"
b"27295d811f1ce7a115111c1823b5c90ce880f5352872a7a76282f6f1fd8a015136ab274c3d30783d"
b"eb6ad7096e33d826eafdf7c70398d5eab4d28f91cd3913c69c7a7ade9ef692b9f8292959be64dec4"
b"6ab2c291b41a6464004b5ddd4b93bfe41b37eedeef4ba2d16dcbb9c28b96f57fb96c20ed4a9471ff"
b"ae643b254f100f8c9702b5f67af6369e8d887f285e5d520c5aa5d3a79e5de96432e6d2e3dea68e58"
b"208c075fb119c6d3d4149b7e1247208d6b337c70272befc41d57f278618f1a82de337173346dc135"
b"4d80a7c9075af99dbb2a14733c06b71600c6677a6bb28c0e4fc63db622228047a2cb7474dc8141c3"
b"5f3a597c3e2bca9911d28eb9fd1a0c915e9f9c1cfd643d4fd8cac867f215380168ec37b8cfa28564"
b"e6288ab04a7d67ca44b4c8375214a7ffaa1e6be92c4b138fcfd6beaba251b31a50a6e2ef241c9554"
b"a1dc710b4acb63e749f5849e53d3f4915c6eb2a9a009bab04e932841ab34ae29eb000a08777d6399"
b"169c2dc3d7952df5bc2d06e90a32139c6a2793d3817e4feadac2ccac554d383a8d41569140c29168"
b"89220d3a5e410282010100fd603d18feef7aac61bda3b674a57ab38748bcde5c3efdba2279638f8e"
b"a413cc26b9dda0375c116a8798a295b2c283aaaad7cca0dbd9bb3322a9a815f6d0aa5fc4f9aff8fb"
b"da8ff914091ede7aefdb07a119c9b2e2b2bda776ac497060b8e88a82eb20c62f26f343566697726e"
b"71aa46fd4efad6f42fc8a478856324d72cbf5eb3918317162d6fc2cfd775969a2077759fa2c8220d"
b"acdc2ebb03ec39feed3f2b415449cbf40a7126bcf01d1068e3a45ec01181f2c68d7e05b4720bfe4a"
b"308e1648123c91214a5f8dfce58727c4cd9396a8b403b733a717449b2f1970db97a3b8467271ffa6"
b"e8c7cc9e2e1c0f789284ae9efe77eaac01131463c9c1329a1ba3530282010100d05ed6ab9b9fbdf7"
b"a0f5f91f68dc3bac5789332d6ece46103fb1ef109fc972fdc99edf3107a23d66d1cdfe6bdddfd1bb"
b"3952ccd10b5c20ad1b3e0aa6a51271ecf3a7ef2a65e029f5d77f238d1235b52a9dca3451c165d70a"
b"99cbaea5c610e5455979696db769191e7cf2db21f641959e4ba1c5c0aae260c724962b6ac2621d92"
b"e9df7adeb82b522d37b42cb454003bbe60d9915bf7737aeccf88c7ed1263a22f431a734e61fe7173"
b"a937ddf76ad2a79994c05238defc15f6846858e9edf27ae2a567c7c5c735ea5d2fbef65a2195bc05"
b"d82cbf06a477b29c84c92e8054c2bb25d8c6f19d43ef5fd1fce13c2cdbc361c39baec37b399200b3"
b"2d4a6798ba0b546102820101008e41492c4e7daff7368d1d6c64034067a94dca5461a0301e201add"
b"2e0d5ccb8cb435685bfa98e362572cf8236a10d191b187a568aee688b6c60050d1bc181d7fd57c86"
b"33195bf5b7576b637c6fb358dae8b52ccc15815affb99e334137dcb91a833475db2f4004164b5d20"
b"2c6c1bbf094a50dc7e70ec9f0ed067bb6944b1e7e3c897aaecfc53984add1c4ff5b525034cf3ca95"
b"e8a09aeba804f1c7e02be391b2bc641166c3e654eef5e72dba37d98f406f3fa520e41f2ea10f5574"
b"ac5984f75145378fefbfac1d07fff3f234fec698d55e746b1da18f6f7de24ec84ed7cb446d428820"
b"bef33c00693e6a0ef114b5d66e9fefa8ee059238df1ac37c87e7841ae7028201000721a7d139c34e"
b"da21cd295894db2cc3aa3f4cdc1a35bf1a2143f2bdabea56202f7d5b802f15b36a4875f76633b2cc"
b"57cf0f71691a2d6e04deb0d1e68031d06a5eb079b406c6944910b60e3e6ec81dca369a4c0e1c4363"
b"07bed9c4c171b4f453da4b187ba3d25a04bc1c07b9f2d6adcb3c256e4238d7049eec36a387c4dd5c"
b"cbc16b5fa62dc175cf8c5f83442cb7d153a3b6ee8daa3b6e929a4bc123f1042df1d6271a992d2b6b"
b"309d33074ac7822c304a72069e61ab590915e10862013dd24cdd825ec8fb17724cfc2c59fc1db825"
b"3641fece0ee9241b9dd5c198f0d575d0b7ebe26b3489b5b09edc3bcd366fd3110e83ce886c383d31"
b"feefe6e302cc2345210282010008f77a33d0081e9be3c1b1ac8b8e0eebb72df2eb69b95d2ed74935"
b"b9dab8e17023cc38465354023c5183b51a6a20288fbb2181172be1c2fdb8b444419454e5b37f7f3b"
b"df11e28cf4746b25534eb62f7e87bbbf28eda37024368b3897fbc661b40a93e04a183db9219c04a8"
b"7643edf5d8b5dbfe3d424e91d558d5e3e2fa02ce1984ee69fb8518470eee2e7db0e1df5ac4571f78"
b"a7a2529bc1fef5e32d46994869a8d8cc47869e174d84e7976be8ebb88f2ccb71a603a8bdb06af3eb"
b"2ddbd62082f40d7987e47f2e321eb5eb2a28fefab263409f89dc97ebc723a1b751418cdd3ea684ba"
b"8b17a330a306a6fbcf51ba83563aed85a4f886fff1a22423748d83798c"
)

# Server
def instance0():
multitest.globals(IP=multitest.get_network_ip())
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(socket.getaddrinfo("0.0.0.0", PORT)[0][-1])
s.listen(1)
multitest.next()
s2, _ = s.accept()
s2 = ssl.wrap_socket(s2, server_side=True, key=key, cert=cert)
print(s2.read(16))
s2.write(b"server to client")
s2.close()
s.close()


# Client
def instance1():
multitest.next()
s = socket.socket()
s.connect(socket.getaddrinfo(IP, PORT)[0][-1])
s = ssl.wrap_socket(s, cert_reqs=ssl.CERT_REQUIRED, cadata=cert)
s.write(b"client to server")
print(s.read(16))
s.close()
4 changes: 4 additions & 0 deletions tests/multi_net/ssl_cert_rsa.py.exp
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
--- instance0 ---
b'client to server'
--- instance1 ---
b'server to client'
74 changes: 74 additions & 0 deletions tests/net_inet/ssl_cert.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
try:
import usocket as _socket
except:
import _socket
try:
import ussl as ssl
import ubinascii as binascii
except:
import ssl
import binascii


# This certificate was obtained from micropython.org using openssl:
# $ openssl s_client -showcerts -connect micropython.org:443 </dev/null 2>/dev/null
# The certificate is from Let's Encrypt:
# 1 s:/C=US/O=Let's Encrypt/CN=R3
# i:/C=US/O=Internet Security Research Group/CN=ISRG Root X1
# Validity
# Not Before: Sep 4 00:00:00 2020 GMT
# Not After : Sep 15 16:00:00 2025 GMT
# Copy PEM content to a file (certmpy.pem) and convert to DER e.g.
# $ openssl x509 -in certmpy.pem -out certmpy.der -outform DER

ca_cert_chain = binascii.unhexlify(
b"30820516308202fea003020102021100912b084acf0c18a753f6d62e25a75f5a300d06092a864886"
b"f70d01010b0500304f310b300906035504061302555331293027060355040a1320496e7465726e65"
b"742053656375726974792052657365617263682047726f7570311530130603550403130c49535247"
b"20526f6f74205831301e170d3230303930343030303030305a170d3235303931353136303030305a"
b"3032310b300906035504061302555331163014060355040a130d4c6574277320456e637279707431"
b"0b300906035504031302523330820122300d06092a864886f70d01010105000382010f003082010a"
b"0282010100bb021528ccf6a094d30f12ec8d5592c3f882f199a67a4288a75d26aab52bb9c54cb1af"
b"8e6bf975c8a3d70f4794145535578c9ea8a23919f5823c42a94e6ef53bc32edb8dc0b05cf35938e7"
b"edcf69f05a0b1bbec094242587fa3771b313e71cace19befdbe43b45524596a9c153ce34c852eeb5"
b"aeed8fde6070e2a554abb66d0e97a540346b2bd3bc66eb66347cfa6b8b8f572999f830175dba726f"
b"fb81c5add286583d17c7e709bbf12bf786dcc1da715dd446e3ccad25c188bc60677566b3f118f7a2"
b"5ce653ff3a88b647a5ff1318ea9809773f9d53f9cf01e5f5a6701714af63a4ff99b3939ddc53a706"
b"fe48851da169ae2575bb13cc5203f5ed51a18bdb150203010001a382010830820104300e0603551d"
b"0f0101ff040403020186301d0603551d250416301406082b0601050507030206082b060105050703"
b"0130120603551d130101ff040830060101ff020100301d0603551d0e04160414142eb317b75856cb"
b"ae500940e61faf9d8b14c2c6301f0603551d2304183016801479b459e67bb6e5e40173800888c81a"
b"58f6e99b6e303206082b0601050507010104263024302206082b060105050730028616687474703a"
b"2f2f78312e692e6c656e63722e6f72672f30270603551d1f0420301e301ca01aa018861668747470"
b"3a2f2f78312e632e6c656e63722e6f72672f30220603551d20041b30193008060667810c01020130"
b"0d060b2b0601040182df13010101300d06092a864886f70d01010b0500038202010085ca4e473ea3"
b"f7854485bcd56778b29863ad754d1e963d336572542d81a0eac3edf820bf5fccb77000b76e3bf65e"
b"94dee4209fa6ef8bb203e7a2b5163c91ceb4ed3902e77c258a47e6656e3f46f4d9f0ce942bee54ce"
b"12bc8c274bb8c1982fa2afcd71914a08b7c8b8237b042d08f908573e83d904330a472178098227c3"
b"2ac89bb9ce5cf264c8c0be79c04f8e6d440c5e92bb2ef78b10e1e81d4429db5920ed63b921f81226"
b"949357a01d6504c10a22ae100d4397a1181f7ee0e08637b55ab1bd30bf876e2b2aff214e1b05c3f5"
b"1897f05eacc3a5b86af02ebc3b33b9ee4bdeccfce4af840b863fc0554336f668e136176a8e99d1ff"
b"a540a734b7c0d063393539756ef2ba76c89302e9a94b6c17ce0c02d9bd81fb9fb768d40665b3823d"
b"7753f88e7903ad0a3107752a43d8559772c4290ef7c45d4ec8ae468430d7f2855f18a179bbe75e70"
b"8b07e18693c3b98fdc6171252aafdfed255052688b92dce5d6b5e3da7dd0876c842131ae82f5fbb9"
b"abc889173de14ce5380ef6bd2bbd968114ebd5db3d20a77e59d3e2f858f95bb848cdfe5c4f1629fe"
b"1e5523afc811b08dea7c9390172ffdaca20947463ff0e9b0b7ff284d6832d6675e1e69a393b8f59d"
b"8b2f0bd25243a66f3257654d3281df3853855d7e5d6629eab8dde495b5cdb5561242cdc44ec62538"
b"44506decce005518fee94964d44eca979cb45bc073a8abb847c2"
)


def main(use_stream=True):
s = _socket.socket()
ai = _socket.getaddrinfo("micropython.org", 443)
addr = ai[0][-1]
s.connect(addr)
s = ssl.wrap_socket(
s, cert_reqs=ssl.CERT_REQUIRED, cadata=ca_cert_chain, server_hostname="micropython.org"
)
s.write(b"GET / HTTP/1.0\r\n\r\n")
print(s.read(17))
s.close()


main()
1 change: 1 addition & 0 deletions tests/net_inet/ssl_cert.py.exp
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
b'HTTP/1.1 200 OK\r\n'