Only return VERIFY_FAILED from a single point

Everything else is a fatal error. Also improve documentation about that for
the vrfy callback.
This commit is contained in:
Manuel Pégourié-Gonnard 2017-06-26 10:11:49 +02:00
parent d15795acd5
commit 31458a1878
8 changed files with 22 additions and 6 deletions

View file

@ -6,6 +6,9 @@ Changes
* Certificate verification functions now set flags to -1 in case the full * Certificate verification functions now set flags to -1 in case the full
chain was not verified due to an internal error (including in the verify chain was not verified due to an internal error (including in the verify
callback) or chain length limitations. callback) or chain length limitations.
* With authmode set to optional, handshake is now aborted if the
verification of the peer's certificate failed due to an overlong chain or
a fatal error in the vrfy callback.
= mbed TLS 2.5.1 released 2017-06-21 = mbed TLS 2.5.1 released 2017-06-21

View file

@ -71,7 +71,7 @@
* Name ID Nr of Errors * Name ID Nr of Errors
* PEM 1 9 * PEM 1 9
* PKCS#12 1 4 (Started from top) * PKCS#12 1 4 (Started from top)
* X509 2 19 * X509 2 20
* PKCS5 2 4 (Started from top) * PKCS5 2 4 (Started from top)
* DHM 3 9 * DHM 3 9
* PK 3 14 (Started from top) * PK 3 14 (Started from top)

View file

@ -1052,7 +1052,7 @@ void mbedtls_ssl_conf_authmode( mbedtls_ssl_config *conf, int authmode );
* *
* If set, the verify callback is called for each * If set, the verify callback is called for each
* certificate in the chain. For implementation * certificate in the chain. For implementation
* information, please see \c x509parse_verify() * information, please see \c mbedtls_x509_crt_verify()
* *
* \param conf SSL configuration * \param conf SSL configuration
* \param f_vrfy verification function * \param f_vrfy verification function

View file

@ -76,6 +76,7 @@
#define MBEDTLS_ERR_X509_ALLOC_FAILED -0x2880 /**< Allocation of memory failed. */ #define MBEDTLS_ERR_X509_ALLOC_FAILED -0x2880 /**< Allocation of memory failed. */
#define MBEDTLS_ERR_X509_FILE_IO_ERROR -0x2900 /**< Read/write of file failed. */ #define MBEDTLS_ERR_X509_FILE_IO_ERROR -0x2900 /**< Read/write of file failed. */
#define MBEDTLS_ERR_X509_BUFFER_TOO_SMALL -0x2980 /**< Destination buffer is too small. */ #define MBEDTLS_ERR_X509_BUFFER_TOO_SMALL -0x2980 /**< Destination buffer is too small. */
#define MBEDTLS_ERR_X509_FATAL_ERROR -0x3000 /**< A fatal error occured, eg the chain is too long or the vrfy callback failed. */
/* \} name */ /* \} name */
/** /**

View file

@ -267,7 +267,13 @@ int mbedtls_x509_crt_verify_info( char *buf, size_t size, const char *prefix,
* *
* All flags left after returning from the callback * All flags left after returning from the callback
* are also returned to the application. The function should * are also returned to the application. The function should
* return 0 for anything but a fatal error. * return 0 for anything (including invalid certificates)
* other than fatal error, as a non-zero return code
* immediately aborts the verification process. For fatal
* errors, a specific error code should be used (different
* from MBEDTLS_ERR_X509_CERT_VERIFY_FAILED which should not
* be returned at this point), or MBEDTLS_ERR_X509_FATAL_ERROR
* can be used if no better code is available.
* *
* \note In case verification failed, the results can be displayed * \note In case verification failed, the results can be displayed
* using \c mbedtls_x509_crt_verify_info() * using \c mbedtls_x509_crt_verify_info()

View file

@ -480,6 +480,8 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
mbedtls_snprintf( buf, buflen, "X509 - Read/write of file failed" ); mbedtls_snprintf( buf, buflen, "X509 - Read/write of file failed" );
if( use_ret == -(MBEDTLS_ERR_X509_BUFFER_TOO_SMALL) ) if( use_ret == -(MBEDTLS_ERR_X509_BUFFER_TOO_SMALL) )
mbedtls_snprintf( buf, buflen, "X509 - Destination buffer is too small" ); mbedtls_snprintf( buf, buflen, "X509 - Destination buffer is too small" );
if( use_ret == -(MBEDTLS_ERR_X509_FATAL_ERROR) )
mbedtls_snprintf( buf, buflen, "X509 - A fatal error occured, eg the chain is too long or the vrfy callback failed" );
#endif /* MBEDTLS_X509_USE_C || MBEDTLS_X509_CREATE_C */ #endif /* MBEDTLS_X509_USE_C || MBEDTLS_X509_CREATE_C */
// END generated code // END generated code

View file

@ -2057,8 +2057,8 @@ static int x509_crt_verify_child(
/* path_cnt is 0 for the first intermediate CA */ /* path_cnt is 0 for the first intermediate CA */
if( 1 + path_cnt > MBEDTLS_X509_MAX_INTERMEDIATE_CA ) if( 1 + path_cnt > MBEDTLS_X509_MAX_INTERMEDIATE_CA )
{ {
*flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED; /* return immediately as the goal is to avoid unbounded recursion */
return( MBEDTLS_ERR_X509_CERT_VERIFY_FAILED ); return( MBEDTLS_ERR_X509_FATAL_ERROR );
} }
if( mbedtls_x509_time_is_past( &child->valid_to ) ) if( mbedtls_x509_time_is_past( &child->valid_to ) )
@ -2310,6 +2310,10 @@ int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt,
} }
exit: exit:
/* prevent misuse of the vrfy callback */
if( ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED )
ret = MBEDTLS_ERR_X509_FATAL_ERROR;
if( ret != 0 ) if( ret != 0 )
{ {
*flags = (uint32_t) -1; *flags = (uint32_t) -1;

View file

@ -1204,7 +1204,7 @@ mbedtls_x509_crt_verify_max:"data_files/test-ca2.crt":"data_files/dir-maxpath":M
X509 CRT verify long chain (max intermediate CA + 1) X509 CRT verify long chain (max intermediate CA + 1)
depends_on:MBEDTLS_SHA256_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED depends_on:MBEDTLS_SHA256_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
mbedtls_x509_crt_verify_max:"data_files/dir-maxpath/00.crt":"data_files/dir-maxpath":MBEDTLS_X509_MAX_INTERMEDIATE_CA+1:MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:-1 mbedtls_x509_crt_verify_max:"data_files/dir-maxpath/00.crt":"data_files/dir-maxpath":MBEDTLS_X509_MAX_INTERMEDIATE_CA+1:MBEDTLS_ERR_X509_FATAL_ERROR:-1
X509 CRT verify chain #1 (zero pathlen intermediate) X509 CRT verify chain #1 (zero pathlen intermediate)
depends_on:MBEDTLS_SHA256_C:MBEDTLS_RSA_C depends_on:MBEDTLS_SHA256_C:MBEDTLS_RSA_C