diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 04ae0c5be..17c986369 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -4818,34 +4818,44 @@ static int ConfirmNameConstraints(Signer* signer, DecodedCert* cert) Base_entry* base = signer->excludedNames; while (base != NULL) { - if (base->type == ASN_DNS_TYPE) { - DNS_entry* name = cert->altNames; - while (name != NULL) { - if (MatchBaseName(ASN_DNS_TYPE, + switch (base->type) { + case ASN_DNS_TYPE: + { + DNS_entry* name = cert->altNames; + while (name != NULL) { + if (MatchBaseName(ASN_DNS_TYPE, name->name, (int)XSTRLEN(name->name), - base->name, base->nameSz)) - return 0; - name = name->next; + base->name, base->nameSz)) { + return 0; + } + name = name->next; + } + break; } - } - else if (base->type == ASN_RFC822_TYPE) { - DNS_entry* name = cert->altEmailNames; - while (name != NULL) { - if (MatchBaseName(ASN_RFC822_TYPE, + case ASN_RFC822_TYPE: + { + DNS_entry* name = cert->altEmailNames; + while (name != NULL) { + if (MatchBaseName(ASN_RFC822_TYPE, name->name, (int)XSTRLEN(name->name), - base->name, base->nameSz)) + base->name, base->nameSz)) { + return 0; + } + name = name->next; + } + break; + } + case ASN_DIR_TYPE: + { + /* allow permitted dirName smaller than actual subject */ + if (cert->subjectRawLen >= base->nameSz && + XMEMCMP(cert->subjectRaw, base->name, + base->nameSz) == 0) { return 0; - - name = name->next; + } + break; } - } - else if (base->type == ASN_DIR_TYPE) { - if (cert->subjectRawLen == base->nameSz && - XMEMCMP(cert->subjectRaw, base->name, base->nameSz) == 0) { - - return 0; - } - } + }; /* switch */ base = base->next; } } @@ -4861,47 +4871,56 @@ static int ConfirmNameConstraints(Signer* signer, DecodedCert* cert) Base_entry* base = signer->permittedNames; while (base != NULL) { - if (base->type == ASN_DNS_TYPE) { - DNS_entry* name = cert->altNames; + switch (base->type) { + case ASN_DNS_TYPE: + { + DNS_entry* name = cert->altNames; - if (name != NULL) - needDns = 1; + if (name != NULL) + needDns = 1; - while (name != NULL) { - matchDns = MatchBaseName(ASN_DNS_TYPE, + while (name != NULL) { + matchDns = MatchBaseName(ASN_DNS_TYPE, name->name, (int)XSTRLEN(name->name), base->name, base->nameSz); - name = name->next; + name = name->next; + } + break; } - } - else if (base->type == ASN_RFC822_TYPE) { - DNS_entry* name = cert->altEmailNames; + case ASN_RFC822_TYPE: + { + DNS_entry* name = cert->altEmailNames; - if (name != NULL) - needEmail = 1; + if (name != NULL) + needEmail = 1; - while (name != NULL) { - matchEmail = MatchBaseName(ASN_DNS_TYPE, + while (name != NULL) { + matchEmail = MatchBaseName(ASN_DNS_TYPE, name->name, (int)XSTRLEN(name->name), base->name, base->nameSz); - name = name->next; + name = name->next; + } + break; } - } - else if (base->type == ASN_DIR_TYPE) { - needDir = 1; - if (cert->subjectRaw != NULL && - cert->subjectRawLen == base->nameSz && - XMEMCMP(cert->subjectRaw, base->name, base->nameSz) == 0) { - - matchDir = 1; + case ASN_DIR_TYPE: + { + /* allow permitted dirName smaller than actual subject */ + needDir = 1; + if (cert->subjectRaw != NULL && + cert->subjectRawLen >= base->nameSz && + XMEMCMP(cert->subjectRaw, base->name, + base->nameSz) == 0) { + matchDir = 1; + } + break; } - } + } /* switch */ base = base->next; } - if ((needDns && !matchDns) || (needEmail && !matchEmail) || - (needDir && !matchDir)) { - + if ((needDns && !matchDns) || + (needEmail && !matchEmail) || + (needDir && !matchDir)) { return 0; } } @@ -5410,6 +5429,7 @@ static int DecodeExtKeyUsage(byte* input, int sz, DecodedCert* cert) #ifndef IGNORE_NAME_CONSTRAINTS +#define ASN_TYPE_MASK 0xF static int DecodeSubtree(byte* input, int sz, Base_entry** head, void* heap) { word32 idx = 0; @@ -5419,27 +5439,37 @@ static int DecodeSubtree(byte* input, int sz, Base_entry** head, void* heap) while (idx < (word32)sz) { int seqLength, strLength; word32 nameIdx; - byte b; + byte b, bType; if (GetSequence(input, &idx, &seqLength, sz) < 0) { WOLFSSL_MSG("\tfail: should be a SEQUENCE"); return ASN_PARSE_E; } - nameIdx = idx; b = input[nameIdx++]; + if (GetLength(input, &nameIdx, &strLength, sz) <= 0) { WOLFSSL_MSG("\tinvalid length"); return ASN_PARSE_E; } - if (b == (ASN_CONTEXT_SPECIFIC | ASN_DNS_TYPE) || - b == (ASN_CONTEXT_SPECIFIC | ASN_RFC822_TYPE) || - b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_DIR_TYPE)) { + /* Get type, LSB 4-bits */ + bType = (b & ASN_TYPE_MASK); - Base_entry* entry = (Base_entry*)XMALLOC(sizeof(Base_entry), - heap, DYNAMIC_TYPE_ALTNAME); + if (bType == ASN_DNS_TYPE || bType == ASN_RFC822_TYPE || + bType == ASN_DIR_TYPE) { + Base_entry* entry; + /* if constructed has leading sequence */ + if (b & ASN_CONSTRUCTED) { + if (GetSequence(input, &nameIdx, &strLength, sz) < 0) { + WOLFSSL_MSG("\tfail: constructed be a SEQUENCE"); + return ASN_PARSE_E; + } + } + + entry = (Base_entry*)XMALLOC(sizeof(Base_entry), heap, + DYNAMIC_TYPE_ALTNAME); if (entry == NULL) { WOLFSSL_MSG("allocate error"); return MEMORY_E; @@ -5454,7 +5484,7 @@ static int DecodeSubtree(byte* input, int sz, Base_entry** head, void* heap) XMEMCPY(entry->name, &input[nameIdx], strLength); entry->nameSz = strLength; - entry->type = b & 0x0F; + entry->type = bType; entry->next = *head; *head = entry; @@ -5614,8 +5644,8 @@ static int DecodePolicyOID(char *out, word32 outSz, byte *in, word32 inSz) return ASN_PARSE_E; } - /* Validate total length (2 is the CERT_POLICY_OID+SEQ) */ - if ((total_length + 2) != sz) { + /* Validate total length */ + if (total_length > (sz - (int)idx)) { WOLFSSL_MSG("\tCertPolicy length mismatch"); return ASN_PARSE_E; } @@ -5640,7 +5670,7 @@ static int DecodePolicyOID(char *out, word32 outSz, byte *in, word32 inSz) return ASN_PARSE_E; } - #if defined(WOLFSSL_SEP) + #if defined(WOLFSSL_SEP) cert->deviceType = (byte*)XMALLOC(length, cert->heap, DYNAMIC_TYPE_X509_EXT); if (cert->deviceType == NULL) { @@ -5650,14 +5680,14 @@ static int DecodePolicyOID(char *out, word32 outSz, byte *in, word32 inSz) cert->deviceTypeSz = length; XMEMCPY(cert->deviceType, input + idx, length); break; - #elif defined(WOLFSSL_CERT_EXT) + #elif defined(WOLFSSL_CERT_EXT) /* decode cert policy */ if (DecodePolicyOID(cert->extCertPolicies[cert->extCertPoliciesNb], MAX_CERTPOL_SZ, input + idx, length) != 0) { WOLFSSL_MSG("\tCouldn't decode CertPolicy"); return ASN_PARSE_E; } - #ifndef WOLFSSL_DUP_CERTPOL + #ifndef WOLFSSL_DUP_CERTPOL /* From RFC 5280 section 4.2.1.3 "A certificate policy OID MUST * NOT appear more than once in a certificate policies * extension". This is a sanity check for duplicates. @@ -5672,12 +5702,12 @@ static int DecodePolicyOID(char *out, word32 outSz, byte *in, word32 inSz) return CERTPOLICIES_E; } } - #endif /* !defined(WOLFSSL_DUP_CERTPOL) */ + #endif /* !WOLFSSL_DUP_CERTPOL */ cert->extCertPoliciesNb++; - #else + #else WOLFSSL_LEAVE("DecodeCertPolicy : unsupported mode", 0); return 0; - #endif + #endif } idx += policy_length; } while((int)idx < total_length @@ -5987,7 +6017,7 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm) /* save extensions */ cert->extensions = &cert->source[cert->srcIdx]; - cert->extensionsSz = cert->sigIndex - cert->srcIdx; + cert->extensionsSz = cert->sigIndex - cert->srcIdx; cert->extensionsIdx = cert->srcIdx; /* for potential later use */ if ((ret = DecodeCertExtensions(cert)) < 0) { @@ -6141,10 +6171,10 @@ Signer* MakeSigner(void* heap) signer->publicKey = NULL; signer->nameLen = 0; signer->name = NULL; - #ifndef IGNORE_NAME_CONSTRAINTS - signer->permittedNames = NULL; - signer->excludedNames = NULL; - #endif /* IGNORE_NAME_CONSTRAINTS */ + #ifndef IGNORE_NAME_CONSTRAINTS + signer->permittedNames = NULL; + signer->excludedNames = NULL; + #endif /* IGNORE_NAME_CONSTRAINTS */ signer->pathLengthSet = 0; signer->pathLength = 0; signer->next = NULL; @@ -6160,12 +6190,12 @@ void FreeSigner(Signer* signer, void* heap) { XFREE(signer->name, heap, DYNAMIC_TYPE_SUBJECT_CN); XFREE(signer->publicKey, heap, DYNAMIC_TYPE_PUBLIC_KEY); - #ifndef IGNORE_NAME_CONSTRAINTS - if (signer->permittedNames) - FreeNameSubtrees(signer->permittedNames, heap); - if (signer->excludedNames) - FreeNameSubtrees(signer->excludedNames, heap); - #endif +#ifndef IGNORE_NAME_CONSTRAINTS + if (signer->permittedNames) + FreeNameSubtrees(signer->permittedNames, heap); + if (signer->excludedNames) + FreeNameSubtrees(signer->excludedNames, heap); +#endif XFREE(signer, heap, DYNAMIC_TYPE_SIGNER); (void)heap; @@ -6203,12 +6233,12 @@ void FreeTrustedPeer(TrustedPeerCert* tp, void* heap) if (tp->sig) { XFREE(tp->sig, heap, DYNAMIC_TYPE_SIGNATURE); } - #ifndef IGNORE_NAME_CONSTRAINTS - if (tp->permittedNames) - FreeNameSubtrees(tp->permittedNames, heap); - if (tp->excludedNames) - FreeNameSubtrees(tp->excludedNames, heap); - #endif +#ifndef IGNORE_NAME_CONSTRAINTS + if (tp->permittedNames) + FreeNameSubtrees(tp->permittedNames, heap); + if (tp->excludedNames) + FreeNameSubtrees(tp->excludedNames, heap); +#endif XFREE(tp, heap, DYNAMIC_TYPE_CERT); (void)heap; diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index c0603f2a1..86776b810 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -87,7 +87,7 @@ enum ASN_Tags { ASN_LONG_LENGTH = 0x80 }; -enum ASN_Flags{ +enum ASN_Flags { ASN_CONSTRUCTED = 0x20, ASN_CONTEXT_SPECIFIC = 0x80 };