46
46
#include "mbedtls/ctr_drbg.h"
47
47
#include "mbedtls/debug.h"
48
48
#include "mbedtls/error.h"
49
+ #ifdef MICROPY_SSL_MBEDTLS_EXTRAS
50
+ #if MBEDTLS_VERSION_NUMBER >= 0x03000000
51
+ #include "mbedtls/build_info.h"
52
+ #else
53
+ #include "mbedtls/version.h"
54
+ #endif
55
+ #endif
49
56
50
57
#define MP_STREAM_POLL_RDWR (MP_STREAM_POLL_RD | MP_STREAM_POLL_WR)
51
58
@@ -59,6 +66,9 @@ typedef struct _mp_obj_ssl_context_t {
59
66
mbedtls_x509_crt cert ;
60
67
mbedtls_pk_context pkey ;
61
68
int authmode ;
69
+ #ifdef MICROPY_SSL_MBEDTLS_EXTRAS
70
+ int cipherid [];
71
+ #endif
62
72
} mp_obj_ssl_context_t ;
63
73
64
74
// This corresponds to an SSLSocket object.
@@ -74,6 +84,9 @@ typedef struct _mp_obj_ssl_socket_t {
74
84
75
85
STATIC const mp_obj_type_t ssl_context_type ;
76
86
STATIC const mp_obj_type_t ssl_socket_type ;
87
+ #ifdef MICROPY_SSL_MBEDTLS_EXTRAS
88
+ STATIC const MP_DEFINE_STR_OBJ (mbedtls_version_obj , MBEDTLS_VERSION_STRING_FULL );
89
+ #endif
77
90
78
91
STATIC mp_obj_t ssl_socket_make_new (mp_obj_ssl_context_t * ssl_context , mp_obj_t sock ,
79
92
bool server_side , bool do_handshake_on_connect , mp_obj_t server_hostname );
@@ -154,6 +167,9 @@ STATIC mp_obj_t ssl_context_make_new(const mp_obj_type_t *type_in, size_t n_args
154
167
mp_obj_ssl_context_t * self = m_new_obj (mp_obj_ssl_context_t );
155
168
#endif
156
169
self -> base .type = type_in ;
170
+ #ifdef MICROPY_SSL_MBEDTLS_EXTRAS
171
+ self -> cipherid [0 ] = 0 ;
172
+ #endif
157
173
158
174
// Initialise mbedTLS state.
159
175
mbedtls_ssl_config_init (& self -> conf );
@@ -230,6 +246,57 @@ STATIC mp_obj_t ssl_context___del__(mp_obj_t self_in) {
230
246
STATIC MP_DEFINE_CONST_FUN_OBJ_1 (ssl_context___del___obj , ssl_context___del__ );
231
247
#endif
232
248
249
+ #ifdef MICROPY_SSL_MBEDTLS_EXTRAS
250
+ // Ciphersuites
251
+
252
+ STATIC mp_obj_t mod_ssl_get_ciphers (mp_obj_t self_in ) {
253
+ mp_obj_t list = mp_obj_new_list (0 , NULL );
254
+ const int * cipher_list = mbedtls_ssl_list_ciphersuites ();
255
+ while (* cipher_list ) {
256
+ const char * cipher_name = mbedtls_ssl_get_ciphersuite_name (* cipher_list );
257
+ mp_obj_list_append (list ,
258
+ MP_OBJ_FROM_PTR (mp_obj_new_str (cipher_name ,
259
+ strlen (cipher_name ))));
260
+ cipher_list ++ ;
261
+ if (!* cipher_list ) {
262
+ break ;
263
+ }
264
+ }
265
+ return list ;
266
+ }
267
+
268
+ STATIC MP_DEFINE_CONST_FUN_OBJ_1 (mod_ssl_get_ciphers_obj , mod_ssl_get_ciphers );
269
+
270
+
271
+ STATIC mp_obj_t mod_ssl_set_ciphers (mp_obj_t self_in , mp_obj_t ciphersuite ) {
272
+ // check that ciphersuite is a list
273
+ if (mp_obj_is_type (ciphersuite , & mp_type_list )) {
274
+ mp_obj_ssl_context_t * self = MP_OBJ_TO_PTR (self_in );
275
+ mp_obj_list_t * ciphers = MP_OBJ_TO_PTR (ciphersuite );
276
+
277
+ for (int i = 0 , n = ciphers -> len ; i < n ; i ++ ) {
278
+
279
+ if (ciphers -> items [i ] != mp_const_none ) {
280
+ const char * ciphername = mp_obj_str_get_str (ciphers -> items [i ]);
281
+ const int id = mbedtls_ssl_get_ciphersuite_id (ciphername );
282
+ self -> cipherid [i ] = id ;
283
+ if (id == 0 ) {
284
+ mbedtls_raise_error (MBEDTLS_ERR_SSL_BAD_CONFIG );
285
+ }
286
+ }
287
+ }
288
+ self -> cipherid [ciphers -> len + 1 ] = 0 ;
289
+ } else {
290
+ mbedtls_raise_error (MBEDTLS_ERR_SSL_BAD_CONFIG );
291
+ }
292
+ return mp_const_none ;
293
+ }
294
+
295
+ STATIC MP_DEFINE_CONST_FUN_OBJ_2 (mod_ssl_set_ciphers_obj , mod_ssl_set_ciphers );
296
+
297
+ #endif
298
+ // SSLContext.load_cert_chain
299
+
233
300
STATIC void ssl_context_load_key (mp_obj_ssl_context_t * self , mp_obj_t key_obj , mp_obj_t cert_obj ) {
234
301
size_t key_len ;
235
302
const byte * key = (const byte * )mp_obj_str_get_data (key_obj , & key_len );
@@ -258,6 +325,32 @@ STATIC void ssl_context_load_key(mp_obj_ssl_context_t *self, mp_obj_t key_obj, m
258
325
}
259
326
}
260
327
328
+ #ifdef MICROPY_SSL_MBEDTLS_EXTRAS
329
+
330
+ STATIC mp_obj_t mod_ssl_load_certchain (size_t n_args , const mp_obj_t * pos_args ,
331
+ mp_map_t * kw_args ) {
332
+
333
+ static const mp_arg_t allowed_args [] = {
334
+ { MP_QSTR_keyfile , MP_ARG_KW_ONLY | MP_ARG_OBJ , {.u_rom_obj = MP_ROM_NONE } },
335
+ };
336
+
337
+ mp_obj_ssl_context_t * self = MP_OBJ_TO_PTR (pos_args [0 ]);
338
+ mp_obj_t cert = pos_args [1 ];
339
+ mp_arg_val_t args [MP_ARRAY_SIZE (allowed_args )];
340
+ mp_arg_parse_all (n_args - 2 , pos_args + 2 , kw_args , MP_ARRAY_SIZE (allowed_args ), allowed_args , args );
341
+
342
+ if (cert != mp_const_none ) {
343
+ mp_check_self (mp_obj_is_str_or_bytes (cert ));
344
+ mp_check_self (mp_obj_is_str_or_bytes (args [0 ].u_obj ));
345
+ ssl_context_load_key (self , args [0 ].u_obj , cert );
346
+ }
347
+ return mp_const_none ;
348
+ }
349
+
350
+ STATIC MP_DEFINE_CONST_FUN_OBJ_KW (mod_ssl_load_certchain_obj , 2 , mod_ssl_load_certchain );
351
+ #endif
352
+ // SSLContext.load_verify_locations
353
+
261
354
STATIC void ssl_context_load_cadata (mp_obj_ssl_context_t * self , mp_obj_t cadata_obj ) {
262
355
size_t cacert_len ;
263
356
const byte * cacert = (const byte * )mp_obj_str_get_data (cadata_obj , & cacert_len );
@@ -270,6 +363,28 @@ STATIC void ssl_context_load_cadata(mp_obj_ssl_context_t *self, mp_obj_t cadata_
270
363
mbedtls_ssl_conf_ca_chain (& self -> conf , & self -> cacert , NULL );
271
364
}
272
365
366
+ #ifdef MICROPY_SSL_MBEDTLS_EXTRAS
367
+ STATIC mp_obj_t mod_ssl_load_cadata (size_t n_args , const mp_obj_t * pos_args ,
368
+ mp_map_t * kw_args ) {
369
+
370
+ static const mp_arg_t allowed_args [] = {
371
+ { MP_QSTR_cadata , MP_ARG_KW_ONLY | MP_ARG_OBJ , {.u_rom_obj = MP_ROM_NONE } },
372
+ };
373
+
374
+ mp_obj_ssl_context_t * self = MP_OBJ_TO_PTR (pos_args [0 ]);
375
+ mp_arg_val_t args [MP_ARRAY_SIZE (allowed_args )];
376
+ mp_arg_parse_all (n_args - 1 , pos_args + 1 , kw_args , MP_ARRAY_SIZE (allowed_args ), allowed_args , args );
377
+
378
+ if (args [0 ].u_obj != mp_const_none ) {
379
+ mp_check_self (mp_obj_is_str_or_bytes (args [0 ].u_obj ));
380
+ ssl_context_load_cadata (self , args [0 ].u_obj );
381
+ }
382
+ return mp_const_none ;
383
+ }
384
+
385
+ STATIC MP_DEFINE_CONST_FUN_OBJ_KW (mod_ssl_load_cadata_obj , 1 , mod_ssl_load_cadata );
386
+ #endif
387
+
273
388
STATIC mp_obj_t ssl_context_wrap_socket (size_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
274
389
enum { ARG_server_side , ARG_do_handshake_on_connect , ARG_server_hostname };
275
390
static const mp_arg_t allowed_args [] = {
@@ -284,6 +399,12 @@ STATIC mp_obj_t ssl_context_wrap_socket(size_t n_args, const mp_obj_t *pos_args,
284
399
mp_arg_val_t args [MP_ARRAY_SIZE (allowed_args )];
285
400
mp_arg_parse_all (n_args - 2 , pos_args + 2 , kw_args , MP_ARRAY_SIZE (allowed_args ), allowed_args , args );
286
401
402
+ if (self -> authmode == MBEDTLS_SSL_VERIFY_REQUIRED && args [ARG_server_side ].u_bool == false) {
403
+
404
+ if (args [ARG_server_hostname ].u_obj == mp_const_none ) {
405
+ mp_raise_ValueError (MP_ERROR_TEXT ("CERT_REQUIRED requires server_hostname" ));
406
+ }
407
+ }
287
408
// Create and return the new SSLSocket object.
288
409
return ssl_socket_make_new (self , sock , args [ARG_server_side ].u_bool ,
289
410
args [ARG_do_handshake_on_connect ].u_bool , args [ARG_server_hostname ].u_obj );
@@ -294,6 +415,12 @@ STATIC const mp_rom_map_elem_t ssl_context_locals_dict_table[] = {
294
415
#if MICROPY_PY_SSL_FINALISER
295
416
{ MP_ROM_QSTR (MP_QSTR___del__ ), MP_ROM_PTR (& ssl_context___del___obj ) },
296
417
#endif
418
+ #ifdef MICROPY_SSL_MBEDTLS_EXTRAS
419
+ { MP_ROM_QSTR (MP_QSTR_get_ciphers ), MP_ROM_PTR (& mod_ssl_get_ciphers_obj )},
420
+ { MP_ROM_QSTR (MP_QSTR_set_ciphers ), MP_ROM_PTR (& mod_ssl_set_ciphers_obj )},
421
+ { MP_ROM_QSTR (MP_QSTR_load_verify_locations ), MP_ROM_PTR (& mod_ssl_load_cadata_obj )},
422
+ { MP_ROM_QSTR (MP_QSTR_load_cert_chain ), MP_ROM_PTR (& mod_ssl_load_certchain_obj )},
423
+ #endif
297
424
{ MP_ROM_QSTR (MP_QSTR_wrap_socket ), MP_ROM_PTR (& ssl_context_wrap_socket_obj ) },
298
425
};
299
426
STATIC MP_DEFINE_CONST_DICT (ssl_context_locals_dict , ssl_context_locals_dict_table );
@@ -363,6 +490,18 @@ STATIC mp_obj_t ssl_socket_make_new(mp_obj_ssl_context_t *ssl_context, mp_obj_t
363
490
o -> last_error = 0 ;
364
491
365
492
int ret ;
493
+ #ifdef MICROPY_SSL_MBEDTLS_EXTRAS
494
+ uint32_t flags = 0 ;
495
+ int * cid = & ssl_context -> cipherid [0 ];
496
+ /* printf("cipherid: %d\n", *cid); */
497
+
498
+ // Ciphersuite Config
499
+ if (* cid != 0 ) {
500
+ mbedtls_ssl_conf_ciphersuites (& ssl_context -> conf , (const int * )& ssl_context -> cipherid );
501
+ }
502
+ #endif
503
+
504
+
366
505
mbedtls_ssl_init (& o -> ssl );
367
506
368
507
ret = mbedtls_ssl_setup (& o -> ssl , & ssl_context -> conf );
@@ -394,7 +533,29 @@ STATIC mp_obj_t ssl_socket_make_new(mp_obj_ssl_context_t *ssl_context, mp_obj_t
394
533
return MP_OBJ_FROM_PTR (o );
395
534
396
535
cleanup :
536
+ #ifdef MICROPY_SSL_MBEDTLS_EXTRAS
537
+ if (ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED ) {
538
+ flags = mbedtls_ssl_get_verify_result (& o -> ssl );
539
+ }
540
+ #endif
541
+
542
+
397
543
mbedtls_ssl_free (& o -> ssl );
544
+
545
+ #ifdef MICROPY_SSL_MBEDTLS_EXTRAS
546
+ if (ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED ) {
547
+ char xcbuf [512 ];
548
+ ret = mbedtls_x509_crt_verify_info (xcbuf , sizeof (xcbuf ), "\n" , flags );
549
+ // The length of the string written (not including the terminated nul byte),
550
+ // or a negative err code.
551
+ if (ret > 0 ) {
552
+ mp_raise_ValueError (MP_ERROR_TEXT (xcbuf ));
553
+ } else {
554
+ mbedtls_raise_error (ret );
555
+ }
556
+ }
557
+ #endif
558
+
398
559
mbedtls_raise_error (ret );
399
560
}
400
561
@@ -411,6 +572,19 @@ STATIC mp_obj_t mod_ssl_getpeercert(mp_obj_t o_in, mp_obj_t binary_form) {
411
572
}
412
573
STATIC MP_DEFINE_CONST_FUN_OBJ_2 (mod_ssl_getpeercert_obj , mod_ssl_getpeercert );
413
574
575
+ #ifdef MICROPY_SSL_MBEDTLS_EXTRAS
576
+ STATIC mp_obj_t mod_ssl_cipher (mp_obj_t o_in ) {
577
+ mp_obj_ssl_socket_t * o = MP_OBJ_TO_PTR (o_in );
578
+ const char * cipher_suite = mbedtls_ssl_get_ciphersuite (& o -> ssl );
579
+ const char * tls_version = mbedtls_ssl_get_version (& o -> ssl );
580
+ mp_obj_t tuple [2 ] = {mp_obj_new_str (cipher_suite , strlen (cipher_suite )),
581
+ mp_obj_new_str (tls_version , strlen (tls_version ))};
582
+
583
+ return mp_obj_new_tuple (2 , tuple );
584
+ }
585
+ STATIC MP_DEFINE_CONST_FUN_OBJ_1 (mod_ssl_cipher_obj , mod_ssl_cipher );
586
+ #endif
587
+
414
588
STATIC mp_uint_t socket_read (mp_obj_t o_in , void * buf , mp_uint_t size , int * errcode ) {
415
589
mp_obj_ssl_socket_t * o = MP_OBJ_TO_PTR (o_in );
416
590
o -> poll_mask = 0 ;
@@ -552,6 +726,9 @@ STATIC const mp_rom_map_elem_t ssl_socket_locals_dict_table[] = {
552
726
{ MP_ROM_QSTR (MP_QSTR_ioctl ), MP_ROM_PTR (& mp_stream_ioctl_obj ) },
553
727
#endif
554
728
{ MP_ROM_QSTR (MP_QSTR_getpeercert ), MP_ROM_PTR (& mod_ssl_getpeercert_obj ) },
729
+ #ifdef MICROPY_SSL_MBEDTLS_EXTRAS
730
+ { MP_ROM_QSTR (MP_QSTR_cipher ), MP_ROM_PTR (& mod_ssl_cipher_obj ) },
731
+ #endif
555
732
};
556
733
STATIC MP_DEFINE_CONST_DICT (ssl_socket_locals_dict , ssl_socket_locals_dict_table );
557
734
@@ -632,6 +809,9 @@ STATIC const mp_rom_map_elem_t mp_module_ssl_globals_table[] = {
632
809
{ MP_ROM_QSTR (MP_QSTR_SSLContext ), MP_ROM_PTR (& ssl_context_type ) },
633
810
634
811
// Constants.
812
+ #ifdef MICROPY_SSL_MBEDTLS_EXTRAS
813
+ { MP_ROM_QSTR (MP_QSTR_MBEDTLS_VERSION ), MP_ROM_PTR (& mbedtls_version_obj )},
814
+ #endif
635
815
{ MP_ROM_QSTR (MP_QSTR_PROTOCOL_TLS_CLIENT ), MP_ROM_INT (MBEDTLS_SSL_IS_CLIENT ) },
636
816
{ MP_ROM_QSTR (MP_QSTR_PROTOCOL_TLS_SERVER ), MP_ROM_INT (MBEDTLS_SSL_IS_SERVER ) },
637
817
{ MP_ROM_QSTR (MP_QSTR_CERT_NONE ), MP_ROM_INT (MBEDTLS_SSL_VERIFY_NONE ) },
0 commit comments