Add DTLS secondary cookie secret for app-driven rotation#10634
Open
julek-wolfssl wants to merge 1 commit into
Open
Add DTLS secondary cookie secret for app-driven rotation#10634julek-wolfssl wants to merge 1 commit into
julek-wolfssl wants to merge 1 commit into
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR adds “verify-only” secondary cookie secrets for DTLS 1.2 (HelloVerifyRequest) and DTLS 1.3 (HelloRetryRequest) so applications can rotate the primary cookie secret on stateless servers without breaking in-flight handshakes.
Changes:
- Introduces two new public APIs to configure a secondary cookie secret used only for verification (never for cookie issuance).
- Updates DTLS 1.2 and DTLS 1.3 cookie verification paths to try the primary secret first, then the secondary on verification failure.
- Adds API-level tests covering rotation overlap, drop/clear/replacement behavior, and argument/side validation.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
wolfssl/ssl.h |
Adds public API declarations for DTLS 1.2 and DTLS 1.3 secondary cookie-secret setters. |
wolfssl/internal.h |
Adds per-SSL secondary secret buffers for DTLS 1.2 cookies and DTLS 1.3 HRR cookies. |
src/tls13.c |
Factors cookie MAC verification and adds secondary-secret fallback for DTLS 1.3 HRR cookie verification; adds wolfSSL_set_hrr_cookie_secret_secondary(). |
src/dtls.c |
Refactors DTLS 1.2 cookie generation to accept an explicit secret; adds secondary-secret fallback during cookie verification. |
src/ssl.c |
Adds wolfSSL_DTLS_SetCookieSecretSecondary() API implementation and manages secondary secret lifetime. |
src/internal.c |
Frees/zeroes the new secondary secret buffers during SSL teardown. |
tests/api/test_dtls.h |
Registers new DTLS cookie secondary-secret tests. |
tests/api/test_dtls.c |
Adds DTLS 1.2 + DTLS 1.3 memio tests for secondary-secret behavior and API validation. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Add verify-only secondary cookie secrets for both DTLS 1.2 (HelloVerifyRequest) and DTLS 1.3 (HelloRetryRequest). A secondary secret is used only during cookie verification, and only if the primary secret fails to verify the cookie; it is never used to issue cookies. This lets an application rotate the cookie secret on a stateless DTLS server without rejecting clients that received a cookie under the previous secret: after rotating the primary, the application installs the old secret as the secondary so in-flight cookies still verify for an overlap window (RFC 9147 Section 5.1). Two APIs rather than one. The 1.2 and 1.3 cookie mechanisms keep separate secrets and separate verify routines, set their primary secret through different APIs (wolfSSL_DTLS_SetCookieSecret for 1.2, wolfSSL_send_hrr_cookie for 1.3), and live under different build guards (a DTLS-1.2-only build has none of the TLS 1.3 / HRR machinery). So each version gets its own sibling API: - wolfSSL_set_hrr_cookie_secret_secondary() - DTLS 1.3. Per-connection and DTLS-only; returns BAD_FUNC_ARG for a non-DTLS or non-TLS-1.3 object, since TLS 1.3 over a reliable transport does not verify cookies statelessly across the HelloRetryRequest exchange. - wolfSSL_DTLS_SetCookieSecretSecondary() - DTLS 1.2, the counterpart of the above. NULL/0 clears it. A server handling both versions sets both secondary secrets. Details: - New per-SSL buffers tls13CookieSecretSecondary and dtlsCookieSecretSecondary, freed on SSL teardown (the 1.3 buffer is also freed in wolfSSL_disable_hrr_cookie()). - TlsCheckCookie() factors its HMAC compute/compare into TlsCheckCookieMac() and tries the primary secret, then the secondary on mismatch. CreateDtls12Cookie() now takes the secret as parameters; CheckDtlsCookie() computes with the primary and retries with the secondary on mismatch. Issuance (CreateCookieExt, SendHelloVerifyRequest) always uses the primary. Tests cover, for both versions: a handshake where the cookie is accepted via the secondary after a rotation; a negative case where the signing secret has been rotated out of both slots; secondary clear behavior; primary still wins on the fast path; replacing the secondary activates the new value; secondary equal to primary is harmless; and issuance uses the primary, not the verify-only secondary. The 1.3 API additionally has NULL/side/version argument-validation coverage.
d19a0d3 to
c218d94
Compare
|
retest this please |
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Add verify-only secondary cookie secrets for both DTLS 1.2 (HelloVerifyRequest) and DTLS 1.3 (HelloRetryRequest). A secondary secret is used only during cookie verification, and only if the primary secret fails to verify the cookie; it is never used to issue cookies.
This lets an application rotate the cookie secret on a stateless DTLS server without rejecting clients that received a cookie under the previous secret: after rotating the primary, the application installs the old secret as the secondary so in-flight cookies still verify for an overlap window (RFC 9147 Section 5.1).
Why two APIs
The DTLS 1.2 and 1.3 cookie mechanisms keep separate secrets and separate verify routines, set their primary secret through different APIs (
wolfSSL_DTLS_SetCookieSecretfor 1.2,wolfSSL_send_hrr_cookiefor 1.3), and live under different build guards (a DTLS-1.2-only build has none of the TLS 1.3 / HRR machinery). So each version gets its own sibling API:wolfSSL_set_hrr_cookie_secret_secondary()— DTLS 1.3. Per-connection and DTLS-only; returnsBAD_FUNC_ARGfor a non-DTLS or non-TLS-1.3 object, since TLS 1.3 over a reliable transport does not verify cookies statelessly across the HelloRetryRequest exchange.wolfSSL_DTLS_SetCookieSecretSecondary()— DTLS 1.2, the counterpart of the above.NULL/0 clears it. A server handling both versions sets both secondary secrets.Implementation
tls13CookieSecretSecondaryanddtlsCookieSecretSecondary, freed on SSL teardown (the 1.3 buffer is also freed inwolfSSL_disable_hrr_cookie()).TlsCheckCookie()factors its HMAC compute/compare intoTlsCheckCookieMac()and tries the primary secret, then the secondary on mismatch.CreateDtls12Cookie()now takes the secret as parameters;CheckDtlsCookie()computes with the primary and retries with the secondary on mismatch.CreateCookieExt,SendHelloVerifyRequest) always uses the primary.Testing
Tests cover, for both versions: a handshake where the cookie is accepted via the secondary after a rotation; a negative case where the signing secret has been rotated out of both slots; secondary clear behavior; primary still wins on the fast path; replacing the secondary activates the new value; secondary equal to primary is harmless; and issuance uses the primary, not the verify-only secondary. The 1.3 API additionally has NULL/side/version argument-validation coverage.