Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 82 additions & 19 deletions src/internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -716,6 +716,8 @@ int IsDtlsNotSrtpMode(WOLFSSL* ssl)
static void* myAlloc(void* opaque, unsigned int item, unsigned int size)
{
(void)opaque;
if (item != 0 && size > ((unsigned int)-1) / item)
return NULL;
return (void *)XMALLOC(item * size, opaque, DYNAMIC_TYPE_LIBZ);
}

Expand Down Expand Up @@ -1094,7 +1096,16 @@ static int ImportCipherSpecState(WOLFSSL* ssl, const byte* exp, word32 len,

if (type == WOLFSSL_EXPORT_TLS &&
ssl->specs.bulk_cipher_algorithm == wolfssl_aes) {
byte *pt = (byte*)ssl->encrypt.aes->reg;
byte *pt;
if ((idx + 2 * WC_AES_BLOCK_SIZE) > len) {
WOLFSSL_MSG("Buffer not large enough for AES state import");
return BUFFER_E;
}
if (ssl->encrypt.aes == NULL || ssl->decrypt.aes == NULL) {
WOLFSSL_MSG("AES cipher objects not allocated for import");
return BAD_STATE_E;
Comment thread
embhorn marked this conversation as resolved.
}
pt = (byte*)ssl->encrypt.aes->reg;
XMEMCPY(pt, exp + idx, WC_AES_BLOCK_SIZE);
idx += WC_AES_BLOCK_SIZE;

Expand Down Expand Up @@ -2052,7 +2063,11 @@ int wolfSSL_session_import_internal(WOLFSSL* ssl, const unsigned char* buf,
}

if (ret == 0) {
rc = ImportCipherSpecState(ssl, buf + idx, length, version, type);
/* Pass remaining buffer size rather than the stored spec length:
* when TLS+AES is active, ExportCipherSpecState writes 2*AES_BLOCK_SIZE
* of extra state immediately after the 16-byte cipher-spec block, and
* the on-wire length prefix does not cover those bytes. */
rc = ImportCipherSpecState(ssl, buf + idx, sz - idx, version, type);
if (rc < 0) {
WOLFSSL_MSG("Import CipherSpecs struct error");
ret = rc;
Expand Down Expand Up @@ -9376,13 +9391,13 @@ void FreeSSL(WOLFSSL* ssl, void* heap)
{
WOLFSSL_CTX* ctx = ssl->ctx;
wolfSSL_ResourceFree(ssl);
#ifdef WOLFSSL_CHECK_MEM_ZERO
wc_MemZero_Check(ssl, sizeof(*ssl));
#endif
XFREE(ssl, heap, DYNAMIC_TYPE_SSL);
if (ctx)
FreeSSL_Ctx(ctx); /* will decrement and free underlying CTX if 0 */
(void)heap;
#ifdef WOLFSSL_CHECK_MEM_ZERO
wc_MemZero_Check(ssl, sizeof(*ssl));
#endif
}

#if !defined(NO_OLD_TLS) || defined(WOLFSSL_DTLS) || \
Expand Down Expand Up @@ -9954,7 +9969,11 @@ void DtlsMsgStore(WOLFSSL* ssl, word16 epoch, word32 seq, const byte* data,
DtlsMsg* cur = DtlsMsgFind(head, epoch, seq);
if (cur == NULL) {
cur = DtlsMsgNew(dataSz, 0, heap);
if (cur != NULL) {
if (cur == NULL) {
WOLFSSL_MSG("DtlsMsgNew allocation failed");
ssl->error = MEMORY_E;
}
else {
if (DtlsMsgSet(cur, seq, epoch, data, type,
fragOffset, fragSz, heap, dataSz, encrypted) < 0) {
DtlsMsgDelete(cur, heap);
Expand All @@ -9973,7 +9992,11 @@ void DtlsMsgStore(WOLFSSL* ssl, word16 epoch, word32 seq, const byte* data,
}
else {
Comment thread
embhorn marked this conversation as resolved.
head = DtlsMsgNew(dataSz, 0, heap);
if (DtlsMsgSet(head, seq, epoch, data, type, fragOffset,
if (head == NULL) {
WOLFSSL_MSG("DtlsMsgNew allocation failed");
ssl->error = MEMORY_E;
}
else if (DtlsMsgSet(head, seq, epoch, data, type, fragOffset,
fragSz, heap, dataSz, encrypted) < 0) {
DtlsMsgDelete(head, heap);
head = NULL;
Expand Down Expand Up @@ -10623,6 +10646,9 @@ static int EdDSA_Update(WOLFSSL* ssl, const byte* data, int sz)
byte* msgs;
Comment thread
embhorn marked this conversation as resolved.

if (ssl->options.cacheMessages) {
if (sz < 0 || ssl->hsHashes->length < 0 ||
ssl->hsHashes->length > INT_MAX - sz)
return BUFFER_ERROR;
msgs = (byte*)XMALLOC(ssl->hsHashes->length + sz, ssl->heap,
DYNAMIC_TYPE_HASHES);
if (msgs == NULL)
Expand Down Expand Up @@ -10776,6 +10802,9 @@ int HashOutput(WOLFSSL* ssl, const byte* output, int sz, int ivSz)
}
#endif

if (sz < 0)
return BUFFER_ERROR;

return HashRaw(ssl, adj, sz);
}

Expand Down Expand Up @@ -17127,6 +17156,8 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
else {
ssl->peerEd25519KeyPresent = 1;
#ifdef HAVE_PK_CALLBACKS
XFREE(ssl->buffers.peerEd25519Key.buffer,
ssl->heap, DYNAMIC_TYPE_ED25519);
ssl->buffers.peerEd25519Key.buffer =
(byte*)XMALLOC(args->dCert->pubKeySize,
Comment thread
embhorn marked this conversation as resolved.
ssl->heap, DYNAMIC_TYPE_ED25519);
Expand Down Expand Up @@ -17182,6 +17213,8 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
else {
ssl->peerEd448KeyPresent = 1;
#ifdef HAVE_PK_CALLBACKS
XFREE(ssl->buffers.peerEd448Key.buffer,
ssl->heap, DYNAMIC_TYPE_ED448);
ssl->buffers.peerEd448Key.buffer =
(byte*)XMALLOC(args->dCert->pubKeySize,
Comment thread
embhorn marked this conversation as resolved.
ssl->heap, DYNAMIC_TYPE_ED448);
Expand Down Expand Up @@ -17629,9 +17662,9 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx,

Comment thread
embhorn marked this conversation as resolved.
ssl->status_request_v2 = 0;

WC_FREE_VAR_EX(status, NULL, DYNAMIC_TYPE_OCSP_STATUS);
WC_FREE_VAR_EX(single, NULL, DYNAMIC_TYPE_OCSP_ENTRY);
WC_FREE_VAR_EX(response, NULL, DYNAMIC_TYPE_OCSP_REQUEST);
WC_FREE_VAR_EX(status, ssl->heap, DYNAMIC_TYPE_OCSP_STATUS);
WC_FREE_VAR_EX(single, ssl->heap, DYNAMIC_TYPE_OCSP_ENTRY);
WC_FREE_VAR_EX(response, ssl->heap, DYNAMIC_TYPE_OCSP_REQUEST);

}
break;
Expand Down Expand Up @@ -26214,8 +26247,6 @@ int SendAsyncData(WOLFSSL* ssl)
*/
static int ssl_in_handshake(WOLFSSL *ssl, int sending_data)
{
int SendAsyncData = 1;
(void)SendAsyncData;
if (IsSCR(ssl)) {
if (sending_data) {
/* allow sending data in SCR */
Expand Down Expand Up @@ -29194,7 +29225,10 @@ static int ParseCipherList(Suites* suites,
/* Restore user ciphers ahead of defaults */
XMEMMOVE(suites->suites + idx, suites->suites,
min(suites->suiteSz, WOLFSSL_MAX_SUITE_SZ-idx));
suites->suiteSz += (word16)idx;
if ((word32)suites->suiteSz + idx > WOLFSSL_MAX_SUITE_SZ)
suites->suiteSz = WOLFSSL_MAX_SUITE_SZ;
else
suites->suiteSz += (word16)idx;
}
else
#endif
Expand Down Expand Up @@ -35034,6 +35068,9 @@ int SetTicket(WOLFSSL* ssl, const byte* ticket, word32 length)
{
word32 sessIdLen = ID_LEN;

if (length > WOLFSSL_MAX_16BIT)
return BUFFER_ERROR;

if (!HaveUniqueSessionObj(ssl))
return MEMORY_ERROR;

Expand Down Expand Up @@ -35812,6 +35849,8 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
args->output[args->idx++] = SetCurveId(ssl->eccTempKey);
#endif
}
if (args->exportSz > WOLFSSL_MAX_8BIT)
return BUFFER_ERROR;
args->output[args->idx++] = (byte)args->exportSz;
XMEMCPY(args->output + args->idx, args->exportBuf, args->exportSz);
return 0;
Expand Down Expand Up @@ -35924,6 +35963,10 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)

static int SKE_AddDhPub(Buffers* buffers, byte* output, int idx)
{ /* add p, g, pub */
if (buffers->serverDH_P.length > WOLFSSL_MAX_16BIT ||
buffers->serverDH_G.length > WOLFSSL_MAX_16BIT ||
buffers->serverDH_Pub.length > WOLFSSL_MAX_16BIT)
return BUFFER_ERROR;
c16toa((word16)buffers->serverDH_P.length, output + idx);
idx += LENGTH_SZ;
XMEMCPY(output + idx, buffers->serverDH_P.buffer,
Expand Down Expand Up @@ -36390,8 +36433,12 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
AddHeaders(args->output, args->length,
server_key_exchange, ssl);
AddServerHint(ssl, args, hintLen);
args->idx = SKE_AddDhPub(&ssl->buffers, args->output,
args->idx);
ret = SKE_AddDhPub(&ssl->buffers, args->output,
args->idx);
if (ret < 0)
goto exit_sske;
args->idx = ret;
ret = 0;
break;
}
#endif /* !defined(NO_DH) && !defined(NO_PSK) */
Expand Down Expand Up @@ -36577,8 +36624,12 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
CHECK_RET(ret, AllocArgsInput(ssl, args), exit_sske);
AddHeaders(args->output, args->length,
server_key_exchange, ssl);
args->idx = SKE_AddDhPub(&ssl->buffers, args->output,
args->idx);
ret = SKE_AddDhPub(&ssl->buffers, args->output,
args->idx);
if (ret < 0)
goto exit_sske;
args->idx = ret;
ret = 0;

#ifdef HAVE_FUZZER
if (ssl->fuzzerCb) {
Expand Down Expand Up @@ -36971,8 +37022,9 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
switch (ssl->options.sigAlgo)
{
#ifndef NO_RSA
#ifndef WC_RSA_PSS
#ifdef WC_RSA_PSS
case rsa_pss_sa_algo:
Comment thread
embhorn marked this conversation as resolved.
case rsa_pss_pss_algo:
#endif
case rsa_sa_algo:
{
Expand Down Expand Up @@ -37499,7 +37551,6 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
Suites clSuites;
int ret = -1;

(void)inSz;
WOLFSSL_MSG("Got old format client hello");
#ifdef WOLFSSL_CALLBACKS
if (ssl->hsInfoOn)
Expand Down Expand Up @@ -37587,6 +37638,11 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
TRUE, TRUE, TRUE, TRUE, ssl->options.side);
}

/* Need at least 3 * OPAQUE16_LEN bytes for suiteSz/sessionSz/randomSz
* headers before reading the per-field bodies. */
if (idx + 3 * OPAQUE16_LEN > inSz)
return BUFFER_ERROR;

/* suite size */
ato16(&input[idx], &clSuites.suiteSz);
idx += OPAQUE16_LEN;
Expand All @@ -37612,6 +37668,11 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
if (randomSz > RAN_LEN)
return BUFFER_ERROR;

Comment thread
embhorn marked this conversation as resolved.
/* Cumulative bounds check against actual input buffer length. */
if ((word32)clSuites.suiteSz + (word32)sessionSz + (word32)randomSz
> inSz - idx)
return BUFFER_ERROR;

/* suites */
for (i = 0, j = 0; i < clSuites.suiteSz; i += 3) {
byte first = input[idx++];
Expand Down Expand Up @@ -39658,6 +39719,8 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
#endif

if (!IsAtLeastTLSv1_3(ssl->version)) {
if (ssl->arrays == NULL)
return;
XMEMCPY(ssl->arrays->masterSecret, it->msecret, SECRET_LEN);
/* Copy the haveExtendedMasterSecret property from the ticket to
* the saved session, so the property may be checked later. */
Expand Down
42 changes: 42 additions & 0 deletions tests/api/test_tls.c
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,48 @@ int test_tls12_curve_intersection(void) {
return EXPECT_RESULT();
}

int test_tls12_dhe_rsa_pss_sigalg(void)
{
EXPECT_DECLS;
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
!defined(WOLFSSL_NO_TLS12) && !defined(NO_DH) && !defined(NO_RSA) && \
defined(WC_RSA_PSS) && !defined(NO_SHA256) && defined(HAVE_AESGCM) && \
!defined(WOLFSSL_HARDEN_TLS) && defined(OPENSSL_EXTRA)
/* Regression test for S1: SendServerKeyExchange had an inverted guard
* (#ifndef WC_RSA_PSS) that compiled out the rsa_pss_sa_algo case in the
* server-side signature self-check for the DHE key exchange path. This
* test drives a DHE-RSA handshake restricted to RSA-PSS+SHA256 so the
* server exercises that code path. The bug did not cause the handshake
* to fail, so we verify by asserting the negotiated sig algorithm. */
WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL;
WOLFSSL *ssl_c = NULL, *ssl_s = NULL;
struct test_memio_ctx test_ctx;

XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
wolfTLSv1_2_client_method, wolfTLSv1_2_server_method), 0);

ExpectIntEQ(wolfSSL_set_cipher_list(ssl_c, "DHE-RSA-AES128-GCM-SHA256"),
WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_set_cipher_list(ssl_s, "DHE-RSA-AES128-GCM-SHA256"),
WOLFSSL_SUCCESS);

ExpectIntEQ(wolfSSL_set1_sigalgs_list(ssl_c, "RSA-PSS+SHA256"), 1);
ExpectIntEQ(wolfSSL_set1_sigalgs_list(ssl_s, "RSA-PSS+SHA256"), 1);

ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);

ExpectIntEQ(ssl_s->options.sigAlgo, rsa_pss_sa_algo);
ExpectIntEQ(ssl_c->options.peerSigAlgo, rsa_pss_sa_algo);

wolfSSL_free(ssl_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_c);
wolfSSL_CTX_free(ctx_s);
#endif
return EXPECT_RESULT();
}

int test_tls13_curve_intersection(void) {
EXPECT_DECLS;
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
Expand Down
2 changes: 2 additions & 0 deletions tests/api/test_tls.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ int test_utils_memio_move_message(void);
int test_tls12_unexpected_ccs(void);
int test_tls13_unexpected_ccs(void);
int test_tls12_curve_intersection(void);
int test_tls12_dhe_rsa_pss_sigalg(void);
int test_tls13_curve_intersection(void);
int test_tls_certreq_order(void);
int test_tls12_bad_cv_sig_alg(void);
Expand All @@ -38,6 +39,7 @@ int test_tls_set_curves_list_ecc_fallback(void);
TEST_DECL_GROUP("tls", test_tls12_unexpected_ccs), \
TEST_DECL_GROUP("tls", test_tls13_unexpected_ccs), \
TEST_DECL_GROUP("tls", test_tls12_curve_intersection), \
TEST_DECL_GROUP("tls", test_tls12_dhe_rsa_pss_sigalg), \
TEST_DECL_GROUP("tls", test_tls13_curve_intersection), \
TEST_DECL_GROUP("tls", test_tls_certreq_order), \
TEST_DECL_GROUP("tls", test_tls12_bad_cv_sig_alg), \
Expand Down
Loading