Add RFC8773(bis) cert_with_extern_psk support#10085
Add RFC8773(bis) cert_with_extern_psk support#10085Frauschi wants to merge 1 commit intowolfSSL:masterfrom
Conversation
wolfSSL-Fenrir-bot
left a comment
There was a problem hiding this comment.
Fenrir Automated Review — PR #10085
Scan targets checked: src, src-bugs, src-compliance
Findings: 3
Medium (2)
DoPreSharedKeys returns fatal error instead of skipping session ticket identity when cert_with_extern_psk is offered
File: src/tls13.c:6193-6198
Function: DoPreSharedKeys
Category: Logic errors
When the server processes PSK identities in DoPreSharedKeys, it iterates through all client-offered identities trying each as a session ticket first, then as an external PSK via FindPsk. The new code returns PSK_KEY_ERROR immediately when a session ticket identity matches and certWithExternOffered is true. This terminates the entire function, preventing the server from trying subsequent identities in the list. A legitimate client could offer a session ticket identity (for resumption with servers that don't support cert_with_extern_psk) followed by an external PSK identity (for cert_with_extern_psk). The fatal return prevents the server from ever reaching the external PSK identity, causing a handshake failure that could be avoided by simply skipping the ticket identity.
#if defined(WOLFSSL_CERT_WITH_EXTERN_PSK) && defined(HAVE_SESSION_TICKET)
if (certWithExternOffered) {
WOLFSSL_ERROR_VERBOSE(PSK_KEY_ERROR);
return PSK_KEY_ERROR;
}
#endifRecommendation: Replace return PSK_KEY_ERROR with continue so that the server skips the session ticket identity and proceeds to try the next identity in the list, which may be a valid external PSK identity suitable for cert_with_extern_psk.
DoPreSharedKeys fatally rejects session ticket match when cert_with_extern_psk is offered, violating RFC 8773bis fallback behavior
File: src/tls13.c:6196-6200
Function: DoPreSharedKeys
Category: Session resumption violations
When the client offers the tls_cert_with_extern_psk extension and also includes a session ticket identity in pre_shared_key, the server returns PSK_KEY_ERROR if the session ticket successfully decrypts. This is a hard return, not a continue, so it aborts the entire PSK identity search loop — even if a valid external PSK identity appears later in the list.
RFC 8773bis Section 3 explicitly permits the server to select a resumption PSK when the client offers cert_with_extern_psk: "If the client includes the 'tls_cert_with_extern_psk' extension in the ClientHello, and the server selects a resumption PSK, the server MUST NOT echo the extension." The spec allows normal ticket resumption as a fallback — the server simply omits the extension from ServerHello.
The current code prevents two valid scenarios:
- A client offering both a session ticket and an external PSK identity (ticket listed first) — the server should skip the ticket and try the external PSK, or fall back to normal resumption.
- A client offering
cert_with_extern_pskwith only a session ticket that matches — the server should fall back to normal ticket resumption without echoing the extension.
#if defined(WOLFSSL_CERT_WITH_EXTERN_PSK) && defined(HAVE_SESSION_TICKET)
if (certWithExternOffered) {
WOLFSSL_ERROR_VERBOSE(PSK_KEY_ERROR);
return PSK_KEY_ERROR;
}
#endif
/* SERVER: using secret in session ticket for peer auth. */
ssl->options.peerAuthGood = 1;Recommendation: Replace return PSK_KEY_ERROR with continue so the server skips the session ticket identity and continues searching for an external PSK identity. If no external PSK matches after the loop completes, the server can fall back to normal behavior (either retry with the ticket without echoing cert_with_extern_psk, or proceed without PSK).
Low (1)
TLSX_Cert_With_Extern_Psk_Parse overwrites actual error code with MEMORY_E
File: src/tls.c:12389-12390
Function: TLSX_Cert_With_Extern_Psk_Parse
Category: Incorrect error handling
In the client_hello handler of TLSX_Cert_With_Extern_Psk_Parse, the return value of TLSX_Cert_With_Extern_Psk_Use(ssl) is checked for non-zero but then hardcoded MEMORY_E is returned instead of the actual error code. TLSX_Cert_With_Extern_Psk_Use internally calls TLSX_Push, which may return various error codes. The actual error is lost and replaced with MEMORY_E, making debugging harder and potentially reporting the wrong error to the caller.
if (msgType == client_hello) {
if (!ssl->options.certWithExternPsk)
return 0;
if (TLSX_Cert_With_Extern_Psk_Use(ssl) != 0)
return MEMORY_E;Recommendation: Propagate the actual error code: int ret = TLSX_Cert_With_Extern_Psk_Use(ssl); if (ret != 0) return ret;
This review was generated automatically by Fenrir. Findings are non-blocking.
2ee0302 to
7a7ba81
Compare
|
@wolfSSL-Fenrir-bot Findings 1 and 2 identify a real bug, RFC 8773bis §5.1 (draft-ietf-tls-8773bis-13) is unambiguous: ▎ "All of the listed PSKs MUST be external PSKs. If a resumption PSK is There is no "skip and continue" option — the presence of any resumption The actual bug was that the check fired too late: only after The fix moves the certWithExternOffered abort to fire immediately upon |
wolfSSL-Fenrir-bot
left a comment
There was a problem hiding this comment.
Fenrir Automated Review — PR #10085
Scan targets checked: src, src-bugs, src-compliance
No new issues found in the changed files. ✅
|
Jenkins retest this please |
Implement RFC8773bis (draft-ietf-tls-8773bis-13) cert_with_extern_psk for TLS 1.3, including protocol checks and API support. Includes unit tests for API and handshake behavior as well as tests in the testsuite using extended examples.
7a7ba81 to
9976db0
Compare
Implement RFC 8773(bis) cert_with_extern_psk for TLS 1.3.
Includes unit tests for API and handshake behavior as well as tests in the testsuite using extended examples.