mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-30 18:57:27 +02:00
dtls13: new methods and version negotiation
This commit is contained in:
committed by
David Garske
parent
9d22e11776
commit
60834ba516
43
src/dtls13.c
43
src/dtls13.c
@ -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 */
|
||||
|
@ -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,6 +30303,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!ssl->options.dtls) {
|
||||
if (pv.minor == SSLv3_MINOR) {
|
||||
/* turn off tls */
|
||||
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");
|
||||
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;
|
||||
#endif
|
||||
|
14
src/ssl.c
14
src/ssl.c
@ -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";
|
||||
}
|
||||
|
153
src/tls.c
153
src/tls.c
@ -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,7 +5716,8 @@ 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 (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
|
||||
@ -5663,7 +5727,8 @@ static int TLSX_SupportedVersions_GetSize(void* data, byte msgType, word16* pSz)
|
||||
}
|
||||
#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,7 +5799,7 @@ static int TLSX_SupportedVersions_Write(void* data, byte* output,
|
||||
cnt = output++;
|
||||
*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
|
||||
@ -5730,13 +5813,13 @@ 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 (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
|
||||
@ -5744,12 +5827,12 @@ static int TLSX_SupportedVersions_Write(void* data, byte* output,
|
||||
) {
|
||||
*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());
|
||||
|
94
src/tls13.c
94
src/tls13.c
@ -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)
|
||||
{
|
||||
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,6 +4806,15 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
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. */
|
||||
if (args->pv.major > SSLv3_MAJOR || (args->pv.major == SSLv3_MAJOR &&
|
||||
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;
|
||||
}
|
||||
/* 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;
|
||||
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. */
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
Reference in New Issue
Block a user