diff --git a/configure.ac b/configure.ac index eeccde13b..3f6b858fa 100644 --- a/configure.ac +++ b/configure.ac @@ -2895,6 +2895,9 @@ AS_IF([test "x$ENABLED_MAXSTRENGTH" = "xyes" && \ test "x$ENABLED_SSLV3" = "xyes"], [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 AS_IF([test "x$ENABLED_DTLS" = "xno" && \ test "x$ENABLED_SCTP" = "xyes"], diff --git a/src/internal.c b/src/internal.c index 0df817e2d..991c39160 100755 --- a/src/internal.c +++ b/src/internal.c @@ -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 enabled returns dtls && !sctp. */ static INLINE int IsDtlsNotSctpMode(WOLFSSL* ssl) @@ -210,7 +209,6 @@ static INLINE int IsDtlsNotSctpMode(WOLFSSL* ssl) return result; } -#endif #ifdef HAVE_QSH @@ -1392,7 +1390,7 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap) ctx->devId = INVALID_DEVID; #if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SCTP) - ctx->dtlsMtuSz = MAX_MTU; + ctx->dtlsMtuSz = MAX_RECORD_SIZE; #endif #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_WriteCtx = &ssl->nxCtx; /* and write */ #endif -#ifdef WOLFSSL_DTLS - ssl->dtls_expected_rx = MAX_MTU; -#endif ssl->options.serverState = NULL_STATE; ssl->options.clientState = NULL_STATE; @@ -3360,6 +3355,10 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx) #ifdef WOLFSSL_DTLS #ifdef WOLFSSL_SCTP ssl->options.dtlsSctp = ctx->dtlsSctp; + ssl->dtlsMtuSz = ctx->dtlsMtuSz; + ssl->dtls_expected_rx = ssl->dtlsMtuSz; + #else + ssl->dtls_expected_rx = MAX_MTU; #endif ssl->dtls_timeout_init = DTLS_TIMEOUT_INIT; ssl->dtls_timeout_max = DTLS_TIMEOUT_MAX; @@ -7448,7 +7447,8 @@ static int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx, /* hello_request not hashed */ /* Also, skip hashing the client_hello message here for DTLS. It will be * 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) { ret = HashInput(ssl, input + *inOutIdx, size); if (ret != 0) return ret; @@ -17843,7 +17843,7 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, XMEMCPY(&pv, input + i, OPAQUE16_LEN); ssl->chVersion = pv; /* store */ #ifdef WOLFSSL_DTLS - if (ssl->options.dtls) { + if (IsDtlsNotSctpMode(ssl)) { int ret; #if defined(NO_SHA) && defined(NO_SHA256) #error "DTLS needs either SHA or SHA-256" @@ -17920,7 +17920,7 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, /* random */ XMEMCPY(ssl->arrays->clientRandom, input + i, RAN_LEN); #ifdef WOLFSSL_DTLS - if (ssl->options.dtls) { + if (IsDtlsNotSctpMode(ssl)) { int ret = wc_HmacUpdate(&cookieHmac, input + i, RAN_LEN); 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); #ifdef WOLFSSL_DTLS - if (ssl->options.dtls) { + if (IsDtlsNotSctpMode(ssl)) { int ret = wc_HmacUpdate(&cookieHmac, input + i - 1, b + 1); 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); #ifdef WOLFSSL_DTLS - if (ssl->options.dtls) { + if (IsDtlsNotSctpMode(ssl)) { int ret = wc_HmacUpdate(&cookieHmac, input + i - OPAQUE16_LEN, clSuites.suiteSz + OPAQUE16_LEN); @@ -18024,7 +18024,7 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, return BUFFER_ERROR; #ifdef WOLFSSL_DTLS - if (ssl->options.dtls) { + if (IsDtlsNotSctpMode(ssl)) { byte newCookie[MAX_COOKIE_LEN]; int ret; diff --git a/src/ssl.c b/src/ssl.c index 4e7346940..4d5fbfbde 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -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) { @@ -575,27 +575,17 @@ int wolfSSL_dtls_set_sctp(WOLFSSL* ssl) } -/* wolfSSL_dtls_set_mtu - * 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) +int wolfSSL_CTX_dtls_set_mtu(WOLFSSL_CTX* ctx, word16 newMtu) { - if (ctx == NULL) + if (ctx == NULL || newMtu > MAX_RECORD_SIZE) return BAD_FUNC_ARG; - if (newMtu > MAX_RECORD_SIZE) { - ssl->error = BAD_FUNC_ARG; - return SSL_FAILURE; - } - + ctx->dtlsMtuSz = newMtu; return SSL_SUCCESS; } -int wolfSSL_dtls_set_mtu(WOLFSSL* ssl, word32 newMtu) +int wolfSSL_dtls_set_mtu(WOLFSSL* ssl, word16 newMtu) { if (ssl == NULL) return BAD_FUNC_ARG; @@ -605,6 +595,7 @@ int wolfSSL_dtls_set_mtu(WOLFSSL* ssl, word32 newMtu) return SSL_FAILURE; } + ssl->dtlsMtuSz = newMtu; return SSL_SUCCESS; } @@ -1117,17 +1108,22 @@ static int wolfSSL_read_internal(WOLFSSL* ssl, void* data, int sz, int peek) #ifdef HAVE_ERRNO_H errno = 0; #endif + #ifdef WOLFSSL_DTLS - if (ssl->options.dtls) + if (ssl->options.dtls) { 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 + sz = min(sz, OUTPUT_RECORD_SIZE); #ifdef HAVE_MAX_FRAGMENT - ret = ReceiveData(ssl, (byte*)data, - min(sz, min(ssl->max_fragment, OUTPUT_RECORD_SIZE)),peek); -#else - ret = ReceiveData(ssl, (byte*)data, min(sz, OUTPUT_RECORD_SIZE), peek); + sz = min(sz, ssl->max_fragment); #endif + ret = ReceiveData(ssl, (byte*)data, sz, peek); WOLFSSL_LEAVE("wolfSSL_read_internal()", ret); @@ -6850,6 +6846,21 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl, } #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 */ 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, * or do a cookie exchange and then skip to FINISHED, assume * we need the cookie exchange first. */ - if (ssl->options.dtls) + if (IsDtlsNotSctpMode(ssl)) neededState = SERVER_HELLOVERIFYREQUEST_COMPLETE; #endif /* get response */ @@ -6931,7 +6942,7 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl, /* if resumption failed, reset needed state */ else if (neededState == SERVER_FINISHED_COMPLETE) if (!ssl->options.resuming) { - if (!ssl->options.dtls) + if (!IsDtlsNotSctpMode(ssl)) neededState = SERVER_HELLODONE_COMPLETE; else neededState = SERVER_HELLOVERIFYREQUEST_COMPLETE; @@ -6946,7 +6957,7 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl, return SSL_SUCCESS; #ifdef WOLFSSL_DTLS - if (ssl->options.dtls) { + if (IsDtlsNotSctpMode(ssl)) { /* re-init hashes, exclude first hello and verify request */ #ifndef NO_OLD_TLS wc_InitMd5(&ssl->hsHashes->hashMd5); @@ -6991,7 +7002,7 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl, case HELLO_AGAIN_REPLY : #ifdef WOLFSSL_DTLS - if (ssl->options.dtls) { + if (IsDtlsNotSctpMode(ssl)) { neededState = ssl->options.resuming ? SERVER_FINISHED_COMPLETE : SERVER_HELLODONE_COMPLETE; diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 31cbf32d7..ec72fe6ea 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2752,7 +2752,7 @@ struct WOLFSSL { word32 dtls_expected_rx; wc_dtls_export dtls_export; /* export function for session */ #ifdef WOLFSSL_SCTP - word32 mtu_size; + word16 dtlsMtuSz; #endif /* WOLFSSL_SCTP */ #endif #ifdef WOLFSSL_CALLBACKS diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 7cd34b34f..4f234b058 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -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_dtls_set_sctp(WOLFSSL*); -WOLFSSL_API int wolfSSL_CTX_dtls_set_mtu(WOLFSSL_CTX*, unsigned int); -WOLFSSL_API int wolfSSL_dtls_set_mtu(WOLFSSL*, unsigned int); +WOLFSSL_API int wolfSSL_CTX_dtls_set_mtu(WOLFSSL_CTX*, unsigned short); +WOLFSSL_API int wolfSSL_dtls_set_mtu(WOLFSSL*, unsigned short); WOLFSSL_API int wolfSSL_ERR_GET_REASON(unsigned long err); WOLFSSL_API char* wolfSSL_ERR_error_string(unsigned long,char*);