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
#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 */

View File

@ -490,7 +490,15 @@ int IsAtLeastTLSv1_2(const WOLFSSL* ssl)
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)
@ -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->heap = ctx; /* defaults to self */
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) {
WOLFSSL_MSG("Mutex error on CTX init");
@ -8350,6 +8368,18 @@ ProtocolVersion MakeDTLSv1_2(void)
#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 */
@ -9416,6 +9446,7 @@ int CheckAvailableSize(WOLFSSL *ssl, int size)
static int GetRecordHeader(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
RecordLayerHeader* rh, word16 *size)
{
byte tls12minor;
#ifdef OPENSSL_ALL
word32 start = *inOutIdx;
#endif
@ -9469,13 +9500,18 @@ static int GetRecordHeader(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
}
#endif
tls12minor = TLSv1_2_MINOR;
#ifdef WOLFSSL_DTLS13
if (ssl->options.dtls)
tls12minor = DTLSv1_2_MINOR;
#endif /* WOLFSSL_DTLS13 */
/* catch version mismatch */
#ifndef WOLFSSL_TLS13
if (rh->pvMajor != ssl->version.major || rh->pvMinor != ssl->version.minor)
#else
if (rh->pvMajor != ssl->version.major ||
(rh->pvMinor != ssl->version.minor &&
(!IsAtLeastTLSv1_3(ssl->version) || rh->pvMinor != TLSv1_2_MINOR)
(!IsAtLeastTLSv1_3(ssl->version) || rh->pvMinor != tls12minor)
))
#endif
{
@ -9598,9 +9634,10 @@ int GetDtlsHandShakeHeader(WOLFSSL* ssl, const byte* input,
idx += DTLS_HANDSHAKE_FRAG_SZ;
c24to32(input + idx, fragSz);
if (ssl->curRL.pvMajor != ssl->version.major ||
ssl->curRL.pvMinor != ssl->version.minor) {
if ((ssl->curRL.pvMajor != ssl->version.major) ||
(!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) {
WOLFSSL_ERROR(VERSION_ERROR);
return VERSION_ERROR;
@ -30173,6 +30210,8 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
word32 i = *inOutIdx;
word32 begin = i;
int ret = 0;
byte lesserVersion;
#ifdef WOLFSSL_DTLS
Hmac cookieHmac;
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)
pv.minor = TLSv1_2_MINOR;
if ((!ssl->options.dtls && ssl->version.minor > pv.minor) ||
(ssl->options.dtls && ssl->version.minor != DTLS_MINOR
&& ssl->version.minor != DTLSv1_2_MINOR && pv.minor != DTLS_MINOR
&& pv.minor != DTLSv1_2_MINOR)) {
lesserVersion = !ssl->options.dtls && ssl->version.minor > pv.minor;
lesserVersion |= ssl->options.dtls && ssl->version.minor < pv.minor;
if (lesserVersion) {
byte belowMinDowngrade;
word16 haveRSA = 0;
word16 havePSK = 0;
int keySz = 0;
@ -30247,7 +30286,15 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
ret = VERSION_ERROR;
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");
#if defined(WOLFSSL_EXTRA_ALERTS) || defined(OPENSSL_EXTRA)
SendAlert(ssl, alert_fatal, handshake_failure);
@ -30256,26 +30303,46 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
goto out;
}
if (pv.minor == SSLv3_MINOR) {
/* turn off tls */
WOLFSSL_MSG("\tdowngrading to SSLv3");
ssl->options.tls = 0;
ssl->options.tls1_1 = 0;
ssl->version.minor = SSLv3_MINOR;
if (!ssl->options.dtls) {
if (pv.minor == SSLv3_MINOR) {
/* turn off tls */
WOLFSSL_MSG("\tdowngrading to SSLv3");
ssl->options.tls = 0;
ssl->options.tls1_1 = 0;
ssl->version.minor = SSLv3_MINOR;
}
else if (pv.minor == TLSv1_MINOR) {
/* turn off tls 1.1+ */
WOLFSSL_MSG("\tdowngrading to TLSv1");
ssl->options.tls1_1 = 0;
ssl->version.minor = TLSv1_MINOR;
}
else if (pv.minor == TLSv1_1_MINOR) {
WOLFSSL_MSG("\tdowngrading to TLSv1.1");
ssl->version.minor = TLSv1_1_MINOR;
}
else if (pv.minor == TLSv1_2_MINOR) {
WOLFSSL_MSG(" downgrading to TLSv1.2");
ssl->version.minor = TLSv1_2_MINOR;
}
}
else if (pv.minor == TLSv1_MINOR) {
/* turn off tls 1.1+ */
WOLFSSL_MSG("\tdowngrading to TLSv1");
ssl->options.tls1_1 = 0;
ssl->version.minor = TLSv1_MINOR;
}
else if (pv.minor == TLSv1_1_MINOR) {
WOLFSSL_MSG("\tdowngrading to TLSv1.1");
ssl->version.minor = TLSv1_1_MINOR;
}
else if (pv.minor == TLSv1_2_MINOR) {
WOLFSSL_MSG(" downgrading to TLSv1.2");
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
haveRSA = 1;

View File

@ -4516,6 +4516,18 @@ static int SetMinVersionHelper(byte* minVersion, int version)
break;
#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:
WOLFSSL_MSG("Bad function argument");
return BAD_FUNC_ARG;
@ -19795,6 +19807,8 @@ static const char* wolfSSL_internal_get_version(const ProtocolVersion* version)
return "DTLS";
case DTLSv1_2_MINOR :
return "DTLSv1.2";
case DTLSv1_3_MINOR :
return "DTLSv1.3";
default:
return "unknown";
}

169
src/tls.c
View File

@ -5628,6 +5628,58 @@ static int TLSX_UseSRTP(TLSX** extensions, word16 profiles, void* heap)
/******************************************************************************/
#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.
*
* 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)
{
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) {
/* TLS v1.2 and TLS v1.3 */
int cnt = 0;
if ((ssl->options.minDowngrade <= TLSv1_3_MINOR)
if (versionIsLessEqual(isDtls, ssl->options.minDowngrade, tls13Minor)
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
defined(WOLFSSL_WPAS_SMALL)
&& (ssl->options.mask & SSL_OP_NO_TLSv1_3) == 0
@ -5653,17 +5716,19 @@ static int TLSX_SupportedVersions_GetSize(void* data, byte msgType, word16* pSz)
if (ssl->options.downgrade) {
#ifndef WOLFSSL_NO_TLS12
if ((ssl->options.minDowngrade <= TLSv1_2_MINOR)
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
defined(WOLFSSL_WPAS_SMALL)
if (versionIsLessEqual(
isDtls, ssl->options.minDowngrade, tls12Minor)
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
defined(WOLFSSL_WPAS_SMALL)
&& (ssl->options.mask & SSL_OP_NO_TLSv1_2) == 0
#endif
#endif
) {
cnt++;
}
#endif
#endif
#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) || \
defined(WOLFSSL_WPAS_SMALL)
&& (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++;
}
#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) || \
defined(WOLFSSL_WPAS_SMALL)
&& (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;
byte major;
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) {
major = ssl->ctx->method->version.major;
@ -5716,11 +5799,11 @@ static int TLSX_SupportedVersions_Write(void* data, byte* output,
cnt = output++;
*cnt = 0;
if ((ssl->options.minDowngrade <= TLSv1_3_MINOR)
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
defined(WOLFSSL_WPAS_SMALL)
if (versionIsLessEqual(isDtls, ssl->options.minDowngrade, tls13minor)
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
defined(WOLFSSL_WPAS_SMALL)
&& (ssl->options.mask & SSL_OP_NO_TLSv1_3) == 0
#endif
#endif
) {
*cnt += OPAQUE16_LEN;
#ifdef WOLFSSL_TLS13_DRAFT
@ -5730,26 +5813,26 @@ static int TLSX_SupportedVersions_Write(void* data, byte* output,
*(output++) = TLS_DRAFT_MINOR;
#else
*(output++) = major;
*(output++) = (byte)TLSv1_3_MINOR;
*(output++) = tls13minor;
#endif
}
if (ssl->options.downgrade) {
#ifndef WOLFSSL_NO_TLS12
if ((ssl->options.minDowngrade <= TLSv1_2_MINOR)
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
if (versionIsLessEqual(isDtls, ssl->options.minDowngrade, tls12minor)
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
defined(WOLFSSL_WPAS_SMALL)
&& (ssl->options.mask & SSL_OP_NO_TLSv1_2) == 0
#endif
) {
*cnt += OPAQUE16_LEN;
*(output++) = major;
*(output++) = (byte)TLSv1_2_MINOR;
*(output++) = tls12minor;
}
#endif
#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) || \
defined(WOLFSSL_WPAS_SMALL)
&& (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;
*(output++) = major;
*(output++) = (byte)TLSv1_1_MINOR;
*(output++) = tls11minor;
}
#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) || \
defined(WOLFSSL_WPAS_SMALL)
&& (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 set = 0;
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) {
/* Must contain a length and at least one version. */
@ -5839,23 +5936,27 @@ static int TLSX_SupportedVersions_Parse(WOLFSSL* ssl, const byte* input,
continue;
/* No upgrade allowed. */
if (minor > ssl->version.minor)
if (versionIsGreater(isDtls, minor, ssl->version.minor))
continue;
/* Check downgrade. */
if (minor < ssl->version.minor) {
if (versionIsLesser(isDtls, minor, ssl->version.minor)) {
if (!ssl->options.downgrade)
continue;
if (minor < ssl->options.minDowngrade)
if (versionIsLesser(
isDtls, minor, ssl->options.minDowngrade))
continue;
if (newMinor == 0 && minor > ssl->options.oldMinor) {
if (newMinor == 0 &&
versionIsGreater(
isDtls, minor, ssl->options.oldMinor)) {
/* Downgrade the version. */
ssl->version.minor = minor;
}
}
if (minor >= TLSv1_3_MINOR) {
if (versionIsAtLeast(isDtls, minor, tls13minor)) {
if (!ssl->options.tls1_3) {
ssl->options.tls1_3 = 1;
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);
}
if (minor > newMinor) {
if (versionIsGreater(isDtls, minor, newMinor)) {
ssl->version.minor = minor;
newMinor = minor;
}
}
else if (minor > ssl->options.oldMinor)
else if (versionIsGreater(
isDtls, minor, ssl->options.oldMinor))
ssl->options.oldMinor = minor;
set = 1;
@ -5896,25 +5998,26 @@ static int TLSX_SupportedVersions_Parse(WOLFSSL* ssl, const byte* input,
return VERSION_ERROR;
/* Can't downgrade with this extension below TLS v1.3. */
if (minor < TLSv1_3_MINOR)
if (versionIsLesser(isDtls, minor, tls13minor))
return VERSION_ERROR;
/* 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+ */
ssl->version.minor = ssl->ctx->method->version.minor;
}
/* No upgrade allowed. */
if (ssl->version.minor < minor)
if (versionIsLesser(isDtls, ssl->version.minor, minor))
return VERSION_ERROR;
/* Check downgrade. */
if (ssl->version.minor > minor) {
if (versionIsGreater(isDtls, ssl->version.minor, minor)) {
if (!ssl->options.downgrade)
return VERSION_ERROR;
if (minor < ssl->options.minDowngrade)
if (versionIsLesser(
isDtls, minor, ssl->options.minDowngrade))
return VERSION_ERROR;
/* Downgrade the version. */
@ -12768,7 +12871,9 @@ int TLSX_Parse(WOLFSSL* ssl, const byte* input, word16 length, byte msgType,
(void)heap;
WOLFSSL_ENTER("DTLS_server_method_ex");
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());
#elif !defined(NO_OLD_TLS)
InitSSL_Method(method, MakeDTLSv1());

View File

@ -3088,10 +3088,22 @@ int SendTls13ClientHello(WOLFSSL* ssl)
#else
Sch13Args args[1];
#endif
byte major, tls12minor;
WOLFSSL_START(WC_FUNC_CLIENT_HELLO_SEND);
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) {
return BAD_FUNC_ARG;
}
@ -3217,8 +3229,9 @@ int SendTls13ClientHello(WOLFSSL* ssl)
AddTls13Headers(args->output, args->length, client_hello, ssl);
/* Protocol version - negotiation now in extension: supported_versions. */
args->output[args->idx++] = SSLv3_MAJOR;
args->output[args->idx++] = TLSv1_2_MINOR;
args->output[args->idx++] = major;
args->output[args->idx++] = tls12minor;
/* Keep for downgrade. */
ssl->chVersion = ssl->version;
@ -3364,6 +3377,7 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
{
int ret;
byte suite[2];
byte tls12minor;
#ifdef WOLFSSL_ASYNC_CRYPT
Dsh13Args* args = NULL;
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_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)
return BAD_FUNC_ARG;
@ -3428,18 +3450,37 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
args->idx += OPAQUE16_LEN;
#ifndef WOLFSSL_NO_TLS12
if (args->pv.major == ssl->version.major &&
args->pv.minor < TLSv1_2_MINOR &&
ssl->options.downgrade)
{
/* Force client hello version 1.2 to work for static RSA. */
ssl->chVersion.minor = TLSv1_2_MINOR;
ssl->version.minor = TLSv1_2_MINOR;
return DoServerHello(ssl, input, inOutIdx, helloSz);
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. */
ssl->chVersion.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);
}
}
#endif
if (args->pv.major != ssl->version.major ||
args->pv.minor != TLSv1_2_MINOR) {
args->pv.minor != tls12minor) {
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. */
ssl->chVersion.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
ssl->options.haveEMS = 0;
if (args->pv.minor < ssl->options.minDowngrade)
@ -3545,8 +3594,13 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
}
#endif
if (args->pv.minor < ssl->options.minDowngrade)
if (!ssl->options.dtls &&
args->pv.minor < ssl->options.minDowngrade)
return VERSION_ERROR;
if (ssl->options.dtls && args->pv.minor > ssl->options.minDowngrade)
return VERSION_ERROR;
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);
ssl->chVersion = args->pv; /* store */
args->idx += OPAQUE16_LEN;
/* this check pass for DTLS Major (0xff) */
if (args->pv.major < SSLv3_MAJOR) {
WOLFSSL_MSG("Legacy version field contains unsupported value");
#ifdef WOLFSSL_MYSQL_COMPATIBLE
@ -4749,25 +4806,38 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
ERROR_OUT(INVALID_PARAMETER, exit_dch);
}
/* Legacy protocol version cannot negotiate TLS 1.3 or higher. */
if (args->pv.major > SSLv3_MAJOR || (args->pv.major == SSLv3_MAJOR &&
args->pv.minor >= TLSv1_3_MINOR)) {
args->pv.major = SSLv3_MAJOR;
args->pv.minor = TLSv1_2_MINOR;
#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;
}
/* 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) {
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. */
if (args->pv.major > SSLv3_MAJOR || (args->pv.major == SSLv3_MAJOR &&
args->pv.minor >= TLSv1_3_MINOR)) {
args->pv.major = SSLv3_MAJOR;
args->pv.minor = TLSv1_2_MINOR;
wantDowngrade = 1;
ssl->version.minor = args->pv.minor;
}
/* 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) {
wantDowngrade = 1;
ssl->version.minor = args->pv.minor;
}
}
else {
if (!wantDowngrade) {
ret = DoTls13SupportedVersions(ssl, input + args->begin,
args->idx - args->begin, helloSz, &wantDowngrade);
if (ret < 0)
goto exit_dch;
}
if (wantDowngrade) {
#ifndef WOLFSSL_NO_TLS12
if (!ssl->options.downgrade) {
@ -4779,7 +4849,9 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
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");
#if defined(WOLFSSL_EXTRA_ALERTS) || defined(OPENSSL_EXTRA)
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. */
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) {
/* Generate server random. */

View File

@ -1179,6 +1179,7 @@ enum Misc {
DTLS_MAJOR = 0xfe, /* DTLS major version number */
DTLS_MINOR = 0xff, /* 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_MINOR = 0, /* TLSv1 minor version number */
TLSv1_MINOR = 1, /* TLSv1 minor version number */
@ -1497,6 +1498,11 @@ enum Misc {
#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 */
#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_2(void);
#ifdef WOLFSSL_DTLS13
WOLFSSL_LOCAL ProtocolVersion MakeDTLSv1_3(void);
#endif /* WOLFSSL_DTLS13 */
#endif
#ifdef WOLFSSL_SESSION_EXPORT
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);
#endif
#ifdef WOLFSSL_DTLS13
#endif /* WOLFSSL_DTLS13 */
#ifdef WOLFSSL_STATIC_EPHEMERAL
WOLFSSL_LOCAL int wolfSSL_StaticEphemeralKeyLoad(WOLFSSL* ssl, int keyAlgo, void* keyPtr);
#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_client_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
/* 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_client_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
#ifdef HAVE_POLY1305
@ -2995,6 +3007,7 @@ enum {
WOLFSSL_TLSV1_3 = 4,
WOLFSSL_DTLSV1 = 5,
WOLFSSL_DTLSV1_2 = 6,
WOLFSSL_DTLSV1_3 = 7,
WOLFSSL_USER_CA = 1, /* user added as trusted */
WOLFSSL_CHAIN_CA = 2 /* added to cache from trusted chain */