@@ -8773,6 +8773,10 @@ void wolfSSL_ResourceFree(WOLFSSL* ssl)
87738773 FreeEchConfigs(ssl->echConfigs, ssl->heap);
87748774 ssl->echConfigs = NULL;
87758775 }
8776+ if (ssl->echRetryConfigs != NULL) {
8777+ FreeEchConfigs(ssl->echRetryConfigs, ssl->heap);
8778+ ssl->echRetryConfigs = NULL;
8779+ }
87768780#endif /* HAVE_ECH */
87778781#endif /* WOLFSSL_TLS13 */
87788782#ifdef WOLFSSL_HAVE_TLS_UNIQUE
@@ -15744,6 +15748,8 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1574415748 byte* subjectHash = NULL;
1574515749 int alreadySigner = 0;
1574615750
15751+ char* domainName = NULL;
15752+
1574715753#if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
1574815754 int addToPendingCAs = 0;
1574915755#endif
@@ -16932,17 +16938,34 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1693216938 }
1693316939 #endif
1693416940
16935- if (!ssl->options.verifyNone && ssl->buffers.domainName.buffer) {
16941+ domainName = (char*)ssl->buffers.domainName.buffer;
16942+ #if !defined(NO_WOLFSSL_CLIENT) && defined(HAVE_ECH)
16943+ /* RFC 9849 s6.1.7: ECH offered but rejected by the server...
16944+ * verify cert is valid for ECHConfig.public_name */
16945+ if (ssl->options.side == WOLFSSL_CLIENT_END &&
16946+ ssl->echConfigs != NULL &&
16947+ !ssl->options.echAccepted) {
16948+ TLSX* echX = TLSX_Find(ssl->extensions, TLSX_ECH);
16949+ if (echX != NULL && echX->data != NULL) {
16950+ WOLFSSL_ECH* ech = (WOLFSSL_ECH*)echX->data;
16951+ if (ech->echConfig != NULL &&
16952+ ech->echConfig->publicName != NULL) {
16953+ domainName = ech->echConfig->publicName;
16954+ }
16955+ }
16956+ }
16957+ #endif
16958+
16959+ if (!ssl->options.verifyNone && domainName) {
1693616960 #ifndef WOLFSSL_ALLOW_NO_CN_IN_SAN
1693716961 /* Per RFC 5280 section 4.2.1.6, "Whenever such identities
1693816962 * are to be bound into a certificate, the subject
1693916963 * alternative name extension MUST be used." */
1694016964 if (args->dCert->altNames) {
16941- if (CheckForAltNames(args->dCert,
16942- (char*)ssl->buffers.domainName.buffer,
16943- (ssl->buffers.domainName.buffer == NULL ? 0 :
16944- (word32)XSTRLEN(
16945- (const char *)ssl->buffers.domainName.buffer)),
16965+ if (CheckForAltNames(
16966+ args->dCert,
16967+ domainName,
16968+ (word32)XSTRLEN((const char *)domainName),
1694616969 NULL, 0, 0) != 1) {
1694716970 WOLFSSL_MSG("DomainName match on alt names failed");
1694816971 /* try to get peer key still */
@@ -16955,11 +16978,9 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1695516978 if (MatchDomainName(
1695616979 args->dCert->subjectCN,
1695716980 args->dCert->subjectCNLen,
16958- (char*)ssl->buffers.domainName.buffer,
16959- (ssl->buffers.domainName.buffer == NULL ? 0 :
16960- (word32)XSTRLEN(
16961- (const char *)ssl->buffers.domainName.buffer)
16962- ), 0) == 0)
16981+ domainName,
16982+ (word32)XSTRLEN((const char *)domainName),
16983+ 0) == 0)
1696316984 #endif
1696416985 {
1696516986 WOLFSSL_MSG("DomainName match failed");
@@ -16970,18 +16991,19 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1697016991 #else /* WOLFSSL_ALL_NO_CN_IN_SAN */
1697116992 /* Old behavior. */
1697216993 #ifndef WOLFSSL_HOSTNAME_VERIFY_ALT_NAME_ONLY
16973- if (MatchDomainName(args->dCert->subjectCN,
16994+ if (MatchDomainName(
16995+ args->dCert->subjectCN,
1697416996 args->dCert->subjectCNLen,
16975- (char*)ssl->buffers. domainName.buffer ,
16976- (ssl->buffers.domainName.buffer == NULL ? 0 :
16977- (word32)XSTRLEN(ssl->buffers.domainName.buffer)), 0) == 0)
16997+ domainName,
16998+ (word32)XSTRLEN((const char *)domainName),
16999+ 0) == 0)
1697817000 #endif
1697917001 {
16980- if (CheckForAltNames(args->dCert,
16981- (char*)ssl->buffers.domainName.buffer ,
16982- (ssl->buffers. domainName.buffer == NULL ? 0 :
16983- (word32)XSTRLEN(ssl->buffers.domainName.buffer) ),
16984- NULL, 0, 0) != 1) {
17002+ if (CheckForAltNames(
17003+ args->dCert ,
17004+ domainName,
17005+ (word32)XSTRLEN((const char *)domainName ),
17006+ NULL, 0, 0) != 1) {
1698517007 WOLFSSL_MSG("DomainName match failed");
1698617008 /* try to get peer key still */
1698717009 ret = DOMAIN_NAME_MISMATCH;
@@ -22210,6 +22232,13 @@ const char* AlertTypeToString(int type)
2221022232 return no_application_protocol_str;
2221122233 }
2221222234
22235+ case ech_required:
22236+ {
22237+ static const char ech_required_str[] =
22238+ "ech_required";
22239+ return ech_required_str;
22240+ }
22241+
2221322242 default:
2221422243 WOLFSSL_MSG("Unknown Alert");
2221522244 return NULL;
@@ -27828,6 +27857,9 @@ const char* wolfSSL_ERR_reason_error_string(unsigned long e)
2782827857
2782927858 case SESSION_TICKET_NONCE_OVERFLOW:
2783027859 return "Session ticket nonce overflow";
27860+
27861+ case ECH_REQUIRED_E:
27862+ return "ECH offered but rejected by server";
2783127863 }
2783227864
2783327865 return "unknown error number";
0 commit comments