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-07-10 11:31:01 +02:00 committed by Simon Butcher
parent 8af7bfa982
commit d0e755716f
7 changed files with 21 additions and 5 deletions

View file

@ -29,6 +29,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 1.3.20 released 2017-06-21 = mbed TLS 1.3.20 released 2017-06-21

View file

@ -76,6 +76,7 @@
#define POLARSSL_ERR_X509_BAD_INPUT_DATA -0x2800 /**< Input invalid. */ #define POLARSSL_ERR_X509_BAD_INPUT_DATA -0x2800 /**< Input invalid. */
#define POLARSSL_ERR_X509_MALLOC_FAILED -0x2880 /**< Allocation of memory failed. */ #define POLARSSL_ERR_X509_MALLOC_FAILED -0x2880 /**< Allocation of memory failed. */
#define POLARSSL_ERR_X509_FILE_IO_ERROR -0x2900 /**< Read/write of file failed. */ #define POLARSSL_ERR_X509_FILE_IO_ERROR -0x2900 /**< Read/write of file failed. */
#define POLARSSL_ERR_X509_FATAL_ERROR -0x3000 /**< A fatal error occured, eg the chain is too long or the vrfy callback failed. */
/* \} name */ /* \} name */
/** /**

View file

@ -232,7 +232,13 @@ int 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 POLARSSL_ERR_X509_CERT_VERIFY_FAILED which should not
* be returned at this point), or POLARSSL_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 x509_crt_verify_info() * using \c x509_crt_verify_info()

View file

@ -496,6 +496,8 @@ void polarssl_strerror( int ret, char *buf, size_t buflen )
polarssl_snprintf( buf, buflen, "X509 - Allocation of memory failed" ); polarssl_snprintf( buf, buflen, "X509 - Allocation of memory failed" );
if( use_ret == -(POLARSSL_ERR_X509_FILE_IO_ERROR) ) if( use_ret == -(POLARSSL_ERR_X509_FILE_IO_ERROR) )
polarssl_snprintf( buf, buflen, "X509 - Read/write of file failed" ); polarssl_snprintf( buf, buflen, "X509 - Read/write of file failed" );
if( use_ret == -(POLARSSL_ERR_X509_FATAL_ERROR) )
polarssl_snprintf( buf, buflen, "X509 - A fatal error occured, eg the chain is too long or the vrfy callback failed" );
#endif /* POLARSSL_X509_USE,X509_CREATE_C */ #endif /* POLARSSL_X509_USE,X509_CREATE_C */
// END generated code // END generated code

View file

@ -1957,8 +1957,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 > POLARSSL_X509_MAX_INTERMEDIATE_CA ) if( 1 + path_cnt > POLARSSL_X509_MAX_INTERMEDIATE_CA )
{ {
*flags |= BADCERT_NOT_TRUSTED; /* return immediately as the goal is to avoid unbounded recursion */
return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED ); return( POLARSSL_ERR_X509_FATAL_ERROR );
} }
if( x509_time_expired( &child->valid_to ) ) if( x509_time_expired( &child->valid_to ) )
@ -2174,6 +2174,10 @@ int x509_crt_verify( x509_crt *crt,
} }
exit: exit:
/* prevent misuse of the vrfy callback */
if( ret == POLARSSL_ERR_X509_CERT_VERIFY_FAILED )
ret = POLARSSL_ERR_X509_FATAL_ERROR;
if( ret != 0 ) if( ret != 0 )
{ {
*flags = (uint32_t) -1; *flags = (uint32_t) -1;

View file

@ -94,7 +94,7 @@ while (my $line = <GREP>)
my $found_hl = grep $_ eq $module_name, @high_level_modules; my $found_hl = grep $_ eq $module_name, @high_level_modules;
if (!$found_ll && !$found_hl) if (!$found_ll && !$found_hl)
{ {
polarssl_printf("Error: Do not know how to handle: $module_name\n"); printf("Error: Do not know how to handle: $module_name\n");
exit 1; exit 1;
} }

View file

@ -1182,7 +1182,7 @@ x509_crt_verify_max:"data_files/test-ca2.crt":"data_files/dir-maxpath":POLARSSL_
X509 CRT verify long chain (max intermediate CA + 1) X509 CRT verify long chain (max intermediate CA + 1)
depends_on:POLARSSL_SHA256_C:POLARSSL_ECDSA_C:POLARSSL_ECP_DP_SECP256R1_ENABLED depends_on:POLARSSL_SHA256_C:POLARSSL_ECDSA_C:POLARSSL_ECP_DP_SECP256R1_ENABLED
x509_crt_verify_max:"data_files/dir-maxpath/00.crt":"data_files/dir-maxpath":POLARSSL_X509_MAX_INTERMEDIATE_CA+1:POLARSSL_ERR_X509_CERT_VERIFY_FAILED:-1 x509_crt_verify_max:"data_files/dir-maxpath/00.crt":"data_files/dir-maxpath":POLARSSL_X509_MAX_INTERMEDIATE_CA+1:POLARSSL_ERR_X509_FATAL_ERROR:-1
X509 CRT verify chain #1 (zero pathlen intermediate) X509 CRT verify chain #1 (zero pathlen intermediate)
depends_on:POLARSSL_SHA256_C:POLARSSL_RSA_C depends_on:POLARSSL_SHA256_C:POLARSSL_RSA_C