forked from wolfSSL/wolfssl
Merge pull request #5473 from icing/quic-hello-retry
Respect disabled curves on HelloRetryRequests
This commit is contained in:
@@ -6861,6 +6861,8 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
|
|||||||
if (ctx->protoMsgCb != NULL) {
|
if (ctx->protoMsgCb != NULL) {
|
||||||
ssl->toInfoOn = 1;
|
ssl->toInfoOn = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ssl->disabledCurves = ctx->disabledCurves;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
InitCiphers(ssl);
|
InitCiphers(ssl);
|
||||||
|
47
src/ssl.c
47
src/ssl.c
@@ -33824,21 +33824,26 @@ void wolfSSL_get0_next_proto_negotiated(const WOLFSSL *s, const unsigned char **
|
|||||||
|
|
||||||
#endif /* WOLFSSL_NGINX / WOLFSSL_HAPROXY */
|
#endif /* WOLFSSL_NGINX / WOLFSSL_HAPROXY */
|
||||||
|
|
||||||
|
#ifdef OPENSSL_EXTRA
|
||||||
|
int wolfSSL_curve_is_disabled(WOLFSSL* ssl, word16 curve_id)
|
||||||
|
{
|
||||||
|
return (curve_id <= WOLFSSL_ECC_MAX &&
|
||||||
|
ssl->disabledCurves &&
|
||||||
|
ssl->disabledCurves & (1 << curve_id));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(OPENSSL_EXTRA) && (defined(HAVE_ECC) || \
|
#if defined(OPENSSL_EXTRA) && (defined(HAVE_ECC) || \
|
||||||
defined(HAVE_CURVE25519) || defined(HAVE_CURVE448))
|
defined(HAVE_CURVE25519) || defined(HAVE_CURVE448))
|
||||||
int wolfSSL_CTX_set1_curves_list(WOLFSSL_CTX* ctx, const char* names)
|
static int set_curves_list(WOLFSSL* ssl, WOLFSSL_CTX *ctx, const char* names)
|
||||||
{
|
{
|
||||||
int idx, start = 0, len;
|
int idx, start = 0, len;
|
||||||
word16 curve;
|
word16 curve;
|
||||||
|
word32 disabled;
|
||||||
char name[MAX_CURVE_NAME_SZ];
|
char name[MAX_CURVE_NAME_SZ];
|
||||||
|
|
||||||
if (ctx == NULL || names == NULL) {
|
|
||||||
WOLFSSL_MSG("ctx or names was NULL");
|
|
||||||
return WOLFSSL_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Disable all curves so that only the ones the user wants are enabled. */
|
/* Disable all curves so that only the ones the user wants are enabled. */
|
||||||
ctx->disabledCurves = 0xFFFFFFFFUL;
|
disabled = 0xFFFFFFFFUL;
|
||||||
for (idx = 1; names[idx-1] != '\0'; idx++) {
|
for (idx = 1; names[idx-1] != '\0'; idx++) {
|
||||||
if (names[idx] != ':' && names[idx] != '\0')
|
if (names[idx] != ':' && names[idx] != '\0')
|
||||||
continue;
|
continue;
|
||||||
@@ -33912,26 +33917,44 @@ int wolfSSL_CTX_set1_curves_list(WOLFSSL_CTX* ctx, const char* names)
|
|||||||
#if defined(HAVE_SUPPORTED_CURVES) && !defined(NO_WOLFSSL_CLIENT)
|
#if defined(HAVE_SUPPORTED_CURVES) && !defined(NO_WOLFSSL_CLIENT)
|
||||||
/* set the supported curve so client TLS extension contains only the
|
/* set the supported curve so client TLS extension contains only the
|
||||||
* desired curves */
|
* desired curves */
|
||||||
if (wolfSSL_CTX_UseSupportedCurve(ctx, curve) != WOLFSSL_SUCCESS) {
|
if ((ssl
|
||||||
|
&& wolfSSL_UseSupportedCurve(ssl, curve) != WOLFSSL_SUCCESS)
|
||||||
|
|| (ctx
|
||||||
|
&& wolfSSL_CTX_UseSupportedCurve(ctx, curve) != WOLFSSL_SUCCESS)) {
|
||||||
WOLFSSL_MSG("Unable to set supported curve");
|
WOLFSSL_MSG("Unable to set supported curve");
|
||||||
return WOLFSSL_FAILURE;
|
return WOLFSSL_FAILURE;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Switch the bit to off and therefore is enabled. */
|
/* Switch the bit to off and therefore is enabled. */
|
||||||
ctx->disabledCurves &= ~(1U << curve);
|
disabled &= ~(1U << curve);
|
||||||
start = idx + 1;
|
start = idx + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ssl)
|
||||||
|
ssl->disabledCurves = disabled;
|
||||||
|
else
|
||||||
|
ctx->disabledCurves = disabled;
|
||||||
|
|
||||||
return WOLFSSL_SUCCESS;
|
return WOLFSSL_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int wolfSSL_set1_curves_list(WOLFSSL* ssl, const char* names)
|
int wolfSSL_CTX_set1_curves_list(WOLFSSL_CTX* ctx, const char* names)
|
||||||
{
|
{
|
||||||
if (ssl == NULL) {
|
if (ctx == NULL || names == NULL) {
|
||||||
|
WOLFSSL_MSG("ctx or names was NULL");
|
||||||
return WOLFSSL_FAILURE;
|
return WOLFSSL_FAILURE;
|
||||||
}
|
}
|
||||||
return wolfSSL_CTX_set1_curves_list(ssl->ctx, names);
|
return set_curves_list(NULL, ctx, names);
|
||||||
|
}
|
||||||
|
|
||||||
|
int wolfSSL_set1_curves_list(WOLFSSL* ssl, const char* names)
|
||||||
|
{
|
||||||
|
if (ssl == NULL || names == NULL) {
|
||||||
|
WOLFSSL_MSG("ssl or names was NULL");
|
||||||
|
return WOLFSSL_FAILURE;
|
||||||
|
}
|
||||||
|
return set_curves_list(ssl, NULL, names);
|
||||||
}
|
}
|
||||||
#endif /* OPENSSL_EXTRA && (HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448) */
|
#endif /* OPENSSL_EXTRA && (HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448) */
|
||||||
|
|
||||||
|
61
src/tls.c
61
src/tls.c
@@ -4181,8 +4181,7 @@ static int tlsx_ffdhe_find_group(WOLFSSL* ssl, SupportedCurve* clientGroup,
|
|||||||
const DhParams* params = NULL;
|
const DhParams* params = NULL;
|
||||||
|
|
||||||
for (; serverGroup != NULL; serverGroup = serverGroup->next) {
|
for (; serverGroup != NULL; serverGroup = serverGroup->next) {
|
||||||
if (serverGroup->name < MIN_FFHDE_GROUP ||
|
if (!WOLFSSL_NAMED_GROUP_IS_FFHDE(serverGroup->name))
|
||||||
serverGroup->name > MAX_FFHDE_GROUP)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (group = clientGroup; group != NULL; group = group->next) {
|
for (group = clientGroup; group != NULL; group = group->next) {
|
||||||
@@ -4259,8 +4258,7 @@ static int tlsx_ffdhe_find_group(WOLFSSL* ssl, SupportedCurve* clientGroup,
|
|||||||
word32 p_len;
|
word32 p_len;
|
||||||
|
|
||||||
for (; serverGroup != NULL; serverGroup = serverGroup->next) {
|
for (; serverGroup != NULL; serverGroup = serverGroup->next) {
|
||||||
if (serverGroup->name < MIN_FFHDE_GROUP ||
|
if (!WOLFSSL_NAMED_GROUP_IS_FFHDE(serverGroup->name))
|
||||||
serverGroup->name > MAX_FFHDE_GROUP)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (group = clientGroup; group != NULL; group = group->next) {
|
for (group = clientGroup; group != NULL; group = group->next) {
|
||||||
@@ -4365,7 +4363,7 @@ int TLSX_SupportedFFDHE_Set(WOLFSSL* ssl)
|
|||||||
return 0;
|
return 0;
|
||||||
clientGroup = (SupportedCurve*)extension->data;
|
clientGroup = (SupportedCurve*)extension->data;
|
||||||
for (group = clientGroup; group != NULL; group = group->next) {
|
for (group = clientGroup; group != NULL; group = group->next) {
|
||||||
if (group->name >= MIN_FFHDE_GROUP && group->name <= MAX_FFHDE_GROUP) {
|
if (WOLFSSL_NAMED_GROUP_IS_FFHDE(group->name)) {
|
||||||
found = 1;
|
found = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -4493,11 +4491,10 @@ int TLSX_ValidateSupportedCurves(WOLFSSL* ssl, byte first, byte second) {
|
|||||||
curve = curve->next) {
|
curve = curve->next) {
|
||||||
|
|
||||||
#ifdef OPENSSL_EXTRA
|
#ifdef OPENSSL_EXTRA
|
||||||
/* skip if name is not in supported ECC range */
|
/* skip if name is not in supported ECC range
|
||||||
if (curve->name > WOLFSSL_ECC_X448)
|
* or disabled by user */
|
||||||
continue;
|
if (curve->name > WOLFSSL_ECC_MAX ||
|
||||||
/* skip if curve is disabled by user */
|
wolfSSL_curve_is_disabled(ssl, curve->name))
|
||||||
if (ssl->ctx->disabledCurves & (1 << curve->name))
|
|
||||||
continue;
|
continue;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -7356,14 +7353,14 @@ static int TLSX_KeyShare_GenKey(WOLFSSL *ssl, KeyShareEntry *kse)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
/* Named FFDHE groups have a bit set to identify them. */
|
/* Named FFDHE groups have a bit set to identify them. */
|
||||||
if (kse->group >= MIN_FFHDE_GROUP && kse->group <= MAX_FFHDE_GROUP)
|
if (WOLFSSL_NAMED_GROUP_IS_FFHDE(kse->group))
|
||||||
ret = TLSX_KeyShare_GenDhKey(ssl, kse);
|
ret = TLSX_KeyShare_GenDhKey(ssl, kse);
|
||||||
else if (kse->group == WOLFSSL_ECC_X25519)
|
else if (kse->group == WOLFSSL_ECC_X25519)
|
||||||
ret = TLSX_KeyShare_GenX25519Key(ssl, kse);
|
ret = TLSX_KeyShare_GenX25519Key(ssl, kse);
|
||||||
else if (kse->group == WOLFSSL_ECC_X448)
|
else if (kse->group == WOLFSSL_ECC_X448)
|
||||||
ret = TLSX_KeyShare_GenX448Key(ssl, kse);
|
ret = TLSX_KeyShare_GenX448Key(ssl, kse);
|
||||||
#ifdef HAVE_PQC
|
#ifdef HAVE_PQC
|
||||||
else if (kse->group >= WOLFSSL_PQC_MIN && kse->group <= WOLFSSL_PQC_MAX)
|
else if (WOLFSSL_NAMED_GROUP_IS_PQC(kse->group))
|
||||||
ret = TLSX_KeyShare_GenPqcKey(ssl, kse);
|
ret = TLSX_KeyShare_GenPqcKey(ssl, kse);
|
||||||
#endif
|
#endif
|
||||||
else
|
else
|
||||||
@@ -7385,8 +7382,7 @@ static void TLSX_KeyShare_FreeAll(KeyShareEntry* list, void* heap)
|
|||||||
|
|
||||||
while ((current = list) != NULL) {
|
while ((current = list) != NULL) {
|
||||||
list = current->next;
|
list = current->next;
|
||||||
if (current->group >= MIN_FFHDE_GROUP &&
|
if (WOLFSSL_NAMED_GROUP_IS_FFHDE(current->group)) {
|
||||||
current->group <= MAX_FFHDE_GROUP) {
|
|
||||||
#ifndef NO_DH
|
#ifndef NO_DH
|
||||||
wc_FreeDhKey((DhKey*)current->key);
|
wc_FreeDhKey((DhKey*)current->key);
|
||||||
#endif
|
#endif
|
||||||
@@ -7402,8 +7398,7 @@ static void TLSX_KeyShare_FreeAll(KeyShareEntry* list, void* heap)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#ifdef HAVE_PQC
|
#ifdef HAVE_PQC
|
||||||
else if (current->group >= WOLFSSL_PQC_MIN &&
|
else if (WOLFSSL_NAMED_GROUP_IS_PQC(current->group) &&
|
||||||
current->group <= WOLFSSL_PQC_MAX &&
|
|
||||||
current->key != NULL) {
|
current->key != NULL) {
|
||||||
ForceZero((byte*)current->key, current->keyLen);
|
ForceZero((byte*)current->key, current->keyLen);
|
||||||
}
|
}
|
||||||
@@ -8251,16 +8246,14 @@ static int TLSX_KeyShare_Process(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
|
|||||||
ssl->arrays->preMasterSz = ENCRYPT_LEN;
|
ssl->arrays->preMasterSz = ENCRYPT_LEN;
|
||||||
|
|
||||||
/* Use Key Share Data from server. */
|
/* Use Key Share Data from server. */
|
||||||
if (keyShareEntry->group >= MIN_FFHDE_GROUP &&
|
if (WOLFSSL_NAMED_GROUP_IS_FFHDE(keyShareEntry->group))
|
||||||
keyShareEntry->group <= MAX_FFHDE_GROUP)
|
|
||||||
ret = TLSX_KeyShare_ProcessDh(ssl, keyShareEntry);
|
ret = TLSX_KeyShare_ProcessDh(ssl, keyShareEntry);
|
||||||
else if (keyShareEntry->group == WOLFSSL_ECC_X25519)
|
else if (keyShareEntry->group == WOLFSSL_ECC_X25519)
|
||||||
ret = TLSX_KeyShare_ProcessX25519(ssl, keyShareEntry);
|
ret = TLSX_KeyShare_ProcessX25519(ssl, keyShareEntry);
|
||||||
else if (keyShareEntry->group == WOLFSSL_ECC_X448)
|
else if (keyShareEntry->group == WOLFSSL_ECC_X448)
|
||||||
ret = TLSX_KeyShare_ProcessX448(ssl, keyShareEntry);
|
ret = TLSX_KeyShare_ProcessX448(ssl, keyShareEntry);
|
||||||
#ifdef HAVE_PQC
|
#ifdef HAVE_PQC
|
||||||
else if (keyShareEntry->group >= WOLFSSL_PQC_MIN &&
|
else if (WOLFSSL_NAMED_GROUP_IS_PQC(keyShareEntry->group))
|
||||||
keyShareEntry->group <= WOLFSSL_PQC_MAX)
|
|
||||||
ret = TLSX_KeyShare_ProcessPqc(ssl, keyShareEntry);
|
ret = TLSX_KeyShare_ProcessPqc(ssl, keyShareEntry);
|
||||||
#endif
|
#endif
|
||||||
else
|
else
|
||||||
@@ -8311,8 +8304,7 @@ static int TLSX_KeyShareEntry_Parse(WOLFSSL* ssl, const byte* input,
|
|||||||
return BUFFER_ERROR;
|
return BUFFER_ERROR;
|
||||||
|
|
||||||
#ifdef HAVE_PQC
|
#ifdef HAVE_PQC
|
||||||
if (group >= WOLFSSL_PQC_MIN &&
|
if (WOLFSSL_NAMED_GROUP_IS_PQC(group) &&
|
||||||
group <= WOLFSSL_PQC_MAX &&
|
|
||||||
ssl->options.side == WOLFSSL_SERVER_END) {
|
ssl->options.side == WOLFSSL_SERVER_END) {
|
||||||
/* For KEMs, the public key is not stored. Casting away const because
|
/* For KEMs, the public key is not stored. Casting away const because
|
||||||
* we know for KEMs, it will be read-only.*/
|
* we know for KEMs, it will be read-only.*/
|
||||||
@@ -8526,7 +8518,7 @@ static int TLSX_KeyShare_Parse(WOLFSSL* ssl, const byte* input, word16 length,
|
|||||||
|
|
||||||
#ifdef HAVE_PQC
|
#ifdef HAVE_PQC
|
||||||
/* For post-quantum groups, do this in TLSX_PopulateExtensions(). */
|
/* For post-quantum groups, do this in TLSX_PopulateExtensions(). */
|
||||||
if (group < WOLFSSL_PQC_MIN || group > WOLFSSL_PQC_MAX)
|
if (!WOLFSSL_NAMED_GROUP_IS_PQC(group))
|
||||||
#endif
|
#endif
|
||||||
ret = TLSX_KeyShare_Use(ssl, group, 0, NULL, NULL);
|
ret = TLSX_KeyShare_Use(ssl, group, 0, NULL, NULL);
|
||||||
}
|
}
|
||||||
@@ -8907,8 +8899,7 @@ int TLSX_KeyShare_Use(WOLFSSL* ssl, word16 group, word16 len, byte* data,
|
|||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_PQC
|
#ifdef HAVE_PQC
|
||||||
if (group >= WOLFSSL_PQC_MIN &&
|
if (WOLFSSL_NAMED_GROUP_IS_PQC(group) &&
|
||||||
group <= WOLFSSL_PQC_MAX &&
|
|
||||||
ssl->options.side == WOLFSSL_SERVER_END) {
|
ssl->options.side == WOLFSSL_SERVER_END) {
|
||||||
ret = server_generate_pqc_ciphertext(ssl, keyShareEntry, data,
|
ret = server_generate_pqc_ciphertext(ssl, keyShareEntry, data,
|
||||||
len);
|
len);
|
||||||
@@ -9261,6 +9252,8 @@ static int TLSX_KeyShare_SetSupported(WOLFSSL* ssl)
|
|||||||
for (; curve != NULL; curve = curve->next) {
|
for (; curve != NULL; curve = curve->next) {
|
||||||
if (!TLSX_KeyShare_IsSupported(curve->name))
|
if (!TLSX_KeyShare_IsSupported(curve->name))
|
||||||
continue;
|
continue;
|
||||||
|
if (wolfSSL_curve_is_disabled(ssl, curve->name))
|
||||||
|
continue;
|
||||||
|
|
||||||
rank = TLSX_KeyShare_GroupRank(ssl, curve->name);
|
rank = TLSX_KeyShare_GroupRank(ssl, curve->name);
|
||||||
if (rank == -1)
|
if (rank == -1)
|
||||||
@@ -9355,21 +9348,16 @@ int TLSX_KeyShare_Establish(WOLFSSL *ssl, int* doHelloRetry)
|
|||||||
if (!TLSX_SupportedGroups_Find(ssl, clientKSE->group))
|
if (!TLSX_SupportedGroups_Find(ssl, clientKSE->group))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (clientKSE->group < MIN_FFHDE_GROUP ||
|
if (!WOLFSSL_NAMED_GROUP_IS_FFHDE(clientKSE->group)) {
|
||||||
clientKSE->group > MAX_FFHDE_GROUP) {
|
|
||||||
/* Check max value supported. */
|
/* Check max value supported. */
|
||||||
if (clientKSE->group > WOLFSSL_ECC_MAX) {
|
if (clientKSE->group > WOLFSSL_ECC_MAX) {
|
||||||
#ifdef HAVE_PQC
|
#ifdef HAVE_PQC
|
||||||
if (clientKSE->group < WOLFSSL_PQC_MIN ||
|
if (!WOLFSSL_NAMED_GROUP_IS_PQC(clientKSE->group))
|
||||||
clientKSE->group > WOLFSSL_PQC_MAX )
|
|
||||||
#endif
|
#endif
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#ifdef OPENSSL_EXTRA
|
if (wolfSSL_curve_is_disabled(ssl, clientKSE->group))
|
||||||
/* Check if server supports group. */
|
|
||||||
if (ssl->ctx->disabledCurves & ((word32)1 << clientKSE->group))
|
|
||||||
continue;
|
continue;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
if (!TLSX_KeyShare_IsSupported(clientKSE->group))
|
if (!TLSX_KeyShare_IsSupported(clientKSE->group))
|
||||||
continue;
|
continue;
|
||||||
@@ -9402,8 +9390,7 @@ int TLSX_KeyShare_Establish(WOLFSSL *ssl, int* doHelloRetry)
|
|||||||
|
|
||||||
if (clientKSE->key == NULL) {
|
if (clientKSE->key == NULL) {
|
||||||
#ifdef HAVE_PQC
|
#ifdef HAVE_PQC
|
||||||
if (clientKSE->group >= WOLFSSL_PQC_MIN &&
|
if (WOLFSSL_NAMED_GROUP_IS_PQC(clientKSE->group)) {
|
||||||
clientKSE->group <= WOLFSSL_PQC_MAX ) {
|
|
||||||
/* Going to need the public key (AKA ciphertext). */
|
/* Going to need the public key (AKA ciphertext). */
|
||||||
serverKSE->pubKey = clientKSE->pubKey;
|
serverKSE->pubKey = clientKSE->pubKey;
|
||||||
clientKSE->pubKey = NULL;
|
clientKSE->pubKey = NULL;
|
||||||
@@ -10447,7 +10434,7 @@ int TLSX_QuicTP_Use(WOLFSSL* ssl, TLSX_Type ext_type, int is_response)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (extension->data) {
|
if (extension->data) {
|
||||||
QuicTransportParam_free(extension->data, ssl->heap);
|
QuicTransportParam_free((QuicTransportParam*)extension->data, ssl->heap);
|
||||||
extension->data = NULL;
|
extension->data = NULL;
|
||||||
}
|
}
|
||||||
extension->resp = is_response;
|
extension->resp = is_response;
|
||||||
@@ -11477,7 +11464,7 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer)
|
|||||||
if (namedGroup > 0) {
|
if (namedGroup > 0) {
|
||||||
#ifdef HAVE_PQC
|
#ifdef HAVE_PQC
|
||||||
/* For KEMs, the key share has already been generated. */
|
/* For KEMs, the key share has already been generated. */
|
||||||
if (namedGroup < WOLFSSL_PQC_MIN || namedGroup > WOLFSSL_PQC_MAX)
|
if (!WOLFSSL_NAMED_GROUP_IS_PQC(namedGroup))
|
||||||
#endif
|
#endif
|
||||||
ret = TLSX_KeyShare_Use(ssl, namedGroup, 0, NULL, NULL);
|
ret = TLSX_KeyShare_Use(ssl, namedGroup, 0, NULL, NULL);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
|
19
src/tls13.c
19
src/tls13.c
@@ -4803,6 +4803,8 @@ static int CheckPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 helloSz,
|
|||||||
#ifdef WOLFSSL_EARLY_DATA
|
#ifdef WOLFSSL_EARLY_DATA
|
||||||
ssl->earlyData = no_early_data;
|
ssl->earlyData = no_early_data;
|
||||||
#endif
|
#endif
|
||||||
|
if (usingPSK)
|
||||||
|
*usingPSK = 0;
|
||||||
/* Hash data up to binders for deriving binders in PSK extension. */
|
/* Hash data up to binders for deriving binders in PSK extension. */
|
||||||
ret = HashInput(ssl, input, helloSz);
|
ret = HashInput(ssl, input, helloSz);
|
||||||
return ret;
|
return ret;
|
||||||
@@ -4860,8 +4862,18 @@ static int CheckPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 helloSz,
|
|||||||
return ret;
|
return ret;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Hash the rest of the ClientHello. */
|
if (*usingPSK) {
|
||||||
ret = HashRaw(ssl, input + helloSz - bindersLen, bindersLen);
|
/* While verifying the selected PSK, we updated the
|
||||||
|
* handshake hash up to the binder bytes in the PSK extensions.
|
||||||
|
* Continuing, we need the rest of the ClientHello hashed as well.
|
||||||
|
*/
|
||||||
|
ret = HashRaw(ssl, input + helloSz - bindersLen, bindersLen);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* No suitable PSK found, Hash the complete ClientHello,
|
||||||
|
* as caller expect it after we return */
|
||||||
|
ret = HashInput(ssl, input, helloSz);
|
||||||
|
}
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@@ -10615,8 +10627,7 @@ int wolfSSL_UseKeyShare(WOLFSSL* ssl, word16 group)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_PQC
|
#ifdef HAVE_PQC
|
||||||
if (group >= WOLFSSL_PQC_MIN &&
|
if (WOLFSSL_NAMED_GROUP_IS_PQC(group)) {
|
||||||
group <= WOLFSSL_PQC_MAX) {
|
|
||||||
|
|
||||||
if (ssl->ctx != NULL && ssl->ctx->method != NULL &&
|
if (ssl->ctx != NULL && ssl->ctx->method != NULL &&
|
||||||
ssl->ctx->method->version.minor != TLSv1_3_MINOR) {
|
ssl->ctx->method->version.minor != TLSv1_3_MINOR) {
|
||||||
|
119
tests/quic.c
119
tests/quic.c
@@ -218,7 +218,7 @@ static void dump_buffer(const char *name, const byte *p, size_t len, int indent)
|
|||||||
while((p != NULL) && (i < len)) {
|
while((p != NULL) && (i < len)) {
|
||||||
if((i % 0x10) == 0) {
|
if((i % 0x10) == 0) {
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf("%*s %04X - ", indent, " ", (int)(i / 0x10));
|
printf("%*s %04X - ", indent, " ", (int)i);
|
||||||
}
|
}
|
||||||
else if((i % 0x08) == 0) {
|
else if((i % 0x08) == 0) {
|
||||||
printf(" ");
|
printf(" ");
|
||||||
@@ -1037,7 +1037,8 @@ static int test_quic_client_hello(int verbose) {
|
|||||||
/* Set transport params, expect both extensions */
|
/* Set transport params, expect both extensions */
|
||||||
QuicTestContext_init(&tctx, ctx, "client", verbose);
|
QuicTestContext_init(&tctx, ctx, "client", verbose);
|
||||||
#ifdef HAVE_SNI
|
#ifdef HAVE_SNI
|
||||||
wolfSSL_UseSNI(tctx.ssl, WOLFSSL_SNI_HOST_NAME, "wolfssl.com", sizeof("wolfssl.com")-1);
|
wolfSSL_UseSNI(tctx.ssl, WOLFSSL_SNI_HOST_NAME,
|
||||||
|
"wolfssl.com", sizeof("wolfssl.com")-1);
|
||||||
#endif
|
#endif
|
||||||
AssertTrue(wolfSSL_connect(tctx.ssl) != 0);
|
AssertTrue(wolfSSL_connect(tctx.ssl) != 0);
|
||||||
AssertIntEQ(wolfSSL_get_error(tctx.ssl, 0), SSL_ERROR_WANT_READ);
|
AssertIntEQ(wolfSSL_get_error(tctx.ssl, 0), SSL_ERROR_WANT_READ);
|
||||||
@@ -1106,9 +1107,11 @@ static int test_quic_server_hello(int verbose) {
|
|||||||
AssertIntEQ(tserver.output.len, 0);
|
AssertIntEQ(tserver.output.len, 0);
|
||||||
/* what have we seen? */
|
/* what have we seen? */
|
||||||
#ifdef HAVE_SESSION_TICKET
|
#ifdef HAVE_SESSION_TICKET
|
||||||
AssertStrEQ(conv.rec_log, "ClientHello:ServerHello:EncryptedExtension:Certificate:CertificateVerify:Finished:Finished:SessionTicket");
|
AssertStrEQ(conv.rec_log, "ClientHello:ServerHello:EncryptedExtension:"
|
||||||
|
"Certificate:CertificateVerify:Finished:Finished:SessionTicket");
|
||||||
#else
|
#else
|
||||||
AssertStrEQ(conv.rec_log, "ClientHello:ServerHello:EncryptedExtension:Certificate:CertificateVerify:Finished:Finished");
|
AssertStrEQ(conv.rec_log, "ClientHello:ServerHello:EncryptedExtension:"
|
||||||
|
"Certificate:CertificateVerify:Finished:Finished");
|
||||||
#endif
|
#endif
|
||||||
/* we are at application encryption level */
|
/* we are at application encryption level */
|
||||||
AssertTrue(wolfSSL_quic_read_level(tclient.ssl) == wolfssl_encryption_application);
|
AssertTrue(wolfSSL_quic_read_level(tclient.ssl) == wolfssl_encryption_application);
|
||||||
@@ -1142,9 +1145,8 @@ static int test_quic_server_hello(int verbose) {
|
|||||||
|
|
||||||
#ifdef HAVE_SESSION_TICKET
|
#ifdef HAVE_SESSION_TICKET
|
||||||
|
|
||||||
static int test_quic_resumption(int verbose) {
|
static int test_quic_key_share(int verbose) {
|
||||||
WOLFSSL_CTX *ctx_c, *ctx_s;
|
WOLFSSL_CTX *ctx_c, *ctx_s;
|
||||||
WOLFSSL_SESSION *session;
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
QuicTestContext tclient, tserver;
|
QuicTestContext tclient, tserver;
|
||||||
QuicConversation conv;
|
QuicConversation conv;
|
||||||
@@ -1154,6 +1156,53 @@ static int test_quic_resumption(int verbose) {
|
|||||||
AssertTrue(wolfSSL_CTX_use_certificate_file(ctx_s, svrCertFile, WOLFSSL_FILETYPE_PEM));
|
AssertTrue(wolfSSL_CTX_use_certificate_file(ctx_s, svrCertFile, WOLFSSL_FILETYPE_PEM));
|
||||||
AssertTrue(wolfSSL_CTX_use_PrivateKey_file(ctx_s, svrKeyFile, WOLFSSL_FILETYPE_PEM));
|
AssertTrue(wolfSSL_CTX_use_PrivateKey_file(ctx_s, svrKeyFile, WOLFSSL_FILETYPE_PEM));
|
||||||
|
|
||||||
|
/* setup & handshake defaults */
|
||||||
|
QuicTestContext_init(&tclient, ctx_c, "client", verbose);
|
||||||
|
QuicTestContext_init(&tserver, ctx_s, "server", verbose);
|
||||||
|
QuicConversation_init(&conv, &tclient, &tserver);
|
||||||
|
QuicConversation_do(&conv);
|
||||||
|
AssertStrEQ(conv.rec_log, "ClientHello:ServerHello:EncryptedExtension:"
|
||||||
|
"Certificate:CertificateVerify:Finished:Finished:SessionTicket");
|
||||||
|
QuicTestContext_free(&tclient);
|
||||||
|
QuicTestContext_free(&tserver);
|
||||||
|
|
||||||
|
/* setup & handshake, restricted groups, will trigger a
|
||||||
|
* HelloRetryRequest(ServerHello) and a new ClientHello */
|
||||||
|
QuicTestContext_init(&tclient, ctx_c, "client", verbose);
|
||||||
|
QuicTestContext_init(&tserver, ctx_s, "server", verbose);
|
||||||
|
AssertTrue(wolfSSL_set1_curves_list(tclient.ssl, "X25519:P-256")
|
||||||
|
== WOLFSSL_SUCCESS);
|
||||||
|
AssertTrue(wolfSSL_set1_curves_list(tserver.ssl, "X25519")
|
||||||
|
== WOLFSSL_SUCCESS);
|
||||||
|
QuicConversation_init(&conv, &tclient, &tserver);
|
||||||
|
QuicConversation_do(&conv);
|
||||||
|
AssertStrEQ(conv.rec_log,
|
||||||
|
"ClientHello:ServerHello:ClientHello:ServerHello:EncryptedExtension:"
|
||||||
|
"Certificate:CertificateVerify:Finished:Finished:SessionTicket");
|
||||||
|
QuicTestContext_free(&tclient);
|
||||||
|
QuicTestContext_free(&tserver);
|
||||||
|
|
||||||
|
wolfSSL_CTX_free(ctx_c);
|
||||||
|
wolfSSL_CTX_free(ctx_s);
|
||||||
|
printf(" test_quic_key_share: %s\n", (ret == 0)? passed : failed);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int test_quic_resumption(int verbose) {
|
||||||
|
WOLFSSL_CTX *ctx_c, *ctx_s;
|
||||||
|
WOLFSSL_SESSION *session, *session_restored;
|
||||||
|
int ret = 0;
|
||||||
|
QuicTestContext tclient, tserver;
|
||||||
|
QuicConversation conv;
|
||||||
|
unsigned char session_buffer[16 * 1024], *session_data;
|
||||||
|
const unsigned char *session_data2;
|
||||||
|
unsigned int session_size;
|
||||||
|
|
||||||
|
AssertNotNull(ctx_c = wolfSSL_CTX_new(wolfTLSv1_3_client_method()));
|
||||||
|
AssertNotNull(ctx_s = wolfSSL_CTX_new(wolfTLSv1_3_server_method()));
|
||||||
|
AssertTrue(wolfSSL_CTX_use_certificate_file(ctx_s, svrCertFile, WOLFSSL_FILETYPE_PEM));
|
||||||
|
AssertTrue(wolfSSL_CTX_use_PrivateKey_file(ctx_s, svrKeyFile, WOLFSSL_FILETYPE_PEM));
|
||||||
|
|
||||||
/* setup ssls */
|
/* setup ssls */
|
||||||
QuicTestContext_init(&tclient, ctx_c, "client", verbose);
|
QuicTestContext_init(&tclient, ctx_c, "client", verbose);
|
||||||
QuicTestContext_init(&tserver, ctx_s, "server", verbose);
|
QuicTestContext_init(&tserver, ctx_s, "server", verbose);
|
||||||
@@ -1162,15 +1211,25 @@ static int test_quic_resumption(int verbose) {
|
|||||||
/* run till end */
|
/* run till end */
|
||||||
QuicConversation_do(&conv);
|
QuicConversation_do(&conv);
|
||||||
/* what have we seen? */
|
/* what have we seen? */
|
||||||
AssertStrEQ(conv.rec_log, "ClientHello:ServerHello:EncryptedExtension:Certificate:CertificateVerify:Finished:Finished:SessionTicket");
|
AssertStrEQ(conv.rec_log, "ClientHello:ServerHello:EncryptedExtension:"
|
||||||
|
"Certificate:CertificateVerify:Finished:Finished:SessionTicket");
|
||||||
|
|
||||||
/* Should have received a session ticket, save the session */
|
/* Should have received a session ticket, save the session
|
||||||
|
* and also make a serialized/deserialized copy to check that persisting
|
||||||
|
* a session works. */
|
||||||
AssertTrue(tclient.ticket_len > 0);
|
AssertTrue(tclient.ticket_len > 0);
|
||||||
AssertNotNull(session = wolfSSL_get1_session(tclient.ssl));
|
AssertNotNull(session = wolfSSL_get1_session(tclient.ssl));
|
||||||
|
AssertTrue((session_size = wolfSSL_i2d_SSL_SESSION(session, NULL)) > 0);
|
||||||
|
AssertTrue((size_t)session_size < sizeof(session_buffer));
|
||||||
|
session_data2 = session_data = session_buffer;
|
||||||
|
session_size = wolfSSL_i2d_SSL_SESSION(session, &session_data);
|
||||||
|
session_restored = wolfSSL_d2i_SSL_SESSION(NULL, &session_data2, session_size);
|
||||||
|
AssertNotNull(session_restored);
|
||||||
|
|
||||||
QuicTestContext_free(&tserver);
|
QuicTestContext_free(&tserver);
|
||||||
QuicTestContext_free(&tclient);
|
QuicTestContext_free(&tclient);
|
||||||
|
|
||||||
/* Do a Session resumption with the ticket */
|
/* Do a Session resumption with the session object */
|
||||||
QuicTestContext_init(&tserver, ctx_s, "server", verbose);
|
QuicTestContext_init(&tserver, ctx_s, "server", verbose);
|
||||||
QuicTestContext_init(&tclient, ctx_c, "client_resume", verbose);
|
QuicTestContext_init(&tclient, ctx_c, "client_resume", verbose);
|
||||||
AssertIntEQ(wolfSSL_set_session(tclient.ssl, session), WOLFSSL_SUCCESS);
|
AssertIntEQ(wolfSSL_set_session(tclient.ssl, session), WOLFSSL_SUCCESS);
|
||||||
@@ -1178,12 +1237,46 @@ static int test_quic_resumption(int verbose) {
|
|||||||
QuicConversation_init(&conv, &tclient, &tserver);
|
QuicConversation_init(&conv, &tclient, &tserver);
|
||||||
QuicConversation_do(&conv);
|
QuicConversation_do(&conv);
|
||||||
/* this is what should happen. Look Ma, no certificate! */
|
/* this is what should happen. Look Ma, no certificate! */
|
||||||
AssertStrEQ(conv.rec_log, "ClientHello:ServerHello:EncryptedExtension:Finished:Finished:SessionTicket");
|
AssertStrEQ(conv.rec_log, "ClientHello:ServerHello:EncryptedExtension:"
|
||||||
|
"Finished:Finished:SessionTicket");
|
||||||
QuicTestContext_free(&tclient);
|
QuicTestContext_free(&tclient);
|
||||||
QuicTestContext_free(&tserver);
|
QuicTestContext_free(&tserver);
|
||||||
|
|
||||||
|
/* Do a Session resumption with the restored session object */
|
||||||
|
QuicTestContext_init(&tserver, ctx_s, "server", verbose);
|
||||||
|
QuicTestContext_init(&tclient, ctx_c, "client_resume_restored", verbose);
|
||||||
|
AssertIntEQ(wolfSSL_set_session(tclient.ssl, session_restored), WOLFSSL_SUCCESS);
|
||||||
|
/* let them talk */
|
||||||
|
QuicConversation_init(&conv, &tclient, &tserver);
|
||||||
|
QuicConversation_do(&conv);
|
||||||
|
/* this is what should happen. Look Ma, no certificate! */
|
||||||
|
AssertStrEQ(conv.rec_log, "ClientHello:ServerHello:EncryptedExtension:"
|
||||||
|
"Finished:Finished:SessionTicket");
|
||||||
|
QuicTestContext_free(&tclient);
|
||||||
|
QuicTestContext_free(&tserver);
|
||||||
|
|
||||||
|
{
|
||||||
|
/* Do a Session resumption with a new server ctx */
|
||||||
|
WOLFSSL_CTX *ctx_s2;
|
||||||
|
AssertNotNull(ctx_s2 = wolfSSL_CTX_new(wolfTLSv1_3_server_method()));
|
||||||
|
AssertTrue(wolfSSL_CTX_use_certificate_file(ctx_s2, eccCertFile, WOLFSSL_FILETYPE_PEM));
|
||||||
|
AssertTrue(wolfSSL_CTX_use_PrivateKey_file(ctx_s2, eccKeyFile, WOLFSSL_FILETYPE_PEM));
|
||||||
|
|
||||||
|
QuicTestContext_init(&tserver, ctx_s2, "server2", verbose);
|
||||||
|
QuicTestContext_init(&tclient, ctx_c, "client_resume2", verbose);
|
||||||
|
AssertIntEQ(wolfSSL_set_session(tclient.ssl, session_restored), WOLFSSL_SUCCESS);
|
||||||
|
/* let them talk */
|
||||||
|
QuicConversation_init(&conv, &tclient, &tserver);
|
||||||
|
QuicConversation_do(&conv);
|
||||||
|
AssertStrEQ(conv.rec_log, "ClientHello:ServerHello:EncryptedExtension:"
|
||||||
|
"Certificate:CertificateVerify:Finished:Finished:SessionTicket");
|
||||||
|
QuicTestContext_free(&tclient);
|
||||||
|
QuicTestContext_free(&tserver);
|
||||||
|
wolfSSL_CTX_free(ctx_s2);
|
||||||
|
}
|
||||||
|
|
||||||
wolfSSL_SESSION_free(session);
|
wolfSSL_SESSION_free(session);
|
||||||
|
wolfSSL_SESSION_free(session_restored);
|
||||||
wolfSSL_CTX_free(ctx_c);
|
wolfSSL_CTX_free(ctx_c);
|
||||||
wolfSSL_CTX_free(ctx_s);
|
wolfSSL_CTX_free(ctx_s);
|
||||||
|
|
||||||
@@ -1220,7 +1313,8 @@ static int test_quic_early_data(int verbose) {
|
|||||||
/* run till end */
|
/* run till end */
|
||||||
QuicConversation_do(&conv);
|
QuicConversation_do(&conv);
|
||||||
/* what have we seen? */
|
/* what have we seen? */
|
||||||
AssertStrEQ(conv.rec_log, "ClientHello:ServerHello:EncryptedExtension:Certificate:CertificateVerify:Finished:Finished:SessionTicket");
|
AssertStrEQ(conv.rec_log, "ClientHello:ServerHello:EncryptedExtension:"
|
||||||
|
"Certificate:CertificateVerify:Finished:Finished:SessionTicket");
|
||||||
|
|
||||||
/* Should have received a session ticket, save the session */
|
/* Should have received a session ticket, save the session */
|
||||||
AssertTrue(tclient.ticket_len > 0);
|
AssertTrue(tclient.ticket_len > 0);
|
||||||
@@ -1379,6 +1473,7 @@ int QuicTest(void)
|
|||||||
if ((ret = test_quic_client_hello(verbose)) != 0) goto leave;
|
if ((ret = test_quic_client_hello(verbose)) != 0) goto leave;
|
||||||
if ((ret = test_quic_server_hello(verbose)) != 0) goto leave;
|
if ((ret = test_quic_server_hello(verbose)) != 0) goto leave;
|
||||||
#ifdef HAVE_SESSION_TICKET
|
#ifdef HAVE_SESSION_TICKET
|
||||||
|
if ((ret = test_quic_key_share(verbose)) != 0) goto leave;
|
||||||
if ((ret = test_quic_resumption(verbose)) != 0) goto leave;
|
if ((ret = test_quic_resumption(verbose)) != 0) goto leave;
|
||||||
#ifdef WOLFSSL_EARLY_DATA
|
#ifdef WOLFSSL_EARLY_DATA
|
||||||
if ((ret = test_quic_early_data(verbose || 1)) != 0) goto leave;
|
if ((ret = test_quic_early_data(verbose || 1)) != 0) goto leave;
|
||||||
|
@@ -1570,6 +1570,15 @@ enum Misc {
|
|||||||
READ_PROTO = 0 /* reading a protocol message */
|
READ_PROTO = 0 /* reading a protocol message */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define WOLFSSL_NAMED_GROUP_IS_FFHDE(group) \
|
||||||
|
(MIN_FFHDE_GROUP <= (group) && (group) <= MAX_FFHDE_GROUP)
|
||||||
|
#ifdef HAVE_PQC
|
||||||
|
#define WOLFSSL_NAMED_GROUP_IS_PQC(group) \
|
||||||
|
(WOLFSSL_PQC_MIN <= (group) && (group) <= WOLFSSL_PQC_MAX)
|
||||||
|
#else
|
||||||
|
#define WOLFSSL_NAMED_GROUP_IS_PQC(group) ((void)(group), 0)
|
||||||
|
#endif /* HAVE_PQC */
|
||||||
|
|
||||||
/* minimum Downgrade Minor version */
|
/* minimum Downgrade Minor version */
|
||||||
#ifndef WOLFSSL_MIN_DOWNGRADE
|
#ifndef WOLFSSL_MIN_DOWNGRADE
|
||||||
#ifndef NO_OLD_TLS
|
#ifndef NO_OLD_TLS
|
||||||
@@ -4659,6 +4668,7 @@ struct WOLFSSL {
|
|||||||
WOLFSSL_BIO* biowr; /* socket bio write to free/close */
|
WOLFSSL_BIO* biowr; /* socket bio write to free/close */
|
||||||
byte sessionCtx[ID_LEN]; /* app session context ID */
|
byte sessionCtx[ID_LEN]; /* app session context ID */
|
||||||
WOLFSSL_X509_VERIFY_PARAM* param; /* verification parameters*/
|
WOLFSSL_X509_VERIFY_PARAM* param; /* verification parameters*/
|
||||||
|
word32 disabledCurves; /* curves disabled by user */
|
||||||
#endif
|
#endif
|
||||||
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
|
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
|
||||||
unsigned long peerVerifyRet;
|
unsigned long peerVerifyRet;
|
||||||
@@ -5242,6 +5252,12 @@ WOLFSSL_LOCAL int SetECKeyInternal(WOLFSSL_EC_KEY* eckey);
|
|||||||
WOLFSSL_LOCAL int SetECKeyExternal(WOLFSSL_EC_KEY* eckey);
|
WOLFSSL_LOCAL int SetECKeyExternal(WOLFSSL_EC_KEY* eckey);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(OPENSSL_EXTRA)
|
||||||
|
WOLFSSL_LOCAL int wolfSSL_curve_is_disabled(WOLFSSL* ssl, word16 named_curve);
|
||||||
|
#else
|
||||||
|
#define wolfSSL_curve_is_disabled(ssl, c) ((void)(ssl), (void)(c), 0)
|
||||||
|
#endif
|
||||||
|
|
||||||
WOLFSSL_LOCAL WC_RNG* WOLFSSL_RSA_GetRNG(WOLFSSL_RSA *rsa, WC_RNG **tmpRNG,
|
WOLFSSL_LOCAL WC_RNG* WOLFSSL_RSA_GetRNG(WOLFSSL_RSA *rsa, WC_RNG **tmpRNG,
|
||||||
int *initTmpRng);
|
int *initTmpRng);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user