From 17f32c3e0592775a2f3df6cd97792dbad327e5ab Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Fri, 11 Dec 2020 05:22:46 +0700 Subject: [PATCH] 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 */