Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions scripts/asn1_oid_sum.pl
Original file line number Diff line number Diff line change
Expand Up @@ -1287,6 +1287,7 @@ sub print_footer {
my @name_description = ( 2, 5, 4, 13 );
my @name_business_cat = ( 2, 5, 4, 15 );
my @name_postal_code = ( 2, 5, 4, 17 );
my @name_x500_unique_id = ( 2, 5, 4, 45 );
my @name_pkcs9_email = ( 1, 2, 840, 113549, 1, 9, 1 );;
my @name_rfc822_mailbox = ( 0, 9, 2342, 19200300, 100, 1, 3 );
my @name_fav_drink = ( 0, 9, 2342, 19200300, 100, 1, 5 );
Expand Down Expand Up @@ -1317,6 +1318,7 @@ sub print_footer {
same => 1 },
{ name => "WC_NAME_INITIALIS", oid => \@csr_initials,
same => 1 },
{ name => "WC_NAME_X500_UNIQUE_ID", oid => \@name_x500_unique_id },
{ name => "WC_NAME_EMAIL_ADDRESS", oid => \@name_pkcs9_email },
{ name => "WC_NAME_USER_ID", oid => \@csr_user_id,
same => 1 },
Expand Down
2 changes: 2 additions & 0 deletions src/ssl_asn1.c
Original file line number Diff line number Diff line change
Expand Up @@ -5068,6 +5068,8 @@ const WOLFSSL_ObjectInfo wolfssl_object_info[] = {

/* Rarely used and legacy attributes. */
{ WC_NID_userId, WC_NAME_USER_ID_OID, oidCertNameType, "UID", "userId"},
{ WC_NID_x500UniqueIdentifier, WC_NAME_X500_UNIQUE_ID_OID, oidCertNameType,
"x500UniqueIdentifier", "X500 unique identifier"},
{ WC_NID_title, WC_NAME_TITLE_OID, oidCertNameType, "title", "title"},
{ WC_NID_description, WC_NAME_DESCRIPTION_OID, oidCertNameType,
"description", "description"},
Expand Down
206 changes: 206 additions & 0 deletions tests/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,211 @@ defined(USE_CERT_BUFFERS_2048)
return EXPECT_RESULT();
}

/* Test parsing an x500UniqueIdentifier (OID 2.5.4.45) in a subject/issuer DN.
* Its value is a BIT STRING, which the RDN parser used to reject. */
static int test_wc_ParseCert_uniqueIdentifier(void)
{
EXPECT_DECLS;
#if !defined(NO_CERTS) && defined(WOLFSSL_ASN_TEMPLATE) && defined(HAVE_ECC)
/* Self-signed ECDSA P-256 certificate with an x500UniqueIdentifier BIT
* STRING in both subject and issuer DN. Built with asn1crypto and
* pyca/cryptography, verified with OpenSSL. */
static const byte leafUniqueIdDer[] = {
0x30, 0x82, 0x01, 0x8C, 0x30, 0x82, 0x01, 0x32, 0xA0, 0x03, 0x02, 0x01,
0x02, 0x02, 0x06, 0x0E, 0xAF, 0x12, 0x34, 0x56, 0x78, 0x30, 0x0A, 0x06,
0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x30, 0x4D, 0x31,
0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x08, 0x54,
0x65, 0x73, 0x74, 0x20, 0x4F, 0x72, 0x67, 0x31, 0x17, 0x30, 0x15, 0x06,
0x03, 0x55, 0x04, 0x03, 0x0C, 0x0E, 0x4C, 0x45, 0x41, 0x46, 0x20, 0x54,
0x65, 0x73, 0x74, 0x20, 0x43, 0x61, 0x72, 0x64, 0x31, 0x12, 0x30, 0x10,
0x06, 0x03, 0x55, 0x04, 0x2D, 0x03, 0x09, 0x00, 0x01, 0x23, 0x45, 0x67,
0x89, 0xAB, 0xCD, 0xEF, 0x30, 0x1E, 0x17, 0x0D, 0x32, 0x30, 0x30, 0x31,
0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5A, 0x17, 0x0D, 0x34,
0x39, 0x31, 0x32, 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5A,
0x30, 0x4D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
0x02, 0x55, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A,
0x0C, 0x08, 0x54, 0x65, 0x73, 0x74, 0x20, 0x4F, 0x72, 0x67, 0x31, 0x17,
0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0E, 0x4C, 0x45, 0x41,
0x46, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x61, 0x72, 0x64, 0x31,
0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x2D, 0x03, 0x09, 0x00, 0x01,
0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x30, 0x59, 0x30, 0x13, 0x06,
0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86,
0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x6A, 0x0B,
0x1A, 0xB0, 0x0F, 0x64, 0x3F, 0xF6, 0x3A, 0x23, 0xAD, 0x01, 0x15, 0x9B,
0xF1, 0x8D, 0xA0, 0x70, 0xCF, 0xD3, 0x1F, 0x37, 0x1D, 0xB8, 0x34, 0x13,
0x1E, 0x22, 0xF6, 0xB7, 0x34, 0x6E, 0xC7, 0xDA, 0xDA, 0x6D, 0xA0, 0xC7,
0xD0, 0x3A, 0x42, 0xA3, 0x39, 0xFA, 0xFE, 0x12, 0x7E, 0x50, 0xB0, 0x49,
0xD9, 0x5A, 0xB6, 0x78, 0x72, 0x3B, 0x00, 0x9E, 0x0C, 0x19, 0x67, 0x91,
0x11, 0xA2, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04,
0x03, 0x02, 0x03, 0x48, 0x00, 0x30, 0x45, 0x02, 0x20, 0x56, 0x24, 0x2F,
0xAD, 0xA4, 0x9D, 0xA0, 0x02, 0xFC, 0x2E, 0x61, 0x79, 0x93, 0x88, 0x48,
0x6B, 0x07, 0x99, 0xF2, 0x34, 0x6E, 0x59, 0x39, 0x12, 0xB5, 0xC7, 0x36,
0x2D, 0x87, 0xED, 0xD9, 0xF4, 0x02, 0x21, 0x00, 0xD3, 0x8B, 0x88, 0xD4,
0xE0, 0x60, 0x8C, 0x6D, 0x13, 0x49, 0xE0, 0xDB, 0x65, 0xB7, 0xA9, 0x84,
0xEF, 0xC4, 0xDF, 0x89, 0x08, 0x45, 0xEC, 0x8E, 0x09, 0x41, 0x6A, 0x24,
0x2B, 0x98, 0x4A, 0xFE
};
static const byte expUniqueId[] = {
0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF
};
/* Same certificate but with an embedded 0x00 in the value. The subject
* display string truncates at the NUL, but the WOLFSSL_X509_NAME entry
* must carry the full value. */
static const byte leafEmbeddedNulDer[] = {
0x30, 0x82, 0x01, 0x84, 0x30, 0x82, 0x01, 0x2A, 0xA0, 0x03, 0x02, 0x01,
0x02, 0x02, 0x06, 0x0E, 0xAF, 0x12, 0x34, 0x56, 0x78, 0x30, 0x0A, 0x06,
0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x30, 0x49, 0x31,
0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x08, 0x54,
0x65, 0x73, 0x74, 0x20, 0x4F, 0x72, 0x67, 0x31, 0x17, 0x30, 0x15, 0x06,
0x03, 0x55, 0x04, 0x03, 0x0C, 0x0E, 0x4C, 0x45, 0x41, 0x46, 0x20, 0x54,
0x65, 0x73, 0x74, 0x20, 0x43, 0x61, 0x72, 0x64, 0x31, 0x0E, 0x30, 0x0C,
0x06, 0x03, 0x55, 0x04, 0x2D, 0x03, 0x05, 0x00, 0xAB, 0x00, 0xCD, 0xEF,
0x30, 0x1E, 0x17, 0x0D, 0x32, 0x30, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30,
0x30, 0x30, 0x30, 0x30, 0x5A, 0x17, 0x0D, 0x34, 0x39, 0x31, 0x32, 0x33,
0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5A, 0x30, 0x49, 0x31, 0x0B,
0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x08, 0x54, 0x65,
0x73, 0x74, 0x20, 0x4F, 0x72, 0x67, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03,
0x55, 0x04, 0x03, 0x0C, 0x0E, 0x4C, 0x45, 0x41, 0x46, 0x20, 0x54, 0x65,
0x73, 0x74, 0x20, 0x43, 0x61, 0x72, 0x64, 0x31, 0x0E, 0x30, 0x0C, 0x06,
0x03, 0x55, 0x04, 0x2D, 0x03, 0x05, 0x00, 0xAB, 0x00, 0xCD, 0xEF, 0x30,
0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01,
0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x03, 0x42,
0x00, 0x04, 0xF4, 0xB3, 0x36, 0x65, 0xF2, 0xB7, 0x33, 0x37, 0x8F, 0xB3,
0x75, 0x1A, 0x79, 0x64, 0x18, 0xED, 0x14, 0x9D, 0xEE, 0x03, 0x3B, 0x35,
0x6E, 0xEA, 0x4B, 0x58, 0x86, 0xCC, 0x0C, 0x6A, 0x76, 0x39, 0xBF, 0x01,
0xA1, 0xA7, 0x78, 0xA1, 0x77, 0xF7, 0xCC, 0x12, 0x5E, 0xDF, 0x2F, 0x90,
0x35, 0x02, 0xE2, 0x51, 0x3F, 0x7A, 0x08, 0x85, 0xF5, 0x93, 0x2A, 0xE1,
0xE0, 0x5A, 0x5D, 0x8F, 0x90, 0x50, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86,
0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x03, 0x48, 0x00, 0x30, 0x45, 0x02,
0x21, 0x00, 0xF8, 0xF0, 0x02, 0x98, 0xE2, 0xA5, 0x22, 0x23, 0x80, 0x6B,
0x73, 0xE3, 0x9F, 0xB8, 0xC6, 0x05, 0x64, 0xE9, 0x56, 0x57, 0xC2, 0xEB,
0x02, 0x50, 0x93, 0xA1, 0x0B, 0x57, 0x06, 0x61, 0x55, 0x88, 0x02, 0x20,
0x28, 0xED, 0xDA, 0x90, 0xF2, 0xB0, 0x94, 0x7E, 0xDB, 0xC3, 0x60, 0x6C,
0x87, 0xC1, 0x51, 0x75, 0xC1, 0x04, 0xA7, 0x70, 0xEC, 0x8D, 0x60, 0xA8,
0x28, 0xC2, 0x3E, 0x08, 0x42, 0x64, 0x9C, 0x5B
};
DecodedCert cert;
const char* p = NULL;
byte badDer[sizeof(leafUniqueIdDer)];
word32 i;
int flipped = 0;
#ifdef OPENSSL_EXTRA
static const byte expEmbeddedNul[] = {
0xAB, 0x00, 0xCD, 0xEF
};
WOLFSSL_X509* x509 = NULL;
WOLFSSL_X509_NAME* name = NULL;
WOLFSSL_X509_NAME_ENTRY* entry = NULL;
WOLFSSL_ASN1_STRING* str = NULL;
int idx = -1;
#endif

wc_InitDecodedCert(&cert, leafUniqueIdDer, (word32)sizeof(leafUniqueIdDer),
NULL);
ExpectIntEQ(wc_ParseCert(&cert, CERT_TYPE, NO_VERIFY, NULL), 0);
/* Value is in the subject string with the unused-bits octet stripped. */
ExpectNotNull(p = XSTRSTR(cert.subject, "/x500UniqueIdentifier="));
if (p != NULL) {
p += XSTRLEN("/x500UniqueIdentifier=");
ExpectIntEQ(XMEMCMP(p, expUniqueId, sizeof(expUniqueId)), 0);
}
wc_FreeDecodedCert(&cert);

/* A value with an embedded 0x00 must still parse successfully. */
wc_InitDecodedCert(&cert, leafEmbeddedNulDer,
(word32)sizeof(leafEmbeddedNulDer), NULL);
ExpectIntEQ(wc_ParseCert(&cert, CERT_TYPE, NO_VERIFY, NULL), 0);
wc_FreeDecodedCert(&cert);

/* Malformed variants exercise the parser's BIT STRING guards. Each keeps
* all byte lengths unchanged so the DER stays structurally valid. */

/* (1) Non-zero unused-bits count must be rejected. */
XMEMCPY(badDer, leafUniqueIdDer, sizeof(leafUniqueIdDer));
flipped = 0;
for (i = 0; (i + 6) <= (word32)sizeof(badDer); i++) {
/* OID 2.5.4.45 (55 04 2d), BIT STRING (03), len 9 (09), 0 unused (00) */
if ((badDer[i] == 0x55) && (badDer[i + 1] == 0x04) &&
(badDer[i + 2] == 0x2D) && (badDer[i + 3] == 0x03) &&
(badDer[i + 4] == 0x09) && (badDer[i + 5] == 0x00)) {
badDer[i + 5] = 0x03; /* 3 unused bits - not byte aligned */
flipped++;
}
}
ExpectIntGT(flipped, 0); /* sanity: mutation was applied */
wc_InitDecodedCert(&cert, badDer, (word32)sizeof(badDer), NULL);
ExpectIntNE(wc_ParseCert(&cert, CERT_TYPE, NO_VERIFY, NULL), 0);
wc_FreeDecodedCert(&cert);

/* (2) A BIT STRING under another known attribute must be rejected. */
XMEMCPY(badDer, leafUniqueIdDer, sizeof(leafUniqueIdDer));
flipped = 0;
for (i = 0; (i + 6) <= (word32)sizeof(badDer); i++) {
if ((badDer[i] == 0x55) && (badDer[i + 1] == 0x04) &&
(badDer[i + 2] == 0x2D) && (badDer[i + 3] == 0x03) &&
(badDer[i + 4] == 0x09) && (badDer[i + 5] == 0x00)) {
badDer[i + 2] = 0x03; /* 2.5.4.45 -> 2.5.4.3 (commonName) */
flipped++;
}
}
ExpectIntGT(flipped, 0);
wc_InitDecodedCert(&cert, badDer, (word32)sizeof(badDer), NULL);
ExpectIntNE(wc_ParseCert(&cert, CERT_TYPE, NO_VERIFY, NULL), 0);
wc_FreeDecodedCert(&cert);

/* (3) A BIT STRING under an unrecognized attribute OID must be rejected,
* not silently accepted. */
XMEMCPY(badDer, leafUniqueIdDer, sizeof(leafUniqueIdDer));
flipped = 0;
for (i = 0; (i + 6) <= (word32)sizeof(badDer); i++) {
if ((badDer[i] == 0x55) && (badDer[i + 1] == 0x04) &&
(badDer[i + 2] == 0x2D) && (badDer[i + 3] == 0x03) &&
(badDer[i + 4] == 0x09) && (badDer[i + 5] == 0x00)) {
badDer[i + 2] = 0x7B; /* 2.5.4.45 -> 2.5.4.123 (unassigned) */
flipped++;
}
}
ExpectIntGT(flipped, 0);
wc_InitDecodedCert(&cert, badDer, (word32)sizeof(badDer), NULL);
ExpectIntNE(wc_ParseCert(&cert, CERT_TYPE, NO_VERIFY, NULL), 0);
wc_FreeDecodedCert(&cert);

#ifdef OPENSSL_EXTRA
/* Value is also reachable by NID through the X509_NAME entries. */
ExpectNotNull(x509 = wolfSSL_X509_d2i(NULL, leafUniqueIdDer,
(int)sizeof(leafUniqueIdDer)));
ExpectNotNull(name = wolfSSL_X509_get_subject_name(x509));
ExpectIntGE(idx = wolfSSL_X509_NAME_get_index_by_NID(name,
WC_NID_x500UniqueIdentifier, -1), 0);
ExpectNotNull(entry = wolfSSL_X509_NAME_get_entry(name, idx));
ExpectNotNull(str = wolfSSL_X509_NAME_ENTRY_get_data(entry));
ExpectIntEQ(wolfSSL_ASN1_STRING_length(str), (int)sizeof(expUniqueId));
ExpectIntEQ(XMEMCMP(wolfSSL_ASN1_STRING_get0_data(str), expUniqueId,
sizeof(expUniqueId)), 0);
wolfSSL_X509_free(x509);
x509 = NULL;

/* Embedded 0x00 survives intact in the entry even though it truncates the
* subject display string. */
ExpectNotNull(x509 = wolfSSL_X509_d2i(NULL, leafEmbeddedNulDer,
(int)sizeof(leafEmbeddedNulDer)));
ExpectNotNull(name = wolfSSL_X509_get_subject_name(x509));
ExpectIntGE(idx = wolfSSL_X509_NAME_get_index_by_NID(name,
WC_NID_x500UniqueIdentifier, -1), 0);
ExpectNotNull(entry = wolfSSL_X509_NAME_get_entry(name, idx));
ExpectNotNull(str = wolfSSL_X509_NAME_ENTRY_get_data(entry));
ExpectIntEQ(wolfSSL_ASN1_STRING_length(str), (int)sizeof(expEmbeddedNul));
ExpectIntEQ(XMEMCMP(wolfSSL_ASN1_STRING_get0_data(str), expEmbeddedNul,
sizeof(expEmbeddedNul)), 0);
wolfSSL_X509_free(x509);
#endif /* OPENSSL_EXTRA */
#endif
return EXPECT_RESULT();
}

/*----------------------------------------------------------------------------*
| Method Allocators
*----------------------------------------------------------------------------*/
Expand Down Expand Up @@ -37958,6 +38163,7 @@ TEST_CASE testCases[] = {
TEST_DECL(test_wc_LoadStaticMemory_CTX),

TEST_DECL(test_wc_FreeCertList),
TEST_DECL(test_wc_ParseCert_uniqueIdentifier),
/* Locking with Compat Mutex */
TEST_DECL(test_wc_SetMutexCb),
TEST_DECL(test_wc_LockMutex_ex),
Expand Down
65 changes: 60 additions & 5 deletions wolfcrypt/src/asn.c
Original file line number Diff line number Diff line change
Expand Up @@ -14684,10 +14684,11 @@ enum {
/* Supported types of encodings (tags) for RDN strings.
* X.509: RFC 5280, 4.1.2.4 - DirectoryString
* (IA5 String not listed in RFC but required for alternative types)
* (BIT STRING only for x500UniqueIdentifier - OID 2.5.4.45)
*/
static const byte rdnChoice[] = {
ASN_PRINTABLE_STRING, ASN_IA5_STRING, ASN_UTF8STRING, ASN_T61STRING,
ASN_UNIVERSALSTRING, ASN_BMPSTRING, 0
ASN_UNIVERSALSTRING, ASN_BMPSTRING, ASN_BIT_STRING, 0
};
#endif

Expand Down Expand Up @@ -15177,6 +15178,14 @@ static int GetRDN(DecodedCert* cert, char* full, word32* idx, int* nid,
*nid = GetCertNameSubjectNID(id);
#endif
}
else if (id == ASN_X500_UNIQUE_ID) {
/* Not in the table as its id is outside the contiguous range. */
typeStr = WOLFSSL_X500_UNIQUE_ID;
typeStrLen = sizeof(WOLFSSL_X500_UNIQUE_ID) - 1;
#ifdef WOLFSSL_X509_NAME_AVAILABLE
*nid = WC_NID_x500UniqueIdentifier;
#endif
}
}
else if (oidSz == sizeof(attrEmailOid) && XMEMCMP(oid, attrEmailOid, oidSz) == 0) {
/* Set the email id, type string, length and NID. */
Expand Down Expand Up @@ -15266,6 +15275,15 @@ static int GetRDN(DecodedCert* cert, char* full, word32* idx, int* nid,
}
}

/* rdnChoice[] allows a BIT STRING tag for any attribute OID but only
* x500UniqueIdentifier may use it - all others are DirectoryString
* (RFC 5280, 4.1.2.4). Checked here to also catch unrecognized OIDs. */
if ((ret == 0) && (dataASN[RDNASN_IDX_ATTR_VAL].tag == ASN_BIT_STRING) &&
(id != ASN_X500_UNIQUE_ID)) {
WOLFSSL_MSG("BIT STRING RDN value only valid for x500UniqueIdentifier");
ret = ASN_PARSE_E;
}

if ((ret == 0) && (typeStr != NULL)) {
/* OID type to store for subject name and add to full string. */
const byte* str;
Expand All @@ -15275,14 +15293,27 @@ static int GetRDN(DecodedCert* cert, char* full, word32* idx, int* nid,
/* Get the string reference and length. */
GetASN_GetRef(&dataASN[RDNASN_IDX_ATTR_VAL], &str, &strLen);

if (isSubject) {
/* Strip the BIT STRING unused-bits count octet. Only byte-aligned
* values are supported as the count isn't stored. */
if (tag == ASN_BIT_STRING) {
Comment thread
embhorn marked this conversation as resolved.
if ((strLen == 0) || (str[0] != 0)) {
WOLFSSL_MSG("BIT STRING RDN value not byte-aligned");
ret = ASN_PARSE_E;
}
else {
str++;
strLen--;
}
}

if ((ret == 0) && isSubject) {
/* Store subject field components. */
ret = SetSubject(cert, id, str, (int)strLen, tag);
}
#if (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)) && \
defined(WOLFSSL_HAVE_ISSUER_NAMES)
/* Put issuer common name string and encoding into certificate. */
else {
else if (ret == 0) {
ret = SetIssuer(cert, id, str, (int)strLen, tag);
}
#endif
Expand All @@ -15291,7 +15322,9 @@ static int GetRDN(DecodedCert* cert, char* full, word32* idx, int* nid,
* terminating NUL character. */
if ((typeStrLen + strLen) < (word32)(WC_ASN_NAME_MAX - *idx))
{
/* Add RDN to full string. */
/* Add RDN to full string. Binary values are copied verbatim,
* so this display string may truncate at an embedded NUL - use
* the WOLFSSL_X509_NAME entry for the full value. */
XMEMCPY(&full[*idx], typeStr, typeStrLen);
*idx += typeStrLen;
XMEMCPY(&full[*idx], str, strLen);
Expand Down Expand Up @@ -15427,6 +15460,25 @@ static int GetCertName(DecodedCert* cert, char* full, byte* hash, int nameType,
}
#endif

/* Only x500UniqueIdentifier may be a BIT STRING. Strip the
* unused-bits count octet - only byte-aligned values are
* supported as the count isn't stored. */
if (tag == ASN_BIT_STRING) {
if (nid != WC_NID_x500UniqueIdentifier) {
WOLFSSL_MSG("BIT STRING RDN value only valid for "
"x500UniqueIdentifier");
ret = ASN_PARSE_E;
}
else if ((strLen == 0) || (str[0] != 0)) {
WOLFSSL_MSG("BIT STRING RDN value not byte-aligned");
ret = ASN_PARSE_E;
}
else {
str++;
strLen--;
}
}

/* Convert BER tag to a OpenSSL type. */
switch (tag) {
case CTC_UTF8:
Expand All @@ -15435,11 +15487,14 @@ static int GetCertName(DecodedCert* cert, char* full, byte* hash, int nameType,
case CTC_PRINTABLE:
enc = WOLFSSL_V_ASN1_PRINTABLESTRING;
break;
case ASN_BIT_STRING:
enc = WOLFSSL_V_ASN1_BIT_STRING;
break;
default:
WOLFSSL_MSG("Unknown encoding type, default UTF8");
enc = WOLFSSL_MBSTRING_UTF8;
}
if (nid != 0) {
if ((ret == 0) && (nid != 0)) {
/* Add an entry to the X509_NAME. */
if (wolfSSL_X509_NAME_add_entry_by_NID(dName, nid, enc, str,
(int)strLen, -1, -1) != WOLFSSL_SUCCESS) {
Expand Down
Loading
Loading