refactor name constraint checks

This commit is contained in:
Jacob Barthelmeh
2022-07-05 17:20:50 -06:00
parent 43e11ec756
commit ff6edbff94

View File

@@ -14333,6 +14333,68 @@ static int MatchBaseName(int type, const char* name, int nameSz,
} }
/* Search through the list to find if the name is permitted.
* name The DNS name to search for
* dnsList The list to search through
* nameType Type of DNS name to currently searching
* return 1 if found in list or if not needed
* return 0 if not found in the list but is needed
*/
static int PermittedListOk(DNS_entry* name, Base_entry* dnsList, byte nameType)
{
Base_entry* current = dnsList;
int match = 0;
int need = 0;
int ret = 1; /* is ok unless needed and no match found */
while (current != NULL) {
if (current->type == nameType) {
need = 1; /* restriction on permitted names is set for this type */
if (name->len >= current->nameSz &&
MatchBaseName(nameType, name->name, name->len,
current->name, current->nameSz)) {
match = 1; /* found the current name in the permitted list*/
break;
}
}
current = current->next;
}
/* check if permitted name restriction was set and no matching name found */
if (need && !match)
ret = 0;
return ret;
}
/* Search through the list to find if the name is excluded.
* name The DNS name to search for
* dnsList The list to search through
* nameType Type of DNS name to currently searching
* return 1 if found in list and 0 if not found in the list
*/
static int IsInExcludedList(DNS_entry* name, Base_entry* dnsList, byte nameType)
{
int ret = 0; /* default of not found in the list */
Base_entry* current = dnsList;
while (current != NULL) {
if (current->type == nameType) {
if (name->len >= current->nameSz &&
MatchBaseName(nameType, name->name, name->len,
current->name, current->nameSz)) {
ret = 1;
break;
}
}
current = current->next;
}
return ret;
}
static int ConfirmNameConstraints(Signer* signer, DecodedCert* cert) static int ConfirmNameConstraints(Signer* signer, DecodedCert* cert)
{ {
const byte nameTypes[] = {ASN_RFC822_TYPE, ASN_DNS_TYPE, ASN_DIR_TYPE}; const byte nameTypes[] = {ASN_RFC822_TYPE, ASN_DNS_TYPE, ASN_DIR_TYPE};
@@ -14347,9 +14409,9 @@ static int ConfirmNameConstraints(Signer* signer, DecodedCert* cert)
for (i=0; i < (int)sizeof(nameTypes); i++) { for (i=0; i < (int)sizeof(nameTypes); i++) {
byte nameType = nameTypes[i]; byte nameType = nameTypes[i];
DNS_entry* name = NULL; DNS_entry* name = NULL;
DNS_entry subjectDnsName; DNS_entry subjectDnsName; /* temporary node used for subject name */
Base_entry* base;
XMEMSET(&subjectDnsName, 0, sizeof(DNS_entry));
switch (nameType) { switch (nameType) {
case ASN_DNS_TYPE: case ASN_DNS_TYPE:
/* Should it also consider CN in subject? It could use /* Should it also consider CN in subject? It could use
@@ -14360,11 +14422,7 @@ static int ConfirmNameConstraints(Signer* signer, DecodedCert* cert)
/* Shouldn't it validade E= in subject as well? */ /* Shouldn't it validade E= in subject as well? */
name = cert->altEmailNames; name = cert->altEmailNames;
/* Add subject email to temporary list for checking. /* Add subject email for checking. */
* In the case of no subject alt. names, the list will be a
* single node having the subject name email address. The node
* subjectDnsName is not needed after done being compared with
* in this function */
if (cert->subjectEmail != NULL) { if (cert->subjectEmail != NULL) {
/* RFC 5280 section 4.2.1.10 /* RFC 5280 section 4.2.1.10
* "When constraints are imposed on the rfc822Name name * "When constraints are imposed on the rfc822Name name
@@ -14372,34 +14430,29 @@ static int ConfirmNameConstraints(Signer* signer, DecodedCert* cert)
* alternative name, the rfc822Name constraint MUST be * alternative name, the rfc822Name constraint MUST be
* applied to the attribute of type emailAddress in the * applied to the attribute of type emailAddress in the
* subject distinguished name" */ * subject distinguished name" */
subjectDnsName.next = name; subjectDnsName.next = NULL;
subjectDnsName.type = ASN_RFC822_TYPE; subjectDnsName.type = ASN_RFC822_TYPE;
subjectDnsName.len = cert->subjectEmailLen; subjectDnsName.len = cert->subjectEmailLen;
subjectDnsName.name = (char *)cert->subjectEmail; subjectDnsName.name = (char *)cert->subjectEmail;
name = &subjectDnsName;
} }
break; break;
case ASN_DIR_TYPE: case ASN_DIR_TYPE:
if (cert->subjectRaw != NULL) { name = cert->altDirNames;
subjectDnsName.next = NULL;
subjectDnsName.type = ASN_DIR_TYPE;
subjectDnsName.len = cert->subjectRawLen;
subjectDnsName.name = (char *)cert->subjectRaw;
name = &subjectDnsName;
}
#ifndef WOLFSSL_NO_ASN_STRICT #ifndef WOLFSSL_NO_ASN_STRICT
/* RFC 5280 section 4.2.1.10 /* RFC 5280 section 4.2.1.10
"Restrictions of the form directoryName MUST be "Restrictions of the form directoryName MUST be
applied to the subject field .... and to any names applied to the subject field .... and to any names
of type directoryName in the subjectAltName of type directoryName in the subjectAltName
extension" extension"
*/ */
if (name != NULL) if (cert->subjectRaw != NULL) {
name->next = cert->altDirNames; subjectDnsName.next = NULL;
else subjectDnsName.type = ASN_DIR_TYPE;
name = cert->altDirNames; subjectDnsName.len = cert->subjectRawLen;
#endif subjectDnsName.name = (char *)cert->subjectRaw;
}
#endif
break; break;
default: default:
/* Other types of names are ignored for now. /* Other types of names are ignored for now.
@@ -14409,44 +14462,35 @@ static int ConfirmNameConstraints(Signer* signer, DecodedCert* cert)
} }
while (name != NULL) { while (name != NULL) {
int match = 0; if (IsInExcludedList(name, signer->excludedNames, nameType) == 1) {
int need = 0; WOLFSSL_MSG("Excluded name was found!");
return 0;
base = signer->excludedNames;
/* Check against the excluded list */
while (base != NULL) {
if (base->type == nameType) {
if (name->len >= base->nameSz &&
MatchBaseName(nameType,
name->name, name->len,
base->name, base->nameSz)) {
return 0;
}
}
base = base->next;
} }
/* Check against the permitted list */ /* Check against the permitted list */
base = signer->permittedNames; if (PermittedListOk(name, signer->permittedNames, nameType) != 1) {
while (base != NULL) { WOLFSSL_MSG("Permitted name was not found!");
if (base->type == nameType) { return 0;
need = 1;
if (name->len >= base->nameSz &&
MatchBaseName(nameType,
name->name, name->len,
base->name, base->nameSz)) {
match = 1;
break;
}
}
base = base->next;
} }
if (need && !match)
return 0;
name = name->next; name = name->next;
} }
/* handle comparing against subject name too */
if (subjectDnsName.len > 0 && subjectDnsName.name != NULL) {
if (IsInExcludedList(&subjectDnsName, signer->excludedNames,
nameType) == 1) {
WOLFSSL_MSG("Excluded name was found!");
return 0;
}
/* Check against the permitted list */
if (PermittedListOk(&subjectDnsName, signer->permittedNames,
nameType) != 1) {
WOLFSSL_MSG("Permitted name was not found!");
return 0;
}
}
} }
return 1; return 1;