@@ -124,6 +124,12 @@ static bool tls_session_pairs_from_crl(fr_pair_list_t *pair_list, TALLOC_CTX *ct
124124
125125 for (i = 0 ; i < sk_DIST_POINT_num (dps ); i ++ ) {
126126 dp = sk_DIST_POINT_value (dps , i );
127+
128+ /*
129+ * RFC 5280 Section 4.2.1.13 says that the distpoint is optional.
130+ */
131+ if (!dp -> distpoint ) return false;
132+
127133 names = dp -> distpoint -> name .fullname ;
128134
129135 /*
@@ -461,6 +467,56 @@ int fr_tls_session_pairs_from_x509_cert(fr_pair_list_t *pair_list, TALLOC_CTX *c
461467 return 0 ;
462468}
463469
470+ static int fr_tls_extension_decode (request_t * request , fr_pair_t * container , uint8_t const * extension ,
471+ size_t hlen , size_t dlen , size_t total_len , fr_dict_attr_t const * da )
472+ {
473+ size_t i ,extension_len ;
474+ uint8_t const * data ;
475+
476+ fr_assert ((hlen == 1 ) || (hlen == 2 ));
477+ fr_assert ((dlen == 1 ) || (dlen == 2 ));
478+
479+ if (total_len < hlen ) {
480+ REDEBUG ("Missing length in %s extension" , da -> name );
481+ return -1 ;
482+ }
483+
484+ if (hlen == 1 ) {
485+ fr_assert (da -> type == FR_TYPE_UINT8 );
486+ extension_len = extension [0 ];
487+ } else {
488+ fr_assert (da -> type == FR_TYPE_UINT16 );
489+ extension_len = (extension [0 ] << 8 ) + extension [1 ];
490+ }
491+
492+ if (extension_len * dlen + hlen > total_len ) {
493+ REDEBUG ("Invalid length in %s extension" , da -> name );
494+ return -1 ;
495+ }
496+
497+ data = extension + hlen ;
498+
499+ for (i = 0 ; i < extension_len ; i += dlen ) {
500+ fr_pair_t * vp ;
501+
502+ MEM (fr_pair_append_by_da (container , & vp , & container -> vp_group , da ) >= 0 );
503+
504+ switch (dlen ) {
505+ case 1 :
506+ vp -> vp_uint8 = data [0 ];
507+ break ;
508+
509+ case 2 :
510+ vp -> vp_uint16 = (data [0 ] << 8 ) + data [1 ];
511+ break ;
512+ }
513+
514+ data += dlen ;
515+ }
516+
517+ return 0 ;
518+ }
519+
464520/** Callback to extract pairs from a Client Hello
465521 *
466522 */
@@ -469,7 +525,7 @@ int fr_tls_session_client_hello_cb(SSL *ssl, UNUSED int *al, UNUSED void *arg)
469525 request_t * request = SSL_get_ex_data (ssl , FR_TLS_EX_INDEX_REQUEST );
470526 request_t * parent = request -> parent ;
471527 uint8_t const * ciphers , * extension ;
472- int * extensions , extension_len , i ;
528+ int * extensions , i ;
473529 size_t data_size , j ;
474530 STACK_OF (SSL_CIPHER ) * sk ;
475531 SSL_CIPHER const * cipher ;
@@ -510,49 +566,40 @@ int fr_tls_session_client_hello_cb(SSL *ssl, UNUSED int *al, UNUSED void *arg)
510566 RPEDEBUG ("Failed to fetch client hello extensions" );
511567 goto fail ;
512568 }
569+
513570 for (j = 0 ; j < data_size ; j ++ ) {
514- if (SSL_client_hello_get0_ext (ssl , extensions [j ], & extension , NULL ) == 0 ) {
571+ size_t total_len ;
572+
573+ if (SSL_client_hello_get0_ext (ssl , extensions [j ], & extension , & total_len ) == 0 ) {
515574 RPDEBUG ("Failed getting client hello extension %d" , extensions [j ]);
516575 OPENSSL_free (extensions );
517576 goto fail ;
518577 }
519578
520579 switch (extensions [j ]) {
521- case TLSEXT_TYPE_supported_groups :
522- extension_len = (extension [0 ] << 8 ) + extension [1 ];
523- for (i = 0 ; i < extension_len ; i += 2 ) {
524- fr_pair_append_by_da (container , & vp , & container -> vp_group , attr_tls_client_hello_supported_group );
525- vp -> vp_uint16 = (extension [i + 2 ] << 8 ) + extension [i + 3 ];
526- }
580+ case TLSEXT_TYPE_supported_groups : /* length[2] + 2*data */
581+ if (fr_tls_extension_decode (request , container , extension , 2 , 2 , total_len ,
582+ attr_tls_client_hello_supported_group ) < 0 ) goto fail ;
527583 break ;
528584
529- case TLSEXT_TYPE_ec_point_formats :
530- for (i = 0 ; i < extension [0 ]; i += 1 ) {
531- fr_pair_append_by_da (container , & vp , & container -> vp_group , attr_tls_client_hello_ec_point_format );
532- vp -> vp_uint8 = extension [i + 1 ];
533- }
585+ case TLSEXT_TYPE_ec_point_formats : /* length[1] + data */
586+ if (fr_tls_extension_decode (request , container , extension , 1 , 1 , total_len ,
587+ attr_tls_client_hello_ec_point_format ) < 0 ) goto fail ;
534588 break ;
535589
536- case TLSEXT_TYPE_signature_algorithms :
537- extension_len = (extension [0 ] << 8 ) + extension [1 ];
538- for (i = 0 ; i < extension_len ; i += 2 ) {
539- fr_pair_append_by_da (container , & vp , & container -> vp_group , attr_tls_client_hello_sig_algo );
540- vp -> vp_uint16 = (extension [i + 2 ] << 8 ) + extension [i + 3 ];
541- }
590+ case TLSEXT_TYPE_signature_algorithms : /* length[2] + 2*data */
591+ if (fr_tls_extension_decode (request , container , extension , 2 , 2 , total_len ,
592+ attr_tls_client_hello_sig_algo ) < 0 ) goto fail ;
542593 break ;
543594
544- case TLSEXT_TYPE_supported_versions :
545- for (i = 0 ; i < extension [0 ]; i += 2 ) {
546- fr_pair_append_by_da (container , & vp , & container -> vp_group , attr_tls_client_hello_tls_version );
547- tls_version = vp -> vp_uint16 = (extension [i + 1 ] << 8 ) + extension [i + 2 ];
548- }
595+ case TLSEXT_TYPE_supported_versions : /* length[1] + 2*data */
596+ if (fr_tls_extension_decode (request , container , extension , 1 , 2 , total_len ,
597+ attr_tls_client_hello_tls_version ) < 0 ) goto fail ;
549598 break ;
550599
551- case TLSEXT_TYPE_psk_kex_modes :
552- for (i = 0 ; i < extension [0 ]; i += 1 ) {
553- fr_pair_append_by_da (container , & vp , & container -> vp_group , attr_tls_client_hello_psk_key_mode );
554- vp -> vp_uint8 = extension [i + 1 ];
555- }
600+ case TLSEXT_TYPE_psk_kex_modes : /* length[1] + data */
601+ if (fr_tls_extension_decode (request , container , extension , 1 , 1 , total_len ,
602+ attr_tls_client_hello_psk_key_mode ) < 0 ) goto fail ;
556603 break ;
557604 }
558605 }
0 commit comments