mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2024-11-26 04:55:44 +01:00
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.
This commit is contained in:
parent
0806379e3e
commit
890819a597
@ -107,6 +107,11 @@ mbedtls_x509_crt;
|
||||
*/
|
||||
typedef struct mbedtls_x509_san_other_name
|
||||
{
|
||||
/**
|
||||
* The type_id is an OID as deifned in RFC 5280.
|
||||
* To check the value of the type id, you should use
|
||||
* \p MBEDTLS_OID_CMP with a known OID mbedtls_x509_buf.
|
||||
*/
|
||||
mbedtls_x509_buf type_id; /**< The type id. */
|
||||
union
|
||||
{
|
||||
@ -133,7 +138,6 @@ typedef struct mbedtls_x509_subject_alternative_name
|
||||
mbedtls_x509_buf unstructured_name; /**< The buffer for the un constructed types. Only dnsName currently supported */
|
||||
}
|
||||
san; /**< A union of the supported SAN types */
|
||||
struct mbedtls_x509_subject_alternative_name *next; /**< The next SAN in the list. */
|
||||
}
|
||||
mbedtls_x509_subject_alternative_name;
|
||||
|
||||
@ -389,24 +393,30 @@ int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path );
|
||||
|
||||
#endif /* MBEDTLS_FS_IO */
|
||||
/**
|
||||
* \brief Parses the subject alternative name list of a given certificate.
|
||||
* \brief Parses a subject alternative name item
|
||||
* to an identified structure;
|
||||
*
|
||||
* \param crt The X509 certificate to parse.
|
||||
* \param san A list holding the parsed certificate.
|
||||
* \param san_buf The buffer holding the raw data item of the subject
|
||||
* alternative name.
|
||||
* \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,
|
||||
* as defined in RFC 4180 is supported.
|
||||
*
|
||||
* \note Any unsupported san type is ignored.
|
||||
* \note This function should be called on a single raw data of
|
||||
* subject alternative name. For example, after successfult
|
||||
* certificate parsing, one must iterate on every item in the
|
||||
* \p crt->subject_alt_names sequence, and send it as parameter
|
||||
* to this function.
|
||||
*
|
||||
* \note The function allocates a list of mbedtls_x509_subject_alternative_name
|
||||
* and it is the caller's responsibility to free it.
|
||||
*
|
||||
* \return Zero for success and negative
|
||||
* value for any other failure.
|
||||
* \return \c 0 on success
|
||||
* \return #MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE for an unsupported
|
||||
* SAN type
|
||||
* \return Negative value for any other failure.
|
||||
*/
|
||||
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 );
|
||||
/**
|
||||
* \brief Returns an informational string about the
|
||||
* certificate.
|
||||
|
@ -1632,6 +1632,12 @@ static int x509_get_other_name( const mbedtls_x509_buf *subject_alt_name,
|
||||
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 @@ static int x509_get_other_name( const mbedtls_x509_buf *subject_alt_name,
|
||||
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 @@ static int x509_info_subject_alt_name( char **buf, size_t *size,
|
||||
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 @@ static int x509_info_subject_alt_name( char **buf, size_t *size,
|
||||
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 );
|
||||
}
|
||||
|
||||
|
@ -303,8 +303,10 @@ int verify_parse_san( mbedtls_x509_subject_alternative_name *san,
|
||||
/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C */
|
||||
void x509_parse_san( char * crt_file, char * result_str )
|
||||
{
|
||||
int ret;
|
||||
mbedtls_x509_crt crt;
|
||||
mbedtls_x509_subject_alternative_name *cur, *next, *san = NULL;
|
||||
mbedtls_x509_subject_alternative_name san;
|
||||
mbedtls_x509_sequence *cur = NULL;
|
||||
char buf[2000];
|
||||
char *p = buf;
|
||||
size_t n = sizeof( buf );
|
||||
@ -313,24 +315,27 @@ void x509_parse_san( char * crt_file, char * result_str )
|
||||
memset( buf, 0, 2000 );
|
||||
|
||||
TEST_ASSERT( mbedtls_x509_crt_parse_file( &crt, crt_file ) == 0 );
|
||||
TEST_ASSERT( mbedtls_x509_parse_subject_alternative_name( &crt, &san ) == 0 );
|
||||
cur = san;
|
||||
while( cur != NULL )
|
||||
|
||||
if( crt.ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME )
|
||||
{
|
||||
TEST_ASSERT( verify_parse_san( cur, &p, &n ) == 0 );
|
||||
cur = cur->next;
|
||||
cur = &crt.subject_alt_names;
|
||||
while( cur != NULL )
|
||||
{
|
||||
ret = mbedtls_x509_parse_subject_alt_name( &cur->buf, &san );
|
||||
TEST_ASSERT( ret == 0 || ret == MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE );
|
||||
/*
|
||||
* If san type not supported, ignore.
|
||||
*/
|
||||
if( ret == 0)
|
||||
TEST_ASSERT( verify_parse_san( &san, &p, &n ) == 0 );
|
||||
cur = cur->next;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_ASSERT( strcmp( buf, result_str ) == 0 );
|
||||
|
||||
exit:
|
||||
|
||||
for( cur = san; cur != NULL; cur = next )
|
||||
{
|
||||
next = cur->next;
|
||||
mbedtls_free( cur );
|
||||
}
|
||||
|
||||
mbedtls_x509_crt_free( &crt );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
Loading…
Reference in New Issue
Block a user