diff --git a/ChangeLog b/ChangeLog index a64de5dd1..d33897c8a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,6 +15,12 @@ Bugfix * Wipe stack buffers in RSA private key operations (rsa_rsaes_pkcs1_v15_decrypt(), rsa_rsaes_oaep_decrypt). Found by Laurent Simon. + * Accept empty trusted CA chain in authentication mode + SSL_VERIFY_OPTIONAL. Fixes #864. Found by jethrogb. + * Fix implementation of ssl_parse_certificate + to not annihilate fatal errors in authentication mode + SSL_VERIFY_OPTIONAL and to reflect bad EC curves + within verification result. = mbed TLS 1.3.19 branch released 2017-03-08 diff --git a/include/polarssl/x509.h b/include/polarssl/x509.h index cd01539b9..adaacfff1 100644 --- a/include/polarssl/x509.h +++ b/include/polarssl/x509.h @@ -97,6 +97,8 @@ #define BADCERT_KEY_USAGE 0x0800 /**< Usage does not match the keyUsage extension. */ #define BADCERT_EXT_KEY_USAGE 0x1000 /**< Usage does not match the extendedKeyUsage extension. */ #define BADCERT_NS_CERT_TYPE 0x2000 /**< Usage does not match the nsCertType extension. */ +#define BADCERT_BAD_KEY 0x10000 /**< Bad key (e.g. unsupported elliptic curve in use) */ + /* \} name */ /* \} addtogroup x509_module */ diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 7cf968d92..577922978 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -2841,12 +2841,6 @@ int ssl_parse_certificate( ssl_context *ssl ) if( ssl->authmode != SSL_VERIFY_NONE ) { - if( ssl->ca_chain == NULL ) - { - SSL_DEBUG_MSG( 1, ( "got no CA chain" ) ); - return( POLARSSL_ERR_SSL_CA_CHAIN_REQUIRED ); - } - /* * Main check: verify certificate */ @@ -2872,6 +2866,8 @@ int ssl_parse_certificate( ssl_context *ssl ) if( pk_can_do( pk, POLARSSL_PK_ECKEY ) && ! ssl_curve_is_acceptable( ssl, pk_ec( *pk )->grp.id ) ) { + ssl->session_negotiate->verify_result |= BADCERT_BAD_KEY; + SSL_DEBUG_MSG( 1, ( "bad certificate (EC key curve)" ) ); if( ret == 0 ) ret = POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE; @@ -2889,8 +2885,36 @@ int ssl_parse_certificate( ssl_context *ssl ) ret = POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE; } - if( ssl->authmode != SSL_VERIFY_REQUIRED ) + /* x509_crt_verify_with_profile is supposed to report a + * verification failure through POLARSSL_ERR_X509_CERT_VERIFY_FAILED, + * with details encoded in the verification flags. All other kinds + * of error codes, including those from the user provided f_vrfy + * functions, are treated as fatal and lead to a failure of + * ssl_parse_certificate even if verification was optional. */ + if( ssl->authmode == SSL_VERIFY_OPTIONAL && + ( ret == POLARSSL_ERR_X509_CERT_VERIFY_FAILED || + ret == POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE ) ) + { ret = 0; + } + + if( ssl->ca_chain == NULL && ssl->authmode == SSL_VERIFY_REQUIRED ) + { + SSL_DEBUG_MSG( 1, ( "got no CA chain" ) ); + ret = POLARSSL_ERR_SSL_CA_CHAIN_REQUIRED; + } + +#if defined(POLARSSL_DEBUG_C) + if( ssl->session_negotiate->verify_result != 0 ) + { + SSL_DEBUG_MSG( 3, ( "! Certificate verification flags %x", + ssl->session_negotiate->verify_result ) ); + } + else + { + SSL_DEBUG_MSG( 3, ( "Certificate verification flags clear" ) ); + } +#endif /* POLARSSL_DEBUG_C */ } SSL_DEBUG_MSG( 2, ( "<= parse certificate" ) ); diff --git a/library/x509_crt.c b/library/x509_crt.c index a3517f64f..16a29b5b3 100644 --- a/library/x509_crt.c +++ b/library/x509_crt.c @@ -1403,6 +1403,7 @@ static const struct x509_crt_verify_string x509_crt_verify_strings[] = { { BADCERT_KEY_USAGE, "Usage does not match the keyUsage extension" }, { BADCERT_EXT_KEY_USAGE, "Usage does not match the extendedKeyUsage extension" }, { BADCERT_NS_CERT_TYPE, "Usage does not match the nsCertType extension" }, + { BADCERT_BAD_KEY, "The certificate uses an invalid key (e.g. unsupported elliptic curve)" }, { 0, NULL } };