Merge pull request #5274 from JacobBarthelmeh/Certs

remove subject/issuer email from altEmailNames list
pull/5330/head
David Garske 2022-07-06 10:48:21 -07:00 committed by GitHub
commit e92034cf6f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 125 additions and 89 deletions

View File

@ -47067,6 +47067,11 @@ static void test_wc_ParseCert(void)
wc_InitDecodedCert(&decodedCert, rawCert, rawCertSize, NULL); wc_InitDecodedCert(&decodedCert, rawCert, rawCertSize, NULL);
AssertIntEQ(wc_ParseCert(&decodedCert, CERT_TYPE, NO_VERIFY, NULL), 0); AssertIntEQ(wc_ParseCert(&decodedCert, CERT_TYPE, NO_VERIFY, NULL), 0);
#ifndef IGNORE_NAME_CONSTRAINTS
/* check that the subjects emailAddress was not put in the alt name list */
AssertNotNull(decodedCert.subjectEmail);
AssertNull(decodedCert.altEmailNames);
#endif
wc_FreeDecodedCert(&decodedCert); wc_FreeDecodedCert(&decodedCert);
printf(resultFmt, passed); printf(resultFmt, passed);

View File

@ -11261,14 +11261,14 @@ static int SetSubject(DecodedCert* cert, int id, byte* str, word32 strLen,
SetCertNameSubjectLen(cert, id, strLen); SetCertNameSubjectLen(cert, id, strLen);
SetCertNameSubjectEnc(cert, id, tag); SetCertNameSubjectEnc(cert, id, tag);
} }
#endif
#if !defined(IGNORE_NAME_CONSTRAINTS) || \
defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
else if (id == ASN_EMAIL) { else if (id == ASN_EMAIL) {
cert->subjectEmail = (char*)str; cert->subjectEmail = (char*)str;
cert->subjectEmailLen = strLen; cert->subjectEmailLen = strLen;
#if !defined(IGNORE_NAME_CONSTRAINTS)
ret = SetDNSEntry(cert, cert->subjectEmail, strLen, 0,
&cert->altEmailNames);
#endif
} }
#endif
#ifdef WOLFSSL_CERT_EXT #ifdef WOLFSSL_CERT_EXT
/* TODO: consider mapping id to an index and using SetCertNameSubect*(). */ /* TODO: consider mapping id to an index and using SetCertNameSubect*(). */
else if (id == ASN_JURIS_C) { else if (id == ASN_JURIS_C) {
@ -11281,7 +11281,6 @@ static int SetSubject(DecodedCert* cert, int id, byte* str, word32 strLen,
cert->subjectJSLen = strLen; cert->subjectJSLen = strLen;
cert->subjectJSEnc = tag; cert->subjectJSEnc = tag;
} }
#endif
#endif #endif
return ret; return ret;
@ -11904,7 +11903,8 @@ static int GetCertName(DecodedCert* cert, char* full, byte* hash, int nameType,
copy = WOLFSSL_EMAIL_ADDR; copy = WOLFSSL_EMAIL_ADDR;
} }
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT) #if !defined(IGNORE_NAME_CONSTRAINTS) || \
defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
if (nameType == SUBJECT) { if (nameType == SUBJECT) {
cert->subjectEmail = (char*)&input[srcIdx]; cert->subjectEmail = (char*)&input[srcIdx];
cert->subjectEmailLen = strLen; cert->subjectEmailLen = strLen;
@ -11921,41 +11921,6 @@ static int GetCertName(DecodedCert* cert, char* full, byte* hash, int nameType,
&& !defined(WOLFCRYPT_ONLY) && !defined(WOLFCRYPT_ONLY)
nid = NID_emailAddress; nid = NID_emailAddress;
#endif /* OPENSSL_EXTRA */ #endif /* OPENSSL_EXTRA */
#ifndef IGNORE_NAME_CONSTRAINTS
{
DNS_entry* emailName;
emailName = AltNameNew(cert->heap);
if (emailName == NULL) {
WOLFSSL_MSG("\tOut of Memory");
#if (defined(OPENSSL_EXTRA) || \
defined(OPENSSL_EXTRA_X509_SMALL)) && \
!defined(WOLFCRYPT_ONLY)
wolfSSL_X509_NAME_free(dName);
#endif /* OPENSSL_EXTRA */
return MEMORY_E;
}
emailName->type = 0;
emailName->name = (char*)XMALLOC(strLen + 1,
cert->heap, DYNAMIC_TYPE_ALTNAME);
if (emailName->name == NULL) {
WOLFSSL_MSG("\tOut of Memory");
XFREE(emailName, cert->heap, DYNAMIC_TYPE_ALTNAME);
#if (defined(OPENSSL_EXTRA) || \
defined(OPENSSL_EXTRA_X509_SMALL)) && \
!defined(WOLFCRYPT_ONLY)
wolfSSL_X509_NAME_free(dName);
#endif /* OPENSSL_EXTRA */
return MEMORY_E;
}
emailName->len = strLen;
XMEMCPY(emailName->name, &input[srcIdx], strLen);
emailName->name[strLen] = '\0';
emailName->next = cert->altEmailNames;
cert->altEmailNames = emailName;
}
#endif /* IGNORE_NAME_CONSTRAINTS */
} }
if (pilot) { if (pilot) {
@ -14525,6 +14490,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};
@ -14539,9 +14566,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
@ -14551,28 +14578,38 @@ static int ConfirmNameConstraints(Signer* signer, DecodedCert* cert)
case ASN_RFC822_TYPE: case ASN_RFC822_TYPE:
/* 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 for checking. */
if (cert->subjectEmail != NULL) {
/* RFC 5280 section 4.2.1.10
* "When constraints are imposed on the rfc822Name name
* form, but the certificate does not include a subject
* alternative name, the rfc822Name constraint MUST be
* applied to the attribute of type emailAddress in the
* subject distinguished name" */
subjectDnsName.next = NULL;
subjectDnsName.type = ASN_RFC822_TYPE;
subjectDnsName.len = cert->subjectEmailLen;
subjectDnsName.name = (char *)cert->subjectEmail;
}
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.
@ -14582,44 +14619,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;

View File

@ -1636,6 +1636,11 @@ struct DecodedCert {
const byte* subjectRaw; /* pointer to subject inside source */ const byte* subjectRaw; /* pointer to subject inside source */
int subjectRawLen; int subjectRawLen;
#endif #endif
#if !defined(IGNORE_NAME_CONSTRAINTS) || \
defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
char* subjectEmail;
int subjectEmailLen;
#endif
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT) #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
/* easy access to subject info for other sign */ /* easy access to subject info for other sign */
char* subjectSN; char* subjectSN;
@ -1677,8 +1682,6 @@ struct DecodedCert {
char* subjectPC; char* subjectPC;
int subjectPCLen; int subjectPCLen;
char subjectPCEnc; char subjectPCEnc;
char* subjectEmail;
int subjectEmailLen;
#if defined(WOLFSSL_HAVE_ISSUER_NAMES) #if defined(WOLFSSL_HAVE_ISSUER_NAMES)
char* issuerCN; char* issuerCN;
int issuerCNLen; int issuerCNLen;