mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-07-10 21:00:52 +02:00
Move ticket hint check to default callback
This commit is contained in:
@@ -41744,6 +41744,13 @@ static int DefTicketEncCb(WOLFSSL* ssl, byte key_name[WOLFSSL_TICKET_NAME_SZ],
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
/* The two-key rotation can only honor a hint below half the key lifetime.
|
||||
* Refuse to issue a ticket whose advertised lifetime it cannot cover. */
|
||||
if (enc && 2 * ctx->ticketHint >= WOLFSSL_TICKET_KEY_LIFETIME) {
|
||||
WOLFSSL_MSG("Ticket hint exceeds half the ticket key lifetime");
|
||||
return WOLFSSL_TICKET_RET_FATAL;
|
||||
}
|
||||
|
||||
/* Check we have setup the RNG, name and primary key. */
|
||||
if (keyCtx->expirary[0] == 0) {
|
||||
#ifndef SINGLE_THREADED
|
||||
|
||||
@@ -1055,8 +1055,6 @@ int wolfSSL_CTX_set_TicketEncCb(WOLFSSL_CTX* ctx, SessionTicketEncCb cb)
|
||||
*
|
||||
* @param [in] ctx SSL/TLS context object.
|
||||
* @param [in] hint Lifetime hint in seconds. No more than 604800 (7 days).
|
||||
* With the default ticket encryption callback, must also be
|
||||
* less than WOLFSSL_TICKET_KEY_LIFETIME / 2.
|
||||
* @return WOLFSSL_SUCCESS on success.
|
||||
* @return BAD_FUNC_ARG when ctx is NULL or hint is out of range.
|
||||
*/
|
||||
@@ -1070,15 +1068,6 @@ int wolfSSL_CTX_set_TicketHint(WOLFSSL_CTX* ctx, int hint)
|
||||
if (hint < 0 || hint > 604800)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
#ifdef WOLFSSL_TICKET_KEY_LIFETIME
|
||||
/* The default ticket encryption callback rotates two keys, each living
|
||||
* WOLFSSL_TICKET_KEY_LIFETIME seconds. Its staggered rotation can only
|
||||
* honor a hint below half that; a larger hint would leave no key available
|
||||
* for encryption. */
|
||||
if (hint >= WOLFSSL_TICKET_KEY_LIFETIME / 2)
|
||||
return BAD_FUNC_ARG;
|
||||
#endif
|
||||
|
||||
ctx->ticketHint = hint;
|
||||
|
||||
return WOLFSSL_SUCCESS;
|
||||
|
||||
+71
-11
@@ -188,24 +188,84 @@ int test_wolfSSL_CTX_set_TicketHint_ext(void)
|
||||
ExpectIntEQ(wolfSSL_CTX_set_TicketHint(ctx, 604801),
|
||||
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
||||
ExpectIntEQ(wolfSSL_CTX_set_TicketHint(ctx, 0), WOLFSSL_SUCCESS);
|
||||
#ifdef WOLFSSL_TICKET_KEY_LIFETIME
|
||||
/* The default ticket encryption callback can only honor a hint below half
|
||||
* the ticket key lifetime; larger values are rejected. */
|
||||
ExpectIntEQ(wolfSSL_CTX_set_TicketHint(ctx, WOLFSSL_TICKET_KEY_LIFETIME / 2),
|
||||
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
||||
ExpectIntEQ(wolfSSL_CTX_set_TicketHint(ctx,
|
||||
WOLFSSL_TICKET_KEY_LIFETIME / 2 - 1), WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(wolfSSL_CTX_set_TicketHint(ctx, 604800),
|
||||
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
||||
#else
|
||||
ExpectIntEQ(wolfSSL_CTX_set_TicketHint(ctx, 604800), WOLFSSL_SUCCESS);
|
||||
#endif
|
||||
|
||||
wolfSSL_CTX_free(ctx);
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_TLS13) \
|
||||
&& defined(HAVE_SESSION_TICKET) && !defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) \
|
||||
&& !defined(NO_WOLFSSL_SERVER)
|
||||
/* Trivial custom ticket encryption callback: it has no key-lifetime constraint,
|
||||
* so it must be able to issue a ticket for any hint. */
|
||||
static int test_TicketHint_custom_encCb(WOLFSSL* ssl,
|
||||
byte key_name[WOLFSSL_TICKET_NAME_SZ], byte iv[WOLFSSL_TICKET_IV_SZ],
|
||||
byte mac[WOLFSSL_TICKET_MAC_SZ], int enc, byte* ticket, int inLen,
|
||||
int* outLen, void* userCtx)
|
||||
{
|
||||
int i;
|
||||
(void)ssl;
|
||||
(void)userCtx;
|
||||
if (enc) {
|
||||
XMEMSET(key_name, 0x2A, WOLFSSL_TICKET_NAME_SZ);
|
||||
XMEMSET(iv, 0x2A, WOLFSSL_TICKET_IV_SZ);
|
||||
XMEMSET(mac, 0x2A, WOLFSSL_TICKET_MAC_SZ);
|
||||
}
|
||||
for (i = 0; i < inLen; i++)
|
||||
ticket[i] = (byte)(ticket[i] ^ 0xA5);
|
||||
*outLen = inLen;
|
||||
return WOLFSSL_TICKET_RET_OK;
|
||||
}
|
||||
|
||||
/* Drive one TLS 1.3 handshake, returning the handshake result. */
|
||||
static int test_TicketHint_handshake(int hint, int customCb)
|
||||
{
|
||||
struct test_memio_ctx test_ctx;
|
||||
WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL;
|
||||
WOLFSSL *ssl_c = NULL, *ssl_s = NULL;
|
||||
int ret;
|
||||
|
||||
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
|
||||
if (test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
|
||||
wolfTLSv1_3_client_method, wolfTLSv1_3_server_method) != 0) {
|
||||
ret = -1;
|
||||
goto done;
|
||||
}
|
||||
if (customCb)
|
||||
wolfSSL_CTX_set_TicketEncCb(ctx_s, test_TicketHint_custom_encCb);
|
||||
wolfSSL_CTX_set_TicketHint(ctx_s, hint);
|
||||
|
||||
ret = test_memio_do_handshake(ssl_c, ssl_s, 10, NULL);
|
||||
done:
|
||||
wolfSSL_free(ssl_c);
|
||||
wolfSSL_free(ssl_s);
|
||||
wolfSSL_CTX_free(ctx_c);
|
||||
wolfSSL_CTX_free(ctx_s);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* The default ticket encryption callback must refuse to issue a ticket when the
|
||||
* hint exceeds half the key lifetime, but a custom callback has no such limit. */
|
||||
int test_wolfSSL_CTX_set_TicketHint_default_cb_limit(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_TLS13) \
|
||||
&& defined(HAVE_SESSION_TICKET) && !defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) \
|
||||
&& !defined(NO_WOLFSSL_SERVER)
|
||||
/* Default callback: a hint below the limit is honored. */
|
||||
ExpectIntEQ(test_TicketHint_handshake(WOLFSSL_TICKET_KEY_LIFETIME / 2 - 1, 0),
|
||||
0);
|
||||
/* Default callback: a hint at/above the limit fails the handshake. */
|
||||
ExpectIntNE(test_TicketHint_handshake(WOLFSSL_TICKET_KEY_LIFETIME / 2, 0), 0);
|
||||
/* Custom callback: the same oversized hint is fine. */
|
||||
ExpectIntEQ(test_TicketHint_handshake(WOLFSSL_TICKET_KEY_LIFETIME / 2, 1), 0);
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
int test_wolfSSL_tlsext_max_fragment_length_ext(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
|
||||
@@ -28,6 +28,7 @@ int test_wolfSSL_CTX_num_tickets_ext(void);
|
||||
int test_wolfSSL_set1_groups_ext(void);
|
||||
int test_wolfSSL_set1_groups_list_ext(void);
|
||||
int test_wolfSSL_CTX_set_TicketHint_ext(void);
|
||||
int test_wolfSSL_CTX_set_TicketHint_default_cb_limit(void);
|
||||
int test_wolfSSL_tlsext_max_fragment_length_ext(void);
|
||||
int test_wolfSSL_DisableExtendedMasterSecret_ext(void);
|
||||
int test_wolfSSL_set_tlsext_host_name_ext(void);
|
||||
@@ -57,6 +58,8 @@ int test_wolfSSL_CTX_set_alpn_protos_inval_ext(void);
|
||||
TEST_DECL_GROUP("ssl_ext", test_wolfSSL_set1_groups_ext), \
|
||||
TEST_DECL_GROUP("ssl_ext", test_wolfSSL_set1_groups_list_ext), \
|
||||
TEST_DECL_GROUP("ssl_ext", test_wolfSSL_CTX_set_TicketHint_ext), \
|
||||
TEST_DECL_GROUP("ssl_ext", \
|
||||
test_wolfSSL_CTX_set_TicketHint_default_cb_limit), \
|
||||
TEST_DECL_GROUP("ssl_ext", \
|
||||
test_wolfSSL_tlsext_max_fragment_length_ext), \
|
||||
TEST_DECL_GROUP("ssl_ext", \
|
||||
|
||||
+31
-3
@@ -5729,12 +5729,38 @@ int test_tls13_short_session_ticket(void)
|
||||
}
|
||||
|
||||
|
||||
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
|
||||
defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET)
|
||||
/* Custom ticket encryption callback with no key-lifetime limit, so the server
|
||||
* issues a ticket for any hint (the default callback refuses a hint of at least
|
||||
* half the key lifetime). */
|
||||
static int test_tls13_max_lifetime_ticketEncCb(WOLFSSL* ssl,
|
||||
byte key_name[WOLFSSL_TICKET_NAME_SZ], byte iv[WOLFSSL_TICKET_IV_SZ],
|
||||
byte mac[WOLFSSL_TICKET_MAC_SZ], int enc, byte* ticket, int inLen,
|
||||
int* outLen, void* userCtx)
|
||||
{
|
||||
int i;
|
||||
(void)ssl;
|
||||
(void)userCtx;
|
||||
if (enc) {
|
||||
XMEMSET(key_name, 0x2A, WOLFSSL_TICKET_NAME_SZ);
|
||||
XMEMSET(iv, 0x2A, WOLFSSL_TICKET_IV_SZ);
|
||||
XMEMSET(mac, 0x2A, WOLFSSL_TICKET_MAC_SZ);
|
||||
}
|
||||
for (i = 0; i < inLen; i++)
|
||||
ticket[i] = (byte)(ticket[i] ^ 0xA5);
|
||||
*outLen = inLen;
|
||||
return WOLFSSL_TICKET_RET_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* RFC 8446 Section 4.6.1: a NewSessionTicket lifetime greater than
|
||||
* MAX_LIFETIME (604800 seconds, 7 days) must be rejected. The public
|
||||
* wolfSSL_CTX_set_TicketHint setter clamps the value, so write the
|
||||
* out-of-range hint directly into the server CTX to force the server to
|
||||
* encode an over-limit lifetime onto the wire and confirm the client's
|
||||
* DoTls13NewSessionTicket bound check fires. */
|
||||
* out-of-range hint directly into the server CTX. A custom encryption callback
|
||||
* is installed so the default callback's key-lifetime limit does not block
|
||||
* issuance, forcing the server to encode the over-limit lifetime onto the wire
|
||||
* and confirming the client's DoTls13NewSessionTicket bound check fires. */
|
||||
int test_tls13_new_session_ticket_max_lifetime(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
@@ -5749,6 +5775,8 @@ int test_tls13_new_session_ticket_max_lifetime(void)
|
||||
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
|
||||
wolfTLSv1_3_client_method, wolfTLSv1_3_server_method), 0);
|
||||
|
||||
wolfSSL_CTX_set_TicketEncCb(ctx_s, test_tls13_max_lifetime_ticketEncCb);
|
||||
|
||||
/* Bypass the public-API clamp at 604800. */
|
||||
if (EXPECT_SUCCESS()) {
|
||||
ctx_s->ticketHint = MAX_LIFETIME + 1;
|
||||
|
||||
+2
-2
@@ -2047,8 +2047,8 @@ WOLFSSL_LOCAL int NamedGroupIsPqcHybrid(int group);
|
||||
/* Default lifetime is 1 hour from issue of first ticket with key. */
|
||||
#define WOLFSSL_TICKET_KEY_LIFETIME (60 * 60)
|
||||
#endif
|
||||
#if WOLFSSL_TICKET_KEY_LIFETIME <= 2 * SESSION_TICKET_HINT_DEFAULT
|
||||
#error "Ticket Key lifetime must be more than twice the ticket life hint."
|
||||
#if WOLFSSL_TICKET_KEY_LIFETIME <= SESSION_TICKET_HINT_DEFAULT
|
||||
#error "Ticket Key lifetime must be longer than ticket life hint."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user