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 != ssl->version.minor) ||
|
||||||
(IsAtLeastTLSv1_3(ssl->version) && ssl->curRL.pvMinor != DTLSv1_2_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);
|
WOLFSSL_ERROR(VERSION_ERROR);
|
||||||
return VERSION_ERROR;
|
return VERSION_ERROR;
|
||||||
}
|
}
|
||||||
@ -24669,6 +24669,7 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType,
|
|||||||
*/
|
*/
|
||||||
int CheckVersion(WOLFSSL *ssl, ProtocolVersion pv)
|
int CheckVersion(WOLFSSL *ssl, ProtocolVersion pv)
|
||||||
{
|
{
|
||||||
|
byte lowerVersion, higherVersion;
|
||||||
#ifdef WOLFSSL_TLS13_DRAFT
|
#ifdef WOLFSSL_TLS13_DRAFT
|
||||||
if (pv.major == TLS_DRAFT_MAJOR) {
|
if (pv.major == TLS_DRAFT_MAJOR) {
|
||||||
pv.major = SSLv3_MAJOR;
|
pv.major = SSLv3_MAJOR;
|
||||||
@ -24682,11 +24683,24 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType,
|
|||||||
}
|
}
|
||||||
#endif
|
#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");
|
WOLFSSL_MSG("Server using higher version, fatal error");
|
||||||
return VERSION_ERROR;
|
return VERSION_ERROR;
|
||||||
}
|
}
|
||||||
if (pv.minor < ssl->version.minor) {
|
if (lowerVersion) {
|
||||||
WOLFSSL_MSG("server using lower version");
|
WOLFSSL_MSG("server using lower version");
|
||||||
|
|
||||||
/* Check for downgrade attack. */
|
/* Check for downgrade attack. */
|
||||||
@ -24694,7 +24708,8 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType,
|
|||||||
WOLFSSL_MSG("\tno downgrade allowed, fatal error");
|
WOLFSSL_MSG("\tno downgrade allowed, fatal error");
|
||||||
return VERSION_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");
|
WOLFSSL_MSG("\tversion below minimum allowed, fatal error");
|
||||||
return VERSION_ERROR;
|
return VERSION_ERROR;
|
||||||
}
|
}
|
||||||
@ -24709,27 +24724,35 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Checks made - OK to downgrade. */
|
/* Checks made - OK to downgrade. */
|
||||||
if (pv.minor == SSLv3_MINOR) {
|
ssl->version.minor = pv.minor;
|
||||||
/* turn off tls */
|
switch(pv.minor) {
|
||||||
WOLFSSL_MSG("\tdowngrading to SSLv3");
|
case SSLv3_MINOR:
|
||||||
ssl->options.tls = 0;
|
/* turn off tls */
|
||||||
ssl->options.tls1_1 = 0;
|
WOLFSSL_MSG("\tdowngrading to SSLv3");
|
||||||
ssl->version.minor = SSLv3_MINOR;
|
ssl->options.tls = 0;
|
||||||
}
|
ssl->options.tls1_1 = 0;
|
||||||
else if (pv.minor == TLSv1_MINOR) {
|
break;
|
||||||
/* turn off tls 1.1+ */
|
case TLSv1_MINOR:
|
||||||
WOLFSSL_MSG("\tdowngrading to TLSv1");
|
/* turn off tls 1.1+ */
|
||||||
ssl->options.tls1_1 = 0;
|
WOLFSSL_MSG("\tdowngrading to TLSv1");
|
||||||
ssl->version.minor = TLSv1_MINOR;
|
ssl->options.tls1_1 = 0;
|
||||||
}
|
break;
|
||||||
else if (pv.minor == TLSv1_1_MINOR) {
|
case TLSv1_1_MINOR:
|
||||||
WOLFSSL_MSG("\tdowngrading to TLSv1.1");
|
WOLFSSL_MSG("\tdowngrading to TLSv1.1");
|
||||||
ssl->version.minor = TLSv1_1_MINOR;
|
break;
|
||||||
}
|
case DTLS_MINOR:
|
||||||
else if (pv.minor == TLSv1_2_MINOR) {
|
WOLFSSL_MSG("\tdowngrading to DTLSv1.1");
|
||||||
WOLFSSL_MSG(" downgrading to TLSv1.2");
|
break;
|
||||||
ssl->version.minor = TLSv1_2_MINOR;
|
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
|
#ifdef OPENSSL_EXTRA
|
||||||
|
@ -4516,17 +4516,19 @@ static int SetMinVersionHelper(byte* minVersion, int version)
|
|||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WOLFSSL_DTLS13
|
#ifdef WOLFSSL_DTLS
|
||||||
case WOLFSSL_DTLSV1:
|
case WOLFSSL_DTLSV1:
|
||||||
*minVersion = DTLS_MINOR;
|
*minVersion = DTLS_MINOR;
|
||||||
break;
|
break;
|
||||||
case WOLFSSL_DTLSV1_2:
|
case WOLFSSL_DTLSV1_2:
|
||||||
*minVersion = DTLSv1_2_MINOR;
|
*minVersion = DTLSv1_2_MINOR;
|
||||||
break;
|
break;
|
||||||
|
#ifdef WOLFSSL_DTLS13
|
||||||
case WOLFSSL_DTLSV1_3:
|
case WOLFSSL_DTLSV1_3:
|
||||||
*minVersion = DTLSv1_3_MINOR;
|
*minVersion = DTLSv1_3_MINOR;
|
||||||
break;
|
break;
|
||||||
#endif /* WOLFSSL_DTLS13 */
|
#endif /* WOLFSSL_DTLS13 */
|
||||||
|
#endif /* WOLFSSL_DTLS */
|
||||||
|
|
||||||
default:
|
default:
|
||||||
WOLFSSL_MSG("Bad function argument");
|
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);
|
XFREE(ssl->dtls13ClientHello, ssl->heap, DYNAMIC_TYPE_DTLS_MSG);
|
||||||
ssl->dtls13ClientHello = NULL;
|
ssl->dtls13ClientHello = NULL;
|
||||||
ssl->dtls13ClientHelloSz = 0;
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif /* WOLFSSL_DTLS13 && !WOLFSSL_NO_CLIENT*/
|
#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);
|
XMEMCPY(&args->pv, input + args->idx, OPAQUE16_LEN);
|
||||||
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
|
#ifndef WOLFSSL_NO_TLS12
|
||||||
{
|
{
|
||||||
byte wantDowngrade;
|
byte wantDowngrade;
|
||||||
|
@ -1205,6 +1205,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 */
|
||||||
|
DTLS_BOGUS_MINOR = 0xfe, /* DTLS 0xfe was skipped, see RFC6347 Sec. 1 */
|
||||||
DTLSv1_2_MINOR = 0xfd, /* DTLS minor version number */
|
DTLSv1_2_MINOR = 0xfd, /* DTLS minor version number */
|
||||||
DTLSv1_3_MINOR = 0xfc, /* 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 */
|
||||||
|
Reference in New Issue
Block a user