Add public API to query for CRT frame and PK

This commit unconditionally adds two convenience API functions:
- mbedtls_x509_crt_get_frame()
- mbedtls_x509_crt_get_pk()
which allow users to extract a CRT frame or PK context
from a certificate.

The difference with the existing acquire/release API for frame and PK
contexts is that in contrast to the latter, the structures returned by
the new API are owned by the user (and, in case of the PK context, need
to be freed by him). This makes the API easier to use, but comes at the
cost of additional memory overhead.
This commit is contained in:
Hanno Becker 2019-02-28 13:23:58 +00:00
parent 180f7bf60b
commit 823efad6e8
2 changed files with 74 additions and 0 deletions

View file

@ -666,6 +666,41 @@ void mbedtls_x509_crt_restart_init( 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 */
/**
* \brief Request CRT frame giving access to basic CRT fields
* and raw ASN.1 data of complex fields.
*
* \param crt The CRT to use. This must be initialized and setup.
* \param dst The address of the destination frame structure.
* This need not be initialized.
*
* \note ::mbedtls_x509_crt_frame does not contain pointers to
* dynamically allocated memory, and hence need not be freed.
* Users may e.g. allocate an instance of
* ::mbedtls_x509_crt_frame on the stack and call this function
* on it, in which case no allocation/freeing has to be done.
*
* \return \c 0 on success. In this case, \p dst is updated
* to hold the frame for the given CRT.
* \return A negative error code on failure.
*/
int mbedtls_x509_crt_get_frame( mbedtls_x509_crt const *crt,
mbedtls_x509_crt_frame *dst );
/**
* \brief Setup a PK context with the public key in a certificate.
*
* \param crt The certificate to use. This must be initialized and setup.
* \param pk The address of the destination PK context to fill.
* This must be initialized via mbedtls_pk_init().
*
* \return \c 0 on success. In this case, the user takes ownership
* of the destination PK context, and is responsible for
* calling mbedtls_pk_free() on it once it's no longer needed.
* \return A negative error code on failure.
*/
int mbedtls_x509_crt_get_pk( mbedtls_x509_crt const *crt,
mbedtls_pk_context *pk );
/**
* \brief Flush internal X.509 CRT parsing cache, if present.

View file

@ -195,6 +195,45 @@ int mbedtls_x509_crt_flush_cache( mbedtls_x509_crt const *crt )
return( 0 );
}
int mbedtls_x509_crt_get_frame( mbedtls_x509_crt const *crt,
mbedtls_x509_crt_frame *dst )
{
int ret;
mbedtls_x509_crt_frame *frame;
ret = mbedtls_x509_crt_frame_acquire( crt, &frame );
if( ret != 0 )
return( ret );
*dst = *frame;
mbedtls_x509_crt_frame_release( crt, frame );
return( 0 );
}
int mbedtls_x509_crt_get_pk( mbedtls_x509_crt const *crt,
mbedtls_pk_context *dst )
{
#if !defined(MBEDTLS_X509_ON_DEMAND_PARSING)
mbedtls_x509_buf_raw pk_raw = crt->cache->pk_raw;
return( mbedtls_pk_parse_subpubkey( &pk_raw.p,
pk_raw.p + pk_raw.len,
dst ) );
#else /* !MBEDTLS_X509_ON_DEMAND_PARSING */
int ret;
mbedtls_pk_context *pk;
ret = mbedtls_x509_crt_pk_acquire( crt, &pk );
if( ret != 0 )
return( ret );
/* Move PK from CRT cache to destination pointer
* to avoid a copy. */
*dst = *pk;
mbedtls_free( crt->cache->pk );
crt->cache->pk = NULL;
mbedtls_x509_crt_pk_release( crt, pk );
return( 0 );
#endif /* MBEDTLS_X509_ON_DEMAND_PARSING */
}
/*
* Item in a verification chain: cert and flags for it
*/