Merge pull request #3174 from embhorn/zd10655

Fix CheckAltNames to handle IP type
This commit is contained in:
JacobBarthelmeh
2020-08-07 16:04:56 -06:00
committed by GitHub
5 changed files with 96 additions and 48 deletions

View File

@ -9312,31 +9312,6 @@ int MatchDomainName(const char* pattern, int len, const char* str)
}
/* try to find an altName match to domain, return 1 on success */
int CheckAltNames(DecodedCert* dCert, char* domain)
{
int match = 0;
DNS_entry* altName = NULL;
WOLFSSL_MSG("Checking AltNames");
if (dCert)
altName = dCert->altNames;
while (altName) {
WOLFSSL_MSG("\tindividual AltName check");
if (MatchDomainName(altName->name, altName->len, domain)){
match = 1;
break;
}
altName = altName->next;
}
return match;
}
/* Check that alternative names, if they exists, match the domain.
* Fail if there are wild patterns and they didn't match.
* Check the common name if no alternative names matched.
@ -9348,30 +9323,66 @@ int CheckAltNames(DecodedCert* dCert, char* domain)
* 0 : no match found.
* -1 : No matches and wild pattern match failed.
*/
static int CheckForAltNames(DecodedCert* dCert, const char* domain, int* checkCN)
int CheckForAltNames(DecodedCert* dCert, const char* domain, int* checkCN)
{
int match;
int match = 0;
DNS_entry* altName = NULL;
char *buf;
word32 len;
WOLFSSL_MSG("Checking AltNames");
if (dCert)
altName = dCert->altNames;
*checkCN = altName == NULL;
match = 0;
if (checkCN != NULL) {
*checkCN = altName == NULL;
}
while (altName) {
WOLFSSL_MSG("\tindividual AltName check");
if (MatchDomainName(altName->name, altName->len, domain)) {
#if defined(OPENSSL_ALL) || defined(WOLFSSL_IP_ALT_NAME)
char name[WOLFSSL_MAX_IPSTR] = {0};
/* check if alt name is stored as IP addr octet */
if (altName->type == ASN_IP_TYPE) {
char tmp[4];
int i;
word32 idx = 0;
for (i = 0; (idx < WOLFSSL_MAX_IPSTR) && (i < altName->len); i++) {
XMEMSET(tmp, 0, sizeof(tmp));
XSNPRINTF(tmp, sizeof(tmp), (altName->len <= 4) ? "%u" : "%02X",
altName->name[i]);
idx += XSTRLEN(tmp);
XSTRNCAT(name, tmp, (altName->len <= 4) ? 3 : 2);
if ((idx < WOLFSSL_MAX_IPSTR ) && ((i + 1) < altName->len)) {
name[idx++] = (altName->len <= 4) ? '.' : ':';
}
}
if (idx >= WOLFSSL_MAX_IPSTR) {
idx = WOLFSSL_MAX_IPSTR -1;
}
name[idx] = '\0';
buf = name;
len = (word32)XSTRLEN(name);
}
else
#endif /* OPENSSL_ALL || WOLFSSL_IP_ALT_NAME */
{
buf = altName->name;
len = altName->len;
}
if (MatchDomainName(buf, len, domain)) {
match = 1;
*checkCN = 0;
if (checkCN != NULL) {
*checkCN = 0;
}
WOLFSSL_MSG("\tmatch found");
break;
}
/* No matches and wild pattern match failed. */
else if (altName->name && altName->len >=1 &&
altName->name[0] == '*' && match == 0) {
else if (buf && (len >=1) && (buf[0] == '*')) {
match = -1;
WOLFSSL_MSG("\twildcard match failed");
}
@ -9975,7 +9986,7 @@ int DoVerifyCallback(WOLFSSL_CERT_MANAGER* cm, WOLFSSL* ssl, int ret,
ssl->param && ssl->param->hostName[0]) {
/* If altNames names is present, then subject common name is ignored */
if (args->dCert->altNames != NULL) {
if (CheckAltNames(args->dCert, ssl->param->hostName) == 0 ) {
if (CheckForAltNames(args->dCert, ssl->param->hostName, NULL) != 1) {
if (ret == 0) {
ret = DOMAIN_NAME_MISMATCH;
}
@ -11255,8 +11266,9 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
* are to be bound into a certificate, the subject
* alternative name extension MUST be used." */
if (args->dCert->altNames) {
if (CheckAltNames(args->dCert,
(char*)ssl->buffers.domainName.buffer) == 0 ) {
if (CheckForAltNames(args->dCert,
(char*)ssl->buffers.domainName.buffer,
NULL) != 1) {
WOLFSSL_MSG("DomainName match on alt names failed");
/* try to get peer key still */
ret = DOMAIN_NAME_MISMATCH;
@ -11277,8 +11289,9 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
args->dCert->subjectCNLen,
(char*)ssl->buffers.domainName.buffer) == 0) {
WOLFSSL_MSG("DomainName match on common name failed");
if (CheckAltNames(args->dCert,
(char*)ssl->buffers.domainName.buffer) == 0 ) {
if (CheckForAltNames(args->dCert,
(char*)ssl->buffers.domainName.buffer,
NULL) != 1) {
WOLFSSL_MSG(
"DomainName match on alt names failed too");
/* try to get peer key still */

View File

@ -9526,20 +9526,16 @@ err:
#ifdef OPENSSL_EXTRA
#ifndef NO_CERTS
int wolfSSL_X509_add_altname(WOLFSSL_X509* x509, const char* name, int type)
int wolfSSL_X509_add_altname_ex(WOLFSSL_X509* x509, const char* name,
word32 nameSz, int type)
{
DNS_entry* newAltName = NULL;
char* nameCopy = NULL;
word32 nameSz;
if (x509 == NULL)
return WOLFSSL_FAILURE;
if (name == NULL)
return WOLFSSL_SUCCESS;
nameSz = (word32)XSTRLEN(name);
if (nameSz == 0)
if ((name == NULL) || (nameSz == 0))
return WOLFSSL_SUCCESS;
newAltName = (DNS_entry*)XMALLOC(sizeof(DNS_entry),
@ -9553,7 +9549,9 @@ int wolfSSL_X509_add_altname(WOLFSSL_X509* x509, const char* name, int type)
return WOLFSSL_FAILURE;
}
XMEMCPY(nameCopy, name, nameSz + 1);
XMEMCPY(nameCopy, name, nameSz);
nameCopy[nameSz] = '\0';
newAltName->next = x509->altNames;
newAltName->type = type;
@ -9564,6 +9562,25 @@ int wolfSSL_X509_add_altname(WOLFSSL_X509* x509, const char* name, int type)
return WOLFSSL_SUCCESS;
}
int wolfSSL_X509_add_altname(WOLFSSL_X509* x509, const char* name, int type)
{
word32 nameSz;
if (name == NULL)
return WOLFSSL_SUCCESS;
nameSz = (word32)XSTRLEN(name);
if (nameSz == 0)
return WOLFSSL_SUCCESS;
if (type == ASN_IP_TYPE) {
WOLFSSL_MSG("Type not supported, use wolfSSL_X509_add_altname_ex");
return WOLFSSL_FAILURE;
}
return wolfSSL_X509_add_altname_ex(x509, name, nameSz, type);
}
#ifndef NO_WOLFSSL_STUB
int wolfSSL_X509_add_ext(WOLFSSL_X509 *x509, WOLFSSL_X509_EXTENSION *ext, int loc)

View File

@ -27423,7 +27423,7 @@ static void test_wolfSSL_X509_sign(void)
#ifdef WOLFSSL_ALT_NAMES
/* Add some subject alt names */
AssertIntNE(wolfSSL_X509_add_altname(NULL,
NULL, ASN_DNS_TYPE), SSL_SUCCESS);
"ipsum", ASN_DNS_TYPE), SSL_SUCCESS);
AssertIntEQ(wolfSSL_X509_add_altname(x509,
NULL, ASN_DNS_TYPE), SSL_SUCCESS);
AssertIntEQ(wolfSSL_X509_add_altname(x509,
@ -27435,7 +27435,15 @@ static void test_wolfSSL_X509_sign(void)
AssertIntEQ(wolfSSL_X509_add_altname(x509,
"Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch",
ASN_DNS_TYPE), SSL_SUCCESS);
#if defined(OPENSSL_ALL) || defined(WOLFSSL_IP_ALT_NAME)
{
unsigned char ip_type[] = {127,0,0,1};
AssertIntEQ(wolfSSL_X509_add_altname_ex(x509, (char*)ip_type,
sizeof(ip_type), ASN_IP_TYPE), SSL_SUCCESS);
}
#endif
#endif /* WOLFSSL_ALT_NAMES */
/* Test invalid parameters */
AssertIntEQ(X509_sign(NULL, priv, EVP_sha256()), 0);
AssertIntEQ(X509_sign(x509, NULL, EVP_sha256()), 0);
@ -27443,6 +27451,10 @@ static void test_wolfSSL_X509_sign(void)
ret = X509_sign(x509, priv, EVP_sha256());
#if defined(WOLFSSL_ALT_NAMES) && (defined(OPENSSL_ALL) || defined(WOLFSSL_IP_ALT_NAME))
AssertIntEQ(wolfSSL_X509_check_ip_asc(x509, "127.0.0.1", 0), 1);
#endif
#if 0
/* example for writing to file */
XFILE tmpFile = XFOPEN("./signed.der", "wb");
@ -27472,8 +27484,13 @@ static void test_wolfSSL_X509_sign(void)
/* Valid case - size should be 798 with 16 byte serial number */
AssertIntEQ(ret, 782 + snSz);
#else /* WOLFSSL_ALT_NAMES */
#if defined(OPENSSL_ALL) || defined(WOLFSSL_IP_ALT_NAME)
/* Valid case - size should be 936 with 16 byte serial number */
AssertIntEQ(ret, 920 + snSz);
#else
/* Valid case - size should be 927 with 16 byte serial number */
AssertIntEQ(ret, 911 + snSz);
#endif
#endif /* WOLFSSL_ALT_NAMES */
X509_NAME_free(name);

View File

@ -1694,7 +1694,7 @@ WOLFSSL_LOCAL void FreeSuites(WOLFSSL* ssl);
WOLFSSL_LOCAL int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, word32 size);
WOLFSSL_LOCAL int MatchDomainName(const char* pattern, int len, const char* str);
#ifndef NO_CERTS
WOLFSSL_LOCAL int CheckAltNames(DecodedCert* dCert, char* domain);
WOLFSSL_LOCAL int CheckForAltNames(DecodedCert* dCert, const char* domain, int* checkCN);
WOLFSSL_LOCAL int CheckIPAddr(DecodedCert* dCert, const char* ipasc);
#endif
WOLFSSL_LOCAL int CreateTicket(WOLFSSL* ssl);

View File

@ -2149,6 +2149,7 @@ WOLFSSL_API int wolfSSL_X509_version(WOLFSSL_X509*);
WOLFSSL_API int wolfSSL_cmp_peer_cert_to_file(WOLFSSL*, const char*);
WOLFSSL_ABI WOLFSSL_API char* wolfSSL_X509_get_next_altname(WOLFSSL_X509*);
WOLFSSL_API int wolfSSL_X509_add_altname_ex(WOLFSSL_X509*, const char*, word32, int);
WOLFSSL_API int wolfSSL_X509_add_altname(WOLFSSL_X509*, const char*, int);
WOLFSSL_API WOLFSSL_X509* wolfSSL_d2i_X509(WOLFSSL_X509** x509,