diff --git a/include/mbedtls/x509_crt.h b/include/mbedtls/x509_crt.h index db99aabba3..ce1ee05397 100644 --- a/include/mbedtls/x509_crt.h +++ b/include/mbedtls/x509_crt.h @@ -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. diff --git a/library/x509_crt.c b/library/x509_crt.c index 20f0bb020a..960296de8b 100644 --- a/library/x509_crt.c +++ b/library/x509_crt.c @@ -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 */