mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-08-03 12:44:45 +02:00
add public wolfSSL_dtls_export and api tests
This commit is contained in:
@@ -1001,16 +1001,16 @@ static int dtls_export_load(byte* exp, word32 len, byte ver, WOLFSSL* ssl)
|
||||
* 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.*/
|
||||
int wolfSSL_dtls_export(byte* buf, word32 sz, WOLFSSL* ssl)
|
||||
int wolfSSL_dtls_export_internal(byte* buf, word32 sz, WOLFSSL* ssl)
|
||||
{
|
||||
int ret;
|
||||
word32 idx = 0;
|
||||
word32 totalLen = 0;
|
||||
|
||||
WOLFSSL_ENTER("wolfSSL_dtls_export");
|
||||
WOLFSSL_ENTER("wolfSSL_dtls_export_internal");
|
||||
|
||||
if (buf == NULL || ssl == NULL) {
|
||||
WOLFSSL_LEAVE("wolfSSL_dtls_export", BAD_FUNC_ARG);
|
||||
WOLFSSL_LEAVE("wolfSSL_dtls_export_internal", BAD_FUNC_ARG);
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
@@ -1022,7 +1022,7 @@ int wolfSSL_dtls_export(byte* buf, word32 sz, WOLFSSL* ssl)
|
||||
totalLen += DTLS_EXPORT_LEN + ssl->buffers.dtlsCtx.peer.sz;
|
||||
|
||||
if (totalLen > sz) {
|
||||
WOLFSSL_LEAVE("wolfSSL_dtls_export", BUFFER_E);
|
||||
WOLFSSL_LEAVE("wolfSSL_dtls_export_internal", BUFFER_E);
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
@@ -1035,16 +1035,16 @@ int wolfSSL_dtls_export(byte* buf, word32 sz, WOLFSSL* ssl)
|
||||
c16toa((word16)DTLS_EXPORT_OPT_SZ, buf + idx); idx += DTLS_EXPORT_LEN;
|
||||
if ((ret = dtls_export_new(buf + idx, sz - idx, DTLS_EXPORT_VERSION,
|
||||
ssl)) < 0) {
|
||||
WOLFSSL_LEAVE("wolfSSL_dtls_export", ret);
|
||||
WOLFSSL_LEAVE("wolfSSL_dtls_export_internal", ret);
|
||||
return ret;
|
||||
}
|
||||
idx += DTLS_EXPORT_OPT_SZ;
|
||||
idx += ret;
|
||||
|
||||
/* export keys struct and dtls state -- variable length stored in ret */
|
||||
idx += DTLS_EXPORT_LEN; /* leave room for length */
|
||||
if ((ret = ExportKeyState(buf + idx, sz - idx,
|
||||
DTLS_EXPORT_VERSION, ssl)) < 0) {
|
||||
WOLFSSL_LEAVE("wolfSSL_dtls_export", ret);
|
||||
WOLFSSL_LEAVE("wolfSSL_dtls_export_internal", ret);
|
||||
return ret;
|
||||
}
|
||||
c16toa((word16)ret, buf + idx - DTLS_EXPORT_LEN); idx += ret;
|
||||
@@ -1053,10 +1053,10 @@ int wolfSSL_dtls_export(byte* buf, word32 sz, WOLFSSL* ssl)
|
||||
c16toa((word16)DTLS_EXPORT_SPC_SZ, buf + idx); idx += DTLS_EXPORT_LEN;
|
||||
if ((ret = ExportCipherSpecState(buf + idx, sz - idx,
|
||||
DTLS_EXPORT_VERSION, ssl)) < 0) {
|
||||
WOLFSSL_LEAVE("wolfSSL_dtls_export", ret);
|
||||
WOLFSSL_LEAVE("wolfSSL_dtls_export_internal", ret);
|
||||
return ret;
|
||||
}
|
||||
idx += DTLS_EXPORT_SPC_SZ;
|
||||
idx += ret;
|
||||
|
||||
/* export of dtls peer information */
|
||||
c16toa((word16)ssl->buffers.dtlsCtx.peer.sz, buf + idx);
|
||||
@@ -1079,7 +1079,7 @@ int wolfSSL_dtls_export(byte* buf, word32 sz, WOLFSSL* ssl)
|
||||
}
|
||||
#endif /* WOLFSSL_SESSION_EXPORT_DEBUG */
|
||||
|
||||
WOLFSSL_LEAVE("wolfSSL_dtls_export", idx);
|
||||
WOLFSSL_LEAVE("wolfSSL_dtls_export_internal", idx);
|
||||
return idx;
|
||||
}
|
||||
|
||||
@@ -1090,7 +1090,7 @@ int wolfSSL_dtls_import_internal(byte* buf, word32 sz, WOLFSSL* ssl)
|
||||
word32 idx = 0;
|
||||
word16 length = 0;
|
||||
int version;
|
||||
int ret, i;
|
||||
int ret;
|
||||
|
||||
WOLFSSL_ENTER("wolfSSL_dtls_import_internal");
|
||||
/* check at least enough room for protocol and length */
|
||||
@@ -1185,15 +1185,11 @@ int wolfSSL_dtls_import_internal(byte* buf, word32 sz, WOLFSSL* ssl)
|
||||
}
|
||||
|
||||
/* peer sa is free'd in SSL_ResourceFree */
|
||||
ssl->buffers.dtlsCtx.peer.sa = XMALLOC(ssl->buffers.dtlsCtx.peer.sz,
|
||||
ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (ssl->buffers.dtlsCtx.peer.sa == NULL) {
|
||||
if ((ret = wolfSSL_dtls_set_peer(ssl, buf + idx,
|
||||
ssl->buffers.dtlsCtx.peer.sz)) != SSL_SUCCESS) {
|
||||
WOLFSSL_MSG("Import DTLS peer info error");
|
||||
return MEMORY_E;
|
||||
return ret;
|
||||
}
|
||||
|
||||
XMEMCPY(ssl->buffers.dtlsCtx.peer.sa, buf + idx,
|
||||
ssl->buffers.dtlsCtx.peer.sz);
|
||||
idx += ssl->buffers.dtlsCtx.peer.sz;
|
||||
|
||||
SetKeysSide(ssl, ENCRYPT_AND_DECRYPT_SIDE);
|
||||
@@ -1205,17 +1201,9 @@ int wolfSSL_dtls_import_internal(byte* buf, word32 sz, WOLFSSL* ssl)
|
||||
}
|
||||
|
||||
/* make sure is a valid suite used */
|
||||
ret = MATCH_SUITE_ERROR;
|
||||
for (i = 0; i < ssl->suites->suiteSz; i += 2) {
|
||||
if (ssl->suites->suites[i] == ssl->options.cipherSuite0 &&
|
||||
ssl->suites->suites[i+1] == ssl->options.cipherSuite) {
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ret != 0) {
|
||||
if (wolfSSL_get_cipher(ssl) == NULL) {
|
||||
WOLFSSL_MSG("Can not match cipher suite imported");
|
||||
return ret;
|
||||
return MATCH_SUITE_ERROR;
|
||||
}
|
||||
|
||||
/* do not allow stream ciphers with DTLS */
|
||||
|
54
src/ssl.c
54
src/ssl.c
@@ -200,6 +200,38 @@ int wolfSSL_dtls_set_export(WOLFSSL* ssl, wc_dtls_export func)
|
||||
}
|
||||
|
||||
|
||||
int wolfSSL_dtls_export(unsigned char* buf, unsigned int* sz, WOLFSSL* ssl)
|
||||
{
|
||||
int ret;
|
||||
|
||||
WOLFSSL_ENTER("wolfSSL_dtls_export");
|
||||
|
||||
if (ssl == NULL || sz == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (buf == NULL) {
|
||||
*sz = MAX_EXPORT_BUFFER;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* if not DTLS do nothing */
|
||||
if (!ssl->options.dtls) {
|
||||
WOLFSSL_MSG("Currently only DTLS export is supported");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* copy over keys, options, and dtls state struct */
|
||||
ret = wolfSSL_dtls_export_internal(buf, *sz, ssl);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* returns 0 on success */
|
||||
int wolfSSL_send_session(WOLFSSL* ssl)
|
||||
{
|
||||
int ret;
|
||||
@@ -221,12 +253,11 @@ int wolfSSL_send_session(WOLFSSL* ssl)
|
||||
if (!ssl->options.dtls) {
|
||||
XFREE(buf, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
WOLFSSL_MSG("Currently only DTLS export is supported");
|
||||
return SSL_SUCCESS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ssl->dtls_export) {
|
||||
/* copy over keys, options, and dtls state struct */
|
||||
ret = wolfSSL_dtls_export(buf, bufSz, ssl);
|
||||
ret = wolfSSL_dtls_export_internal(buf, bufSz, ssl);
|
||||
if (ret < 0) {
|
||||
XFREE(buf, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
return ret;
|
||||
@@ -240,12 +271,7 @@ int wolfSSL_send_session(WOLFSSL* ssl)
|
||||
}
|
||||
|
||||
XFREE(buf, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
return SSL_SUCCESS;
|
||||
}
|
||||
else {
|
||||
XFREE(buf, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
return SSL_FAILURE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif /* WOLFSSL_DTLS */
|
||||
#endif /* WOLFSSL_SESSION_EXPORT */
|
||||
@@ -6641,7 +6667,6 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
|
||||
#ifdef WOLFSSL_DTLS
|
||||
else {
|
||||
ssl->options.dtlsHsRetain = 1;
|
||||
|
||||
}
|
||||
#endif /* WOLFSSL_DTLS */
|
||||
|
||||
@@ -6931,8 +6956,13 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
|
||||
#endif /* WOLFSSL_DTLS */
|
||||
|
||||
#ifdef WOLFSSL_SESSION_EXPORT
|
||||
WOLFSSL_MSG("sending session");
|
||||
wolfSSL_send_session(ssl);
|
||||
if (ssl->dtls_export) {
|
||||
if ((ssl->error = wolfSSL_send_session(ssl)) != 0) {
|
||||
WOLFSSL_MSG("Export DTLS session error");
|
||||
WOLFSSL_ERROR(ssl->error);
|
||||
return SSL_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
WOLFSSL_LEAVE("SSL_accept()", SSL_SUCCESS);
|
||||
|
116
tests/api.c
116
tests/api.c
@@ -493,6 +493,34 @@ static void test_wolfSSL_SetTmpDH_buffer(void)
|
||||
|
||||
/* helper functions */
|
||||
#ifdef HAVE_IO_TESTS_DEPENDENCIES
|
||||
#ifdef WOLFSSL_SESSION_EXPORT
|
||||
/* set up function for sending session information */
|
||||
static int test_export(WOLFSSL* inSsl, byte* buf, word32 sz, void* userCtx)
|
||||
{
|
||||
WOLFSSL_CTX* ctx;
|
||||
WOLFSSL* ssl;
|
||||
|
||||
AssertNotNull(inSsl);
|
||||
AssertNotNull(buf);
|
||||
AssertIntNE(0, sz);
|
||||
|
||||
/* Set ctx to DTLS 1.2 */
|
||||
ctx = wolfSSL_CTX_new(wolfDTLSv1_2_server_method());
|
||||
AssertNotNull(ctx);
|
||||
|
||||
ssl = wolfSSL_new(ctx);
|
||||
AssertNotNull(ssl);
|
||||
|
||||
AssertIntGE(wolfSSL_dtls_import(ssl, buf, sz), 0);
|
||||
|
||||
wolfSSL_free(ssl);
|
||||
wolfSSL_CTX_free(ctx);
|
||||
(void)userCtx;
|
||||
return SSL_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static THREAD_RETURN WOLFSSL_THREAD test_server_nofail(void* args)
|
||||
{
|
||||
SOCKET_T sockfd = 0;
|
||||
@@ -711,8 +739,8 @@ done2:
|
||||
return;
|
||||
}
|
||||
|
||||
/* SNI / ALPN helper functions */
|
||||
#if defined(HAVE_SNI) || defined(HAVE_ALPN)
|
||||
/* SNI / ALPN / session export helper functions */
|
||||
#if defined(HAVE_SNI) || defined(HAVE_ALPN) || defined(WOLFSSL_SESSION_EXPORT)
|
||||
|
||||
static THREAD_RETURN WOLFSSL_THREAD run_wolfssl_server(void* args)
|
||||
{
|
||||
@@ -752,6 +780,9 @@ static THREAD_RETURN WOLFSSL_THREAD run_wolfssl_server(void* args)
|
||||
#ifdef OPENSSL_EXTRA
|
||||
wolfSSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
|
||||
#endif
|
||||
#ifdef WOLFSSL_SESSION_EXPORT
|
||||
AssertIntEQ(SSL_SUCCESS, wolfSSL_CTX_dtls_set_export(ctx, test_export));
|
||||
#endif
|
||||
|
||||
|
||||
AssertIntEQ(SSL_SUCCESS, wolfSSL_CTX_load_verify_locations(ctx, cliCert, 0));
|
||||
@@ -766,9 +797,21 @@ static THREAD_RETURN WOLFSSL_THREAD run_wolfssl_server(void* args)
|
||||
callbacks->ctx_ready(ctx);
|
||||
|
||||
ssl = wolfSSL_new(ctx);
|
||||
if (wolfSSL_dtls(ssl)) {
|
||||
SOCKADDR_IN_T cliAddr;
|
||||
socklen_t cliLen;
|
||||
|
||||
cliLen = sizeof(cliAddr);
|
||||
tcp_accept(&sfd, &cfd, (func_args*)args, port, 0, 1, 0, 0);
|
||||
idx = (int)recvfrom(sfd, input, sizeof(input), MSG_PEEK,
|
||||
(struct sockaddr*)&cliAddr, &cliLen);
|
||||
AssertIntGT(idx, 0);
|
||||
wolfSSL_dtls_set_peer(ssl, &cliAddr, cliLen);
|
||||
}
|
||||
else {
|
||||
tcp_accept(&sfd, &cfd, (func_args*)args, port, 0, 0, 0, 1);
|
||||
CloseSocket(sfd);
|
||||
}
|
||||
|
||||
AssertIntEQ(SSL_SUCCESS, wolfSSL_set_fd(ssl, cfd));
|
||||
|
||||
@@ -796,6 +839,20 @@ static THREAD_RETURN WOLFSSL_THREAD run_wolfssl_server(void* args)
|
||||
}
|
||||
|
||||
AssertIntEQ(len, wolfSSL_write(ssl, msg, len));
|
||||
#ifdef WOLFSSL_SESSION_EXPORT
|
||||
if (wolfSSL_dtls(ssl)) {
|
||||
byte* import;
|
||||
word32 sz;
|
||||
|
||||
wolfSSL_dtls_export(NULL, &sz, ssl);
|
||||
import = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
AssertNotNull(import);
|
||||
idx = wolfSSL_dtls_export(import, &sz, ssl);
|
||||
AssertIntGE(idx, 0);
|
||||
AssertIntGE(wolfSSL_dtls_import(ssl, import, idx), 0);
|
||||
XFREE(import, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
}
|
||||
#endif
|
||||
#ifdef WOLFSSL_TIRTOS
|
||||
Task_yield();
|
||||
#endif
|
||||
@@ -861,7 +918,12 @@ static void run_wolfssl_client(void* args)
|
||||
callbacks->ctx_ready(ctx);
|
||||
|
||||
ssl = wolfSSL_new(ctx);
|
||||
if (wolfSSL_dtls(ssl)) {
|
||||
tcp_connect(&sfd, wolfSSLIP, ((func_args*)args)->signal->port, 1, ssl);
|
||||
}
|
||||
else {
|
||||
tcp_connect(&sfd, wolfSSLIP, ((func_args*)args)->signal->port, 0, ssl);
|
||||
}
|
||||
AssertIntEQ(SSL_SUCCESS, wolfSSL_set_fd(ssl, sfd));
|
||||
|
||||
if (callbacks->ssl_ready)
|
||||
@@ -894,7 +956,8 @@ static void run_wolfssl_client(void* args)
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* defined(HAVE_SNI) || defined(HAVE_ALPN) */
|
||||
#endif /* defined(HAVE_SNI) || defined(HAVE_ALPN) ||
|
||||
defined(WOLFSSL_SESSION_EXPORT) */
|
||||
#endif /* io tests dependencies */
|
||||
|
||||
|
||||
@@ -952,6 +1015,52 @@ static void test_wolfSSL_read_write(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void test_wolfSSL_dtls_export(void)
|
||||
{
|
||||
#if defined(HAVE_IO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS) && \
|
||||
defined(WOLFSSL_SESSION_EXPORT)
|
||||
tcp_ready ready;
|
||||
func_args client_args;
|
||||
func_args server_args;
|
||||
THREAD_TYPE serverThread;
|
||||
callback_functions server_cbf;
|
||||
callback_functions client_cbf;
|
||||
#ifdef WOLFSSL_TIRTOS
|
||||
fdOpenSession(Task_self());
|
||||
#endif
|
||||
|
||||
InitTcpReady(&ready);
|
||||
|
||||
/* set using dtls */
|
||||
XMEMSET(&server_cbf, 0, sizeof(callback_functions));
|
||||
XMEMSET(&client_cbf, 0, sizeof(callback_functions));
|
||||
server_cbf.method = wolfDTLSv1_2_server_method;
|
||||
client_cbf.method = wolfDTLSv1_2_client_method;
|
||||
server_args.callbacks = &server_cbf;
|
||||
client_args.callbacks = &client_cbf;
|
||||
|
||||
server_args.signal = &ready;
|
||||
client_args.signal = &ready;
|
||||
|
||||
start_thread(run_wolfssl_server, &server_args, &serverThread);
|
||||
wait_tcp_ready(&server_args);
|
||||
run_wolfssl_client(&client_args);
|
||||
join_thread(serverThread);
|
||||
|
||||
AssertTrue(client_args.return_code);
|
||||
AssertTrue(server_args.return_code);
|
||||
|
||||
FreeTcpReady(&ready);
|
||||
|
||||
#ifdef WOLFSSL_TIRTOS
|
||||
fdOpenSession(Task_self());
|
||||
#endif
|
||||
printf(testingFmt, "wolfSSL_dtls_export()");
|
||||
printf(resultFmt, passed);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
| TLS extensions tests
|
||||
*----------------------------------------------------------------------------*/
|
||||
@@ -1738,6 +1847,7 @@ void ApiTest(void)
|
||||
test_wolfSSL_SetTmpDH_file();
|
||||
test_wolfSSL_SetTmpDH_buffer();
|
||||
test_wolfSSL_read_write();
|
||||
test_wolfSSL_dtls_export();
|
||||
|
||||
/* TLS extensions tests */
|
||||
test_wolfSSL_UseSNI();
|
||||
|
@@ -1203,8 +1203,6 @@ typedef struct ProtocolVersion {
|
||||
} WOLFSSL_PACK ProtocolVersion;
|
||||
|
||||
|
||||
WOLFSSL_LOCAL int wolfSSL_dtls_import_internal(byte* buf, word32 sz, WOLFSSL* ssl);
|
||||
WOLFSSL_LOCAL int wolfSSL_dtls_export(byte* buf, word32 sz, WOLFSSL* ssl);
|
||||
WOLFSSL_LOCAL ProtocolVersion MakeSSLv3(void);
|
||||
WOLFSSL_LOCAL ProtocolVersion MakeTLSv1(void);
|
||||
WOLFSSL_LOCAL ProtocolVersion MakeTLSv1_1(void);
|
||||
@@ -1213,6 +1211,14 @@ WOLFSSL_LOCAL ProtocolVersion MakeTLSv1_2(void);
|
||||
#ifdef WOLFSSL_DTLS
|
||||
WOLFSSL_LOCAL ProtocolVersion MakeDTLSv1(void);
|
||||
WOLFSSL_LOCAL ProtocolVersion MakeDTLSv1_2(void);
|
||||
|
||||
#ifdef WOLFSSL_SESSION_EXPORT
|
||||
WOLFSSL_LOCAL int wolfSSL_dtls_import_internal(byte* buf, word32 sz,
|
||||
WOLFSSL* ssl);
|
||||
WOLFSSL_LOCAL int wolfSSL_dtls_export_internal(byte* buf, word32 sz,
|
||||
WOLFSSL* ssl);
|
||||
WOLFSSL_LOCAL int wolfSSL_send_session(WOLFSSL* ssl);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
@@ -229,10 +229,13 @@ WOLFSSL_API WOLFSSL_METHOD *wolfTLSv1_2_client_method(void);
|
||||
#ifdef WOLFSSL_DTLS
|
||||
typedef int (*wc_dtls_export)(WOLFSSL* ssl,
|
||||
unsigned char* exportBuffer, unsigned int sz, void* userCtx);
|
||||
WOLFSSL_API int wolfSSL_dtls_import(WOLFSSL* ssl, unsigned char* buf, unsigned int sz);
|
||||
WOLFSSL_API int wolfSSL_CTX_dtls_set_export(WOLFSSL_CTX* ctx, wc_dtls_export func);
|
||||
WOLFSSL_API int wolfSSL_dtls_import(WOLFSSL* ssl, unsigned char* buf,
|
||||
unsigned int sz);
|
||||
WOLFSSL_API int wolfSSL_CTX_dtls_set_export(WOLFSSL_CTX* ctx,
|
||||
wc_dtls_export func);
|
||||
WOLFSSL_API int wolfSSL_dtls_set_export(WOLFSSL* ssl, wc_dtls_export func);
|
||||
WOLFSSL_LOCAL int wolfSSL_send_session(WOLFSSL* ssl);
|
||||
WOLFSSL_API int wolfSSL_dtls_export(unsigned char* buf, unsigned int* sz,
|
||||
WOLFSSL* ssl);
|
||||
#endif /* WOLFSSL_DTLS */
|
||||
#endif /* WOLFSSL_SESSION_EXPORT */
|
||||
|
||||
|
Reference in New Issue
Block a user