/* * Name ::= CHOICE { -- only one possibility for now -- * rdnSequence RDNSequence } * * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName * * RelativeDistinguishedName ::= * SET OF AttributeTypeAndValue * * AttributeTypeAndValue ::= SEQUENCE { * type AttributeType, * value AttributeValue } * * AttributeType ::= OBJECT IDENTIFIER * * AttributeValue ::= ANY DEFINED BY AttributeType * * The data structure is optimized for the common case where each RDN has only * one element, which is represented as a list of AttributeTypeAndValue. * For the general case we still use a flat list, but we mark elements of the * same set so that they are "merged" together in the functions that consume * this list, eg x509_dn_gets(). */ int x509_get_name( unsigned char **p, const unsigned char *end, x509_name *cur ) { int ret; size_t set_len; const unsigned char *end_set; /* don't use recursion, we'd risk stack overflow if not optimized */ while( 1 ) { /* * parse SET */ if( ( ret = asn1_get_tag( p, end, &set_len, ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 ) return( POLARSSL_ERR_X509_INVALID_NAME + ret ); end_set = *p + set_len; while( 1 ) { if( ( ret = x509_get_attr_type_value( p, end_set, cur ) ) != 0 ) return( ret ); if( *p == end_set ) break; /* Mark this item as being not the only one in a set */ cur->next_merged = 1; cur->next = polarssl_malloc( sizeof( x509_name ) ); if( cur->next == NULL ) return( POLARSSL_ERR_X509_MALLOC_FAILED ); memset( cur->next, 0, sizeof( x509_name ) ); cur = cur->next; } /* * continue until end of SEQUENCE is reached */ if( *p == end ) return( 0 ); cur->next = polarssl_malloc( sizeof( x509_name ) ); if( cur->next == NULL ) return( POLARSSL_ERR_X509_MALLOC_FAILED ); memset( cur->next, 0, sizeof( x509_name ) ); cur = cur->next; } }
/* * RelativeDistinguishedName ::= * SET OF AttributeTypeAndValue * * AttributeTypeAndValue ::= SEQUENCE { * type AttributeType, * value AttributeValue } * * AttributeType ::= OBJECT IDENTIFIER * * AttributeValue ::= ANY DEFINED BY AttributeType */ int x509_get_name( unsigned char **p, const unsigned char *end, x509_name *cur ) { int ret; size_t len; const unsigned char *end2; x509_name *use; if( ( ret = asn1_get_tag( p, end, &len, ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 ) return( POLARSSL_ERR_X509_INVALID_NAME + ret ); end2 = end; end = *p + len; use = cur; do { if( ( ret = x509_get_attr_type_value( p, end, use ) ) != 0 ) return( ret ); if( *p != end ) { use->next = (x509_name *) polarssl_malloc( sizeof( x509_name ) ); if( use->next == NULL ) return( POLARSSL_ERR_X509_MALLOC_FAILED ); memset( use->next, 0, sizeof( x509_name ) ); use = use->next; } } while( *p != end ); /* * recurse until end of SEQUENCE is reached */ if( *p == end2 ) return( 0 ); cur->next = (x509_name *) polarssl_malloc( sizeof( x509_name ) ); if( cur->next == NULL ) return( POLARSSL_ERR_X509_MALLOC_FAILED ); memset( cur->next, 0, sizeof( x509_name ) ); return( x509_get_name( p, end2, cur->next ) ); }
/* * RelativeDistinguishedName ::= * SET OF AttributeTypeAndValue * * AttributeTypeAndValue ::= SEQUENCE { * type AttributeType, * value AttributeValue } * * AttributeType ::= OBJECT IDENTIFIER * * AttributeValue ::= ANY DEFINED BY AttributeType * * We restrict RelativeDistinguishedName to be a set of 1 element. This is * the most common case, and our x509_name structure currently can't handle * more than that. */ int x509_get_name( unsigned char **p, const unsigned char *end, x509_name *cur ) { int ret; size_t set_len; const unsigned char *end_set; /* * parse first SET, restricted to 1 element */ if( ( ret = asn1_get_tag( p, end, &set_len, ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 ) return( POLARSSL_ERR_X509_INVALID_NAME + ret ); end_set = *p + set_len; if( ( ret = x509_get_attr_type_value( p, end_set, cur ) ) != 0 ) return( ret ); if( *p != end_set ) return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE ); /* * recurse until end of SEQUENCE is reached */ if( *p == end ) return( 0 ); cur->next = (x509_name *) polarssl_malloc( sizeof( x509_name ) ); if( cur->next == NULL ) return( POLARSSL_ERR_X509_MALLOC_FAILED ); memset( cur->next, 0, sizeof( x509_name ) ); return( x509_get_name( p, end, cur->next ) ); }