forked from wolfSSL/wolfssl
dtls: support version negotiation
This commit is contained in:
@ -10015,7 +10015,7 @@ int GetDtlsHandShakeHeader(WOLFSSL* ssl, const byte* input,
|
||||
(!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 && *type != server_hello) {
|
||||
WOLFSSL_ERROR(VERSION_ERROR);
|
||||
return VERSION_ERROR;
|
||||
}
|
||||
@ -24669,6 +24669,7 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType,
|
||||
*/
|
||||
int CheckVersion(WOLFSSL *ssl, ProtocolVersion pv)
|
||||
{
|
||||
byte lowerVersion, higherVersion;
|
||||
#ifdef WOLFSSL_TLS13_DRAFT
|
||||
if (pv.major == TLS_DRAFT_MAJOR) {
|
||||
pv.major = SSLv3_MAJOR;
|
||||
@ -24682,11 +24683,24 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType,
|
||||
}
|
||||
#endif
|
||||
|
||||
if (pv.minor > ssl->version.minor) {
|
||||
if (ssl->options.dtls) {
|
||||
if (pv.major != DTLS_MAJOR || pv.minor == DTLS_BOGUS_MINOR)
|
||||
return VERSION_ERROR;
|
||||
lowerVersion = pv.minor > ssl->version.minor;
|
||||
higherVersion = pv.minor < ssl->version.minor;
|
||||
}
|
||||
else {
|
||||
if (pv.major != SSLv3_MAJOR)
|
||||
return VERSION_ERROR;
|
||||
lowerVersion = pv.minor < ssl->version.minor;
|
||||
higherVersion = pv.minor > ssl->version.minor;
|
||||
}
|
||||
|
||||
if (higherVersion) {
|
||||
WOLFSSL_MSG("Server using higher version, fatal error");
|
||||
return VERSION_ERROR;
|
||||
}
|
||||
if (pv.minor < ssl->version.minor) {
|
||||
if (lowerVersion) {
|
||||
WOLFSSL_MSG("server using lower version");
|
||||
|
||||
/* Check for downgrade attack. */
|
||||
@ -24694,7 +24708,8 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType,
|
||||
WOLFSSL_MSG("\tno downgrade allowed, fatal error");
|
||||
return VERSION_ERROR;
|
||||
}
|
||||
if (pv.minor < ssl->options.minDowngrade) {
|
||||
if ((!ssl->options.dtls && pv.minor < ssl->options.minDowngrade) ||
|
||||
(ssl->options.dtls && pv.minor > ssl->options.minDowngrade)) {
|
||||
WOLFSSL_MSG("\tversion below minimum allowed, fatal error");
|
||||
return VERSION_ERROR;
|
||||
}
|
||||
@ -24709,27 +24724,35 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType,
|
||||
#endif
|
||||
|
||||
/* Checks made - OK to downgrade. */
|
||||
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;
|
||||
}
|
||||
ssl->version.minor = pv.minor;
|
||||
switch(pv.minor) {
|
||||
case SSLv3_MINOR:
|
||||
/* turn off tls */
|
||||
WOLFSSL_MSG("\tdowngrading to SSLv3");
|
||||
ssl->options.tls = 0;
|
||||
ssl->options.tls1_1 = 0;
|
||||
break;
|
||||
case TLSv1_MINOR:
|
||||
/* turn off tls 1.1+ */
|
||||
WOLFSSL_MSG("\tdowngrading to TLSv1");
|
||||
ssl->options.tls1_1 = 0;
|
||||
break;
|
||||
case TLSv1_1_MINOR:
|
||||
WOLFSSL_MSG("\tdowngrading to TLSv1.1");
|
||||
break;
|
||||
case DTLS_MINOR:
|
||||
WOLFSSL_MSG("\tdowngrading to DTLSv1.1");
|
||||
break;
|
||||
case TLSv1_2_MINOR:
|
||||
WOLFSSL_MSG("\tdowngrading to TLSv1.2");
|
||||
break;
|
||||
case DTLSv1_2_MINOR:
|
||||
WOLFSSL_MSG("\tdowngrading to DTLSv1.2");
|
||||
break;
|
||||
default:
|
||||
WOLFSSL_MSG("\tbad minor version");
|
||||
return VERSION_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef OPENSSL_EXTRA
|
||||
|
@ -4516,17 +4516,19 @@ static int SetMinVersionHelper(byte* minVersion, int version)
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_DTLS13
|
||||
#ifdef WOLFSSL_DTLS
|
||||
case WOLFSSL_DTLSV1:
|
||||
*minVersion = DTLS_MINOR;
|
||||
break;
|
||||
case WOLFSSL_DTLSV1_2:
|
||||
*minVersion = DTLSv1_2_MINOR;
|
||||
break;
|
||||
#ifdef WOLFSSL_DTLS13
|
||||
case WOLFSSL_DTLSV1_3:
|
||||
*minVersion = DTLSv1_3_MINOR;
|
||||
break;
|
||||
#endif /* WOLFSSL_DTLS13 */
|
||||
#endif /* WOLFSSL_DTLS */
|
||||
|
||||
default:
|
||||
WOLFSSL_MSG("Bad function argument");
|
||||
|
10
src/tls13.c
10
src/tls13.c
@ -3659,6 +3659,10 @@ static int Dtls13DoDowngrade(WOLFSSL* ssl)
|
||||
XFREE(ssl->dtls13ClientHello, ssl->heap, DYNAMIC_TYPE_DTLS_MSG);
|
||||
ssl->dtls13ClientHello = NULL;
|
||||
ssl->dtls13ClientHelloSz = 0;
|
||||
ssl->keys.dtls_sequence_number_hi =
|
||||
w64GetHigh32(ssl->dtls13EncryptEpoch->nextSeqNumber);
|
||||
ssl->keys.dtls_sequence_number_lo =
|
||||
w64GetLow32(ssl->dtls13EncryptEpoch->nextSeqNumber);
|
||||
return ret;
|
||||
}
|
||||
#endif /* WOLFSSL_DTLS13 && !WOLFSSL_NO_CLIENT*/
|
||||
@ -3762,6 +3766,12 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
XMEMCPY(&args->pv, input + args->idx, OPAQUE16_LEN);
|
||||
args->idx += OPAQUE16_LEN;
|
||||
|
||||
#ifdef WOLFSSL_DTLS
|
||||
if (ssl->options.dtls &&
|
||||
(args->pv.major != DTLS_MAJOR || args->pv.minor == DTLS_BOGUS_MINOR))
|
||||
return VERSION_ERROR;
|
||||
#endif /* WOLFSSL_DTLS */
|
||||
|
||||
#ifndef WOLFSSL_NO_TLS12
|
||||
{
|
||||
byte wantDowngrade;
|
||||
|
@ -1205,6 +1205,7 @@ enum Misc {
|
||||
|
||||
DTLS_MAJOR = 0xfe, /* DTLS major version number */
|
||||
DTLS_MINOR = 0xff, /* DTLS minor version number */
|
||||
DTLS_BOGUS_MINOR = 0xfe, /* DTLS 0xfe was skipped, see RFC6347 Sec. 1 */
|
||||
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 */
|
||||
|
Reference in New Issue
Block a user