diff --git a/ChangeLog b/ChangeLog index dbffdf250..9ae1a4142 100644 --- a/ChangeLog +++ b/ChangeLog @@ -13,6 +13,8 @@ Security Found by Laurent Simon. Tighten parsing of RSA PKCS#1 v1.5 signatures, to avoid a potential Bleichenbacher/BERserk-style attack. + * Remove support for X509 certificates signed with MD5. + Issue raised by Harm Verhagen Bugfix * Fix insufficient support for signature-hash-algorithm extension, diff --git a/include/polarssl/config.h b/include/polarssl/config.h index 498fc5b9a..60d96ec65 100644 --- a/include/polarssl/config.h +++ b/include/polarssl/config.h @@ -2366,6 +2366,29 @@ /* X509 options */ //#define POLARSSL_X509_MAX_INTERMEDIATE_CA 8 /**< Maximum number of intermediate CAs in a verification chain. */ +/** + * \def POLARSSL_X509_MIN_VERIFY_MD_ALG + * + * Minimal hash algorithm accepted in X.509 chain verification. + * + * The value should be one of the enumerations in md_type_t defined in md.h + * Only algorithms with a value equal or higher are accepted. + * + * typedef enum { + * POLARSSL_MD_NONE=0, + * POLARSSL_MD_MD2, + * POLARSSL_MD_MD4, + * POLARSSL_MD_MD5, + * POLARSSL_MD_SHA1, + * POLARSSL_MD_SHA224, + * POLARSSL_MD_SHA256, + * POLARSSL_MD_SHA384, + * POLARSSL_MD_SHA512, + * POLARSSL_MD_RIPEMD160, + * } md_type_t; + */ +//#define POLARSSL_X509_MIN_VERIFY_MD_ALG POLARSSL_MD_SHA1 + /* \} name SECTION: Module configuration options */ #include "check_config.h" diff --git a/library/x509_crt.c b/library/x509_crt.c index 16a29b5b3..0bf4dea17 100644 --- a/library/x509_crt.c +++ b/library/x509_crt.c @@ -76,6 +76,10 @@ #endif /* !_WIN32 || EFIX64 || EFI32 */ #endif +#if !defined(POLARSSL_X509_MIN_VERIFY_MD_ALG) +#define POLARSSL_X509_MIN_VERIFY_MD_ALG POLARSSL_MD_SHA1 +#endif + /* Implementation that should never be optimized out by the compiler */ static void polarssl_zeroize( void *v, size_t n ) { volatile unsigned char *p = v; while( n-- ) *p++ = 0; @@ -1435,6 +1439,18 @@ int x509_crt_verify_info( char *buf, size_t size, const char *prefix, return( (int) ( size - n ) ); } +/* + * Check md_alg against profile + * Return 0 if md_alg acceptable for this profile, -1 otherwise + */ +static int x509_check_md_alg( md_type_t md_alg ) +{ + if( md_alg >= POLARSSL_X509_MIN_VERIFY_MD_ALG ) + return( 0 ); + + return( -1 ); +} + #if defined(POLARSSL_X509_CHECK_KEY_USAGE) int x509_crt_check_key_usage( const x509_crt *crt, int usage ) { @@ -1542,6 +1558,15 @@ static int x509_crt_verifycrl( x509_crt *crt, x509_crt *ca, } #endif + /* + * Check if CRL is signed with a valid MD + */ + if( x509_check_md_alg( crl_list->sig_md ) != 0 ) + { + flags |= BADCRL_NOT_TRUSTED; + break; + } + /* * Check if CRL is correctly signed by the trusted CA */ @@ -1789,6 +1814,18 @@ static int x509_crt_verify_top( */ *flags |= BADCERT_NOT_TRUSTED; + /* + * Check if certificate is signed with a valid MD + */ + if( x509_check_md_alg( child->sig_md ) != 0 ) + { + *flags |= BADCERT_NOT_TRUSTED; + /* + * not signed with a valid MD, no need to check trust_ca + */ + trust_ca = NULL; + } + md_info = md_info_from_type( child->sig_md ); if( md_info == NULL ) { @@ -1926,6 +1963,12 @@ static int x509_crt_verify_child( if( x509_time_future( &child->valid_from ) ) *flags |= BADCERT_FUTURE; + /* + * Check if certificate is signed with a valid MD + */ + if( x509_check_md_alg( child->sig_md ) != 0 ) + *flags |= BADCERT_NOT_TRUSTED; + md_info = md_info_from_type( child->sig_md ); if( md_info == NULL ) { diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data index 717cd6f79..7920fc626 100644 --- a/tests/suites/test_suite_x509parse.data +++ b/tests/suites/test_suite_x509parse.data @@ -417,11 +417,11 @@ x509_verify:"data_files/server2.crt":"data_files/server1.crt":"data_files/crl_ex X509 Certificate verification #12 (Valid Cert MD4 Digest) depends_on:POLARSSL_MD4_C:POLARSSL_PEM_PARSE_C:POLARSSL_SHA1_C:POLARSSL_RSA_C:POLARSSL_PKCS1_V15 -x509_verify:"data_files/cert_md4.crt":"data_files/test-ca.crt":"data_files/crl.pem":"NULL":0:0:"NULL" +x509_verify:"data_files/cert_md4.crt":"data_files/test-ca.crt":"data_files/crl.pem":"NULL":POLARSSL_ERR_X509_CERT_VERIFY_FAILED:BADCERT_NOT_TRUSTED:"NULL" X509 Certificate verification #13 (Valid Cert MD5 Digest) depends_on:POLARSSL_MD5_C:POLARSSL_PEM_PARSE_C:POLARSSL_SHA1_C:POLARSSL_RSA_C:POLARSSL_PKCS1_V15 -x509_verify:"data_files/cert_md5.crt":"data_files/test-ca.crt":"data_files/crl.pem":"NULL":0:0:"NULL" +x509_verify:"data_files/cert_md5.crt":"data_files/test-ca.crt":"data_files/crl.pem":"NULL":POLARSSL_ERR_X509_CERT_VERIFY_FAILED:BADCERT_NOT_TRUSTED:"NULL" X509 Certificate verification #14 (Valid Cert SHA1 Digest) depends_on:POLARSSL_SHA1_C:POLARSSL_PEM_PARSE_C:POLARSSL_SHA1_C:POLARSSL_RSA_C:POLARSSL_PKCS1_V15 @@ -723,6 +723,14 @@ X509 Certificate verification #87 (Expired CA and invalid CA) depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_ECP_C:POLARSSL_ECP_DP_SECP256R1_ENABLED:POLARSSL_ECP_DP_SECP384R1_ENABLED:POLARSSL_SHA1_C:POLARSSL_SHA256_C x509_verify:"data_files/server5.crt":"data_files/test-ca2_cat-past-invalid.crt":"data_files/crl-ec-sha1.pem":"NULL":POLARSSL_ERR_X509_CERT_VERIFY_FAILED:BADCERT_EXPIRED:"NULL" +X509 Certificate verification #88 (MD4 CRL) +depends_on:POLARSSL_SHA256_C:POLARSSL_PEM_PARSE_C:POLARSSL_SHA1_C:POLARSSL_RSA_C:POLARSSL_PKCS1_V15 +x509_verify:"data_files/cert_sha256.crt":"data_files/test-ca.crt":"data_files/crl_md4.pem":"NULL":POLARSSL_ERR_X509_CERT_VERIFY_FAILED:BADCRL_NOT_TRUSTED:"NULL" + +X509 Certificate verification #89 (MD5 CRL) +depends_on:POLARSSL_SHA256_C:POLARSSL_PEM_PARSE_C:POLARSSL_SHA1_C:POLARSSL_RSA_C:POLARSSL_PKCS1_V15 +x509_verify:"data_files/cert_sha256.crt":"data_files/test-ca.crt":"data_files/crl_md5.pem":"NULL":POLARSSL_ERR_X509_CERT_VERIFY_FAILED:BADCRL_NOT_TRUSTED:"NULL" + X509 Certificate verification callback: trusted EE cert depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_ECDSA_C:POLARSSL_SHA256_C:POLARSSL_ECP_DP_SECP256R1_ENABLED x509_verify_callback:"data_files/server5-selfsigned.crt":"data_files/server5-selfsigned.crt":0:"depth 0 - serial 53\:A2\:CB\:4B\:12\:4E\:AD\:83\:7D\:A8\:94\:B2 - subject CN=selfsigned, OU=testing, O=PolarSSL, C=NL\n"