@@ -12393,55 +12393,77 @@ int CipherRequires(byte first, byte second, int requirement)
1239312393 *.z.com matches y.z.com but not x.y.z.com
1239412394
1239512395 return 1 on success */
12396- int MatchDomainName(const char* pattern, int len, const char* str)
12396+ int MatchDomainName(const char* pattern, int patternLen, const char* str,
12397+ word32 strLen)
1239712398{
1239812399 int ret = 0;
1239912400
12400- if (pattern == NULL || str == NULL || len < = 0)
12401+ if (pattern == NULL || str == NULL || patternLen <= 0 || strLen = = 0)
1240112402 return 0;
1240212403
12403- while (len > 0) {
12404-
12405- char p = (char)XTOLOWER((unsigned char)*pattern++ );
12404+ while (patternLen > 0) {
12405+ /* Get the next pattern char to evaluate */
12406+ char p = (char)XTOLOWER((unsigned char)*pattern);
1240612407 if (p == '\0')
1240712408 break;
1240812409
12410+ pattern++;
12411+
1240912412 if (p == '*') {
1241012413 char s;
12414+ /* We will always match '*' */
12415+ patternLen--;
1241112416
12412- while (--len > 0) {
12417+ /* Consume any extra '*' chars until the next non '*' char. */
12418+ while (patternLen > 0) {
1241312419 p = (char)XTOLOWER((unsigned char)*pattern);
1241412420 pattern++;
12415- if (p == '\0' && len > 0)
12421+ if (p == '\0' && patternLen > 0)
1241612422 return 0;
1241712423 if (p != '*')
1241812424 break;
12425+
12426+ patternLen--;
1241912427 }
1242012428
12421- if (len == 0)
12422- p = '\0';
12429+ /* Consume str until we reach next char in pattern after '*' or
12430+ * end of string */
12431+ while (strLen > 0) {
12432+ s = (char)XTOLOWER((unsigned char) *str);
12433+ str++;
12434+ strLen--;
12435+
12436+ /* p is next char in pattern after '*', or '*' if '*' is the
12437+ * last char in the pattern (in which case patternLen is 1) */
12438+ if ( ((s == p) && (patternLen > 0))) {
12439+ /* We had already counted the '*' as matched, this means
12440+ * we also matched the next non '*' char in pattern */
12441+ patternLen--;
12442+ break;
12443+ }
1242312444
12424- while ( (s = (char)XTOLOWER((unsigned char) *str)) != '\0') {
12425- if (s == p)
12445+ /* If strlen is 0, we have consumed the entire string. Count that
12446+ * as a match of '*' */
12447+ if (strLen == 0) {
1242612448 break;
12449+ }
12450+
1242712451 if (s == '.')
1242812452 return 0;
12429- str++;
1243012453 }
1243112454 }
1243212455 else {
12456+ /* Simple case, pattern match exactly */
1243312457 if (p != (char)XTOLOWER((unsigned char) *str))
1243412458 return 0;
12435- }
12436-
1243712459
12438- if (len > 0) {
1243912460 str++;
12440- len--;
12461+ strLen--;
12462+ patternLen--;
1244112463 }
1244212464 }
1244312465
12444- if (*str == '\0' && len == 0) {
12466+ if (strLen == 0 && patternLen == 0) {
1244512467 ret = 1; /* success */
1244612468 }
1244712469
@@ -12453,14 +12475,16 @@ int MatchDomainName(const char* pattern, int len, const char* str)
1245312475 * Fail if there are wild patterns and they didn't match.
1245412476 * Check the common name if no alternative names matched.
1245512477 *
12456- * dCert Decoded cert to get the alternative names from.
12457- * domain Domain name to compare against.
12458- * checkCN Whether to check the common name.
12459- * returns 1 : match was found.
12460- * 0 : no match found.
12461- * -1 : No matches and wild pattern match failed.
12478+ * dCert Decoded cert to get the alternative names from.
12479+ * domain Domain name to compare against.
12480+ * domainLen Length of the domain name.
12481+ * checkCN Whether to check the common name.
12482+ * returns 1 : match was found.
12483+ * 0 : no match found.
12484+ * -1 : No matches and wild pattern match failed.
1246212485 */
12463- int CheckForAltNames(DecodedCert* dCert, const char* domain, int* checkCN)
12486+ int CheckForAltNames(DecodedCert* dCert, const char* domain, word32 domainLen,
12487+ int* checkCN)
1246412488{
1246512489 int match = 0;
1246612490 DNS_entry* altName = NULL;
@@ -12491,7 +12515,7 @@ int CheckForAltNames(DecodedCert* dCert, const char* domain, int* checkCN)
1249112515 len = (word32)altName->len;
1249212516 }
1249312517
12494- if (MatchDomainName(buf, (int)len, domain)) {
12518+ if (MatchDomainName(buf, (int)len, domain, domainLen )) {
1249512519 match = 1;
1249612520 if (checkCN != NULL) {
1249712521 *checkCN = 0;
@@ -12525,10 +12549,8 @@ int CheckHostName(DecodedCert* dCert, const char *domainName, size_t domainNameL
1252512549 int checkCN;
1252612550 int ret = DOMAIN_NAME_MISMATCH;
1252712551
12528- /* Assume name is NUL terminated. */
12529- (void)domainNameLen;
12530-
12531- if (CheckForAltNames(dCert, domainName, &checkCN) != 1) {
12552+ if (CheckForAltNames(dCert, domainName, (word32)domainNameLen,
12553+ &checkCN) != 1) {
1253212554 WOLFSSL_MSG("DomainName match on alt names failed");
1253312555 }
1253412556 else {
@@ -12538,7 +12560,7 @@ int CheckHostName(DecodedCert* dCert, const char *domainName, size_t domainNameL
1253812560#ifndef WOLFSSL_HOSTNAME_VERIFY_ALT_NAME_ONLY
1253912561 if (checkCN == 1) {
1254012562 if (MatchDomainName(dCert->subjectCN, dCert->subjectCNLen,
12541- domainName) == 1) {
12563+ domainName, (word32)domainNameLen ) == 1) {
1254212564 ret = 0;
1254312565 }
1254412566 else {
@@ -13576,7 +13598,8 @@ int DoVerifyCallback(WOLFSSL_CERT_MANAGER* cm, WOLFSSL* ssl, int cert_err,
1357613598 ssl->param && ssl->param->hostName[0]) {
1357713599 /* If altNames names is present, then subject common name is ignored */
1357813600 if (args->dCert->altNames != NULL) {
13579- if (CheckForAltNames(args->dCert, ssl->param->hostName, NULL) != 1) {
13601+ if (CheckForAltNames(args->dCert, ssl->param->hostName,
13602+ (word32)XSTRLEN(ssl->param->hostName), NULL) != 1) {
1358013603 if (cert_err == 0) {
1358113604 ret = DOMAIN_NAME_MISMATCH;
1358213605 WOLFSSL_ERROR_VERBOSE(ret);
@@ -13586,9 +13609,11 @@ int DoVerifyCallback(WOLFSSL_CERT_MANAGER* cm, WOLFSSL* ssl, int cert_err,
1358613609 #ifndef WOLFSSL_HOSTNAME_VERIFY_ALT_NAME_ONLY
1358713610 else {
1358813611 if (args->dCert->subjectCN) {
13589- if (MatchDomainName(args->dCert->subjectCN,
13590- args->dCert->subjectCNLen,
13591- ssl->param->hostName) == 0) {
13612+ if (MatchDomainName(
13613+ args->dCert->subjectCN,
13614+ args->dCert->subjectCNLen,
13615+ ssl->param->hostName,
13616+ (word32)XSTRLEN(ssl->param->hostName)) == 0) {
1359213617 if (cert_err == 0) {
1359313618 ret = DOMAIN_NAME_MISMATCH;
1359413619 WOLFSSL_ERROR_VERBOSE(ret);
@@ -15401,6 +15426,9 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1540115426 if (args->dCert->altNames) {
1540215427 if (CheckForAltNames(args->dCert,
1540315428 (char*)ssl->buffers.domainName.buffer,
15429+ (ssl->buffers.domainName.buffer == NULL ? 0 :
15430+ (word32)XSTRLEN(
15431+ (const char *)ssl->buffers.domainName.buffer)),
1540415432 NULL) != 1) {
1540515433 WOLFSSL_MSG("DomainName match on alt names failed");
1540615434 /* try to get peer key still */
@@ -15410,9 +15438,14 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1541015438 }
1541115439 else {
1541215440 if (MatchDomainName(
15413- args->dCert->subjectCN,
15414- args->dCert->subjectCNLen,
15415- (char*)ssl->buffers.domainName.buffer) == 0) {
15441+ args->dCert->subjectCN,
15442+ args->dCert->subjectCNLen,
15443+ (char*)ssl->buffers.domainName.buffer,
15444+ (ssl->buffers.domainName.buffer == NULL ? 0 :
15445+ (word32)XSTRLEN(
15446+ (const char *)ssl->buffers.domainName.buffer)
15447+ )) == 0)
15448+ {
1541615449 WOLFSSL_MSG("DomainName match on common name failed");
1541715450 ret = DOMAIN_NAME_MISMATCH;
1541815451 WOLFSSL_ERROR_VERBOSE(ret);
@@ -15422,10 +15455,15 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1542215455 /* Old behavior. */
1542315456 if (MatchDomainName(args->dCert->subjectCN,
1542415457 args->dCert->subjectCNLen,
15425- (char*)ssl->buffers.domainName.buffer) == 0) {
15458+ (char*)ssl->buffers.domainName.buffer,
15459+ (ssl->buffers.domainName.buffer == NULL ? 0 :
15460+ (word32)XSTRLEN(ssl->buffers.domainName.buffer))) == 0)
15461+ {
1542615462 WOLFSSL_MSG("DomainName match on common name failed");
1542715463 if (CheckForAltNames(args->dCert,
1542815464 (char*)ssl->buffers.domainName.buffer,
15465+ (ssl->buffers.domainName.buffer == NULL ? 0 :
15466+ (word32)XSTRLEN(ssl->buffers.domainName.buffer)),
1542915467 NULL) != 1) {
1543015468 WOLFSSL_MSG(
1543115469 "DomainName match on alt names failed too");
0 commit comments