From 2c6cc045c27318157792f6944044ee83b1486a7a Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Thu, 21 Feb 2019 13:30:50 +0000 Subject: [PATCH] Add function to traverse raw SubjectAltName extension This commit adds a new function `x509_subject_alt_name_traverse()` which allows to traverse the raw ASN.1 data of a `SubjectAlternativeNames` extension. The `SubjectAlternativeNames` extension needs to be traversed in the following situations: 1 Initial traversal to check well-formedness of ASN.1 data 2 Traversal to check for a particular name component 3 Building the legacy linked list presentation Analogously to how multiple tasks related to X.509 name comparison are implemented through the workhorse `mbedtlS_x509_name_cmp_raw()`, the new function `x509_subject_alt_name_traverse()` allows to pass an arbitrary callback which is called on any component of the `SubjectAlternativeNames` extension found. This way, the above three tasks can be implemented by passing 1 a NULL callback, 2 a name comparison callback 3 a linked list building callback. --- library/x509_crt.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/library/x509_crt.c b/library/x509_crt.c index c628e812a..a38f74981 100644 --- a/library/x509_crt.c +++ b/library/x509_crt.c @@ -517,6 +517,56 @@ static int x509_get_ext_key_usage( unsigned char **p, * * NOTE: we only parse and use dNSName at this point. */ +static int x509_subject_alt_name_traverse( unsigned char *p, + const unsigned char *end, + int (*cb)( void *ctx, + int tag, + unsigned char *data, + size_t data_len ), + void *ctx ) +{ + int ret; + size_t len; + + /* Get main sequence tag */ + if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) + { + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); + } + + if( p + len != end ) + { + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + } + + while( p < end ) + { + unsigned char const tag = *p++; + if( ( ret = mbedtls_asn1_get_len( &p, end, &len ) ) != 0 ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); + + if( ( tag & MBEDTLS_ASN1_TAG_CLASS_MASK ) != + MBEDTLS_ASN1_CONTEXT_SPECIFIC ) + { + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); + } + + if( cb != NULL ) + { + ret = cb( ctx, tag, p, len ); + if( ret != 0 ) + return( ret ); + } + + p += len; + } + + return( 0 ); +} + static int x509_get_subject_alt_name( unsigned char **p, const unsigned char *end, mbedtls_x509_sequence *subject_alt_name )