1
0
mirror of https://github.com/Mbed-TLS/mbedtls.git synced 2025-07-29 11:41:15 +03:00

Merge remote-tracking branch 'origin/pr/2532' into development

* origin/pr/2532: (29 commits)
  Document and test flags in x509_verify
  Fix style issues and a typo
  Fix name to function call
  Address comments for x509 tests
  Address review comments regarding ssl_client2 and ssl tests
  Remove mbedtls_ from the static function name
  Change docs according to review comments
  Change the verify function naming
  Fix ssl_client2 and ssl_server2 if !PLATFORM_C
  Correct placement of usage macro in ssl_client2
  Update version_features.c
  Remove trailing whitespace in test_suite_x509parse.function
  Update query_config.c
  Add ssl-opt.sh tests for trusted CA callbacks
  Only run X.509 CRT verification tests with CA callback tests if !CRL
  Minor fixes to CA callback tests
  Declare CA callback type even if feature is disabled
  Implement X.509 CRT verification using CA callback
  Add prototype for CRT verification with static and dynamic CA list
  Make use of CA callback if present when verifying peer CRT chain
  ...
This commit is contained in:
Jaeden Amero
2019-04-16 14:42:11 +01:00
13 changed files with 927 additions and 102 deletions

View File

@ -2818,6 +2818,11 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
if( ssl->conf->cert_req_ca_list == MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED )
{
/* NOTE: If trusted certificates are provisioned
* via a CA callback (configured through
* `mbedtls_ssl_conf_ca_cb()`, then the
* CertificateRequest is currently left empty. */
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
if( ssl->handshake->sni_ca_chain != NULL )
crt = ssl->handshake->sni_ca_chain;

View File

@ -6035,35 +6035,60 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl,
int ret = 0;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
ssl->transform_negotiate->ciphersuite_info;
mbedtls_x509_crt *ca_chain;
mbedtls_x509_crl *ca_crl;
int have_ca_chain = 0;
if( authmode == MBEDTLS_SSL_VERIFY_NONE )
return( 0 );
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
if( ssl->handshake->sni_ca_chain != NULL )
{
ca_chain = ssl->handshake->sni_ca_chain;
ca_crl = ssl->handshake->sni_ca_crl;
}
else
#endif
{
ca_chain = ssl->conf->ca_chain;
ca_crl = ssl->conf->ca_crl;
}
/*
* Main check: verify certificate
*/
ret = mbedtls_x509_crt_verify_restartable(
chain,
ca_chain, ca_crl,
ssl->conf->cert_profile,
ssl->hostname,
&ssl->session_negotiate->verify_result,
ssl->conf->f_vrfy, ssl->conf->p_vrfy, rs_ctx );
#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
if( ssl->conf->f_ca_cb != NULL )
{
((void) rs_ctx);
have_ca_chain = 1;
MBEDTLS_SSL_DEBUG_MSG( 3, ( "use CA callback for X.509 CRT verification" ) );
ret = mbedtls_x509_crt_verify_with_ca_cb(
chain,
ssl->conf->f_ca_cb,
ssl->conf->p_ca_cb,
ssl->conf->cert_profile,
ssl->hostname,
&ssl->session_negotiate->verify_result,
ssl->conf->f_vrfy, ssl->conf->p_vrfy );
}
else
#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
{
mbedtls_x509_crt *ca_chain;
mbedtls_x509_crl *ca_crl;
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
if( ssl->handshake->sni_ca_chain != NULL )
{
ca_chain = ssl->handshake->sni_ca_chain;
ca_crl = ssl->handshake->sni_ca_crl;
}
else
#endif
{
ca_chain = ssl->conf->ca_chain;
ca_crl = ssl->conf->ca_crl;
}
if( ca_chain != NULL )
have_ca_chain = 1;
ret = mbedtls_x509_crt_verify_restartable(
chain,
ca_chain, ca_crl,
ssl->conf->cert_profile,
ssl->hostname,
&ssl->session_negotiate->verify_result,
ssl->conf->f_vrfy, ssl->conf->p_vrfy, rs_ctx );
}
if( ret != 0 )
{
@ -6119,7 +6144,7 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl,
ret = 0;
}
if( ca_chain == NULL && authmode == MBEDTLS_SSL_VERIFY_REQUIRED )
if( have_ca_chain == 0 && authmode == MBEDTLS_SSL_VERIFY_REQUIRED )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no CA chain" ) );
ret = MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED;
@ -7875,7 +7900,29 @@ void mbedtls_ssl_conf_ca_chain( mbedtls_ssl_config *conf,
{
conf->ca_chain = ca_chain;
conf->ca_crl = ca_crl;
#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
/* mbedtls_ssl_conf_ca_chain() and mbedtls_ssl_conf_ca_cb()
* cannot be used together. */
conf->f_ca_cb = NULL;
conf->p_ca_cb = NULL;
#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
}
#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
void mbedtls_ssl_conf_ca_cb( mbedtls_ssl_config *conf,
mbedtls_x509_crt_ca_cb_t f_ca_cb,
void *p_ca_cb )
{
conf->f_ca_cb = f_ca_cb;
conf->p_ca_cb = p_ca_cb;
/* mbedtls_ssl_conf_ca_chain() and mbedtls_ssl_conf_ca_cb()
* cannot be used together. */
conf->ca_chain = NULL;
conf->ca_crl = NULL;
}
#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
#endif /* MBEDTLS_X509_CRT_PARSE_C */
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)

View File

@ -546,6 +546,9 @@ static const char *features[] = {
#if defined(MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
"MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION",
#endif /* MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION */
#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
"MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK",
#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
#if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
"MBEDTLS_X509_CHECK_KEY_USAGE",
#endif /* MBEDTLS_X509_CHECK_KEY_USAGE */

View File

@ -377,6 +377,10 @@ static void x509_crt_verify_chain_reset(
}
ver_chain->len = 0;
#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
ver_chain->trust_ca_cb_result = NULL;
#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
}
/*
@ -2319,6 +2323,8 @@ static int x509_crt_verify_chain(
mbedtls_x509_crt *crt,
mbedtls_x509_crt *trust_ca,
mbedtls_x509_crl *ca_crl,
mbedtls_x509_crt_ca_cb_t f_ca_cb,
void *p_ca_cb,
const mbedtls_x509_crt_profile *profile,
mbedtls_x509_crt_verify_chain *ver_chain,
mbedtls_x509_crt_restart_ctx *rs_ctx )
@ -2334,6 +2340,7 @@ static int x509_crt_verify_chain(
int child_is_trusted;
int signature_is_good;
unsigned self_cnt;
mbedtls_x509_crt *cur_trust_ca = NULL;
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
/* resume if we had an operation in progress */
@ -2393,8 +2400,32 @@ static int x509_crt_verify_chain(
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
find_parent:
#endif
/* Obtain list of potential trusted signers from CA callback,
* or use statically provided list. */
#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
if( f_ca_cb != NULL )
{
mbedtls_x509_crt_free( ver_chain->trust_ca_cb_result );
mbedtls_free( ver_chain->trust_ca_cb_result );
ver_chain->trust_ca_cb_result = NULL;
ret = f_ca_cb( p_ca_cb, child, &ver_chain->trust_ca_cb_result );
if( ret != 0 )
return( MBEDTLS_ERR_X509_FATAL_ERROR );
cur_trust_ca = ver_chain->trust_ca_cb_result;
}
else
#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
{
((void) f_ca_cb);
((void) p_ca_cb);
cur_trust_ca = trust_ca;
}
/* Look for a parent in trusted CAs or up the chain */
ret = x509_crt_find_parent( child, trust_ca, &parent,
ret = x509_crt_find_parent( child, cur_trust_ca, &parent,
&parent_is_trusted, &signature_is_good,
ver_chain->len - 1, self_cnt, rs_ctx );
@ -2549,36 +2580,6 @@ static int x509_crt_merge_flags_with_cb(
return( 0 );
}
/*
* Verify the certificate validity (default profile, not restartable)
*/
int mbedtls_x509_crt_verify( mbedtls_x509_crt *crt,
mbedtls_x509_crt *trust_ca,
mbedtls_x509_crl *ca_crl,
const char *cn, uint32_t *flags,
int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
void *p_vrfy )
{
return( mbedtls_x509_crt_verify_restartable( crt, trust_ca, ca_crl,
&mbedtls_x509_crt_profile_default, cn, flags,
f_vrfy, p_vrfy, NULL ) );
}
/*
* Verify the certificate validity (user-chosen profile, not restartable)
*/
int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt,
mbedtls_x509_crt *trust_ca,
mbedtls_x509_crl *ca_crl,
const mbedtls_x509_crt_profile *profile,
const char *cn, uint32_t *flags,
int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
void *p_vrfy )
{
return( mbedtls_x509_crt_verify_restartable( crt, trust_ca, ca_crl,
profile, cn, flags, f_vrfy, p_vrfy, NULL ) );
}
/*
* Verify the certificate validity, with profile, restartable version
*
@ -2588,10 +2589,19 @@ int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt,
* as that isn't done as part of chain building/verification currently
* - builds and verifies the chain
* - then calls the callback and merges the flags
*
* The parameters pairs `trust_ca`, `ca_crl` and `f_ca_cb`, `p_ca_cb`
* are mutually exclusive: If `f_ca_cb != NULL`, it will be used by the
* verification routine to search for trusted signers, and CRLs will
* be disabled. Otherwise, `trust_ca` will be used as the static list
* of trusted signers, and `ca_crl` will be use as the static list
* of CRLs.
*/
int mbedtls_x509_crt_verify_restartable( mbedtls_x509_crt *crt,
static int x509_crt_verify_restartable_ca_cb( mbedtls_x509_crt *crt,
mbedtls_x509_crt *trust_ca,
mbedtls_x509_crl *ca_crl,
mbedtls_x509_crt_ca_cb_t f_ca_cb,
void *p_ca_cb,
const mbedtls_x509_crt_profile *profile,
const char *cn, uint32_t *flags,
int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
@ -2627,7 +2637,8 @@ int mbedtls_x509_crt_verify_restartable( mbedtls_x509_crt *crt,
ee_flags |= MBEDTLS_X509_BADCERT_BAD_KEY;
/* Check the chain */
ret = x509_crt_verify_chain( crt, trust_ca, ca_crl, profile,
ret = x509_crt_verify_chain( crt, trust_ca, ca_crl,
f_ca_cb, p_ca_cb, profile,
&ver_chain, rs_ctx );
if( ret != 0 )
@ -2640,6 +2651,13 @@ int mbedtls_x509_crt_verify_restartable( mbedtls_x509_crt *crt,
ret = x509_crt_merge_flags_with_cb( flags, &ver_chain, f_vrfy, p_vrfy );
exit:
#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
mbedtls_x509_crt_free( ver_chain.trust_ca_cb_result );
mbedtls_free( ver_chain.trust_ca_cb_result );
ver_chain.trust_ca_cb_result = NULL;
#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
if( rs_ctx != NULL && ret != MBEDTLS_ERR_ECP_IN_PROGRESS )
mbedtls_x509_crt_restart_free( rs_ctx );
@ -2663,6 +2681,77 @@ exit:
return( 0 );
}
/*
* Verify the certificate validity (default profile, not restartable)
*/
int mbedtls_x509_crt_verify( mbedtls_x509_crt *crt,
mbedtls_x509_crt *trust_ca,
mbedtls_x509_crl *ca_crl,
const char *cn, uint32_t *flags,
int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
void *p_vrfy )
{
return( x509_crt_verify_restartable_ca_cb( crt, trust_ca, ca_crl,
NULL, NULL,
&mbedtls_x509_crt_profile_default,
cn, flags,
f_vrfy, p_vrfy, NULL ) );
}
/*
* Verify the certificate validity (user-chosen profile, not restartable)
*/
int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt,
mbedtls_x509_crt *trust_ca,
mbedtls_x509_crl *ca_crl,
const mbedtls_x509_crt_profile *profile,
const char *cn, uint32_t *flags,
int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
void *p_vrfy )
{
return( x509_crt_verify_restartable_ca_cb( crt, trust_ca, ca_crl,
NULL, NULL,
profile, cn, flags,
f_vrfy, p_vrfy, NULL ) );
}
#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
/*
* Verify the certificate validity (user-chosen profile, CA callback,
* not restartable).
*/
int mbedtls_x509_crt_verify_with_ca_cb( mbedtls_x509_crt *crt,
mbedtls_x509_crt_ca_cb_t f_ca_cb,
void *p_ca_cb,
const mbedtls_x509_crt_profile *profile,
const char *cn, uint32_t *flags,
int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
void *p_vrfy )
{
return( x509_crt_verify_restartable_ca_cb( crt, NULL, NULL,
f_ca_cb, p_ca_cb,
profile, cn, flags,
f_vrfy, p_vrfy, NULL ) );
}
#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
int mbedtls_x509_crt_verify_restartable( mbedtls_x509_crt *crt,
mbedtls_x509_crt *trust_ca,
mbedtls_x509_crl *ca_crl,
const mbedtls_x509_crt_profile *profile,
const char *cn, uint32_t *flags,
int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
void *p_vrfy,
mbedtls_x509_crt_restart_ctx *rs_ctx )
{
return( x509_crt_verify_restartable_ca_cb( crt, trust_ca, ca_crl,
NULL, NULL,
profile, cn, flags,
f_vrfy, p_vrfy, rs_ctx ) );
}
/*
* Initialize a certificate chain
*/