Skip to content

Commit d320260

Browse files
Merge pull request #6525 from lealem47/san
Improve subjectAltName extension parsing and printing
2 parents 2acc4a6 + 318c95a commit d320260

5 files changed

Lines changed: 253 additions & 11 deletions

File tree

configure.ac

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8173,6 +8173,9 @@ then
81738173

81748174
# Uses alt name
81758175
ENABLED_ALTNAMES="yes"
8176+
8177+
AM_CFLAGS="$AM_CFLAGS -DHAVE_OID_ENCODING -DWOLFSSL_NO_ASN_STRICT"
8178+
81768179
fi
81778180

81788181
if test "$ENABLED_STRONGSWAN" = "yes"; then

src/ssl.c

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24918,7 +24918,9 @@ const WOLFSSL_ObjectInfo wolfssl_object_info[] = {
2491824918

2491924919
/* oidCertNameType */
2492024920
{ NID_commonName, NID_commonName, oidCertNameType, "CN", "commonName"},
24921+
#if !defined(WOLFSSL_CERT_REQ)
2492124922
{ NID_surname, NID_surname, oidCertNameType, "SN", "surname"},
24923+
#endif
2492224924
{ NID_serialNumber, NID_serialNumber, oidCertNameType, "serialNumber",
2492324925
"serialNumber"},
2492424926
{ NID_userId, NID_userId, oidCertNameType, "UID", "userid"},
@@ -33109,6 +33111,24 @@ word32 nid2oid(int nid, int grp)
3310933111
}
3311033112
break;
3311133113

33114+
/* oidCmsKeyAgreeType */
33115+
#ifdef WOLFSSL_CERT_REQ
33116+
case oidCsrAttrType:
33117+
switch (nid) {
33118+
case NID_pkcs9_contentType:
33119+
return PKCS9_CONTENT_TYPE_OID;
33120+
case NID_pkcs9_challengePassword:
33121+
return CHALLENGE_PASSWORD_OID;
33122+
case NID_serialNumber:
33123+
return SERIAL_NUMBER_OID;
33124+
case NID_userId:
33125+
return USER_ID_OID;
33126+
case NID_surname:
33127+
return SURNAME_OID;
33128+
}
33129+
break;
33130+
#endif
33131+
3311233132
default:
3311333133
WOLFSSL_MSG("NID not in table");
3311433134
/* MSVC warns without the cast */
@@ -33487,7 +33507,7 @@ int oid2nid(word32 oid, int grp)
3348733507
#endif
3348833508

3348933509
default:
33490-
WOLFSSL_MSG("NID not in table");
33510+
WOLFSSL_MSG("OID not in table");
3349133511
}
3349233512
/* If not found in above switch then try the table */
3349333513
for (i = 0; i < WOLFSSL_OBJECT_INFO_SZ; i++) {

src/x509.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5866,11 +5866,21 @@ static int X509PrintSubjAltName(WOLFSSL_BIO* bio, WOLFSSL_X509* x509,
58665866
else if (entry->type == ASN_URI_TYPE) {
58675867
len = XSNPRINTF(scratch, MAX_WIDTH, "URI:%s",
58685868
entry->name);
5869+
if (len >= MAX_WIDTH) {
5870+
ret = WOLFSSL_FAILURE;
5871+
break;
5872+
}
5873+
}
5874+
#if defined(OPENSSL_ALL)
5875+
else if (entry->type == ASN_RID_TYPE) {
5876+
len = XSNPRINTF(scratch, MAX_WIDTH, "Registered ID:%s",
5877+
entry->ridString);
58695878
if (len >= MAX_WIDTH) {
58705879
ret = WOLFSSL_FAILURE;
58715880
break;
58725881
}
58735882
}
5883+
#endif
58745884
else if (entry->type == ASN_OTHER_TYPE) {
58755885
len = XSNPRINTF(scratch, MAX_WIDTH,
58765886
"othername <unsupported>");

wolfcrypt/src/asn.c

Lines changed: 207 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5465,13 +5465,18 @@ static int CheckCurve(word32 oid)
54655465
* @return BAD_FUNC_ARG when in or outSz is NULL.
54665466
* @return BUFFER_E when buffer too small.
54675467
*/
5468+
int wc_EncodeObjectId(const word16* in, word32 inSz, byte* out, word32* outSz)
5469+
{
5470+
return EncodeObjectId(in, inSz, out, outSz);
5471+
}
5472+
54685473
int EncodeObjectId(const word16* in, word32 inSz, byte* out, word32* outSz)
54695474
{
54705475
int i, x, len;
54715476
word32 d, t;
54725477

54735478
/* check args */
5474-
if (in == NULL || outSz == NULL) {
5479+
if (in == NULL || outSz == NULL || inSz <= 0) {
54755480
return BAD_FUNC_ARG;
54765481
}
54775482

@@ -5540,7 +5545,8 @@ int EncodeObjectId(const word16* in, word32 inSz, byte* out, word32* outSz)
55405545
}
55415546
#endif /* HAVE_OID_ENCODING */
55425547

5543-
#if defined(HAVE_OID_DECODING) || defined(WOLFSSL_ASN_PRINT)
5548+
#if defined(HAVE_OID_DECODING) || defined(WOLFSSL_ASN_PRINT) || \
5549+
defined(OPENSSL_ALL)
55445550
/* Encode dotted form of OID into byte array version.
55455551
*
55465552
* @param [in] in Byte array containing OID.
@@ -5587,7 +5593,7 @@ int DecodeObjectId(const byte* in, word32 inSz, word16* out, word32* outSz)
55875593

55885594
return 0;
55895595
}
5590-
#endif /* HAVE_OID_DECODING */
5596+
#endif /* HAVE_OID_DECODING || WOLFSSL_ASN_PRINT || OPENSSL_ALL */
55915597

55925598
/* Decode the header of a BER/DER encoded OBJECT ID.
55935599
*
@@ -11196,6 +11202,9 @@ void FreeAltNames(DNS_entry* altNames, void* heap)
1119611202
XFREE(altNames->name, heap, DYNAMIC_TYPE_ALTNAME);
1119711203
#if defined(OPENSSL_ALL) || defined(WOLFSSL_IP_ALT_NAME)
1119811204
XFREE(altNames->ipString, heap, DYNAMIC_TYPE_ALTNAME);
11205+
#endif
11206+
#if defined(OPENSSL_ALL)
11207+
XFREE(altNames->ridString, heap, DYNAMIC_TYPE_ALTNAME);
1119911208
#endif
1120011209
XFREE(altNames, heap, DYNAMIC_TYPE_ALTNAME);
1120111210
altNames = tmp;
@@ -12970,6 +12979,90 @@ static int GenerateDNSEntryIPString(DNS_entry* entry, void* heap)
1297012979
}
1297112980
#endif /* OPENSSL_ALL || WOLFSSL_IP_ALT_NAME */
1297212981

12982+
#if defined(OPENSSL_ALL)
12983+
/* used to set the human readable string for the registeredID with an
12984+
* ASN_RID_TYPE DNS entry
12985+
* return 0 on success
12986+
*/
12987+
static int GenerateDNSEntryRIDString(DNS_entry* entry, void* heap)
12988+
{
12989+
int i, j, ret = 0;
12990+
int nameSz = 0;
12991+
int numerical = 0;
12992+
int nid = 0;
12993+
int tmpSize = MAX_OID_SZ;
12994+
word32 oid = 0;
12995+
word32 idx = 0;
12996+
word16 tmpName[MAX_OID_SZ];
12997+
char oidName[MAX_OID_SZ];
12998+
char* finalName;
12999+
13000+
if (entry == NULL || entry->type != ASN_RID_TYPE) {
13001+
return BAD_FUNC_ARG;
13002+
}
13003+
13004+
if (entry->len <= 0) {
13005+
return BAD_FUNC_ARG;
13006+
}
13007+
13008+
XMEMSET(&oidName, 0, MAX_OID_SZ);
13009+
13010+
ret = GetOID((const byte*)entry->name, &idx, &oid, oidIgnoreType,
13011+
entry->len);
13012+
13013+
if (ret == 0 && (nid = oid2nid(oid, oidCsrAttrType)) > 0) {
13014+
/* OID has known string value */
13015+
finalName = (char*)wolfSSL_OBJ_nid2ln(nid);
13016+
}
13017+
else {
13018+
/* Decode OBJECT_ID into dotted form array. */
13019+
ret = DecodeObjectId((const byte*)(entry->name),(word32)entry->len,
13020+
tmpName, (word32*)&tmpSize);
13021+
13022+
numerical = 1;
13023+
if (ret == 0) {
13024+
j = 0;
13025+
/* Append each number of dotted form. */
13026+
for (i = 0; i < tmpSize; i++) {
13027+
ret = XSNPRINTF(oidName + j, MAX_OID_SZ, "%d", tmpName[i]);
13028+
if (ret >= 0) {
13029+
j += ret;
13030+
if (i < tmpSize - 1) {
13031+
oidName[j] = '.';
13032+
j++;
13033+
}
13034+
}
13035+
else {
13036+
return BUFFER_E;
13037+
}
13038+
}
13039+
ret = 0;
13040+
finalName = oidName;
13041+
}
13042+
}
13043+
13044+
if (ret == 0) {
13045+
nameSz = (int)XSTRLEN((const char*)finalName);
13046+
13047+
entry->ridString = (char*)XMALLOC(nameSz + numerical, heap,
13048+
DYNAMIC_TYPE_ALTNAME);
13049+
13050+
if (entry->ridString == NULL) {
13051+
ret = MEMORY_E;
13052+
}
13053+
13054+
if (ret == 0) {
13055+
XMEMCPY(entry->ridString, finalName, nameSz);
13056+
if (numerical) {
13057+
entry->ridString[nameSz] = '\0';
13058+
}
13059+
}
13060+
}
13061+
13062+
return ret;
13063+
}
13064+
#endif /* OPENSSL_ALL && WOLFSSL_ASN_TEMPLATE */
13065+
1297313066
#ifdef WOLFSSL_ASN_TEMPLATE
1297413067

1297513068
#if defined(WOLFSSL_CERT_GEN) || !defined(NO_CERTS)
@@ -13048,6 +13141,15 @@ static int SetDNSEntry(DecodedCert* cert, const char* str, int strLen,
1304813141
XMEMCPY(dnsEntry->name, str, (size_t)strLen);
1304913142
dnsEntry->name[strLen] = '\0';
1305013143

13144+
#if defined(OPENSSL_ALL)
13145+
/* store registeredID as a string */
13146+
if (type == ASN_RID_TYPE) {
13147+
if ((ret = GenerateDNSEntryRIDString(dnsEntry, cert->heap)) != 0) {
13148+
XFREE(dnsEntry->name, cert->heap, DYNAMIC_TYPE_ALTNAME);
13149+
XFREE(dnsEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
13150+
}
13151+
}
13152+
#endif
1305113153
#if defined(OPENSSL_ALL) || defined(WOLFSSL_IP_ALT_NAME)
1305213154
/* store IP addresses as a string */
1305313155
if (type == ASN_IP_TYPE) {
@@ -17599,6 +17701,15 @@ static int DecodeGeneralName(const byte* input, word32* inOutIdx, byte tag,
1759917701
}
1760017702
}
1760117703
#endif /* WOLFSSL_QT || OPENSSL_ALL */
17704+
17705+
/* GeneralName choice: registeredID */
17706+
else if (tag == (ASN_CONTEXT_SPECIFIC | ASN_RID_TYPE)) {
17707+
ret = SetDNSEntry(cert, (const char*)(input + idx), len,
17708+
ASN_RID_TYPE, &cert->altNames);
17709+
if (ret == 0) {
17710+
idx += (word32)len;
17711+
}
17712+
}
1760217713
#endif /* IGNORE_NAME_CONSTRAINTS */
1760317714
#if defined(WOLFSSL_SEP) || defined(WOLFSSL_FPKI)
1760417715
/* GeneralName choice: otherName */
@@ -17607,8 +17718,7 @@ static int DecodeGeneralName(const byte* input, word32* inOutIdx, byte tag,
1760717718
ret = DecodeOtherName(cert, input, &idx, idx + (word32)len);
1760817719
}
1760917720
#endif
17610-
/* GeneralName choice: dNSName, x400Address, ediPartyName,
17611-
* registeredID */
17721+
/* GeneralName choice: dNSName, x400Address, ediPartyName */
1761217722
else {
1761317723
WOLFSSL_MSG("\tUnsupported name type, skipping");
1761417724
idx += (word32)len;
@@ -18118,7 +18228,55 @@ static int DecodeAltNames(const byte* input, word32 sz, DecodedCert* cert)
1811818228
length -= strLen;
1811918229
idx += (word32)strLen;
1812018230
}
18121-
#endif /* WOLFSSL_QT || OPENSSL_ALL */
18231+
#endif /* WOLFSSL_QT || OPENSSL_ALL || WOLFSSL_IP_ALT_NAME */
18232+
#if defined(OPENSSL_ALL)
18233+
else if (current_byte == (ASN_CONTEXT_SPECIFIC | ASN_RID_TYPE)) {
18234+
DNS_entry* rid;
18235+
int strLen;
18236+
word32 lenStartIdx = idx;
18237+
WOLFSSL_MSG("Decoding Subject Alt. Name: Registered Id");
18238+
18239+
if (GetLength(input, &idx, &strLen, sz) < 0) {
18240+
WOLFSSL_MSG("\tfail: str length");
18241+
return ASN_PARSE_E;
18242+
}
18243+
length -= (idx - lenStartIdx);
18244+
/* check that strLen at index is not past input buffer */
18245+
if (strLen + idx > sz) {
18246+
return BUFFER_E;
18247+
}
18248+
18249+
rid = AltNameNew(cert->heap);
18250+
if (rid == NULL) {
18251+
WOLFSSL_MSG("\tOut of Memory");
18252+
return MEMORY_E;
18253+
}
18254+
18255+
rid->type = ASN_RID_TYPE;
18256+
rid->name = (char*)XMALLOC((size_t)strLen + 1, cert->heap,
18257+
DYNAMIC_TYPE_ALTNAME);
18258+
if (rid->name == NULL) {
18259+
WOLFSSL_MSG("\tOut of Memory");
18260+
XFREE(rid, cert->heap, DYNAMIC_TYPE_ALTNAME);
18261+
return MEMORY_E;
18262+
}
18263+
rid->len = strLen;
18264+
XMEMCPY(rid->name, &input[idx], strLen);
18265+
rid->name[strLen] = '\0';
18266+
18267+
if (GenerateDNSEntryRIDString(rid, cert->heap) != 0) {
18268+
WOLFSSL_MSG("\tOut of Memory for registerd Id string");
18269+
XFREE(rid->name, cert->heap, DYNAMIC_TYPE_ALTNAME);
18270+
XFREE(rid, cert->heap, DYNAMIC_TYPE_ALTNAME);
18271+
return MEMORY_E;
18272+
}
18273+
18274+
AddAltName(cert, rid);
18275+
18276+
length -= strLen;
18277+
idx += (word32)strLen;
18278+
}
18279+
#endif /* OPENSSL_ALL */
1812218280
#endif /* IGNORE_NAME_CONSTRAINTS */
1812318281
else if (current_byte ==
1812418282
(ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_OTHER_TYPE)) {
@@ -21191,6 +21349,22 @@ static int DecodeCertReqAttrValue(DecodedCert* cert, int* criticalExt,
2119121349
}
2119221350
break;
2119321351

21352+
case UNSTRUCTURED_NAME_OID:
21353+
/* Clear dynamic data and specify choices acceptable. */
21354+
XMEMSET(strDataASN, 0, sizeof(strDataASN));
21355+
GetASN_Choice(&strDataASN[STRATTRASN_IDX_STR], strAttrChoice);
21356+
/* Parse a string. */
21357+
ret = GetASN_Items(strAttrASN, strDataASN, strAttrASN_Length,
21358+
1, input, &idx, maxIdx);
21359+
if (ret == 0) {
21360+
/* Store references to unstructured name. */
21361+
cert->unstructuredName =
21362+
(char*)strDataASN[STRATTRASN_IDX_STR].data.ref.data;
21363+
cert->unstructuredNameLen = (int)strDataASN[STRATTRASN_IDX_STR].
21364+
data.ref.length;
21365+
}
21366+
break;
21367+
2119421368
/* Certificate extensions to be included in generated certificate.
2119521369
* PKCS#9: RFC 2985, 5.4.2 - Extension request
2119621370
*/
@@ -29706,6 +29880,11 @@ static const ASNItem certReqBodyASN[] = {
2970629880
/* ATTRS_CPW_SET */ { 3, ASN_SET, 1, 1, 0 },
2970729881
/* ATTRS_CPW_PS */ { 4, ASN_PRINTABLE_STRING, 0, 0, 0 },
2970829882
/* ATTRS_CPW_UTF */ { 4, ASN_UTF8STRING, 0, 0, 0 },
29883+
/* ATTRS_USN_SEQ */ { 2, ASN_SEQUENCE, 1, 1, 1 },
29884+
/* ATTRS_USN_OID */ { 3, ASN_OBJECT_ID, 0, 0, 0 },
29885+
/* ATTRS_USN_SET */ { 3, ASN_SET, 1, 1, 0 },
29886+
/* ATTRS_USN_PS */ { 4, ASN_PRINTABLE_STRING, 0, 0, 0 },
29887+
/* ATTRS_USN_UTF */ { 4, ASN_UTF8STRING, 0, 0, 0 },
2970929888
/* Extensions Attribute */
2971029889
/* EXT_SEQ */ { 2, ASN_SEQUENCE, 1, 1, 1 },
2971129890
/* EXT_OID */ { 3, ASN_OBJECT_ID, 0, 0, 0 },
@@ -29723,6 +29902,11 @@ enum {
2972329902
CERTREQBODYASN_IDX_ATTRS_CPW_SET,
2972429903
CERTREQBODYASN_IDX_ATTRS_CPW_PS,
2972529904
CERTREQBODYASN_IDX_ATTRS_CPW_UTF,
29905+
CERTREQBODYASN_IDX_ATTRS_USN_SEQ,
29906+
CERTREQBODYASN_IDX_ATTRS_USN_OID,
29907+
CERTREQBODYASN_IDX_ATTRS_USN_SET,
29908+
CERTREQBODYASN_IDX_ATTRS_USN_PS,
29909+
CERTREQBODYASN_IDX_ATTRS_USN_UTF,
2972629910
CERTREQBODYASN_IDX_EXT_SEQ,
2972729911
CERTREQBODYASN_IDX_EXT_OID,
2972829912
CERTREQBODYASN_IDX_EXT_SET,
@@ -29976,6 +30160,23 @@ static int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz,
2997630160
SetASNItem_NoOutNode(dataASN, certReqBodyASN,
2997730161
CERTREQBODYASN_IDX_ATTRS_CPW_SEQ, certReqBodyASN_Length);
2997830162
}
30163+
if (cert->unstructuredName[0] != '\0') {
30164+
/* Add unstructured name attribute. */
30165+
/* Set unstructured name OID. */
30166+
SetASN_Buffer(&dataASN[CERTREQBODYASN_IDX_ATTRS_USN_OID],
30167+
attrUnstructuredNameOid, sizeof(attrUnstructuredNameOid));
30168+
/* PRINTABLE_STRING - set buffer */
30169+
SetASN_Buffer(&dataASN[CERTREQBODYASN_IDX_ATTRS_USN_PS],
30170+
(byte*)cert->unstructuredName,
30171+
(word32)XSTRLEN(cert->unstructuredName));
30172+
/* UTF8STRING - don't encode */
30173+
dataASN[CERTREQBODYASN_IDX_ATTRS_USN_UTF].noOut = 1;
30174+
}
30175+
else {
30176+
/* Leave out unstructured name attribute item. */
30177+
SetASNItem_NoOutNode(dataASN, certReqBodyASN,
30178+
CERTREQBODYASN_IDX_ATTRS_USN_SEQ, certReqBodyASN_Length);
30179+
}
2997930180
if (extSz > 0) {
2998030181
/* Set extension attribute OID. */
2998130182
SetASN_Buffer(&dataASN[CERTREQBODYASN_IDX_EXT_OID], attrExtensionRequestOid,
@@ -37515,9 +37716,6 @@ int wc_Asn1_SetFile(Asn1* asn1, XFILE file)
3751537716
return ret;
3751637717
}
3751737718

37518-
/* Maximum OID dotted form size. */
37519-
#define ASN1_OID_DOTTED_MAX_SZ 16
37520-
3752137719
/* Print OID in dotted form or as hex bytes.
3752237720
*
3752337721
* @param [in] file File pointer to write to.

0 commit comments

Comments
 (0)