Improve domain and IP address matching in certificate verification

- Distinguish between domain and IP address checks.
- Update curl action to test with httpd server
This commit is contained in:
Juliusz Sosinowicz
2025-11-04 17:01:14 +01:00
parent 5922b5def5
commit f95cb4e9bf
4 changed files with 26 additions and 18 deletions

View File

@@ -52,7 +52,7 @@ jobs:
- name: Install test dependencies
run: |
sudo apt-get update
sudo apt-get install nghttp2 libpsl5 libpsl-dev python3-impacket
sudo apt-get install nghttp2 libpsl5 libpsl-dev python3-impacket apache2 apache2-dev
- name: Download lib
uses: actions/download-artifact@v4
@@ -68,9 +68,9 @@ jobs:
repository: curl/curl
path: curl
ref: ${{ matrix.curl_ref }}
configure: --with-wolfssl=$GITHUB_WORKSPACE/build-dir
configure: --with-wolfssl=$GITHUB_WORKSPACE/build-dir --with-test-httpd=yes
check: false
- name: Test curl
working-directory: curl
run: make -j $(nproc) test-ci
run: make -j $(nproc) test-nonflaky

View File

@@ -13103,12 +13103,14 @@ int MatchDomainName(const char* pattern, int patternLen, const char* str,
* domain Domain name to compare against.
* domainLen Length of the domain name.
* checkCN Whether to check the common name.
* flags Matching flags.
* isIP Whether the domain is an IP address.
* returns 1 : match was found.
* 0 : no match found.
* -1 : No matches and wild pattern match failed.
*/
int CheckForAltNames(DecodedCert* dCert, const char* domain, word32 domainLen,
int* checkCN, unsigned int flags)
int* checkCN, unsigned int flags, byte isIP)
{
int match = 0;
DNS_entry* altName = NULL;
@@ -13117,14 +13119,13 @@ int CheckForAltNames(DecodedCert* dCert, const char* domain, word32 domainLen,
WOLFSSL_MSG("Checking AltNames");
if (dCert)
if (dCert != NULL)
altName = dCert->altNames;
if (checkCN != NULL) {
if (checkCN != NULL)
*checkCN = (altName == NULL) ? 1 : 0;
}
while (altName) {
for (; altName != NULL; altName = altName->next) {
WOLFSSL_MSG("\tindividual AltName check");
#ifdef WOLFSSL_IP_ALT_NAME
@@ -13139,6 +13140,12 @@ int CheckForAltNames(DecodedCert* dCert, const char* domain, word32 domainLen,
len = (word32)altName->len;
}
if ((isIP && (altName->type != ASN_IP_TYPE)) ||
(!isIP && (altName->type == ASN_IP_TYPE))) {
WOLFSSL_MSG("\tAltName type mismatch, continue");
continue;
}
if (MatchDomainName(buf, (int)len, domain, domainLen, flags)) {
match = 1;
if (checkCN != NULL) {
@@ -13152,8 +13159,6 @@ int CheckForAltNames(DecodedCert* dCert, const char* domain, word32 domainLen,
match = -1;
WOLFSSL_MSG("\twildcard match failed");
}
altName = altName->next;
}
return match;
@@ -13166,16 +13171,18 @@ int CheckForAltNames(DecodedCert* dCert, const char* domain, word32 domainLen,
* dcert Decoded certificate.
* domainName The domain name.
* domainNameLen The length of the domain name.
* flags Matching flags.
* isIP Whether the domain name is an IP address.
* returns DOMAIN_NAME_MISMATCH when no match found and 0 on success.
*/
int CheckHostName(DecodedCert* dCert, const char *domainName,
size_t domainNameLen, unsigned int flags)
size_t domainNameLen, unsigned int flags, byte isIP)
{
int checkCN;
int ret = WC_NO_ERR_TRACE(DOMAIN_NAME_MISMATCH);
if (CheckForAltNames(dCert, domainName, (word32)domainNameLen,
&checkCN, flags) != 1) {
&checkCN, flags, isIP) != 1) {
ret = DOMAIN_NAME_MISMATCH;
WOLFSSL_MSG("DomainName match on alt names failed");
}
@@ -13203,7 +13210,7 @@ int CheckIPAddr(DecodedCert* dCert, const char* ipasc)
{
WOLFSSL_MSG("Checking IPAddr");
return CheckHostName(dCert, ipasc, (size_t)XSTRLEN(ipasc), 0);
return CheckHostName(dCert, ipasc, (size_t)XSTRLEN(ipasc), 0, 1);
}
@@ -14413,7 +14420,7 @@ int DoVerifyCallback(WOLFSSL_CERT_MANAGER* cm, WOLFSSL* ssl, int cert_err,
/* If altNames names is present, then subject common name is ignored */
if (args->dCert->altNames != NULL) {
if (CheckForAltNames(args->dCert, ssl->param->hostName,
(word32)XSTRLEN(ssl->param->hostName), NULL, 0) != 1) {
(word32)XSTRLEN(ssl->param->hostName), NULL, 0, 0) != 1) {
if (cert_err == 0) {
ret = DOMAIN_NAME_MISMATCH;
WOLFSSL_ERROR_VERBOSE(ret);
@@ -16452,7 +16459,7 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
(ssl->buffers.domainName.buffer == NULL ? 0 :
(word32)XSTRLEN(
(const char *)ssl->buffers.domainName.buffer)),
NULL, 0) != 1) {
NULL, 0, 0) != 1) {
WOLFSSL_MSG("DomainName match on alt names failed");
/* try to get peer key still */
ret = DOMAIN_NAME_MISMATCH;

View File

@@ -14190,7 +14190,7 @@ int wolfSSL_X509_check_host(WOLFSSL_X509 *x, const char *chk, size_t chklen,
chklen--;
}
ret = CheckHostName(dCert, (char *)chk, chklen, flags);
ret = CheckHostName(dCert, (char *)chk, chklen, flags, 0);
out:

View File

@@ -2210,7 +2210,7 @@ WOLFSSL_LOCAL int MatchDomainName(const char* pattern, int len,
#if !defined(NO_CERTS) && !defined(NO_ASN)
WOLFSSL_LOCAL int CheckForAltNames(DecodedCert* dCert, const char* domain,
word32 domainLen, int* checkCN,
unsigned int flags);
unsigned int flags, byte isIP);
WOLFSSL_LOCAL int CheckIPAddr(DecodedCert* dCert, const char* ipasc);
WOLFSSL_LOCAL void CopyDecodedName(WOLFSSL_X509_NAME* name, DecodedCert* dCert, int nameType);
#endif
@@ -6388,7 +6388,8 @@ WOLFSSL_TEST_VIS void wolfSSL_ResourceFree(WOLFSSL* ssl); /* Micrium uses */
#ifndef NO_ASN
WOLFSSL_LOCAL int CheckHostName(DecodedCert* dCert, const char *domainName,
size_t domainNameLen, unsigned int flags);
size_t domainNameLen, unsigned int flags,
byte isIP);
#endif
#endif