Merge pull request #1497 from SparkiDev/tls13_draft28

Tls13 draft28
This commit is contained in:
toddouska 2018-04-25 10:17:37 -07:00 committed by GitHub
commit 5c61810d4d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 1713 additions and 765 deletions

View File

@ -189,6 +189,50 @@ static void ShowVersions(void)
printf("\n");
}
#ifdef WOLFSSL_TLS13
static void SetKeyShare(WOLFSSL* ssl, int onlyKeyShare, int useX25519)
{
(void)useX25519;
WOLFSSL_START(WC_FUNC_CLIENT_KEY_EXCHANGE_SEND);
if (onlyKeyShare == 0 || onlyKeyShare == 2) {
#ifdef HAVE_CURVE25519
if (useX25519) {
int groups[1] = { WOLFSSL_ECC_X25519 };
if (wolfSSL_UseKeyShare(ssl, WOLFSSL_ECC_X25519) != WOLFSSL_SUCCESS)
err_sys("unable to use curve x25519");
if (wolfSSL_set_groups(ssl, groups, 1) != WOLFSSL_SUCCESS)
err_sys("unable to set groups: x25519");
}
else
#endif
{
#ifdef HAVE_ECC
#if defined(HAVE_ECC256) || defined(HAVE_ALL_CURVES)
int groups[1] = { WOLFSSL_ECC_SECP256R1 };
if (wolfSSL_UseKeyShare(ssl, WOLFSSL_ECC_SECP256R1)
!= WOLFSSL_SUCCESS) {
err_sys("unable to use curve secp256r1");
}
if (wolfSSL_set_groups(ssl, groups, 1) != WOLFSSL_SUCCESS)
err_sys("unable to set groups: secp256r1");
#endif
#endif
}
}
if (onlyKeyShare == 0 || onlyKeyShare == 1) {
#ifdef HAVE_FFDHE_2048
int groups[1] = { WOLFSSL_FFDHE_2048 };
if (wolfSSL_UseKeyShare(ssl, WOLFSSL_FFDHE_2048) != WOLFSSL_SUCCESS)
err_sys("unable to use DH 2048-bit parameters");
if (wolfSSL_set_groups(ssl, groups, 1) != WOLFSSL_SUCCESS)
err_sys("unable to set groups: DH 2048-bit");
#endif
}
WOLFSSL_END(WC_FUNC_CLIENT_KEY_EXCHANGE_SEND);
}
#endif
/* Measures average time to create, connect and disconnect a connection (TPS).
Benchmark = number of connections. */
static int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port,
@ -230,55 +274,21 @@ static int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port,
if (ssl == NULL)
err_sys("unable to get SSL object");
#ifndef NO_SESSION_CACHE
if (benchResume)
wolfSSL_set_session(ssl, benchSession);
#endif
#ifdef WOLFSSL_TLS13
if (version >= 4) {
if (!helloRetry) {
WOLFSSL_START(WC_FUNC_CLIENT_KEY_EXCHANGE_SEND);
if (onlyKeyShare == 0 || onlyKeyShare == 2) {
#ifdef HAVE_CURVE25519
if (useX25519) {
if (wolfSSL_UseKeyShare(ssl, WOLFSSL_ECC_X25519)
!= WOLFSSL_SUCCESS) {
err_sys("unable to use curve x25519");
}
}
else
#endif
#ifdef HAVE_ECC
#if defined(HAVE_ECC256) || defined(HAVE_ALL_CURVES)
if (wolfSSL_UseKeyShare(ssl, WOLFSSL_ECC_SECP256R1)
!= WOLFSSL_SUCCESS) {
err_sys("unable to use curve secp256r1");
}
else
#endif
#endif
{
}
}
if (onlyKeyShare == 0 || onlyKeyShare == 1) {
#ifdef HAVE_FFDHE_2048
if (wolfSSL_UseKeyShare(ssl, WOLFSSL_FFDHE_2048)
!= WOLFSSL_SUCCESS) {
err_sys("unable to use DH 2048-bit parameters");
}
#endif
}
WOLFSSL_END(WC_FUNC_CLIENT_KEY_EXCHANGE_SEND);
}
else {
else if (version >= 4) {
if (!helloRetry)
SetKeyShare(ssl, onlyKeyShare, useX25519);
else
wolfSSL_NoKeyShares(ssl);
}
}
#endif
tcp_connect(&sockfd, host, port, dtlsUDP, dtlsSCTP, ssl);
#ifndef NO_SESSION_CACHE
if (benchResume)
wolfSSL_set_session(ssl, benchSession);
#endif
if (wolfSSL_set_fd(ssl, sockfd) != WOLFSSL_SUCCESS) {
err_sys("error in setting fd");
}
@ -1198,7 +1208,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
#ifdef HAVE_MAX_FRAGMENT
maxFragment = atoi(myoptarg);
if (maxFragment < WOLFSSL_MFL_2_9 ||
maxFragment > WOLFSSL_MFL_2_13) {
maxFragment > WOLFSSL_MFL_2_13) {
Usage();
exit(MY_EX_USAGE);
}
@ -1804,6 +1814,10 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
!= WOLFSSL_SUCCESS) {
err_sys("unable to support secp256r1");
}
if (wolfSSL_CTX_UseSupportedCurve(ctx, WOLFSSL_ECC_SECP384R1)
!= WOLFSSL_SUCCESS) {
err_sys("unable to support secp384r1");
}
}
#endif /* HAVE_CURVE25519 && HAVE_SUPPORTED_CURVES */
@ -1896,7 +1910,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
#ifdef HAVE_CURVE25519
if (useX25519) {
if (wolfSSL_UseKeyShare(ssl, WOLFSSL_ECC_X25519)
!= WOLFSSL_SUCCESS) {
!= WOLFSSL_SUCCESS) {
err_sys("unable to use curve x25519");
}
}
@ -1904,13 +1918,13 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
#ifdef HAVE_ECC
#if defined(HAVE_ECC256) || defined(HAVE_ALL_CURVES)
if (wolfSSL_UseKeyShare(ssl, WOLFSSL_ECC_SECP256R1)
!= WOLFSSL_SUCCESS) {
!= WOLFSSL_SUCCESS) {
err_sys("unable to use curve secp256r1");
}
#endif
#if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)
if (wolfSSL_UseKeyShare(ssl, WOLFSSL_ECC_SECP384R1)
!= WOLFSSL_SUCCESS) {
!= WOLFSSL_SUCCESS) {
err_sys("unable to use curve secp384r1");
}
#endif
@ -2313,38 +2327,6 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
(void*)"resumed session");
#endif
#ifdef WOLFSSL_TLS13
if (!helloRetry) {
#ifdef HAVE_CURVE25519
if (useX25519) {
if (wolfSSL_UseKeyShare(ssl, WOLFSSL_ECC_X25519) != WOLFSSL_SUCCESS) {
err_sys("unable to use curve x25519");
}
}
#endif
#ifdef HAVE_ECC
if (wolfSSL_UseKeyShare(sslResume,
WOLFSSL_ECC_SECP256R1) != WOLFSSL_SUCCESS) {
err_sys("unable to use curve secp256r1");
}
#if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)
if (wolfSSL_UseKeyShare(sslResume,
WOLFSSL_ECC_SECP384R1) != WOLFSSL_SUCCESS) {
err_sys("unable to use curve secp384r1");
}
#endif
#endif
#ifdef HAVE_FFDHE_2048
if (wolfSSL_UseKeyShare(sslResume, WOLFSSL_FFDHE_2048) != WOLFSSL_SUCCESS) {
err_sys("unable to use DH 2048-bit parameters");
}
#endif
}
else {
wolfSSL_NoKeyShares(ssl);
}
#endif
#ifndef WOLFSSL_CALLBACKS
if (nonBlocking) {
wolfSSL_set_using_nonblock(sslResume, 1);
@ -2423,7 +2405,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
#else
timeout.tv_sec = DEFAULT_TIMEOUT_SEC;
timeout.tv_usec = 0;
ret = NonBlockingSSL_Connect(ssl); /* will keep retrying on timeout */
ret = NonBlockingSSL_Connect(sslResume); /* will keep retrying on timeout */
#endif
if (ret != WOLFSSL_SUCCESS) {
printf("wolfSSL_connect resume error %d, %s\n", err,

View File

@ -1210,10 +1210,10 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
#endif /* WOLFSSL_ASYNC_CRYPT */
#ifdef WOLFSSL_TLS13
if (noPskDheKe)
wolfSSL_CTX_no_dhe_psk(ctx);
if (noTicket)
wolfSSL_CTX_no_ticket_TLSv13(ctx);
if (noPskDheKe)
wolfSSL_CTX_no_dhe_psk(ctx);
if (noTicket)
wolfSSL_CTX_no_ticket_TLSv13(ctx);
#endif
while (1) {
@ -1341,30 +1341,45 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
if (onlyKeyShare == 2) {
if (useX25519 == 1) {
#ifdef HAVE_CURVE25519
int groups[1] = { WOLFSSL_ECC_X25519 };
if (wolfSSL_UseKeyShare(ssl, WOLFSSL_ECC_X25519)
!= WOLFSSL_SUCCESS) {
err_sys("unable to use curve x25519");
}
if (wolfSSL_set_groups(ssl, groups, 1) != WOLFSSL_SUCCESS) {
err_sys("unable to set groups: x25519");
}
#endif
}
else
{
#ifdef HAVE_ECC
#if defined(HAVE_ECC256) || defined(HAVE_ALL_CURVES)
if (wolfSSL_UseKeyShare(ssl, WOLFSSL_ECC_SECP256R1)
int groups[1] = { WOLFSSL_ECC_SECP256R1 };
if (wolfSSL_UseKeyShare(ssl, WOLFSSL_ECC_SECP256R1)
!= WOLFSSL_SUCCESS) {
err_sys("unable to use curve secp256r1");
}
err_sys("unable to use curve secp256r1");
}
if (wolfSSL_set_groups(ssl, groups, 1) != WOLFSSL_SUCCESS) {
err_sys("unable to set groups: secp256r1");
}
#endif
#endif
}
}
else if (onlyKeyShare == 1) {
#ifdef HAVE_FFDHE_2048
int groups[1] = { WOLFSSL_FFDHE_2048 };
if (wolfSSL_UseKeyShare(ssl, WOLFSSL_FFDHE_2048)
!= WOLFSSL_SUCCESS) {
err_sys("unable to use DH 2048-bit parameters");
}
if (wolfSSL_set_groups(ssl, groups, 1) != WOLFSSL_SUCCESS) {
err_sys("unable to set groups: DH 2048-bit");
}
#endif
}
WOLFSSL_END(WC_FUNC_CLIENT_KEY_EXCHANGE_DO);

View File

@ -421,6 +421,71 @@ if [ $RESULT -ne 0 ]; then
fi
echo ""
# TLS Downgrade server / TLS Downgrade client.
echo -e "\n\nTLS server and client able to downgrade but don't"
port=0
./examples/server/server -v d -R $ready_file -p $port &
server_pid=$!
create_port
./examples/client/client -v d -p $port
RESULT=$?
remove_ready_file
if [ $RESULT -ne 0 ]; then
echo -e "\n\nIssue with TLS not downgrading"
do_cleanup
exit 1
fi
echo ""
# TLS Downgrade server / TLS Downgrade client resumption.
echo -e "\n\nTLS server and client able to downgrade but don't and resume"
port=0
./examples/server/server -v d -r -R $ready_file -p $port &
server_pid=$!
create_port
./examples/client/client -v d -r -p $port
RESULT=$?
remove_ready_file
if [ $RESULT -ne 0 ]; then
echo -e "\n\nIssue with TLS not downgrading and resumption"
do_cleanup
exit 1
fi
echo ""
# TLS Downgrade server / TLS 1.2 client and resume.
echo -e "\n\nTLS server downgrade and resume"
port=0
./examples/server/server -v d -r -R $ready_file -p $port &
server_pid=$!
create_port
./examples/client/client -v 3 -r -p $port
RESULT=$?
remove_ready_file
if [ $RESULT -ne 0 ]; then
echo -e "\n\nIssue with TLS server downgrading and resumption"
do_cleanup
exit 1
fi
echo ""
# TLS 1.2 server / TLS downgrade client and resume.
echo -e "\n\nTLS client downgrade and resume"
port=0
./examples/server/server -v 3 -r -R $ready_file -p $port &
server_pid=$!
create_port
./examples/client/client -v d -r -p $port
RESULT=$?
remove_ready_file
if [ $RESULT -ne 0 ]; then
echo -e "\n\nIssue with TLS client downgrading and resumption"
do_cleanup
exit 1
fi
echo ""
# TLS Downgrade server / TLS Downgrade client.
# TLS 1.3 server / TLS 1.3 client send KeyUpdate before sending app data.
echo -e "\n\nTLS v1.3 KeyUpdate"
port=0

View File

@ -4465,6 +4465,11 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
#if defined(WOLFSSL_POST_HANDSHAKE_AUTH)
ssl->options.postHandshakeAuth = ctx->postHandshakeAuth;
#endif
if (ctx->numGroups > 0) {
XMEMCPY(ssl->group, ctx->group, sizeof(*ctx->group) * ctx->numGroups);
ssl->numGroups = ctx->numGroups;
}
#endif
#ifdef HAVE_TLS_EXTENSIONS
@ -9385,10 +9390,6 @@ exit_ppc:
ssl->nonblockarg = NULL;
#endif
#ifdef OPENSSL_EXTRA
ssl->options.serverState = SERVER_CERT_COMPLETE;
#endif
FreeKeyExchange(ssl);
return ret;
@ -9405,6 +9406,10 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx,
ret = ProcessPeerCerts(ssl, input, inOutIdx, size);
#ifdef OPENSSL_EXTRA
ssl->options.serverState = SERVER_CERT_COMPLETE;
#endif
WOLFSSL_LEAVE("DoCertificateVerify", ret);
WOLFSSL_END(WC_FUNC_CERTIFICATE_DO);
@ -11949,7 +11954,7 @@ int DoApplicationData(WOLFSSL* ssl, byte* input, word32* inOutIdx)
#endif
#ifdef WOLFSSL_EARLY_DATA
if (ssl->earlyData) {
if (ssl->earlyData != no_early_data) {
}
else
#endif
@ -11974,7 +11979,7 @@ int DoApplicationData(WOLFSSL* ssl, byte* input, word32* inOutIdx)
return BUFFER_ERROR;
}
#ifdef WOLFSSL_EARLY_DATA
if (ssl->earlyData) {
if (ssl->earlyData != no_early_data) {
if (ssl->earlyDataSz + dataSz > ssl->options.maxEarlyDataSz) {
SendAlert(ssl, alert_fatal, unexpected_message);
return WOLFSSL_FATAL_ERROR;
@ -12603,7 +12608,7 @@ int ProcessReply(WOLFSSL* ssl)
if (ssl->options.side == WOLFSSL_SERVER_END &&
ssl->earlyData &&
ssl->options.handShakeState == HANDSHAKE_DONE) {
ssl->earlyData = 0;
ssl->earlyData = no_early_data;
ssl->options.processReply = doProcessInit;
return ZERO_RETURN;
}
@ -14446,7 +14451,7 @@ int SendData(WOLFSSL* ssl, const void* data, int sz)
#endif /* WOLFSSL_DTLS */
#ifdef WOLFSSL_EARLY_DATA
if (ssl->earlyData) {
if (ssl->earlyData != no_early_data) {
if (ssl->options.handShakeState == HANDSHAKE_DONE) {
WOLFSSL_MSG("handshake complete, trying to send early data");
return BUILD_MSG_ERROR;
@ -14610,7 +14615,7 @@ int ReceiveData(WOLFSSL* ssl, byte* output, int sz, int peek)
}
#ifdef WOLFSSL_EARLY_DATA
if (ssl->earlyData) {
if (ssl->earlyData != no_early_data) {
}
else
#endif
@ -16858,31 +16863,26 @@ void PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo,
#endif
if (sigAlgo == ssl->suites->sigAlgo || (sigAlgo == rsa_pss_sa_algo &&
ssl->suites->sigAlgo == rsa_sa_algo)) {
if (hashAlgo == sha_mac) {
ssl->suites->sigAlgo = sigAlgo;
break;
}
switch (hashAlgo) {
case sha_mac:
#ifndef NO_SHA256
else if (hashAlgo == sha256_mac) {
ssl->suites->hashAlgo = sha256_mac;
ssl->suites->sigAlgo = sigAlgo;
break;
}
case sha256_mac:
#endif
#ifdef WOLFSSL_SHA384
else if (hashAlgo == sha384_mac) {
ssl->suites->hashAlgo = sha384_mac;
ssl->suites->sigAlgo = sigAlgo;
break;
}
case sha384_mac:
#endif
#ifdef WOLFSSL_SHA512
else if (hashAlgo == sha512_mac) {
ssl->suites->hashAlgo = sha512_mac;
ssl->suites->sigAlgo = sigAlgo;
break;
}
case sha512_mac:
#endif
if (hashAlgo < ssl->suites->hashAlgo)
continue;
ssl->suites->hashAlgo = hashAlgo;
ssl->suites->sigAlgo = sigAlgo;
break;
default:
continue;
}
break;
}
else if (ssl->specs.sig_algo == 0) {
ssl->suites->hashAlgo = ssl->specs.mac_algorithm;
@ -17408,6 +17408,7 @@ void PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo,
int CheckVersion(WOLFSSL *ssl, ProtocolVersion pv)
{
#ifdef WOLFSSL_TLS13
#ifndef WOLFSSL_TLS13_FINAL
/* TODO: [TLS13] Remove this.
* Translate the draft TLS v1.3 version to final version.
*/
@ -17415,6 +17416,7 @@ void PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo,
pv.major = SSLv3_MAJOR;
pv.minor = TLSv1_3_MINOR;
}
#endif
#endif
#ifdef OPENSSL_EXTRA
@ -17545,38 +17547,43 @@ void PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo,
return ret;
#ifdef WOLFSSL_TLS13
if (IsAtLeastTLSv1_3(pv))
return DoTls13ServerHello(ssl, input, inOutIdx, helloSz);
if (IsAtLeastTLSv1_3(pv)) {
byte type = server_hello;
return DoTls13ServerHello(ssl, input, inOutIdx, helloSz, &type);
}
#endif
/* random */
XMEMCPY(ssl->arrays->serverRandom, input + i, RAN_LEN);
i += RAN_LEN;
if (!ssl->options.resuming) {
#ifdef WOLFSSL_TLS13
if (IsAtLeastTLSv1_3(ssl->ctx->method->version)) {
/* TLS v1.3 capable client not allowed to downgrade when connecting
* to TLS v1.3 capable server.
*/
if (XMEMCMP(input + i - (TLS13_DOWNGRADE_SZ + 1),
tls13Downgrade, TLS13_DOWNGRADE_SZ) == 0 &&
if (IsAtLeastTLSv1_3(ssl->ctx->method->version)) {
/* TLS v1.3 capable client not allowed to downgrade when
* connecting to TLS v1.3 capable server unless cipher suite
* demands it.
*/
if (XMEMCMP(input + i - (TLS13_DOWNGRADE_SZ + 1),
tls13Downgrade, TLS13_DOWNGRADE_SZ) == 0 &&
(*(input + i - 1) == 0 || *(input + i - 1) == 1)) {
SendAlert(ssl, alert_fatal, illegal_parameter);
return VERSION_ERROR;
SendAlert(ssl, alert_fatal, illegal_parameter);
return VERSION_ERROR;
}
}
}
else
else
#endif
if (ssl->ctx->method->version.major == SSLv3_MAJOR &&
if (ssl->ctx->method->version.major == SSLv3_MAJOR &&
ssl->ctx->method->version.minor == TLSv1_2_MINOR) {
/* TLS v1.2 capable client not allowed to downgrade when connecting
* to TLS v1.2 capable server.
*/
if (XMEMCMP(input + i - (TLS13_DOWNGRADE_SZ + 1),
tls13Downgrade, TLS13_DOWNGRADE_SZ) == 0 &&
/* TLS v1.2 capable client not allowed to downgrade when
* connecting to TLS v1.2 capable server.
*/
if (XMEMCMP(input + i - (TLS13_DOWNGRADE_SZ + 1),
tls13Downgrade, TLS13_DOWNGRADE_SZ) == 0 &&
*(input + i - 1) == 0) {
SendAlert(ssl, alert_fatal, illegal_parameter);
return VERSION_ERROR;
SendAlert(ssl, alert_fatal, illegal_parameter);
return VERSION_ERROR;
}
}
}
@ -22992,7 +22999,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
#if defined(HAVE_SUPPORTED_CURVES) && defined(HAVE_ECC)
if (!TLSX_ValidateSupportedCurves(ssl, first, second)) {
WOLFSSL_MSG("Don't have matching curves");
return 0;
return 0;
}
#endif
@ -23005,7 +23012,8 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
ssl->options.haveQSH = 1; /* matched TLS_QSH */
}
else {
WOLFSSL_MSG("Version of SSL connection does not support TLS_QSH");
WOLFSSL_MSG("Version of SSL connection does not support "
"TLS_QSH");
}
return 0;
}
@ -23017,10 +23025,15 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
/* Try to establish a key share. */
int ret = TLSX_KeyShare_Establish(ssl);
if (ret == KEY_SHARE_ERROR)
ssl->options.serverState = SERVER_HELLO_RETRY_REQUEST;
ssl->options.serverState = SERVER_HELLO_RETRY_REQUEST_COMPLETE;
else if (ret != 0)
return 0;
}
else if (first == TLS13_BYTE) {
/* Can't negotiate TLS 1.3 ciphersuites with lower protocol
* version. */
return 0;
}
#endif
return 1;
@ -23296,6 +23309,76 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
#endif /* OLD_HELLO_ALLOWED */
int HandleTlsResumption(WOLFSSL* ssl, int bogusID, Suites* clSuites)
{
int ret = 0;
WOLFSSL_SESSION* session = GetSession(ssl,
ssl->arrays->masterSecret, 1);
(void)bogusID;
#ifdef HAVE_SESSION_TICKET
if (ssl->options.useTicket == 1) {
session = &ssl->session;
} else if (bogusID == 1 && ssl->options.rejectTicket == 0) {
WOLFSSL_MSG("Bogus session ID without session ticket");
return BUFFER_ERROR;
}
#endif
if (!session) {
WOLFSSL_MSG("Session lookup for resume failed");
ssl->options.resuming = 0;
}
else if (session->haveEMS != ssl->options.haveEMS) {
/* RFC 7627, 5.3, server-side */
/* if old sess didn't have EMS, but new does, full handshake */
if (!session->haveEMS && ssl->options.haveEMS) {
WOLFSSL_MSG("Attempting to resume a session that didn't "
"use EMS with a new session with EMS. Do full "
"handshake.");
ssl->options.resuming = 0;
}
/* if old sess used EMS, but new doesn't, MUST abort */
else if (session->haveEMS && !ssl->options.haveEMS) {
WOLFSSL_MSG("Trying to resume a session with EMS without "
"using EMS");
return EXT_MASTER_SECRET_NEEDED_E;
}
#ifdef HAVE_EXT_CACHE
wolfSSL_SESSION_free(session);
#endif
}
else {
#ifdef HAVE_EXT_CACHE
wolfSSL_SESSION_free(session);
#endif
if (MatchSuite(ssl, clSuites) < 0) {
WOLFSSL_MSG("Unsupported cipher suite, ClientHello");
return UNSUPPORTED_SUITE;
}
ret = wc_RNG_GenerateBlock(ssl->rng, ssl->arrays->serverRandom,
RAN_LEN);
if (ret != 0)
return ret;
#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
ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
}
return ret;
}
/* handle processing of client_hello (1) */
int DoClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
@ -23360,6 +23443,10 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
#endif /* WOLFSSL_DTLS */
i += OPAQUE16_LEN;
/* Legacy protocol version cannot negotiate TLS 1.3 or higher. */
if (pv.major == SSLv3_MAJOR && pv.minor >= TLSv1_3_MINOR)
pv.minor = TLSv1_2_MINOR;
if ((!ssl->options.dtls && ssl->version.minor > pv.minor) ||
(ssl->options.dtls && ssl->version.minor != DTLS_MINOR
&& ssl->version.minor != DTLSv1_2_MINOR && pv.minor != DTLS_MINOR
@ -23672,10 +23759,11 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
#ifdef HAVE_QSH
QSH_Init(ssl);
#endif
if (TLSX_SupportExtensions(ssl)) {
if (TLSX_SupportExtensions(ssl))
#else
if (IsAtLeastTLSv1_2(ssl)) {
if (IsAtLeastTLSv1_2(ssl))
#endif
{
/* Process the hello extension. Skip unsupported. */
word16 totalExtSz;
@ -23771,66 +23859,10 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
/* ProcessOld uses same resume code */
if (ssl->options.resuming) {
WOLFSSL_SESSION* session = GetSession(ssl,
ssl->arrays->masterSecret, 1);
#ifdef HAVE_SESSION_TICKET
if (ssl->options.useTicket == 1) {
session = &ssl->session;
} else if (bogusID == 1 && ssl->options.rejectTicket == 0) {
WOLFSSL_MSG("Bogus session ID without session ticket");
return BUFFER_ERROR;
}
#endif
if (!session) {
WOLFSSL_MSG("Session lookup for resume failed");
ssl->options.resuming = 0;
}
else if (session->haveEMS != ssl->options.haveEMS) {
/* RFC 7627, 5.3, server-side */
/* if old sess didn't have EMS, but new does, full handshake */
if (!session->haveEMS && ssl->options.haveEMS) {
WOLFSSL_MSG("Attempting to resume a session that didn't "
"use EMS with a new session with EMS. Do full "
"handshake.");
ssl->options.resuming = 0;
}
/* if old sess used EMS, but new doesn't, MUST abort */
else if (session->haveEMS && !ssl->options.haveEMS) {
WOLFSSL_MSG("Trying to resume a session with EMS without "
"using EMS");
return EXT_MASTER_SECRET_NEEDED_E;
}
#ifdef HAVE_EXT_CACHE
wolfSSL_SESSION_free(session);
#endif
}
else {
#ifdef HAVE_EXT_CACHE
wolfSSL_SESSION_free(session);
#endif
if (MatchSuite(ssl, &clSuites) < 0) {
WOLFSSL_MSG("Unsupported cipher suite, ClientHello");
return UNSUPPORTED_SUITE;
}
ret = wc_RNG_GenerateBlock(ssl->rng, ssl->arrays->serverRandom,
RAN_LEN);
if (ret != 0)
return ret;
#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
ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
ret = HandleTlsResumption(ssl, bogusID, &clSuites);
if (ret != 0)
return ret;
if (ssl->options.clientState == CLIENT_KEYEXCHANGE_COMPLETE) {
WOLFSSL_LEAVE("DoClientHello", ret);
WOLFSSL_END(WC_FUNC_CLIENT_HELLO_DO);
@ -24256,7 +24288,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
word16 haveEMS; /* have extended master secret */
#ifdef WOLFSSL_TLS13
word32 ageAdd; /* Obfuscation of age */
byte namedGroup; /* Named group used */
word16 namedGroup; /* Named group used */
#ifndef WOLFSSL_TLS13_DRAFT_18
TicketNonce ticketNonce; /* Ticket nonce */
#endif
@ -24307,7 +24339,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
#ifdef WOLFSSL_TLS13
/* Client adds to ticket age to obfuscate. */
ret = wc_RNG_GenerateBlock(ssl->rng, (byte*)&it.ageAdd,
sizeof(it.ageAdd));
sizeof(it.ageAdd));
if (ret != 0)
return BAD_TICKET_ENCRYPT;
ssl->session.ticketAdd = it.ageAdd;
@ -24416,6 +24448,23 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
/* get master secret */
if (ret == WOLFSSL_TICKET_RET_OK || ret == WOLFSSL_TICKET_RET_CREATE) {
if (ssl->version.minor < it->pv.minor) {
WOLFSSL_MSG("Ticket has greater version");
return VERSION_ERROR;
}
else if (ssl->version.minor > it->pv.minor) {
if (!ssl->options.downgrade) {
WOLFSSL_MSG("Ticket has lesser version");
return VERSION_ERROR;
}
WOLFSSL_MSG("Downgrading protocol due to ticket");
if (it->pv.minor < ssl->options.minDowngrade)
return VERSION_ERROR;
ssl->version.minor = it->pv.minor;
}
if (!IsAtLeastTLSv1_3(ssl->version)) {
XMEMCPY(ssl->arrays->masterSecret, it->msecret, SECRET_LEN);
/* Copy the haveExtendedMasterSecret property from the ticket to

View File

@ -1599,11 +1599,11 @@ int wolfSSL_write(WOLFSSL* ssl, const void* data, int sz)
return BAD_FUNC_ARG;
#ifdef WOLFSSL_EARLY_DATA
if (ssl->earlyData && (ret = wolfSSL_negotiate(ssl)) < 0) {
if (ssl->earlyData != no_early_data && (ret = wolfSSL_negotiate(ssl)) < 0) {
ssl->error = ret;
return WOLFSSL_FATAL_ERROR;
}
ssl->earlyData = 0;
ssl->earlyData = no_early_data;
#endif
#ifdef HAVE_WRITE_DUP
@ -8581,6 +8581,10 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
#endif
/* get response */
while (ssl->options.serverState < neededState) {
#ifdef WOLFSSL_TLS13
if (ssl->options.tls1_3)
return wolfSSL_connect_TLSv13(ssl);
#endif
if ( (ssl->error = ProcessReply(ssl)) < 0) {
WOLFSSL_ERROR(ssl->error);
return WOLFSSL_FATAL_ERROR;
@ -8635,13 +8639,14 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
/* get response */
while (ssl->options.serverState < neededState) {
if ( (ssl->error = ProcessReply(ssl)) < 0) {
WOLFSSL_ERROR(ssl->error);
return WOLFSSL_FATAL_ERROR;
WOLFSSL_ERROR(ssl->error);
return WOLFSSL_FATAL_ERROR;
}
/* if resumption failed, reset needed state */
else if (neededState == SERVER_FINISHED_COMPLETE)
if (neededState == SERVER_FINISHED_COMPLETE) {
if (!ssl->options.resuming)
neededState = SERVER_HELLODONE_COMPLETE;
}
}
}
#endif
@ -9759,9 +9764,13 @@ int AddSession(WOLFSSL* ssl)
session->cipherSuite = ssl->options.cipherSuite;
}
#endif /* SESSION_CERTS || (WOLFSSL_TLS13 & HAVE_SESSION_TICKET) */
#if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET)
#if defined(WOLFSSL_TLS13)
if (error == 0) {
session->namedGroup = ssl->session.namedGroup;
}
#endif
#if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET)
if (error == 0) {
session->ticketSeen = ssl->session.ticketSeen;
session->ticketAdd = ssl->session.ticketAdd;
#ifndef WOLFSSL_TLS13_DRAFT_18

856
src/tls.c

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -18145,6 +18145,8 @@ static int test_tls13_apis(void)
#ifdef WOLFSSL_EARLY_DATA
int outSz;
#endif
int groups[1] = { WOLFSSL_ECC_X25519 };
int numGroups = 1;
clientTls12Ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method());
clientTls12Ssl = wolfSSL_new(clientTls12Ctx);
@ -18248,6 +18250,38 @@ static int test_tls13_apis(void)
AssertIntEQ(wolfSSL_request_certificate(serverSsl), NOT_READY_ERROR);
#endif
#ifndef WOLFSSL_NO_SERVER_GROUPS_EXT
AssertIntEQ(wolfSSL_preferred_group(NULL), BAD_FUNC_ARG);
AssertIntEQ(wolfSSL_preferred_group(serverSsl), SIDE_ERROR);
AssertIntEQ(wolfSSL_preferred_group(clientTls12Ssl), BAD_FUNC_ARG);
AssertIntEQ(wolfSSL_preferred_group(clientSsl), NOT_READY_ERROR);
#endif
AssertIntEQ(wolfSSL_CTX_set_groups(NULL, NULL, 0), BAD_FUNC_ARG);
AssertIntEQ(wolfSSL_CTX_set_groups(clientCtx, NULL, 0), BAD_FUNC_ARG);
AssertIntEQ(wolfSSL_CTX_set_groups(NULL, groups, numGroups), BAD_FUNC_ARG);
AssertIntEQ(wolfSSL_CTX_set_groups(clientTls12Ctx, groups, numGroups),
BAD_FUNC_ARG);
AssertIntEQ(wolfSSL_CTX_set_groups(clientCtx, groups,
WOLFSSL_MAX_GROUP_COUNT + 1),
BAD_FUNC_ARG);
AssertIntEQ(wolfSSL_CTX_set_groups(clientCtx, groups, numGroups),
WOLFSSL_SUCCESS);
AssertIntEQ(wolfSSL_CTX_set_groups(serverCtx, groups, numGroups),
WOLFSSL_SUCCESS);
AssertIntEQ(wolfSSL_set_groups(NULL, NULL, 0), BAD_FUNC_ARG);
AssertIntEQ(wolfSSL_set_groups(clientSsl, NULL, 0), BAD_FUNC_ARG);
AssertIntEQ(wolfSSL_set_groups(NULL, groups, numGroups), BAD_FUNC_ARG);
AssertIntEQ(wolfSSL_set_groups(clientTls12Ssl, groups, numGroups),
BAD_FUNC_ARG);
AssertIntEQ(wolfSSL_set_groups(clientSsl, groups,
WOLFSSL_MAX_GROUP_COUNT + 1), BAD_FUNC_ARG);
AssertIntEQ(wolfSSL_set_groups(clientSsl, groups, numGroups),
WOLFSSL_SUCCESS);
AssertIntEQ(wolfSSL_set_groups(serverSsl, groups, numGroups),
WOLFSSL_SUCCESS);
#ifdef WOLFSSL_EARLY_DATA
AssertIntEQ(wolfSSL_CTX_set_max_early_data(NULL, 0), BAD_FUNC_ARG);
AssertIntEQ(wolfSSL_CTX_set_max_early_data(clientCtx, 0), SIDE_ERROR);

View File

@ -1,12 +1,12 @@
# server TLSv1.3 TLS13-CHACH20-POLY1305-SHA256
# server TLSv1.3 TLS13-CHACHA20-POLY1305-SHA256
-v 4
-l TLS13-CHACH20-POLY1305-SHA256
-l TLS13-CHACHA20-POLY1305-SHA256
-c ./certs/server-ecc.pem
-k ./certs/ecc-key.pem
# client TLSv1.3 TLS13-CHACH20-POLY1305-SHA256
# client TLSv1.3 TLS13-CHACHA20-POLY1305-SHA256
-v 4
-l TLS13-CHACH20-POLY1305-SHA256
-l TLS13-CHACHA20-POLY1305-SHA256
-A ./certs/ca-ecc-cert.pem
# server TLSv1.3 TLS13-AES128-GCM-SHA256
@ -58,6 +58,7 @@
-l TLS13-AES128-GCM-SHA256
-c ./certs/server-ecc.pem
-k ./certs/ecc-key.pem
-t
# client TLSv1.3 TLS13-AES128-GCM-SHA256
-v 4
@ -65,3 +66,16 @@
-A ./certs/ca-ecc-cert.pem
-t
# server TLSv1.3 TLS13-AES128-GCM-SHA256
-v 4
-l TLS13-AES128-GCM-SHA256
-c ./certs/server-ecc.pem
-k ./certs/ecc-key.pem
-Y
# client TLSv1.3 TLS13-AES128-GCM-SHA256
-v 4
-l TLS13-AES128-GCM-SHA256
-A ./certs/ca-ecc-cert.pem
-y

View File

@ -1,10 +1,10 @@
# server TLSv1.3 TLS13-CHACH20-POLY1305-SHA256
# server TLSv1.3 TLS13-CHACHA20-POLY1305-SHA256
-v 4
-l TLS13-CHACH20-POLY1305-SHA256
-l TLS13-CHACHA20-POLY1305-SHA256
# client TLSv1.3 TLS13-CHACH20-POLY1305-SHA256
# client TLSv1.3 TLS13-CHACHA20-POLY1305-SHA256
-v 4
-l TLS13-CHACH20-POLY1305-SHA256
-l TLS13-CHACHA20-POLY1305-SHA256
# server TLSv1.3 TLS13-AES128-GCM-SHA256
-v 4

View File

@ -1031,6 +1031,7 @@ enum Misc {
TLSv1_1_MINOR = 2, /* TLSv1_1 minor version number */
TLSv1_2_MINOR = 3, /* TLSv1_2 minor version number */
TLSv1_3_MINOR = 4, /* TLSv1_3 minor version number */
#ifndef WOLFSSL_TLS13_FINAL
TLS_DRAFT_MAJOR = 0x7f, /* Draft TLS major version number */
#ifdef WOLFSSL_TLS13_DRAFT_18
TLS_DRAFT_MINOR = 0x12, /* Minor version number of TLS draft */
@ -1039,7 +1040,8 @@ enum Misc {
#elif defined(WOLFSSL_TLS13_DRAFT_23)
TLS_DRAFT_MINOR = 0x17, /* Minor version number of TLS draft */
#else
TLS_DRAFT_MINOR = 0x1b, /* Minor version number of TLS draft */
TLS_DRAFT_MINOR = 0x1c, /* Minor version number of TLS draft */
#endif
#endif
OLD_HELLO_ID = 0x01, /* SSLv2 Client Hello Indicator */
INVALID_BYTE = 0xff, /* Used to initialize cipher specs values */
@ -1385,6 +1387,7 @@ enum states {
NULL_STATE = 0,
SERVER_HELLOVERIFYREQUEST_COMPLETE,
SERVER_HELLO_RETRY_REQUEST_COMPLETE,
SERVER_HELLO_COMPLETE,
SERVER_ENCRYPTED_EXTENSIONS_COMPLETE,
SERVER_CERT_COMPLETE,
@ -1392,7 +1395,6 @@ enum states {
SERVER_HELLODONE_COMPLETE,
SERVER_CHANGECIPHERSPEC_COMPLETE,
SERVER_FINISHED_COMPLETE,
SERVER_HELLO_RETRY_REQUEST,
CLIENT_HELLO_COMPLETE,
CLIENT_KEYEXCHANGE_COMPLETE,
@ -1470,6 +1472,8 @@ struct WOLFSSL_METHOD {
/* wolfSSL buffer type - internal uses "buffer" type */
typedef WOLFSSL_BUFFER_INFO buffer;
typedef struct Suites Suites;
/* defaults to client */
WOLFSSL_LOCAL void InitSSL_Method(WOLFSSL_METHOD*, ProtocolVersion);
@ -1479,6 +1483,8 @@ WOLFSSL_LOCAL int DoFinished(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
word32 size, word32 totalSz, int sniff);
WOLFSSL_LOCAL int DoApplicationData(WOLFSSL* ssl, byte* input, word32* inOutIdx);
/* TLS v1.3 needs these */
WOLFSSL_LOCAL int HandleTlsResumption(WOLFSSL* ssl, int bogusID,
Suites* clSuites);
WOLFSSL_LOCAL int DoClientHello(WOLFSSL* ssl, const byte* input, word32*,
word32);
#ifdef WOLFSSL_TLS13
@ -1518,7 +1524,8 @@ WOLFSSL_LOCAL int DoTls13HandShakeMsgType(WOLFSSL* ssl, byte* input,
WOLFSSL_LOCAL int DoTls13HandShakeMsg(WOLFSSL* ssl, byte* input,
word32* inOutIdx, word32 totalSz);
WOLFSSL_LOCAL int DoTls13ServerHello(WOLFSSL* ssl, const byte* input,
word32* inOutIdx, word32 helloSz);
word32* inOutIdx, word32 helloSz,
byte* extMsgType);
#endif
@ -1599,7 +1606,7 @@ typedef struct {
} bufferStatic;
/* Cipher Suites holder */
typedef struct Suites {
struct Suites {
word16 suiteSz; /* suite length in bytes */
word16 hashSigAlgoSz; /* SigAlgo extension length in bytes */
byte suites[WOLFSSL_MAX_SUITE_SZ];
@ -1607,7 +1614,7 @@ typedef struct Suites {
byte setSuites; /* user set suites from default */
byte hashAlgo; /* selected hash algorithm */
byte sigAlgo; /* selected sig algorithm */
} Suites;
};
WOLFSSL_LOCAL void InitSuitesHashSigAlgo(Suites* suites, int haveECDSAsig,
@ -1940,6 +1947,7 @@ typedef struct TLSX {
} TLSX;
WOLFSSL_LOCAL TLSX* TLSX_Find(TLSX* list, TLSX_Type type);
WOLFSSL_LOCAL void TLSX_Remove(TLSX** list, TLSX_Type type, void* heap);
WOLFSSL_LOCAL void TLSX_FreeAll(TLSX* list, void* heap);
WOLFSSL_LOCAL int TLSX_SupportExtensions(WOLFSSL* ssl);
WOLFSSL_LOCAL int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isRequest);
@ -2105,6 +2113,9 @@ WOLFSSL_LOCAL int TLSX_UsePointFormat(TLSX** extensions, byte point,
#ifndef NO_WOLFSSL_SERVER
WOLFSSL_LOCAL int TLSX_ValidateSupportedCurves(WOLFSSL* ssl, byte first,
byte second);
WOLFSSL_LOCAL int TLSX_SupportedCurve_CheckPriority(WOLFSSL* ssl);
WOLFSSL_LOCAL int TLSX_SupportedCurve_Preferred(WOLFSSL* ssl,
int checkSupported);
#endif
#endif /* HAVE_SUPPORTED_CURVES */
@ -2425,6 +2436,10 @@ struct WOLFSSL_CTX {
wc_psk_server_callback server_psk_cb; /* server callback */
char server_hint[MAX_PSK_ID_LEN + NULL_TERM_LEN];
#endif /* HAVE_SESSION_TICKET || !NO_PSK */
#ifdef WOLFSSL_TLS13
word16 group[WOLFSSL_MAX_GROUP_COUNT];
byte numGroups;
#endif
#ifdef WOLFSSL_EARLY_DATA
word32 maxEarlyDataSz;
#endif
@ -2778,9 +2793,11 @@ struct WOLFSSL_SESSION {
byte sessionCtxSz; /* sessionCtx length */
byte sessionCtx[ID_LEN]; /* app specific context id */
#endif
#ifdef WOLFSSL_TLS13
word16 namedGroup;
#endif
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
#ifdef WOLFSSL_TLS13
byte namedGroup;
word32 ticketSeen; /* Time ticket seen (ms) */
word32 ticketAdd; /* Added by client */
#ifndef WOLFSSL_TLS13_DRAFT_18
@ -3065,8 +3082,12 @@ typedef struct Options {
byte verifyDepth; /* maximum verification depth */
#endif
#ifdef WOLFSSL_EARLY_DATA
word16 pskIdIndex;
word32 maxEarlyDataSz;
#endif
#ifdef WOLFSSL_TLS13
byte oldMinor; /* client preferred version < TLS 1.3 */
#endif
} Options;
typedef struct Arrays {
@ -3362,6 +3383,15 @@ struct CertReqCtx {
};
#endif
#ifdef WOLFSSL_EARLY_DATA
typedef enum EarlyDataState {
no_early_data,
expecting_early_data,
process_early_data,
done_early_data
} EarlyDataState;
#endif
/* wolfSSL ssl type */
struct WOLFSSL {
WOLFSSL_CTX* ctx;
@ -3453,6 +3483,8 @@ struct WOLFSSL {
#endif
#ifdef WOLFSSL_TLS13
word16 namedGroup;
word16 group[WOLFSSL_MAX_GROUP_COUNT];
byte numGroups;
#endif
byte pssAlgo;
#ifdef WOLFSSL_TLS13
@ -3641,7 +3673,7 @@ struct WOLFSSL {
void* jObjectRef; /* reference to WolfSSLSession in JNI wrapper */
#endif /* WOLFSSL_JNI */
#ifdef WOLFSSL_EARLY_DATA
int earlyData;
EarlyDataState earlyData;
word32 earlyDataSz;
#endif
};

View File

@ -402,6 +402,8 @@ enum AlertLevel {
/* Maximum master key length (SECRET_LEN) */
#define WOLFSSL_MAX_MASTER_KEY_LENGTH 48
/* Maximum number of groups that can be set */
#define WOLFSSL_MAX_GROUP_COUNT 10
typedef WOLFSSL_METHOD* (*wolfSSL_method_func)(void* heap);
WOLFSSL_API WOLFSSL_METHOD *wolfSSLv3_server_method_ex(void* heap);
@ -558,6 +560,11 @@ WOLFSSL_API int wolfSSL_CTX_allow_post_handshake_auth(WOLFSSL_CTX* ctx);
WOLFSSL_API int wolfSSL_allow_post_handshake_auth(WOLFSSL* ssl);
WOLFSSL_API int wolfSSL_request_certificate(WOLFSSL* ssl);
WOLFSSL_API int wolfSSL_preferred_group(WOLFSSL* ssl);
WOLFSSL_API int wolfSSL_CTX_set_groups(WOLFSSL_CTX* ctx, int* groups,
int count);
WOLFSSL_API int wolfSSL_set_groups(WOLFSSL* ssl, int* groups, int count);
WOLFSSL_API int wolfSSL_connect_TLSv13(WOLFSSL*);
WOLFSSL_API int wolfSSL_accept_TLSv13(WOLFSSL*);
@ -581,12 +588,11 @@ WOLFSSL_API void wolfSSL_set_quiet_shutdown(WOLFSSL*, int);
WOLFSSL_API int wolfSSL_get_error(WOLFSSL*, int);
WOLFSSL_API int wolfSSL_get_alert_history(WOLFSSL*, WOLFSSL_ALERT_HISTORY *);
WOLFSSL_API int wolfSSL_set_session(WOLFSSL* ssl,WOLFSSL_SESSION* session);
WOLFSSL_API long wolfSSL_SSL_SESSION_set_timeout(WOLFSSL_SESSION* session, long t);
WOLFSSL_API WOLFSSL_SESSION* wolfSSL_get_session(WOLFSSL* ssl);
WOLFSSL_API void wolfSSL_flush_sessions(WOLFSSL_CTX *ctx, long tm);
WOLFSSL_API int wolfSSL_SetServerID(WOLFSSL* ssl, const unsigned char*,
int, int);
WOLFSSL_API int wolfSSL_set_session(WOLFSSL*, WOLFSSL_SESSION*);
WOLFSSL_API long wolfSSL_SSL_SESSION_set_timeout(WOLFSSL_SESSION*, long);
WOLFSSL_API WOLFSSL_SESSION* wolfSSL_get_session(WOLFSSL*);
WOLFSSL_API void wolfSSL_flush_sessions(WOLFSSL_CTX*, long);
WOLFSSL_API int wolfSSL_SetServerID(WOLFSSL*, const unsigned char*, int, int);
#ifdef SESSION_INDEX
WOLFSSL_API int wolfSSL_GetSessionIndex(WOLFSSL* ssl);