mirror of https://github.com/wolfSSL/wolfssl.git
Merge pull request #2299 from JacobBarthelmeh/DTLS-MultiCore
DTLS export/import state onlypull/2335/head
commit
2a4b935e07
135
src/internal.c
135
src/internal.c
|
@ -1131,6 +1131,64 @@ static int ImportPeerInfo(WOLFSSL* ssl, byte* buf, word32 len, byte ver)
|
|||
}
|
||||
|
||||
|
||||
/* WOLFSSL_LOCAL function that serializes the current WOLFSSL session state only
|
||||
* buf is used to hold the serialized WOLFSSL struct and sz is the size of buf
|
||||
* passed in.
|
||||
* On success returns the size of serialized session state.*/
|
||||
int wolfSSL_dtls_export_state_internal(WOLFSSL* ssl, byte* buf, word32 sz)
|
||||
{
|
||||
int ret;
|
||||
word32 idx = 0;
|
||||
word32 totalLen = 0;
|
||||
|
||||
WOLFSSL_ENTER("wolfSSL_dtls_export_state_internal");
|
||||
|
||||
if (buf == NULL || ssl == NULL) {
|
||||
WOLFSSL_LEAVE("wolfSSL_dtls_export_state_internal", BAD_FUNC_ARG);
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
totalLen += DTLS_EXPORT_LEN * 2; /* 2 protocol bytes and 2 length bytes */
|
||||
/* each of the following have a 2 byte length before data */
|
||||
totalLen += DTLS_EXPORT_LEN + DTLS_EXPORT_KEY_SZ;
|
||||
if (totalLen > sz) {
|
||||
WOLFSSL_LEAVE("wolfSSL_dtls_export_state_internal", BUFFER_E);
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
buf[idx++] = (byte)DTLS_EXPORT_STATE_PRO;
|
||||
buf[idx++] = ((byte)DTLS_EXPORT_STATE_PRO & 0xF0) |
|
||||
((byte)DTLS_EXPORT_VERSION & 0X0F);
|
||||
idx += DTLS_EXPORT_LEN; /* leave room for total length */
|
||||
|
||||
/* export keys struct and dtls state -- variable length stored in ret */
|
||||
idx += DTLS_EXPORT_LEN; /* leave room for length */
|
||||
if ((ret = ExportKeyState(ssl, buf + idx, sz - idx,
|
||||
DTLS_EXPORT_VERSION)) < 0) {
|
||||
WOLFSSL_LEAVE("wolfSSL_dtls_export_state_internal", ret);
|
||||
return ret;
|
||||
}
|
||||
c16toa((word16)ret, buf + idx - DTLS_EXPORT_LEN); idx += ret;
|
||||
|
||||
/* place total length of exported buffer minus 2 bytes protocol/version */
|
||||
c16toa((word16)(idx - DTLS_EXPORT_LEN), buf + DTLS_EXPORT_LEN);
|
||||
|
||||
#ifdef WOLFSSL_SESSION_EXPORT_DEBUG
|
||||
/* if compiled with debug options then print the version, protocol, size */
|
||||
{
|
||||
char debug[256];
|
||||
XSNPRINTF(debug, sizeof(debug), "Exporting DTLS session state\n"
|
||||
"\tVersion : %d\n\tProtocol : %02X%01X\n\tLength of: %d\n\n"
|
||||
, (int)DTLS_EXPORT_VERSION, buf[0], (buf[1] >> 4), idx - 2);
|
||||
WOLFSSL_MSG(debug);
|
||||
}
|
||||
#endif /* WOLFSSL_SESSION_EXPORT_DEBUG */
|
||||
|
||||
WOLFSSL_LEAVE("wolfSSL_dtls_export_state_internal", idx);
|
||||
return idx;
|
||||
}
|
||||
|
||||
|
||||
/* WOLFSSL_LOCAL function that serializes the current WOLFSSL session
|
||||
* buf is used to hold the serialized WOLFSSL struct and sz is the size of buf
|
||||
* passed in.
|
||||
|
@ -1221,6 +1279,78 @@ int wolfSSL_dtls_export_internal(WOLFSSL* ssl, byte* buf, word32 sz)
|
|||
}
|
||||
|
||||
|
||||
/* On success return amount of buffer consumed */
|
||||
int wolfSSL_dtls_import_state_internal(WOLFSSL* ssl, byte* buf, word32 sz)
|
||||
{
|
||||
word32 idx = 0;
|
||||
word16 length = 0;
|
||||
int version;
|
||||
int ret;
|
||||
|
||||
WOLFSSL_ENTER("wolfSSL_dtls_import_state_internal");
|
||||
/* check at least enough room for protocol and length */
|
||||
if (sz < DTLS_EXPORT_LEN * 2 || ssl == NULL) {
|
||||
WOLFSSL_LEAVE("wolfSSL_dtls_import_state_internal", BAD_FUNC_ARG);
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (buf[idx++] != (byte)DTLS_EXPORT_STATE_PRO ||
|
||||
(buf[idx] & 0xF0) != ((byte)DTLS_EXPORT_PRO & 0xF0)) {
|
||||
WOLFSSL_MSG("Incorrect protocol");
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
version = buf[idx++] & 0x0F;
|
||||
|
||||
ato16(buf + idx, &length); idx += DTLS_EXPORT_LEN;
|
||||
if (length > sz - DTLS_EXPORT_LEN) { /* subtract 2 for protocol */
|
||||
WOLFSSL_MSG("Buffer size sanity check failed");
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_SESSION_EXPORT_DEBUG
|
||||
/* if compiled with debug options then print the version, protocol, size */
|
||||
{
|
||||
char debug[256];
|
||||
XSNPRINTF(debug, sizeof(debug), "Importing DTLS session state\n"
|
||||
"\tVersion : %d\n\tProtocol : %02X%01X\n\tLength of: %d\n\n"
|
||||
, (int)version, buf[0], (buf[1] >> 4), length);
|
||||
WOLFSSL_MSG(debug);
|
||||
}
|
||||
#endif /* WOLFSSL_SESSION_EXPORT_DEBUG */
|
||||
|
||||
/* perform sanity checks and extract Options information used */
|
||||
switch (version) {
|
||||
case DTLS_EXPORT_VERSION:
|
||||
break;
|
||||
|
||||
default:
|
||||
WOLFSSL_MSG("Bad export state version");
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
}
|
||||
|
||||
/* perform sanity checks and extract Keys struct */
|
||||
if (DTLS_EXPORT_LEN + idx > sz) {
|
||||
WOLFSSL_MSG("Import Key struct error");
|
||||
return BUFFER_E;
|
||||
}
|
||||
ato16(buf + idx, &length); idx += DTLS_EXPORT_LEN;
|
||||
if (length > DTLS_EXPORT_KEY_SZ || length + idx > sz) {
|
||||
WOLFSSL_MSG("Import Key struct error");
|
||||
return BUFFER_E;
|
||||
}
|
||||
if ((ret = ImportKeyState(ssl, buf + idx, length, version)) < 0) {
|
||||
WOLFSSL_MSG("Import Key struct error");
|
||||
WOLFSSL_LEAVE("wolfSSL_dtls_import_state_internal", ret);
|
||||
return ret;
|
||||
}
|
||||
idx += ret;
|
||||
|
||||
WOLFSSL_LEAVE("wolfSSL_dtls_import_state_internal", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* On success return amount of buffer consumed */
|
||||
int wolfSSL_dtls_import_internal(WOLFSSL* ssl, byte* buf, word32 sz)
|
||||
{
|
||||
|
@ -1240,8 +1370,9 @@ int wolfSSL_dtls_import_internal(WOLFSSL* ssl, byte* buf, word32 sz)
|
|||
if (buf[idx++] != (byte)DTLS_EXPORT_PRO ||
|
||||
(buf[idx] & 0xF0) != ((byte)DTLS_EXPORT_PRO & 0xF0)) {
|
||||
/* don't increment on second idx to next get version */
|
||||
WOLFSSL_MSG("Incorrect protocol");
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
/* check if importing state only */
|
||||
return wolfSSL_dtls_import_state_internal(ssl, buf, sz);
|
||||
}
|
||||
version = buf[idx++] & 0x0F;
|
||||
|
||||
|
|
37
src/ssl.c
37
src/ssl.c
|
@ -160,7 +160,7 @@ int wolfSSL_dtls_set_export(WOLFSSL* ssl, wc_dtls_export func)
|
|||
/* This function allows for directly serializing a session rather than using
|
||||
* callbacks. It has less overhead by removing a temporary buffer and gives
|
||||
* control over when the session gets serialized. When using callbacks the
|
||||
* session is always serialized immediatly after the handshake is finished.
|
||||
* session is always serialized immediately after the handshake is finished.
|
||||
*
|
||||
* buf is the argument to contain the serialized session
|
||||
* sz is the size of the buffer passed in
|
||||
|
@ -191,6 +191,41 @@ int wolfSSL_dtls_export(WOLFSSL* ssl, unsigned char* buf, unsigned int* sz)
|
|||
}
|
||||
|
||||
|
||||
/* This function is similar to wolfSSL_dtls_export but only exports the portion
|
||||
* of the WOLFSSL structure related to the state of the connection, i.e. peer
|
||||
* sequence number, epoch, AEAD state etc.
|
||||
*
|
||||
* buf is the argument to contain the serialized state, if null then set "sz" to
|
||||
* buffer size required
|
||||
* sz is the size of the buffer passed in
|
||||
* ssl is the WOLFSSL struct to serialize
|
||||
* returns the size of serialized session on success, 0 on no action, and
|
||||
* negative value on error */
|
||||
int wolfSSL_dtls_export_state_only(WOLFSSL* ssl, unsigned char* buf,
|
||||
unsigned int* sz)
|
||||
{
|
||||
WOLFSSL_ENTER("wolfSSL_dtls_export_state_only");
|
||||
|
||||
if (ssl == NULL || sz == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (buf == NULL) {
|
||||
*sz = MAX_EXPORT_STATE_BUFFER;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* if not DTLS do nothing */
|
||||
if (!ssl->options.dtls) {
|
||||
WOLFSSL_MSG("Currently only DTLS export state is supported");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* copy over keys, options, and dtls state struct */
|
||||
return wolfSSL_dtls_export_state_internal(ssl, buf, *sz);
|
||||
}
|
||||
|
||||
|
||||
/* returns 0 on success */
|
||||
int wolfSSL_send_session(WOLFSSL* ssl)
|
||||
{
|
||||
|
|
181
tests/api.c
181
tests/api.c
|
@ -1840,6 +1840,75 @@ static int test_export(WOLFSSL* inSsl, byte* buf, word32 sz, void* userCtx)
|
|||
#endif
|
||||
|
||||
#if !defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER)
|
||||
#ifdef WOLFSSL_SESSION_EXPORT
|
||||
/* returns negative value on fail and positive (including 0) on success */
|
||||
static int nonblocking_accept_read(void* args, WOLFSSL* ssl, SOCKET_T* sockfd)
|
||||
{
|
||||
int ret, err, loop_count, count, timeout = 10;
|
||||
char msg[] = "I hear you fa shizzle!";
|
||||
char input[1024];
|
||||
|
||||
loop_count = ((func_args*)args)->argc;
|
||||
do {
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
if (err == WC_PENDING_E) {
|
||||
ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
|
||||
if (ret < 0) { break; } else if (ret == 0) { continue; }
|
||||
}
|
||||
#endif
|
||||
|
||||
err = 0; /* Reset error */
|
||||
|
||||
ret = wolfSSL_accept(ssl);
|
||||
if (ret != WOLFSSL_SUCCESS) {
|
||||
err = wolfSSL_get_error(ssl, 0);
|
||||
if (err == WOLFSSL_ERROR_WANT_READ ||
|
||||
err == WOLFSSL_ERROR_WANT_WRITE) {
|
||||
int select_ret;
|
||||
|
||||
err = WC_PENDING_E;
|
||||
select_ret = tcp_select(*sockfd, timeout);
|
||||
if (select_ret == TEST_TIMEOUT) {
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (ret != WOLFSSL_SUCCESS && err == WC_PENDING_E);
|
||||
|
||||
if (ret != WOLFSSL_SUCCESS) {
|
||||
char buff[WOLFSSL_MAX_ERROR_SZ];
|
||||
printf("error = %d, %s\n", err, wolfSSL_ERR_error_string(err, buff));
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (count = 0; count < loop_count; count++) {
|
||||
int select_ret;
|
||||
|
||||
select_ret = tcp_select(*sockfd, timeout);
|
||||
if (select_ret == TEST_TIMEOUT) {
|
||||
ret = WOLFSSL_FATAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
do {
|
||||
ret = wolfSSL_read(ssl, input, sizeof(input)-1);
|
||||
if (ret > 0) {
|
||||
input[ret] = '\0';
|
||||
printf("Client message: %s\n", input);
|
||||
}
|
||||
} while (err == WOLFSSL_ERROR_WANT_READ && ret != WOLFSSL_SUCCESS);
|
||||
|
||||
do {
|
||||
if ((ret = wolfSSL_write(ssl, msg, sizeof(msg))) != sizeof(msg)) {
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
err = wolfSSL_get_error(ssl, ret);
|
||||
} while (err == WOLFSSL_ERROR_WANT_READ && ret != WOLFSSL_SUCCESS);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static THREAD_RETURN WOLFSSL_THREAD test_server_nofail(void* args)
|
||||
{
|
||||
SOCKET_T sockfd = 0;
|
||||
|
@ -1931,6 +2000,15 @@ static THREAD_RETURN WOLFSSL_THREAD test_server_nofail(void* args)
|
|||
goto done;
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_SESSION_EXPORT
|
||||
/* only add in more complex nonblocking case with session export tests */
|
||||
if (args && ((func_args*)args)->argc > 0) {
|
||||
/* set as nonblock and time out for waiting on read/write */
|
||||
tcp_set_nonblocking(&clientfd);
|
||||
wolfSSL_dtls_set_using_nonblock(ssl, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (sharedCtx && wolfSSL_use_certificate_file(ssl, svrCertFile,
|
||||
WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) {
|
||||
/*err_sys("can't load server cert chain file, "
|
||||
|
@ -1960,6 +2038,20 @@ static THREAD_RETURN WOLFSSL_THREAD test_server_nofail(void* args)
|
|||
cbf->ssl_ready(ssl);
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_SESSION_EXPORT
|
||||
/* only add in more complex nonblocking case with session export tests */
|
||||
if (args && ((func_args*)args)->argc > 0) {
|
||||
ret = nonblocking_accept_read(args, ssl, &clientfd);
|
||||
if (ret >= 0) {
|
||||
((func_args*)args)->return_code = TEST_SUCCESS;
|
||||
}
|
||||
#ifdef WOLFSSL_TIRTOS
|
||||
Task_yield();
|
||||
#endif
|
||||
goto done;
|
||||
}
|
||||
#endif
|
||||
|
||||
do {
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
if (err == WC_PENDING_E) {
|
||||
|
@ -3090,8 +3182,17 @@ static void test_wolfSSL_dtls_export(void)
|
|||
#endif
|
||||
|
||||
{
|
||||
SOCKET_T sockfd = 0;
|
||||
WOLFSSL_CTX* ctx;
|
||||
WOLFSSL* ssl;
|
||||
char msg[64] = "hello wolfssl!";
|
||||
char reply[1024];
|
||||
int msgSz = (int)XSTRLEN(msg);
|
||||
byte *session, *window;
|
||||
unsigned int sessionSz, windowSz;
|
||||
struct sockaddr_in peerAddr;
|
||||
int i;
|
||||
|
||||
|
||||
/* Set ctx to DTLS 1.2 */
|
||||
AssertNotNull(ctx = wolfSSL_CTX_new(wolfDTLSv1_2_server_method()));
|
||||
|
@ -3107,7 +3208,87 @@ static void test_wolfSSL_dtls_export(void)
|
|||
AssertIntLT(wolfSSL_dtls_import(ssl, version_3, sizeof(version_3)), 0);
|
||||
wolfSSL_free(ssl);
|
||||
wolfSSL_CTX_free(ctx);
|
||||
|
||||
|
||||
/* check storing client state after connection and storing window only */
|
||||
#ifdef WOLFSSL_TIRTOS
|
||||
fdOpenSession(Task_self());
|
||||
#endif
|
||||
|
||||
InitTcpReady(&ready);
|
||||
|
||||
#if defined(USE_WINDOWS_API)
|
||||
/* use RNG to get random port if using windows */
|
||||
ready.port = GetRandomPort();
|
||||
#endif
|
||||
|
||||
/* set using dtls */
|
||||
XMEMSET(&server_args, 0, sizeof(func_args));
|
||||
XMEMSET(&server_cbf, 0, sizeof(callback_functions));
|
||||
server_cbf.method = wolfDTLSv1_2_server_method;
|
||||
server_args.callbacks = &server_cbf;
|
||||
server_args.argc = 3; /* set loop_count to 3 */
|
||||
|
||||
|
||||
server_args.signal = &ready;
|
||||
start_thread(test_server_nofail, &server_args, &serverThread);
|
||||
wait_tcp_ready(&server_args);
|
||||
|
||||
/* create and connect with client */
|
||||
AssertNotNull(ctx = wolfSSL_CTX_new(wolfDTLSv1_2_client_method()));
|
||||
AssertIntEQ(WOLFSSL_SUCCESS,
|
||||
wolfSSL_CTX_load_verify_locations(ctx, caCertFile, 0));
|
||||
AssertIntEQ(WOLFSSL_SUCCESS,
|
||||
wolfSSL_CTX_use_certificate_file(ctx, cliCertFile, SSL_FILETYPE_PEM));
|
||||
AssertIntEQ(WOLFSSL_SUCCESS,
|
||||
wolfSSL_CTX_use_PrivateKey_file(ctx, cliKeyFile, SSL_FILETYPE_PEM));
|
||||
tcp_connect(&sockfd, wolfSSLIP, server_args.signal->port, 0, 0, NULL);
|
||||
AssertNotNull(ssl = wolfSSL_new(ctx));
|
||||
AssertIntEQ(wolfSSL_set_fd(ssl, sockfd), WOLFSSL_SUCCESS);
|
||||
|
||||
/* store server information connected too */
|
||||
XMEMSET(&peerAddr, 0, sizeof(peerAddr));
|
||||
peerAddr.sin_family = AF_INET;
|
||||
peerAddr.sin_port = XHTONS(server_args.signal->port);
|
||||
wolfSSL_dtls_set_peer(ssl, &peerAddr, sizeof(peerAddr));
|
||||
|
||||
AssertIntEQ(wolfSSL_connect(ssl), WOLFSSL_SUCCESS);
|
||||
AssertIntEQ(wolfSSL_dtls_export(ssl, NULL, &sessionSz), 0);
|
||||
session = (byte*)XMALLOC(sessionSz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
AssertIntGT(wolfSSL_dtls_export(ssl, session, &sessionSz), 0);
|
||||
AssertIntEQ(wolfSSL_write(ssl, msg, msgSz), msgSz);
|
||||
AssertIntGT(wolfSSL_read(ssl, reply, sizeof(reply)), 0);
|
||||
AssertIntEQ(wolfSSL_dtls_export_state_only(ssl, NULL, &windowSz), 0);
|
||||
window = (byte*)XMALLOC(windowSz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
AssertIntGT(wolfSSL_dtls_export_state_only(ssl, window, &windowSz), 0);
|
||||
wolfSSL_free(ssl);
|
||||
|
||||
for (i = 1; i < server_args.argc; i++) {
|
||||
/* restore state */
|
||||
AssertNotNull(ssl = wolfSSL_new(ctx));
|
||||
AssertIntGT(wolfSSL_dtls_import(ssl, session, sessionSz), 0);
|
||||
AssertIntGT(wolfSSL_dtls_import(ssl, window, windowSz), 0);
|
||||
AssertIntEQ(wolfSSL_set_fd(ssl, sockfd), WOLFSSL_SUCCESS);
|
||||
AssertIntEQ(wolfSSL_write(ssl, msg, msgSz), msgSz);
|
||||
AssertIntGE(wolfSSL_read(ssl, reply, sizeof(reply)), 0);
|
||||
AssertIntGT(wolfSSL_dtls_export_state_only(ssl, window, &windowSz), 0);
|
||||
wolfSSL_free(ssl);
|
||||
}
|
||||
XFREE(session, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(window, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
wolfSSL_CTX_free(ctx);
|
||||
|
||||
printf("done and waiting for server\n");
|
||||
join_thread(serverThread);
|
||||
AssertIntEQ(server_args.return_code, TEST_SUCCESS);
|
||||
|
||||
FreeTcpReady(&ready);
|
||||
|
||||
#ifdef WOLFSSL_TIRTOS
|
||||
fdOpenSession(Task_self());
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
printf(testingFmt, "wolfSSL_dtls_export()");
|
||||
printf(resultFmt, passed);
|
||||
|
|
|
@ -1273,6 +1273,7 @@ enum Misc {
|
|||
DTLS_HANDSHAKE_FRAG_SZ = 3, /* fragment offset and length are 24 bit */
|
||||
DTLS_POOL_SZ = 255,/* allowed number of list items in TX pool */
|
||||
DTLS_EXPORT_PRO = 165,/* wolfSSL protocol for serialized session */
|
||||
DTLS_EXPORT_STATE_PRO = 166,/* wolfSSL protocol for serialized state */
|
||||
DTLS_EXPORT_VERSION = 4, /* wolfSSL version for serialized session */
|
||||
DTLS_EXPORT_OPT_SZ = 60, /* amount of bytes used from Options */
|
||||
DTLS_EXPORT_VERSION_3 = 3, /* wolfSSL version before TLS 1.3 addition */
|
||||
|
@ -1285,6 +1286,8 @@ enum Misc {
|
|||
DTLS_EXPORT_LEN = 2, /* 2 bytes for length and protocol */
|
||||
DTLS_EXPORT_IP = 46, /* max ip size IPv4 mapped IPv6 */
|
||||
MAX_EXPORT_BUFFER = 514, /* max size of buffer for exporting */
|
||||
MAX_EXPORT_STATE_BUFFER = DTLS_EXPORT_KEY_SZ + 3 * DTLS_EXPORT_LEN,
|
||||
/* max size of buffer for exporting state */
|
||||
FINISHED_LABEL_SZ = 15, /* TLS finished label size */
|
||||
TLS_FINISHED_SZ = 12, /* TLS has a shorter size */
|
||||
EXT_MASTER_LABEL_SZ = 22, /* TLS extended master secret label sz */
|
||||
|
@ -1570,6 +1573,10 @@ WOLFSSL_LOCAL ProtocolVersion MakeTLSv1_3(void);
|
|||
word32 sz);
|
||||
WOLFSSL_LOCAL int wolfSSL_dtls_export_internal(WOLFSSL* ssl, byte* buf,
|
||||
word32 sz);
|
||||
WOLFSSL_LOCAL int wolfSSL_dtls_export_state_internal(WOLFSSL* ssl,
|
||||
byte* buf, word32 sz);
|
||||
WOLFSSL_LOCAL int wolfSSL_dtls_import_state_internal(WOLFSSL* ssl,
|
||||
byte* buf, word32 sz);
|
||||
WOLFSSL_LOCAL int wolfSSL_send_session(WOLFSSL* ssl);
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -508,6 +508,8 @@ WOLFSSL_API int wolfSSL_CTX_dtls_set_export(WOLFSSL_CTX* ctx,
|
|||
WOLFSSL_API int wolfSSL_dtls_set_export(WOLFSSL* ssl, wc_dtls_export func);
|
||||
WOLFSSL_API int wolfSSL_dtls_export(WOLFSSL* ssl, unsigned char* buf,
|
||||
unsigned int* sz);
|
||||
WOLFSSL_API int wolfSSL_dtls_export_state_only(WOLFSSL* ssl, unsigned char* buf,
|
||||
unsigned int* sz);
|
||||
#endif /* WOLFSSL_DTLS */
|
||||
#endif /* WOLFSSL_SESSION_EXPORT */
|
||||
|
||||
|
|
Loading…
Reference in New Issue