@@ -49,28 +49,6 @@ static int x509_v3_basic_constraints(const uint8_t *cert, int offset,
4949 X509_CTX * x509_ctx );
5050static int x509_v3_key_usage (const uint8_t * cert , int offset ,
5151 X509_CTX * x509_ctx );
52-
53- /**
54- * Retrieve the signature from a certificate.
55- */
56- static const uint8_t * get_signature (const uint8_t * asn1_sig , int * len )
57- {
58- int offset = 0 ;
59- const uint8_t * ptr = NULL ;
60-
61- if (asn1_next_obj (asn1_sig , & offset , ASN1_SEQUENCE ) < 0 ||
62- asn1_skip_obj (asn1_sig , & offset , ASN1_SEQUENCE ))
63- goto end_get_sig ;
64-
65- if (asn1_sig [offset ++ ] != ASN1_OCTET_STRING )
66- goto end_get_sig ;
67- * len = get_asn1_length (asn1_sig , & offset );
68- ptr = & asn1_sig [offset ]; /* all ok */
69-
70- end_get_sig :
71- return ptr ;
72- }
73-
7452#endif
7553
7654/**
@@ -412,17 +390,56 @@ void x509_free(X509_CTX *x509_ctx)
412390}
413391
414392#ifdef CONFIG_SSL_CERT_VERIFICATION
393+ static const uint8_t sig_prefix_md5 [] PROGMEM = {0x30 , 0x20 , 0x30 , 0x0C , 0x06 , 0x08 , 0x2A , 0x86 , 0x48 , 0x86 , 0xF7 , 0x0D , 0x02 , 0x05 , 0x05 , 0x00 , 0x04 , 0x10 };
394+ static const uint8_t sig_prefix_sha1 [] PROGMEM = {0x30 , 0x21 , 0x30 , 0x09 , 0x06 , 0x05 , 0x2b , 0x0E , 0x03 , 0x02 , 0x1A , 0x05 , 0x00 , 0x04 , 0x14 };
395+ static const uint8_t sig_prefix_sha256 [] PROGMEM = {0x30 , 0x31 , 0x30 , 0x0d , 0x06 , 0x09 , 0x60 , 0x86 , 0x48 , 0x01 , 0x65 , 0x03 , 0x04 , 0x02 , 0x01 , 0x05 , 0x00 , 0x04 , 0x20 };
396+ static const uint8_t sig_prefix_sha384 [] PROGMEM = {0x30 , 0x41 , 0x30 , 0x0d , 0x06 , 0x09 , 0x60 , 0x86 , 0x48 , 0x01 , 0x65 , 0x03 , 0x04 , 0x02 , 0x02 , 0x05 , 0x00 , 0x04 , 0x30 };
397+ static const uint8_t sig_prefix_sha512 [] PROGMEM = {0x30 , 0x51 , 0x30 , 0x0d , 0x06 , 0x09 , 0x60 , 0x86 , 0x48 , 0x01 , 0x65 , 0x03 , 0x04 , 0x02 , 0x03 , 0x05 , 0x00 , 0x04 , 0x40 };
398+
415399/**
416400 * Take a signature and decrypt it.
417401 */
418- static bigint * sig_verify (BI_CTX * ctx , const uint8_t * sig , int sig_len ,
402+ static bigint * sig_verify (BI_CTX * ctx , const uint8_t * sig , int sig_len , uint8_t sig_type ,
419403 bigint * modulus , bigint * pub_exp )
420404{
421- int i , size ;
405+ int i ;
422406 bigint * decrypted_bi , * dat_bi ;
423407 bigint * bir = NULL ;
424408 uint8_t * block = (uint8_t * )malloc (sig_len );
425409
410+ const uint8_t * sig_prefix = NULL ;
411+ uint8_t sig_prefix_size = 0 , hash_len = 0 ;
412+ /* adjust our expections */
413+ switch (sig_type )
414+ {
415+ case SIG_TYPE_MD5 :
416+ sig_prefix = sig_prefix_md5 ;
417+ sig_prefix_size = sizeof (sig_prefix_md5 );
418+ break ;
419+ case SIG_TYPE_SHA1 :
420+ sig_prefix = sig_prefix_sha1 ;
421+ sig_prefix_size = sizeof (sig_prefix_sha1 );
422+ break ;
423+ case SIG_TYPE_SHA256 :
424+ sig_prefix = sig_prefix_sha256 ;
425+ sig_prefix_size = sizeof (sig_prefix_sha256 );
426+ break ;
427+ case SIG_TYPE_SHA384 :
428+ sig_prefix = sig_prefix_sha384 ;
429+ sig_prefix_size = sizeof (sig_prefix_sha384 );
430+ break ;
431+ case SIG_TYPE_SHA512 :
432+ sig_prefix = sig_prefix_sha512 ;
433+ sig_prefix_size = sizeof (sig_prefix_sha512 );
434+ break ;
435+ }
436+ if (sig_prefix )
437+ hash_len = sig_prefix [sig_prefix_size - 1 ];
438+
439+ /* check length (#A) */
440+ if (sig_len < 2 + 8 + 1 + sig_prefix_size + hash_len )
441+ goto err ;
442+
426443 /* decrypt */
427444 dat_bi = bi_import (ctx , sig , sig_len );
428445 ctx -> mod_offset = BIGINT_M_OFFSET ;
@@ -433,21 +450,30 @@ static bigint *sig_verify(BI_CTX *ctx, const uint8_t *sig, int sig_len,
433450 bi_export (ctx , decrypted_bi , block , sig_len );
434451 ctx -> mod_offset = BIGINT_M_OFFSET ;
435452
436- i = 10 ; /* start at the first possible non-padded byte */
437- while (block [i ++ ] && i < sig_len );
438- size = sig_len - i ;
439-
440- /* get only the bit we want */
441- if (size > 0 )
442- {
443- int len ;
444- const uint8_t * sig_ptr = get_signature (& block [i ], & len );
453+ /* check the first 2 bytes */
454+ if (block [0 ] != 0 || block [1 ] != 1 )
455+ goto err ;
445456
446- if (sig_ptr )
447- {
448- bir = bi_import (ctx , sig_ptr , len );
449- }
457+ /* check the padding */
458+ i = 2 ; /* start at the first padding byte */
459+ while (i < sig_len - 1 - sig_prefix_size - hash_len )
460+ { /* together with (#A), we require at least 8 bytes of padding */
461+ if (block [i ++ ] != 0xFF )
462+ goto err ;
450463 }
464+
465+ /* check end of padding */
466+ if (block [i ++ ] != 0 )
467+ goto err ;
468+
469+ /* check the ASN.1 metadata */
470+ if (memcmp_P (block + i , sig_prefix , sig_prefix_size ))
471+ goto err ;
472+
473+ /* now we can get the hash we need */
474+ bir = bi_import (ctx , block + i + sig_prefix_size , hash_len );
475+
476+ err :
451477 free (block );
452478 /* save a few bytes of memory */
453479 bi_clear_cache (ctx );
@@ -600,7 +626,7 @@ int x509_verify(const CA_CERT_CTX *ca_cert_ctx, const X509_CTX *cert,
600626 }
601627
602628 /* check the signature */
603- cert_sig = sig_verify (ctx , cert -> signature , cert -> sig_len ,
629+ cert_sig = sig_verify (ctx , cert -> signature , cert -> sig_len , cert -> sig_type ,
604630 bi_clone (ctx , mod ), bi_clone (ctx , expn ));
605631
606632 if (cert_sig && cert -> digest )
0 commit comments