1. Added missing -DWOLFSSL_SCTP to configure.ac.

2. Don't do hello verify requests in SCTP mode.
3. Implemented the SCTP MTU size changes.
4. Simplified the MAX_FRAGMENT size when calling ReceiveData().
This commit is contained in:
John Safranek
2016-08-24 13:17:38 -07:00
parent 52e2f1a7ab
commit a6c0d4fed7
5 changed files with 53 additions and 39 deletions

View File

@@ -2895,6 +2895,9 @@ AS_IF([test "x$ENABLED_MAXSTRENGTH" = "xyes" && \
test "x$ENABLED_SSLV3" = "xyes"], test "x$ENABLED_SSLV3" = "xyes"],
[AC_MSG_ERROR([Cannot use Max Strength and SSLv3 at the same time.])]) [AC_MSG_ERROR([Cannot use Max Strength and SSLv3 at the same time.])])
AS_IF([test "x$ENABLED_SCTP" = "xyes"],
[AM_CFLAGS="-DWOLFSSL_SCTP $AM_CFLAGS"])
# SCTP requires DTLS # SCTP requires DTLS
AS_IF([test "x$ENABLED_DTLS" = "xno" && \ AS_IF([test "x$ENABLED_DTLS" = "xno" && \
test "x$ENABLED_SCTP" = "xyes"], test "x$ENABLED_SCTP" = "xyes"],

View File

@@ -195,7 +195,6 @@ static INLINE int IsEncryptionOn(WOLFSSL* ssl, int isSend)
} }
#ifdef WOLFSSL_DTLS
/* If SCTP is not enabled returns the state of the dtls option. /* If SCTP is not enabled returns the state of the dtls option.
* If SCTP is enabled returns dtls && !sctp. */ * If SCTP is enabled returns dtls && !sctp. */
static INLINE int IsDtlsNotSctpMode(WOLFSSL* ssl) static INLINE int IsDtlsNotSctpMode(WOLFSSL* ssl)
@@ -210,7 +209,6 @@ static INLINE int IsDtlsNotSctpMode(WOLFSSL* ssl)
return result; return result;
} }
#endif
#ifdef HAVE_QSH #ifdef HAVE_QSH
@@ -1392,7 +1390,7 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap)
ctx->devId = INVALID_DEVID; ctx->devId = INVALID_DEVID;
#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SCTP) #if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SCTP)
ctx->dtlsMtuSz = MAX_MTU; ctx->dtlsMtuSz = MAX_RECORD_SIZE;
#endif #endif
#ifndef NO_CERTS #ifndef NO_CERTS
@@ -3346,9 +3344,6 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx)
ssl->IOCB_ReadCtx = &ssl->nxCtx; /* default NetX IO ctx, same for read */ ssl->IOCB_ReadCtx = &ssl->nxCtx; /* default NetX IO ctx, same for read */
ssl->IOCB_WriteCtx = &ssl->nxCtx; /* and write */ ssl->IOCB_WriteCtx = &ssl->nxCtx; /* and write */
#endif #endif
#ifdef WOLFSSL_DTLS
ssl->dtls_expected_rx = MAX_MTU;
#endif
ssl->options.serverState = NULL_STATE; ssl->options.serverState = NULL_STATE;
ssl->options.clientState = NULL_STATE; ssl->options.clientState = NULL_STATE;
@@ -3360,6 +3355,10 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx)
#ifdef WOLFSSL_DTLS #ifdef WOLFSSL_DTLS
#ifdef WOLFSSL_SCTP #ifdef WOLFSSL_SCTP
ssl->options.dtlsSctp = ctx->dtlsSctp; ssl->options.dtlsSctp = ctx->dtlsSctp;
ssl->dtlsMtuSz = ctx->dtlsMtuSz;
ssl->dtls_expected_rx = ssl->dtlsMtuSz;
#else
ssl->dtls_expected_rx = MAX_MTU;
#endif #endif
ssl->dtls_timeout_init = DTLS_TIMEOUT_INIT; ssl->dtls_timeout_init = DTLS_TIMEOUT_INIT;
ssl->dtls_timeout_max = DTLS_TIMEOUT_MAX; ssl->dtls_timeout_max = DTLS_TIMEOUT_MAX;
@@ -7448,7 +7447,8 @@ static int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx,
/* hello_request not hashed */ /* hello_request not hashed */
/* Also, skip hashing the client_hello message here for DTLS. It will be /* Also, skip hashing the client_hello message here for DTLS. It will be
* hashed later if the DTLS cookie is correct. */ * hashed later if the DTLS cookie is correct. */
if (type != hello_request && !(ssl->options.dtls && type == client_hello) && if (type != hello_request &&
!(IsDtlsNotSctpMode(ssl) && type == client_hello) &&
ssl->error != WC_PENDING_E) { ssl->error != WC_PENDING_E) {
ret = HashInput(ssl, input + *inOutIdx, size); ret = HashInput(ssl, input + *inOutIdx, size);
if (ret != 0) return ret; if (ret != 0) return ret;
@@ -17843,7 +17843,7 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
XMEMCPY(&pv, input + i, OPAQUE16_LEN); XMEMCPY(&pv, input + i, OPAQUE16_LEN);
ssl->chVersion = pv; /* store */ ssl->chVersion = pv; /* store */
#ifdef WOLFSSL_DTLS #ifdef WOLFSSL_DTLS
if (ssl->options.dtls) { if (IsDtlsNotSctpMode(ssl)) {
int ret; int ret;
#if defined(NO_SHA) && defined(NO_SHA256) #if defined(NO_SHA) && defined(NO_SHA256)
#error "DTLS needs either SHA or SHA-256" #error "DTLS needs either SHA or SHA-256"
@@ -17920,7 +17920,7 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
/* random */ /* random */
XMEMCPY(ssl->arrays->clientRandom, input + i, RAN_LEN); XMEMCPY(ssl->arrays->clientRandom, input + i, RAN_LEN);
#ifdef WOLFSSL_DTLS #ifdef WOLFSSL_DTLS
if (ssl->options.dtls) { if (IsDtlsNotSctpMode(ssl)) {
int ret = wc_HmacUpdate(&cookieHmac, input + i, RAN_LEN); int ret = wc_HmacUpdate(&cookieHmac, input + i, RAN_LEN);
if (ret != 0) return ret; if (ret != 0) return ret;
} }
@@ -17953,7 +17953,7 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
XMEMCPY(ssl->arrays->sessionID, input + i, b); XMEMCPY(ssl->arrays->sessionID, input + i, b);
#ifdef WOLFSSL_DTLS #ifdef WOLFSSL_DTLS
if (ssl->options.dtls) { if (IsDtlsNotSctpMode(ssl)) {
int ret = wc_HmacUpdate(&cookieHmac, input + i - 1, b + 1); int ret = wc_HmacUpdate(&cookieHmac, input + i - 1, b + 1);
if (ret != 0) return ret; if (ret != 0) return ret;
} }
@@ -18007,7 +18007,7 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
XMEMCPY(clSuites.suites, input + i, clSuites.suiteSz); XMEMCPY(clSuites.suites, input + i, clSuites.suiteSz);
#ifdef WOLFSSL_DTLS #ifdef WOLFSSL_DTLS
if (ssl->options.dtls) { if (IsDtlsNotSctpMode(ssl)) {
int ret = wc_HmacUpdate(&cookieHmac, int ret = wc_HmacUpdate(&cookieHmac,
input + i - OPAQUE16_LEN, input + i - OPAQUE16_LEN,
clSuites.suiteSz + OPAQUE16_LEN); clSuites.suiteSz + OPAQUE16_LEN);
@@ -18024,7 +18024,7 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
return BUFFER_ERROR; return BUFFER_ERROR;
#ifdef WOLFSSL_DTLS #ifdef WOLFSSL_DTLS
if (ssl->options.dtls) { if (IsDtlsNotSctpMode(ssl)) {
byte newCookie[MAX_COOKIE_LEN]; byte newCookie[MAX_COOKIE_LEN];
int ret; int ret;

View File

@@ -549,7 +549,7 @@ int wolfSSL_dtls_get_peer(WOLFSSL* ssl, void* peer, unsigned int* peerSz)
} }
#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SCTP) #if defined(WOLFSSL_SCTP) && defined(WOLFSSL_DTLS)
int wolfSSL_CTX_dtls_set_sctp(WOLFSSL_CTX* ctx) int wolfSSL_CTX_dtls_set_sctp(WOLFSSL_CTX* ctx)
{ {
@@ -575,27 +575,17 @@ int wolfSSL_dtls_set_sctp(WOLFSSL* ssl)
} }
/* wolfSSL_dtls_set_mtu int wolfSSL_CTX_dtls_set_mtu(WOLFSSL_CTX* ctx, word16 newMtu)
* Sets the DTLS MTU size. For the deafult MTU of 1500, set to 1500.
* The maximum allowed value is 16384, the maximum record size. The MTU
* needs to be larger than 200, need to be able to fit in the IP/UDP/DTLS
* headers.
*/
int wolfSSL_CTX_dtls_set_mtu(WOLFSSL_CTX* ctx, word32 newMtu)
{ {
if (ctx == NULL) if (ctx == NULL || newMtu > MAX_RECORD_SIZE)
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
if (newMtu > MAX_RECORD_SIZE) { ctx->dtlsMtuSz = newMtu;
ssl->error = BAD_FUNC_ARG;
return SSL_FAILURE;
}
return SSL_SUCCESS; return SSL_SUCCESS;
} }
int wolfSSL_dtls_set_mtu(WOLFSSL* ssl, word32 newMtu) int wolfSSL_dtls_set_mtu(WOLFSSL* ssl, word16 newMtu)
{ {
if (ssl == NULL) if (ssl == NULL)
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
@@ -605,6 +595,7 @@ int wolfSSL_dtls_set_mtu(WOLFSSL* ssl, word32 newMtu)
return SSL_FAILURE; return SSL_FAILURE;
} }
ssl->dtlsMtuSz = newMtu;
return SSL_SUCCESS; return SSL_SUCCESS;
} }
@@ -1117,17 +1108,22 @@ static int wolfSSL_read_internal(WOLFSSL* ssl, void* data, int sz, int peek)
#ifdef HAVE_ERRNO_H #ifdef HAVE_ERRNO_H
errno = 0; errno = 0;
#endif #endif
#ifdef WOLFSSL_DTLS #ifdef WOLFSSL_DTLS
if (ssl->options.dtls) if (ssl->options.dtls) {
ssl->dtls_expected_rx = max(sz + 100, MAX_MTU); ssl->dtls_expected_rx = max(sz + 100, MAX_MTU);
#ifdef WOLFSSL_SCTP
if (ssl->options.dtlsSctp)
ssl->dtls_expected_rx = max(ssl->dtls_expected_rx, ssl->dtlsMtuSz);
#endif
}
#endif #endif
sz = min(sz, OUTPUT_RECORD_SIZE);
#ifdef HAVE_MAX_FRAGMENT #ifdef HAVE_MAX_FRAGMENT
ret = ReceiveData(ssl, (byte*)data, sz = min(sz, ssl->max_fragment);
min(sz, min(ssl->max_fragment, OUTPUT_RECORD_SIZE)),peek);
#else
ret = ReceiveData(ssl, (byte*)data, min(sz, OUTPUT_RECORD_SIZE), peek);
#endif #endif
ret = ReceiveData(ssl, (byte*)data, sz, peek);
WOLFSSL_LEAVE("wolfSSL_read_internal()", ret); WOLFSSL_LEAVE("wolfSSL_read_internal()", ret);
@@ -6850,6 +6846,21 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
} }
#endif #endif
/* If SCTP is not enabled returns the state of the dtls option.
* If SCTP is enabled returns dtls && !sctp. */
static INLINE int IsDtlsNotSctpMode(WOLFSSL* ssl)
{
int result = ssl->options.dtls;
if (result) {
#ifdef WOLFSSL_SCTP
result = !ssl->options.dtlsSctp;
#endif
}
return result;
}
/* please see note at top of README if you get an error from connect */ /* please see note at top of README if you get an error from connect */
int wolfSSL_connect(WOLFSSL* ssl) int wolfSSL_connect(WOLFSSL* ssl)
{ {
@@ -6919,7 +6930,7 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
/* In DTLS, when resuming, we can go straight to FINISHED, /* In DTLS, when resuming, we can go straight to FINISHED,
* or do a cookie exchange and then skip to FINISHED, assume * or do a cookie exchange and then skip to FINISHED, assume
* we need the cookie exchange first. */ * we need the cookie exchange first. */
if (ssl->options.dtls) if (IsDtlsNotSctpMode(ssl))
neededState = SERVER_HELLOVERIFYREQUEST_COMPLETE; neededState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
#endif #endif
/* get response */ /* get response */
@@ -6931,7 +6942,7 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
/* if resumption failed, reset needed state */ /* if resumption failed, reset needed state */
else if (neededState == SERVER_FINISHED_COMPLETE) else if (neededState == SERVER_FINISHED_COMPLETE)
if (!ssl->options.resuming) { if (!ssl->options.resuming) {
if (!ssl->options.dtls) if (!IsDtlsNotSctpMode(ssl))
neededState = SERVER_HELLODONE_COMPLETE; neededState = SERVER_HELLODONE_COMPLETE;
else else
neededState = SERVER_HELLOVERIFYREQUEST_COMPLETE; neededState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
@@ -6946,7 +6957,7 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
return SSL_SUCCESS; return SSL_SUCCESS;
#ifdef WOLFSSL_DTLS #ifdef WOLFSSL_DTLS
if (ssl->options.dtls) { if (IsDtlsNotSctpMode(ssl)) {
/* re-init hashes, exclude first hello and verify request */ /* re-init hashes, exclude first hello and verify request */
#ifndef NO_OLD_TLS #ifndef NO_OLD_TLS
wc_InitMd5(&ssl->hsHashes->hashMd5); wc_InitMd5(&ssl->hsHashes->hashMd5);
@@ -6991,7 +7002,7 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
case HELLO_AGAIN_REPLY : case HELLO_AGAIN_REPLY :
#ifdef WOLFSSL_DTLS #ifdef WOLFSSL_DTLS
if (ssl->options.dtls) { if (IsDtlsNotSctpMode(ssl)) {
neededState = ssl->options.resuming ? neededState = ssl->options.resuming ?
SERVER_FINISHED_COMPLETE : SERVER_HELLODONE_COMPLETE; SERVER_FINISHED_COMPLETE : SERVER_HELLODONE_COMPLETE;

View File

@@ -2752,7 +2752,7 @@ struct WOLFSSL {
word32 dtls_expected_rx; word32 dtls_expected_rx;
wc_dtls_export dtls_export; /* export function for session */ wc_dtls_export dtls_export; /* export function for session */
#ifdef WOLFSSL_SCTP #ifdef WOLFSSL_SCTP
word32 mtu_size; word16 dtlsMtuSz;
#endif /* WOLFSSL_SCTP */ #endif /* WOLFSSL_SCTP */
#endif #endif
#ifdef WOLFSSL_CALLBACKS #ifdef WOLFSSL_CALLBACKS

View File

@@ -411,8 +411,8 @@ WOLFSSL_API int wolfSSL_dtls_get_peer(WOLFSSL*, void*, unsigned int*);
WOLFSSL_API int wolfSSL_CTX_dtls_set_sctp(WOLFSSL_CTX*); WOLFSSL_API int wolfSSL_CTX_dtls_set_sctp(WOLFSSL_CTX*);
WOLFSSL_API int wolfSSL_dtls_set_sctp(WOLFSSL*); WOLFSSL_API int wolfSSL_dtls_set_sctp(WOLFSSL*);
WOLFSSL_API int wolfSSL_CTX_dtls_set_mtu(WOLFSSL_CTX*, unsigned int); WOLFSSL_API int wolfSSL_CTX_dtls_set_mtu(WOLFSSL_CTX*, unsigned short);
WOLFSSL_API int wolfSSL_dtls_set_mtu(WOLFSSL*, unsigned int); WOLFSSL_API int wolfSSL_dtls_set_mtu(WOLFSSL*, unsigned short);
WOLFSSL_API int wolfSSL_ERR_GET_REASON(unsigned long err); WOLFSSL_API int wolfSSL_ERR_GET_REASON(unsigned long err);
WOLFSSL_API char* wolfSSL_ERR_error_string(unsigned long,char*); WOLFSSL_API char* wolfSSL_ERR_error_string(unsigned long,char*);