dtls: support version negotiation

This commit is contained in:
Marco Oliverio
2022-07-04 17:07:39 +02:00
parent 8fe3f51ecb
commit df7e81d187
4 changed files with 62 additions and 26 deletions

View File

@ -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

View File

@ -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");

View File

@ -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;

View File

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