Fix for parsing permitted name constraint for subject directory name. Cleanup to use switch in ConfirmNameConstraints.

This commit is contained in:
David Garske
2017-05-18 14:06:56 -07:00
parent 4370a01778
commit 36e1fb5e5b
2 changed files with 114 additions and 84 deletions

View File

@ -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) {
case ASN_DNS_TYPE:
{
DNS_entry* name = cert->altNames; DNS_entry* name = cert->altNames;
while (name != NULL) { while (name != NULL) {
if (MatchBaseName(ASN_DNS_TYPE, 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;
} }
else if (base->type == ASN_RFC822_TYPE) { case 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; return 0;
}
name = name->next; name = name->next;
} }
break;
} }
else if (base->type == ASN_DIR_TYPE) { case ASN_DIR_TYPE:
if (cert->subjectRawLen == base->nameSz && {
XMEMCMP(cert->subjectRaw, base->name, base->nameSz) == 0) { /* allow permitted dirName smaller than actual subject */
if (cert->subjectRawLen >= base->nameSz &&
XMEMCMP(cert->subjectRaw, base->name,
base->nameSz) == 0) {
return 0; return 0;
} }
break;
} }
}; /* switch */
base = base->next; base = base->next;
} }
} }
@ -4859,7 +4869,9 @@ 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) {
case ASN_DNS_TYPE:
{
DNS_entry* name = cert->altNames; DNS_entry* name = cert->altNames;
if (name != NULL) if (name != NULL)
@ -4871,8 +4883,10 @@ static int ConfirmNameConstraints(Signer* signer, DecodedCert* cert)
base->name, base->nameSz); base->name, base->nameSz);
name = name->next; name = name->next;
} }
break;
} }
else if (base->type == ASN_RFC822_TYPE) { case ASN_RFC822_TYPE:
{
DNS_entry* name = cert->altEmailNames; DNS_entry* name = cert->altEmailNames;
if (name != NULL) if (name != NULL)
@ -4884,22 +4898,27 @@ static int ConfirmNameConstraints(Signer* signer, DecodedCert* cert)
base->name, base->nameSz); base->name, base->nameSz);
name = name->next; name = name->next;
} }
break;
} }
else if (base->type == ASN_DIR_TYPE) { case ASN_DIR_TYPE:
{
/* allow permitted dirName smaller than actual subject */
needDir = 1; needDir = 1;
if (cert->subjectRaw != NULL && if (cert->subjectRaw != NULL &&
cert->subjectRawLen == base->nameSz && cert->subjectRawLen >= base->nameSz &&
XMEMCMP(cert->subjectRaw, base->name, base->nameSz) == 0) { XMEMCMP(cert->subjectRaw, base->name,
base->nameSz) == 0) {
matchDir = 1; matchDir = 1;
} }
break;
} }
} /* switch */
base = base->next; base = base->next;
} }
if ((needDns && !matchDns) || (needEmail && !matchEmail) || if ((needDns && !matchDns) ||
(needEmail && !matchEmail) ||
(needDir && !matchDir)) { (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;
} }
@ -5670,7 +5700,7 @@ 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);