Only return VERIFY_FAILED from a single point
Everything else is a fatal error. Also improve documentation about that for
the vrfy callback.
diff --git a/library/error.c b/library/error.c
index dd2db0c..db42381 100644
--- a/library/error.c
+++ b/library/error.c
@@ -480,6 +480,8 @@
mbedtls_snprintf( buf, buflen, "X509 - Read/write of file failed" );
if( use_ret == -(MBEDTLS_ERR_X509_BUFFER_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 */
// END generated code
diff --git a/library/x509_crt.c b/library/x509_crt.c
index ee5f27e..ec5f772 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -2057,8 +2057,8 @@
/* path_cnt is 0 for the first intermediate CA */
if( 1 + path_cnt > MBEDTLS_X509_MAX_INTERMEDIATE_CA )
{
- *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED;
- return( MBEDTLS_ERR_X509_CERT_VERIFY_FAILED );
+ /* return immediately as the goal is to avoid unbounded recursion */
+ return( MBEDTLS_ERR_X509_FATAL_ERROR );
}
if( mbedtls_x509_time_is_past( &child->valid_to ) )
@@ -2310,6 +2310,10 @@
}
exit:
+ /* prevent misuse of the vrfy callback */
+ if( ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED )
+ ret = MBEDTLS_ERR_X509_FATAL_ERROR;
+
if( ret != 0 )
{
*flags = (uint32_t) -1;