@@ -12377,55 +12377,77 @@ int CipherRequires(byte first, byte second, int requirement)
1237712377 *.z.com matches y.z.com but not x.y.z.com
1237812378
1237912379 return 1 on success */
12380- int MatchDomainName(const char* pattern, int len, const char* str)
12380+ int MatchDomainName(const char* pattern, int patternLen, const char* str,
12381+ word32 strLen)
1238112382{
1238212383 int ret = 0;
1238312384
12384- if (pattern == NULL || str == NULL || len < = 0)
12385+ if (pattern == NULL || str == NULL || patternLen <= 0 || strLen = = 0)
1238512386 return 0;
1238612387
12387- while (len > 0) {
12388-
12389- char p = (char)XTOLOWER((unsigned char)*pattern++ );
12388+ while (patternLen > 0) {
12389+ /* Get the next pattern char to evaluate */
12390+ char p = (char)XTOLOWER((unsigned char)*pattern);
1239012391 if (p == '\0')
1239112392 break;
1239212393
12394+ pattern++;
12395+
1239312396 if (p == '*') {
1239412397 char s;
12398+ /* We will always match '*' */
12399+ patternLen--;
1239512400
12396- while (--len > 0) {
12401+ /* Consume any extra '*' chars until the next non '*' char. */
12402+ while (patternLen > 0) {
1239712403 p = (char)XTOLOWER((unsigned char)*pattern);
1239812404 pattern++;
12399- if (p == '\0' && len > 0)
12405+ if (p == '\0' && patternLen > 0)
1240012406 return 0;
1240112407 if (p != '*')
1240212408 break;
12409+
12410+ patternLen--;
1240312411 }
1240412412
12405- if (len == 0)
12406- p = '\0';
12413+ /* Consume str until we reach next char in pattern after '*' or
12414+ * end of string */
12415+ while (strLen > 0) {
12416+ s = (char)XTOLOWER((unsigned char) *str);
12417+ str++;
12418+ strLen--;
1240712419
12408- while ( (s = (char)XTOLOWER((unsigned char) *str)) != '\0') {
12409- if (s == p)
12410- break;
1241112420 if (s == '.')
1241212421 return 0;
12413- str++;
12422+
12423+ /* p is next char in pattern after '*', or '*' if '*' is the
12424+ * last char in the pattern (in which case patternLen is 1) */
12425+ if ( ((s == p) && (patternLen > 0))) {
12426+ /* We had already counted the '*' as matched, this means
12427+ * we also matched the next non '*' char in pattern */
12428+ patternLen--;
12429+ break;
12430+ }
12431+
12432+ /* If strlen is 0, we have consumed the entire string. Count that
12433+ * as a match of '*' */
12434+ if (strLen == 0) {
12435+ break;
12436+ }
1241412437 }
1241512438 }
1241612439 else {
12440+ /* Simple case, pattern match exactly */
1241712441 if (p != (char)XTOLOWER((unsigned char) *str))
1241812442 return 0;
12419- }
12420-
1242112443
12422- if (len > 0) {
1242312444 str++;
12424- len--;
12445+ strLen--;
12446+ patternLen--;
1242512447 }
1242612448 }
1242712449
12428- if (*str == '\0' && len == 0) {
12450+ if (strLen == 0 && patternLen == 0) {
1242912451 ret = 1; /* success */
1243012452 }
1243112453
@@ -12437,14 +12459,16 @@ int MatchDomainName(const char* pattern, int len, const char* str)
1243712459 * Fail if there are wild patterns and they didn't match.
1243812460 * Check the common name if no alternative names matched.
1243912461 *
12440- * dCert Decoded cert to get the alternative names from.
12441- * domain Domain name to compare against.
12442- * checkCN Whether to check the common name.
12443- * returns 1 : match was found.
12444- * 0 : no match found.
12445- * -1 : No matches and wild pattern match failed.
12462+ * dCert Decoded cert to get the alternative names from.
12463+ * domain Domain name to compare against.
12464+ * domainLen Length of the domain name.
12465+ * checkCN Whether to check the common name.
12466+ * returns 1 : match was found.
12467+ * 0 : no match found.
12468+ * -1 : No matches and wild pattern match failed.
1244612469 */
12447- int CheckForAltNames(DecodedCert* dCert, const char* domain, int* checkCN)
12470+ int CheckForAltNames(DecodedCert* dCert, const char* domain, word32 domainLen,
12471+ int* checkCN)
1244812472{
1244912473 int match = 0;
1245012474 DNS_entry* altName = NULL;
@@ -12475,7 +12499,7 @@ int CheckForAltNames(DecodedCert* dCert, const char* domain, int* checkCN)
1247512499 len = (word32)altName->len;
1247612500 }
1247712501
12478- if (MatchDomainName(buf, (int)len, domain)) {
12502+ if (MatchDomainName(buf, (int)len, domain, domainLen )) {
1247912503 match = 1;
1248012504 if (checkCN != NULL) {
1248112505 *checkCN = 0;
@@ -12509,10 +12533,8 @@ int CheckHostName(DecodedCert* dCert, const char *domainName, size_t domainNameL
1250912533 int checkCN;
1251012534 int ret = DOMAIN_NAME_MISMATCH;
1251112535
12512- /* Assume name is NUL terminated. */
12513- (void)domainNameLen;
12514-
12515- if (CheckForAltNames(dCert, domainName, &checkCN) != 1) {
12536+ if (CheckForAltNames(dCert, domainName, (word32)domainNameLen,
12537+ &checkCN) != 1) {
1251612538 WOLFSSL_MSG("DomainName match on alt names failed");
1251712539 }
1251812540 else {
@@ -12522,7 +12544,7 @@ int CheckHostName(DecodedCert* dCert, const char *domainName, size_t domainNameL
1252212544#ifndef WOLFSSL_HOSTNAME_VERIFY_ALT_NAME_ONLY
1252312545 if (checkCN == 1) {
1252412546 if (MatchDomainName(dCert->subjectCN, dCert->subjectCNLen,
12525- domainName) == 1) {
12547+ domainName, (word32)domainNameLen ) == 1) {
1252612548 ret = 0;
1252712549 }
1252812550 else {
@@ -13560,7 +13582,8 @@ int DoVerifyCallback(WOLFSSL_CERT_MANAGER* cm, WOLFSSL* ssl, int cert_err,
1356013582 ssl->param && ssl->param->hostName[0]) {
1356113583 /* If altNames names is present, then subject common name is ignored */
1356213584 if (args->dCert->altNames != NULL) {
13563- if (CheckForAltNames(args->dCert, ssl->param->hostName, NULL) != 1) {
13585+ if (CheckForAltNames(args->dCert, ssl->param->hostName,
13586+ (word32)XSTRLEN(ssl->param->hostName), NULL) != 1) {
1356413587 if (cert_err == 0) {
1356513588 ret = DOMAIN_NAME_MISMATCH;
1356613589 WOLFSSL_ERROR_VERBOSE(ret);
@@ -13570,9 +13593,11 @@ int DoVerifyCallback(WOLFSSL_CERT_MANAGER* cm, WOLFSSL* ssl, int cert_err,
1357013593 #ifndef WOLFSSL_HOSTNAME_VERIFY_ALT_NAME_ONLY
1357113594 else {
1357213595 if (args->dCert->subjectCN) {
13573- if (MatchDomainName(args->dCert->subjectCN,
13574- args->dCert->subjectCNLen,
13575- ssl->param->hostName) == 0) {
13596+ if (MatchDomainName(
13597+ args->dCert->subjectCN,
13598+ args->dCert->subjectCNLen,
13599+ ssl->param->hostName,
13600+ (word32)XSTRLEN(ssl->param->hostName)) == 0) {
1357613601 if (cert_err == 0) {
1357713602 ret = DOMAIN_NAME_MISMATCH;
1357813603 WOLFSSL_ERROR_VERBOSE(ret);
@@ -15385,6 +15410,8 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1538515410 if (args->dCert->altNames) {
1538615411 if (CheckForAltNames(args->dCert,
1538715412 (char*)ssl->buffers.domainName.buffer,
15413+ (ssl->buffers.domainName.buffer == NULL ? 0 :
15414+ (word32)XSTRLEN((const char *)ssl->buffers.domainName.buffer)),
1538815415 NULL) != 1) {
1538915416 WOLFSSL_MSG("DomainName match on alt names failed");
1539015417 /* try to get peer key still */
@@ -15394,9 +15421,12 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1539415421 }
1539515422 else {
1539615423 if (MatchDomainName(
15397- args->dCert->subjectCN,
15398- args->dCert->subjectCNLen,
15399- (char*)ssl->buffers.domainName.buffer) == 0) {
15424+ args->dCert->subjectCN,
15425+ args->dCert->subjectCNLen,
15426+ (char*)ssl->buffers.domainName.buffer,
15427+ (ssl->buffers.domainName.buffer == NULL ? 0 :
15428+ (word32)XSTRLEN((const char *)ssl->buffers.domainName.buffer))) == 0)
15429+ {
1540015430 WOLFSSL_MSG("DomainName match on common name failed");
1540115431 ret = DOMAIN_NAME_MISMATCH;
1540215432 WOLFSSL_ERROR_VERBOSE(ret);
@@ -15406,10 +15436,15 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1540615436 /* Old behavior. */
1540715437 if (MatchDomainName(args->dCert->subjectCN,
1540815438 args->dCert->subjectCNLen,
15409- (char*)ssl->buffers.domainName.buffer) == 0) {
15439+ (char*)ssl->buffers.domainName.buffer,
15440+ (ssl->buffers.domainName.buffer == NULL ? 0 :
15441+ (word32)XSTRLEN(ssl->buffers.domainName.buffer))) == 0)
15442+ {
1541015443 WOLFSSL_MSG("DomainName match on common name failed");
1541115444 if (CheckForAltNames(args->dCert,
1541215445 (char*)ssl->buffers.domainName.buffer,
15446+ (ssl->buffers.domainName.buffer == NULL ? 0 :
15447+ (word32)XSTRLEN(ssl->buffers.domainName.buffer)),
1541315448 NULL) != 1) {
1541415449 WOLFSSL_MSG(
1541515450 "DomainName match on alt names failed too");
0 commit comments