Merge remote-tracking branch 'tls/development' into development

Merge Mbed TLS at f790a6cbee into Mbed Crypto.

Resolve conflicts by performing the following:
    - Reject changes to README.md
    - Don't add crypto as a submodule
    - Remove test/ssl_cert_test from programs/Makefile
    - Add cipher.nist_kw test to tests/CMakeLists.txt
    - Reject removal of crypto-specific all.sh tests
    - Reject update to SSL-specific portion of component_test_valgrind
      in all.sh
    - Reject addition of ssl-opt.sh testing to component_test_m32_o1 in
      all.sh

* tls/development: (87 commits)
  Call mbedtls_cipher_free() to reset a cipher context
  Don't call mbedtls_cipher_setkey twice
  Update crypto submodule
  Minor fixes in get certificate policies oid test
  Add certificate policy oid x509 extension
  cpp_dummy_build: Add missing header psa_util.h
  Clarify comment mangled by an earlier refactoring
  Add an "out-of-box" component
  Run ssl-opt.sh on 32-bit runtime
  Don't use debug level 1 for informational messages
  Skip uncritical unsupported extensions
  Give credit to OSS-Fuzz for #2404
  all.sh: remove component_test_new_ecdh_context
  Remove crypto-only related components from all.sh
  Remove ssl_cert_test sample app
  Make CRT callback tests more robust
  Rename constant in client2.c
  Document and test flags in x509_verify
  Fix style issues and a typo
  Fix a rebase error
  ...
This commit is contained in:
Jaeden Amero 2019-04-17 12:12:24 +01:00
commit 521dbc67da
46 changed files with 1558 additions and 1189 deletions

View file

@ -582,15 +582,20 @@ int mbedtls_mpi_write_string( const mbedtls_mpi *X, int radix,
if( radix < 2 || radix > 16 )
return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
n = mbedtls_mpi_bitlen( X );
if( radix >= 4 ) n >>= 1;
if( radix >= 16 ) n >>= 1;
/*
* Round up the buffer length to an even value to ensure that there is
* enough room for hexadecimal values that can be represented in an odd
* number of digits.
*/
n += 3 + ( ( n + 1 ) & 1 );
n = mbedtls_mpi_bitlen( X ); /* Number of bits necessary to present `n`. */
if( radix >= 4 ) n >>= 1; /* Number of 4-adic digits necessary to present
* `n`. If radix > 4, this might be a strict
* overapproximation of the number of
* radix-adic digits needed to present `n`. */
if( radix >= 16 ) n >>= 1; /* Number of hexadecimal digits necessary to
* present `n`. */
n += 1; /* Terminating null byte */
n += 1; /* Compensate for the divisions above, which round down `n`
* in case it's not even. */
n += 1; /* Potential '-'-sign. */
n += ( n & 1 ); /* Make n even to have enough space for hexadecimal writing,
* which always uses an even number of hex-digits. */
if( buflen < n )
{
@ -602,7 +607,10 @@ int mbedtls_mpi_write_string( const mbedtls_mpi *X, int radix,
mbedtls_mpi_init( &T );
if( X->s == -1 )
{
*p++ = '-';
buflen--;
}
if( radix == 16 )
{

View file

@ -63,6 +63,10 @@
#include "mbedtls/psa_util.h"
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_NIST_KW_C)
#include "mbedtls/nist_kw.h"
#endif
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
@ -1385,6 +1389,22 @@ int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx,
ilen, iv, ad, ad_len, input, output, tag ) );
}
#endif /* MBEDTLS_CHACHAPOLY_C */
#if defined(MBEDTLS_NIST_KW_C)
if( MBEDTLS_MODE_KW == ctx->cipher_info->mode ||
MBEDTLS_MODE_KWP == ctx->cipher_info->mode )
{
mbedtls_nist_kw_mode_t mode = ( MBEDTLS_MODE_KW == ctx->cipher_info->mode ) ?
MBEDTLS_KW_MODE_KW : MBEDTLS_KW_MODE_KWP;
/* There is no iv, tag or ad associated with KW and KWP, these length should be 0 */
if( iv_len != 0 || tag_len != 0 || ad_len != 0 )
{
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
}
return( mbedtls_nist_kw_wrap( ctx->cipher_ctx, mode, input, ilen, output, olen, SIZE_MAX ) );
}
#endif /* MBEDTLS_NIST_KW_C */
return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
}
@ -1494,6 +1514,22 @@ int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx,
return( ret );
}
#endif /* MBEDTLS_CHACHAPOLY_C */
#if defined(MBEDTLS_NIST_KW_C)
if( MBEDTLS_MODE_KW == ctx->cipher_info->mode ||
MBEDTLS_MODE_KWP == ctx->cipher_info->mode )
{
mbedtls_nist_kw_mode_t mode = ( MBEDTLS_MODE_KW == ctx->cipher_info->mode ) ?
MBEDTLS_KW_MODE_KW : MBEDTLS_KW_MODE_KWP;
/* There is no iv, tag or ad associated with KW and KWP, these length should be 0 */
if( iv_len != 0 || tag_len != 0 || ad_len != 0 )
{
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
}
return( mbedtls_nist_kw_unwrap( ctx->cipher_ctx, mode, input, ilen, output, olen, SIZE_MAX ) );
}
#endif /* MBEDTLS_NIST_KW_C */
return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
}

View file

@ -73,6 +73,10 @@
#include "mbedtls/ccm.h"
#endif
#if defined(MBEDTLS_NIST_KW_C)
#include "mbedtls/nist_kw.h"
#endif
#if defined(MBEDTLS_CIPHER_NULL_CIPHER)
#include <string.h>
#endif
@ -2119,6 +2123,131 @@ static const mbedtls_cipher_info_t null_cipher_info = {
};
#endif /* defined(MBEDTLS_CIPHER_NULL_CIPHER) */
#if defined(MBEDTLS_NIST_KW_C)
static void *kw_ctx_alloc( void )
{
void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_nist_kw_context ) );
if( ctx != NULL )
mbedtls_nist_kw_init( (mbedtls_nist_kw_context *) ctx );
return( ctx );
}
static void kw_ctx_free( void *ctx )
{
mbedtls_nist_kw_free( ctx );
mbedtls_free( ctx );
}
static int kw_aes_setkey_wrap( void *ctx, const unsigned char *key,
unsigned int key_bitlen )
{
return mbedtls_nist_kw_setkey( (mbedtls_nist_kw_context *) ctx,
MBEDTLS_CIPHER_ID_AES, key, key_bitlen, 1 );
}
static int kw_aes_setkey_unwrap( void *ctx, const unsigned char *key,
unsigned int key_bitlen )
{
return mbedtls_nist_kw_setkey( (mbedtls_nist_kw_context *) ctx,
MBEDTLS_CIPHER_ID_AES, key, key_bitlen, 0 );
}
static const mbedtls_cipher_base_t kw_aes_info = {
MBEDTLS_CIPHER_ID_AES,
NULL,
#if defined(MBEDTLS_CIPHER_MODE_CBC)
NULL,
#endif
#if defined(MBEDTLS_CIPHER_MODE_CFB)
NULL,
#endif
#if defined(MBEDTLS_CIPHER_MODE_OFB)
NULL,
#endif
#if defined(MBEDTLS_CIPHER_MODE_CTR)
NULL,
#endif
#if defined(MBEDTLS_CIPHER_MODE_XTS)
NULL,
#endif
#if defined(MBEDTLS_CIPHER_MODE_STREAM)
NULL,
#endif
kw_aes_setkey_wrap,
kw_aes_setkey_unwrap,
kw_ctx_alloc,
kw_ctx_free,
};
static const mbedtls_cipher_info_t aes_128_nist_kw_info = {
MBEDTLS_CIPHER_AES_128_KW,
MBEDTLS_MODE_KW,
128,
"AES-128-KW",
0,
0,
16,
&kw_aes_info
};
static const mbedtls_cipher_info_t aes_192_nist_kw_info = {
MBEDTLS_CIPHER_AES_192_KW,
MBEDTLS_MODE_KW,
192,
"AES-192-KW",
0,
0,
16,
&kw_aes_info
};
static const mbedtls_cipher_info_t aes_256_nist_kw_info = {
MBEDTLS_CIPHER_AES_256_KW,
MBEDTLS_MODE_KW,
256,
"AES-256-KW",
0,
0,
16,
&kw_aes_info
};
static const mbedtls_cipher_info_t aes_128_nist_kwp_info = {
MBEDTLS_CIPHER_AES_128_KWP,
MBEDTLS_MODE_KWP,
128,
"AES-128-KWP",
0,
0,
16,
&kw_aes_info
};
static const mbedtls_cipher_info_t aes_192_nist_kwp_info = {
MBEDTLS_CIPHER_AES_192_KWP,
MBEDTLS_MODE_KWP,
192,
"AES-192-KWP",
0,
0,
16,
&kw_aes_info
};
static const mbedtls_cipher_info_t aes_256_nist_kwp_info = {
MBEDTLS_CIPHER_AES_256_KWP,
MBEDTLS_MODE_KWP,
256,
"AES-256-KWP",
0,
0,
16,
&kw_aes_info
};
#endif /* MBEDTLS_NIST_KW_C */
const mbedtls_cipher_definition_t mbedtls_cipher_definitions[] =
{
#if defined(MBEDTLS_AES_C)
@ -2259,6 +2388,15 @@ const mbedtls_cipher_definition_t mbedtls_cipher_definitions[] =
{ MBEDTLS_CIPHER_CHACHA20_POLY1305, &chachapoly_info },
#endif
#if defined(MBEDTLS_NIST_KW_C)
{ MBEDTLS_CIPHER_AES_128_KW, &aes_128_nist_kw_info },
{ MBEDTLS_CIPHER_AES_192_KW, &aes_192_nist_kw_info },
{ MBEDTLS_CIPHER_AES_256_KW, &aes_256_nist_kw_info },
{ MBEDTLS_CIPHER_AES_128_KWP, &aes_128_nist_kwp_info },
{ MBEDTLS_CIPHER_AES_192_KWP, &aes_192_nist_kwp_info },
{ MBEDTLS_CIPHER_AES_256_KWP, &aes_256_nist_kwp_info },
#endif
#if defined(MBEDTLS_CIPHER_NULL_CIPHER)
{ MBEDTLS_CIPHER_NULL, &null_cipher_info },
#endif /* MBEDTLS_CIPHER_NULL_CIPHER */

View file

@ -254,25 +254,29 @@ typedef struct {
static const oid_x509_ext_t oid_x509_ext[] =
{
{
{ ADD_LEN( MBEDTLS_OID_BASIC_CONSTRAINTS ), "id-ce-basicConstraints", "Basic Constraints" },
{ ADD_LEN( MBEDTLS_OID_BASIC_CONSTRAINTS ), "id-ce-basicConstraints", "Basic Constraints" },
MBEDTLS_OID_X509_EXT_BASIC_CONSTRAINTS,
},
{
{ ADD_LEN( MBEDTLS_OID_KEY_USAGE ), "id-ce-keyUsage", "Key Usage" },
{ ADD_LEN( MBEDTLS_OID_KEY_USAGE ), "id-ce-keyUsage", "Key Usage" },
MBEDTLS_OID_X509_EXT_KEY_USAGE,
},
{
{ ADD_LEN( MBEDTLS_OID_EXTENDED_KEY_USAGE ), "id-ce-extKeyUsage", "Extended Key Usage" },
{ ADD_LEN( MBEDTLS_OID_EXTENDED_KEY_USAGE ), "id-ce-extKeyUsage", "Extended Key Usage" },
MBEDTLS_OID_X509_EXT_EXTENDED_KEY_USAGE,
},
{
{ ADD_LEN( MBEDTLS_OID_SUBJECT_ALT_NAME ), "id-ce-subjectAltName", "Subject Alt Name" },
{ ADD_LEN( MBEDTLS_OID_SUBJECT_ALT_NAME ), "id-ce-subjectAltName", "Subject Alt Name" },
MBEDTLS_OID_X509_EXT_SUBJECT_ALT_NAME,
},
{
{ ADD_LEN( MBEDTLS_OID_NS_CERT_TYPE ), "id-netscape-certtype", "Netscape Certificate Type" },
{ ADD_LEN( MBEDTLS_OID_NS_CERT_TYPE ), "id-netscape-certtype", "Netscape Certificate Type" },
MBEDTLS_OID_X509_EXT_NS_CERT_TYPE,
},
{
{ ADD_LEN( MBEDTLS_OID_CERTIFICATE_POLICIES ), "id-ce-certificatePolicies", "Certificate Policies" },
MBEDTLS_OID_X509_EXT_CERTIFICATE_POLICIES,
},
{
{ NULL, 0, NULL, NULL },
0,
@ -284,12 +288,13 @@ FN_OID_GET_ATTR1(mbedtls_oid_get_x509_ext_type, oid_x509_ext_t, x509_ext, int, e
static const mbedtls_oid_descriptor_t oid_ext_key_usage[] =
{
{ ADD_LEN( MBEDTLS_OID_SERVER_AUTH ), "id-kp-serverAuth", "TLS Web Server Authentication" },
{ ADD_LEN( MBEDTLS_OID_CLIENT_AUTH ), "id-kp-clientAuth", "TLS Web Client Authentication" },
{ ADD_LEN( MBEDTLS_OID_CODE_SIGNING ), "id-kp-codeSigning", "Code Signing" },
{ ADD_LEN( MBEDTLS_OID_EMAIL_PROTECTION ), "id-kp-emailProtection", "E-mail Protection" },
{ ADD_LEN( MBEDTLS_OID_TIME_STAMPING ), "id-kp-timeStamping", "Time Stamping" },
{ ADD_LEN( MBEDTLS_OID_OCSP_SIGNING ), "id-kp-OCSPSigning", "OCSP Signing" },
{ ADD_LEN( MBEDTLS_OID_SERVER_AUTH ), "id-kp-serverAuth", "TLS Web Server Authentication" },
{ ADD_LEN( MBEDTLS_OID_CLIENT_AUTH ), "id-kp-clientAuth", "TLS Web Client Authentication" },
{ ADD_LEN( MBEDTLS_OID_CODE_SIGNING ), "id-kp-codeSigning", "Code Signing" },
{ ADD_LEN( MBEDTLS_OID_EMAIL_PROTECTION ), "id-kp-emailProtection", "E-mail Protection" },
{ ADD_LEN( MBEDTLS_OID_TIME_STAMPING ), "id-kp-timeStamping", "Time Stamping" },
{ ADD_LEN( MBEDTLS_OID_OCSP_SIGNING ), "id-kp-OCSPSigning", "OCSP Signing" },
{ ADD_LEN( MBEDTLS_OID_WISUN_FAN ), "id-kp-wisun-fan-device", "Wi-SUN Alliance Field Area Network (FAN)" },
{ NULL, 0, NULL, NULL },
};

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

@ -1238,7 +1238,7 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
if( ret == 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "Successfully setup PSA-based encryption cipher context" ) );
MBEDTLS_SSL_DEBUG_MSG( 3, ( "Successfully setup PSA-based encryption cipher context" ) );
psa_fallthrough = 0;
}
else
@ -1281,7 +1281,7 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
if( ret == 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "Successfully setup PSA-based decryption cipher context" ) );
MBEDTLS_SSL_DEBUG_MSG( 3, ( "Successfully setup PSA-based decryption cipher context" ) );
psa_fallthrough = 0;
}
else
@ -6035,35 +6035,76 @@ 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;
int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *);
void *p_vrfy;
if( authmode == MBEDTLS_SSL_VERIFY_NONE )
return( 0 );
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
if( ssl->handshake->sni_ca_chain != NULL )
if( ssl->f_vrfy != NULL )
{
ca_chain = ssl->handshake->sni_ca_chain;
ca_crl = ssl->handshake->sni_ca_crl;
MBEDTLS_SSL_DEBUG_MSG( 3, ( "Use context-specific verification callback" ) );
f_vrfy = ssl->f_vrfy;
p_vrfy = ssl->p_vrfy;
}
else
#endif
{
ca_chain = ssl->conf->ca_chain;
ca_crl = ssl->conf->ca_crl;
MBEDTLS_SSL_DEBUG_MSG( 3, ( "Use configuration-specific verification callback" ) );
f_vrfy = ssl->conf->f_vrfy;
p_vrfy = ssl->conf->p_vrfy;
}
/*
* 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,
f_vrfy, 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,
f_vrfy, p_vrfy, rs_ctx );
}
if( ret != 0 )
{
@ -6119,7 +6160,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 +7916,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)
@ -7902,6 +7965,16 @@ void mbedtls_ssl_set_hs_authmode( mbedtls_ssl_context *ssl,
}
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
#if defined(MBEDTLS_X509_CRT_PARSE_C)
void mbedtls_ssl_set_verify( mbedtls_ssl_context *ssl,
int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
void *p_vrfy )
{
ssl->f_vrfy = f_vrfy;
ssl->p_vrfy = p_vrfy;
}
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
/*
* Set EC J-PAKE password for current handshake
@ -10444,7 +10517,7 @@ int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl,
psa_hash_operation_t hash_operation = PSA_HASH_OPERATION_INIT;
psa_algorithm_t hash_alg = mbedtls_psa_translate_md( md_alg );
MBEDTLS_SSL_DEBUG_MSG( 1, ( "Perform PSA-based computation of digest of ServerKeyExchange" ) );
MBEDTLS_SSL_DEBUG_MSG( 3, ( "Perform PSA-based computation of digest of ServerKeyExchange" ) );
if( ( status = psa_hash_setup( &hash_operation,
hash_alg ) ) != PSA_SUCCESS )
@ -10507,7 +10580,7 @@ int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl,
const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg );
*hashlen = mbedtls_md_get_size( md_info );
MBEDTLS_SSL_DEBUG_MSG( 1, ( "Perform mbedtls-based computation of digest of ServerKeyExchange" ) );
MBEDTLS_SSL_DEBUG_MSG( 3, ( "Perform mbedtls-based computation of digest of ServerKeyExchange" ) );
mbedtls_md_init( &ctx );

View file

@ -549,6 +549,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

@ -1001,8 +1001,8 @@ int mbedtls_x509_time_is_future( const mbedtls_x509_time *from )
*/
int mbedtls_x509_self_test( int verbose )
{
int ret = 0;
#if defined(MBEDTLS_CERTS_C) && defined(MBEDTLS_SHA256_C)
int ret;
uint32_t flags;
mbedtls_x509_crt cacert;
mbedtls_x509_crt clicert;
@ -1010,6 +1010,7 @@ int mbedtls_x509_self_test( int verbose )
if( verbose != 0 )
mbedtls_printf( " X.509 certificate load: " );
mbedtls_x509_crt_init( &cacert );
mbedtls_x509_crt_init( &clicert );
ret = mbedtls_x509_crt_parse( &clicert, (const unsigned char *) mbedtls_test_cli_crt,
@ -1019,11 +1020,9 @@ int mbedtls_x509_self_test( int verbose )
if( verbose != 0 )
mbedtls_printf( "failed\n" );
return( ret );
goto cleanup;
}
mbedtls_x509_crt_init( &cacert );
ret = mbedtls_x509_crt_parse( &cacert, (const unsigned char *) mbedtls_test_ca_crt,
mbedtls_test_ca_crt_len );
if( ret != 0 )
@ -1031,7 +1030,7 @@ int mbedtls_x509_self_test( int verbose )
if( verbose != 0 )
mbedtls_printf( "failed\n" );
return( ret );
goto cleanup;
}
if( verbose != 0 )
@ -1043,20 +1042,19 @@ int mbedtls_x509_self_test( int verbose )
if( verbose != 0 )
mbedtls_printf( "failed\n" );
return( ret );
goto cleanup;
}
if( verbose != 0 )
mbedtls_printf( "passed\n\n");
cleanup:
mbedtls_x509_crt_free( &cacert );
mbedtls_x509_crt_free( &clicert );
return( 0 );
#else
((void) verbose);
return( 0 );
#endif /* MBEDTLS_CERTS_C && MBEDTLS_SHA1_C */
return( ret );
}
#endif /* MBEDTLS_SELF_TEST */

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 */
}
/*
@ -820,7 +824,17 @@ static int x509_get_crt_ext( unsigned char **p,
break;
default:
return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE );
/*
* If this is a non-critical extension, which the oid layer
* supports, but there isn't an x509 parser for it,
* skip the extension.
*/
#if !defined(MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
if( is_critical )
return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE );
else
#endif
*p = end_ext_octet;
}
}
@ -2309,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 )
@ -2324,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 */
@ -2383,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 );
@ -2539,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
*
@ -2578,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 *),
@ -2617,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 )
@ -2630,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 );
@ -2653,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
*/