Change mbedtls_x509_subject_alternative_name
Make `mbedtls_x509_subject_alternative_name` to be a single item
rather than a list. Adapt the subject alternative name parsing function,
to receive a signle `mbedtls_x509_buf` item from the subject_alt_names
sequence of the certificate.
diff --git a/library/x509_crt.c b/library/x509_crt.c
index 9777726..cce230b 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -1632,6 +1632,12 @@
return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE );
}
+ if( p + len >= end )
+ {
+ mbedtls_platform_zeroize( other_name, sizeof( other_name ) );
+ return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ }
p += len;
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC ) ) != 0 )
@@ -1648,31 +1654,30 @@
other_name->value.hardware_module_name.oid.p = p;
other_name->value.hardware_module_name.oid.len = len;
+ if( p + len >= end )
+ {
+ mbedtls_platform_zeroize( other_name, sizeof( other_name ) );
+ return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ }
p += len;
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
- goto cleanup;
+ return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
other_name->value.hardware_module_name.val.tag = MBEDTLS_ASN1_OCTET_STRING;
other_name->value.hardware_module_name.val.p = p;
other_name->value.hardware_module_name.val.len = len;
other_name->value.hardware_module_name.next = NULL;
other_name->value.hardware_module_name.next_merged = 0;
-
p += len;
if( p != end )
{
- ret = MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
+ mbedtls_platform_zeroize( other_name,
+ sizeof( other_name ) );
+ return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
}
-
-cleanup:
-
- if( ret != 0 )
- {
- memset( other_name, 0, sizeof( *other_name ) );
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
- }
-
return( 0 );
}
@@ -1686,107 +1691,91 @@
size_t n = *size;
char *p = *buf;
const mbedtls_x509_sequence *cur = subject_alt_name;
+ mbedtls_x509_subject_alternative_name san;
+ int parse_ret;
while( cur != NULL )
{
- switch( cur->buf.tag &
- ( MBEDTLS_ASN1_TAG_CLASS_MASK | MBEDTLS_ASN1_TAG_VALUE_MASK ) )
+ memset( &san, 0, sizeof( san ) );
+ parse_ret = mbedtls_x509_parse_subject_alt_name( &cur->buf, &san );
+ if( parse_ret != 0 )
+ {
+ if( parse_ret == MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE )
+ {
+ ret = mbedtls_snprintf( p, n, "\n%s <unsupported>", prefix );
+ MBEDTLS_X509_SAFE_SNPRINTF;
+ }
+ else
+ {
+ ret = mbedtls_snprintf( p, n, "\n%s <malformed>", prefix );
+ MBEDTLS_X509_SAFE_SNPRINTF;
+ }
+ cur = cur->next;
+ continue;
+ }
+
+ switch( san.type )
{
/*
* otherName
*/
- case( MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_OTHER_NAME ):
+ case( MBEDTLS_X509_SAN_OTHER_NAME ):
+ {
+ mbedtls_x509_san_other_name *other_name = &san.san.other_name;
+
+ ret = mbedtls_snprintf( p, n, "\n%s otherName :", prefix );
+ MBEDTLS_X509_SAFE_SNPRINTF;
+
+ if( MBEDTLS_OID_CMP( MBEDTLS_OID_ON_HW_MODULE_NAME,
+ &other_name->value.hardware_module_name.oid ) != 0 )
{
- mbedtls_x509_san_other_name other_name;
-
- int parse_ret = x509_get_other_name( &cur->buf,
- &other_name );
-
- ret = mbedtls_snprintf( p, n, "\n%s otherName :",
- prefix );
+ ret = mbedtls_snprintf( p, n, "\n%s hardware module name :", prefix );
+ MBEDTLS_X509_SAFE_SNPRINTF;
+ ret = mbedtls_snprintf( p, n, "\n%s hardware type : ", prefix );
MBEDTLS_X509_SAFE_SNPRINTF;
- if( parse_ret != 0 )
- {
- if( ret == MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE )
- {
- ret = mbedtls_snprintf( p, n, " <unsupported>" );
- MBEDTLS_X509_SAFE_SNPRINTF;
- }
- else
- {
- ret = mbedtls_snprintf( p, n, " <malformed>" );
- MBEDTLS_X509_SAFE_SNPRINTF;
- }
+ ret = mbedtls_oid_get_numeric_string( p, n, &other_name->value.hardware_module_name.oid );
+ MBEDTLS_X509_SAFE_SNPRINTF;
- break;
+ ret = mbedtls_snprintf( p, n, "\n%s hardware serial number : ", prefix );
+ MBEDTLS_X509_SAFE_SNPRINTF;
+
+ if( other_name->value.hardware_module_name.val.len >= n )
+ {
+ *p = '\0';
+ return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL );
}
- if( MBEDTLS_OID_CMP( MBEDTLS_OID_ON_HW_MODULE_NAME,
- &other_name.value.hardware_module_name.oid )
- != 0 )
+ for( i = 0; i < other_name->value.hardware_module_name.val.len; i++ )
{
- ret = mbedtls_snprintf( p, n, "\n%s "
- "hardware module name :",
- prefix );
- MBEDTLS_X509_SAFE_SNPRINTF;
- ret = mbedtls_snprintf( p, n,
- "\n%s "
- "hardware type : ",
- prefix );
- MBEDTLS_X509_SAFE_SNPRINTF;
+ *p++ = other_name->value.hardware_module_name.val.p[i];
+ }
+ n -= other_name->value.hardware_module_name.val.len;
- ret = mbedtls_oid_get_numeric_string( p, n,
- &other_name.value.hardware_module_name.oid );
- MBEDTLS_X509_SAFE_SNPRINTF;
-
- ret = mbedtls_snprintf( p, n,
- "\n%s "
- "hardware serial number : ",
- prefix );
- MBEDTLS_X509_SAFE_SNPRINTF;
-
- if( other_name.value.hardware_module_name.val.len >= n )
- {
- *p = '\0';
- return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL );
- }
-
- for( i = 0;
- i < other_name.value.hardware_module_name.val.len;
- i++ )
- {
- *p++ =
- other_name.value.hardware_module_name.val.p[i];
- }
- n -= other_name.value.hardware_module_name.val.len;
-
- }/* MBEDTLS_OID_ON_HW_MODULE_NAME */
-
- }
- break;
+ }/* MBEDTLS_OID_ON_HW_MODULE_NAME */
+ }
+ break;
/*
* dNSName
*/
- case( MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_DNS_NAME ):
+ case( MBEDTLS_X509_SAN_DNS_NAME ):
+ {
ret = mbedtls_snprintf( p, n, "\n%s dNSName : ", prefix );
MBEDTLS_X509_SAFE_SNPRINTF;
-
- if( cur->buf.len >= n )
+ if( san.san.unstructured_name.len >= n )
{
*p = '\0';
return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL );
}
-
- n -= cur->buf.len;
- for( i = 0; i < cur->buf.len; i++ )
- *p++ = cur->buf.p[i];
-
- break;
+ n -= san.san.unstructured_name.len;
+ for( i = 0; i < san.san.unstructured_name.len; i++ )
+ *p++ = san.san.unstructured_name.p[i];
+ }
+ break;
/*
- * Type not supported.
+ * Type not supported, skip item.
*/
default:
ret = mbedtls_snprintf( p, n, "\n%s <unsupported>", prefix );
@@ -1805,102 +1794,53 @@
return( 0 );
}
-int mbedtls_x509_parse_subject_alternative_name( const mbedtls_x509_crt *crt,
- mbedtls_x509_subject_alternative_name **san )
+int mbedtls_x509_parse_subject_alt_name( const mbedtls_x509_buf *san_buf,
+ mbedtls_x509_subject_alternative_name *san )
{
int ret;
- const mbedtls_x509_sequence *cur = &crt->subject_alt_names;
- mbedtls_x509_subject_alternative_name *cur_san = *san, *prev_san = NULL;
-
- if( crt->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME )
+ switch( san_buf->tag &
+ ( MBEDTLS_ASN1_TAG_CLASS_MASK |
+ MBEDTLS_ASN1_TAG_VALUE_MASK ) )
{
- if( cur_san != NULL )
+ /*
+ * otherName
+ */
+ case( MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_OTHER_NAME ):
{
- return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
+ mbedtls_x509_san_other_name other_name;
+
+ ret = x509_get_other_name( san_buf, &other_name );
+ if( ret != 0 )
+ return( ret );
+
+ memset( san, 0, sizeof( mbedtls_x509_subject_alternative_name ) );
+ san->type = MBEDTLS_X509_SAN_OTHER_NAME;
+ memcpy( &san->san.other_name,
+ &other_name, sizeof( other_name ) );
+
}
+ break;
- while( cur != NULL )
+ /*
+ * dNSName
+ */
+ case( MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_DNS_NAME ):
{
- switch( cur->buf.tag &
- ( MBEDTLS_ASN1_TAG_CLASS_MASK |
- MBEDTLS_ASN1_TAG_VALUE_MASK ) )
- {
- /*
- * otherName
- */
- case( MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_OTHER_NAME ):
- {
- mbedtls_x509_san_other_name other_name;
+ memset( san, 0, sizeof( mbedtls_x509_subject_alternative_name ) );
+ san->type = MBEDTLS_X509_SAN_DNS_NAME;
- ret = x509_get_other_name( &cur->buf, &other_name );
- if( ret != 0 )
- {
- /*
- * In case MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE is returned,
- * then the "otherName" is of an unsupported type. Ignore.
- */
- if( ret != MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE )
- return MBEDTLS_ERR_X509_INVALID_FORMAT;
+ memcpy( &san->san.unstructured_name,
+ san_buf, sizeof( *san_buf ) );
- cur = cur->next;
- continue;
- }
+ }
+ break;
- cur_san = mbedtls_calloc( 1, sizeof( mbedtls_x509_subject_alternative_name ) );
- if( cur_san == NULL )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_ALLOC_FAILED );
-
- if( prev_san != NULL )
- prev_san->next = cur_san;
-
- cur_san->type = MBEDTLS_X509_SAN_OTHER_NAME;
- memcpy( &cur_san->san.other_name,
- &other_name, sizeof( other_name ) );
-
- }
- break;
-
- /*
- * dNSName
- */
- case( MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_DNS_NAME ):
- {
- cur_san = mbedtls_calloc( 1, sizeof( mbedtls_x509_subject_alternative_name ) );
- if( cur_san == NULL )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_ALLOC_FAILED );
-
- if( prev_san != NULL )
- prev_san->next = cur_san;
-
- cur_san->type = MBEDTLS_X509_SAN_DNS_NAME;
-
- memcpy( &cur_san->san.unstructured_name,
- &cur->buf, sizeof( cur->buf ) );
-
- }
- break;
-
- /*
- * Type not supported, skip item.
- */
- default:
- break;
- }
-
- if( *san == NULL )
- *san = cur_san;
-
- if( cur_san != NULL )
- {
- prev_san = cur_san;
- cur_san = cur_san->next;
- }
-
- cur = cur->next;
- }/* while( cur != NULL ) */
- }/* crt->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME */
+ /*
+ * Type not supported
+ */
+ default:
+ return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE );
+ }
return( 0 );
}