From f6fafe67387a5e44445bcda8a089689065b5bb8d Mon Sep 17 00:00:00 2001 From: John Safranek Date: Sun, 21 Feb 2016 21:52:38 -0800 Subject: [PATCH 1/3] for DTLS, retain the handshake resources until peer sends application data record --- src/internal.c | 8 +++++++- src/ssl.c | 22 ++++++++++++++++++++-- wolfssl/internal.h | 3 +++ 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/internal.c b/src/internal.c index f1cbab102..c13f127e4 100644 --- a/src/internal.c +++ b/src/internal.c @@ -7689,6 +7689,12 @@ int ProcessReply(WOLFSSL* ssl) case application_data: WOLFSSL_MSG("got app DATA"); + #ifdef WOLFSSL_DTLS + if (ssl->options.dtls && ssl->options.dtlsHsRetain) { + FreeHandshakeResources(ssl); + ssl->options.dtlsHsRetain = 0; + } + #endif if ((ret = DoApplicationData(ssl, ssl->buffers.inputBuffer.buffer, &ssl->buffers.inputBuffer.idx)) @@ -7819,7 +7825,7 @@ int SendChangeCipher(WOLFSSL* ssl) if (ssl->options.groupMessages) return 0; - #ifdef WOLFSSL_DTLS + #if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_DEBUG_DTLS) else if (ssl->options.dtls) { /* If using DTLS, force the ChangeCipherSpec message to be in the * same datagram as the finished message. */ diff --git a/src/ssl.c b/src/ssl.c index c9ec2c951..a5eaa9565 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -5985,7 +5985,16 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl, } } #endif /* NO_HANDSHAKE_DONE_CB */ - FreeHandshakeResources(ssl); + + if (!ssl->options.dtls) { + FreeHandshakeResources(ssl); + } +#ifdef WOLFSSL_DTLS + else { + ssl->options.dtlsHsRetain = 1; + } +#endif /* WOLFSSL_DTLS */ + WOLFSSL_LEAVE("SSL_connect()", SSL_SUCCESS); return SSL_SUCCESS; @@ -6259,7 +6268,16 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl, } } #endif /* NO_HANDSHAKE_DONE_CB */ - FreeHandshakeResources(ssl); + + if (!ssl->options.dtls) { + FreeHandshakeResources(ssl); + } +#ifdef WOLFSSL_DTLS + else { + ssl->options.dtlsHsRetain = 1; + } +#endif /* WOLFSSL_DTLS */ + WOLFSSL_LEAVE("SSL_accept()", SSL_SUCCESS); return SSL_SUCCESS; diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 5ecfd6858..110285d4c 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2255,6 +2255,9 @@ typedef struct Options { word16 createTicket:1; /* Server to create new Ticket */ word16 useTicket:1; /* Use Ticket not session cache */ #endif +#ifdef WOLFSSL_DTLS + word16 dtlsHsRetain:1; /* DTLS retaining HS data */ +#endif /* need full byte values for this section */ byte processReply; /* nonblocking resume */ From f621f81fa205d103a4e1259d10c3d5f439fcf61c Mon Sep 17 00:00:00 2001 From: John Safranek Date: Mon, 22 Feb 2016 14:08:35 -0800 Subject: [PATCH 2/3] 1. Some DTLS code was missing an ifdef. 2. If receiving a handshake message that's already been processed, retransmit the previous message flight. --- src/internal.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/internal.c b/src/internal.c index c13f127e4..5df7821be 100644 --- a/src/internal.c +++ b/src/internal.c @@ -6101,7 +6101,7 @@ static int DoDtlsHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx, *inOutIdx += fragSz; if(type == finished ) *inOutIdx += ssl->keys.padSz; - ret = 0; + ret = DtlsPoolSend(ssl); } else if (fragSz < size) { /* Since this branch is in order, but fragmented, dtls_msg_list will be @@ -7612,6 +7612,7 @@ int ProcessReply(WOLFSSL* ssl) } #endif +#ifdef WOLFSSL_DTLS /* Check for duplicate CCS message in DTLS mode. * DTLS allows for duplicate messages, and it should be * skipped. */ @@ -7619,6 +7620,10 @@ int ProcessReply(WOLFSSL* ssl) ssl->msgsReceived.got_change_cipher) { WOLFSSL_MSG("Duplicate ChangeCipher msg"); + ret = DtlsPoolSend(ssl); + if (ret != 0) + return ret; + if (ssl->curSize != 1) { WOLFSSL_MSG("Malicious or corrupted" " duplicate ChangeCipher msg"); @@ -7627,6 +7632,7 @@ int ProcessReply(WOLFSSL* ssl) ssl->buffers.inputBuffer.idx++; break; } +#endif ret = SanityCheckMsgReceived(ssl, change_cipher_hs); if (ret != 0) From 69e00a3f97251e686835d09b49930d446833003d Mon Sep 17 00:00:00 2001 From: John Safranek Date: Mon, 22 Feb 2016 21:13:05 -0800 Subject: [PATCH 3/3] allow dtls timeout to be 0 in the recvfrom callback, set to 0 if the handshake is done --- src/io.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/io.c b/src/io.c index 026c66e7a..c710754ae 100644 --- a/src/io.c +++ b/src/io.c @@ -404,7 +404,10 @@ int EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx) WOLFSSL_ENTER("EmbedReceiveFrom()"); - if (!wolfSSL_get_using_nonblock(ssl) && dtls_timeout != 0) { + if (ssl->options.handShakeDone) + dtls_timeout = 0; + + if (!wolfSSL_get_using_nonblock(ssl)) { #ifdef USE_WINDOWS_API DWORD timeout = dtls_timeout * 1000; #else