Renaming x509_get_subject_alt_name to x509_get_general_names and mbedtls_x509_parse_subject_alt_name to mbedtls_x509_parse_general_name so they can be used not only to collect subject alt name, but the V3 authority cert issuer that is also GeneralName type.
Also updated the x509_get_general_names function to be able to parse rfc822Names
Test are also updated according these changes.
Signed-off-by: toth92g <toth92g@gmail.com>
diff --git a/include/mbedtls/x509.h b/include/mbedtls/x509.h
index 1654843..4aa52b0 100644
--- a/include/mbedtls/x509.h
+++ b/include/mbedtls/x509.h
@@ -249,7 +249,7 @@
typedef struct mbedtls_x509_authority
{
mbedtls_x509_buf keyIdentifier;
- mbedtls_x509_name authorityCertIssuer;
+ mbedtls_x509_sequence authorityCertIssuer;
mbedtls_x509_buf authorityCertSerialNumber;
mbedtls_x509_buf raw;
}
diff --git a/include/mbedtls/x509_crt.h b/include/mbedtls/x509_crt.h
index b38adb6..982a30f 100644
--- a/include/mbedtls/x509_crt.h
+++ b/include/mbedtls/x509_crt.h
@@ -610,7 +610,7 @@
* \param san The target structure to populate with the parsed presentation
* of the subject alternative name encoded in \p san_raw.
*
- * \note Only "dnsName" and "otherName" of type hardware_module_name
+ * \note Only "dnsName" and "otherName" and "rfc822Name" of type hardware_module_name
* as defined in RFC 4180 is supported.
*
* \note This function should be called on a single raw data of
@@ -628,7 +628,7 @@
* SAN type.
* \return Another negative value for any other failure.
*/
-int mbedtls_x509_parse_subject_alt_name( const mbedtls_x509_buf *san_buf,
+int mbedtls_x509_parse_general_name( const mbedtls_x509_buf *san_buf,
mbedtls_x509_subject_alternative_name *san );
#if !defined(MBEDTLS_X509_REMOVE_INFO)
diff --git a/library/x509_crt.c b/library/x509_crt.c
index c3e5f37..0d8d134 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -645,103 +645,6 @@
}
/*
- * AuthorityKeyIdentifier ::= SEQUENCE {
- * keyIdentifier [0] KeyIdentifier OPTIONAL,
- * authorityCertIssuer [1] GeneralNames OPTIONAL,
- * authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL }
- *
- * KeyIdentifier ::= OCTET STRING
- */
-static int x509_get_authority_key_id( unsigned char** p,
- unsigned char* end,
- mbedtls_x509_authority* authority_key_id )
-{
- int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
- size_t len = 0u;
-
- if ( ( ret = mbedtls_asn1_get_tag( p, end, &len,
- MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- {
- return( ret );
- }
-
- if ( (ret = mbedtls_asn1_get_tag( p, end, &len,
- MBEDTLS_ASN1_CONTEXT_SPECIFIC ) ) != 0 )
- {
- /* KeyIdentifier is an OPTIONAL field */
- }
- else
- {
- authority_key_id->keyIdentifier.len = len;
- authority_key_id->keyIdentifier.p = *p;
- authority_key_id->keyIdentifier.tag = MBEDTLS_ASN1_OCTET_STRING;
-
- *p += len;
- }
-
- if ( *p < end )
- {
- if ( ( ret = mbedtls_asn1_get_tag( p, end, &len,
- MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_BOOLEAN ) ) != 0 )
- {
- /* authorityCertIssuer is an OPTIONAL field */
- }
- else
- {
- if ( ( ret = mbedtls_asn1_get_tag( p, end, &len,
- MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
- {
- return( ret );
- }
- else
- {
- authority_key_id->raw.p = *p;
-
- if ( ( ret = mbedtls_asn1_get_tag( p, end, &len,
- MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- {
- return( ret );
- }
-
- if ( ( ret = mbedtls_x509_get_name( p, *p + len, &authority_key_id->authorityCertIssuer ) ) != 0 )
- {
- return( ret );
- }
-
- authority_key_id->raw.len = *p - authority_key_id->raw.p;
- }
- }
- }
-
- if ( *p < end )
- {
- if ( ( ret = mbedtls_asn1_get_tag( p, end, &len,
- MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_INTEGER ) ) != 0 )
- {
- /* authorityCertSerialNumber is an OPTIONAL field, but if there are still data it must be the serial number */
- return( ret );
- }
- else
- {
- authority_key_id->authorityCertSerialNumber.len = len;
- authority_key_id->authorityCertSerialNumber.p = *p;
- authority_key_id->authorityCertSerialNumber.tag = MBEDTLS_ASN1_OCTET_STRING;
- *p += len;
- }
- }
-
- if ( *p != end )
- {
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
- }
-
- return( 0 );
-}
-
-/*
- * SubjectAltName ::= GeneralNames
- *
* GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
*
* GeneralName ::= CHOICE {
@@ -766,7 +669,7 @@
* NOTE: we list all types, but only use dNSName and otherName
* of type HwModuleName, as defined in RFC 4108, at this point.
*/
-static int x509_get_subject_alt_name( unsigned char **p,
+static int x509_get_general_names( unsigned char **p,
const unsigned char *end,
mbedtls_x509_sequence *subject_alt_name )
{
@@ -795,17 +698,19 @@
if( ( ret = mbedtls_asn1_get_len( p, end, &tag_len ) ) != 0 )
return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
+ /* Tag shall be CONTEXT_SPECIFIC or SET */
if( ( tag & MBEDTLS_ASN1_TAG_CLASS_MASK ) !=
MBEDTLS_ASN1_CONTEXT_SPECIFIC )
{
- return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
- MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) );
+ if( ( tag & (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) )
+ return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
+ MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
}
/*
* Check that the SAN is structured correctly.
*/
- ret = mbedtls_x509_parse_subject_alt_name( &(cur->buf), &dummy_san_buf );
+ ret = mbedtls_x509_parse_general_name( &(cur->buf), &dummy_san_buf );
/*
* In case the extension is malformed, return an error,
* and clear the allocated sequences.
@@ -850,6 +755,91 @@
}
/*
+ * AuthorityKeyIdentifier ::= SEQUENCE {
+ * keyIdentifier [0] KeyIdentifier OPTIONAL,
+ * authorityCertIssuer [1] GeneralNames OPTIONAL,
+ * authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL }
+ *
+ * KeyIdentifier ::= OCTET STRING
+ */
+static int x509_get_authority_key_id( unsigned char** p,
+ unsigned char* end,
+ mbedtls_x509_authority* authority_key_id )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t len = 0u;
+
+ if ( ( ret = mbedtls_asn1_get_tag( p, end, &len,
+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE | 0 ) ) != 0 )
+ {
+ return( ret );
+ }
+
+ if ( (ret = mbedtls_asn1_get_tag( p, end, &len,
+ MBEDTLS_ASN1_CONTEXT_SPECIFIC ) ) != 0 )
+ {
+ /* KeyIdentifier is an OPTIONAL field */
+ }
+ else
+ {
+ authority_key_id->keyIdentifier.len = len;
+ authority_key_id->keyIdentifier.p = *p;
+ authority_key_id->keyIdentifier.tag = MBEDTLS_ASN1_OCTET_STRING;
+
+ *p += len;
+ }
+
+ if ( *p < end )
+ {
+ if ((ret = mbedtls_asn1_get_tag(p, end, &len,
+ MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 1 ) ) != 0)
+ {
+ /* authorityCertIssuer is an OPTIONAL field */
+ }
+ else
+ {
+ if ((ret = mbedtls_asn1_get_tag(p, end, &len,
+ MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 4 ) ) != 0)
+ {
+ return(ret);
+ }
+ else
+ {
+ /* "end" also includes the CertSerialNumber field so "len" shall be used */
+ ret = x509_get_general_names( p,
+ (*p+len),
+ &authority_key_id->authorityCertIssuer );
+ }
+ }
+ }
+
+ if ( *p < end )
+ {
+ if ( ( ret = mbedtls_asn1_get_tag( p, end, &len,
+ MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_INTEGER ) ) != 0 )
+ {
+ /* authorityCertSerialNumber is an OPTIONAL field, but if there are still data it must be the serial number */
+ return( ret );
+ }
+ else
+ {
+ authority_key_id->authorityCertSerialNumber.len = len;
+ authority_key_id->authorityCertSerialNumber.p = *p;
+ authority_key_id->authorityCertSerialNumber.tag = MBEDTLS_ASN1_OCTET_STRING;
+ *p += len;
+ }
+ }
+
+ if ( *p != end )
+ {
+ return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ }
+
+ return( 0 );
+}
+
+/*
* id-ce-certificatePolicies OBJECT IDENTIFIER ::= { id-ce 32 }
*
* anyPolicy OBJECT IDENTIFIER ::= { id-ce-certificatePolicies 0 }
@@ -1132,6 +1122,7 @@
&crt->ext_key_usage ) ) != 0 )
return( ret );
break;
+
case MBEDTLS_X509_EXT_SUBJECT_KEY_IDENTIFIER:
/* Parse subject key identifier */
if ( ( ret = x509_get_subject_key_id( p, end_ext_data,
@@ -1140,17 +1131,20 @@
return ( ret );
}
break;
+
case MBEDTLS_X509_EXT_AUTHORITY_KEY_IDENTIFIER:
/* Parse authority key identifier */
- if ( (ret = x509_get_authority_key_id(p, end_ext_octet,
- &crt->authority_key_id)) != 0 )
+ if ( ( ret = x509_get_authority_key_id( p, end_ext_octet,
+ &crt->authority_key_id ) ) != 0 )
{
return ( ret );
}
break;
case MBEDTLS_X509_EXT_SUBJECT_ALT_NAME:
- /* Parse subject alt name */
- if( ( ret = x509_get_subject_alt_name( p, end_ext_octet,
+ /* Parse subject alt name
+ * SubjectAltName ::= GeneralNames
+ */
+ if( ( ret = x509_get_general_names( p, end_ext_octet,
&crt->subject_alt_names ) ) != 0 )
return( ret );
break;
@@ -1989,7 +1983,7 @@
while( cur != NULL )
{
memset( &san, 0, sizeof( san ) );
- parse_ret = mbedtls_x509_parse_subject_alt_name( &cur->buf, &san );
+ parse_ret = mbedtls_x509_parse_general_name( &cur->buf, &san );
if( parse_ret != 0 )
{
if( parse_ret == MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE )
@@ -2080,6 +2074,80 @@
return( 0 );
}
+int mbedtls_x509_parse_general_name( const mbedtls_x509_buf *san_buf,
+ mbedtls_x509_subject_alternative_name *san )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ switch( san_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;
+
+ 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;
+
+ /*
+ * dNSName
+ */
+ case( MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_DNS_NAME ):
+ {
+ memset( san, 0, sizeof( mbedtls_x509_subject_alternative_name ) );
+ san->type = MBEDTLS_X509_SAN_DNS_NAME;
+
+ memcpy( &san->san.unstructured_name,
+ san_buf, sizeof( *san_buf ) );
+
+ }
+ break;
+
+ /*
+ * RFC822 Name
+ */
+ case( MBEDTLS_ASN1_SEQUENCE | MBEDTLS_X509_SAN_RFC822_NAME ):
+ {
+ mbedtls_x509_name rfc822Name;
+ unsigned char* bufferPointer = san_buf->p;
+ unsigned char** p = &bufferPointer;
+ const unsigned char* end = san_buf->p + san_buf->len;
+
+ /* The leading ASN1 tag and length has been processed. Stepping back with 2 bytes, because mbedtls_x509_get_name expects the beginning of the SET tag */
+ *p = *p - 2;
+
+ ret = mbedtls_x509_get_name( p, end, &rfc822Name );
+ if ( ret != 0 )
+ return( ret );
+
+ memset( san, 0, sizeof( mbedtls_x509_subject_alternative_name ) );
+ san->type = MBEDTLS_X509_SAN_OTHER_NAME;
+ memcpy( &san->san.unstructured_name,
+ &rfc822Name, sizeof( rfc822Name ) );
+ }
+ break;
+
+ /*
+ * Type not supported
+ */
+ default:
+ return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE );
+ }
+ return( 0 );
+}
+
#define PRINT_ITEM(i) \
{ \
ret = mbedtls_snprintf( p, n, "%s" i, sep ); \
@@ -3442,13 +3510,14 @@
mbedtls_asn1_sequence_free( cert_cur->subject_alt_names.next );
mbedtls_asn1_sequence_free( cert_cur->certificate_policies.next );
- name_cur = cert_cur->authority_key_id.authorityCertIssuer.next;
- while ( name_cur != NULL )
+ seq_cur = cert_cur->authority_key_id.authorityCertIssuer.next;
+ while ( seq_cur != NULL )
{
- name_prv = name_cur;
- name_cur = name_cur->next;
- mbedtls_platform_zeroize( name_prv, sizeof(mbedtls_x509_name) );
- mbedtls_free( name_prv );
+ seq_prv = seq_cur;
+ seq_cur = seq_cur->next;
+ mbedtls_platform_zeroize( seq_prv,
+ sizeof( mbedtls_x509_sequence ) );
+ mbedtls_free( seq_prv );
}
if( cert_cur->raw.p != NULL && cert_cur->own_buffer )
diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data
index 44835b0..1ad62ad 100644
--- a/tests/suites/test_suite_x509parse.data
+++ b/tests/suites/test_suite_x509parse.data
@@ -2926,4 +2926,4 @@
X509 CRT parse Authority Key Id - Wrong Issuer Tag 4
depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C:MBEDTLS_CERTS_C:MBEDTLS_SHA1_C:MBEDTLS_RSA_C
-x509_crt_parse_authoritykeyid:"308203873082026fa003020102020100300d06092a864886f70d0101050500303b310b3009060355040613024e4c3111300f060355040a1308506f6c617253534c3119301706035504031310506f6c617253534c2054657374204341301e170d3131303231323134343430305a170d3231303231323134343430305a303b310b3009060355040613024e4c3111300f060355040a1308506f6c617253534c3119301706035504031310506f6c617253534c205465737420434130820122300d06092a864886f70d01010105000382010f003082010a0282010100c0df37fc17bbe0969d3f86de96327d44a516a0cd21f199d4eceacb7c18580894a5ec9bc58bdf1a1e993899871e7bc08d39df385d707807d39ed993e8b97251c5cea33052a9f2e7407014cb44a2720bc2e540f93ee5a60eb3f9ec4a63c0b82900749c573ba8a5049071f1bd83d93fd6a5e23c2a8fef2760c3c69fcbbaec607db7e68432be4ffb582622035bd4b4d5fbf5e3962e70c0e42ebdfc2eeee24155c0342e7d247269cb47b11440837d67f486f631abf179a4b2b52e12f98417f0626f273e1358b1540d219a7337a130cf6f92dcf6e9fcacdb2e28d17e024b23a015f238656409ea0c6e8e1b17a071c8b39bc9abe9c3f2cf87968f8002329e99586fa2d50203010001a38195308192300c0603551d13040530030101ff301d0603551d0e04160414b45ae4a5b3ded252f6b9d5a6950feb3ebcc7fdff30630603551d23045c305a8014b45ae4a5b3ded252f6b9d5a6950feb3ebcc7fdffa13fa43d303b000b3009060355040613024e4c3111300f060355040a1308506f6c617253534c3119301706035504031310506f6c617253534c2054657374204341820100300d06092a864886f70d01010505000382010100b8fd54d80054908b25b027dd95cda2f784071d87894ac47811d807b5d722508e48eb627a3289be634753ffb6bef12e8c54c0993fa0b93723725f0d46598fd847cd974c9f070c1262093a24e436d9e92cda38d0737561d7c16c268b9be0d5dc67ed8c6b33d774223c4cdbb58d2ace2c0d0859050905a6399fb3671be283e5e18f53f66793c7f96f76445812e83ad497e7e9c03ea87a723d87531fe52c8484e79a9e7f66d91f9bf51348b04d14d1deb224d9787df535cc5819d1d299ef4d73f81f89d45ad052ce09f5b146516a008e3bcc6f63010099ed9da60860cd3218d073e05871d9e5d253d78dd0cae95d2a0a0d5d55ec21501716e6064acd5edef7e0e954":0:"":0:MBEDTLS_ERR_ASN1_UNEXPECTED_TAG + MBEDTLS_ERR_X509_INVALID_NAME
+x509_crt_parse_authoritykeyid:"308203873082026fa003020102020100300d06092a864886f70d0101050500303b310b3009060355040613024e4c3111300f060355040a1308506f6c617253534c3119301706035504031310506f6c617253534c2054657374204341301e170d3131303231323134343430305a170d3231303231323134343430305a303b310b3009060355040613024e4c3111300f060355040a1308506f6c617253534c3119301706035504031310506f6c617253534c205465737420434130820122300d06092a864886f70d01010105000382010f003082010a0282010100c0df37fc17bbe0969d3f86de96327d44a516a0cd21f199d4eceacb7c18580894a5ec9bc58bdf1a1e993899871e7bc08d39df385d707807d39ed993e8b97251c5cea33052a9f2e7407014cb44a2720bc2e540f93ee5a60eb3f9ec4a63c0b82900749c573ba8a5049071f1bd83d93fd6a5e23c2a8fef2760c3c69fcbbaec607db7e68432be4ffb582622035bd4b4d5fbf5e3962e70c0e42ebdfc2eeee24155c0342e7d247269cb47b11440837d67f486f631abf179a4b2b52e12f98417f0626f273e1358b1540d219a7337a130cf6f92dcf6e9fcacdb2e28d17e024b23a015f238656409ea0c6e8e1b17a071c8b39bc9abe9c3f2cf87968f8002329e99586fa2d50203010001a38195308192300c0603551d13040530030101ff301d0603551d0e04160414b45ae4a5b3ded252f6b9d5a6950feb3ebcc7fdff30630603551d23045c305a8014b45ae4a5b3ded252f6b9d5a6950feb3ebcc7fdffa13fa43d303b000b3009060355040613024e4c3111300f060355040a1308506f6c617253534c3119301706035504031310506f6c617253534c2054657374204341820100300d06092a864886f70d01010505000382010100b8fd54d80054908b25b027dd95cda2f784071d87894ac47811d807b5d722508e48eb627a3289be634753ffb6bef12e8c54c0993fa0b93723725f0d46598fd847cd974c9f070c1262093a24e436d9e92cda38d0737561d7c16c268b9be0d5dc67ed8c6b33d774223c4cdbb58d2ace2c0d0859050905a6399fb3671be283e5e18f53f66793c7f96f76445812e83ad497e7e9c03ea87a723d87531fe52c8484e79a9e7f66d91f9bf51348b04d14d1deb224d9787df535cc5819d1d299ef4d73f81f89d45ad052ce09f5b146516a008e3bcc6f63010099ed9da60860cd3218d073e05871d9e5d253d78dd0cae95d2a0a0d5d55ec21501716e6064acd5edef7e0e954":0:"":0:MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
diff --git a/tests/suites/test_suite_x509parse.function b/tests/suites/test_suite_x509parse.function
index 487a62c..57bbc59 100644
--- a/tests/suites/test_suite_x509parse.function
+++ b/tests/suites/test_suite_x509parse.function
@@ -434,7 +434,7 @@
cur = &crt.subject_alt_names;
while( cur != NULL )
{
- ret = mbedtls_x509_parse_subject_alt_name( &cur->buf, &san );
+ ret = mbedtls_x509_parse_general_name( &cur->buf, &san );
TEST_ASSERT( ret == 0 || ret == MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE );
/*
* If san type not supported, ignore.
@@ -1447,18 +1447,19 @@
TEST_ASSERT( crt.authority_key_id.keyIdentifier.len == keyIdLength );
/* Issuer test */
- mbedtls_x509_name* issuerPtr = &crt.authority_key_id.authorityCertIssuer;
+ mbedtls_x509_sequence* issuerPtr = &crt.authority_key_id.authorityCertIssuer;
while ( issuerPtr != NULL )
{
- for ( issuerCounter = 0u; issuerCounter < issuerPtr->val.len; issuerCounter++ )
+ /* First 9 bytes are always ASN1 coding related information that does not matter right now. Only the values are asserted */
+ for ( issuerCounter = 9u; issuerCounter < issuerPtr->buf.len; issuerCounter++ )
{
- result |= ( authorityKeyId_issuer[bufferCounter++] != issuerPtr->val.p[issuerCounter] );
+ result |= ( authorityKeyId_issuer[bufferCounter++] != issuerPtr->buf.p[issuerCounter] );
}
bufferCounter++; /* Skipping the slash */
issuerPtr = issuerPtr->next;
}
TEST_ASSERT( result == 0 );
-
+
/* Serial test */
TEST_ASSERT( crt.authority_key_id.authorityCertSerialNumber.tag == MBEDTLS_ASN1_OCTET_STRING );
TEST_ASSERT( crt.authority_key_id.authorityCertSerialNumber.len == serialLength );