Pass "certificate policies" extension to callback
Pass the "certificate policies" extension to the callback supplied to
mbedtls_x509_crt_parse_der_with_ext_cb() if it contains unsupported
policies. This allows the callback to fully replicate the behaviour
of the deprecated MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
configuration.
Signed-off-by: Nicola Di Lieto <nicola.dilieto@gmail.com>
diff --git a/tests/suites/test_suite_x509parse.function b/tests/suites/test_suite_x509parse.function
index 54e5156..a72532f 100644
--- a/tests/suites/test_suite_x509parse.function
+++ b/tests/suites/test_suite_x509parse.function
@@ -303,17 +303,91 @@
}
int parse_crt_ext_cb( void *p_ctx, mbedtls_x509_crt const *crt, mbedtls_x509_buf const *oid,
- int critical, const unsigned char *p, const unsigned char *end )
+ int critical, const unsigned char *cp, const unsigned char *end )
{
( void ) crt;
- ( void ) p;
+ ( void ) cp;
( void ) end;
( void ) critical;
mbedtls_x509_buf *new_oid = (mbedtls_x509_buf *)p_ctx;
- if( new_oid == NULL || new_oid->tag != oid->tag || new_oid->len != oid->len ||
- memcmp(new_oid->p, oid->p, oid->len) != 0 )
+ if( oid->tag == MBEDTLS_ASN1_OID &&
+ MBEDTLS_OID_CMP( MBEDTLS_OID_CERTIFICATE_POLICIES, oid ) == 0 )
+ {
+ /* Handle unknown certificate policy */
+ int ret, parse_ret = 0;
+ size_t len;
+ unsigned char **p = (unsigned char **)&cp;
+
+ /* Get main sequence tag */
+ ret = mbedtls_asn1_get_tag( p, end, &len,
+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE );
+ if( ret != 0 )
+ return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+
+ if( *p + len != end )
+ return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+
+ /*
+ * Cannot be an empty sequence.
+ */
+ if( len == 0 )
+ return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+
+ while( *p < end )
+ {
+ const unsigned char *policy_end;
+
+ /*
+ * Get the policy sequence
+ */
+ if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+ return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+
+ policy_end = *p + len;
+
+ if( ( ret = mbedtls_asn1_get_tag( p, policy_end, &len,
+ MBEDTLS_ASN1_OID ) ) != 0 )
+ return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+
+ if( len != 1 || *p[0] != 1 )
+ parse_ret = MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE;
+
+ *p += len;
+
+ /*
+ * If there is an optional qualifier, then *p < policy_end
+ * Check the Qualifier len to verify it doesn't exceed policy_end.
+ */
+ if( *p < policy_end )
+ {
+ if( ( ret = mbedtls_asn1_get_tag( p, policy_end, &len,
+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+ return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+ /*
+ * Skip the optional policy qualifiers.
+ */
+ *p += len;
+ }
+
+ if( *p != policy_end )
+ return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ }
+
+ if( *p != end )
+ return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+
+ return( parse_ret );
+ }
+ else if( new_oid != NULL && new_oid->tag == oid->tag && new_oid->len == oid->len &&
+ memcmp( new_oid->p, oid->p, oid->len ) == 0 )
+ return( 0 );
+ else
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
- return( 0 );
}
#endif /* MBEDTLS_X509_CRT_PARSE_C */
/* END_HEADER */