Add parsing cache to mbedtls_x509_crt

This commit replaces the dummy implementation of the CRT acquire/release
framework by a cache-based implementation which remembers frame and PK
associated to a CRT across multiple `acquire/release` pairs.
This commit is contained in:
Hanno Becker 2019-02-25 13:50:14 +00:00
parent 73cd8d8adc
commit b6c39fca5c
2 changed files with 302 additions and 110 deletions

View file

@ -32,6 +32,7 @@
#include "x509.h" #include "x509.h"
#include "x509_crl.h" #include "x509_crl.h"
#include "threading.h"
/** /**
* \addtogroup x509_module * \addtogroup x509_module
@ -99,6 +100,22 @@ typedef struct mbedtls_x509_crt_frame
} mbedtls_x509_crt_frame; } mbedtls_x509_crt_frame;
/* This is an internal structure used for caching parsed data from an X.509 CRT.
*
* This structure may change at any time, and it is discouraged
* to access it directly.
*/
typedef struct mbedtls_x509_crt_cache
{
#if defined(MBEDTLS_THREADING_C)
mbedtls_threading_mutex_t frame_mutex;
mbedtls_threading_mutex_t pk_mutex;
#endif
mbedtls_x509_buf_raw pk_raw;
mbedtls_x509_crt_frame *frame;
mbedtls_pk_context *pk;
} mbedtls_x509_crt_cache;
/** /**
* Container for an X.509 certificate. The certificate may be chained. * Container for an X.509 certificate. The certificate may be chained.
*/ */
@ -150,6 +167,8 @@ typedef struct mbedtls_x509_crt
mbedtls_pk_type_t sig_pk; /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. MBEDTLS_PK_RSA */ mbedtls_pk_type_t sig_pk; /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. MBEDTLS_PK_RSA */
void *sig_opts; /**< Signature options to be passed to mbedtls_pk_verify_ext(), e.g. for RSASSA-PSS */ void *sig_opts; /**< Signature options to be passed to mbedtls_pk_verify_ext(), e.g. for RSASSA-PSS */
mbedtls_x509_crt_cache *cache; /**< Internal parsing cache. */
struct mbedtls_x509_crt *next; /**< Next certificate in the CA-chain. */ struct mbedtls_x509_crt *next; /**< Next certificate in the CA-chain. */
} }
mbedtls_x509_crt; mbedtls_x509_crt;
@ -643,6 +662,127 @@ void mbedtls_x509_crt_restart_init( mbedtls_x509_crt_restart_ctx *ctx );
*/ */
void mbedtls_x509_crt_restart_free( mbedtls_x509_crt_restart_ctx *ctx ); void mbedtls_x509_crt_restart_free( mbedtls_x509_crt_restart_ctx *ctx );
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
/**
* \brief Flush internal X.509 CRT parsing cache, if present.
*
* \param crt The CRT structure whose cache to flush.
*
* \note Calling this function frequently reduces RAM usage
* at the cost of performance.
*
* \return \c 0 on success.
* \return A negative error code on failure.
*/
int mbedtls_x509_crt_flush_cache( mbedtls_x509_crt const *crt );
/* Internal X.509 CRT cache handling functions.
* They are not part of the public API and may change
* at any time. */
int mbedtls_x509_crt_cache_provide_frame( mbedtls_x509_crt const *crt );
int mbedtls_x509_crt_cache_provide_pk( mbedtls_x509_crt const *crt );
static inline int mbedtls_x509_crt_cache_frame_set(
mbedtls_x509_crt_cache *cache )
{
return( cache->frame != NULL );
}
static inline mbedtls_x509_crt_frame* mbedtls_x509_crt_cache_get_frame(
mbedtls_x509_crt_cache *cache )
{
return( cache->frame );
}
static inline int mbedtls_x509_crt_cache_pk_set(
mbedtls_x509_crt_cache *cache )
{
return( cache->pk != NULL );
}
static inline mbedtls_pk_context* mbedtls_x509_crt_cache_get_pk(
mbedtls_x509_crt_cache *cache )
{
return( cache->pk );
}
static inline int mbedtls_x509_crt_frame_acquire( mbedtls_x509_crt const *crt,
mbedtls_x509_crt_frame **frame_ptr )
{
#if defined(MBEDTLS_THREADING_C)
if( mbedtls_mutex_lock( &crt->cache->frame_mutex ) != 0 )
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
#endif
if( !mbedtls_x509_crt_cache_frame_set( crt->cache ) )
{
int ret;
ret = mbedtls_x509_crt_cache_provide_frame( crt );
if( ret != 0 )
{
#if defined(MBEDTLS_THREADING_C)
if( mbedtls_mutex_unlock( &crt->cache->frame_mutex ) != 0 )
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
#endif
return( ret );
}
}
*frame_ptr = mbedtls_x509_crt_cache_get_frame( crt->cache );
return( 0 );
}
static inline void mbedtls_x509_crt_frame_release(
mbedtls_x509_crt const *crt,
mbedtls_x509_crt_frame *frame )
{
((void) frame);
((void) crt);
#if defined(MBEDTLS_THREADING_C)
mbedtls_mutex_unlock( &crt->cache->frame_mutex );
#endif
}
static inline int mbedtls_x509_crt_pk_acquire( mbedtls_x509_crt *crt,
mbedtls_pk_context **pk_ptr )
{
#if defined(MBEDTLS_THREADING_C)
if( mbedtls_mutex_lock( &crt->cache->pk_mutex ) != 0 )
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
#endif
if( !mbedtls_x509_crt_cache_pk_set( crt->cache ) )
{
int ret;
ret = mbedtls_x509_crt_cache_provide_pk( crt );
if( ret != 0 )
{
#if defined(MBEDTLS_THREADING_C)
if( mbedtls_mutex_unlock( &crt->cache->pk_mutex ) != 0 )
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
#endif
return( ret );
}
}
*pk_ptr = mbedtls_x509_crt_cache_get_pk( crt->cache );
return( 0 );
}
static inline void mbedtls_x509_crt_pk_release( mbedtls_x509_crt *crt,
mbedtls_pk_context *pk )
{
((void) pk);
((void) crt);
#if defined(MBEDTLS_THREADING_C)
mbedtls_mutex_unlock( &crt->cache->pk_mutex );
#endif
}
#endif /* MBEDTLS_X509_CRT_PARSE_C */ #endif /* MBEDTLS_X509_CRT_PARSE_C */
/* \} name */ /* \} name */

View file

@ -93,55 +93,91 @@ static int x509_crt_ext_key_usage_from_frame( mbedtls_x509_crt_frame *frame,
static void x509_free_sequence( mbedtls_x509_sequence *seq ); static void x509_free_sequence( mbedtls_x509_sequence *seq );
static void x509_free_name( mbedtls_x509_name *name ); static void x509_free_name( mbedtls_x509_name *name );
static int x509_crt_pk_acquire( mbedtls_x509_crt *crt, int mbedtls_x509_crt_cache_provide_frame( mbedtls_x509_crt const *crt )
mbedtls_pk_context **pk );
static int x509_crt_frame_acquire( mbedtls_x509_crt const *crt,
mbedtls_x509_crt_frame **frame );
static void x509_crt_pk_release( mbedtls_x509_crt *crt,
mbedtls_pk_context *pk );
static void x509_crt_frame_release( mbedtls_x509_crt *crt,
mbedtls_pk_context *pk );
static int x509_crt_frame_acquire( mbedtls_x509_crt const *crt,
mbedtls_x509_crt_frame **frame_ptr )
{ {
int ret; mbedtls_x509_crt_cache *cache = crt->cache;
mbedtls_x509_crt_frame *frame; mbedtls_x509_crt_frame *frame;
frame = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt_frame ) ); frame = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt_frame ) );
if( frame == NULL ) if( frame == NULL )
return( MBEDTLS_ERR_X509_ALLOC_FAILED ); return( MBEDTLS_ERR_X509_ALLOC_FAILED );
cache->frame = frame;
ret = x509_crt_parse_frame( crt->raw.p, crt->raw.p + crt->raw.len, return( x509_crt_parse_frame( crt->raw.p,
frame ); crt->raw.p + crt->raw.len,
if( ret != 0 ) frame ) );
return( ret ); }
*frame_ptr = frame; int mbedtls_x509_crt_cache_provide_pk( mbedtls_x509_crt const *crt )
{
mbedtls_x509_crt_cache *cache = crt->cache;
mbedtls_pk_context *pk;
pk = mbedtls_calloc( 1, sizeof( mbedtls_pk_context ) );
if( pk == NULL )
return( MBEDTLS_ERR_X509_ALLOC_FAILED );
*pk = crt->pk;
cache->pk = pk;
return( 0 ); return( 0 );
} }
static void x509_crt_frame_release( mbedtls_x509_crt const *crt, static void x509_crt_cache_init( mbedtls_x509_crt_cache *cache )
mbedtls_x509_crt_frame *frame )
{ {
((void) crt); memset( cache, 0, sizeof( *cache ) );
if( frame == NULL ) #if defined(MBEDTLS_THREADING_C)
mbedtls_mutex_init( &cache->frame_mutex );
mbedtls_mutex_init( &cache->pk_mutex );
#endif
}
static void x509_crt_cache_clear_pk( mbedtls_x509_crt_cache *cache )
{
/* The cache holds a shallow copy of the PK context
* in the legacy struct, so don't free PK context. */
mbedtls_free( cache->pk );
cache->pk = NULL;
}
static void x509_crt_cache_clear_frame( mbedtls_x509_crt_cache *cache )
{
mbedtls_free( cache->frame );
cache->frame = NULL;
}
static void x509_crt_cache_free( mbedtls_x509_crt_cache *cache )
{
if( cache == NULL )
return; return;
mbedtls_free( frame );
} #if defined(MBEDTLS_THREADING_C)
static int x509_crt_pk_acquire( mbedtls_x509_crt *crt, mbedtls_mutex_free( &cache->frame_mutex );
mbedtls_pk_context **pk ) mbedtls_mutex_free( &cache->pk_mutex );
{ #endif
*pk = &crt->pk;
return( 0 ); x509_crt_cache_clear_frame( cache );
x509_crt_cache_clear_pk( cache );
memset( cache, 0, sizeof( *cache ) );
} }
static void x509_crt_pk_release( mbedtls_x509_crt *crt, int mbedtls_x509_crt_flush_cache( mbedtls_x509_crt const *crt )
mbedtls_pk_context *pk )
{ {
((void) crt); #if defined(MBEDTLS_THREADING_C)
((void) pk); if( mbedtls_mutex_lock( &crt->cache->frame_mutex ) != 0 )
return; return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
if( mbedtls_mutex_lock( &crt->cache->pk_mutex ) != 0 )
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
#endif
x509_crt_cache_clear_frame( crt->cache );
x509_crt_cache_clear_pk( crt->cache );
#if defined(MBEDTLS_THREADING_C)
if( mbedtls_mutex_unlock( &crt->cache->frame_mutex ) != 0 )
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
if( mbedtls_mutex_unlock( &crt->cache->pk_mutex ) != 0 )
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
#endif
return( 0 );
} }
/* /*
@ -1163,7 +1199,8 @@ static int x509_crt_parse_der_core( mbedtls_x509_crt *crt,
int make_copy ) int make_copy )
{ {
int ret; int ret;
mbedtls_x509_crt_frame frame; mbedtls_x509_crt_frame *frame;
mbedtls_x509_crt_cache *cache;
if( crt == NULL || buf == NULL ) if( crt == NULL || buf == NULL )
return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
@ -1185,19 +1222,21 @@ static int x509_crt_parse_der_core( mbedtls_x509_crt *crt,
crt->own_buffer = 1; crt->own_buffer = 1;
} }
/* Parse CRT frame. cache = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt_cache ) );
* This omits: if( cache == NULL )
* - Issuer, Subject {
* - ExtKeyUsage, SubjectAltNames, ret = MBEDTLS_ERR_X509_ALLOC_FAILED;
* - Time goto exit;
* - PK }
*/ crt->cache = cache;
ret = x509_crt_parse_frame( crt->raw.p, x509_crt_cache_init( cache );
crt->raw.p + crt->raw.len,
&frame ); ret = mbedtls_x509_crt_cache_provide_frame( crt );
if( ret != 0 ) if( ret != 0 )
goto exit; goto exit;
frame = mbedtls_x509_crt_cache_get_frame( crt->cache );
/* Currently, we accept DER encoded CRTs with trailing garbage /* Currently, we accept DER encoded CRTs with trailing garbage
* and promise to not account for the garbage in the `raw` field. * and promise to not account for the garbage in the `raw` field.
* *
@ -1207,38 +1246,40 @@ static int x509_crt_parse_der_core( mbedtls_x509_crt *crt,
* need the size, and the garbage data doesn't need zeroization. */ * need the size, and the garbage data doesn't need zeroization. */
crt->raw.len = frame->raw.len; crt->raw.len = frame->raw.len;
cache->pk_raw = frame->pubkey_raw;
/* Copy frame to legacy CRT structure -- that's inefficient, but if /* Copy frame to legacy CRT structure -- that's inefficient, but if
* memory matters, the new CRT structure should be used anyway. */ * memory matters, the new CRT structure should be used anyway. */
crt->tbs.p = frame.tbs.p; crt->tbs.p = frame->tbs.p;
crt->tbs.len = frame.tbs.len; crt->tbs.len = frame->tbs.len;
crt->serial.p = frame.serial.p; crt->serial.p = frame->serial.p;
crt->serial.len = frame.serial.len; crt->serial.len = frame->serial.len;
crt->issuer_raw.p = frame.issuer_raw_with_hdr.p; crt->issuer_raw.p = frame->issuer_raw_with_hdr.p;
crt->issuer_raw.len = frame.issuer_raw_with_hdr.len; crt->issuer_raw.len = frame->issuer_raw_with_hdr.len;
crt->subject_raw.p = frame.subject_raw_with_hdr.p; crt->subject_raw.p = frame->subject_raw_with_hdr.p;
crt->subject_raw.len = frame.subject_raw_with_hdr.len; crt->subject_raw.len = frame->subject_raw_with_hdr.len;
crt->issuer_raw_no_hdr = frame.issuer_raw; crt->issuer_raw_no_hdr = frame->issuer_raw;
crt->subject_raw_no_hdr = frame.subject_raw; crt->subject_raw_no_hdr = frame->subject_raw;
crt->issuer_id.p = frame.issuer_id.p; crt->issuer_id.p = frame->issuer_id.p;
crt->issuer_id.len = frame.issuer_id.len; crt->issuer_id.len = frame->issuer_id.len;
crt->subject_id.p = frame.subject_id.p; crt->subject_id.p = frame->subject_id.p;
crt->subject_id.len = frame.subject_id.len; crt->subject_id.len = frame->subject_id.len;
crt->pk_raw.p = frame.pubkey_raw.p; crt->pk_raw.p = frame->pubkey_raw.p;
crt->pk_raw.len = frame.pubkey_raw.len; crt->pk_raw.len = frame->pubkey_raw.len;
crt->ext_key_usage_raw = frame.ext_key_usage_raw; crt->ext_key_usage_raw = frame->ext_key_usage_raw;
crt->subject_alt_raw = frame.subject_alt_raw; crt->subject_alt_raw = frame->subject_alt_raw;
crt->sig.p = frame.sig.p; crt->sig.p = frame->sig.p;
crt->sig.len = frame.sig.len; crt->sig.len = frame->sig.len;
crt->valid_from = frame.valid_from; crt->valid_from = frame->valid_from;
crt->valid_to = frame.valid_to; crt->valid_to = frame->valid_to;
crt->v3_ext.p = frame.v3_ext.p; crt->v3_ext.p = frame->v3_ext.p;
crt->v3_ext.len = frame.v3_ext.len; crt->v3_ext.len = frame->v3_ext.len;
crt->version = frame.version; crt->version = frame->version;
crt->ca_istrue = frame.ca_istrue; crt->ca_istrue = frame->ca_istrue;
crt->max_pathlen = frame.max_pathlen; crt->max_pathlen = frame->max_pathlen;
crt->ext_types = frame.ext_types; crt->ext_types = frame->ext_types;
crt->key_usage = frame.key_usage; crt->key_usage = frame->key_usage;
crt->ns_cert_type = frame.ns_cert_type; crt->ns_cert_type = frame->ns_cert_type;
/* /*
* Obtain the remaining fields from the frame. * Obtain the remaining fields from the frame.
@ -1247,8 +1288,8 @@ static int x509_crt_parse_der_core( mbedtls_x509_crt *crt,
{ {
/* sig_oid: Previously, needed for convenience in /* sig_oid: Previously, needed for convenience in
* mbedtls_x509_crt_info(), now pure legacy burden. */ * mbedtls_x509_crt_info(), now pure legacy burden. */
unsigned char *tmp = frame.sig_alg.p; unsigned char *tmp = frame->sig_alg.p;
unsigned char *end = tmp + frame.sig_alg.len; unsigned char *end = tmp + frame->sig_alg.len;
mbedtls_x509_buf sig_oid, sig_params; mbedtls_x509_buf sig_oid, sig_params;
ret = mbedtls_x509_get_alg( &tmp, end, ret = mbedtls_x509_get_alg( &tmp, end,
@ -1264,7 +1305,7 @@ static int x509_crt_parse_der_core( mbedtls_x509_crt *crt,
crt->sig_oid = sig_oid; crt->sig_oid = sig_oid;
/* Signature parameters */ /* Signature parameters */
tmp = frame.sig_alg.p; tmp = frame->sig_alg.p;
ret = mbedtls_x509_get_sig_alg_raw( &tmp, end, ret = mbedtls_x509_get_sig_alg_raw( &tmp, end,
&crt->sig_md, &crt->sig_pk, &crt->sig_md, &crt->sig_pk,
&crt->sig_opts ); &crt->sig_opts );
@ -1276,23 +1317,31 @@ static int x509_crt_parse_der_core( mbedtls_x509_crt *crt,
} }
} }
ret = x509_crt_pk_from_frame( &frame, &crt->pk ); ret = x509_crt_pk_from_frame( frame, &crt->pk );
if( ret != 0 ) if( ret != 0 )
goto exit; goto exit;
ret = x509_crt_subject_from_frame( &frame, &crt->subject ); ret = x509_crt_subject_from_frame( frame, &crt->subject );
if( ret != 0 ) if( ret != 0 )
goto exit; goto exit;
ret = x509_crt_issuer_from_frame( &frame, &crt->issuer ); ret = x509_crt_issuer_from_frame( frame, &crt->issuer );
if( ret != 0 ) if( ret != 0 )
goto exit; goto exit;
ret = x509_crt_subject_alt_from_frame( &frame, &crt->subject_alt_names ); ret = x509_crt_subject_alt_from_frame( frame, &crt->subject_alt_names );
if( ret != 0 ) if( ret != 0 )
goto exit; goto exit;
ret = x509_crt_ext_key_usage_from_frame( &frame, &crt->ext_key_usage ); ret = x509_crt_ext_key_usage_from_frame( frame, &crt->ext_key_usage );
if( ret != 0 )
goto exit;
/* The cache just references the PK structure from the legacy
* implementation, so set up the latter first before setting up
* the cache. */
ret = mbedtls_x509_crt_cache_provide_pk( crt );
if( ret != 0 ) if( ret != 0 )
goto exit; goto exit;
@ -1858,11 +1907,11 @@ int mbedtls_x509_crt_info( char *buf, size_t size, const char *prefix,
return( (int) ( size - n ) ); return( (int) ( size - n ) );
} }
ret = x509_crt_frame_acquire( crt_raw, &crt ); ret = mbedtls_x509_crt_frame_acquire( crt_raw, &crt );
if( ret != 0 ) if( ret != 0 )
return( MBEDTLS_ERR_X509_FATAL_ERROR ); return( MBEDTLS_ERR_X509_FATAL_ERROR );
ret = x509_crt_pk_acquire( (mbedtls_x509_crt*) crt_raw, &pk ); ret = mbedtls_x509_crt_pk_acquire( (mbedtls_x509_crt*) crt_raw, &pk );
if( ret != 0 ) if( ret != 0 )
{ {
ret = MBEDTLS_ERR_X509_FATAL_ERROR; ret = MBEDTLS_ERR_X509_FATAL_ERROR;
@ -2023,8 +2072,8 @@ int mbedtls_x509_crt_info( char *buf, size_t size, const char *prefix,
cleanup: cleanup:
x509_crt_frame_release( crt_raw, crt ); mbedtls_x509_crt_frame_release( crt_raw, crt );
x509_crt_pk_release( (mbedtls_x509_crt*) crt_raw, pk ); mbedtls_x509_crt_pk_release( (mbedtls_x509_crt*) crt_raw, pk );
x509_crt_free_sig_info( &sig_info ); x509_crt_free_sig_info( &sig_info );
x509_free_name( issuer.next ); x509_free_name( issuer.next );
@ -2122,12 +2171,13 @@ int mbedtls_x509_crt_check_key_usage( const mbedtls_x509_crt *crt,
{ {
int ret; int ret;
mbedtls_x509_crt_frame *frame; mbedtls_x509_crt_frame *frame;
ret = x509_crt_frame_acquire( crt, (mbedtls_x509_crt_frame**) &frame ); ret = mbedtls_x509_crt_frame_acquire( crt,
(mbedtls_x509_crt_frame**) &frame );
if( ret != 0 ) if( ret != 0 )
return( MBEDTLS_ERR_X509_FATAL_ERROR ); return( MBEDTLS_ERR_X509_FATAL_ERROR );
ret = x509_crt_check_key_usage_frame( frame, usage ); ret = x509_crt_check_key_usage_frame( frame, usage );
x509_crt_frame_release( crt, (mbedtls_x509_crt_frame*) frame ); mbedtls_x509_crt_frame_release( crt, (mbedtls_x509_crt_frame*) frame );
return( ret ); return( ret );
} }
@ -2174,7 +2224,7 @@ int mbedtls_x509_crt_check_extended_key_usage( const mbedtls_x509_crt *crt,
unsigned char *p, *end; unsigned char *p, *end;
x509_crt_check_ext_key_usage_cb_ctx_t cb_ctx = { usage_oid, usage_len }; x509_crt_check_ext_key_usage_cb_ctx_t cb_ctx = { usage_oid, usage_len };
ret = x509_crt_frame_acquire( crt, &frame ); ret = mbedtls_x509_crt_frame_acquire( crt, &frame );
if( ret != 0 ) if( ret != 0 )
return( MBEDTLS_ERR_X509_FATAL_ERROR ); return( MBEDTLS_ERR_X509_FATAL_ERROR );
@ -2195,7 +2245,7 @@ int mbedtls_x509_crt_check_extended_key_usage( const mbedtls_x509_crt *crt,
ret = MBEDTLS_ERR_X509_BAD_INPUT_DATA; ret = MBEDTLS_ERR_X509_BAD_INPUT_DATA;
} }
x509_crt_frame_release( crt, frame ); mbedtls_x509_crt_frame_release( crt, frame );
return( ret ); return( ret );
} }
#endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */ #endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */
@ -2231,14 +2281,14 @@ int mbedtls_x509_crt_is_revoked( const mbedtls_x509_crt *crt,
int ret; int ret;
mbedtls_x509_crt_frame *frame; mbedtls_x509_crt_frame *frame;
ret = x509_crt_frame_acquire( crt, &frame ); ret = mbedtls_x509_crt_frame_acquire( crt, &frame );
if( ret != 0 ) if( ret != 0 )
return( MBEDTLS_ERR_X509_FATAL_ERROR ); return( MBEDTLS_ERR_X509_FATAL_ERROR );
ret = x509_serial_is_revoked( frame->serial.p, ret = x509_serial_is_revoked( frame->serial.p,
frame->serial.len, frame->serial.len,
crl ); crl );
x509_crt_frame_release( crt, frame ); mbedtls_x509_crt_frame_release( crt, frame );
return( ret ); return( ret );
} }
@ -2265,7 +2315,7 @@ static int x509_crt_verifycrl( unsigned char *crt_serial,
{ {
mbedtls_x509_crt_frame *ca; mbedtls_x509_crt_frame *ca;
ret = x509_crt_frame_acquire( ca_crt, &ca ); ret = mbedtls_x509_crt_frame_acquire( ca_crt, &ca );
if( ret != 0 ) if( ret != 0 )
return( MBEDTLS_X509_BADCRL_NOT_TRUSTED ); return( MBEDTLS_X509_BADCRL_NOT_TRUSTED );
@ -2278,10 +2328,10 @@ static int x509_crt_verifycrl( unsigned char *crt_serial,
can_sign = 1; can_sign = 1;
} }
x509_crt_frame_release( ca_crt, ca ); mbedtls_x509_crt_frame_release( ca_crt, ca );
} }
ret = x509_crt_pk_acquire( ca_crt, &pk ); ret = mbedtls_x509_crt_pk_acquire( ca_crt, &pk );
if( ret != 0 ) if( ret != 0 )
return( MBEDTLS_X509_BADCRL_NOT_TRUSTED ); return( MBEDTLS_X509_BADCRL_NOT_TRUSTED );
@ -2356,7 +2406,7 @@ static int x509_crt_verifycrl( unsigned char *crt_serial,
crl_list = crl_list->next; crl_list = crl_list->next;
} }
x509_crt_pk_release( ca_crt, pk ); mbedtls_x509_crt_pk_release( ca_crt, pk );
return( flags ); return( flags );
} }
#endif /* MBEDTLS_X509_CRL_PARSE_C */ #endif /* MBEDTLS_X509_CRL_PARSE_C */
@ -2371,7 +2421,7 @@ static int x509_crt_check_signature( const mbedtls_x509_crt_sig_info *sig_info,
int ret; int ret;
mbedtls_pk_context *pk; mbedtls_pk_context *pk;
ret = x509_crt_pk_acquire( parent, &pk ); ret = mbedtls_x509_crt_pk_acquire( parent, &pk );
if( ret != 0 ) if( ret != 0 )
return( MBEDTLS_ERR_X509_FATAL_ERROR ); return( MBEDTLS_ERR_X509_FATAL_ERROR );
@ -2405,7 +2455,7 @@ static int x509_crt_check_signature( const mbedtls_x509_crt_sig_info *sig_info,
} }
exit: exit:
x509_crt_pk_release( parent, pk ); mbedtls_x509_crt_pk_release( parent, pk );
return( ret ); return( ret );
} }
@ -2543,7 +2593,7 @@ check_signature:
{ {
mbedtls_x509_crt_frame *parent; mbedtls_x509_crt_frame *parent;
ret = x509_crt_frame_acquire( parent_crt, &parent ); ret = mbedtls_x509_crt_frame_acquire( parent_crt, &parent );
if( ret != 0 ) if( ret != 0 )
return( MBEDTLS_ERR_X509_FATAL_ERROR ); return( MBEDTLS_ERR_X509_FATAL_ERROR );
@ -2565,7 +2615,7 @@ check_signature:
path_len_ok = 1; path_len_ok = 1;
} }
x509_crt_frame_release( parent_crt, parent ); mbedtls_x509_crt_frame_release( parent_crt, parent );
} }
if( parent_match == 0 || path_len_ok == 0 ) if( parent_match == 0 || path_len_ok == 0 )
@ -2836,7 +2886,7 @@ find_parent:
{ {
mbedtls_x509_crt_frame *child; mbedtls_x509_crt_frame *child;
ret = x509_crt_frame_acquire( child_crt, &child ); ret = mbedtls_x509_crt_frame_acquire( child_crt, &child );
if( ret != 0 ) if( ret != 0 )
return( MBEDTLS_ERR_X509_FATAL_ERROR ); return( MBEDTLS_ERR_X509_FATAL_ERROR );
@ -2849,7 +2899,7 @@ find_parent:
/* Stop here for trusted roots (but not for trusted EE certs) */ /* Stop here for trusted roots (but not for trusted EE certs) */
if( child_is_trusted ) if( child_is_trusted )
{ {
x509_crt_frame_release( child_crt, child ); mbedtls_x509_crt_frame_release( child_crt, child );
return( 0 ); return( 0 );
} }
@ -2872,7 +2922,7 @@ find_parent:
if( ver_chain->len == 1 && self_issued && if( ver_chain->len == 1 && self_issued &&
x509_crt_check_ee_locally_trusted( child, trust_ca ) == 0 ) x509_crt_check_ee_locally_trusted( child, trust_ca ) == 0 )
{ {
x509_crt_frame_release( child_crt, child ); mbedtls_x509_crt_frame_release( child_crt, child );
return( 0 ); return( 0 );
} }
@ -2881,8 +2931,8 @@ find_parent:
#endif /* MBEDTLS_X509_CRL_PARSE_C */ #endif /* MBEDTLS_X509_CRL_PARSE_C */
ret = x509_crt_get_sig_info( child, &child_sig ); ret = x509_crt_get_sig_info( child, &child_sig );
mbedtls_x509_crt_frame_release( child_crt, child );
x509_crt_frame_release( child_crt, child );
if( ret != 0 ) if( ret != 0 )
return( MBEDTLS_ERR_X509_FATAL_ERROR ); return( MBEDTLS_ERR_X509_FATAL_ERROR );
} }
@ -2937,7 +2987,7 @@ find_parent:
{ {
mbedtls_pk_context *parent_pk; mbedtls_pk_context *parent_pk;
ret = x509_crt_pk_acquire( parent_crt, &parent_pk ); ret = mbedtls_x509_crt_pk_acquire( parent_crt, &parent_pk );
if( ret != 0 ) if( ret != 0 )
return( MBEDTLS_ERR_X509_FATAL_ERROR ); return( MBEDTLS_ERR_X509_FATAL_ERROR );
@ -2945,7 +2995,7 @@ find_parent:
if( x509_profile_check_key( profile, parent_pk ) != 0 ) if( x509_profile_check_key( profile, parent_pk ) != 0 )
*flags |= MBEDTLS_X509_BADCERT_BAD_KEY; *flags |= MBEDTLS_X509_BADCERT_BAD_KEY;
x509_crt_pk_release( parent_crt, parent_pk ); mbedtls_x509_crt_pk_release( parent_crt, parent_pk );
} }
#if defined(MBEDTLS_X509_CRL_PARSE_C) #if defined(MBEDTLS_X509_CRL_PARSE_C)
@ -3037,7 +3087,7 @@ static int x509_crt_verify_name( const mbedtls_x509_crt *crt,
int ret; int ret;
mbedtls_x509_crt_frame *frame; mbedtls_x509_crt_frame *frame;
ret = x509_crt_frame_acquire( crt, &frame ); ret = mbedtls_x509_crt_frame_acquire( crt, &frame );
if( ret != 0 ) if( ret != 0 )
return( MBEDTLS_ERR_X509_FATAL_ERROR ); return( MBEDTLS_ERR_X509_FATAL_ERROR );
@ -3063,7 +3113,7 @@ static int x509_crt_verify_name( const mbedtls_x509_crt *crt,
x509_crt_check_name, (void*) cn ); x509_crt_check_name, (void*) cn );
} }
x509_crt_frame_release( crt, frame ); mbedtls_x509_crt_frame_release( crt, frame );
/* x509_crt_check_name() and x509_crt_subject_alt_check_name() /* x509_crt_check_name() and x509_crt_subject_alt_check_name()
* return 1 when finding a name component matching `cn`. */ * return 1 when finding a name component matching `cn`. */
@ -3181,7 +3231,7 @@ int mbedtls_x509_crt_verify_restartable( mbedtls_x509_crt *crt,
mbedtls_pk_context *pk; mbedtls_pk_context *pk;
mbedtls_pk_type_t pk_type; mbedtls_pk_type_t pk_type;
ret = x509_crt_pk_acquire( crt, &pk ); ret = mbedtls_x509_crt_pk_acquire( crt, &pk );
if( ret != 0 ) if( ret != 0 )
return( MBEDTLS_ERR_X509_FATAL_ERROR ); return( MBEDTLS_ERR_X509_FATAL_ERROR );
@ -3194,7 +3244,7 @@ int mbedtls_x509_crt_verify_restartable( mbedtls_x509_crt *crt,
if( x509_profile_check_key( profile, pk ) != 0 ) if( x509_profile_check_key( profile, pk ) != 0 )
ee_flags |= MBEDTLS_X509_BADCERT_BAD_KEY; ee_flags |= MBEDTLS_X509_BADCERT_BAD_KEY;
x509_crt_pk_release( crt, pk ); mbedtls_x509_crt_pk_release( crt, pk );
} }
/* Check the chain */ /* Check the chain */
@ -3278,6 +3328,8 @@ void mbedtls_x509_crt_free( mbedtls_x509_crt *crt )
do do
{ {
x509_crt_cache_free( cert_cur->cache );
mbedtls_free( cert_cur->cache );
mbedtls_pk_free( &cert_cur->pk ); mbedtls_pk_free( &cert_cur->pk );
#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)