initial server side session ticket support

pull/72/head
toddouska 2015-05-15 12:51:44 -07:00
parent dcd6602293
commit f6d12bfc37
7 changed files with 421 additions and 21 deletions

View File

@ -64,6 +64,15 @@
int myHsDoneCb(WOLFSSL* ssl, void* user_ctx);
#endif
#if defined(HAVE_SESSION_TICKET) && defined(HAVE_CHACHA) && \
defined(HAVE_POLY1305)
#include <wolfssl/wolfcrypt/chacha20_poly1305.h>
static int TicketInit(void);
static int myTicketEncCb(WOLFSSL* ssl, byte key_name[16], byte iv[16],
byte mac[32], int enc, byte* ticket, int inLen,
int* outLen);
#endif
static void NonBlockingSSL_Accept(SSL* ssl)
{
@ -415,6 +424,13 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
if (ctx == NULL)
err_sys("unable to get ctx");
#if defined(HAVE_SESSION_TICKET) && defined(HAVE_CHACHA) && \
defined(HAVE_POLY1305)
if (TicketInit() != 0)
err_sys("unable to setup Session Ticket Key context");
wolfSSL_CTX_set_TicketEncCb(ctx, myTicketEncCb);
#endif
if (cipherList)
if (SSL_CTX_set_cipher_list(ctx, cipherList) != SSL_SUCCESS)
err_sys("server can't set cipher list 1");
@ -732,3 +748,84 @@ while (1) { /* allow resume option */
}
#endif
#if defined(HAVE_SESSION_TICKET) && defined(HAVE_CHACHA) && \
defined(HAVE_POLY1305)
typedef struct key_ctx {
byte name[WOLFSSL_TICKET_NAME_SZ]; /* name for this context */
byte key[16]; /* cipher key */
} key_ctx;
static key_ctx myKey_ctx;
static RNG rng;
static int TicketInit(void)
{
int ret = wc_InitRng(&rng);
if (ret != 0) return ret;
ret = wc_RNG_GenerateBlock(&rng, myKey_ctx.key, sizeof(myKey_ctx.key));
if (ret != 0) return ret;
ret = wc_RNG_GenerateBlock(&rng, myKey_ctx.name,sizeof(myKey_ctx.name));
if (ret != 0) return ret;
return 0;
}
static int myTicketEncCb(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)ssl;
int ret;
word16 sLen = htons(inLen);
byte aad[WOLFSSL_TICKET_NAME_SZ + WOLFSSL_TICKET_IV_SZ + 2];
int aadSz = WOLFSSL_TICKET_NAME_SZ + WOLFSSL_TICKET_IV_SZ + 2;
byte* tmp = aad;
if (enc) {
XMEMCPY(key_name, myKey_ctx.name, WOLFSSL_TICKET_NAME_SZ);
ret = wc_RNG_GenerateBlock(&rng, iv, WOLFSSL_TICKET_IV_SZ);
if (ret != 0) return ret;
/* build aad from key name, iv, and length */
XMEMCPY(tmp, key_name, WOLFSSL_TICKET_NAME_SZ);
tmp += WOLFSSL_TICKET_NAME_SZ;
XMEMCPY(tmp, iv, WOLFSSL_TICKET_IV_SZ);
tmp += WOLFSSL_TICKET_IV_SZ;
XMEMCPY(tmp, &sLen, 2);
ret = wc_ChaCha20Poly1305_Encrypt(myKey_ctx.key, iv,
aad, aadSz,
ticket, inLen,
ticket,
mac);
if (ret != 0) return ret;
*outLen = inLen; /* no padding in this mode */
} else {
/* decrypt */
/* build aad from key name, iv, and length */
XMEMCPY(tmp, key_name, WOLFSSL_TICKET_NAME_SZ);
tmp += WOLFSSL_TICKET_NAME_SZ;
XMEMCPY(tmp, iv, WOLFSSL_TICKET_IV_SZ);
tmp += WOLFSSL_TICKET_IV_SZ;
XMEMCPY(tmp, &sLen, 2);
ret = wc_ChaCha20Poly1305_Decrypt(myKey_ctx.key, iv,
aad, aadSz,
ticket, inLen,
mac,
ticket);
if (ret != 0) return ret;
*outLen = inLen; /* no padding in this mode */
}
return 0;
}
#endif

View File

@ -417,6 +417,10 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method)
}
#endif
#if defined(HAVE_SESSION_TICKET) && !defined(NO_WOLFSSL_SERVER)
ctx->ticketHint = SESSION_TICKET_HINT_DEFAULT;
#endif
return 0;
}
@ -4909,6 +4913,10 @@ static int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx,
if (ssl->keys.encryptionOn) {
*inOutIdx += ssl->keys.padSz;
}
if (ssl->options.resuming) {
WOLFSSL_MSG("Not resuming as thought");
ssl->options.resuming = 0;
}
break;
case finished:
@ -8007,6 +8015,12 @@ const char* wolfSSL_ERR_reason_error_string(unsigned long e)
case SOCKET_PEER_CLOSED_E:
return "Peer closed underlying transport Error";
case BAD_TICKET_KEY_CB_SZ:
return "Bad user session ticket key callback Size Error";
case BAD_TICKET_MSG_SZ:
return "Bad session ticket message Size Error";
default :
return "unknown error number";
}
@ -11339,6 +11353,7 @@ int DoSessionTicket(WOLFSSL* ssl,
word32 length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
int sendSz;
int ret;
byte sessIdSz = ID_LEN;
length = VERSION_SZ + RAN_LEN
+ ID_LEN + ENUM_LEN
@ -11347,6 +11362,14 @@ int DoSessionTicket(WOLFSSL* ssl,
#ifdef HAVE_TLS_EXTENSIONS
length += TLSX_GetResponseSize(ssl);
#ifdef HAVE_SESSION_TICKET
if (ssl->options.useTicket && ssl->arrays->sessionIDSz == 0) {
/* no session id */
length -= ID_LEN;
sessIdSz = 0;
}
#endif /* HAVE_SESSION_TICKET */
#endif
/* check for avalaible size */
@ -11392,17 +11415,19 @@ int DoSessionTicket(WOLFSSL* ssl,
}
#endif
/* then session id */
output[idx++] = ID_LEN;
output[idx++] = sessIdSz;
if (sessIdSz) {
if (!ssl->options.resuming) {
ret = wc_RNG_GenerateBlock(ssl->rng, ssl->arrays->sessionID, ID_LEN);
if (ret != 0)
return ret;
if (!ssl->options.resuming) {
ret = wc_RNG_GenerateBlock(ssl->rng, ssl->arrays->sessionID,
sessIdSz);
if (ret != 0) return ret;
}
XMEMCPY(output + idx, ssl->arrays->sessionID, sessIdSz);
idx += sessIdSz;
}
XMEMCPY(output + idx, ssl->arrays->sessionID, ID_LEN);
idx += ID_LEN;
/* then cipher suite */
output[idx++] = ssl->options.cipherSuite0;
output[idx++] = ssl->options.cipherSuite;
@ -13069,6 +13094,7 @@ int DoSessionTicket(WOLFSSL* ssl,
/* session id */
if (sessionSz) {
XMEMCPY(ssl->arrays->sessionID, input + idx, sessionSz);
ssl->arrays->sessionIDSz = (byte)sessionSz;
idx += sessionSz;
ssl->options.resuming = 1;
}
@ -13090,7 +13116,14 @@ int DoSessionTicket(WOLFSSL* ssl,
/* DoClientHello uses same resume code */
if (ssl->options.resuming) { /* let's try */
int ret = -1;
WOLFSSL_SESSION* session = GetSession(ssl,ssl->arrays->masterSecret);
WOLFSSL_SESSION* session = GetSession(ssl,
ssl->arrays->masterSecret);
#ifdef HAVE_SESSION_TICKET
if (ssl->options.useTicket == 1) {
session = &ssl->session;
}
#endif
if (!session) {
WOLFSSL_MSG("Session lookup for resume failed");
ssl->options.resuming = 0;
@ -13217,6 +13250,7 @@ int DoSessionTicket(WOLFSSL* ssl,
return BUFFER_ERROR;
XMEMCPY(ssl->arrays->sessionID, input + i, ID_LEN);
ssl->arrays->sessionIDSz = ID_LEN;
i += ID_LEN;
ssl->options.resuming = 1; /* client wants to resume */
WOLFSSL_MSG("Client wants to resume session");
@ -13379,7 +13413,13 @@ int DoSessionTicket(WOLFSSL* ssl,
if (ssl->options.resuming && (!ssl->options.dtls ||
ssl->options.acceptState == HELLO_VERIFY_SENT)) { /* let's try */
int ret = -1;
WOLFSSL_SESSION* session = GetSession(ssl,ssl->arrays->masterSecret);
WOLFSSL_SESSION* session = GetSession(ssl,
ssl->arrays->masterSecret);
#ifdef HAVE_SESSION_TICKET
if (ssl->options.useTicket == 1) {
session = &ssl->session;
}
#endif
if (!session) {
WOLFSSL_MSG("Session lookup for resume failed");
@ -13655,6 +13695,170 @@ int DoSessionTicket(WOLFSSL* ssl,
return SendBuffered(ssl);
}
#ifdef HAVE_SESSION_TICKET
#define WOLFSSL_TICKET_FIXED_SZ (WOLFSSL_TICKET_NAME_SZ + \
WOLFSSL_TICKET_IV_SZ + WOLFSSL_TICKET_MAC_SZ + LENGTH_SZ)
#define WOLFSSL_TICKET_ENC_SZ (SESSION_TICKET_LEN - WOLFSSL_TICKET_FIXED_SZ)
/* our ticket format */
typedef struct InternalTicket {
ProtocolVersion pv; /* version when ticket created */
byte suite[SUITE_LEN]; /* cipher suite when created */
byte msecret[SECRET_LEN]; /* master secret */
word32 timestamp; /* born on */
} InternalTicket;
/* fit within SESSION_TICKET_LEN */
typedef struct ExternalTicket {
byte key_name[WOLFSSL_TICKET_NAME_SZ]; /* key context name */
byte iv[WOLFSSL_TICKET_IV_SZ]; /* this ticket's iv */
byte enc_len[LENGTH_SZ]; /* encrypted length */
byte enc_ticket[WOLFSSL_TICKET_ENC_SZ]; /* encrypted internal ticket */
byte mac[WOLFSSL_TICKET_MAC_SZ]; /* total mac */
/* !! if add to structure, add to TICKET_FIXED_SZ !! */
} ExternalTicket;
/* create a new session ticket, 0 on success */
static int CreateTicket(WOLFSSL* ssl)
{
InternalTicket it;
ExternalTicket* et = (ExternalTicket*)ssl->session.ticket;
int encLen;
int ret;
/* build internal */
it.pv.major = ssl->version.major;
it.pv.minor = ssl->version.minor;
it.suite[0] = ssl->options.cipherSuite0;
it.suite[1] = ssl->options.cipherSuite;
XMEMCPY(it.msecret, ssl->arrays->masterSecret, SECRET_LEN);
c32toa(LowResTimer(), (byte*)&it.timestamp);
/* build external */
XMEMCPY(et->enc_ticket, &it, sizeof(InternalTicket));
/* encrypt */
encLen = WOLFSSL_TICKET_ENC_SZ; /* max size user can use */
ret = ssl->ctx->ticketEncCb(ssl, et->key_name, et->iv, et->mac, 1,
et->enc_ticket, sizeof(InternalTicket),
&encLen);
if (ret == 0) {
if (encLen < (int)sizeof(InternalTicket) ||
encLen > WOLFSSL_TICKET_ENC_SZ) {
WOLFSSL_MSG("Bad user ticket encrypt size");
return BAD_TICKET_KEY_CB_SZ;
}
c16toa(encLen, et->enc_len);
ssl->session.ticketLen = (word16)(encLen + WOLFSSL_TICKET_FIXED_SZ);
if (encLen < WOLFSSL_TICKET_ENC_SZ) {
/* move mac up since whole enc buffer not used */
XMEMMOVE(et->enc_ticket +encLen, et->mac,WOLFSSL_TICKET_MAC_SZ);
}
}
return ret;
}
/* Parse ticket sent by client */
int DoClientTicket(WOLFSSL* ssl, const byte* input, word32 len)
{
ExternalTicket* et;
InternalTicket* it;
int ret;
int outLen;
word16 inLen;
if (len > SESSION_TICKET_LEN ||
len < (word32)(sizeof(InternalTicket) + WOLFSSL_TICKET_FIXED_SZ)) {
return BAD_TICKET_MSG_SZ;
}
et = (ExternalTicket*)input;
it = (InternalTicket*)et->enc_ticket;
/* decrypt */
ato16(et->enc_len, &inLen);
if (inLen > (word16)(len - WOLFSSL_TICKET_FIXED_SZ)) {
return BAD_TICKET_MSG_SZ;
}
outLen = inLen; /* may be reduced by user padding */
ret = ssl->ctx->ticketEncCb(ssl, et->key_name, et->iv,
et->enc_ticket + inLen, 0,
et->enc_ticket, inLen, &outLen);
if (ret != 0) return ret;
if (outLen > inLen || outLen < (int)sizeof(InternalTicket)) {
WOLFSSL_MSG("Bad user ticket decrypt len");
return BAD_TICKET_KEY_CB_SZ;
}
/* get master secret */
XMEMCPY(ssl->arrays->masterSecret, it->msecret, SECRET_LEN);
return ret;
}
/* send Session Ticket */
int SendTicket(WOLFSSL* ssl)
{
byte* output;
int ret;
int sendSz;
word32 length = SESSION_HINT_SZ + LENGTH_SZ;
word32 idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
#ifdef WOLFSSL_DTLS
if (ssl->options.dtls) {
length += DTLS_RECORD_EXTRA;
idx += DTLS_RECORD_EXTRA;
}
#endif
if (ssl->options.createTicket) {
ret = CreateTicket(ssl);
if (ret != 0) return ret;
}
length += ssl->session.ticketLen;
sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
/* check for available size */
if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
return ret;
/* get ouput buffer */
output = ssl->buffers.outputBuffer.buffer +
ssl->buffers.outputBuffer.length;
AddHeaders(output, length, session_ticket, ssl);
/* hint */
c32toa(ssl->ctx->ticketHint, output + idx);
idx += SESSION_HINT_SZ;
/* length */
c16toa(ssl->session.ticketLen, output + idx);
idx += LENGTH_SZ;
/* ticket */
XMEMCPY(output + idx, ssl->session.ticket, ssl->session.ticketLen);
/* idx += ssl->session.ticketLen; */
ret = HashOutput(ssl, output, sendSz, 0);
if (ret != 0) return ret;
ssl->buffers.outputBuffer.length += sendSz;
return SendBuffered(ssl);
}
#endif /* HAVE_SESSION_TICKET */
#ifdef WOLFSSL_DTLS
int SendHelloVerifyRequest(WOLFSSL* ssl)
{

View File

@ -865,6 +865,21 @@ int wolfSSL_Rehandshake(WOLFSSL* ssl)
#endif /* HAVE_SECURE_RENEGOTIATION */
/* Session Ticket */
#if !defined(NO_WOLFSSL_SERVER) && defined(HAVE_SESSION_TICKET)
/* SSL_SUCCESS on ok */
int wolfSSL_CTX_set_TicketEncCb(WOLFSSL_CTX* ctx, SessionTicketEncCb cb)
{
if (ctx == NULL)
return BAD_FUNC_ARG;
ctx->ticketEncCb = cb;
return SSL_SUCCESS;
}
#endif /* !defined(NO_WOLFSSL_CLIENT) && defined(HAVE_SESSION_TICKET) */
/* Session Ticket */
#if !defined(NO_WOLFSSL_CLIENT) && defined(HAVE_SESSION_TICKET)
int wolfSSL_UseSessionTicket(WOLFSSL* ssl)
@ -5562,6 +5577,18 @@ int wolfSSL_dtls_got_timeout(WOLFSSL* ssl)
WOLFSSL_MSG("accept state ACCEPT_SECOND_REPLY_DONE");
case ACCEPT_SECOND_REPLY_DONE :
#ifdef HAVE_SESSION_TICKET
if (ssl->options.createTicket) {
if ( (ssl->error = SendTicket(ssl)) != 0) {
WOLFSSL_ERROR(ssl->error);
return SSL_FATAL_ERROR;
}
}
#endif /* HAVE_SESSION_TICKET */
ssl->options.acceptState = TICKET_SENT;
WOLFSSL_MSG("accept state TICKET_SENT");
case TICKET_SENT:
if ( (ssl->error = SendChangeCipher(ssl)) != 0) {
WOLFSSL_ERROR(ssl->error);
return SSL_FATAL_ERROR;
@ -5808,6 +5835,11 @@ WOLFSSL_SESSION* GetSession(WOLFSSL* ssl, byte* masterSecret)
if (ssl->options.haveSessionId == 0)
return NULL;
#ifdef HAVE_SESSION_TICKET
if (ssl->options.side == WOLFSSL_SERVER_END && ssl->options.useTicket == 1)
return NULL;
#endif
if (ssl->arrays)
id = ssl->arrays->sessionID;
else
@ -5896,6 +5928,11 @@ int AddSession(WOLFSSL* ssl)
if (ssl->options.haveSessionId == 0)
return 0;
#ifdef HAVE_SESSION_TICKET
if (ssl->options.side == WOLFSSL_SERVER_END && ssl->options.useTicket == 1)
return 0;
#endif
row = HashSession(ssl->arrays->sessionID, ID_LEN, &error) % SESSION_ROWS;
if (error != 0) {
WOLFSSL_MSG("Hash session failed");

View File

@ -1800,14 +1800,15 @@ static void TLSX_SessionTicket_ValidateRequest(WOLFSSL* ssl)
static word16 TLSX_SessionTicket_GetSize(SessionTicket* ticket, int isRequest)
{
return isRequest && ticket ? ticket->size : 0;
(void)isRequest;
return ticket ? ticket->size : 0;
}
static word16 TLSX_SessionTicket_Write(SessionTicket* ticket, byte* output,
int isRequest)
{
int offset = 0; /* empty ticket */
if (isRequest && ticket) {
XMEMCPY(output + offset, ticket->data, ticket->size);
offset += ticket->size;
@ -1820,18 +1821,44 @@ static word16 TLSX_SessionTicket_Write(SessionTicket* ticket, byte* output,
static int TLSX_SessionTicket_Parse(WOLFSSL* ssl, byte* input, word16 length,
byte isRequest)
{
int ret = 0;
if (!isRequest) {
/* client side */
if (length != 0)
return BUFFER_ERROR;
ssl->expect_session_ticket = 1;
}
#ifndef NO_WOLFSSL_SERVER
else {
/* TODO server side */
(void)input;
}
/* server side */
if (ssl->ctx->ticketEncCb == NULL) {
WOLFSSL_MSG("Client sent session ticket, server has no callback");
return 0;
}
return 0;
if (length == 0) {
/* blank ticket */
ret = TLSX_UseSessionTicket(&ssl->extensions, NULL);
if (ret == SSL_SUCCESS) {
ret = 0;
TLSX_SetResponse(ssl, SESSION_TICKET); /* send blank ticket */
ssl->options.createTicket = 1; /* will send ticket msg */
ssl->options.useTicket = 1;
}
} else {
/* got actual ticket from client */
ret = DoClientTicket(ssl, input, length);
if (ret == 0) { /* use ticket to resume */
ssl->options.useTicket = 1;
ssl->options.resuming = 1;
}
}
}
#endif /* NO_WOLFSSL_SERVER */
return ret;
}
WOLFSSL_LOCAL SessionTicket* TLSX_SessionTicket_Create(word32 lifetime,

View File

@ -129,6 +129,9 @@ enum wolfSSL_ErrorCodes {
SNI_UNSUPPORTED = -396, /* SSL 3.0 does not support SNI */
SOCKET_PEER_CLOSED_E = -397, /* Underlying transport closed */
BAD_TICKET_KEY_CB_SZ = -398, /* Bad session ticket key cb size */
BAD_TICKET_MSG_SZ = -399, /* Bad session ticket msg size */
/* add strings to SetErrorString !!!!! */
/* begin negotiation parameter errors */

View File

@ -764,6 +764,7 @@ enum Misc {
VERIFY_HEADER = 2, /* always use 2 bytes */
EXT_ID_SZ = 2, /* always use 2 bytes */
MAX_DH_SIZE = 513, /* 4096 bit plus possible leading 0 */
SESSION_HINT_SZ = 4, /* session timeout hint */
MAX_SUITE_SZ = 200, /* 100 suites for now! */
RAN_LEN = 32, /* random length */
@ -910,6 +911,10 @@ enum Misc {
#define SESSION_TICKET_LEN 256
#endif
#ifndef SESSION_TICKET_HINT_DEFAULT
#define SESSION_TICKET_HINT_DEFAULT 300
#endif
/* don't use extra 3/4k stack space unless need to */
#ifdef HAVE_NTRU
@ -1535,6 +1540,10 @@ struct WOLFSSL_CTX {
#endif
#ifdef HAVE_TLS_EXTENSIONS
TLSX* extensions; /* RFC 6066 TLS Extensions data */
#if defined(HAVE_SESSION_TICKET) && !defined(NO_WOLFSSL_SEVER)
SessionTicketEncCb ticketEncCb; /* enc/dec session ticket Cb */
int ticketHint; /* ticket hint in seconds */
#endif
#endif
#ifdef ATOMIC_USER
CallbackMacEncrypt MacEncryptCb; /* Atomic User Mac/Encrypt Cb */
@ -1797,6 +1806,7 @@ enum AcceptState {
CERT_REQ_SENT,
SERVER_HELLO_DONE,
ACCEPT_SECOND_REPLY_DONE,
TICKET_SENT,
CHANGE_CIPHER_SENT,
ACCEPT_FINISHED_DONE,
ACCEPT_THIRD_REPLY_DONE
@ -1889,7 +1899,11 @@ typedef struct Options {
#endif
#ifdef HAVE_ANON
word16 haveAnon:1; /* User wants to allow Anon suites */
#endif /* HAVE_ANON */
#endif
#ifdef HAVE_SESSION_TICKET
word16 createTicket:1; /* Server to create new Ticket */
word16 useTicket:1; /* Use Ticket not session cache */
#endif
/* need full byte values for this section */
byte processReply; /* nonblocking resume */
@ -2353,6 +2367,8 @@ static const byte tls_server[FINISHED_LABEL_SZ + 1] = "server finished";
/* internal functions */
WOLFSSL_LOCAL int SendChangeCipher(WOLFSSL*);
WOLFSSL_LOCAL int SendTicket(WOLFSSL*);
WOLFSSL_LOCAL int DoClientTicket(WOLFSSL*, const byte*, word32);
WOLFSSL_LOCAL int SendData(WOLFSSL*, const void*, int);
WOLFSSL_LOCAL int SendCertificate(WOLFSSL*);
WOLFSSL_LOCAL int SendCertificateRequest(WOLFSSL*);

View File

@ -1359,8 +1359,8 @@ WOLFSSL_API int wolfSSL_Rehandshake(WOLFSSL* ssl);
/* Session Ticket */
#ifdef HAVE_SESSION_TICKET
#ifndef NO_WOLFSSL_CLIENT
#ifndef NO_WOLFSSL_CLIENT
WOLFSSL_API int wolfSSL_UseSessionTicket(WOLFSSL* ssl);
WOLFSSL_API int wolfSSL_CTX_UseSessionTicket(WOLFSSL_CTX* ctx);
WOLFSSL_API int wolfSSL_get_SessionTicket(WOLFSSL*, unsigned char*, unsigned int*);
@ -1368,9 +1368,25 @@ WOLFSSL_API int wolfSSL_set_SessionTicket(WOLFSSL*, unsigned char*, unsigned int
typedef int (*CallbackSessionTicket)(WOLFSSL*, const unsigned char*, int, void*);
WOLFSSL_API int wolfSSL_set_SessionTicket_cb(WOLFSSL*,
CallbackSessionTicket, void*);
#endif /* NO_WOLFSSL_CLIENT */
#endif
#endif
#ifndef NO_WOLFSSL_SERVER
#define WOLFSSL_TICKET_NAME_SZ 16
#define WOLFSSL_TICKET_IV_SZ 16
#define WOLFSSL_TICKET_MAC_SZ 32
typedef int (*SessionTicketEncCb)(WOLFSSL*,
unsigned char key_name[WOLFSSL_TICKET_NAME_SZ],
unsigned char iv[WOLFSSL_TICKET_IV_SZ],
unsigned char mac[WOLFSSL_TICKET_MAC_SZ],
int enc, unsigned char*, int, int*);
WOLFSSL_API int wolfSSL_CTX_set_TicketEncCb(WOLFSSL_CTX* ctx,
SessionTicketEncCb);
#endif /* NO_WOLFSSL_SERVER */
#endif /* HAVE_SESSION_TICKET */
#define WOLFSSL_CRL_MONITOR 0x01 /* monitor this dir flag */
#define WOLFSSL_CRL_START_MON 0x02 /* start monitoring flag */