From 17f32c3e0592775a2f3df6cd97792dbad327e5ab Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Fri, 11 Dec 2020 05:22:46 +0700 Subject: [PATCH 1/3] add strict check on name constraints with DIR alt names --- wolfcrypt/src/asn.c | 58 +++++++++++++++++++++++++++++++++++++++++ wolfssl/wolfcrypt/asn.h | 1 + 2 files changed, 59 insertions(+) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 6c1d938d5..eb1491b6c 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -5090,6 +5090,8 @@ void FreeDecodedCert(DecodedCert* cert) #ifndef IGNORE_NAME_CONSTRAINTS if (cert->altEmailNames) FreeAltNames(cert->altEmailNames, cert->heap); + if (cert->altDirNames) + FreeAltNames(cert->altDirNames, cert->heap); if (cert->permittedNames) FreeNameSubtrees(cert->permittedNames, cert->heap); if (cert->excludedNames) @@ -7684,6 +7686,26 @@ static int ConfirmNameConstraints(Signer* signer, DecodedCert* cert) XMEMCMP(cert->subjectRaw, base->name, base->nameSz) == 0) { matchDir = 1; + + #ifndef WOLFSSL_NO_ASN_STRICT + /* RFC 5280 section 4.2.1.10 + "Restrictions of the form directoryName MUST be + applied to the subject field .... and to any names + of type directoryName in the subjectAltName + extension" + */ + if (cert->altDirNames != NULL) { + DNS_entry* cur = cert->altDirNames; + while (cur != NULL) { + if (XMEMCMP(cur->name, base->name, base->nameSz) + != 0) { + WOLFSSL_MSG("DIR alt name constraint err"); + matchDir = 0; /* did not match */ + } + cur = cur->next; + } + } + #endif /* !WOLFSSL_NO_ASN_STRICT */ } break; } @@ -7768,6 +7790,42 @@ static int DecodeAltNames(const byte* input, int sz, DecodedCert* cert) idx += strLen; } #ifndef IGNORE_NAME_CONSTRAINTS + else if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_DIR_TYPE)) { + DNS_entry* dirEntry; + int strLen; + word32 lenStartIdx = idx; + + if (GetLength(input, &idx, &strLen, sz) < 0) { + WOLFSSL_MSG("\tfail: str length"); + return ASN_PARSE_E; + } + length -= (idx - lenStartIdx); + + dirEntry = (DNS_entry*)XMALLOC(sizeof(DNS_entry), cert->heap, + DYNAMIC_TYPE_ALTNAME); + if (dirEntry == NULL) { + WOLFSSL_MSG("\tOut of Memory"); + return MEMORY_E; + } + + dirEntry->type = ASN_DIR_TYPE; + dirEntry->name = (char*)XMALLOC(strLen + 1, cert->heap, + DYNAMIC_TYPE_ALTNAME); + if (dirEntry->name == NULL) { + WOLFSSL_MSG("\tOut of Memory"); + XFREE(dirEntry, cert->heap, DYNAMIC_TYPE_ALTNAME); + return MEMORY_E; + } + dirEntry->len = strLen; + XMEMCPY(dirEntry->name, &input[idx], strLen); + dirEntry->name[strLen] = '\0'; + + dirEntry->next = cert->altDirNames; + cert->altDirNames = dirEntry; + + length -= strLen; + idx += strLen; + } else if (b == (ASN_CONTEXT_SPECIFIC | ASN_RFC822_TYPE)) { DNS_entry* emailEntry; int strLen; diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index edb3d0d12..26eeee647 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -769,6 +769,7 @@ struct DecodedCert { DNS_entry* altNames; /* alt names list of dns entries */ #ifndef IGNORE_NAME_CONSTRAINTS DNS_entry* altEmailNames; /* alt names list of RFC822 entries */ + DNS_entry* altDirNames; /* alt names list of DIR entries */ Base_entry* permittedNames; /* Permitted name bases */ Base_entry* excludedNames; /* Excluded name bases */ #endif /* IGNORE_NAME_CONSTRAINTS */ From f00263889b97ba4a0d5894d41735de191b0ec316 Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Fri, 11 Dec 2020 08:20:48 +0700 Subject: [PATCH 2/3] add test case --- certs/test/cert-ext-ndir.cfg | 23 ++++++++++ certs/test/cert-ext-ndir.der | Bin 0 -> 1260 bytes certs/test/gen-ext-certs.sh | 34 +++++++++++++- certs/test/include.am | 2 + tests/api.c | 85 +++++++++++++++++++++++++++++++++++ wolfcrypt/src/asn.c | 11 ++++- 6 files changed, 153 insertions(+), 2 deletions(-) create mode 100644 certs/test/cert-ext-ndir.cfg create mode 100644 certs/test/cert-ext-ndir.der diff --git a/certs/test/cert-ext-ndir.cfg b/certs/test/cert-ext-ndir.cfg new file mode 100644 index 000000000..0757874d8 --- /dev/null +++ b/certs/test/cert-ext-ndir.cfg @@ -0,0 +1,23 @@ +[ req ] +distinguished_name = req_distinguished_name +prompt = no +x509_extensions = constraints + +[ req_distinguished_name ] +C = US +ST = Montana +L = Bozeman +O = Sawtooth +OU = Consulting +CN = www.wolfssl.com +emailAddress = info@wolfsssl.com + +[constraints] +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always,issuer:always +basicConstraints=CA:TRUE +nameConstraints=critical,permitted;dirName:dir_name + +[dir_name] +countryName = US + diff --git a/certs/test/cert-ext-ndir.der b/certs/test/cert-ext-ndir.der new file mode 100644 index 0000000000000000000000000000000000000000..63f566bfc02ba2e783f5231f39c4d8094570edbb GIT binary patch literal 1260 zcmXqLVtHZE#C%}^GZP~dlSqAq)Q_^4&D+ao6`4nB$Uj^XQ&4Nb%f_kI=F#?@mywa1 zmBFBKsv)-lCmVAp3!5-gXt1Gx0UwCN!NcyGpI4HYmk1MK=V5osuS(5L%rg`;;0LMU z;^7EREHBB=FUc?zHV^~}ar1CF=jRod=9FaSr5j2Zh=Bx|dHBoA%k|3hbJB{7bM%t) za}5;?ltHlwp{i7 z-iFfPDK@sJlB4H~ZoMoktS@=d=60FYnH{w!pB}n?%OU@U;+B@dH-UhnL?qs>i{pN9ZTIYJ6Sd>QJE=isY}Y3AI_ zFo*ZX+%Glaf+xARZtZUVebMDv_M7^HVwtxE6ymn7cG!LY>(@&@8+$UX)?IyEds+LE zo13)VA$3;I@H4k3KD#a$@$TMP 2>&1 @@ -96,3 +97,34 @@ nsComment = "Testing Netscape Certificate Type" EOF gen_cert +KEY=certs/ca-key.der +OUT=certs/test/cert-ext-ndir.der +KEYFILE=certs/ca-key.der +CONFIG=certs/test/cert-ext-ndir.cfg +tee >$CONFIG <heap, @@ -12717,7 +12722,11 @@ int FlattenAltNames(byte* output, word32 outputSz, const DNS_entry* names) curName = names; do { - output[idx++] = ASN_CONTEXT_SPECIFIC | curName->type; + output[idx] = ASN_CONTEXT_SPECIFIC | curName->type; + if (curName->type == ASN_DIR_TYPE) { + output[idx] |= ASN_CONSTRUCTED; + } + idx++; idx += SetLength(curName->len, output + idx); XMEMCPY(output + idx, curName->name, curName->len); idx += curName->len; From 04e22b0747a41bf56ca0dfce3d15e208720c7ef9 Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Fri, 11 Dec 2020 10:00:11 +0700 Subject: [PATCH 3/3] add restriction to excluded DIR name constraint --- certs/test/cert-ext-ndir-exc.cfg | 24 +++++++++++++++++++ certs/test/cert-ext-ndir-exc.der | Bin 0 -> 1281 bytes certs/test/gen-ext-certs.sh | 32 ++++++++++++++++++++++++++ certs/test/include.am | 2 ++ tests/api.c | 38 ++++++++++++++++++++++++++++--- wolfcrypt/src/asn.c | 19 ++++++++++++++++ 6 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 certs/test/cert-ext-ndir-exc.cfg create mode 100644 certs/test/cert-ext-ndir-exc.der diff --git a/certs/test/cert-ext-ndir-exc.cfg b/certs/test/cert-ext-ndir-exc.cfg new file mode 100644 index 000000000..8d66b8a07 --- /dev/null +++ b/certs/test/cert-ext-ndir-exc.cfg @@ -0,0 +1,24 @@ +[ req ] +distinguished_name = req_distinguished_name +prompt = no +x509_extensions = constraints + +[ req_distinguished_name ] +C = US +ST = Montana +L = Bozeman +O = Sawtooth +OU = Consulting +CN = www.wolfssl.com +emailAddress = info@wolfsssl.com + +[constraints] +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always,issuer:always +basicConstraints=CA:TRUE +nameConstraints=critical,excluded;dirName:dir_name_exclude + +[dir_name_exclude] +countryName = US +stateOrProvinceName = California + diff --git a/certs/test/cert-ext-ndir-exc.der b/certs/test/cert-ext-ndir-exc.der new file mode 100644 index 0000000000000000000000000000000000000000..19afbab840a90d09b8b50c8658fb48465f70ec88 GIT binary patch literal 1281 zcmXqLV)<*(#QbytGZP~dlZb}T2I*f+%_ltHlwp{i7 z-iFfPDK@sJlB4H~ZoMoktS@=d=60FYnH{w!pB}n?%OU@U;+B@dH-UhnL?qs>i{pN{XcGAEBAc?&oxAZhiuX${CM>?1K5N3)=RzmW-I!A-EOo=;{jU^e!T$aI z@^kMh*`9p3A?4T^(+w)sk+}-*+&FqZo(@Pf4Av@LdHV6%)IGNX6%u-Tzi&i$2^t zqPAM|o}~OEhkHK?Qf9H&uh<$msW!&#_Ju3+;#W_~30-^c+_`J5sy-Gk-mHp>R+?B5 VU~_ht*1hYB%n#J=t}x$v2ms7j#8UtO literal 0 HcmV?d00001 diff --git a/certs/test/gen-ext-certs.sh b/certs/test/gen-ext-certs.sh index 65ce2124c..e418157ab 100755 --- a/certs/test/gen-ext-certs.sh +++ b/certs/test/gen-ext-certs.sh @@ -128,3 +128,35 @@ countryName = US EOF gen_cert +OUT=certs/test/cert-ext-ndir-exc.der +KEYFILE=certs/ca-key.der +CONFIG=certs/test/cert-ext-ndir-exc.cfg +tee >$CONFIG <nameSz) == 0) { return 0; } + #ifndef WOLFSSL_NO_ASN_STRICT + /* RFC 5280 section 4.2.1.10 + "Restrictions of the form directoryName MUST be + applied to the subject field .... and to any names + of type directoryName in the subjectAltName + extension" + */ + if (cert->altDirNames != NULL) { + DNS_entry* cur = cert->altDirNames; + while (cur != NULL) { + if (XMEMCMP(cur->name, base->name, base->nameSz) + == 0) { + WOLFSSL_MSG("DIR alt name constraint err"); + return 0; + } + cur = cur->next; + } + } + #endif /* !WOLFSSL_NO_ASN_STRICT */ break; } }; /* switch */