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()`.
diff --git a/include/mbedtls/x509_crt.h b/include/mbedtls/x509_crt.h
index ce1ee05..790016e 100644
--- a/include/mbedtls/x509_crt.h
+++ b/include/mbedtls/x509_crt.h
@@ -703,6 +703,54 @@
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.
*
* \param crt The CRT structure whose cache to flush.
diff --git a/library/x509_crt.c b/library/x509_crt.c
index 960296d..fe782bb 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -195,6 +195,52 @@
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 )
{