Skip to content

Commit 4e4758e

Browse files
committed
Fix handling of registeredID
1 parent 619a6c4 commit 4e4758e

10 files changed

Lines changed: 407 additions & 28 deletions

File tree

certs/test/cert-ext-ncrid.der

1.06 KB
Binary file not shown.

certs/test/cert-ext-ncrid.pem

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIEOjCCAyKgAwIBAgIUBD6sBdFHNsQ5qoW3MIkJ/BKsB/4wDQYJKoZIhvcNAQEL
3+
BQAwezELMAkGA1UEBhMCQVUxEzARBgNVBAgMClF1ZWVuc2xhbmQxETAPBgNVBAcM
4+
CEJyaXNiYW5lMRQwEgYDVQQKDAt3b2xmU1NMIEluYzEUMBIGA1UECwwLRW5naW5l
5+
ZXJpbmcxGDAWBgNVBAMMD3d3dy53b2xmc3NsLmNvbTAeFw0yNjA0MjkyMTAzMTZa
6+
Fw0yOTAxMjMyMTAzMTZaMHsxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApRdWVlbnNs
7+
YW5kMREwDwYDVQQHDAhCcmlzYmFuZTEUMBIGA1UECgwLd29sZlNTTCBJbmMxFDAS
8+
BgNVBAsMC0VuZ2luZWVyaW5nMRgwFgYDVQQDDA93d3cud29sZnNzbC5jb20wggEi
9+
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDAlQjhV0HycW230kVBJwFlxkWu
10+
8rwkMLiVzi9O1vYciLx8n/uoZ3/+XJxRdfeKygfnNS+P4b17wC98q2SoF/zKXXu6
11+
4CHlci5vLobYlXParBtTuV8/1xkNJU/hY2NRiwtkP61DuKUcXDSzrgCgY8X2fwtZ
12+
aHhzpowYqQJtr8MZAS64EOPGzEC0aaNGM2mHbsS7F6bz6N2tc7x7LyG1/WZRDL1U
13+
s+FtXxy8I3PRCQOJFNIQuWTDKtChlkq84dQaW8egwMFjeA9ENzAyloAyI5Whd7oT
14+
0pdz4l0lyWoNwzlgpLSwaUJCCenYCLwzILNYIqeq68Th5mGDxdKW39nQT63XAgMB
15+
AAGjgbUwgbIwHQYDVR0OBBYEFLMRMsmSmITiyfjQO24DQsofDo48MB8GA1UdIwQY
16+
MBaAFLMRMsmSmITiyfjQO24DQsofDo48MBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYD
17+
VR0PAQH/BAQDAgGGMBYGA1UdHgEB/wQMMAqgCDAGiAQqAwQFMDQGCWCGSAGG+EIB
18+
DQQnFiVUZXN0aW5nIHJlZ2lzdGVyZWRJRCBuYW1lIGNvbnN0cmFpbnRzMA0GCSqG
19+
SIb3DQEBCwUAA4IBAQARs/sdZs71KWRoyWuTevfnS5h5PH9S07xl+hFcfSXpI6sx
20+
gQoBMzEv8BBN3vLL4HOoNCwnqmFbwG5ogt/HuohAT6bXtdIkK1jNEP50t1pdDOmi
21+
/3fYKDvjvtX2DDQe2K8o/qVsu63MtKkOuc1ZURtsVrlrFFW7D7FsuNxa1dS8fbGl
22+
qrEnIXKemPmco5EIFDygXFIFkL/CP/LxHjTOuib68hBUDOqhMpMruSp7OfAt9Kfe
23+
rsEVY5mv82DfaCjo9bw17dSHUFo4vC+wzB5E8Wg33Pxbn0v8aRTvAsPz22Mlkd9b
24+
mxdLFh0mqPBj/UvWOK1xH0kXGsblNNAz5KeDceAZ
25+
-----END CERTIFICATE-----

certs/test/gen-ext-certs.sh

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,35 @@ EOF
196196
gen_cert
197197
rm -f ./certs/test/cert-ext-ncip.cfg
198198

199+
OUT=certs/test/cert-ext-ncrid
200+
KEYFILE=certs/test/cert-ext-ncrid-key.der
201+
CONFIG=certs/test/cert-ext-ncrid.cfg
202+
tee >$CONFIG <<EOF
203+
[ req ]
204+
distinguished_name = req_distinguished_name
205+
prompt = no
206+
x509_extensions = v3_ca
207+
208+
[ req_distinguished_name ]
209+
C = AU
210+
ST = Queensland
211+
L = Brisbane
212+
O = wolfSSL Inc
213+
OU = Engineering
214+
CN = www.wolfssl.com
215+
216+
[ v3_ca ]
217+
subjectKeyIdentifier = hash
218+
authorityKeyIdentifier = keyid:always,issuer
219+
basicConstraints = critical, CA:true, pathlen:0
220+
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
221+
nameConstraints = critical,permitted;RID:1.2.3.4.5
222+
nsComment = "Testing registeredID name constraints"
223+
224+
EOF
225+
gen_cert
226+
rm -f ./certs/test/cert-ext-ncrid.cfg
227+
199228
OUT=certs/test/cert-ext-ia
200229
KEYFILE=certs/test/cert-ext-ia-key.der
201230
CONFIG=certs/test/cert-ext-ia.cfg

certs/test/include.am

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ EXTRA_DIST += \
1313
certs/test/cert-ext-nc-combined.pem \
1414
certs/test/cert-ext-ncip.der \
1515
certs/test/cert-ext-ncip.pem \
16+
certs/test/cert-ext-ncrid.der \
17+
certs/test/cert-ext-ncrid.pem \
1618
certs/test/cert-ext-ncdns.der \
1719
certs/test/cert-ext-ncdns.pem \
1820
certs/test/cert-ext-ncmulti.der \

src/internal.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13470,14 +13470,18 @@ int CheckForAltNames(DecodedCert* dCert, const char* domain, word32 domainLen,
1347013470
* cannot match anything here; treat them as absent so a cert
1347113471
* presenting only iPAddress SANs still falls back to CN as it
1347213472
* did before iPAddress entries were unconditionally added to
13473-
* altNames for name-constraint enforcement. */
13473+
* altNames for name-constraint enforcement. The same reasoning
13474+
* applies to registeredID entries: hostname matching against an
13475+
* OID is not meaningful, so they never count toward *checkCN. */
1347413476
DNS_entry* a = altName;
1347513477
*checkCN = 1;
1347613478
for (; a != NULL; a = a->next) {
1347713479
#ifndef WOLFSSL_IP_ALT_NAME
1347813480
if (a->type == ASN_IP_TYPE)
1347913481
continue;
1348013482
#endif
13483+
if (a->type == ASN_RID_TYPE)
13484+
continue;
1348113485
*checkCN = 0;
1348213486
break;
1348313487
}
@@ -13504,6 +13508,13 @@ int CheckForAltNames(DecodedCert* dCert, const char* domain, word32 domainLen,
1350413508
continue;
1350513509
}
1350613510

13511+
/* registeredID entries hold raw OID bytes; they are not eligible
13512+
* for hostname matching regardless of build flags. */
13513+
if (altName->type == ASN_RID_TYPE) {
13514+
WOLFSSL_MSG("\tAltName is registeredID, skipping for hostname");
13515+
continue;
13516+
}
13517+
1350713518
if (MatchDomainName(buf, (int)len, domain, domainLen, flags)) {
1350813519
match = 1;
1350913520
if (checkCN != NULL) {

src/x509.c

Lines changed: 55 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -650,8 +650,14 @@ static int DNS_to_GENERAL_NAME(WOLFSSL_GENERAL_NAME* gn, DNS_entry* dns)
650650
/* @TODO extract dir name info from DNS_entry */
651651
break;
652652

653-
#ifdef WOLFSSL_RID_ALT_NAME
654653
case WOLFSSL_GEN_RID:
654+
/* registeredID is parsed into altNames unconditionally so
655+
* ConfirmNameConstraints can enforce RID name constraints
656+
* (RFC 5280 Sec. 4.2.1.10). The body uses only the raw OID
657+
* bytes carried in dns->name/dns->len and constructs a
658+
* proper ASN1_OBJECT, so this case is independent of
659+
* WOLFSSL_RID_ALT_NAME (which only gates the human-readable
660+
* ridString form). */
655661
gn->type = dns->type;
656662
/* wolfSSL_GENERAL_NAME_new() mallocs this by default */
657663
wolfSSL_ASN1_STRING_free(gn->d.ia5);
@@ -681,7 +687,6 @@ static int DNS_to_GENERAL_NAME(WOLFSSL_GENERAL_NAME* gn, DNS_entry* dns)
681687
gn->d.registeredID->dynamic |= WOLFSSL_ASN1_DYNAMIC_DATA;
682688
gn->d.registeredID->grp = oidCertExtType;
683689
break;
684-
#endif
685690

686691
case WOLFSSL_GEN_X400:
687692
/* Unsupported: fall through */
@@ -2533,8 +2538,12 @@ void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509, int nid, int* c,
25332538
gn->d.iPAddress->type = WOLFSSL_V_ASN1_OCTET_STRING;
25342539
break;
25352540

2536-
#ifdef WOLFSSL_RID_ALT_NAME
25372541
case ASN_RID_TYPE:
2542+
/* Always handle registeredID: the union
2543+
* member d.registeredID is populated from
2544+
* raw OID body bytes. WOLFSSL_RID_ALT_NAME
2545+
* only gates the human-readable ridString,
2546+
* which this path does not need. */
25382547
gn->type = dns->type;
25392548
/* Free ia5 before using union for registeredID */
25402549
wolfSSL_ASN1_STRING_free(gn->d.ia5);
@@ -2567,7 +2576,6 @@ void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509, int nid, int* c,
25672576
WOLFSSL_ASN1_DYNAMIC_DATA;
25682577
gn->d.registeredID->grp = oidCertExtType;
25692578
break;
2570-
#endif /* WOLFSSL_RID_ALT_NAME */
25712579

25722580
default:
25732581
gn->type = dns->type;
@@ -4262,24 +4270,35 @@ char* wolfSSL_X509_get_next_altname(WOLFSSL_X509* cert)
42624270
return NULL;
42634271
}
42644272

4265-
#ifndef WOLFSSL_IP_ALT_NAME
42664273
/* In default builds iPAddress entries hold raw 4/16 octet payloads
4267-
* (no human-readable ipString), so returning them as a C string would
4268-
* truncate at any embedded NUL byte. Such entries are still parsed
4269-
* into altNames for name-constraint enforcement; skip them here so
4274+
* and registeredID entries hold raw OID body bytes (no human-readable
4275+
* ipString/ridString), so returning them as a C string would truncate
4276+
* at any embedded NUL byte. Such entries are still parsed into
4277+
* altNames for name-constraint enforcement; skip them here so
42704278
* string-iteration callers see the same set of entries as before.
42714279
*
42724280
* With WOLFSSL_MULTICIRCULATE_ALTNAMELIST, a list consisting only of
4273-
* iPAddress entries collapses to "no entries" on the first pass and
4281+
* skipped entries collapses to "no entries" on the first pass and
42744282
* resets to head on the next call; the cycle shape matches the
42754283
* pre-fix behavior where such entries were never parsed. */
4276-
while (cert->altNamesNext != NULL &&
4277-
cert->altNamesNext->type == ASN_IP_TYPE) {
4284+
#if !defined(WOLFSSL_IP_ALT_NAME) || !defined(WOLFSSL_RID_ALT_NAME)
4285+
while (cert->altNamesNext != NULL) {
4286+
int skip = 0;
4287+
#ifndef WOLFSSL_IP_ALT_NAME
4288+
if (cert->altNamesNext->type == ASN_IP_TYPE)
4289+
skip = 1;
4290+
#endif
4291+
#ifndef WOLFSSL_RID_ALT_NAME
4292+
if (cert->altNamesNext->type == ASN_RID_TYPE)
4293+
skip = 1;
4294+
#endif
4295+
if (!skip)
4296+
break;
42784297
cert->altNamesNext = cert->altNamesNext->next;
42794298
}
42804299
if (cert->altNamesNext == NULL)
42814300
return NULL;
4282-
#endif
4301+
#endif /* !WOLFSSL_IP_ALT_NAME || !WOLFSSL_RID_ALT_NAME */
42834302

42844303
/* unsafe cast required for ABI compatibility. */
42854304
ret = (char *)(wc_ptr_t)cert->altNamesNext->name;
@@ -4288,6 +4307,12 @@ char* wolfSSL_X509_get_next_altname(WOLFSSL_X509* cert)
42884307
if (cert->altNamesNext->type == ASN_IP_TYPE) {
42894308
ret = cert->altNamesNext->ipString;
42904309
}
4310+
#endif
4311+
#ifdef WOLFSSL_RID_ALT_NAME
4312+
/* return the registeredID as a string */
4313+
if (cert->altNamesNext->type == ASN_RID_TYPE) {
4314+
ret = cert->altNamesNext->ridString;
4315+
}
42914316
#endif
42924317
cert->altNamesNext = cert->altNamesNext->next;
42934318

@@ -6903,6 +6928,14 @@ static int X509_print_name_entry(WOLFSSL_BIO* bio,
69036928
len = XSNPRINTF(scratch, MAX_WIDTH, "IP Address:%s",
69046929
entry->ipString);
69056930
}
6931+
#else
6932+
else if (entry->type == ASN_IP_TYPE) {
6933+
/* iPAddress entries are now always parsed into altNames so
6934+
* name constraints can be enforced. Without the
6935+
* human-readable ipString field, emit a fixed label so this
6936+
* print path does not fail. */
6937+
len = XSNPRINTF(scratch, MAX_WIDTH, "IP Address:<unavailable>");
6938+
}
69066939
#endif /* OPENSSL_ALL || WOLFSSL_IP_ALT_NAME */
69076940
else if (entry->type == ASN_RFC822_TYPE) {
69086941
len = XSNPRINTF(scratch, MAX_WIDTH, "email:%s",
@@ -6915,12 +6948,20 @@ static int X509_print_name_entry(WOLFSSL_BIO* bio,
69156948
len = XSNPRINTF(scratch, MAX_WIDTH, "URI:%s",
69166949
entry->name);
69176950
}
6918-
#if defined(OPENSSL_ALL)
6951+
#ifdef WOLFSSL_RID_ALT_NAME
69196952
else if (entry->type == ASN_RID_TYPE) {
69206953
len = XSNPRINTF(scratch, MAX_WIDTH, "Registered ID:%s",
69216954
entry->ridString);
69226955
}
6923-
#endif
6956+
#else
6957+
else if (entry->type == ASN_RID_TYPE) {
6958+
/* registeredID entries are now always parsed into altNames
6959+
* so name constraints can be enforced. Without the
6960+
* human-readable ridString field, emit a fixed label so
6961+
* this print path does not fail. */
6962+
len = XSNPRINTF(scratch, MAX_WIDTH, "Registered ID:<unavailable>");
6963+
}
6964+
#endif /* WOLFSSL_RID_ALT_NAME */
69246965
else if (entry->type == ASN_OTHER_TYPE) {
69256966
len = XSNPRINTF(scratch, MAX_WIDTH,
69266967
"othername <unsupported>");

0 commit comments

Comments
 (0)