mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-29 18:27:29 +02:00
Merge pull request #3713 from SparkiDev/tls_def_sess_ticket_cb
TLS Session Ticket: default encryption callback
This commit is contained in:
@ -165,9 +165,8 @@ THREAD_RETURN CYASSL_THREAD echoserver_test(void* args)
|
||||
CyaSSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_SESSION_TICKET) && \
|
||||
((defined(HAVE_CHACHA) && defined(HAVE_POLY1305)) || \
|
||||
defined(HAVE_AESGCM))
|
||||
#if defined(HAVE_SESSION_TICKET) && defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) && \
|
||||
((defined(HAVE_CHACHA) && defined(HAVE_POLY1305)) || defined(HAVE_AESGCM))
|
||||
if (TicketInit() != 0)
|
||||
err_sys("unable to setup Session Ticket Key context");
|
||||
wolfSSL_CTX_set_TicketEncCb(ctx, myTicketEncCb);
|
||||
@ -521,8 +520,8 @@ THREAD_RETURN CYASSL_THREAD echoserver_test(void* args)
|
||||
fdCloseSession(Task_self());
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_SESSION_TICKET) && defined(HAVE_CHACHA) && \
|
||||
defined(HAVE_POLY1305)
|
||||
#if defined(HAVE_SESSION_TICKET) && defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) && \
|
||||
((defined(HAVE_CHACHA) && defined(HAVE_POLY1305)) || defined(HAVE_AESGCM))
|
||||
TicketCleanup();
|
||||
#endif
|
||||
|
||||
|
@ -1800,9 +1800,8 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
|
||||
wolfSSL_CTX_SetIOSend(ctx, SimulateWantWriteIOSendCb);
|
||||
}
|
||||
|
||||
#if defined(HAVE_SESSION_TICKET) && \
|
||||
((defined(HAVE_CHACHA) && defined(HAVE_POLY1305)) || \
|
||||
defined(HAVE_AESGCM))
|
||||
#if defined(HAVE_SESSION_TICKET) && defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) && \
|
||||
((defined(HAVE_CHACHA) && defined(HAVE_POLY1305)) || defined(HAVE_AESGCM))
|
||||
if (TicketInit() != 0)
|
||||
err_sys_ex(catastrophic, "unable to setup Session Ticket Key context");
|
||||
wolfSSL_CTX_set_TicketEncCb(ctx, myTicketEncCb);
|
||||
@ -2835,8 +2834,8 @@ exit:
|
||||
fdCloseSession(Task_self());
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_SESSION_TICKET) && defined(HAVE_CHACHA) && \
|
||||
defined(HAVE_POLY1305)
|
||||
#if defined(HAVE_SESSION_TICKET) && defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) && \
|
||||
((defined(HAVE_CHACHA) && defined(HAVE_POLY1305)) || defined(HAVE_AESGCM))
|
||||
TicketCleanup();
|
||||
#endif
|
||||
|
||||
|
483
src/internal.c
483
src/internal.c
@ -42,6 +42,24 @@
|
||||
* read timeout. By default we resend in two more cases, when we receive:
|
||||
* - an out of order last msg of the peer's flight
|
||||
* - a duplicate of the first msg from the peer's flight
|
||||
* WOLFSSL_NO_DEF_TICKET_ENC_CB:
|
||||
* No default ticket encryption callback.
|
||||
* Server only.
|
||||
* Application must set its own callback to use session tickets.
|
||||
* WOLFSSL_TICKET_ENC_CHACHA20_POLY1305
|
||||
* Use ChaCha20-Poly1305 to encrypt/decrypt session tickets in default
|
||||
* callback. Default algorithm if none defined and algorithms compiled in.
|
||||
* Server only.
|
||||
* WOLFSSL_TICKET_ENC_AES128_GCM
|
||||
* Use AES128-GCM to encrypt/decrypt session tickets in default callback.
|
||||
* Server only. Default algorithm if ChaCha20/Poly1305 not compiled in.
|
||||
* WOLFSSL_TICKET_ENC_AES256_GCM
|
||||
* Use AES256-GCM to encrypt/decrypt session tickets in default callback.
|
||||
* Server only.
|
||||
* WOLFSSL_TICKET_DECRYPT_NO_CREATE
|
||||
* Default callback will not request creation of new ticket on successful
|
||||
* decryption.
|
||||
* Server only.
|
||||
*/
|
||||
|
||||
|
||||
@ -129,10 +147,25 @@ WOLFSSL_CALLBACKS needs LARGE_STATIC_BUFFERS, please add LARGE_STATIC_BUFFERS
|
||||
#ifdef WOLFSSL_DTLS
|
||||
static int SendHelloVerifyRequest(WOLFSSL*, const byte*, byte);
|
||||
#endif /* WOLFSSL_DTLS */
|
||||
#endif
|
||||
|
||||
#endif /* !NO_WOLFSSL_SERVER */
|
||||
|
||||
#endif /* !WOLFSSL_NO_TLS12 */
|
||||
|
||||
#ifndef NO_WOLFSSL_SERVER
|
||||
#if defined(HAVE_SESSION_TICKET) && !defined(WOLFSSL_NO_DEF_TICKET_ENC_CB)
|
||||
static int TicketEncCbCtx_Init(WOLFSSL_CTX* ctx,
|
||||
TicketEncCbCtx* keyCtx);
|
||||
static void TicketEncCbCtx_Free(TicketEncCbCtx* keyCtx);
|
||||
static int DefTicketEncCb(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);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_DTLS
|
||||
static WC_INLINE int DtlsCheckWindow(WOLFSSL* ssl);
|
||||
static WC_INLINE int DtlsUpdateWindow(WOLFSSL* ssl);
|
||||
@ -1781,6 +1814,12 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap)
|
||||
#endif /* HAVE_EXTENDED_MASTER && !NO_WOLFSSL_CLIENT */
|
||||
|
||||
#if defined(HAVE_SESSION_TICKET) && !defined(NO_WOLFSSL_SERVER)
|
||||
#ifndef WOLFSSL_NO_DEF_TICKET_ENC_CB
|
||||
ret = TicketEncCbCtx_Init(ctx, &ctx->ticketKeyCtx);
|
||||
if (ret != 0) return ret;
|
||||
ctx->ticketEncCb = DefTicketEncCb;
|
||||
ctx->ticketEncCtx = (void*)&ctx->ticketKeyCtx;
|
||||
#endif
|
||||
ctx->ticketHint = SESSION_TICKET_HINT_DEFAULT;
|
||||
#endif
|
||||
|
||||
@ -1913,7 +1952,7 @@ void SSL_CtxResourceFree(WOLFSSL_CTX* ctx)
|
||||
#ifdef HAVE_ECC
|
||||
if (ctx->staticKE.ecKey)
|
||||
FreeDer(&ctx->staticKE.ecKey);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#ifdef WOLFSSL_STATIC_MEMORY
|
||||
if (ctx->heap != NULL) {
|
||||
@ -1949,6 +1988,10 @@ void FreeSSL_Ctx(WOLFSSL_CTX* ctx)
|
||||
void* heap = ctx->heap;
|
||||
WOLFSSL_MSG("CTX ref count down to 0, doing full free");
|
||||
SSL_CtxResourceFree(ctx);
|
||||
#if defined(HAVE_SESSION_TICKET) && !defined(NO_WOLFSSL_SERVER) && \
|
||||
!defined(WOLFSSL_NO_DEF_TICKET_ENC_CB)
|
||||
TicketEncCbCtx_Free(&ctx->ticketKeyCtx);
|
||||
#endif
|
||||
wc_FreeMutex(&ctx->countMutex);
|
||||
#ifdef WOLFSSL_STATIC_MEMORY
|
||||
if (ctx->onHeap == 0) {
|
||||
@ -12970,7 +13013,6 @@ static int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||
else {
|
||||
ShrinkInputBuffer(ssl, NO_FORCED_FREE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLFSSL_NONBLOCK_OCSP)
|
||||
@ -17138,7 +17180,7 @@ int CreateOcspResponse(WOLFSSL* ssl, OcspRequest** ocspRequest,
|
||||
#endif /* !NO_WOLFSSL_SERVER */
|
||||
|
||||
#if (!defined(WOLFSSL_NO_TLS12) && !defined(NO_CERTS)) \
|
||||
|| defined(HAVE_SESSION_TICKET)
|
||||
|| (defined(HAVE_SESSION_TICKET) && !defined(NO_WOLFSSL_SERVER))
|
||||
static int cipherExtraData(WOLFSSL* ssl)
|
||||
{
|
||||
/* Cipher data that may be added by BuildMessage */
|
||||
@ -29146,6 +29188,435 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef WOLFSSL_NO_DEF_TICKET_ENC_CB
|
||||
|
||||
/* Initialize the context for session ticket encryption.
|
||||
*
|
||||
* @param [in] ctx SSL context.
|
||||
* @param [in] keyCtx Context for session ticket encryption.
|
||||
* @return 0 on success.
|
||||
* @return BAD_MUTEX_E when initializing mutex fails.
|
||||
*/
|
||||
static int TicketEncCbCtx_Init(WOLFSSL_CTX* ctx, TicketEncCbCtx* keyCtx)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
XMEMSET(keyCtx, 0, sizeof(*keyCtx));
|
||||
keyCtx->ctx = ctx;
|
||||
|
||||
#ifndef SINGLE_THREADED
|
||||
ret = wc_InitMutex(&keyCtx->mutex);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Setup the session ticket encryption context for this.
|
||||
*
|
||||
* Initialize RNG, generate name, generate primeary key and set primary key
|
||||
* expirary.
|
||||
*
|
||||
* @param [in] keyCtx Context for session ticket encryption.
|
||||
* @param [in] heap Dynamic memory allocation hint.
|
||||
* @param [in] devId Device identifier.
|
||||
* @return 0 on success.
|
||||
* @return Other value when random number generator fails.
|
||||
*/
|
||||
static int TicketEncCbCtx_Setup(TicketEncCbCtx* keyCtx, void* heap, int devId)
|
||||
{
|
||||
int ret;
|
||||
|
||||
#ifndef SINGLE_THREADED
|
||||
ret = 0;
|
||||
|
||||
/* Check that key wasn't set up while waiting. */
|
||||
if (keyCtx->expirary[0] == 0)
|
||||
#endif
|
||||
{
|
||||
ret = wc_InitRng_ex(&keyCtx->rng, heap, devId);
|
||||
if (ret == 0) {
|
||||
ret = wc_RNG_GenerateBlock(&keyCtx->rng, keyCtx->name,
|
||||
sizeof(keyCtx->name));
|
||||
}
|
||||
if (ret == 0) {
|
||||
/* Mask of the bottom bit - used for index of key. */
|
||||
keyCtx->name[WOLFSSL_TICKET_NAME_SZ - 1] &= 0xfe;
|
||||
|
||||
/* Generate initial primary key. */
|
||||
ret = wc_RNG_GenerateBlock(&keyCtx->rng, keyCtx->key[0],
|
||||
WOLFSSL_TICKET_KEY_SZ);
|
||||
}
|
||||
if (ret == 0) {
|
||||
keyCtx->expirary[0] = LowResTimer() + WOLFSSL_TICKET_KEY_LIFETIME;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
/* Free the context for session ticket encryption.
|
||||
*
|
||||
* Zeroize keys and name.
|
||||
*
|
||||
* @param [in] keyCtx Context for session ticket encryption.
|
||||
*/
|
||||
static void TicketEncCbCtx_Free(TicketEncCbCtx* keyCtx)
|
||||
{
|
||||
/* Zeroize sensitive data. */
|
||||
ForceZero(keyCtx->name, sizeof(keyCtx->name));
|
||||
ForceZero(keyCtx->key[0], sizeof(keyCtx->key[0]));
|
||||
ForceZero(keyCtx->key[1], sizeof(keyCtx->key[1]));
|
||||
|
||||
#ifndef SINGLE_THREADED
|
||||
wc_FreeMutex(&keyCtx->mutex);
|
||||
#endif
|
||||
wc_FreeRng(&keyCtx->rng);
|
||||
}
|
||||
|
||||
#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) && \
|
||||
!defined(WOLFSSL_TICKET_ENC_AES128_GCM) && \
|
||||
!defined(WOLFSSL_TICKET_ENC_AES256_GCM)
|
||||
/* Ticket encryption/decryption implementation.
|
||||
*
|
||||
* @param [in] key Key for encryption/decryption.
|
||||
* @param [in] keyLen Length of key in bytes.
|
||||
* @param [in] iv IV/Nonce for encryption/decryption.
|
||||
* @param [in] aad Additional authentication data.
|
||||
* @param [in] aadSz Length of additional authentication data.
|
||||
* @param [in] in Data to encrypt/decrypt.
|
||||
* @param [in] inLen Length of encrypted data.
|
||||
* @param [out] out Resulting data from encrypt/decrypt.
|
||||
* @param [out] outLen Size of resulting data.
|
||||
* @param [in] tag Authentication tag for encrypted data.
|
||||
* @param [in] heap Dynamic memory allocation data hint.
|
||||
* @param [in] enc 1 when encrypting, 0 when decrypting.
|
||||
* @return 0 on success.
|
||||
* @return Other value when encryption/decryption fails.
|
||||
*/
|
||||
static int TicketEncDec(byte* key, int keyLen, byte* iv, byte* aad, int aadSz,
|
||||
byte* in, int inLen, byte* out, int* outLen, byte* tag,
|
||||
void* heap, int enc)
|
||||
{
|
||||
int ret;
|
||||
|
||||
(void)keyLen;
|
||||
(void)heap;
|
||||
|
||||
if (enc) {
|
||||
ret = wc_ChaCha20Poly1305_Encrypt(key, iv, aad, aadSz, in, inLen, out,
|
||||
tag);
|
||||
}
|
||||
else {
|
||||
ret = wc_ChaCha20Poly1305_Decrypt(key, iv, aad, aadSz, in, inLen, tag,
|
||||
out);
|
||||
}
|
||||
|
||||
*outLen = inLen;
|
||||
|
||||
return ret;
|
||||
}
|
||||
#elif defined(HAVE_AESGCM)
|
||||
/* Ticket encryption/decryption implementation.
|
||||
*
|
||||
* @param [in] key Key for encryption/decryption.
|
||||
* @param [in] keyLen Length of key in bytes.
|
||||
* @param [in] iv IV/Nonce for encryption/decryption.
|
||||
* @param [in] aad Additional authentication data.
|
||||
* @param [in] aadSz Length of additional authentication data.
|
||||
* @param [in] in Data to encrypt/decrypt.
|
||||
* @param [in] inLen Length of encrypted data.
|
||||
* @param [out] out Resulting data from encrypt/decrypt.
|
||||
* @param [out] outLen Size of resulting data.
|
||||
* @param [in] tag Authentication tag for encrypted data.
|
||||
* @param [in] heap Dynamic memory allocation data hint.
|
||||
* @param [in] enc 1 when encrypting, 0 when decrypting.
|
||||
* @return 0 on success.
|
||||
* @return MEMORY_E when dynamic memory allocation fails.
|
||||
* @return Other value when encryption/decryption fails.
|
||||
*/
|
||||
static int TicketEncDec(byte* key, int keyLen, byte* iv, byte* aad, int aadSz,
|
||||
byte* in, int inLen, byte* out, int* outLen, byte* tag,
|
||||
void* heap, int enc)
|
||||
{
|
||||
int ret;
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
Aes* aes;
|
||||
#else
|
||||
Aes aes[1];
|
||||
#endif
|
||||
|
||||
(void)heap;
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (aes == NULL)
|
||||
return MEMORY_E;
|
||||
#endif
|
||||
|
||||
if (enc) {
|
||||
ret = wc_AesInit(aes, NULL, INVALID_DEVID);
|
||||
if (ret == 0) {
|
||||
ret = wc_AesGcmSetKey(aes, key, keyLen);
|
||||
}
|
||||
if (ret == 0) {
|
||||
ret = wc_AesGcmEncrypt(aes, in, out, inLen, iv, GCM_NONCE_MID_SZ,
|
||||
tag, AES_BLOCK_SIZE, aad, aadSz);
|
||||
}
|
||||
wc_AesFree(aes);
|
||||
}
|
||||
else {
|
||||
ret = wc_AesInit(aes, NULL, INVALID_DEVID);
|
||||
if (ret == 0) {
|
||||
ret = wc_AesGcmSetKey(aes, key, keyLen);
|
||||
}
|
||||
if (ret == 0) {
|
||||
ret = wc_AesGcmDecrypt(aes, in, out, inLen, iv, GCM_NONCE_MID_SZ,
|
||||
tag, AES_BLOCK_SIZE, aad, aadSz);
|
||||
}
|
||||
wc_AesFree(aes);
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(aes, heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
|
||||
*outLen = inLen;
|
||||
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
#error "No encryption algorithm available for default ticket encryption."
|
||||
#endif
|
||||
|
||||
/* Choose a key to use for encryption.
|
||||
*
|
||||
* Generate a new key if the current ones are expired.
|
||||
* If the secondary key has not been used and the primary key has expired then
|
||||
* generate a new primary key.
|
||||
*
|
||||
* @param [in] Ticket encryption callback context.
|
||||
* @param [in] Session ticket lifetime.
|
||||
* @param [out] Index of key to use for encryption.
|
||||
* @return 0 on success.
|
||||
* @return Other value when random number generation fails.
|
||||
*/
|
||||
static int TicketEncCbCtx_ChooseKey(TicketEncCbCtx* keyCtx, int ticketHint,
|
||||
int* keyIdx)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
/* Get new current time as lock may have taken some time. */
|
||||
word32 now = LowResTimer();
|
||||
|
||||
/* Check expirary of primary key for encrypt. */
|
||||
if (keyCtx->expirary[0] >= now + ticketHint) {
|
||||
*keyIdx = 0;
|
||||
}
|
||||
/* Check expirary of primary key for encrypt. */
|
||||
else if (keyCtx->expirary[1] >= now + ticketHint) {
|
||||
*keyIdx = 1;
|
||||
}
|
||||
/* No key available to use. */
|
||||
else {
|
||||
int genKey;
|
||||
|
||||
/* Generate which ever key is expired for decrypt - primary first. */
|
||||
if (keyCtx->expirary[0] < now) {
|
||||
genKey = 0;
|
||||
}
|
||||
else if (keyCtx->expirary[1] < now) {
|
||||
genKey = 1;
|
||||
}
|
||||
/* Timeouts and expirary should not allow this to happen. */
|
||||
else {
|
||||
return BAD_STATE_E;
|
||||
}
|
||||
|
||||
/* Generate the required key */
|
||||
ret = wc_RNG_GenerateBlock(&keyCtx->rng, keyCtx->key[genKey],
|
||||
WOLFSSL_TICKET_KEY_SZ);
|
||||
if (ret == 0) {
|
||||
keyCtx->expirary[genKey] = now + WOLFSSL_TICKET_KEY_LIFETIME;
|
||||
*keyIdx = genKey;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Default Session Ticket encryption/decryption callback.
|
||||
*
|
||||
* Use ChaCha20-Poly1305 or AES-GCM to encrypt/decrypt the ticket.
|
||||
* Two keys are used:
|
||||
* - When the first expires for encryption, then use the other.
|
||||
* - Don't encrypt with key if the ticket lifetime will go beyond expirary.
|
||||
* - Generate a new primary key when primary key expired for decrypt and
|
||||
* no secondary key is activate for encryption.
|
||||
* - Generate a new secondary key when expired and needed.
|
||||
* - Calculate expirary starting from first encrypted ticket.
|
||||
* - Key name has last bit set to indicate index of key.
|
||||
* Keys expire for decryption after ticket key lifetime from the first encrypted
|
||||
* ticket.
|
||||
* Keys can only be use for encryption while the ticket hint does not exceed
|
||||
* the key lifetime.
|
||||
* Lifetime of a key must be greater than the lifetime of a ticket. This means
|
||||
* that if one ticket is only valid for decryption, then the other will be
|
||||
* valid for encryption.
|
||||
* AAD = key_name | iv | ticket len (16-bits network order)
|
||||
*
|
||||
* @param [in] ssl SSL connection.
|
||||
* @param [in,out] key_name Name of key from client.
|
||||
* Encrypt: name of key returned.
|
||||
* Decrypt: name from ticket message to check.
|
||||
* @param [in] iv IV to use in encryption/decryption.
|
||||
* @param [in] mac MAC for authentication of encrypted data.
|
||||
* @param [in] enc 1 when encrypting ticket, 0 when decrypting.
|
||||
* @param [in,out] ticket Encrypted/decrypted session ticket bytes.
|
||||
* @param [in] inLen Length of incoming ticket.
|
||||
* @param [out] outLen Length of outgoing ticket.
|
||||
* @param [in] userCtx Context for encryption/decryption of ticket.
|
||||
* @return WOLFSSL_TICKET_RET_OK when successful.
|
||||
* @return WOLFSSL_TICKET_RET_CREATE when successful and a new ticket is to
|
||||
* be created for TLS 1.2 and below.
|
||||
* @return WOLFSSL_TICKET_RET_REJECT when failed to produce valid encrypted or
|
||||
* decrypted ticket.
|
||||
* @return WOLFSSL_TICKET_RET_FATAL when key name does not match.
|
||||
*/
|
||||
static int DefTicketEncCb(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 ret;
|
||||
TicketEncCbCtx* keyCtx = (TicketEncCbCtx*)userCtx;
|
||||
WOLFSSL_CTX* ctx = keyCtx->ctx;
|
||||
word16 sLen = XHTONS(inLen);
|
||||
byte aad[WOLFSSL_TICKET_NAME_SZ + WOLFSSL_TICKET_IV_SZ + sizeof(sLen)];
|
||||
int aadSz = WOLFSSL_TICKET_NAME_SZ + WOLFSSL_TICKET_IV_SZ + sizeof(sLen);
|
||||
byte* p = aad;
|
||||
int keyIdx = 0;
|
||||
|
||||
/* Check we have setup the RNG, name and primary key. */
|
||||
if (keyCtx->expirary[0] == 0) {
|
||||
#ifndef SINGLE_THREADED
|
||||
/* Lock around access to expirary and key - stop initial key being
|
||||
* generated twice at the same time. */
|
||||
if (wc_LockMutex(&keyCtx->mutex) != 0) {
|
||||
WOLFSSL_MSG("Couldn't lock key context mutex");
|
||||
return WOLFSSL_TICKET_RET_REJECT;
|
||||
}
|
||||
#endif
|
||||
/* Sets expirary of primary key in setup. */
|
||||
ret = TicketEncCbCtx_Setup(keyCtx, ssl->ctx->heap, ssl->ctx->devId);
|
||||
#ifndef SINGLE_THREADED
|
||||
wc_UnLockMutex(&keyCtx->mutex);
|
||||
#endif
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (enc) {
|
||||
/* Return the name of the key - missing key index. */
|
||||
XMEMCPY(key_name, keyCtx->name, WOLFSSL_TICKET_NAME_SZ);
|
||||
|
||||
/* Generate a new IV into buffer to be returned.
|
||||
* Don't use the RNG in keyCtx as it's for generating private data. */
|
||||
ret = wc_RNG_GenerateBlock(ssl->rng, iv, WOLFSSL_TICKET_IV_SZ);
|
||||
if (ret != 0) {
|
||||
return WOLFSSL_TICKET_RET_REJECT;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Mask of last bit that is the key index. */
|
||||
byte lastByte = key_name[WOLFSSL_TICKET_NAME_SZ - 1] & 0xfe;
|
||||
|
||||
/* For decryption, see if we know this key - check all but last byte. */
|
||||
if (XMEMCMP(key_name, keyCtx->name, WOLFSSL_TICKET_NAME_SZ - 1) != 0) {
|
||||
return WOLFSSL_TICKET_RET_FATAL;
|
||||
}
|
||||
/* Ensure last byte without index bit matches too. */
|
||||
if (lastByte != keyCtx->name[WOLFSSL_TICKET_NAME_SZ - 1]) {
|
||||
return WOLFSSL_TICKET_RET_FATAL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Build AAD from: key name, iv, and length of ticket. */
|
||||
XMEMCPY(p, keyCtx->name, WOLFSSL_TICKET_NAME_SZ);
|
||||
p += WOLFSSL_TICKET_NAME_SZ;
|
||||
XMEMCPY(p, iv, WOLFSSL_TICKET_IV_SZ);
|
||||
p += WOLFSSL_TICKET_IV_SZ;
|
||||
XMEMCPY(p, &sLen, sizeof(sLen));
|
||||
|
||||
/* Encrypt ticket. */
|
||||
if (enc) {
|
||||
word32 now;
|
||||
|
||||
now = LowResTimer();
|
||||
/* As long as encryption expirary isn't imminent - no lock. */
|
||||
if (keyCtx->expirary[0] > now + ctx->ticketHint) {
|
||||
keyIdx = 0;
|
||||
}
|
||||
else if (keyCtx->expirary[1] > now + ctx->ticketHint) {
|
||||
keyIdx = 1;
|
||||
}
|
||||
else {
|
||||
#ifndef SINGLE_THREADED
|
||||
/* Lock around access to expirary and key - stop key being generated
|
||||
* twice at the same time. */
|
||||
if (wc_LockMutex(&keyCtx->mutex) != 0) {
|
||||
WOLFSSL_MSG("Couldn't lock key context mutex");
|
||||
return WOLFSSL_TICKET_RET_REJECT;
|
||||
}
|
||||
#endif
|
||||
ret = TicketEncCbCtx_ChooseKey(keyCtx, ctx->ticketHint, &keyIdx);
|
||||
#ifndef SINGLE_THREADED
|
||||
wc_UnLockMutex(&keyCtx->mutex);
|
||||
#endif
|
||||
if (ret != 0) {
|
||||
return WOLFSSL_TICKET_RET_REJECT;
|
||||
}
|
||||
}
|
||||
/* Set the name of the key to the index chosen. */
|
||||
key_name[WOLFSSL_TICKET_NAME_SZ - 1] |= keyIdx;
|
||||
/* Update AAD too. */
|
||||
aad[WOLFSSL_TICKET_NAME_SZ - 1] |= keyIdx;
|
||||
|
||||
/* Encrypt ticket data. */
|
||||
ret = TicketEncDec(keyCtx->key[keyIdx], WOLFSSL_TICKET_KEY_SZ, iv, aad,
|
||||
aadSz, ticket, inLen, ticket, outLen, mac, ssl->heap,
|
||||
1);
|
||||
if (ret != 0) return WOLFSSL_TICKET_RET_REJECT;
|
||||
}
|
||||
/* Decrypt ticket. */
|
||||
else {
|
||||
/* Get index of key from name. */
|
||||
keyIdx = key_name[WOLFSSL_TICKET_NAME_SZ - 1] & 0x1;
|
||||
/* Update AAD with index. */
|
||||
aad[WOLFSSL_TICKET_NAME_SZ - 1] |= keyIdx;
|
||||
|
||||
/* Check expirary */
|
||||
if (keyCtx->expirary[keyIdx] <= LowResTimer()) {
|
||||
return WOLFSSL_TICKET_RET_REJECT;
|
||||
}
|
||||
|
||||
/* Decrypt ticket data. */
|
||||
ret = TicketEncDec(keyCtx->key[keyIdx], WOLFSSL_TICKET_KEY_SZ, iv, aad,
|
||||
aadSz, ticket, inLen, ticket, outLen, mac, ssl->heap,
|
||||
0);
|
||||
if (ret != 0) {
|
||||
return WOLFSSL_TICKET_RET_REJECT;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef WOLFSSL_TICKET_DECRYPT_NO_CREATE
|
||||
if (!IsAtLeastTLSv1_3(ssl->version) && !enc)
|
||||
return WOLFSSL_TICKET_RET_CREATE;
|
||||
#endif
|
||||
return WOLFSSL_TICKET_RET_OK;
|
||||
}
|
||||
|
||||
#endif /* !WOLFSSL_NO_DEF_TICKET_ENC_CB */
|
||||
|
||||
#endif /* HAVE_SESSION_TICKET */
|
||||
|
||||
#ifndef WOLFSSL_NO_TLS12
|
||||
@ -29839,9 +30310,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
ssl->arrays->preMasterSz = private_key->dp->size;
|
||||
|
||||
ssl->peerEccKeyPresent = 1;
|
||||
|
||||
|
||||
#if defined(WOLFSSL_TLS13) || defined(HAVE_FFDHE)
|
||||
/* client_hello may have sent FFEDH2048, which sets namedGroup,
|
||||
/* client_hello may have sent FFEDH2048, which sets namedGroup,
|
||||
but that is not being used, so clear it */
|
||||
/* resolves issue with server side wolfSSL_get_curve_name */
|
||||
ssl->namedGroup = 0;
|
||||
|
68
src/ssl.c
68
src/ssl.c
@ -47412,11 +47412,79 @@ int wolfSSL_CTX_set_tlsext_ticket_key_cb(WOLFSSL_CTX *ctx, int (*cb)(
|
||||
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
|
||||
#endif /* HAVE_SESSION_TICKET */
|
||||
|
||||
#endif /* OPENSSL_ALL || WOLFSSL_NGINX || WOLFSSL_HAPROXY ||
|
||||
OPENSSL_EXTRA || HAVE_LIGHTY */
|
||||
|
||||
#if defined(HAVE_SESSION_TICKET) && !defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) && \
|
||||
!defined(NO_WOLFSSL_SERVER)
|
||||
/* Serialize the session ticket encryption keys.
|
||||
*
|
||||
* @param [in] ctx SSL/TLS context object.
|
||||
* @param [in] keys Buffer to hold session ticket keys.
|
||||
* @param [in] keylen Length of buffer.
|
||||
* @return WOLFSSL_SUCCESS on success.
|
||||
* @return WOLFSSL_FAILURE when ctx is NULL, keys is NULL or keylen is not the
|
||||
* correct length.
|
||||
*/
|
||||
long wolfSSL_CTX_get_tlsext_ticket_keys(WOLFSSL_CTX *ctx,
|
||||
unsigned char *keys, int keylen)
|
||||
{
|
||||
if (ctx == NULL || keys == NULL) {
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
if (keylen != WOLFSSL_TICKET_KEYS_SZ) {
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
XMEMCPY(keys, ctx->ticketKeyCtx.name, WOLFSSL_TICKET_NAME_SZ);
|
||||
keys += WOLFSSL_TICKET_NAME_SZ;
|
||||
XMEMCPY(keys, ctx->ticketKeyCtx.key[0], WOLFSSL_TICKET_KEY_SZ);
|
||||
keys += WOLFSSL_TICKET_KEY_SZ;
|
||||
XMEMCPY(keys, ctx->ticketKeyCtx.key[1], WOLFSSL_TICKET_KEY_SZ);
|
||||
keys += WOLFSSL_TICKET_KEY_SZ;
|
||||
c32toa(ctx->ticketKeyCtx.expirary[0], keys);
|
||||
keys += OPAQUE32_LEN;
|
||||
c32toa(ctx->ticketKeyCtx.expirary[1], keys);
|
||||
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
|
||||
/* Deserialize the session ticket encryption keys.
|
||||
*
|
||||
* @param [in] ctx SSL/TLS context object.
|
||||
* @param [in] keys Session ticket keys.
|
||||
* @param [in] keylen Length of data.
|
||||
* @return WOLFSSL_SUCCESS on success.
|
||||
* @return WOLFSSL_FAILURE when ctx is NULL, keys is NULL or keylen is not the
|
||||
* correct length.
|
||||
*/
|
||||
long wolfSSL_CTX_set_tlsext_ticket_keys(WOLFSSL_CTX *ctx,
|
||||
unsigned char *keys, int keylen)
|
||||
{
|
||||
if (ctx == NULL || keys == NULL) {
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
if (keylen != WOLFSSL_TICKET_KEYS_SZ) {
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
XMEMCPY(ctx->ticketKeyCtx.name, keys, WOLFSSL_TICKET_NAME_SZ);
|
||||
keys += WOLFSSL_TICKET_NAME_SZ;
|
||||
XMEMCPY(ctx->ticketKeyCtx.key[0], keys, WOLFSSL_TICKET_KEY_SZ);
|
||||
keys += WOLFSSL_TICKET_KEY_SZ;
|
||||
XMEMCPY(ctx->ticketKeyCtx.key[1], keys, WOLFSSL_TICKET_KEY_SZ);
|
||||
keys += WOLFSSL_TICKET_KEY_SZ;
|
||||
ato32(keys, &ctx->ticketKeyCtx.expirary[0]);
|
||||
keys += OPAQUE32_LEN;
|
||||
ato32(keys, &ctx->ticketKeyCtx.expirary[1]);
|
||||
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
|
||||
#ifdef HAVE_OCSP
|
||||
/* Not an OpenSSL API. */
|
||||
|
57
tests/api.c
57
tests/api.c
@ -2646,9 +2646,8 @@ static THREAD_RETURN WOLFSSL_THREAD test_server_nofail(void* args)
|
||||
ctx = wolfSSL_CTX_new(method);
|
||||
}
|
||||
|
||||
#if defined(HAVE_SESSION_TICKET) && \
|
||||
((defined(HAVE_CHACHA) && defined(HAVE_POLY1305)) || \
|
||||
defined(HAVE_AESGCM))
|
||||
#if defined(HAVE_SESSION_TICKET) && defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) && \
|
||||
((defined(HAVE_CHACHA) && defined(HAVE_POLY1305)) || defined(HAVE_AESGCM))
|
||||
TicketInit();
|
||||
wolfSSL_CTX_set_TicketEncCb(ctx, myTicketEncCb);
|
||||
#endif
|
||||
@ -2834,8 +2833,8 @@ done:
|
||||
wc_ecc_fp_free(); /* free per thread cache */
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_SESSION_TICKET) && defined(HAVE_CHACHA) && \
|
||||
defined(HAVE_POLY1305)
|
||||
#if defined(HAVE_SESSION_TICKET) && defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) && \
|
||||
((defined(HAVE_CHACHA) && defined(HAVE_POLY1305)) || defined(HAVE_AESGCM))
|
||||
TicketCleanup();
|
||||
#endif
|
||||
|
||||
@ -31678,6 +31677,53 @@ static void test_wolfSSL_SESSION(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
static void test_wolfSSL_ticket_keys(void)
|
||||
{
|
||||
#if defined(HAVE_SESSION_TICKET) && !defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) && \
|
||||
!defined(NO_WOLFSSL_SERVER)
|
||||
WOLFSSL_CTX* ctx;
|
||||
byte keys[WOLFSSL_TICKET_KEYS_SZ];
|
||||
|
||||
AssertNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
|
||||
|
||||
AssertIntEQ(wolfSSL_CTX_get_tlsext_ticket_keys(NULL, NULL, 0),
|
||||
WOLFSSL_FAILURE);
|
||||
AssertIntEQ(wolfSSL_CTX_get_tlsext_ticket_keys(ctx, NULL, 0),
|
||||
WOLFSSL_FAILURE);
|
||||
AssertIntEQ(wolfSSL_CTX_get_tlsext_ticket_keys(ctx, keys, 0),
|
||||
WOLFSSL_FAILURE);
|
||||
AssertIntEQ(wolfSSL_CTX_get_tlsext_ticket_keys(NULL, keys, 0),
|
||||
WOLFSSL_FAILURE);
|
||||
AssertIntEQ(wolfSSL_CTX_get_tlsext_ticket_keys(NULL, NULL, sizeof(keys)),
|
||||
WOLFSSL_FAILURE);
|
||||
AssertIntEQ(wolfSSL_CTX_get_tlsext_ticket_keys(ctx, NULL, sizeof(keys)),
|
||||
WOLFSSL_FAILURE);
|
||||
AssertIntEQ(wolfSSL_CTX_get_tlsext_ticket_keys(NULL, keys, sizeof(keys)),
|
||||
WOLFSSL_FAILURE);
|
||||
|
||||
AssertIntEQ(wolfSSL_CTX_set_tlsext_ticket_keys(NULL, NULL, 0),
|
||||
WOLFSSL_FAILURE);
|
||||
AssertIntEQ(wolfSSL_CTX_set_tlsext_ticket_keys(ctx, NULL, 0),
|
||||
WOLFSSL_FAILURE);
|
||||
AssertIntEQ(wolfSSL_CTX_set_tlsext_ticket_keys(ctx, keys, 0),
|
||||
WOLFSSL_FAILURE);
|
||||
AssertIntEQ(wolfSSL_CTX_set_tlsext_ticket_keys(NULL, keys, 0),
|
||||
WOLFSSL_FAILURE);
|
||||
AssertIntEQ(wolfSSL_CTX_set_tlsext_ticket_keys(NULL, NULL, sizeof(keys)),
|
||||
WOLFSSL_FAILURE);
|
||||
AssertIntEQ(wolfSSL_CTX_set_tlsext_ticket_keys(ctx, NULL, sizeof(keys)),
|
||||
WOLFSSL_FAILURE);
|
||||
AssertIntEQ(wolfSSL_CTX_set_tlsext_ticket_keys(NULL, keys, sizeof(keys)),
|
||||
WOLFSSL_FAILURE);
|
||||
|
||||
AssertIntEQ(wolfSSL_CTX_get_tlsext_ticket_keys(ctx, keys, sizeof(keys)),
|
||||
WOLFSSL_SUCCESS);
|
||||
AssertIntEQ(wolfSSL_CTX_set_tlsext_ticket_keys(ctx, keys, sizeof(keys)),
|
||||
WOLFSSL_SUCCESS);
|
||||
|
||||
wolfSSL_CTX_free(ctx);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef NO_BIO
|
||||
|
||||
@ -40312,6 +40358,7 @@ void ApiTest(void)
|
||||
test_wolfSSL_BIO_f_md();
|
||||
#endif
|
||||
test_wolfSSL_SESSION();
|
||||
test_wolfSSL_ticket_keys();
|
||||
test_wolfSSL_DES_ecb_encrypt();
|
||||
test_wolfSSL_sk_GENERAL_NAME();
|
||||
test_wolfSSL_MD4();
|
||||
|
@ -114,6 +114,15 @@
|
||||
#ifdef HAVE_CURVE448
|
||||
#include <wolfssl/wolfcrypt/curve448.h>
|
||||
#endif
|
||||
#ifndef WOLFSSL_NO_DEF_TICKET_ENC_CB
|
||||
#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) && \
|
||||
!defined(WOLFSSL_TICKET_ENC_AES128_GCM) && \
|
||||
!defined(WOLFSSL_TICKET_ENC_AES256_GCM)
|
||||
#include <wolfssl/wolfcrypt/chacha20_poly1305.h>
|
||||
#else
|
||||
#include <wolfssl/wolfcrypt/aes.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <wolfssl/wolfcrypt/wc_encrypt.h>
|
||||
#include <wolfssl/wolfcrypt/hash.h>
|
||||
@ -1585,6 +1594,26 @@ enum Misc {
|
||||
#define SESSION_TICKET_HINT_DEFAULT 300
|
||||
#endif
|
||||
|
||||
#if !defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) && !defined(WOLFSSL_NO_SERVER)
|
||||
/* Check chosen encryption is available. */
|
||||
#if !(defined(HAVE_CHACHA) && defined(HAVE_POLY1305)) && \
|
||||
defined(WOLFSSL_TICKET_ENC_CHACHA20_POLY1305)
|
||||
#error "ChaCha20-Poly1305 not availble for default ticket encryption"
|
||||
#endif
|
||||
#if !defined(HAVE_AESGCM) && (defined(WOLFSSL_TICKET_ENC_AES128_GCM) || \
|
||||
defined(WOLFSSL_TICKET_ENC_AES256_GCM))
|
||||
#error "AES-GCM not availble for default ticket encryption"
|
||||
#endif
|
||||
|
||||
#ifndef WOLFSSL_TICKET_KEY_LIFETIME
|
||||
/* 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 <= SESSION_TICKET_HINT_DEFAULT
|
||||
#error "Ticket Key lifetime must be longer than ticket life hint."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* don't use extra 3/4k stack space unless need to */
|
||||
#ifdef HAVE_NTRU
|
||||
@ -2473,6 +2502,28 @@ typedef struct SessionTicket {
|
||||
word16 size;
|
||||
} SessionTicket;
|
||||
|
||||
#if !defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) && !defined(WOLFSSL_NO_SERVER)
|
||||
|
||||
/* Data passed to default SessionTicket enc/dec callback. */
|
||||
typedef struct TicketEncCbCtx {
|
||||
/* Name for this context. */
|
||||
byte name[WOLFSSL_TICKET_NAME_SZ];
|
||||
/* Current keys - current and next. */
|
||||
byte key[2][WOLFSSL_TICKET_KEY_SZ];
|
||||
/* Expirary date of keys. */
|
||||
word32 expirary[2];
|
||||
/* Random number generator to use for generating name, keys and IV. */
|
||||
WC_RNG rng;
|
||||
#ifndef SINGLE_THREADED
|
||||
/* Mutex for access to changing keys. */
|
||||
wolfSSL_Mutex mutex;
|
||||
#endif
|
||||
/* Pointer back to SSL_CTX. */
|
||||
WOLFSSL_CTX* ctx;
|
||||
} TicketEncCbCtx;
|
||||
|
||||
#endif /* !WOLFSSL_NO_DEF_TICKET_ENC_CB && !WOLFSSL_NO_SERVER */
|
||||
|
||||
WOLFSSL_LOCAL int TLSX_UseSessionTicket(TLSX** extensions,
|
||||
SessionTicket* ticket, void* heap);
|
||||
WOLFSSL_LOCAL SessionTicket* TLSX_SessionTicket_Create(word32 lifetime,
|
||||
@ -2868,6 +2919,9 @@ struct WOLFSSL_CTX {
|
||||
SessionTicketEncCb ticketEncCb; /* enc/dec session ticket Cb */
|
||||
void* ticketEncCtx; /* session encrypt context */
|
||||
int ticketHint; /* ticket hint in seconds */
|
||||
#ifndef WOLFSSL_NO_DEF_TICKET_ENC_CB
|
||||
TicketEncCbCtx ticketKeyCtx;
|
||||
#endif
|
||||
#endif
|
||||
#ifdef HAVE_SUPPORTED_CURVES
|
||||
byte userCurves; /* indicates user called wolfSSL_CTX_UseSupportedCurve */
|
||||
|
@ -1069,6 +1069,9 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_
|
||||
|
||||
#define SSL_get_tlsext_status_exts wolfSSL_get_tlsext_status_exts
|
||||
|
||||
#define SSL_CTX_get_tlsext_ticket_keys wolfSSL_CTX_get_tlsext_ticket_keys
|
||||
#define SSL_CTX_set_tlsext_ticket_keys wolfSSL_CTX_set_tlsext_ticket_keys
|
||||
|
||||
#define SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS 11
|
||||
#define SSL_CTRL_GET_TOTAL_RENEGOTIATIONS 12
|
||||
#define SSL_CTRL_SET_TMP_DH 3
|
||||
|
@ -3193,6 +3193,22 @@ WOLFSSL_API long wolfSSL_SSL_get_secure_renegotiation_support(WOLFSSL* ssl);
|
||||
/* Session Ticket */
|
||||
#ifdef HAVE_SESSION_TICKET
|
||||
|
||||
#if !defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) && !defined(WOLFSSL_NO_SERVER)
|
||||
#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) && \
|
||||
!defined(WOLFSSL_TICKET_ENC_AES128_GCM) && \
|
||||
!defined(WOLFSSL_TICKET_ENC_AES256_GCM)
|
||||
#define WOLFSSL_TICKET_KEY_SZ CHACHA20_POLY1305_AEAD_KEYSIZE
|
||||
#elif defined(WOLFSSL_TICKET_ENC_AES256_GCM)
|
||||
#define WOLFSSL_TICKET_KEY_SZ AES_256_KEY_SIZE
|
||||
#else
|
||||
#define WOLFSSL_TICKET_KEY_SZ AES_128_KEY_SIZE
|
||||
#endif
|
||||
|
||||
#define WOLFSSL_TICKET_KEYS_SZ (WOLFSSL_TICKET_NAME_SZ + \
|
||||
2 * WOLFSSL_TICKET_KEY_SZ + \
|
||||
sizeof(word32) * 2)
|
||||
#endif
|
||||
|
||||
#ifndef NO_WOLFSSL_CLIENT
|
||||
WOLFSSL_API int wolfSSL_UseSessionTicket(WOLFSSL* ssl);
|
||||
WOLFSSL_API int wolfSSL_CTX_UseSessionTicket(WOLFSSL_CTX* ctx);
|
||||
@ -3987,6 +4003,14 @@ WOLFSSL_API int PEM_write_bio_WOLFSSL_X509(WOLFSSL_BIO *bio,
|
||||
#endif /* OPENSSL_ALL || WOLFSSL_NGINX || WOLFSSL_HAPROXY ||
|
||||
OPENSSL_EXTRA || HAVE_LIGHTY */
|
||||
|
||||
#if defined(HAVE_SESSION_TICKET) && !defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) && \
|
||||
!defined(NO_WOLFSSL_SERVER)
|
||||
WOLFSSL_API long wolfSSL_CTX_get_tlsext_ticket_keys(WOLFSSL_CTX *ctx,
|
||||
unsigned char *keys, int keylen);
|
||||
WOLFSSL_API long wolfSSL_CTX_set_tlsext_ticket_keys(WOLFSSL_CTX *ctx,
|
||||
unsigned char *keys, int keylen);
|
||||
#endif
|
||||
|
||||
WOLFSSL_API void wolfSSL_get0_alpn_selected(const WOLFSSL *ssl,
|
||||
const unsigned char **data, unsigned int *len);
|
||||
WOLFSSL_API int wolfSSL_select_next_proto(unsigned char **out,
|
||||
|
@ -3926,7 +3926,7 @@ static WC_INLINE const char* mymktemp(char *tempfn, int len, int num)
|
||||
|
||||
|
||||
|
||||
#if defined(HAVE_SESSION_TICKET) && \
|
||||
#if defined(HAVE_SESSION_TICKET) && defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) && \
|
||||
((defined(HAVE_CHACHA) && defined(HAVE_POLY1305)) || \
|
||||
defined(HAVE_AESGCM))
|
||||
|
||||
|
Reference in New Issue
Block a user