mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-31 03:07:29 +02:00
Fix for parsing permitted name constraint for subject directory name. Cleanup to use switch in ConfirmNameConstraints.
This commit is contained in:
@ -4816,34 +4816,44 @@ static int ConfirmNameConstraints(Signer* signer, DecodedCert* cert)
|
|||||||
Base_entry* base = signer->excludedNames;
|
Base_entry* base = signer->excludedNames;
|
||||||
|
|
||||||
while (base != NULL) {
|
while (base != NULL) {
|
||||||
if (base->type == ASN_DNS_TYPE) {
|
switch (base->type) {
|
||||||
DNS_entry* name = cert->altNames;
|
case ASN_DNS_TYPE:
|
||||||
while (name != NULL) {
|
{
|
||||||
if (MatchBaseName(ASN_DNS_TYPE,
|
DNS_entry* name = cert->altNames;
|
||||||
|
while (name != NULL) {
|
||||||
|
if (MatchBaseName(ASN_DNS_TYPE,
|
||||||
name->name, (int)XSTRLEN(name->name),
|
name->name, (int)XSTRLEN(name->name),
|
||||||
base->name, base->nameSz))
|
base->name, base->nameSz)) {
|
||||||
return 0;
|
return 0;
|
||||||
name = name->next;
|
}
|
||||||
|
name = name->next;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
case ASN_RFC822_TYPE:
|
||||||
else if (base->type == ASN_RFC822_TYPE) {
|
{
|
||||||
DNS_entry* name = cert->altEmailNames;
|
DNS_entry* name = cert->altEmailNames;
|
||||||
while (name != NULL) {
|
while (name != NULL) {
|
||||||
if (MatchBaseName(ASN_RFC822_TYPE,
|
if (MatchBaseName(ASN_RFC822_TYPE,
|
||||||
name->name, (int)XSTRLEN(name->name),
|
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;
|
return 0;
|
||||||
|
}
|
||||||
name = name->next;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}; /* switch */
|
||||||
else if (base->type == ASN_DIR_TYPE) {
|
|
||||||
if (cert->subjectRawLen == base->nameSz &&
|
|
||||||
XMEMCMP(cert->subjectRaw, base->name, base->nameSz) == 0) {
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
base = base->next;
|
base = base->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4859,47 +4869,56 @@ static int ConfirmNameConstraints(Signer* signer, DecodedCert* cert)
|
|||||||
Base_entry* base = signer->permittedNames;
|
Base_entry* base = signer->permittedNames;
|
||||||
|
|
||||||
while (base != NULL) {
|
while (base != NULL) {
|
||||||
if (base->type == ASN_DNS_TYPE) {
|
switch (base->type) {
|
||||||
DNS_entry* name = cert->altNames;
|
case ASN_DNS_TYPE:
|
||||||
|
{
|
||||||
|
DNS_entry* name = cert->altNames;
|
||||||
|
|
||||||
if (name != NULL)
|
if (name != NULL)
|
||||||
needDns = 1;
|
needDns = 1;
|
||||||
|
|
||||||
while (name != NULL) {
|
while (name != NULL) {
|
||||||
matchDns = MatchBaseName(ASN_DNS_TYPE,
|
matchDns = MatchBaseName(ASN_DNS_TYPE,
|
||||||
name->name, (int)XSTRLEN(name->name),
|
name->name, (int)XSTRLEN(name->name),
|
||||||
base->name, base->nameSz);
|
base->name, base->nameSz);
|
||||||
name = name->next;
|
name = name->next;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
case ASN_RFC822_TYPE:
|
||||||
else if (base->type == ASN_RFC822_TYPE) {
|
{
|
||||||
DNS_entry* name = cert->altEmailNames;
|
DNS_entry* name = cert->altEmailNames;
|
||||||
|
|
||||||
if (name != NULL)
|
if (name != NULL)
|
||||||
needEmail = 1;
|
needEmail = 1;
|
||||||
|
|
||||||
while (name != NULL) {
|
while (name != NULL) {
|
||||||
matchEmail = MatchBaseName(ASN_DNS_TYPE,
|
matchEmail = MatchBaseName(ASN_DNS_TYPE,
|
||||||
name->name, (int)XSTRLEN(name->name),
|
name->name, (int)XSTRLEN(name->name),
|
||||||
base->name, base->nameSz);
|
base->name, base->nameSz);
|
||||||
name = name->next;
|
name = name->next;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
case ASN_DIR_TYPE:
|
||||||
else if (base->type == ASN_DIR_TYPE) {
|
{
|
||||||
needDir = 1;
|
/* allow permitted dirName smaller than actual subject */
|
||||||
if (cert->subjectRaw != NULL &&
|
needDir = 1;
|
||||||
cert->subjectRawLen == base->nameSz &&
|
if (cert->subjectRaw != NULL &&
|
||||||
XMEMCMP(cert->subjectRaw, base->name, base->nameSz) == 0) {
|
cert->subjectRawLen >= base->nameSz &&
|
||||||
|
XMEMCMP(cert->subjectRaw, base->name,
|
||||||
matchDir = 1;
|
base->nameSz) == 0) {
|
||||||
|
matchDir = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
} /* switch */
|
||||||
base = base->next;
|
base = base->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((needDns && !matchDns) || (needEmail && !matchEmail) ||
|
if ((needDns && !matchDns) ||
|
||||||
(needDir && !matchDir)) {
|
(needEmail && !matchEmail) ||
|
||||||
|
(needDir && !matchDir)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5408,6 +5427,7 @@ static int DecodeExtKeyUsage(byte* input, int sz, DecodedCert* cert)
|
|||||||
|
|
||||||
|
|
||||||
#ifndef IGNORE_NAME_CONSTRAINTS
|
#ifndef IGNORE_NAME_CONSTRAINTS
|
||||||
|
#define ASN_TYPE_MASK 0xF
|
||||||
static int DecodeSubtree(byte* input, int sz, Base_entry** head, void* heap)
|
static int DecodeSubtree(byte* input, int sz, Base_entry** head, void* heap)
|
||||||
{
|
{
|
||||||
word32 idx = 0;
|
word32 idx = 0;
|
||||||
@ -5417,27 +5437,37 @@ static int DecodeSubtree(byte* input, int sz, Base_entry** head, void* heap)
|
|||||||
while (idx < (word32)sz) {
|
while (idx < (word32)sz) {
|
||||||
int seqLength, strLength;
|
int seqLength, strLength;
|
||||||
word32 nameIdx;
|
word32 nameIdx;
|
||||||
byte b;
|
byte b, bType;
|
||||||
|
|
||||||
if (GetSequence(input, &idx, &seqLength, sz) < 0) {
|
if (GetSequence(input, &idx, &seqLength, sz) < 0) {
|
||||||
WOLFSSL_MSG("\tfail: should be a SEQUENCE");
|
WOLFSSL_MSG("\tfail: should be a SEQUENCE");
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
nameIdx = idx;
|
nameIdx = idx;
|
||||||
b = input[nameIdx++];
|
b = input[nameIdx++];
|
||||||
|
|
||||||
if (GetLength(input, &nameIdx, &strLength, sz) <= 0) {
|
if (GetLength(input, &nameIdx, &strLength, sz) <= 0) {
|
||||||
WOLFSSL_MSG("\tinvalid length");
|
WOLFSSL_MSG("\tinvalid length");
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (b == (ASN_CONTEXT_SPECIFIC | ASN_DNS_TYPE) ||
|
/* Get type, LSB 4-bits */
|
||||||
b == (ASN_CONTEXT_SPECIFIC | ASN_RFC822_TYPE) ||
|
bType = (b & ASN_TYPE_MASK);
|
||||||
b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_DIR_TYPE)) {
|
|
||||||
|
|
||||||
Base_entry* entry = (Base_entry*)XMALLOC(sizeof(Base_entry),
|
if (bType == ASN_DNS_TYPE || bType == ASN_RFC822_TYPE ||
|
||||||
heap, DYNAMIC_TYPE_ALTNAME);
|
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) {
|
if (entry == NULL) {
|
||||||
WOLFSSL_MSG("allocate error");
|
WOLFSSL_MSG("allocate error");
|
||||||
return MEMORY_E;
|
return MEMORY_E;
|
||||||
@ -5452,7 +5482,7 @@ static int DecodeSubtree(byte* input, int sz, Base_entry** head, void* heap)
|
|||||||
|
|
||||||
XMEMCPY(entry->name, &input[nameIdx], strLength);
|
XMEMCPY(entry->name, &input[nameIdx], strLength);
|
||||||
entry->nameSz = strLength;
|
entry->nameSz = strLength;
|
||||||
entry->type = b & 0x0F;
|
entry->type = bType;
|
||||||
|
|
||||||
entry->next = *head;
|
entry->next = *head;
|
||||||
*head = entry;
|
*head = entry;
|
||||||
@ -5612,8 +5642,8 @@ static int DecodePolicyOID(char *out, word32 outSz, byte *in, word32 inSz)
|
|||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Validate total length (2 is the CERT_POLICY_OID+SEQ) */
|
/* Validate total length */
|
||||||
if ((total_length + 2) != sz) {
|
if (total_length > (sz - (int)idx)) {
|
||||||
WOLFSSL_MSG("\tCertPolicy length mismatch");
|
WOLFSSL_MSG("\tCertPolicy length mismatch");
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
@ -5638,7 +5668,7 @@ static int DecodePolicyOID(char *out, word32 outSz, byte *in, word32 inSz)
|
|||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(WOLFSSL_SEP)
|
#if defined(WOLFSSL_SEP)
|
||||||
cert->deviceType = (byte*)XMALLOC(length, cert->heap,
|
cert->deviceType = (byte*)XMALLOC(length, cert->heap,
|
||||||
DYNAMIC_TYPE_X509_EXT);
|
DYNAMIC_TYPE_X509_EXT);
|
||||||
if (cert->deviceType == NULL) {
|
if (cert->deviceType == NULL) {
|
||||||
@ -5648,14 +5678,14 @@ static int DecodePolicyOID(char *out, word32 outSz, byte *in, word32 inSz)
|
|||||||
cert->deviceTypeSz = length;
|
cert->deviceTypeSz = length;
|
||||||
XMEMCPY(cert->deviceType, input + idx, length);
|
XMEMCPY(cert->deviceType, input + idx, length);
|
||||||
break;
|
break;
|
||||||
#elif defined(WOLFSSL_CERT_EXT)
|
#elif defined(WOLFSSL_CERT_EXT)
|
||||||
/* decode cert policy */
|
/* decode cert policy */
|
||||||
if (DecodePolicyOID(cert->extCertPolicies[cert->extCertPoliciesNb], MAX_CERTPOL_SZ,
|
if (DecodePolicyOID(cert->extCertPolicies[cert->extCertPoliciesNb], MAX_CERTPOL_SZ,
|
||||||
input + idx, length) != 0) {
|
input + idx, length) != 0) {
|
||||||
WOLFSSL_MSG("\tCouldn't decode CertPolicy");
|
WOLFSSL_MSG("\tCouldn't decode CertPolicy");
|
||||||
return ASN_PARSE_E;
|
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
|
/* From RFC 5280 section 4.2.1.3 "A certificate policy OID MUST
|
||||||
* NOT appear more than once in a certificate policies
|
* NOT appear more than once in a certificate policies
|
||||||
* extension". This is a sanity check for duplicates.
|
* extension". This is a sanity check for duplicates.
|
||||||
@ -5670,12 +5700,12 @@ static int DecodePolicyOID(char *out, word32 outSz, byte *in, word32 inSz)
|
|||||||
return CERTPOLICIES_E;
|
return CERTPOLICIES_E;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* !defined(WOLFSSL_DUP_CERTPOL) */
|
#endif /* !WOLFSSL_DUP_CERTPOL */
|
||||||
cert->extCertPoliciesNb++;
|
cert->extCertPoliciesNb++;
|
||||||
#else
|
#else
|
||||||
WOLFSSL_LEAVE("DecodeCertPolicy : unsupported mode", 0);
|
WOLFSSL_LEAVE("DecodeCertPolicy : unsupported mode", 0);
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
idx += policy_length;
|
idx += policy_length;
|
||||||
} while((int)idx < total_length
|
} while((int)idx < total_length
|
||||||
@ -5985,7 +6015,7 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm)
|
|||||||
|
|
||||||
/* save extensions */
|
/* save extensions */
|
||||||
cert->extensions = &cert->source[cert->srcIdx];
|
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 */
|
cert->extensionsIdx = cert->srcIdx; /* for potential later use */
|
||||||
|
|
||||||
if ((ret = DecodeCertExtensions(cert)) < 0) {
|
if ((ret = DecodeCertExtensions(cert)) < 0) {
|
||||||
@ -6120,10 +6150,10 @@ Signer* MakeSigner(void* heap)
|
|||||||
signer->publicKey = NULL;
|
signer->publicKey = NULL;
|
||||||
signer->nameLen = 0;
|
signer->nameLen = 0;
|
||||||
signer->name = NULL;
|
signer->name = NULL;
|
||||||
#ifndef IGNORE_NAME_CONSTRAINTS
|
#ifndef IGNORE_NAME_CONSTRAINTS
|
||||||
signer->permittedNames = NULL;
|
signer->permittedNames = NULL;
|
||||||
signer->excludedNames = NULL;
|
signer->excludedNames = NULL;
|
||||||
#endif /* IGNORE_NAME_CONSTRAINTS */
|
#endif /* IGNORE_NAME_CONSTRAINTS */
|
||||||
signer->pathLengthSet = 0;
|
signer->pathLengthSet = 0;
|
||||||
signer->pathLength = 0;
|
signer->pathLength = 0;
|
||||||
signer->next = NULL;
|
signer->next = NULL;
|
||||||
@ -6139,12 +6169,12 @@ void FreeSigner(Signer* signer, void* heap)
|
|||||||
{
|
{
|
||||||
XFREE(signer->name, heap, DYNAMIC_TYPE_SUBJECT_CN);
|
XFREE(signer->name, heap, DYNAMIC_TYPE_SUBJECT_CN);
|
||||||
XFREE(signer->publicKey, heap, DYNAMIC_TYPE_PUBLIC_KEY);
|
XFREE(signer->publicKey, heap, DYNAMIC_TYPE_PUBLIC_KEY);
|
||||||
#ifndef IGNORE_NAME_CONSTRAINTS
|
#ifndef IGNORE_NAME_CONSTRAINTS
|
||||||
if (signer->permittedNames)
|
if (signer->permittedNames)
|
||||||
FreeNameSubtrees(signer->permittedNames, heap);
|
FreeNameSubtrees(signer->permittedNames, heap);
|
||||||
if (signer->excludedNames)
|
if (signer->excludedNames)
|
||||||
FreeNameSubtrees(signer->excludedNames, heap);
|
FreeNameSubtrees(signer->excludedNames, heap);
|
||||||
#endif
|
#endif
|
||||||
XFREE(signer, heap, DYNAMIC_TYPE_SIGNER);
|
XFREE(signer, heap, DYNAMIC_TYPE_SIGNER);
|
||||||
|
|
||||||
(void)heap;
|
(void)heap;
|
||||||
@ -6182,12 +6212,12 @@ void FreeTrustedPeer(TrustedPeerCert* tp, void* heap)
|
|||||||
if (tp->sig) {
|
if (tp->sig) {
|
||||||
XFREE(tp->sig, heap, DYNAMIC_TYPE_SIGNATURE);
|
XFREE(tp->sig, heap, DYNAMIC_TYPE_SIGNATURE);
|
||||||
}
|
}
|
||||||
#ifndef IGNORE_NAME_CONSTRAINTS
|
#ifndef IGNORE_NAME_CONSTRAINTS
|
||||||
if (tp->permittedNames)
|
if (tp->permittedNames)
|
||||||
FreeNameSubtrees(tp->permittedNames, heap);
|
FreeNameSubtrees(tp->permittedNames, heap);
|
||||||
if (tp->excludedNames)
|
if (tp->excludedNames)
|
||||||
FreeNameSubtrees(tp->excludedNames, heap);
|
FreeNameSubtrees(tp->excludedNames, heap);
|
||||||
#endif
|
#endif
|
||||||
XFREE(tp, heap, DYNAMIC_TYPE_CERT);
|
XFREE(tp, heap, DYNAMIC_TYPE_CERT);
|
||||||
|
|
||||||
(void)heap;
|
(void)heap;
|
||||||
|
@ -87,7 +87,7 @@ enum ASN_Tags {
|
|||||||
ASN_LONG_LENGTH = 0x80
|
ASN_LONG_LENGTH = 0x80
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ASN_Flags{
|
enum ASN_Flags {
|
||||||
ASN_CONSTRUCTED = 0x20,
|
ASN_CONSTRUCTED = 0x20,
|
||||||
ASN_CONTEXT_SPECIFIC = 0x80
|
ASN_CONTEXT_SPECIFIC = 0x80
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user