Skip to content

Commit 9fa5db5

Browse files
Merge pull request #10509 from kareem-wolfssl/zd21863_5
Disallow matching URI type in CheckForAltNames. NULL *response on error in wolfSSL_d2i_OCSP_RESPONSE.
2 parents 1f32365 + 4472980 commit 9fa5db5

6 files changed

Lines changed: 110 additions & 18 deletions

File tree

src/internal.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13696,6 +13696,16 @@ int CheckForAltNames(DecodedCert* dCert, const char* domain, word32 domainLen,
1369613696
continue;
1369713697
}
1369813698

13699+
/* RFC 9525 Sec. 6.3: a DNS-ID reference identifier is matched only
13700+
* against dNSName SAN entries, never uniformResourceIdentifier
13701+
* (even when the URI value resembles a ostname). URI-ID matching
13702+
* requires scheme and host parsing (RFC 9525 Sec. 6.5, Sec. 7.2). */
13703+
if (!isIP && altName->type == ASN_URI_TYPE) {
13704+
WOLFSSL_MSG("\tAltName is uniformResourceIdentifier, "
13705+
"skipping for DNS hostname");
13706+
continue;
13707+
}
13708+
1369913709
if (MatchDomainName(buf, (int)len, domain, domainLen, flags)) {
1370013710
match = 1;
1370113711
if (checkCN != NULL) {

src/ocsp.c

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1270,7 +1270,7 @@ OcspResponse* wolfSSL_d2i_OCSP_RESPONSE(OcspResponse** response,
12701270
int length = 0;
12711271
int ret;
12721272

1273-
if (data == NULL)
1273+
if (data == NULL || *data == NULL || len <= 0)
12741274
return NULL;
12751275

12761276
if (response != NULL)
@@ -1283,39 +1283,35 @@ OcspResponse* wolfSSL_d2i_OCSP_RESPONSE(OcspResponse** response,
12831283
XMEMSET(resp, 0, sizeof(OcspResponse));
12841284
}
12851285

1286+
if (resp->source != NULL)
1287+
XFREE(resp->source, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12861288
resp->source = (byte*)XMALLOC((size_t)len, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1287-
if (resp->source == NULL) {
1288-
XFREE(resp, NULL, DYNAMIC_TYPE_OCSP_REQUEST);
1289-
return NULL;
1289+
if (resp->source == NULL)
1290+
goto error;
1291+
1292+
if (resp->single != NULL) {
1293+
FreeOcspEntry(resp->single, NULL);
1294+
XFREE(resp->single, NULL, DYNAMIC_TYPE_OCSP_ENTRY);
12901295
}
12911296
resp->single = (OcspEntry*)XMALLOC(sizeof(OcspEntry), NULL,
12921297
DYNAMIC_TYPE_OCSP_ENTRY);
1293-
if (resp->single == NULL) {
1294-
XFREE(resp->source, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1295-
XFREE(resp, NULL, DYNAMIC_TYPE_OCSP_REQUEST);
1296-
return NULL;
1297-
}
1298+
if (resp->single == NULL)
1299+
goto error;
12981300
XMEMSET(resp->single, 0, sizeof(OcspEntry));
12991301
resp->single->status = (CertStatus*)XMALLOC(sizeof(CertStatus), NULL,
13001302
DYNAMIC_TYPE_OCSP_STATUS);
1303+
if (resp->single->status == NULL)
1304+
goto error;
13011305
resp->single->ownStatus = 1;
1302-
if (resp->single->status == NULL) {
1303-
XFREE(resp->source, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1304-
XFREE(resp->single, NULL, DYNAMIC_TYPE_OCSP_ENTRY);
1305-
XFREE(resp, NULL, DYNAMIC_TYPE_OCSP_REQUEST);
1306-
return NULL;
1307-
}
13081306
XMEMSET(resp->single->status, 0, sizeof(CertStatus));
1309-
13101307
XMEMCPY(resp->source, *data, (size_t)len);
13111308
resp->maxIdx = (word32)len;
13121309

13131310
ret = OcspResponseDecode(resp, NULL, NULL, 1, 1);
13141311
if (ret != 0 && ret != WC_NO_ERR_TRACE(ASN_OCSP_CONFIRM_E)) {
13151312
/* for just converting from a DER to an internal structure the CA may
13161313
* not yet be known to this function for signature verification */
1317-
wolfSSL_OCSP_RESPONSE_free(resp);
1318-
return NULL;
1314+
goto error;
13191315
}
13201316

13211317
if (GetSequence(*data, &idx, &length, (word32)len) >= 0)
@@ -1325,6 +1321,12 @@ OcspResponse* wolfSSL_d2i_OCSP_RESPONSE(OcspResponse** response,
13251321
*response = resp;
13261322

13271323
return resp;
1324+
1325+
error:
1326+
wolfSSL_OCSP_RESPONSE_free(resp);
1327+
if (response != NULL && *response == resp)
1328+
*response = NULL;
1329+
return NULL;
13281330
}
13291331

13301332
int wolfSSL_i2d_OCSP_RESPONSE(OcspResponse* response,

tests/api/test_certman.c

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2109,6 +2109,70 @@ int test_wolfSSL_X509_check_host_IP_only_SAN_CN_fallback(void)
21092109
return EXPECT_RESULT();
21102110
}
21112111

2112+
int test_wolfSSL_X509_check_host_URI_SAN_not_DNS_match(void)
2113+
{
2114+
EXPECT_DECLS;
2115+
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_RSA) && \
2116+
defined(OPENSSL_EXTRA) && defined(WOLFSSL_CERT_GEN) && \
2117+
defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_ALT_NAMES) && \
2118+
!defined(NO_SHA256)
2119+
/* RFC 6125 Sec. 6.4 / RFC 9525 Sec. 6.3: DNS-ID reference identifiers
2120+
* must be matched only against dNSName SANs, not uniformResourceIdentifier.
2121+
* wolfSSL_X509_add_altname() is used to attach a bare-hostname URI SAN
2122+
* (the misissue shape that can reach altNames when certificate parsing is
2123+
* built without strict URI checks). URI SAN presence still suppresses CN
2124+
* fallback per RFC 6125 Sec. 6.4.4. */
2125+
WOLFSSL_EVP_PKEY *priv = NULL;
2126+
WOLFSSL_X509_NAME* name = NULL;
2127+
const char* server_cert = "./certs/test/server-goodcn.pem";
2128+
const char hostName[] = "cnhost.local";
2129+
const char uriSan[] = "cnhost.local";
2130+
byte *pt;
2131+
WOLFSSL_X509 *leafUri = NULL;
2132+
WOLFSSL_X509 *leafUriDns = NULL;
2133+
2134+
pt = (byte*)server_key_der_2048;
2135+
ExpectNotNull(priv = wolfSSL_d2i_PrivateKey(EVP_PKEY_RSA, NULL,
2136+
(const unsigned char**)&pt, sizeof_server_key_der_2048));
2137+
2138+
ExpectNotNull(leafUri = wolfSSL_X509_load_certificate_file(server_cert,
2139+
WOLFSSL_FILETYPE_PEM));
2140+
ExpectNotNull(name = X509_NAME_new());
2141+
ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "commonName", MBSTRING_UTF8,
2142+
(byte*)hostName, (int)XSTRLEN(hostName), -1, 0), SSL_SUCCESS);
2143+
ExpectIntEQ(wolfSSL_X509_set_subject_name(leafUri, name), WOLFSSL_SUCCESS);
2144+
X509_NAME_free(name);
2145+
name = NULL;
2146+
ExpectIntEQ(wolfSSL_X509_add_altname(leafUri, uriSan, ASN_URI_TYPE),
2147+
WOLFSSL_SUCCESS);
2148+
ExpectIntGT(wolfSSL_X509_sign(leafUri, priv, EVP_sha256()), 0);
2149+
ExpectIntEQ(wolfSSL_X509_check_host(leafUri, hostName, XSTRLEN(hostName),
2150+
0, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
2151+
2152+
ExpectNotNull(leafUriDns = wolfSSL_X509_load_certificate_file(server_cert,
2153+
WOLFSSL_FILETYPE_PEM));
2154+
ExpectNotNull(name = X509_NAME_new());
2155+
ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "commonName", MBSTRING_UTF8,
2156+
(byte*)hostName, (int)XSTRLEN(hostName), -1, 0), SSL_SUCCESS);
2157+
ExpectIntEQ(wolfSSL_X509_set_subject_name(leafUriDns, name),
2158+
WOLFSSL_SUCCESS);
2159+
X509_NAME_free(name);
2160+
name = NULL;
2161+
ExpectIntEQ(wolfSSL_X509_add_altname(leafUriDns, uriSan, ASN_URI_TYPE),
2162+
WOLFSSL_SUCCESS);
2163+
ExpectIntEQ(wolfSSL_X509_add_altname(leafUriDns, hostName, ASN_DNS_TYPE),
2164+
WOLFSSL_SUCCESS);
2165+
ExpectIntGT(wolfSSL_X509_sign(leafUriDns, priv, EVP_sha256()), 0);
2166+
ExpectIntEQ(wolfSSL_X509_check_host(leafUriDns, hostName,
2167+
XSTRLEN(hostName), 0, NULL), WOLFSSL_SUCCESS);
2168+
2169+
wolfSSL_X509_free(leafUri);
2170+
wolfSSL_X509_free(leafUriDns);
2171+
wolfSSL_EVP_PKEY_free(priv);
2172+
#endif
2173+
return EXPECT_RESULT();
2174+
}
2175+
21122176
int test_wolfSSL_CertManagerCRL(void)
21132177
{
21142178
EXPECT_DECLS;

tests/api/test_certman.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ int test_wolfSSL_CertManagerNameConstraint_IP_SAN(void);
4040
int test_wolfSSL_CertManagerNameConstraint_RID_SAN(void);
4141
int test_wolfSSL_X509_get_ext_d2i_RID_SAN(void);
4242
int test_wolfSSL_X509_check_host_IP_only_SAN_CN_fallback(void);
43+
int test_wolfSSL_X509_check_host_URI_SAN_not_DNS_match(void);
4344
int test_wolfSSL_CertManagerCRL(void);
4445
int test_wolfSSL_CRL_reason_extensions_cleanup(void);
4546
int test_wolfSSL_CRL_static_revoked_list(void);
@@ -70,6 +71,8 @@ int test_wolfSSL_X509_V_ERR_strings(void);
7071
TEST_DECL_GROUP("certman", test_wolfSSL_X509_get_ext_d2i_RID_SAN), \
7172
TEST_DECL_GROUP("certman", \
7273
test_wolfSSL_X509_check_host_IP_only_SAN_CN_fallback), \
74+
TEST_DECL_GROUP("certman", \
75+
test_wolfSSL_X509_check_host_URI_SAN_not_DNS_match), \
7376
TEST_DECL_GROUP("certman", test_wolfSSL_CertManagerCRL), \
7477
TEST_DECL_GROUP("certman", test_wolfSSL_CRL_reason_extensions_cleanup), \
7578
TEST_DECL_GROUP("certman", test_wolfSSL_CRL_static_revoked_list), \

tests/api/test_ocsp.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,15 @@ int test_ocsp_basic_verify(void)
247247
ExpectNull(
248248
response = wolfSSL_d2i_OCSP_RESPONSE(NULL, &ptr, sizeof(resp_bad)));
249249

250+
/* reuse failure must clear caller pointer */
251+
ptr = (const unsigned char*)resp;
252+
ExpectNotNull(
253+
response = wolfSSL_d2i_OCSP_RESPONSE(&response, &ptr, sizeof(resp)));
254+
ptr = (const unsigned char*)resp_bad;
255+
ExpectNull(
256+
wolfSSL_d2i_OCSP_RESPONSE(&response, &ptr, sizeof(resp_bad)));
257+
ExpectNull(response);
258+
250259
ptr = (const unsigned char*)resp;
251260
ExpectNotNull(
252261
response = wolfSSL_d2i_OCSP_RESPONSE(NULL, &ptr, sizeof(resp)));

wolfcrypt/src/asn.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18734,6 +18734,10 @@ static int DecodeGeneralName(const byte* input, word32* inOutIdx, byte tag,
1873418734
* - CheckForAltNames (TLS hostname matching): skips ASN_RID_TYPE
1873518735
* unconditionally and excludes them from *checkCN, so a cert
1873618736
* with only registeredID SANs still falls back to CN.
18737+
* - CheckForAltNames (TLS hostname matching): skips ASN_URI_TYPE
18738+
* for DNS hostname checks (RFC 9525 Sec. 6.3) but URI SAN presence
18739+
* still suppresses CN fallback because URI-ID is a distinct presented
18740+
* identifier.
1873718741
* - DNS_to_GENERAL_NAME (used by wolfSSL_X509_get_ext) and the
1873818742
* ALT_NAMES_OID arm of wolfSSL_X509_get_ext_d2i: build a proper
1873918743
* ASN1_OBJECT in d.registeredID from raw OID bytes regardless

0 commit comments

Comments
 (0)