From 63e6998dd7559a52d56d04583eeae62efdfb9a6e Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Tue, 26 Feb 2019 18:50:49 +0000 Subject: [PATCH] Add public API to query subject and issuer from CRT The legacy `mbedtls_x509_crt` contains fields `issuer/subject` which are dynamically allocated linked list presentations of the CRTs issuer and subject names, respectively. The new CRT frame structure `mbedtls_x509_crt_frame`, however, only provides pointers to the raw ASN.1 buffers for the issuer and subject, for reasons of memory usage. For convenience to users that previously used the `issuer`/`subject` fields of `mbedtls_x509_crt`, this commit adds two public API functions `mbedtls_x509_crt_get_subject()` and `mbedtls_x509_crt_get_issuer()` which allow to request the legacy linked list presentation of the CRTs subject / issuer names. Similar to `mbedtls_x509_crt_get_pk()`, the returned names are owned by the user, and must be freed through a call to `mbedtls_x509_name_free()`. --- include/mbedtls/x509_crt.h | 48 ++++++++++++++++++++++++++++++++++++++ library/x509_crt.c | 46 ++++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+) diff --git a/include/mbedtls/x509_crt.h b/include/mbedtls/x509_crt.h index ce1ee0539..790016efa 100644 --- a/include/mbedtls/x509_crt.h +++ b/include/mbedtls/x509_crt.h @@ -702,6 +702,54 @@ int mbedtls_x509_crt_get_frame( mbedtls_x509_crt const *crt, int mbedtls_x509_crt_get_pk( mbedtls_x509_crt const *crt, mbedtls_pk_context *pk ); +/** + * \brief Request the subject name of a CRT, presented + * as a dynamically allocated linked list. + * + * \param crt The CRT to use. This must be initialized and setup. + * \param subject The address at which to store the address of the + * first entry of the generated linked list holding + * the subject name. + * + * \note Depending in your use case, consider using the raw ASN.1 + * describing the subject name instead of the heap-allocated + * linked list generated by this call. The pointers to the + * raw ASN.1 data are part of the CRT frame that can be queried + * via mbedtls_x509_crt_get_frame(), and they can be traversed + * via mbedtls_asn1_traverse_sequence_of(). + * + * \return \c 0 on success. In this case, the user takes ownership + * of the name context, and is responsible for freeing it + * once it's no longer needed. + * \return A negative error code on failure. + */ +int mbedtls_x509_crt_get_subject( mbedtls_x509_crt const *crt, + mbedtls_x509_name **subject ); + +/** + * \brief Request the subject name of a CRT, presented + * as a dynamically allocated linked list. + * + * \param crt The CRT to use. This must be initialized and setup. + * \param issuer The address at which to store the address of the + * first entry of the generated linked list holding + * the subject name. + * + * \note Depending in your use case, consider using the raw ASN.1 + * describing the subject name instead of the heap-allocated + * linked list generated by this call. The pointers to the + * raw ASN.1 data are part of the CRT frame that can be queried + * via mbedtls_x509_crt_get_frame(), and they can be traversed + * via mbedtls_asn1_traverse_sequence_of(). + * + * \return \c 0 on success. In this case, the user takes ownership + * of the name context, and is responsible for freeing it + * once it's no longer needed. + * \return A negative error code on failure. + */ +int mbedtls_x509_crt_get_issuer( mbedtls_x509_crt const *crt, + mbedtls_x509_name **issuer ); + /** * \brief Flush internal X.509 CRT parsing cache, if present. * diff --git a/library/x509_crt.c b/library/x509_crt.c index 960296de8..fe782bbeb 100644 --- a/library/x509_crt.c +++ b/library/x509_crt.c @@ -195,6 +195,52 @@ int mbedtls_x509_crt_flush_cache( mbedtls_x509_crt const *crt ) return( 0 ); } +int mbedtls_x509_crt_get_subject( mbedtls_x509_crt const *crt, + mbedtls_x509_name **subject ) +{ + int ret; + mbedtls_x509_crt_frame *frame; + mbedtls_x509_name *name; + + ret = mbedtls_x509_crt_frame_acquire( crt, &frame ); + if( ret != 0 ) + return( ret ); + + name = mbedtls_calloc( 1, sizeof( mbedtls_x509_name ) ); + if( name == NULL ) + ret = MBEDTLS_ERR_X509_ALLOC_FAILED; + else + ret = x509_crt_subject_from_frame( frame, name ); + + mbedtls_x509_crt_frame_release( crt, frame ); + + *subject = name; + return( ret ); +} + +int mbedtls_x509_crt_get_issuer( mbedtls_x509_crt const *crt, + mbedtls_x509_name **issuer ) +{ + int ret; + mbedtls_x509_crt_frame *frame; + mbedtls_x509_name *name; + + ret = mbedtls_x509_crt_frame_acquire( crt, &frame ); + if( ret != 0 ) + return( ret ); + + name = mbedtls_calloc( 1, sizeof( mbedtls_x509_name ) ); + if( name == NULL ) + ret = MBEDTLS_ERR_X509_ALLOC_FAILED; + else + ret = x509_crt_issuer_from_frame( frame, name ); + + mbedtls_x509_crt_frame_release( crt, frame ); + + *issuer = name; + return( ret ); +} + int mbedtls_x509_crt_get_frame( mbedtls_x509_crt const *crt, mbedtls_x509_crt_frame *dst ) {