Support FFDHE in TLS 1.2 and below. Better TLS 1.3 version support.

Add support for the fixed FFDHE curves to TLS 1.2. Same curves in TLS
1.3 already. On by default - no checking of prime required.
Add option to require client to see FFDHE parameters from server as per
'may' requirements in RFC 7919.

Change TLS 1.3 ClientHello and ServerHello parsing to find the
SupportedVersions extension first and process it. Then it can handle
other extensions knowing which protocol we are using.
This commit is contained in:
Sean Parkinson
2019-02-18 10:57:12 +10:00
parent 25dd5882f8
commit 7aa5cd6f10
11 changed files with 551 additions and 317 deletions

View File

@@ -193,7 +193,7 @@ then
AM_CFLAGS="$AM_CFLAGS -DHAVE_AES_DECRYPT -DHAVE_AES_ECB -DWOLFSSL_ALT_NAMES -DWOLFSSL_DER_LOAD -DKEEP_OUR_CERT -DKEEP_PEER_CERT -DHAVE_CRL_IO -DHAVE_IO_TIMEOUT"
# Enable DH const table speedups (eliminates `-lm` math lib dependency)
AM_CFLAGS="$AM_CFLAGS -DHAVE_FFDHE_2048 -DHAVE_FFDHE_3072 -DHAVE_FFDHE_4096 -DHAVE_FFDHE_6144 -DHAVE_FFDHE_8192"
AM_CFLAGS="$AM_CFLAGS -DHAVE_FFDHE_2048 -DHAVE_FFDHE_3072 -DFP_MAX_BITS=6144"
fi
AM_CONDITIONAL([BUILD_ALL], [test "x$ENABLED_ALL" = "xyes"])
@@ -1908,11 +1908,6 @@ else
fi
fi
if test "$ENABLED_TLS13" = "yes" && test "$ENABLED_DH" = "yes"
then
AM_CFLAGS="-DHAVE_FFDHE_2048 $AM_CFLAGS"
fi
AM_CONDITIONAL([BUILD_DH], [test "x$ENABLED_DH" = "xyes"])
@@ -2921,6 +2916,35 @@ then
[AM_CFLAGS="$AM_CFLAGS -DHAVE_TLS_EXTENSIONS -DHAVE_SUPPORTED_CURVES"])
fi
# Diffie-Hellman
if test "$ENABLED_DH" = "yes"
then
if test "$ENABLED_TLS13" = "yes" || test "$ENABLED_SUPPORTED_CURVES" = "yes"
then
AM_CFLAGS="-DHAVE_FFDHE_2048 $AM_CFLAGS"
fi
fi
# FFDHE parameters only
AC_ARG_ENABLE([ffdhe-only],
[AS_HELP_STRING([--enable-ffdhe-only],[Enable using only FFDHE in client (default: disabled)])],
[ ENABLED_FFDHE_ONLY=$enableval ],
[ ENABLED_FFDHE_ONLY=no ]
)
if test "x$ENABLED_FFDHE_ONLY" = "xyes"
then
if test "$ENABLED_DH" = "no"
then
AC_MSG_ERROR([FFDHE only support requires DH support])
fi
if test "$ENABLED_SUPPORTED_CURVES" = "no"
then
AC_MSG_ERROR([FFDHE only support requires Supported Curves extension])
fi
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_REQUIRE_FFDHE"
fi
# Session Ticket Extension
AC_ARG_ENABLE([session-ticket],
[AS_HELP_STRING([--enable-session-ticket],[Enable Session Ticket (default: disabled)])],
@@ -4904,6 +4928,7 @@ echo " * ALPN: $ENABLED_ALPN"
echo " * Maximum Fragment Length: $ENABLED_MAX_FRAGMENT"
echo " * Truncated HMAC: $ENABLED_TRUNCATED_HMAC"
echo " * Supported Elliptic Curves: $ENABLED_SUPPORTED_CURVES"
echo " * FFDHE only in client: $ENABLED_FFDHE_ONLY"
echo " * Session Ticket: $ENABLED_SESSION_TICKET"
echo " * Extended Master Secret: $ENABLED_EXTENDED_MASTER"
echo " * Renegotiation Indication: $ENABLED_RENEGOTIATION_INDICATION"

View File

@@ -1361,9 +1361,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
int doSTARTTLS = 0;
char* starttlsProt = NULL;
int useVerifyCb = 0;
#ifdef HAVE_ECC
int useSupCurve = 0;
#endif
#ifdef WOLFSSL_TRUST_PEER_CERT
const char* trustCert = NULL;
@@ -1466,9 +1464,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
(void)useX25519;
(void)helloRetry;
(void)onlyKeyShare;
#ifdef HAVE_ECC
(void)useSupCurve;
#endif
(void)loadCertKeyIntoSSLObj;
StackTrap();
@@ -1617,12 +1613,10 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
printf("Verify should fail\n");
myVerifyFail = 1;
}
#ifdef HAVE_ECC
else if (XSTRNCMP(myoptarg, "useSupCurve", 11) == 0) {
printf("Test use supported curve\n");
useSupCurve = 1;
}
#endif
else if (XSTRNCMP(myoptarg, "loadSSL", 7) == 0) {
printf("Load cert/key into wolfSSL object\n");
#ifndef NO_CERTS
@@ -2395,6 +2389,14 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
#endif
}
#endif /* HAVE_ECC */
#ifdef HAVE_FFDHE_2048
if (useSupCurve) {
if (wolfSSL_CTX_UseSupportedCurve(ctx, WOLFSSL_FFDHE_2048)
!= WOLFSSL_SUCCESS) {
err_sys("unable to support FFDHE 2048");
}
}
#endif
#endif /* HAVE_SUPPORTED_CURVES */
#ifdef WOLFSSL_TLS13

View File

@@ -15886,6 +15886,9 @@ const char* wolfSSL_ERR_reason_error_string(unsigned long e)
case DTLS_RETX_OVER_TX:
return "DTLS interrupting flight transmit with retransmit";
case DH_PARAMS_NOT_FFDHE_E:
return "Server DH parameters were not from the FFDHE set as required";
default :
return "unknown error number";
}
@@ -18041,7 +18044,6 @@ exit_dpk:
#endif /* HAVE_ECC */
/* Persistable DoServerKeyExchange arguments */
typedef struct DskeArgs {
byte* output; /* not allocated */
@@ -18073,6 +18075,168 @@ static void FreeDskeArgs(WOLFSSL* ssl, void* pArgs)
#endif
}
#ifndef NO_DH
static int GetDhPublicKey(WOLFSSL* ssl, const byte* input, word32 size,
DskeArgs* args)
{
int ret = 0;
word16 length;
#ifdef HAVE_FFDHE
const DhParams* params = NULL;
int group;
#endif
/* p */
if ((args->idx - args->begin) + OPAQUE16_LEN > size) {
ERROR_OUT(BUFFER_ERROR, exit_gdpk);
}
ato16(input + args->idx, &length);
args->idx += OPAQUE16_LEN;
if ((args->idx - args->begin) + length > size) {
ERROR_OUT(BUFFER_ERROR, exit_gdpk);
}
if (length < ssl->options.minDhKeySz) {
WOLFSSL_MSG("Server using a DH key that is too small");
SendAlert(ssl, alert_fatal, handshake_failure);
ERROR_OUT(DH_KEY_SIZE_E, exit_gdpk);
}
if (length > ssl->options.maxDhKeySz) {
WOLFSSL_MSG("Server using a DH key that is too big");
SendAlert(ssl, alert_fatal, handshake_failure);
ERROR_OUT(DH_KEY_SIZE_E, exit_gdpk);
}
ssl->buffers.serverDH_P.buffer =
(byte*)XMALLOC(length, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
if (ssl->buffers.serverDH_P.buffer) {
ssl->buffers.serverDH_P.length = length;
}
else {
ERROR_OUT(MEMORY_ERROR, exit_gdpk);
}
XMEMCPY(ssl->buffers.serverDH_P.buffer, input + args->idx,
length);
args->idx += length;
ssl->options.dhKeySz = length;
/* g */
if ((args->idx - args->begin) + OPAQUE16_LEN > size) {
ERROR_OUT(BUFFER_ERROR, exit_gdpk);
}
ato16(input + args->idx, &length);
args->idx += OPAQUE16_LEN;
if ((args->idx - args->begin) + length > size) {
ERROR_OUT(BUFFER_ERROR, exit_gdpk);
}
ssl->buffers.serverDH_G.buffer =
(byte*)XMALLOC(length, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
if (ssl->buffers.serverDH_G.buffer) {
ssl->buffers.serverDH_G.length = length;
}
else {
ERROR_OUT(MEMORY_ERROR, exit_gdpk);
}
XMEMCPY(ssl->buffers.serverDH_G.buffer, input + args->idx,
length);
args->idx += length;
ssl->buffers.weOwnDH = 1;
/* pub */
if ((args->idx - args->begin) + OPAQUE16_LEN > size) {
ERROR_OUT(BUFFER_ERROR, exit_gdpk);
}
ato16(input + args->idx, &length);
args->idx += OPAQUE16_LEN;
if ((args->idx - args->begin) + length > size) {
ERROR_OUT(BUFFER_ERROR, exit_gdpk);
}
ssl->buffers.serverDH_Pub.buffer =
(byte*)XMALLOC(length, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
if (ssl->buffers.serverDH_Pub.buffer) {
ssl->buffers.serverDH_Pub.length = length;
}
else {
ERROR_OUT(MEMORY_ERROR, exit_gdpk);
}
XMEMCPY(ssl->buffers.serverDH_Pub.buffer, input + args->idx,
length);
args->idx += length;
#ifdef HAVE_FFDHE
switch (ssl->options.dhKeySz) {
#ifdef HAVE_FFDHE_2048
case 2048/8:
params = wc_Dh_ffdhe2048_Get();
group = WOLFSSL_FFDHE_2048;
break;
#endif
#ifdef HAVE_FFDHE_3072
case 3072/8:
params = wc_Dh_ffdhe3072_Get();
group = WOLFSSL_FFDHE_3072;
break;
#endif
#ifdef HAVE_FFDHE_4096
case 4096/8:
params = wc_Dh_ffdhe4096_Get();
group = WOLFSSL_FFDHE_4096;
break;
#endif
#ifdef HAVE_FFDHE_6144
case 6144/8:
params = wc_Dh_ffdhe6144_Get();
group = WOLFSSL_FFDHE_6144;
break;
#endif
#ifdef HAVE_FFDHE_8192
case 8192/8:
params = wc_Dh_ffdhe8192_Get();
group = WOLFSSL_FFDHE_8192;
break;
#endif
default:
break;
}
if (params == NULL || params->g_len != ssl->buffers.serverDH_G.length ||
(XMEMCMP(ssl->buffers.serverDH_G.buffer, params->g,
params->g_len) != 0) ||
(XMEMCMP(ssl->buffers.serverDH_P.buffer, params->p,
params->p_len) != 0)) {
WOLFSSL_MSG("Server not using FFDHE parameters");
#ifdef WOLFSSL_REQUIRE_FFDHE
SendAlert(ssl, alert_fatal, handshake_failure);
ERROR_OUT(DH_PARAMS_NOT_FFDHE_E, exit_gdpk);
#endif
}
else {
ssl->namedGroup = group;
#if !defined(WOLFSSL_OLD_PRIME_CHECK) && !defined(HAVE_FIPS) && \
!defined(HAVE_SELFTEST)
ssl->options.dhDoKeyTest = 0;
#endif
}
#endif /* HAVE_FFDHE */
exit_gdpk:
return ret;
}
#endif
/* handle processing of server_key_exchange (12) */
static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input,
word32* inOutIdx, word32 size)
@@ -18157,97 +18321,9 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input,
#ifndef NO_DH
case diffie_hellman_kea:
{
word16 length;
/* p */
if ((args->idx - args->begin) + OPAQUE16_LEN > size) {
ERROR_OUT(BUFFER_ERROR, exit_dske);
}
ato16(input + args->idx, &length);
args->idx += OPAQUE16_LEN;
if ((args->idx - args->begin) + length > size) {
ERROR_OUT(BUFFER_ERROR, exit_dske);
}
if (length < ssl->options.minDhKeySz) {
WOLFSSL_MSG("Server using a DH key that is too small");
SendAlert(ssl, alert_fatal, handshake_failure);
ERROR_OUT(DH_KEY_SIZE_E, exit_dske);
}
if (length > ssl->options.maxDhKeySz) {
WOLFSSL_MSG("Server using a DH key that is too big");
SendAlert(ssl, alert_fatal, handshake_failure);
ERROR_OUT(DH_KEY_SIZE_E, exit_dske);
}
ssl->buffers.serverDH_P.buffer =
(byte*)XMALLOC(length, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
if (ssl->buffers.serverDH_P.buffer) {
ssl->buffers.serverDH_P.length = length;
}
else {
ERROR_OUT(MEMORY_ERROR, exit_dske);
}
XMEMCPY(ssl->buffers.serverDH_P.buffer, input + args->idx,
length);
args->idx += length;
ssl->options.dhKeySz = length;
/* g */
if ((args->idx - args->begin) + OPAQUE16_LEN > size) {
ERROR_OUT(BUFFER_ERROR, exit_dske);
}
ato16(input + args->idx, &length);
args->idx += OPAQUE16_LEN;
if ((args->idx - args->begin) + length > size) {
ERROR_OUT(BUFFER_ERROR, exit_dske);
}
ssl->buffers.serverDH_G.buffer =
(byte*)XMALLOC(length, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
if (ssl->buffers.serverDH_G.buffer) {
ssl->buffers.serverDH_G.length = length;
}
else {
ERROR_OUT(MEMORY_ERROR, exit_dske);
}
XMEMCPY(ssl->buffers.serverDH_G.buffer, input + args->idx,
length);
args->idx += length;
ssl->buffers.weOwnDH = 1;
/* pub */
if ((args->idx - args->begin) + OPAQUE16_LEN > size) {
ERROR_OUT(BUFFER_ERROR, exit_dske);
}
ato16(input + args->idx, &length);
args->idx += OPAQUE16_LEN;
if ((args->idx - args->begin) + length > size) {
ERROR_OUT(BUFFER_ERROR, exit_dske);
}
ssl->buffers.serverDH_Pub.buffer =
(byte*)XMALLOC(length, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
if (ssl->buffers.serverDH_Pub.buffer) {
ssl->buffers.serverDH_Pub.length = length;
}
else {
ERROR_OUT(MEMORY_ERROR, exit_dske);
}
XMEMCPY(ssl->buffers.serverDH_Pub.buffer, input + args->idx,
length);
args->idx += length;
ret = GetDhPublicKey(ssl, input, size, args);
if (ret != 0)
goto exit_dske;
break;
}
#endif /* !NO_DH */
@@ -18362,98 +18438,12 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input,
ssl->arrays->server_hint[srvHintLen] = '\0'; /* null term */
args->idx += length;
/* p */
if ((args->idx - args->begin) + OPAQUE16_LEN > size) {
ERROR_OUT(BUFFER_ERROR, exit_dske);
}
ato16(input + args->idx, &length);
args->idx += OPAQUE16_LEN;
if ((args->idx - args->begin) + length > size) {
ERROR_OUT(BUFFER_ERROR, exit_dske);
}
if (length < ssl->options.minDhKeySz) {
WOLFSSL_MSG("Server using a DH key that is too small");
SendAlert(ssl, alert_fatal, handshake_failure);
ERROR_OUT(DH_KEY_SIZE_E, exit_dske);
}
if (length > ssl->options.maxDhKeySz) {
WOLFSSL_MSG("Server using a DH key that is too big");
SendAlert(ssl, alert_fatal, handshake_failure);
ERROR_OUT(DH_KEY_SIZE_E, exit_dske);
}
ssl->buffers.serverDH_P.buffer = (byte*)XMALLOC(length,
ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
if (ssl->buffers.serverDH_P.buffer) {
ssl->buffers.serverDH_P.length = length;
}
else {
ERROR_OUT(MEMORY_ERROR, exit_dske);
}
XMEMCPY(ssl->buffers.serverDH_P.buffer, input + args->idx,
length);
args->idx += length;
ssl->options.dhKeySz = length;
/* g */
if ((args->idx - args->begin) + OPAQUE16_LEN > size) {
ERROR_OUT(BUFFER_ERROR, exit_dske);
}
ato16(input + args->idx, &length);
args->idx += OPAQUE16_LEN;
if ((args->idx - args->begin) + length > size) {
ERROR_OUT(BUFFER_ERROR, exit_dske);
}
ssl->buffers.serverDH_G.buffer = (byte*)XMALLOC(length,
ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
if (ssl->buffers.serverDH_G.buffer) {
ssl->buffers.serverDH_G.length = length;
}
else {
ERROR_OUT(MEMORY_ERROR, exit_dske);
}
XMEMCPY(ssl->buffers.serverDH_G.buffer, input + args->idx,
length);
args->idx += length;
ssl->buffers.weOwnDH = 1;
/* pub */
if ((args->idx - args->begin) + OPAQUE16_LEN > size) {
ERROR_OUT(BUFFER_ERROR, exit_dske);
}
ato16(input + args->idx, &length);
args->idx += OPAQUE16_LEN;
if ((args->idx - args->begin) + length > size) {
ERROR_OUT(BUFFER_ERROR, exit_dske);
}
ssl->buffers.serverDH_Pub.buffer = (byte*)XMALLOC(length,
ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
if (ssl->buffers.serverDH_Pub.buffer) {
ssl->buffers.serverDH_Pub.length = length;
}
else {
ERROR_OUT(MEMORY_ERROR, exit_dske);
}
XMEMCPY(ssl->buffers.serverDH_Pub.buffer, input + args->idx,
length);
args->idx += length;
ret = GetDhPublicKey(ssl, input, size, args);
if (ret != 0)
goto exit_dske;
break;
}
#endif /* !NO_DH || !NO_PSK */
#endif /* !NO_DH && !NO_PSK */
#if (defined(HAVE_ECC) || defined(HAVE_CURVE25519)) && \
!defined(NO_PSK)
case ecdhe_psk_kea:
@@ -23934,6 +23924,13 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
}
ret = MatchSuite(ssl, &clSuites);
#if defined(HAVE_FFDHE) && defined(HAVE_SUPPORTED_CURVES)
if (ret == 0 && (ssl->specs.kea == diffie_hellman_kea ||
ssl->specs.kea == dhe_psk_kea)) {
ret = TLSX_SupportedFFDHE_Set(ssl);
}
#endif
#ifdef HAVE_SECURE_RENEGOTIATION
if (ssl->secure_renegotiation && ssl->secure_renegotiation->enabled &&
IsEncryptionOn(ssl, 0)) {

View File

@@ -2099,18 +2099,13 @@ int wolfSSL_UseSupportedCurve(WOLFSSL* ssl, word16 name)
case WOLFSSL_ECC_BRAINPOOLP384R1:
case WOLFSSL_ECC_BRAINPOOLP512R1:
case WOLFSSL_ECC_X25519:
break;
#ifdef WOLFSSL_TLS13
case WOLFSSL_FFDHE_2048:
case WOLFSSL_FFDHE_3072:
case WOLFSSL_FFDHE_4096:
case WOLFSSL_FFDHE_6144:
case WOLFSSL_FFDHE_8192:
if (!IsAtLeastTLSv1_3(ssl->version))
return WOLFSSL_SUCCESS;
break;
#endif
default:
return BAD_FUNC_ARG;
@@ -2143,16 +2138,12 @@ int wolfSSL_CTX_UseSupportedCurve(WOLFSSL_CTX* ctx, word16 name)
case WOLFSSL_ECC_BRAINPOOLP384R1:
case WOLFSSL_ECC_BRAINPOOLP512R1:
case WOLFSSL_ECC_X25519:
break;
#ifdef WOLFSSL_TLS13
case WOLFSSL_FFDHE_2048:
case WOLFSSL_FFDHE_3072:
case WOLFSSL_FFDHE_4096:
case WOLFSSL_FFDHE_6144:
case WOLFSSL_FFDHE_8192:
break;
#endif
default:
return BAD_FUNC_ARG;
@@ -16237,7 +16228,31 @@ const char* wolfSSL_get_cipher_name_from_suite(const byte cipherSuite0,
}
#ifdef HAVE_ECC
#if defined(HAVE_ECC) || !defined(NO_DH)
#ifdef HAVE_FFDHE
static const char* wolfssl_ffdhe_name(word16 group)
{
const char* str = NULL;
switch (group) {
case WOLFSSL_FFDHE_2048:
str = "FFDHE_2048";
break;
case WOLFSSL_FFDHE_3072:
str = "FFDHE_3072";
break;
case WOLFSSL_FFDHE_4096:
str = "FFDHE_4096";
break;
case WOLFSSL_FFDHE_6144:
str = "FFDHE_6144";
break;
case WOLFSSL_FFDHE_8192:
str = "FFDHE_8192";
break;
}
return str;
}
#endif
/* Return the name of the curve used for key exchange as a printable string.
*
* ssl The SSL/TLS object.
@@ -16247,14 +16262,19 @@ const char* wolfSSL_get_curve_name(WOLFSSL* ssl)
{
if (ssl == NULL)
return NULL;
if (!IsAtLeastTLSv1_3(ssl->version) && ssl->specs.kea != ecdhe_psk_kea &&
ssl->specs.kea != ecc_diffie_hellman_kea)
return NULL;
#ifdef HAVE_FFDHE
if (ssl->namedGroup != 0)
return wolfssl_ffdhe_name(ssl->namedGroup);
#endif
#ifdef HAVE_ECC
if (ssl->ecdhCurveOID == 0)
return NULL;
if (ssl->ecdhCurveOID == ECC_X25519_OID)
return "X25519";
return wc_ecc_get_name(wc_ecc_get_oid(ssl->ecdhCurveOID, NULL, NULL));
#else
return NULL;
#endif
}
#endif

331
src/tls.c
View File

@@ -3271,9 +3271,10 @@ int TLSX_UseCertificateStatusRequestV2(TLSX** extensions, byte status_type,
#ifdef HAVE_SUPPORTED_CURVES
#if !defined(HAVE_ECC) && !defined(HAVE_CURVE25519) && !defined(WOLFSSL_TLS13)
#if !defined(HAVE_ECC) && !defined(HAVE_CURVE25519) && !defined(HAVE_FFDHE)
#error Elliptic Curves Extension requires Elliptic Curve Cryptography. \
Use --enable-ecc in the configure script or define HAVE_ECC.
Use --enable-ecc in the configure script or define HAVE_ECC. \
Alternatively use FFDHE for DH ciperhsuites.
#endif
static int TLSX_SupportedCurve_New(SupportedCurve** curve, word16 name,
@@ -3384,11 +3385,21 @@ static void TLSX_SupportedCurve_ValidateRequest(WOLFSSL* ssl, byte* semaphore)
{
int i;
for (i = 0; i < ssl->suites->suiteSz; i+= 2)
if (ssl->suites->suites[i] == ECC_BYTE ||
ssl->suites->suites[i] == CHACHA_BYTE ||
ssl->suites->suites[i] == TLS13_BYTE)
for (i = 0; i < ssl->suites->suiteSz; i+= 2) {
if (ssl->suites->suites[i] == TLS13_BYTE)
return;
if (ssl->suites->suites[i] == ECC_BYTE ||
ssl->suites->suites[i] == CHACHA_BYTE) {
#if defined(HAVE_ECC) || defined(HAVE_CURVE25519)
return;
#endif
}
else {
#ifdef HAVE_FFDHE
return;
#endif
}
}
/* turns semaphore on to avoid sending this extension. */
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_GROUPS));
@@ -3398,11 +3409,21 @@ static void TLSX_PointFormat_ValidateRequest(WOLFSSL* ssl, byte* semaphore)
{
int i;
for (i = 0; i < ssl->suites->suiteSz; i+= 2)
if (ssl->suites->suites[i] == ECC_BYTE ||
ssl->suites->suites[i] == CHACHA_BYTE ||
ssl->suites->suites[i] == TLS13_BYTE)
for (i = 0; i < ssl->suites->suiteSz; i+= 2) {
if (ssl->suites->suites[i] == TLS13_BYTE)
return;
if (ssl->suites->suites[i] == ECC_BYTE ||
ssl->suites->suites[i] == CHACHA_BYTE) {
#if defined(HAVE_ECC) || defined(HAVE_CURVE25519)
return;
#endif
}
else {
#ifdef HAVE_FFDHE
return;
#endif
}
}
/* turns semaphore on to avoid sending this extension. */
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_EC_POINT_FORMATS));
@@ -3414,10 +3435,19 @@ static void TLSX_PointFormat_ValidateRequest(WOLFSSL* ssl, byte* semaphore)
static void TLSX_PointFormat_ValidateResponse(WOLFSSL* ssl, byte* semaphore)
{
if (ssl->options.cipherSuite0 == ECC_BYTE ||
ssl->options.cipherSuite0 == CHACHA_BYTE ||
ssl->options.cipherSuite0 == TLS13_BYTE)
if (ssl->options.cipherSuite0 == TLS13_BYTE)
return;
if (ssl->options.cipherSuite0 == ECC_BYTE ||
ssl->options.cipherSuite0 == CHACHA_BYTE) {
#if defined(HAVE_ECC) || defined(HAVE_CURVE25519)
return;
#endif
}
else {
#ifdef HAVE_FFDHE
return;
#endif
}
/* turns semaphore on to avoid sending this extension. */
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_EC_POINT_FORMATS));
@@ -3554,8 +3584,9 @@ static int TLSX_SupportedCurve_Parse(WOLFSSL* ssl, byte* input, word16 length,
#endif
#if !defined(NO_WOLFSSL_SERVER) && defined(WOLFSSL_TLS13) && \
!defined(WOLFSSL_NO_SERVER_GROUPS_EXT)
#if !defined(NO_WOLFSSL_SERVER)
#if defined(WOLFSSL_TLS13) && !defined(WOLFSSL_NO_SERVER_GROUPS_EXT)
/* Checks the priority of the groups on the server and set the supported groups
* response if there is a group not advertised by the client that is preferred.
@@ -3608,6 +3639,118 @@ int TLSX_SupportedCurve_CheckPriority(WOLFSSL* ssl)
#endif
#if defined(HAVE_FFDHE) && !defined(WOLFSSL_NO_TLS12)
/* Set the highest priority common FFDHE group on the server as compared to
* client extensions.
*
* ssl SSL/TLS object.
* returns 0 on success, otherwise an error.
*/
int TLSX_SupportedFFDHE_Set(WOLFSSL* ssl)
{
int ret = 0;
TLSX* extension;
TLSX* priority = NULL;
TLSX* ext = NULL;
SupportedCurve* serverGroup;
SupportedCurve* clientGroup;
SupportedCurve* group;
const DhParams* params;
extension = TLSX_Find(ssl->extensions, TLSX_SUPPORTED_GROUPS);
/* May be doing PSK with no key exchange. */
if (extension == NULL)
return 0;
clientGroup = (SupportedCurve*)extension->data;
if ((ret = TLSX_PopulateSupportedGroups(ssl, &priority)) != WOLFSSL_SUCCESS)
return ret;
ret = 0;
ext = TLSX_Find(priority, TLSX_SUPPORTED_GROUPS);
serverGroup = (SupportedCurve*)ext->data;
while (serverGroup != NULL) {
if ((serverGroup->name & NAMED_DH_MASK) == NAMED_DH_MASK) {
group = clientGroup;
while (group != NULL) {
if (serverGroup->name == group->name) {
switch (serverGroup->name) {
#ifdef HAVE_FFDHE_2048
case WOLFSSL_FFDHE_2048:
params = wc_Dh_ffdhe2048_Get();
break;
#endif
#ifdef HAVE_FFDHE_3072
case WOLFSSL_FFDHE_3072:
params = wc_Dh_ffdhe3072_Get();
break;
#endif
#ifdef HAVE_FFDHE_4096
case WOLFSSL_FFDHE_4096:
params = wc_Dh_ffdhe4096_Get();
break;
#endif
#ifdef HAVE_FFDHE_6144
case WOLFSSL_FFDHE_6144:
params = wc_Dh_ffdhe6144_Get();
break;
#endif
#ifdef HAVE_FFDHE_8192
case WOLFSSL_FFDHE_8192:
params = wc_Dh_ffdhe8192_Get();
break;
#endif
default:
return BAD_FUNC_ARG;
}
if (params->p_len >= ssl->options.minDhKeySz &&
params->p_len <= ssl->options.maxDhKeySz) {
break;
}
}
group = group->next;
}
if (group != NULL && serverGroup->name == group->name)
break;
}
serverGroup = serverGroup->next;
}
if (serverGroup) {
if (ssl->buffers.serverDH_P.buffer && ssl->buffers.weOwnDH) {
XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap,
DYNAMIC_TYPE_PUBLIC_KEY);
ssl->buffers.serverDH_P.buffer = NULL;
}
if (ssl->buffers.serverDH_G.buffer && ssl->buffers.weOwnDH) {
XFREE(ssl->buffers.serverDH_G.buffer, ssl->heap,
DYNAMIC_TYPE_PUBLIC_KEY);
ssl->buffers.serverDH_G.buffer = NULL;
}
ssl->buffers.weOwnDH = 0;
ssl->buffers.serverDH_P.buffer = (unsigned char *)params->p;
ssl->buffers.serverDH_P.length = params->p_len;
ssl->buffers.serverDH_G.buffer = (unsigned char *)params->g;
ssl->buffers.serverDH_G.length = params->g_len;
ssl->namedGroup = serverGroup->name;
#if !defined(WOLFSSL_OLD_PRIME_CHECK) && \
!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
ssl->options.dhDoKeyTest = 0;
#endif
}
TLSX_FreeAll(priority, ssl->heap);
return ret;
}
#endif /* HAVE_FFDHE && !WOLFSSL_NO_TLS12 */
#endif /* !NO_WOLFSSL_SERVER */
#if defined(WOLFSSL_TLS13) && !defined(WOLFSSL_NO_SERVER_GROUPS_EXT)
/* Return the preferred group.
*
@@ -3662,24 +3805,24 @@ static int TLSX_PointFormat_Parse(WOLFSSL* ssl, byte* input, word16 length,
#if defined(HAVE_ECC) || defined(HAVE_CURVE25519)
int TLSX_ValidateSupportedCurves(WOLFSSL* ssl, byte first, byte second) {
TLSX* extension = (first == ECC_BYTE || first == CHACHA_BYTE)
? TLSX_Find(ssl->extensions, TLSX_SUPPORTED_GROUPS)
: NULL;
TLSX* extension = NULL;
SupportedCurve* curve = NULL;
word32 oid = 0;
word32 pkOid = 0;
word32 defOid = 0;
word32 defSz = 80; /* Maximum known curve size is 66. */
word32 nextOid = 0;
word32 nextSz = 80; /* Maximum known curve size is 66. */
word32 currOid = ssl->ecdhCurveOID;
int ephmSuite = 0;
word16 octets = 0; /* according to 'ecc_set_type ecc_sets[];' */
int sig = 0; /* validate signature */
int key = 0; /* validate key */
word32 oid = 0;
word32 pkOid = 0;
word32 defOid = 0;
word32 defSz = 80; /* Maximum known curve size is 66. */
word32 nextOid = 0;
word32 nextSz = 80; /* Maximum known curve size is 66. */
word32 currOid = ssl->ecdhCurveOID;
int ephmSuite = 0;
word16 octets = 0; /* according to 'ecc_set_type ecc_sets[];' */
int sig = 0; /* validate signature */
int key = 0; /* validate key */
(void)oid;
if (first == ECC_BYTE || first == CHACHA_BYTE)
extension = TLSX_Find(ssl->extensions, TLSX_SUPPORTED_GROUPS);
if (!extension)
return 1; /* no suite restriction */
@@ -8819,41 +8962,52 @@ static int TLSX_PopulateSupportedGroups(WOLFSSL* ssl, TLSX** extensions)
#endif /* HAVE_FIPS */
#endif /* HAVE_ECC && HAVE_SUPPORTED_CURVES */
#ifdef WOLFSSL_TLS13
if (IsAtLeastTLSv1_3(ssl->version)) {
/* Add FFDHE supported groups. */
#ifdef HAVE_FFDHE_8192
if (8192/8 >= ssl->options.minDhKeySz &&
8192/8 <= ssl->options.maxDhKeySz) {
ret = TLSX_UseSupportedCurve(extensions,
WOLFSSL_FFDHE_8192, ssl->heap);
if (ret != WOLFSSL_SUCCESS)
return ret;
}
#endif
#ifdef HAVE_FFDHE_6144
if (6144/8 >= ssl->options.minDhKeySz &&
6144/8 <= ssl->options.maxDhKeySz) {
ret = TLSX_UseSupportedCurve(extensions,
WOLFSSL_FFDHE_6144, ssl->heap);
if (ret != WOLFSSL_SUCCESS)
return ret;
}
#endif
#ifdef HAVE_FFDHE_4096
if (4096/8 >= ssl->options.minDhKeySz &&
4096/8 <= ssl->options.maxDhKeySz) {
ret = TLSX_UseSupportedCurve(extensions,
WOLFSSL_FFDHE_4096, ssl->heap);
if (ret != WOLFSSL_SUCCESS)
return ret;
}
#endif
#ifdef HAVE_FFDHE_3072
if (3072/8 >= ssl->options.minDhKeySz &&
3072/8 <= ssl->options.maxDhKeySz) {
ret = TLSX_UseSupportedCurve(extensions,
WOLFSSL_FFDHE_3072, ssl->heap);
if (ret != WOLFSSL_SUCCESS)
return ret;
}
#endif
#ifdef HAVE_FFDHE_2048
if (2048/8 >= ssl->options.minDhKeySz &&
2048/8 <= ssl->options.maxDhKeySz) {
ret = TLSX_UseSupportedCurve(extensions,
WOLFSSL_FFDHE_2048, ssl->heap);
if (ret != WOLFSSL_SUCCESS)
return ret;
}
#endif
}
#endif /* WOLFSSL_TLS13 */
(void)ssl;
(void)extensions;
@@ -9590,6 +9744,45 @@ int TLSX_WriteResponse(WOLFSSL *ssl, byte* output, byte msgType, word16* pOffset
#endif /* WOLFSSL_TLS13 || !NO_WOLFSSL_SERVER */
#ifdef WOLFSSL_TLS13
int TLSX_ParseVersion(WOLFSSL* ssl, byte* input, word16 length, byte msgType,
int* found)
{
int ret = 0;
int offset = 0;
*found = 0;
while (offset < length) {
word16 type;
word16 size;
ato16(input + offset, &type);
offset += HELLO_EXT_TYPE_SZ;
ato16(input + offset, &size);
offset += OPAQUE16_LEN;
if (offset + size > length) {
ret = BUFFER_ERROR;
break;
}
if (type == TLSX_SUPPORTED_VERSIONS) {
*found = 1;
WOLFSSL_MSG("Supported Versions extension received");
ret = SV_PARSE(ssl, input + offset, size, msgType);
break;
}
offset += size;
}
return ret;
}
#endif
/** Parses a buffer of TLS extensions. */
int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType,
Suites *suites)
@@ -9635,7 +9828,7 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType,
WOLFSSL_MSG("SNI extension received");
#ifdef WOLFSSL_TLS13
if (IsAtLeastTLSv1_3(ssl->ctx->method->version) &&
if (IsAtLeastTLSv1_3(ssl->version) &&
msgType != client_hello &&
msgType != server_hello &&
msgType != encrypted_extensions) {
@@ -9653,7 +9846,7 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType,
WOLFSSL_MSG("Max Fragment Length extension received");
#ifdef WOLFSSL_TLS13
if (IsAtLeastTLSv1_3(ssl->ctx->method->version) &&
if (IsAtLeastTLSv1_3(ssl->version) &&
msgType != client_hello &&
msgType != encrypted_extensions) {
return EXT_NOT_ALLOWED;
@@ -9670,10 +9863,8 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType,
WOLFSSL_MSG("Truncated HMAC extension received");
#ifdef WOLFSSL_TLS13
if (IsAtLeastTLSv1_3(ssl->ctx->method->version) &&
!ssl->options.downgrade) {
if (IsAtLeastTLSv1_3(ssl->version))
break;
}
#endif
ret = THM_PARSE(ssl, input + offset, size, isRequest);
break;
@@ -9682,7 +9873,7 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType,
WOLFSSL_MSG("Supported Groups extension received");
#ifdef WOLFSSL_TLS13
if (IsAtLeastTLSv1_3(ssl->ctx->method->version) &&
if (IsAtLeastTLSv1_3(ssl->version) &&
msgType != client_hello &&
msgType != server_hello &&
msgType != encrypted_extensions) {
@@ -9692,11 +9883,6 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType,
msgType == encrypted_extensions) {
return EXT_NOT_ALLOWED;
}
else if (IsAtLeastTLSv1_3(ssl->ctx->method->version) &&
msgType == server_hello &&
!ssl->options.downgrade) {
return EXT_NOT_ALLOWED;
}
#endif
ret = EC_PARSE(ssl, input + offset, size, isRequest);
break;
@@ -9705,10 +9891,8 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType,
WOLFSSL_MSG("Point Formats extension received");
#ifdef WOLFSSL_TLS13
if (IsAtLeastTLSv1_3(ssl->ctx->method->version) &&
!ssl->options.downgrade) {
if (IsAtLeastTLSv1_3(ssl->ctx->method->version))
break;
}
#endif
ret = PF_PARSE(ssl, input + offset, size, isRequest);
break;
@@ -9717,10 +9901,8 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType,
WOLFSSL_MSG("Certificate Status Request extension received");
#ifdef WOLFSSL_TLS13
if (IsAtLeastTLSv1_3(ssl->ctx->method->version) &&
!ssl->options.downgrade) {
if (IsAtLeastTLSv1_3(ssl->version))
break;
}
#endif
ret = CSR_PARSE(ssl, input + offset, size, isRequest);
break;
@@ -9729,7 +9911,7 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType,
WOLFSSL_MSG("Certificate Status Request v2 extension received");
#ifdef WOLFSSL_TLS13
if (IsAtLeastTLSv1_3(ssl->ctx->method->version) &&
if (IsAtLeastTLSv1_3(ssl->version) &&
msgType != client_hello &&
msgType != certificate_request &&
msgType != certificate) {
@@ -9744,10 +9926,8 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType,
WOLFSSL_MSG("Extended Master Secret extension received");
#ifdef WOLFSSL_TLS13
if (IsAtLeastTLSv1_3(ssl->ctx->method->version) &&
!ssl->options.downgrade) {
if (IsAtLeastTLSv1_3(ssl->version))
break;
}
#endif
#ifndef NO_WOLFSSL_SERVER
if (isRequest)
@@ -9761,10 +9941,8 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType,
WOLFSSL_MSG("Secure Renegotiation extension received");
#ifdef WOLFSSL_TLS13
if (IsAtLeastTLSv1_3(ssl->ctx->method->version) &&
!ssl->options.downgrade) {
if (IsAtLeastTLSv1_3(ssl->version))
break;
}
#endif
ret = SCR_PARSE(ssl, input + offset, size, isRequest);
break;
@@ -9785,10 +9963,8 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType,
WOLFSSL_MSG("Quantum-Safe-Hybrid extension received");
#ifdef WOLFSSL_TLS13
if (IsAtLeastTLSv1_3(ssl->ctx->method->version) &&
!ssl->options.downgrade) {
if (IsAtLeastTLSv1_3(ssl->version))
break;
}
#endif
ret = QSH_PARSE(ssl, input + offset, size, isRequest);
break;
@@ -9797,7 +9973,7 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType,
WOLFSSL_MSG("ALPN extension received");
#ifdef WOLFSSL_TLS13
if (IsAtLeastTLSv1_3(ssl->ctx->method->version) &&
if (IsAtLeastTLSv1_3(ssl->version) &&
msgType != client_hello &&
msgType != server_hello &&
msgType != encrypted_extensions) {
@@ -9818,7 +9994,7 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType,
break;
#ifdef WOLFSSL_TLS13
if (IsAtLeastTLSv1_3(ssl->ctx->method->version) &&
if (IsAtLeastTLSv1_3(ssl->version) &&
msgType != client_hello &&
msgType != certificate_request) {
return EXT_NOT_ALLOWED;
@@ -9829,29 +10005,14 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType,
#ifdef WOLFSSL_TLS13
case TLSX_SUPPORTED_VERSIONS:
WOLFSSL_MSG("Supported Versions extension received");
WOLFSSL_MSG("Skipping Supported Versions - already processed");
if (!IsAtLeastTLSv1_3(ssl->ctx->method->version))
break;
if (
#ifdef WOLFSSL_TLS13_DRAFT_18
msgType != client_hello
#else
msgType != client_hello &&
msgType != server_hello &&
msgType != hello_retry_request
#endif
) {
return EXT_NOT_ALLOWED;
}
ret = SV_PARSE(ssl, input + offset, size, msgType);
break;
case TLSX_COOKIE:
WOLFSSL_MSG("Cookie extension received");
if (!IsAtLeastTLSv1_3(ssl->ctx->method->version))
if (!IsAtLeastTLSv1_3(ssl->version))
break;
if (msgType != client_hello &&
@@ -9866,7 +10027,7 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType,
case TLSX_PRE_SHARED_KEY:
WOLFSSL_MSG("Pre-Shared Key extension received");
if (!IsAtLeastTLSv1_3(ssl->ctx->method->version))
if (!IsAtLeastTLSv1_3(ssl->version))
break;
if (msgType != client_hello && msgType != server_hello)
@@ -9879,7 +10040,7 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType,
case TLSX_PSK_KEY_EXCHANGE_MODES:
WOLFSSL_MSG("PSK Key Exchange Modes extension received");
if (!IsAtLeastTLSv1_3(ssl->ctx->method->version))
if (!IsAtLeastTLSv1_3(ssl->version))
break;
if (msgType != client_hello)
@@ -9893,7 +10054,7 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType,
case TLSX_EARLY_DATA:
WOLFSSL_MSG("Early Data extension received");
if (!IsAtLeastTLSv1_3(ssl->ctx->method->version))
if (!IsAtLeastTLSv1_3(ssl->version))
break;
if (msgType != client_hello && msgType != session_ticket &&
@@ -9913,7 +10074,7 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType,
case TLSX_POST_HANDSHAKE_AUTH:
WOLFSSL_MSG("Post Handshake Authentication extension received");
if (!IsAtLeastTLSv1_3(ssl->ctx->method->version))
if (!IsAtLeastTLSv1_3(ssl->version))
break;
if (msgType != client_hello)
@@ -9927,7 +10088,7 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType,
case TLSX_SIGNATURE_ALGORITHMS_CERT:
WOLFSSL_MSG("Signature Algorithms extension received");
if (!IsAtLeastTLSv1_3(ssl->ctx->method->version))
if (!IsAtLeastTLSv1_3(ssl->version))
break;
if (msgType != client_hello &&
@@ -9946,7 +10107,7 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType,
case TLSX_KEY_SHARE:
WOLFSSL_MSG("Key Share extension received");
if (!IsAtLeastTLSv1_3(ssl->ctx->method->version))
if (!IsAtLeastTLSv1_3(ssl->version))
break;
if (msgType != client_hello && msgType != server_hello &&

View File

@@ -2788,6 +2788,7 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
byte sessIdSz;
const byte* sessId;
byte b;
int foundVersion;
#endif
word16 totalExtSz;
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
@@ -2910,9 +2911,24 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
return BUFFER_ERROR;
#ifndef WOLFSSL_TLS13_DRAFT_18
if (ssl->options.downgrade)
ssl->version.minor = TLSv1_2_MINOR;
/* Need to negotiate version first. */
if ((ret = TLSX_ParseVersion(ssl, (byte*)input + i, totalExtSz,
*extMsgType, &foundVersion))) {
return ret;
}
if (!foundVersion) {
if (!ssl->options.downgrade) {
WOLFSSL_MSG("Server trying to downgrade to version less than "
"TLS v1.3");
return VERSION_ERROR;
}
if (pv.minor < ssl->options.minDowngrade)
return VERSION_ERROR;
ssl->version.minor = pv.minor;
}
#endif
/* Parse and handle extensions. */
ret = TLSX_Parse(ssl, (byte *) input + i, totalExtSz, *extMsgType,
NULL);
@@ -3799,6 +3815,7 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
#ifdef HAVE_SESSION_TICKET
int inputHashed = 0;
#endif
int foundVersion;
WOLFSSL_START(WC_FUNC_CLIENT_HELLO_DO);
WOLFSSL_ENTER("DoTls13ClientHello");
@@ -3923,6 +3940,23 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
if ((ret = TLSX_PopulateExtensions(ssl, 1)) != 0)
return ret;
/* Need to negotiate version first. */
if ((ret = TLSX_ParseVersion(ssl, (byte*)input + i, totalExtSz,
client_hello, &foundVersion))) {
return ret;
}
if (!foundVersion) {
if (!ssl->options.downgrade) {
WOLFSSL_MSG("Client trying to connect with lesser version than "
"TLS v1.3");
return VERSION_ERROR;
}
if (pv.minor < ssl->options.minDowngrade)
return VERSION_ERROR;
ssl->version.minor = pv.minor;
}
/* Parse extensions */
if ((ret = TLSX_Parse(ssl, (byte*)input + i, totalExtSz, client_hello,
&clSuites))) {
@@ -3940,29 +3974,12 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
i += totalExtSz;
*inOutIdx = i;
if (TLSX_Find(ssl->extensions, TLSX_SUPPORTED_VERSIONS) == NULL) {
if (!ssl->options.downgrade) {
WOLFSSL_MSG("Client trying to connect with lesser version than "
"TLS v1.3");
return VERSION_ERROR;
}
if (pv.minor < ssl->options.minDowngrade)
return VERSION_ERROR;
ssl->version.minor = pv.minor;
}
ssl->options.sendVerify = SEND_CERT;
ssl->options.clientState = CLIENT_HELLO_COMPLETE;
ssl->options.haveSessionId = 1;
if (IsAtLeastTLSv1_3(ssl->version)) {
#ifdef HAVE_SERVER_RENEGOTIATION_INFO
TLSX_Remove(&ssl->extensions, TLSX_RENEGOTIATION_INFO, ssl->heap);
ssl->secure_renegotiation = NULL;
#endif
#if !defined(WOLFSSL_TLS13_DRAFT_18) && defined(WOLFSSL_SEND_HRR_COOKIE)
if (ssl->options.sendCookie &&
ssl->options.serverState == SERVER_HELLO_RETRY_REQUEST_COMPLETE) {

View File

@@ -164,6 +164,7 @@ enum wolfSSL_ErrorCodes {
UNSUPPORTED_EXTENSION = -429, /* TLSX not requested by client */
PRF_MISSING = -430, /* PRF not compiled in */
DTLS_RETX_OVER_TX = -431, /* Retransmit DTLS flight over */
DH_PARAMS_NOT_FFDHE_E = -432, /* DH params from server not FFDHE */
/* add strings to wolfSSL_ERR_reason_error_string in internal.c !!!!! */
/* begin negotiation parameter errors */

View File

@@ -2106,6 +2106,8 @@ WOLFSSL_LOCAL int TLSX_WriteResponse(WOLFSSL *ssl, byte* output, byte msgType,
word16* pOffset);
#endif
WOLFSSL_LOCAL int TLSX_ParseVersion(WOLFSSL* ssl, byte* input, word16 length,
byte msgType, int* found);
WOLFSSL_LOCAL int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length,
byte msgType, Suites *suites);
@@ -2260,6 +2262,7 @@ WOLFSSL_LOCAL int TLSX_UsePointFormat(TLSX** extensions, byte point,
WOLFSSL_LOCAL int TLSX_ValidateSupportedCurves(WOLFSSL* ssl, byte first,
byte second);
WOLFSSL_LOCAL int TLSX_SupportedCurve_CheckPriority(WOLFSSL* ssl);
WOLFSSL_LOCAL int TLSX_SupportedFFDHE_Set(WOLFSSL* ssl);
#endif
WOLFSSL_LOCAL int TLSX_SupportedCurve_Preferred(WOLFSSL* ssl,
int checkSupported);
@@ -3697,8 +3700,10 @@ struct WOLFSSL {
byte maxRequest;
byte user_set_QSHSchemes;
#endif
#ifdef WOLFSSL_TLS13
#if defined(WOLFSSL_TLS13) || defined(HAVE_FFDHE)
word16 namedGroup;
#endif
#ifdef WOLFSSL_TLS13
word16 group[WOLFSSL_MAX_GROUP_COUNT];
byte numGroups;
#endif

View File

@@ -2393,7 +2393,6 @@ enum {
WOLFSSL_ECC_BRAINPOOLP384R1 = 27,
WOLFSSL_ECC_BRAINPOOLP512R1 = 28,
WOLFSSL_ECC_X25519 = 29,
#ifdef WOLFSSL_TLS13
/* Not implemented. */
WOLFSSL_ECC_X448 = 30,
@@ -2402,7 +2401,6 @@ enum {
WOLFSSL_FFDHE_4096 = 258,
WOLFSSL_FFDHE_6144 = 259,
WOLFSSL_FFDHE_8192 = 260,
#endif
};
enum {

View File

@@ -670,7 +670,7 @@ static WC_INLINE void showPeerEx(WOLFSSL* ssl, int lng_index)
WOLFSSL_CIPHER* cipher;
const char** words = client_showpeer_msg[lng_index];
#ifdef HAVE_ECC
#if defined(HAVE_ECC) || !defined(NO_DH)
const char *name;
#endif
#ifndef NO_DH
@@ -697,12 +697,12 @@ static WC_INLINE void showPeerEx(WOLFSSL* ssl, int lng_index)
#else
printf("%s %s\n", words[1], wolfSSL_CIPHER_get_name(cipher));
#endif
#ifdef HAVE_ECC
#if defined(HAVE_ECC) || !defined(NO_DH)
if ((name = wolfSSL_get_curve_name(ssl)) != NULL)
printf("%s %s\n", words[2], name);
#endif
#ifndef NO_DH
if ((bits = wolfSSL_GetDhKey_Sz(ssl)) > 0)
else if ((bits = wolfSSL_GetDhKey_Sz(ssl)) > 0)
printf("%s %d bits\n", words[3], bits);
#endif
if (wolfSSL_session_reused(ssl))

View File

@@ -1808,6 +1808,14 @@ extern void uITRON4_free(void *p) ;
#define SSL_CTRL_SET_TLSEXT_HOSTNAME
#endif
#if !defined(NO_DH) && !defined(HAVE_FFDHE)
#if defined(HAVE_FFDHE_2048) || defined(HAVE_FFDHE_3072) || \
defined(HAVE_FFDHE_4096) || defined(HAVE_FFDHE_6144) || \
defined(HAVE_FFDHE_8192)
#define HAVE_FFDHE
#endif
#endif
/* both CURVE and ED small math should be enabled */
#ifdef CURVED25519_SMALL
#define CURVE25519_SMALL