dtls13: new methods and version negotiation

This commit is contained in:
Marco Oliverio
2022-05-20 09:59:24 +02:00
committed by David Garske
parent 9d22e11776
commit 60834ba516
7 changed files with 412 additions and 85 deletions

View File

@@ -27,4 +27,47 @@
#ifdef WOLFSSL_DTLS13 #ifdef WOLFSSL_DTLS13
#include <wolfssl/ssl.h>
#include <wolfssl/internal.h>
WOLFSSL_METHOD* wolfDTLSv1_3_client_method_ex(void* heap)
{
WOLFSSL_METHOD* method;
WOLFSSL_ENTER("DTLSv1_3_client_method_ex");
method = (WOLFSSL_METHOD*)XMALLOC(sizeof(WOLFSSL_METHOD), heap,
DYNAMIC_TYPE_METHOD);
if (method)
InitSSL_Method(method, MakeDTLSv1_3());
return method;
}
WOLFSSL_METHOD* wolfDTLSv1_3_server_method_ex(void* heap)
{
WOLFSSL_METHOD* method;
WOLFSSL_ENTER("DTLSv1_3_server_method_ex");
method = (WOLFSSL_METHOD*)XMALLOC(sizeof(WOLFSSL_METHOD), heap,
DYNAMIC_TYPE_METHOD);
if (method) {
InitSSL_Method(method, MakeDTLSv1_3());
method->side = WOLFSSL_SERVER_END;
}
return method;
}
WOLFSSL_METHOD* wolfDTLSv1_3_client_method(void)
{
return wolfDTLSv1_3_client_method_ex(NULL);
}
WOLFSSL_METHOD* wolfDTLSv1_3_server_method(void)
{
return wolfDTLSv1_3_server_method_ex(NULL);
}
#endif /* WOLFSSL_DTLS13 */ #endif /* WOLFSSL_DTLS13 */

View File

@@ -490,7 +490,15 @@ int IsAtLeastTLSv1_2(const WOLFSSL* ssl)
int IsAtLeastTLSv1_3(const ProtocolVersion pv) int IsAtLeastTLSv1_3(const ProtocolVersion pv)
{ {
return (pv.major == SSLv3_MAJOR && pv.minor >= TLSv1_3_MINOR); int ret;
ret = (pv.major == SSLv3_MAJOR && pv.minor >= TLSv1_3_MINOR);
#ifdef WOLFSSL_DTLS13
if (ret == 0 && pv.major == DTLS_MAJOR && pv.minor <= DTLSv1_3_MINOR)
return 1;
#endif
return ret;
} }
static WC_INLINE int IsEncryptionOn(WOLFSSL* ssl, int isSend) static WC_INLINE int IsEncryptionOn(WOLFSSL* ssl, int isSend)
@@ -2099,7 +2107,17 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap)
ctx->refCount = 1; /* so either CTX_free or SSL_free can release */ ctx->refCount = 1; /* so either CTX_free or SSL_free can release */
ctx->heap = ctx; /* defaults to self */ ctx->heap = ctx; /* defaults to self */
ctx->timeout = WOLFSSL_SESSION_TIMEOUT; ctx->timeout = WOLFSSL_SESSION_TIMEOUT;
ctx->minDowngrade = WOLFSSL_MIN_DOWNGRADE; /* current default: TLSv1_MINOR */
#ifdef WOLFSSL_DTLS
if (method->version.major == DTLS_MAJOR) {
ctx->minDowngrade = WOLFSSL_MIN_DTLS_DOWNGRADE;
}
else
#endif /* WOLFSSL_DTLS */
{
/* current default: TLSv1_MINOR */
ctx->minDowngrade = WOLFSSL_MIN_DOWNGRADE;
}
if (wc_InitMutex(&ctx->countMutex) < 0) { if (wc_InitMutex(&ctx->countMutex) < 0) {
WOLFSSL_MSG("Mutex error on CTX init"); WOLFSSL_MSG("Mutex error on CTX init");
@@ -8350,6 +8368,18 @@ ProtocolVersion MakeDTLSv1_2(void)
#endif /* !WOLFSSL_NO_TLS12 */ #endif /* !WOLFSSL_NO_TLS12 */
#ifdef WOLFSSL_DTLS13
ProtocolVersion MakeDTLSv1_3(void)
{
ProtocolVersion pv;
pv.major = DTLS_MAJOR;
pv.minor = DTLSv1_3_MINOR;
return pv;
}
#endif /* WOLFSSL_DTLS13 */
#endif /* WOLFSSL_DTLS */ #endif /* WOLFSSL_DTLS */
@@ -9416,6 +9446,7 @@ int CheckAvailableSize(WOLFSSL *ssl, int size)
static int GetRecordHeader(WOLFSSL* ssl, const byte* input, word32* inOutIdx, static int GetRecordHeader(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
RecordLayerHeader* rh, word16 *size) RecordLayerHeader* rh, word16 *size)
{ {
byte tls12minor;
#ifdef OPENSSL_ALL #ifdef OPENSSL_ALL
word32 start = *inOutIdx; word32 start = *inOutIdx;
#endif #endif
@@ -9469,13 +9500,18 @@ static int GetRecordHeader(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
} }
#endif #endif
tls12minor = TLSv1_2_MINOR;
#ifdef WOLFSSL_DTLS13
if (ssl->options.dtls)
tls12minor = DTLSv1_2_MINOR;
#endif /* WOLFSSL_DTLS13 */
/* catch version mismatch */ /* catch version mismatch */
#ifndef WOLFSSL_TLS13 #ifndef WOLFSSL_TLS13
if (rh->pvMajor != ssl->version.major || rh->pvMinor != ssl->version.minor) if (rh->pvMajor != ssl->version.major || rh->pvMinor != ssl->version.minor)
#else #else
if (rh->pvMajor != ssl->version.major || if (rh->pvMajor != ssl->version.major ||
(rh->pvMinor != ssl->version.minor && (rh->pvMinor != ssl->version.minor &&
(!IsAtLeastTLSv1_3(ssl->version) || rh->pvMinor != TLSv1_2_MINOR) (!IsAtLeastTLSv1_3(ssl->version) || rh->pvMinor != tls12minor)
)) ))
#endif #endif
{ {
@@ -9598,9 +9634,10 @@ int GetDtlsHandShakeHeader(WOLFSSL* ssl, const byte* input,
idx += DTLS_HANDSHAKE_FRAG_SZ; idx += DTLS_HANDSHAKE_FRAG_SZ;
c24to32(input + idx, fragSz); c24to32(input + idx, fragSz);
if (ssl->curRL.pvMajor != ssl->version.major || if ((ssl->curRL.pvMajor != ssl->version.major) ||
ssl->curRL.pvMinor != ssl->version.minor) { (!IsAtLeastTLSv1_3(ssl->version) && ssl->curRL.pvMinor != ssl->version.minor) ||
(IsAtLeastTLSv1_3(ssl->version) && ssl->curRL.pvMinor != DTLSv1_2_MINOR)
) {
if (*type != client_hello && *type != hello_verify_request) { if (*type != client_hello && *type != hello_verify_request) {
WOLFSSL_ERROR(VERSION_ERROR); WOLFSSL_ERROR(VERSION_ERROR);
return VERSION_ERROR; return VERSION_ERROR;
@@ -30173,6 +30210,8 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
word32 i = *inOutIdx; word32 i = *inOutIdx;
word32 begin = i; word32 begin = i;
int ret = 0; int ret = 0;
byte lesserVersion;
#ifdef WOLFSSL_DTLS #ifdef WOLFSSL_DTLS
Hmac cookieHmac; Hmac cookieHmac;
byte newCookie[MAX_COOKIE_LEN]; byte newCookie[MAX_COOKIE_LEN];
@@ -30230,11 +30269,11 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
if (pv.major == SSLv3_MAJOR && pv.minor >= TLSv1_3_MINOR) if (pv.major == SSLv3_MAJOR && pv.minor >= TLSv1_3_MINOR)
pv.minor = TLSv1_2_MINOR; pv.minor = TLSv1_2_MINOR;
if ((!ssl->options.dtls && ssl->version.minor > pv.minor) || lesserVersion = !ssl->options.dtls && ssl->version.minor > pv.minor;
(ssl->options.dtls && ssl->version.minor != DTLS_MINOR lesserVersion |= ssl->options.dtls && ssl->version.minor < pv.minor;
&& ssl->version.minor != DTLSv1_2_MINOR && pv.minor != DTLS_MINOR
&& pv.minor != DTLSv1_2_MINOR)) {
if (lesserVersion) {
byte belowMinDowngrade;
word16 haveRSA = 0; word16 haveRSA = 0;
word16 havePSK = 0; word16 havePSK = 0;
int keySz = 0; int keySz = 0;
@@ -30247,7 +30286,15 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
ret = VERSION_ERROR; ret = VERSION_ERROR;
goto out; goto out;
} }
if (pv.minor < ssl->options.minDowngrade) {
belowMinDowngrade = pv.minor < ssl->options.minDowngrade;
/* DTLS versions increase backwards (-1,-2,-3) ecc */
if (ssl->options.dtls)
belowMinDowngrade = ssl->options.dtls
&& pv.minor > ssl->options.minDowngrade;
if (belowMinDowngrade) {
WOLFSSL_MSG("\tversion below minimum allowed, fatal error"); WOLFSSL_MSG("\tversion below minimum allowed, fatal error");
#if defined(WOLFSSL_EXTRA_ALERTS) || defined(OPENSSL_EXTRA) #if defined(WOLFSSL_EXTRA_ALERTS) || defined(OPENSSL_EXTRA)
SendAlert(ssl, alert_fatal, handshake_failure); SendAlert(ssl, alert_fatal, handshake_failure);
@@ -30256,6 +30303,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
goto out; goto out;
} }
if (!ssl->options.dtls) {
if (pv.minor == SSLv3_MINOR) { if (pv.minor == SSLv3_MINOR) {
/* turn off tls */ /* turn off tls */
WOLFSSL_MSG("\tdowngrading to SSLv3"); WOLFSSL_MSG("\tdowngrading to SSLv3");
@@ -30277,6 +30325,25 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
WOLFSSL_MSG(" downgrading to TLSv1.2"); WOLFSSL_MSG(" downgrading to TLSv1.2");
ssl->version.minor = TLSv1_2_MINOR; ssl->version.minor = TLSv1_2_MINOR;
} }
}
else {
if (pv.minor == DTLSv1_2_MINOR) {
WOLFSSL_MSG("\tDowngrading to DTLSv1.2");
ssl->options.tls1_3 = 0;
ssl->version.minor = DTLSv1_2_MINOR;
/* reset hashes, DTLSv1.2 will take care of the hashing
later */
ret = InitHandshakeHashes(ssl);
if (ret != 0)
return ret;
}
else if (pv.minor == DTLS_MINOR) {
WOLFSSL_MSG("\tDowngrading to DTLSv1.2");
ssl->options.tls1_3 = 0;
ssl->version.minor = DTLS_MINOR;
}
}
#ifndef NO_RSA #ifndef NO_RSA
haveRSA = 1; haveRSA = 1;
#endif #endif

View File

@@ -4516,6 +4516,18 @@ static int SetMinVersionHelper(byte* minVersion, int version)
break; break;
#endif #endif
#ifdef WOLFSSL_DTLS13
case WOLFSSL_DTLSV1:
*minVersion = DTLS_MINOR;
break;
case WOLFSSL_DTLSV1_2:
*minVersion = DTLSv1_2_MINOR;
break;
case WOLFSSL_DTLSV1_3:
*minVersion = DTLSv1_3_MINOR;
break;
#endif /* WOLFSSL_DTLS13 */
default: default:
WOLFSSL_MSG("Bad function argument"); WOLFSSL_MSG("Bad function argument");
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
@@ -19795,6 +19807,8 @@ static const char* wolfSSL_internal_get_version(const ProtocolVersion* version)
return "DTLS"; return "DTLS";
case DTLSv1_2_MINOR : case DTLSv1_2_MINOR :
return "DTLSv1.2"; return "DTLSv1.2";
case DTLSv1_3_MINOR :
return "DTLSv1.3";
default: default:
return "unknown"; return "unknown";
} }

153
src/tls.c
View File

@@ -5628,6 +5628,58 @@ static int TLSX_UseSRTP(TLSX** extensions, word16 profiles, void* heap)
/******************************************************************************/ /******************************************************************************/
#ifdef WOLFSSL_TLS13 #ifdef WOLFSSL_TLS13
static WC_INLINE int versionIsGreater(byte isDtls, byte a, byte b)
{
(void)isDtls;
#ifdef WOLFSSL_DTLS
/* DTLS version increases backwards (-1,-2,-3,etc) */
if (isDtls)
return a < b;
#endif /* WOLFSSL_DTLS */
return a > b;
}
static WC_INLINE int versionIsLesser(byte isDtls, byte a, byte b)
{
(void)isDtls;
#ifdef WOLFSSL_DTLS
/* DTLS version increases backwards (-1,-2,-3,etc) */
if (isDtls)
return a > b;
#endif /* WOLFSSL_DTLS */
return a < b;
}
static WC_INLINE int versionIsAtLeast(byte isDtls, byte a, byte b)
{
(void)isDtls;
#ifdef WOLFSSL_DTLS
/* DTLS version increases backwards (-1,-2,-3,etc) */
if (isDtls)
return a <= b;
#endif /* WOLFSSL_DTLS */
return a >= b;
}
static WC_INLINE int versionIsLessEqual(byte isDtls, byte a, byte b)
{
(void)isDtls;
#ifdef WOLFSSL_DTLS
/* DTLS version increases backwards (-1,-2,-3,etc) */
if (isDtls)
return a >= b;
#endif /* WOLFSSL_DTLS */
return a <= b;
}
/* Return the size of the SupportedVersions extension's data. /* Return the size of the SupportedVersions extension's data.
* *
* data The SSL/TLS object. * data The SSL/TLS object.
@@ -5637,12 +5689,23 @@ static int TLSX_UseSRTP(TLSX** extensions, word16 profiles, void* heap)
static int TLSX_SupportedVersions_GetSize(void* data, byte msgType, word16* pSz) static int TLSX_SupportedVersions_GetSize(void* data, byte msgType, word16* pSz)
{ {
WOLFSSL* ssl = (WOLFSSL*)data; WOLFSSL* ssl = (WOLFSSL*)data;
byte tls13Minor, tls12Minor, tls11Minor, isDtls;
/* unused on some configuration */
(void)tls12Minor;
(void)tls13Minor;
(void)tls11Minor;
isDtls = !!ssl->options.dtls;
tls13Minor = (byte)(isDtls ? DTLSv1_3_MINOR : TLSv1_3_MINOR);
tls12Minor = (byte)(isDtls ? DTLSv1_2_MINOR : TLSv1_2_MINOR);
tls11Minor = (byte)(isDtls ? DTLS_MINOR : TLSv1_1_MINOR);
if (msgType == client_hello) { if (msgType == client_hello) {
/* TLS v1.2 and TLS v1.3 */ /* TLS v1.2 and TLS v1.3 */
int cnt = 0; int cnt = 0;
if ((ssl->options.minDowngrade <= TLSv1_3_MINOR) if (versionIsLessEqual(isDtls, ssl->options.minDowngrade, tls13Minor)
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \ #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
defined(WOLFSSL_WPAS_SMALL) defined(WOLFSSL_WPAS_SMALL)
&& (ssl->options.mask & SSL_OP_NO_TLSv1_3) == 0 && (ssl->options.mask & SSL_OP_NO_TLSv1_3) == 0
@@ -5653,7 +5716,8 @@ static int TLSX_SupportedVersions_GetSize(void* data, byte msgType, word16* pSz)
if (ssl->options.downgrade) { if (ssl->options.downgrade) {
#ifndef WOLFSSL_NO_TLS12 #ifndef WOLFSSL_NO_TLS12
if ((ssl->options.minDowngrade <= TLSv1_2_MINOR) if (versionIsLessEqual(
isDtls, ssl->options.minDowngrade, tls12Minor)
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \ #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
defined(WOLFSSL_WPAS_SMALL) defined(WOLFSSL_WPAS_SMALL)
&& (ssl->options.mask & SSL_OP_NO_TLSv1_2) == 0 && (ssl->options.mask & SSL_OP_NO_TLSv1_2) == 0
@@ -5663,7 +5727,8 @@ static int TLSX_SupportedVersions_GetSize(void* data, byte msgType, word16* pSz)
} }
#endif #endif
#ifndef NO_OLD_TLS #ifndef NO_OLD_TLS
if ((ssl->options.minDowngrade <= TLSv1_1_MINOR) if (versionIsLessEqual(
isDtls, ssl->options.minDowngrade, tls11Minor)
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \ #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
defined(WOLFSSL_WPAS_SMALL) defined(WOLFSSL_WPAS_SMALL)
&& (ssl->options.mask & SSL_OP_NO_TLSv1_1) == 0 && (ssl->options.mask & SSL_OP_NO_TLSv1_1) == 0
@@ -5672,7 +5737,7 @@ static int TLSX_SupportedVersions_GetSize(void* data, byte msgType, word16* pSz)
cnt++; cnt++;
} }
#ifdef WOLFSSL_ALLOW_TLSV10 #ifdef WOLFSSL_ALLOW_TLSV10
if ((ssl->options.minDowngrade <= TLSv1_MINOR) if (!ssl->options.dtls && (ssl->options.minDowngrade <= TLSv1_MINOR)
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \ #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
defined(WOLFSSL_WPAS_SMALL) defined(WOLFSSL_WPAS_SMALL)
&& (ssl->options.mask & SSL_OP_NO_TLSv1) == 0 && (ssl->options.mask & SSL_OP_NO_TLSv1) == 0
@@ -5709,6 +5774,24 @@ static int TLSX_SupportedVersions_Write(void* data, byte* output,
WOLFSSL* ssl = (WOLFSSL*)data; WOLFSSL* ssl = (WOLFSSL*)data;
byte major; byte major;
byte* cnt; byte* cnt;
byte tls13minor, tls12minor, tls11minor, isDtls = 0;
tls13minor = (byte)TLSv1_3_MINOR;
tls12minor = (byte)TLSv1_2_MINOR;
tls11minor = (byte)TLSv1_1_MINOR;
/* unused in some configuration */
(void)tls11minor;
(void)tls12minor;
#ifdef WOLFSSL_DTLS13
if (ssl->options.dtls) {
tls13minor = (byte)DTLSv1_3_MINOR;
tls12minor = (byte)DTLSv1_2_MINOR;
tls11minor = (byte)DTLS_MINOR;
isDtls = 1;
}
#endif /* WOLFSSL_DTLS13 */
if (msgType == client_hello) { if (msgType == client_hello) {
major = ssl->ctx->method->version.major; major = ssl->ctx->method->version.major;
@@ -5716,7 +5799,7 @@ static int TLSX_SupportedVersions_Write(void* data, byte* output,
cnt = output++; cnt = output++;
*cnt = 0; *cnt = 0;
if ((ssl->options.minDowngrade <= TLSv1_3_MINOR) if (versionIsLessEqual(isDtls, ssl->options.minDowngrade, tls13minor)
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \ #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
defined(WOLFSSL_WPAS_SMALL) defined(WOLFSSL_WPAS_SMALL)
&& (ssl->options.mask & SSL_OP_NO_TLSv1_3) == 0 && (ssl->options.mask & SSL_OP_NO_TLSv1_3) == 0
@@ -5730,13 +5813,13 @@ static int TLSX_SupportedVersions_Write(void* data, byte* output,
*(output++) = TLS_DRAFT_MINOR; *(output++) = TLS_DRAFT_MINOR;
#else #else
*(output++) = major; *(output++) = major;
*(output++) = (byte)TLSv1_3_MINOR; *(output++) = tls13minor;
#endif #endif
} }
if (ssl->options.downgrade) { if (ssl->options.downgrade) {
#ifndef WOLFSSL_NO_TLS12 #ifndef WOLFSSL_NO_TLS12
if ((ssl->options.minDowngrade <= TLSv1_2_MINOR) if (versionIsLessEqual(isDtls, ssl->options.minDowngrade, tls12minor)
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \ #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
defined(WOLFSSL_WPAS_SMALL) defined(WOLFSSL_WPAS_SMALL)
&& (ssl->options.mask & SSL_OP_NO_TLSv1_2) == 0 && (ssl->options.mask & SSL_OP_NO_TLSv1_2) == 0
@@ -5744,12 +5827,12 @@ static int TLSX_SupportedVersions_Write(void* data, byte* output,
) { ) {
*cnt += OPAQUE16_LEN; *cnt += OPAQUE16_LEN;
*(output++) = major; *(output++) = major;
*(output++) = (byte)TLSv1_2_MINOR; *(output++) = tls12minor;
} }
#endif #endif
#ifndef NO_OLD_TLS #ifndef NO_OLD_TLS
if ((ssl->options.minDowngrade <= TLSv1_1_MINOR) if (versionIsLessEqual(isDtls, ssl->options.minDowngrade, tls11minor)
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \ #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
defined(WOLFSSL_WPAS_SMALL) defined(WOLFSSL_WPAS_SMALL)
&& (ssl->options.mask & SSL_OP_NO_TLSv1_1) == 0 && (ssl->options.mask & SSL_OP_NO_TLSv1_1) == 0
@@ -5757,10 +5840,10 @@ static int TLSX_SupportedVersions_Write(void* data, byte* output,
) { ) {
*cnt += OPAQUE16_LEN; *cnt += OPAQUE16_LEN;
*(output++) = major; *(output++) = major;
*(output++) = (byte)TLSv1_1_MINOR; *(output++) = tls11minor;
} }
#ifdef WOLFSSL_ALLOW_TLSV10 #ifdef WOLFSSL_ALLOW_TLSV10
if ((ssl->options.minDowngrade <= TLSv1_MINOR) if (!ssl->options.dtls && (ssl->options.minDowngrade <= TLSv1_MINOR)
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \ #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
defined(WOLFSSL_WPAS_SMALL) defined(WOLFSSL_WPAS_SMALL)
&& (ssl->options.mask & SSL_OP_NO_TLSv1) == 0 && (ssl->options.mask & SSL_OP_NO_TLSv1) == 0
@@ -5806,6 +5889,20 @@ static int TLSX_SupportedVersions_Parse(WOLFSSL* ssl, const byte* input,
int newMinor = 0; int newMinor = 0;
int set = 0; int set = 0;
int ret; int ret;
int tls13minor;
int tls12minor;
byte isDtls;
tls13minor = TLSv1_3_MINOR;
tls12minor = TLSv1_2_MINOR;
isDtls = ssl->options.dtls == 1;
#ifdef WOLFSSL_DTLS13
if (ssl->options.dtls) {
tls13minor = DTLSv1_3_MINOR;
tls12minor = DTLSv1_2_MINOR;
}
#endif /* WOLFSSL_DTLS13 */
if (msgType == client_hello) { if (msgType == client_hello) {
/* Must contain a length and at least one version. */ /* Must contain a length and at least one version. */
@@ -5839,23 +5936,27 @@ static int TLSX_SupportedVersions_Parse(WOLFSSL* ssl, const byte* input,
continue; continue;
/* No upgrade allowed. */ /* No upgrade allowed. */
if (minor > ssl->version.minor) if (versionIsGreater(isDtls, minor, ssl->version.minor))
continue; continue;
/* Check downgrade. */ /* Check downgrade. */
if (minor < ssl->version.minor) { if (versionIsLesser(isDtls, minor, ssl->version.minor)) {
if (!ssl->options.downgrade) if (!ssl->options.downgrade)
continue; continue;
if (minor < ssl->options.minDowngrade) if (versionIsLesser(
isDtls, minor, ssl->options.minDowngrade))
continue; continue;
if (newMinor == 0 && minor > ssl->options.oldMinor) { if (newMinor == 0 &&
versionIsGreater(
isDtls, minor, ssl->options.oldMinor)) {
/* Downgrade the version. */ /* Downgrade the version. */
ssl->version.minor = minor; ssl->version.minor = minor;
} }
} }
if (minor >= TLSv1_3_MINOR) { if (versionIsAtLeast(isDtls, minor, tls13minor)) {
if (!ssl->options.tls1_3) { if (!ssl->options.tls1_3) {
ssl->options.tls1_3 = 1; ssl->options.tls1_3 = 1;
ret = TLSX_Prepend(&ssl->extensions, ret = TLSX_Prepend(&ssl->extensions,
@@ -5865,12 +5966,13 @@ static int TLSX_SupportedVersions_Parse(WOLFSSL* ssl, const byte* input,
} }
TLSX_SetResponse(ssl, TLSX_SUPPORTED_VERSIONS); TLSX_SetResponse(ssl, TLSX_SUPPORTED_VERSIONS);
} }
if (minor > newMinor) { if (versionIsGreater(isDtls, minor, newMinor)) {
ssl->version.minor = minor; ssl->version.minor = minor;
newMinor = minor; newMinor = minor;
} }
} }
else if (minor > ssl->options.oldMinor) else if (versionIsGreater(
isDtls, minor, ssl->options.oldMinor))
ssl->options.oldMinor = minor; ssl->options.oldMinor = minor;
set = 1; set = 1;
@@ -5896,25 +5998,26 @@ static int TLSX_SupportedVersions_Parse(WOLFSSL* ssl, const byte* input,
return VERSION_ERROR; return VERSION_ERROR;
/* Can't downgrade with this extension below TLS v1.3. */ /* Can't downgrade with this extension below TLS v1.3. */
if (minor < TLSv1_3_MINOR) if (versionIsLesser(isDtls, minor, tls13minor))
return VERSION_ERROR; return VERSION_ERROR;
/* Version is TLS v1.2 to handle downgrading from TLS v1.3+. */ /* Version is TLS v1.2 to handle downgrading from TLS v1.3+. */
if (ssl->options.downgrade && ssl->version.minor == TLSv1_2_MINOR) { if (ssl->options.downgrade && ssl->version.minor == tls12minor) {
/* Set minor version back to TLS v1.3+ */ /* Set minor version back to TLS v1.3+ */
ssl->version.minor = ssl->ctx->method->version.minor; ssl->version.minor = ssl->ctx->method->version.minor;
} }
/* No upgrade allowed. */ /* No upgrade allowed. */
if (ssl->version.minor < minor) if (versionIsLesser(isDtls, ssl->version.minor, minor))
return VERSION_ERROR; return VERSION_ERROR;
/* Check downgrade. */ /* Check downgrade. */
if (ssl->version.minor > minor) { if (versionIsGreater(isDtls, ssl->version.minor, minor)) {
if (!ssl->options.downgrade) if (!ssl->options.downgrade)
return VERSION_ERROR; return VERSION_ERROR;
if (minor < ssl->options.minDowngrade) if (versionIsLesser(
isDtls, minor, ssl->options.minDowngrade))
return VERSION_ERROR; return VERSION_ERROR;
/* Downgrade the version. */ /* Downgrade the version. */
@@ -12768,7 +12871,9 @@ int TLSX_Parse(WOLFSSL* ssl, const byte* input, word16 length, byte msgType,
(void)heap; (void)heap;
WOLFSSL_ENTER("DTLS_server_method_ex"); WOLFSSL_ENTER("DTLS_server_method_ex");
if (method) { if (method) {
#if !defined(WOLFSSL_NO_TLS12) #if defined(WOLFSSL_DTLS13)
InitSSL_Method(method, MakeDTLSv1_3());
#elif !defined(WOLFSSL_NO_TLS12)
InitSSL_Method(method, MakeDTLSv1_2()); InitSSL_Method(method, MakeDTLSv1_2());
#elif !defined(NO_OLD_TLS) #elif !defined(NO_OLD_TLS)
InitSSL_Method(method, MakeDTLSv1()); InitSSL_Method(method, MakeDTLSv1());

View File

@@ -3088,10 +3088,22 @@ int SendTls13ClientHello(WOLFSSL* ssl)
#else #else
Sch13Args args[1]; Sch13Args args[1];
#endif #endif
byte major, tls12minor;
WOLFSSL_START(WC_FUNC_CLIENT_HELLO_SEND); WOLFSSL_START(WC_FUNC_CLIENT_HELLO_SEND);
WOLFSSL_ENTER("SendTls13ClientHello"); WOLFSSL_ENTER("SendTls13ClientHello");
major = SSLv3_MAJOR;
tls12minor = TLSv1_2_MINOR;
#ifdef WOLFSSL_DTLS13
if (ssl->options.dtls) {
major = DTLS_MAJOR;
tls12minor = DTLSv1_2_MINOR;
}
#endif /* WOLFSSL_DTLS */
if (ssl == NULL) { if (ssl == NULL) {
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
} }
@@ -3217,8 +3229,9 @@ int SendTls13ClientHello(WOLFSSL* ssl)
AddTls13Headers(args->output, args->length, client_hello, ssl); AddTls13Headers(args->output, args->length, client_hello, ssl);
/* Protocol version - negotiation now in extension: supported_versions. */ /* Protocol version - negotiation now in extension: supported_versions. */
args->output[args->idx++] = SSLv3_MAJOR; args->output[args->idx++] = major;
args->output[args->idx++] = TLSv1_2_MINOR; args->output[args->idx++] = tls12minor;
/* Keep for downgrade. */ /* Keep for downgrade. */
ssl->chVersion = ssl->version; ssl->chVersion = ssl->version;
@@ -3364,6 +3377,7 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
{ {
int ret; int ret;
byte suite[2]; byte suite[2];
byte tls12minor;
#ifdef WOLFSSL_ASYNC_CRYPT #ifdef WOLFSSL_ASYNC_CRYPT
Dsh13Args* args = NULL; Dsh13Args* args = NULL;
WOLFSSL_ASSERT_SIZEOF_GE(ssl->async->args, *args); WOLFSSL_ASSERT_SIZEOF_GE(ssl->async->args, *args);
@@ -3374,6 +3388,14 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
WOLFSSL_START(WC_FUNC_SERVER_HELLO_DO); WOLFSSL_START(WC_FUNC_SERVER_HELLO_DO);
WOLFSSL_ENTER("DoTls13ServerHello"); WOLFSSL_ENTER("DoTls13ServerHello");
tls12minor = TLSv1_2_MINOR;
#ifdef WOLFSSL_DTLS13
if (ssl->options.dtls)
tls12minor = DTLSv1_2_MINOR;
#endif /* WOLFSSL_DTLS13 */
if (ssl == NULL || ssl->arrays == NULL) if (ssl == NULL || ssl->arrays == NULL)
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
@@ -3428,18 +3450,37 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
args->idx += OPAQUE16_LEN; args->idx += OPAQUE16_LEN;
#ifndef WOLFSSL_NO_TLS12 #ifndef WOLFSSL_NO_TLS12
if (args->pv.major == ssl->version.major &&
args->pv.minor < TLSv1_2_MINOR &&
ssl->options.downgrade)
{ {
byte wantDowngrade;
wantDowngrade = args->pv.major == ssl->version.major &&
args->pv.minor < TLSv1_2_MINOR;
#ifdef WOLFSSL_DTLS13
if (ssl->options.dtls)
wantDowngrade = args->pv.major == ssl->version.major &&
args->pv.minor > DTLSv1_2_MINOR;
#endif /* WOLFSSL_DTLS13 */
if (wantDowngrade && ssl->options.downgrade) {
/* Force client hello version 1.2 to work for static RSA. */ /* Force client hello version 1.2 to work for static RSA. */
ssl->chVersion.minor = TLSv1_2_MINOR; ssl->chVersion.minor = TLSv1_2_MINOR;
ssl->version.minor = TLSv1_2_MINOR; ssl->version.minor = TLSv1_2_MINOR;
#ifdef WOLFSSL_DTLS13
if (ssl->options.dtls) {
ssl->chVersion.minor = DTLSv1_2_MINOR;
ssl->version.minor = DTLSv1_2_MINOR;
}
#endif /* WOLFSSL_DTLS13 */
return DoServerHello(ssl, input, inOutIdx, helloSz); return DoServerHello(ssl, input, inOutIdx, helloSz);
} }
}
#endif #endif
if (args->pv.major != ssl->version.major || if (args->pv.major != ssl->version.major ||
args->pv.minor != TLSv1_2_MINOR) { args->pv.minor != tls12minor) {
return VERSION_ERROR; return VERSION_ERROR;
} }
@@ -3502,6 +3543,14 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
/* Force client hello version 1.2 to work for static RSA. */ /* Force client hello version 1.2 to work for static RSA. */
ssl->chVersion.minor = TLSv1_2_MINOR; ssl->chVersion.minor = TLSv1_2_MINOR;
ssl->version.minor = TLSv1_2_MINOR; ssl->version.minor = TLSv1_2_MINOR;
#ifdef WOLFSSL_DTLS13
if (ssl->options.dtls) {
ssl->chVersion.minor = DTLSv1_2_MINOR;
ssl->version.minor = DTLSv1_2_MINOR;
}
#endif /* WOLFSSL_DTLS13 */
#endif #endif
ssl->options.haveEMS = 0; ssl->options.haveEMS = 0;
if (args->pv.minor < ssl->options.minDowngrade) if (args->pv.minor < ssl->options.minDowngrade)
@@ -3545,8 +3594,13 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
} }
#endif #endif
if (args->pv.minor < ssl->options.minDowngrade) if (!ssl->options.dtls &&
args->pv.minor < ssl->options.minDowngrade)
return VERSION_ERROR; return VERSION_ERROR;
if (ssl->options.dtls && args->pv.minor > ssl->options.minDowngrade)
return VERSION_ERROR;
ssl->version.minor = args->pv.minor; ssl->version.minor = args->pv.minor;
} }
} }
@@ -4739,6 +4793,9 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
XMEMCPY(&args->pv, input + args->idx, OPAQUE16_LEN); XMEMCPY(&args->pv, input + args->idx, OPAQUE16_LEN);
ssl->chVersion = args->pv; /* store */ ssl->chVersion = args->pv; /* store */
args->idx += OPAQUE16_LEN; args->idx += OPAQUE16_LEN;
/* this check pass for DTLS Major (0xff) */
if (args->pv.major < SSLv3_MAJOR) { if (args->pv.major < SSLv3_MAJOR) {
WOLFSSL_MSG("Legacy version field contains unsupported value"); WOLFSSL_MSG("Legacy version field contains unsupported value");
#ifdef WOLFSSL_MYSQL_COMPATIBLE #ifdef WOLFSSL_MYSQL_COMPATIBLE
@@ -4749,6 +4806,15 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
ERROR_OUT(INVALID_PARAMETER, exit_dch); ERROR_OUT(INVALID_PARAMETER, exit_dch);
} }
#ifdef WOLFSSL_DTLS13
if (ssl->options.dtls &&
args->pv.major == DTLS_MAJOR && args->pv.minor > DTLSv1_2_MINOR) {
wantDowngrade = 1;
ssl->version.minor = args->pv.minor;
}
#endif /* WOLFSSL_DTLS13 */
if (!ssl->options.dtls) {
/* Legacy protocol version cannot negotiate TLS 1.3 or higher. */ /* Legacy protocol version cannot negotiate TLS 1.3 or higher. */
if (args->pv.major > SSLv3_MAJOR || (args->pv.major == SSLv3_MAJOR && if (args->pv.major > SSLv3_MAJOR || (args->pv.major == SSLv3_MAJOR &&
args->pv.minor >= TLSv1_3_MINOR)) { args->pv.minor >= TLSv1_3_MINOR)) {
@@ -4758,16 +4824,20 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
ssl->version.minor = args->pv.minor; ssl->version.minor = args->pv.minor;
} }
/* Legacy version must be [ SSLv3_MAJOR, TLSv1_2_MINOR ] for TLS v1.3 */ /* Legacy version must be [ SSLv3_MAJOR, TLSv1_2_MINOR ] for TLS v1.3 */
else if (args->pv.major == SSLv3_MAJOR && args->pv.minor < TLSv1_2_MINOR) { else if (args->pv.major == SSLv3_MAJOR &&
args->pv.minor < TLSv1_2_MINOR) {
wantDowngrade = 1; wantDowngrade = 1;
ssl->version.minor = args->pv.minor; ssl->version.minor = args->pv.minor;
} }
else { }
if (!wantDowngrade) {
ret = DoTls13SupportedVersions(ssl, input + args->begin, ret = DoTls13SupportedVersions(ssl, input + args->begin,
args->idx - args->begin, helloSz, &wantDowngrade); args->idx - args->begin, helloSz, &wantDowngrade);
if (ret < 0) if (ret < 0)
goto exit_dch; goto exit_dch;
} }
if (wantDowngrade) { if (wantDowngrade) {
#ifndef WOLFSSL_NO_TLS12 #ifndef WOLFSSL_NO_TLS12
if (!ssl->options.downgrade) { if (!ssl->options.downgrade) {
@@ -4779,7 +4849,9 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
ERROR_OUT(VERSION_ERROR, exit_dch); ERROR_OUT(VERSION_ERROR, exit_dch);
} }
if (args->pv.minor < ssl->options.minDowngrade) { if ((!ssl->options.dtls
&& args->pv.minor < ssl->options.minDowngrade) ||
(ssl->options.dtls && args->pv.minor > ssl->options.minDowngrade)) {
WOLFSSL_MSG("\tversion below minimum allowed, fatal error"); WOLFSSL_MSG("\tversion below minimum allowed, fatal error");
#if defined(WOLFSSL_EXTRA_ALERTS) || defined(OPENSSL_EXTRA) #if defined(WOLFSSL_EXTRA_ALERTS) || defined(OPENSSL_EXTRA)
SendAlert(ssl, alert_fatal, handshake_failure); SendAlert(ssl, alert_fatal, handshake_failure);
@@ -5096,7 +5168,7 @@ int SendTls13ServerHello(WOLFSSL* ssl, byte extMsgType)
/* The protocol version must be TLS v1.2 for middleboxes. */ /* The protocol version must be TLS v1.2 for middleboxes. */
output[idx++] = ssl->version.major; output[idx++] = ssl->version.major;
output[idx++] = TLSv1_2_MINOR; output[idx++] = ssl->options.dtls ? DTLSv1_2_MINOR : TLSv1_2_MINOR;
if (extMsgType == server_hello) { if (extMsgType == server_hello) {
/* Generate server random. */ /* Generate server random. */

View File

@@ -1179,6 +1179,7 @@ enum Misc {
DTLS_MAJOR = 0xfe, /* DTLS major version number */ DTLS_MAJOR = 0xfe, /* DTLS major version number */
DTLS_MINOR = 0xff, /* DTLS minor version number */ DTLS_MINOR = 0xff, /* DTLS minor version number */
DTLSv1_2_MINOR = 0xfd, /* DTLS minor version number */ DTLSv1_2_MINOR = 0xfd, /* DTLS minor version number */
DTLSv1_3_MINOR = 0xfc, /* DTLS minor version number */
SSLv3_MAJOR = 3, /* SSLv3 and TLSv1+ major version number */ SSLv3_MAJOR = 3, /* SSLv3 and TLSv1+ major version number */
SSLv3_MINOR = 0, /* TLSv1 minor version number */ SSLv3_MINOR = 0, /* TLSv1 minor version number */
TLSv1_MINOR = 1, /* TLSv1 minor version number */ TLSv1_MINOR = 1, /* TLSv1 minor version number */
@@ -1497,6 +1498,11 @@ enum Misc {
#endif #endif
#endif #endif
/* minimum DTLS Downgrade Minor version */
#ifndef WOLFSSL_MIN_DTLS_DOWNGRADE
#define WOLFSSL_MIN_DTLS_DOWNGRADE DTLS_MINOR;
#endif
/* Set max implicit IV size for AEAD cipher suites */ /* Set max implicit IV size for AEAD cipher suites */
#define AEAD_MAX_IMP_SZ 12 #define AEAD_MAX_IMP_SZ 12
@@ -1666,6 +1672,10 @@ WOLFSSL_LOCAL ProtocolVersion MakeTLSv1_3(void);
WOLFSSL_LOCAL ProtocolVersion MakeDTLSv1(void); WOLFSSL_LOCAL ProtocolVersion MakeDTLSv1(void);
WOLFSSL_LOCAL ProtocolVersion MakeDTLSv1_2(void); WOLFSSL_LOCAL ProtocolVersion MakeDTLSv1_2(void);
#ifdef WOLFSSL_DTLS13
WOLFSSL_LOCAL ProtocolVersion MakeDTLSv1_3(void);
#endif /* WOLFSSL_DTLS13 */
#endif #endif
#ifdef WOLFSSL_SESSION_EXPORT #ifdef WOLFSSL_SESSION_EXPORT
WOLFSSL_LOCAL int wolfSSL_session_export_internal(WOLFSSL* ssl, byte* buf, WOLFSSL_LOCAL int wolfSSL_session_export_internal(WOLFSSL* ssl, byte* buf,
@@ -5228,6 +5238,9 @@ WOLFSSL_LOCAL int oid2nid(word32 oid, int grp);
WOLFSSL_LOCAL word32 nid2oid(int nid, int grp); WOLFSSL_LOCAL word32 nid2oid(int nid, int grp);
#endif #endif
#ifdef WOLFSSL_DTLS13
#endif /* WOLFSSL_DTLS13 */
#ifdef WOLFSSL_STATIC_EPHEMERAL #ifdef WOLFSSL_STATIC_EPHEMERAL
WOLFSSL_LOCAL int wolfSSL_StaticEphemeralKeyLoad(WOLFSSL* ssl, int keyAlgo, void* keyPtr); WOLFSSL_LOCAL int wolfSSL_StaticEphemeralKeyLoad(WOLFSSL* ssl, int keyAlgo, void* keyPtr);
#endif #endif

View File

@@ -865,6 +865,12 @@ WOLFSSL_API WOLFSSL_METHOD *wolfSSLv23_client_method_ex(void* heap);
WOLFSSL_API WOLFSSL_METHOD *wolfDTLSv1_2_method_ex(void* heap); WOLFSSL_API WOLFSSL_METHOD *wolfDTLSv1_2_method_ex(void* heap);
WOLFSSL_API WOLFSSL_METHOD *wolfDTLSv1_2_client_method_ex(void* heap); WOLFSSL_API WOLFSSL_METHOD *wolfDTLSv1_2_client_method_ex(void* heap);
WOLFSSL_API WOLFSSL_METHOD *wolfDTLSv1_2_server_method_ex(void* heap); WOLFSSL_API WOLFSSL_METHOD *wolfDTLSv1_2_server_method_ex(void* heap);
#ifdef WOLFSSL_DTLS13
WOLFSSL_API WOLFSSL_METHOD *wolfDTLSv1_3_client_method_ex(void* heap);
WOLFSSL_API WOLFSSL_METHOD *wolfDTLSv1_3_server_method_ex(void* heap);
#endif
#endif #endif
/* CTX Method Constructor Functions */ /* CTX Method Constructor Functions */
@@ -899,6 +905,12 @@ WOLFSSL_ABI WOLFSSL_API WOLFSSL_METHOD *wolfTLSv1_2_client_method(void);
WOLFSSL_API WOLFSSL_METHOD *wolfDTLSv1_2_method(void); WOLFSSL_API WOLFSSL_METHOD *wolfDTLSv1_2_method(void);
WOLFSSL_API WOLFSSL_METHOD *wolfDTLSv1_2_client_method(void); WOLFSSL_API WOLFSSL_METHOD *wolfDTLSv1_2_client_method(void);
WOLFSSL_API WOLFSSL_METHOD *wolfDTLSv1_2_server_method(void); WOLFSSL_API WOLFSSL_METHOD *wolfDTLSv1_2_server_method(void);
#ifdef WOLFSSL_DTLS13
WOLFSSL_API WOLFSSL_METHOD *wolfDTLSv1_3_client_method(void);
WOLFSSL_API WOLFSSL_METHOD *wolfDTLSv1_3_server_method(void);
#endif
#endif #endif
#ifdef HAVE_POLY1305 #ifdef HAVE_POLY1305
@@ -2995,6 +3007,7 @@ enum {
WOLFSSL_TLSV1_3 = 4, WOLFSSL_TLSV1_3 = 4,
WOLFSSL_DTLSV1 = 5, WOLFSSL_DTLSV1 = 5,
WOLFSSL_DTLSV1_2 = 6, WOLFSSL_DTLSV1_2 = 6,
WOLFSSL_DTLSV1_3 = 7,
WOLFSSL_USER_CA = 1, /* user added as trusted */ WOLFSSL_USER_CA = 1, /* user added as trusted */
WOLFSSL_CHAIN_CA = 2 /* added to cache from trusted chain */ WOLFSSL_CHAIN_CA = 2 /* added to cache from trusted chain */