From 06798ab8bfd8bfbca6987b9179d107bd6f7f4eec Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Tue, 2 Apr 2024 15:18:50 +0200 Subject: [PATCH] EAP-FAST Implement PACs for EAP-FAST - wolfSSL_set_session_ticket_ext_cb - server side wolfSSL_set_session_secret_cb (tls <=1.2 only) --- src/internal.c | 62 +++++++++++++++++++++++++++++++++++++++++++++ src/ssl.c | 15 ++++++++++- wolfcrypt/src/kdf.c | 16 ++++++++++++ wolfssl/internal.h | 2 ++ wolfssl/ssl.h | 8 ++++-- 5 files changed, 100 insertions(+), 3 deletions(-) diff --git a/src/internal.c b/src/internal.c index 02e34dbc2..b71ea8563 100644 --- a/src/internal.c +++ b/src/internal.c @@ -35942,6 +35942,47 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, { int ret = 0; WOLFSSL_SESSION* session; + +#ifdef HAVE_SECRET_CALLBACK + if (ssl->sessionSecretCb != NULL +#ifdef HAVE_SESSION_TICKET + && ssl->session->ticketLen > 0 +#endif + ) { + int secretSz = SECRET_LEN; + WOLFSSL_MSG("Calling session secret callback"); + ret = wc_RNG_GenerateBlock(ssl->rng, ssl->arrays->serverRandom, + RAN_LEN); + if (ret == 0) { + ret = ssl->sessionSecretCb(ssl, ssl->arrays->masterSecret, + &secretSz, ssl->sessionSecretCtx); + if (secretSz != SECRET_LEN) + ret = SESSION_SECRET_CB_E; + } + if (ret == 0) + ret = MatchSuite(ssl, clSuites); + if (ret == 0) { + #ifdef NO_OLD_TLS + ret = DeriveTlsKeys(ssl); + #else + #ifndef NO_TLS + if (ssl->options.tls) + ret = DeriveTlsKeys(ssl); + #endif + if (!ssl->options.tls) + ret = DeriveKeys(ssl); + #endif + /* SERVER: peer auth based on session secret. */ + ssl->options.peerAuthGood = (ret == 0); + ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE; + } + if (ret != 0) + WOLFSSL_ERROR_VERBOSE(ret); + WOLFSSL_LEAVE("HandleTlsResumption", ret); + return ret; + } +#endif /* HAVE_SECRET_CALLBACK */ + #ifdef HAVE_SESSION_TICKET if (ssl->options.useTicket == 1) { session = ssl->session; @@ -36601,6 +36642,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, ssl->options.haveSessionId = 1; /* ProcessOld uses same resume code */ + WOLFSSL_MSG_EX("ssl->options.resuming %d", ssl->options.resuming); if (ssl->options.resuming) { ret = HandleTlsResumption(ssl, clSuites); if (ret != 0) @@ -37982,6 +38024,22 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, WOLFSSL_START(WC_FUNC_TICKET_DO); WOLFSSL_ENTER("DoClientTicket"); +#ifdef HAVE_SECRET_CALLBACK + if (ssl->ticketParseCb != NULL) { + decryptRet = WOLFSSL_TICKET_RET_OK; + if (!ssl->ticketParseCb(ssl, input, len, ssl->ticketParseCtx)) { + /* Failure kills the connection */ + decryptRet = WOLFSSL_TICKET_RET_FATAL; + } + else { + if (wolfSSL_set_SessionTicket(ssl, input, len) != + WOLFSSL_SUCCESS) + decryptRet = WOLFSSL_TICKET_RET_REJECT; + } + goto cleanup; + } + else +#endif #ifdef WOLFSSL_TLS13 if (len == ID_LEN && IsAtLeastTLSv1_3(ssl->version)) { /* This is a stateful ticket. We can be sure about this because @@ -37996,7 +38054,11 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } else #endif + if (len >= sizeof(*it)) decryptRet = DoDecryptTicket(ssl, input, len, &it); + else + WOLFSSL_MSG("Ticket is smaller than InternalTicket. Rejecting."); + if (decryptRet != WOLFSSL_TICKET_RET_OK && decryptRet != WOLFSSL_TICKET_RET_CREATE) { diff --git a/src/ssl.c b/src/ssl.c index c2b4f8205..c36422d52 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -8191,7 +8191,7 @@ int wolfSSL_set_session_secret_cb(WOLFSSL* ssl, SessionSecretCb cb, void* ctx) { WOLFSSL_ENTER("wolfSSL_set_session_secret_cb"); if (ssl == NULL) - return WOLFSSL_FATAL_ERROR; + return WOLFSSL_FAILURE; ssl->sessionSecretCb = cb; ssl->sessionSecretCtx = ctx; @@ -8204,6 +8204,19 @@ int wolfSSL_set_session_secret_cb(WOLFSSL* ssl, SessionSecretCb cb, void* ctx) return WOLFSSL_SUCCESS; } +int wolfSSL_set_session_ticket_ext_cb(WOLFSSL* ssl, TicketParseCb cb, + void *ctx) +{ + WOLFSSL_ENTER("wolfSSL_set_session_ticket_ext_cb"); + if (ssl == NULL) + return WOLFSSL_FAILURE; + + ssl->ticketParseCb = cb; + ssl->ticketParseCtx = ctx; + + return WOLFSSL_SUCCESS; +} + int wolfSSL_set_secret_cb(WOLFSSL* ssl, TlsSecretCb cb, void* ctx) { WOLFSSL_ENTER("wolfSSL_set_secret_cb"); diff --git a/wolfcrypt/src/kdf.c b/wolfcrypt/src/kdf.c index 15672e8f4..7fef6a56d 100644 --- a/wolfcrypt/src/kdf.c +++ b/wolfcrypt/src/kdf.c @@ -306,6 +306,16 @@ int wc_PRF_TLS(byte* digest, word32 digLen, const byte* secret, word32 secLen, { int ret = 0; +#ifdef WOLFSSL_DEBUG_TLS + WOLFSSL_MSG(" secret"); + WOLFSSL_BUFFER(secret, secLen); + WOLFSSL_MSG(" label"); + WOLFSSL_BUFFER(label, labLen); + WOLFSSL_MSG(" seed"); + WOLFSSL_BUFFER(seed, seedLen); +#endif + + if (useAtLeastSha256) { #ifdef WOLFSSL_SMALL_STACK byte* labelSeed; @@ -350,6 +360,12 @@ int wc_PRF_TLS(byte* digest, word32 digLen, const byte* secret, word32 secLen, #endif } +#ifdef WOLFSSL_DEBUG_TLS + WOLFSSL_MSG(" digest"); + WOLFSSL_BUFFER(digest, digLen); + WOLFSSL_MSG_EX("hash_type %d", hash_type); +#endif + return ret; } #endif /* WOLFSSL_HAVE_PRF && !NO_HMAC */ diff --git a/wolfssl/internal.h b/wolfssl/internal.h index ea828a84c..a339de4bd 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -5869,6 +5869,8 @@ struct WOLFSSL { #ifdef HAVE_SECRET_CALLBACK SessionSecretCb sessionSecretCb; void* sessionSecretCtx; + TicketParseCb ticketParseCb; + void* ticketParseCtx; TlsSecretCb tlsSecretCb; void* tlsSecretCtx; #ifdef WOLFSSL_TLS13 diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 2d1086462..e7c8832f0 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1366,8 +1366,12 @@ WOLFSSL_ABI WOLFSSL_API long wolfSSL_CTX_set_session_cache_mode(WOLFSSL_CTX* ctx typedef int (*SessionSecretCb)(WOLFSSL* ssl, void* secret, int* secretSz, void* ctx); /* This callback is used to set the master secret during resumption */ -WOLFSSL_API int wolfSSL_set_session_secret_cb(WOLFSSL* ssl, SessionSecretCb, - void*); +WOLFSSL_API int wolfSSL_set_session_secret_cb(WOLFSSL* ssl, SessionSecretCb cb, + void* ctx); +typedef int (*TicketParseCb)(WOLFSSL *ssl, const unsigned char *data, + int len, void *ctx); +WOLFSSL_API int wolfSSL_set_session_ticket_ext_cb(WOLFSSL* ssl, + TicketParseCb cb, void *ctx); typedef int (*TlsSecretCb)(WOLFSSL* ssl, void* secret, int secretSz, void* ctx); /* This callback is used to log the secret for TLS <= 1.2 */