mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-07-05 10:40:52 +02:00
@@ -631,6 +631,16 @@ static int wolfSSL_BIO_MEMORY_write(WOLFSSL_BIO* bio, const void* data,
|
||||
if (len <= 0)
|
||||
return 0; /* Nothing to write */
|
||||
|
||||
/* Reject sizes that would overflow the buffer growth calculation, which
|
||||
* rounds the requested size up to the next multiple of 4/3 via
|
||||
* (size + 3) / 3 * 4. The extra rounding slack means the safe ceiling is
|
||||
* one below (INT_MAX / 4) * 3. Without this an oversized length grows a
|
||||
* short buffer and copies past the source. */
|
||||
if (len > ((INT_MAX / 4) * 3) - 1 - bio->wrSz) {
|
||||
WOLFSSL_MSG("write length too large");
|
||||
return WOLFSSL_BIO_ERROR;
|
||||
}
|
||||
|
||||
if (wolfSSL_BUF_MEM_grow_ex(bio->mem_buf, ((size_t)bio->wrSz) +
|
||||
((size_t)len), 0) == 0) {
|
||||
WOLFSSL_MSG("Error growing memory area");
|
||||
|
||||
+49
-28
@@ -2222,6 +2222,7 @@ WOLFSSL_ASN1_OBJECT *wolfSSL_d2i_ASN1_OBJECT(WOLFSSL_ASN1_OBJECT **a,
|
||||
WOLFSSL_ASN1_OBJECT* ret = NULL;
|
||||
int len = 0;
|
||||
word32 idx = 0;
|
||||
word32 maxIdx;
|
||||
|
||||
WOLFSSL_ENTER("wolfSSL_d2i_ASN1_OBJECT");
|
||||
|
||||
@@ -2231,7 +2232,17 @@ WOLFSSL_ASN1_OBJECT *wolfSSL_d2i_ASN1_OBJECT(WOLFSSL_ASN1_OBJECT **a,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (GetASNHeader(*der, ASN_OBJECT_ID, &idx, &len, (word32)length) < 0) {
|
||||
/* An ASN.1 OBJECT is an OID, whose DER encoding cannot exceed the OID
|
||||
* ceiling: a tag byte, a single short-form length byte (content is at
|
||||
* most MAX_OID_SZ, which is below the long-form threshold) and the OID
|
||||
* content. Cap the parse window so an oversized length argument cannot
|
||||
* drive the header decode to read past the end of the actual buffer. */
|
||||
maxIdx = (word32)length;
|
||||
if (maxIdx > (word32)(MAX_OID_SZ + 2)) {
|
||||
maxIdx = (word32)(MAX_OID_SZ + 2);
|
||||
}
|
||||
|
||||
if (GetASNHeader(*der, ASN_OBJECT_ID, &idx, &len, maxIdx) < 0) {
|
||||
WOLFSSL_MSG("error getting tag");
|
||||
return NULL;
|
||||
}
|
||||
@@ -3163,42 +3174,52 @@ int wolfSSL_ASN1_STRING_set(WOLFSSL_ASN1_STRING* asn1, const void* data, int sz)
|
||||
* when sz == INT_MAX. By this point sz >= 0 (negative sz is
|
||||
* handled above as OpenSSL -1/strlen compat). */
|
||||
size_t allocSz = (size_t)sz + 1;
|
||||
char* oldData = asn1->data;
|
||||
int oldDynamic = asn1->isDynamic;
|
||||
char* dst;
|
||||
|
||||
/* Dispose of any existing dynamic data. */
|
||||
if (asn1->isDynamic) {
|
||||
XFREE(asn1->data, NULL, DYNAMIC_TYPE_OPENSSL);
|
||||
asn1->data = NULL;
|
||||
}
|
||||
|
||||
/* Check string will fit - including NUL. */
|
||||
/* Select the destination buffer WITHOUT disposing of the existing
|
||||
* data yet. Deferring the free keeps the copy below safe even when
|
||||
* the source aliases the object's own buffer (data == asn1->data),
|
||||
* avoiding a use-after-free or clear-before-copy without needing an
|
||||
* ephemeral allocation. */
|
||||
if (allocSz > CTC_NAME_SIZE) {
|
||||
/* Allocate new buffer. */
|
||||
asn1->data = (char*)XMALLOC(allocSz, NULL,
|
||||
DYNAMIC_TYPE_OPENSSL);
|
||||
if (asn1->data == NULL) {
|
||||
dst = (char*)XMALLOC(allocSz, NULL, DYNAMIC_TYPE_OPENSSL);
|
||||
if (dst == NULL) {
|
||||
ret = 0;
|
||||
}
|
||||
else {
|
||||
/* Ensure buffer will be freed. */
|
||||
asn1->isDynamic = 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Clear out fixed array and use it for data. */
|
||||
XMEMSET(asn1->strData, 0, CTC_NAME_SIZE);
|
||||
asn1->data = asn1->strData;
|
||||
asn1->isDynamic = 0;
|
||||
/* Use the fixed array for data. */
|
||||
dst = asn1->strData;
|
||||
}
|
||||
}
|
||||
if (ret == 1) {
|
||||
/* Check if there is a string to copy. */
|
||||
if (data != NULL) {
|
||||
/* Copy string and append NUL. */
|
||||
XMEMCPY(asn1->data, data, (size_t)sz);
|
||||
asn1->data[sz] = '\0';
|
||||
|
||||
if (ret == 1) {
|
||||
/* Copy string and append NUL. XMEMMOVE handles the case where
|
||||
* data aliases the fixed array (source and destination overlap). */
|
||||
if (data != NULL) {
|
||||
XMEMMOVE(dst, data, (size_t)sz);
|
||||
}
|
||||
dst[sz] = '\0';
|
||||
|
||||
/* Clear any remainder of the fixed array (matches prior behavior
|
||||
* of zeroing the whole array). Done after the copy so it never
|
||||
* disturbs an aliased source. */
|
||||
if (dst == asn1->strData) {
|
||||
XMEMSET(dst + sz + 1, 0, CTC_NAME_SIZE - (size_t)sz - 1);
|
||||
}
|
||||
|
||||
/* Dispose of any old dynamic buffer now the copy is complete. */
|
||||
if (oldDynamic && (oldData != dst)) {
|
||||
XFREE(oldData, NULL, DYNAMIC_TYPE_OPENSSL);
|
||||
}
|
||||
|
||||
/* Commit the new buffer and its properties. */
|
||||
asn1->data = dst;
|
||||
asn1->isDynamic = (allocSz > CTC_NAME_SIZE) ? 1 : 0;
|
||||
asn1->length = sz;
|
||||
}
|
||||
/* Set size of string. */
|
||||
asn1->length = sz;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
+19
-1
@@ -13590,6 +13590,16 @@ static int SanityCheckTls13MsgReceived(WOLFSSL* ssl, byte type)
|
||||
|
||||
case key_update:
|
||||
/* Valid on both sides. */
|
||||
#ifdef WOLFSSL_QUIC
|
||||
/* RFC 9001 Section 6: QUIC performs key updates at the QUIC
|
||||
* packet-protection layer, so a TLS KeyUpdate message must be
|
||||
* rejected as a fatal unexpected_message connection error. */
|
||||
if (WOLFSSL_IS_QUIC(ssl)) {
|
||||
WOLFSSL_MSG("KeyUpdate received over QUIC");
|
||||
WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
|
||||
return SANITY_MSG_E;
|
||||
}
|
||||
#endif
|
||||
/* Check state.
|
||||
* Client and server must have received finished message from other
|
||||
* side.
|
||||
@@ -14976,6 +14986,13 @@ int Tls13UpdateKeys(WOLFSSL* ssl)
|
||||
if (ssl == NULL || !IsAtLeastTLSv1_3(ssl->version))
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
#ifdef WOLFSSL_QUIC
|
||||
/* RFC 9001 Section 6: a QUIC connection must not send a TLS KeyUpdate;
|
||||
* key updates are handled at the QUIC packet-protection layer. */
|
||||
if (WOLFSSL_IS_QUIC(ssl))
|
||||
return BAD_FUNC_ARG;
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_DTLS13
|
||||
/* we are already waiting for the ack of a sent key update message. We can't
|
||||
send another one before receiving its ack. Either wolfSSL_update_keys()
|
||||
@@ -14995,7 +15012,8 @@ int Tls13UpdateKeys(WOLFSSL* ssl)
|
||||
* calling wolfSSL_write() will have the message sent when ready.
|
||||
*
|
||||
* ssl The SSL/TLS object.
|
||||
* returns BAD_FUNC_ARG when ssl is NULL, or not using TLS v1.3,
|
||||
* returns BAD_FUNC_ARG when ssl is NULL, not using TLS v1.3, or running over
|
||||
* QUIC (RFC 9001 handles key updates at the QUIC packet-protection layer),
|
||||
* WOLFSSL_ERROR_WANT_WRITE when non-blocking I/O is not ready to write,
|
||||
* WOLFSSL_SUCCESS on success and otherwise failure.
|
||||
*/
|
||||
|
||||
@@ -254,6 +254,48 @@ int test_wc_CamelliaCbcEncryptDecrypt(void)
|
||||
} /* END test_wc_CamelliaCbcEncryptDecrypt */
|
||||
|
||||
|
||||
/*
|
||||
* Cipher operations must fail safely when no key has been configured.
|
||||
*/
|
||||
int test_wc_Camellia_MissingKey(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#ifdef HAVE_CAMELLIA
|
||||
wc_Camellia camellia;
|
||||
static const byte plainT[] = {
|
||||
0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
|
||||
0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A
|
||||
};
|
||||
byte out[WC_CAMELLIA_BLOCK_SIZE];
|
||||
|
||||
XMEMSET(out, 0, sizeof(out));
|
||||
|
||||
/* Zeroed context, never keyed: every op must reject with MISSING_KEY
|
||||
* rather than silently emitting unencrypted output. */
|
||||
XMEMSET(&camellia, 0, sizeof(camellia));
|
||||
|
||||
ExpectIntEQ(wc_CamelliaEncryptDirect(&camellia, out, plainT),
|
||||
WC_NO_ERR_TRACE(MISSING_KEY));
|
||||
ExpectIntEQ(wc_CamelliaDecryptDirect(&camellia, out, plainT),
|
||||
WC_NO_ERR_TRACE(MISSING_KEY));
|
||||
ExpectIntEQ(wc_CamelliaCbcEncrypt(&camellia, out, plainT,
|
||||
WC_CAMELLIA_BLOCK_SIZE), WC_NO_ERR_TRACE(MISSING_KEY));
|
||||
ExpectIntEQ(wc_CamelliaCbcDecrypt(&camellia, out, plainT,
|
||||
WC_CAMELLIA_BLOCK_SIZE), WC_NO_ERR_TRACE(MISSING_KEY));
|
||||
|
||||
/* Garbage key size that is not 128/192/256 must also be rejected. */
|
||||
XMEMSET(&camellia, 0, sizeof(camellia));
|
||||
camellia.keySz = 64;
|
||||
|
||||
ExpectIntEQ(wc_CamelliaEncryptDirect(&camellia, out, plainT),
|
||||
WC_NO_ERR_TRACE(MISSING_KEY));
|
||||
ExpectIntEQ(wc_CamelliaCbcEncrypt(&camellia, out, plainT,
|
||||
WC_CAMELLIA_BLOCK_SIZE), WC_NO_ERR_TRACE(MISSING_KEY));
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
} /* END test_wc_Camellia_MissingKey */
|
||||
|
||||
|
||||
#include <wolfssl/wolfcrypt/random.h>
|
||||
|
||||
#define MC_CIPHER_TEST_COUNT 100
|
||||
|
||||
@@ -29,6 +29,7 @@ int test_wc_CamelliaSetIV(void);
|
||||
int test_wc_CamelliaFree(void);
|
||||
int test_wc_CamelliaEncryptDecryptDirect(void);
|
||||
int test_wc_CamelliaCbcEncryptDecrypt(void);
|
||||
int test_wc_Camellia_MissingKey(void);
|
||||
int test_wc_CamelliaCbc_MonteCarlo(void);
|
||||
|
||||
#define TEST_CAMELLIA_DECLS \
|
||||
@@ -37,6 +38,7 @@ int test_wc_CamelliaCbc_MonteCarlo(void);
|
||||
TEST_DECL_GROUP("camellia", test_wc_CamelliaFree), \
|
||||
TEST_DECL_GROUP("camellia", test_wc_CamelliaEncryptDecryptDirect), \
|
||||
TEST_DECL_GROUP("camellia", test_wc_CamelliaCbcEncryptDecrypt), \
|
||||
TEST_DECL_GROUP("camellia", test_wc_Camellia_MissingKey), \
|
||||
TEST_DECL_GROUP("camellia", test_wc_CamelliaCbc_MonteCarlo)
|
||||
|
||||
#endif /* WOLFCRYPT_TEST_CAMELLIA_H */
|
||||
|
||||
@@ -203,6 +203,25 @@ int test_wolfSSL_EVP_EncodeUpdate(void)
|
||||
sizeof(encBlock0)-1);
|
||||
ExpectStrEQ(encOutBuff, encBlock0);
|
||||
|
||||
/* oversized length must be rejected, not read past the input buffer */
|
||||
XMEMSET( encOutBuff,0, sizeof(encOutBuff));
|
||||
ExpectIntEQ(EVP_EncodeBlock(encOutBuff, plain0, 0x7FFFFFFF), -1);
|
||||
|
||||
/* oversized length must be rejected by EVP_EncodeUpdate as well, rather
|
||||
* than reading far past the caller's input buffer */
|
||||
EVP_EncodeInit(ctx);
|
||||
outl = 1;
|
||||
XMEMSET( encOutBuff,0, sizeof(encOutBuff));
|
||||
ExpectIntEQ(
|
||||
EVP_EncodeUpdate(
|
||||
ctx,
|
||||
encOutBuff,
|
||||
&outl,
|
||||
plain0,
|
||||
0x7FFFFFFF),
|
||||
0);
|
||||
ExpectIntEQ(outl, 0);
|
||||
|
||||
/* pass small size( < 48bytes ) input, then make sure they are not
|
||||
* encoded and just stored in ctx
|
||||
*/
|
||||
|
||||
@@ -916,6 +916,8 @@ int test_wolfSSL_ASN1_get_object(void)
|
||||
const unsigned char objDerBadLen[] = { 0x30, 0x04 };
|
||||
const unsigned char objDerNotObj[] = { 0x02, 0x01, 0x00 };
|
||||
const unsigned char objDerNoData[] = { 0x06, 0x00 };
|
||||
/* OBJECT_ID header claims 126 content bytes but only one is present. */
|
||||
const unsigned char objDerOobLen[] = { 0x06, 0x7e, 0x2a };
|
||||
const unsigned char* p;
|
||||
unsigned char objDer[10];
|
||||
unsigned char* der;
|
||||
@@ -1018,6 +1020,10 @@ int test_wolfSSL_ASN1_get_object(void)
|
||||
ExpectNull(d2i_ASN1_OBJECT(&a, &p, sizeof(objDerNotObj)));
|
||||
p = objDerNoData;
|
||||
ExpectNull(d2i_ASN1_OBJECT(&a, &p, sizeof(objDerNoData)));
|
||||
/* Oversized length must not let the header's claimed content length drive
|
||||
* a read past the end of the actual buffer. */
|
||||
p = objDerOobLen;
|
||||
ExpectNull(d2i_ASN1_OBJECT(&a, &p, INT_MAX));
|
||||
|
||||
/* Create an ASN OBJECT from content */
|
||||
p = derBuf + 2;
|
||||
@@ -1188,6 +1194,22 @@ int test_wolfSSL_ASN1_STRING(void)
|
||||
ExpectIntEQ(ASN1_STRING_length(NULL), 0);
|
||||
ExpectIntGT(ASN1_STRING_length(str), 0);
|
||||
|
||||
/* Setting from the object's own buffer must not read freed/cleared data.
|
||||
* Fixed-buffer case: data is held in the small array. */
|
||||
ExpectIntEQ(ASN1_STRING_set(str, (const void*)data, (int)XSTRLEN(data)), 1);
|
||||
ExpectIntEQ(ASN1_STRING_set(str, ASN1_STRING_get0_data(str),
|
||||
ASN1_STRING_length(str)), 1);
|
||||
ExpectIntEQ(ASN1_STRING_length(str), (int)XSTRLEN(data));
|
||||
ExpectIntEQ(XMEMCMP(ASN1_STRING_get0_data(str), data, XSTRLEN(data)), 0);
|
||||
/* Dynamic-buffer case: data is held in a heap allocation. */
|
||||
ExpectIntEQ(ASN1_STRING_set(str, (const void*)longData,
|
||||
(int)XSTRLEN(longData)), 1);
|
||||
ExpectIntEQ(ASN1_STRING_set(str, ASN1_STRING_get0_data(str),
|
||||
ASN1_STRING_length(str)), 1);
|
||||
ExpectIntEQ(ASN1_STRING_length(str), (int)XSTRLEN(longData));
|
||||
ExpectIntEQ(XMEMCMP(ASN1_STRING_get0_data(str), longData,
|
||||
XSTRLEN(longData)), 0);
|
||||
|
||||
ASN1_STRING_free(c);
|
||||
ASN1_STRING_free(str);
|
||||
ASN1_STRING_free(NULL);
|
||||
|
||||
@@ -1019,6 +1019,39 @@ int test_wolfSSL_BIO_read_negative_len(void)
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
/* A length larger than the source buffer must never reach XMEMCPY in the
|
||||
* memory-BIO write path. A huge positive length on a fresh buffer would
|
||||
* otherwise overflow the buffer growth calculation, allocate a short
|
||||
* destination, and copy far past the small source. Verify such a length is
|
||||
* rejected with an error, nothing is buffered, and normal writes still work. */
|
||||
int test_wolfSSL_BIO_write_large_len(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(OPENSSL_EXTRA)
|
||||
BIO* bio = NULL;
|
||||
char msg[] = "large length test";
|
||||
int msgLen = (int)XSTRLEN(msg);
|
||||
char out[64];
|
||||
|
||||
ExpectNotNull(bio = BIO_new(BIO_s_mem()));
|
||||
|
||||
/* Oversized length on a fresh buffer: must be rejected with an error, not
|
||||
* a wild copy from the small source buffer. */
|
||||
ExpectIntLT(BIO_write(bio, msg, (int)0x7FFFFFFF), 0);
|
||||
/* Nothing should have been buffered. */
|
||||
ExpectIntEQ(BIO_pending(bio), 0);
|
||||
|
||||
/* A normal write then read still returns the intact message. */
|
||||
ExpectIntEQ(BIO_write(bio, msg, msgLen), msgLen);
|
||||
XMEMSET(out, 0, sizeof(out));
|
||||
ExpectIntEQ(BIO_read(bio, out, (int)sizeof(out)), msgLen);
|
||||
ExpectIntEQ(XMEMCMP(out, msg, msgLen), 0);
|
||||
|
||||
BIO_free(bio);
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
|
||||
int test_wolfSSL_BIO_printf(void)
|
||||
{
|
||||
|
||||
@@ -36,6 +36,7 @@ int test_wolfSSL_BIO_s_null(void);
|
||||
int test_wolfSSL_BIO_accept(void);
|
||||
int test_wolfSSL_BIO_write(void);
|
||||
int test_wolfSSL_BIO_read_negative_len(void);
|
||||
int test_wolfSSL_BIO_write_large_len(void);
|
||||
int test_wolfSSL_BIO_printf(void);
|
||||
int test_wolfSSL_BIO_f_md(void);
|
||||
int test_wolfSSL_BIO_up_ref(void);
|
||||
@@ -57,6 +58,7 @@ int test_wolfSSL_BIO_get_init(void);
|
||||
TEST_DECL_GROUP("ossl_bio", test_wolfSSL_BIO_s_null), \
|
||||
TEST_DECL_GROUP("ossl_bio", test_wolfSSL_BIO_write), \
|
||||
TEST_DECL_GROUP("ossl_bio", test_wolfSSL_BIO_read_negative_len), \
|
||||
TEST_DECL_GROUP("ossl_bio", test_wolfSSL_BIO_write_large_len), \
|
||||
TEST_DECL_GROUP("ossl_bio", test_wolfSSL_BIO_printf), \
|
||||
TEST_DECL_GROUP("ossl_bio", test_wolfSSL_BIO_f_md), \
|
||||
TEST_DECL_GROUP("ossl_bio", test_wolfSSL_BIO_up_ref), \
|
||||
|
||||
@@ -228,6 +228,37 @@ int test_wc_Rc2CbcEncryptDecrypt(void)
|
||||
} /* END test_wc_Rc2CbcEncryptDecrypt */
|
||||
|
||||
|
||||
/*
|
||||
* Cipher operations must fail safely when no key has been configured.
|
||||
*/
|
||||
int test_wc_Rc2_MissingKey(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#ifdef WC_RC2
|
||||
Rc2 rc2;
|
||||
byte out[RC2_BLOCK_SIZE];
|
||||
byte in[RC2_BLOCK_SIZE];
|
||||
|
||||
XMEMSET(out, 0, sizeof(out));
|
||||
XMEMSET(in, 0, sizeof(in));
|
||||
|
||||
/* Zeroed context, never keyed: every op must reject with MISSING_KEY
|
||||
* rather than ciphering under an all-zero key schedule. */
|
||||
XMEMSET(&rc2, 0, sizeof(rc2));
|
||||
|
||||
ExpectIntEQ(wc_Rc2EcbEncrypt(&rc2, out, in, RC2_BLOCK_SIZE),
|
||||
WC_NO_ERR_TRACE(MISSING_KEY));
|
||||
ExpectIntEQ(wc_Rc2EcbDecrypt(&rc2, out, in, RC2_BLOCK_SIZE),
|
||||
WC_NO_ERR_TRACE(MISSING_KEY));
|
||||
ExpectIntEQ(wc_Rc2CbcEncrypt(&rc2, out, in, RC2_BLOCK_SIZE),
|
||||
WC_NO_ERR_TRACE(MISSING_KEY));
|
||||
ExpectIntEQ(wc_Rc2CbcDecrypt(&rc2, out, in, RC2_BLOCK_SIZE),
|
||||
WC_NO_ERR_TRACE(MISSING_KEY));
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
} /* END test_wc_Rc2_MissingKey */
|
||||
|
||||
|
||||
#define MC_CIPHER_TEST_COUNT 100
|
||||
#define MC_RC2_MAX_DATA_SZ 1024
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ int test_wc_Rc2SetKey(void);
|
||||
int test_wc_Rc2SetIV(void);
|
||||
int test_wc_Rc2EcbEncryptDecrypt(void);
|
||||
int test_wc_Rc2CbcEncryptDecrypt(void);
|
||||
int test_wc_Rc2_MissingKey(void);
|
||||
int test_wc_Rc2Cbc_MonteCarlo(void);
|
||||
int test_wc_Rc2Free(void);
|
||||
|
||||
@@ -36,6 +37,7 @@ int test_wc_Rc2Free(void);
|
||||
TEST_DECL_GROUP("rc2", test_wc_Rc2SetIV), \
|
||||
TEST_DECL_GROUP("rc2", test_wc_Rc2EcbEncryptDecrypt), \
|
||||
TEST_DECL_GROUP("rc2", test_wc_Rc2CbcEncryptDecrypt), \
|
||||
TEST_DECL_GROUP("rc2", test_wc_Rc2_MissingKey), \
|
||||
TEST_DECL_GROUP("rc2", test_wc_Rc2Cbc_MonteCarlo), \
|
||||
TEST_DECL_GROUP("rc2", test_wc_Rc2Free)
|
||||
|
||||
|
||||
@@ -1470,6 +1470,56 @@ static int test_quic_server_hello_fail(int verbose) {
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
static int test_quic_key_update_rejected(int verbose) {
|
||||
EXPECT_DECLS;
|
||||
WOLFSSL_CTX * ctx_c = NULL;
|
||||
WOLFSSL_CTX * ctx_s = NULL;
|
||||
QuicTestContext tclient, tserver;
|
||||
QuicConversation conv;
|
||||
uint8_t lbuffer[16];
|
||||
size_t len;
|
||||
int ret;
|
||||
|
||||
ExpectNotNull(ctx_c = wolfSSL_CTX_new(wolfTLSv1_3_client_method()));
|
||||
ExpectNotNull(ctx_s = wolfSSL_CTX_new(wolfTLSv1_3_server_method()));
|
||||
ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx_s, svrCertFile,
|
||||
WOLFSSL_FILETYPE_PEM));
|
||||
ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx_s, svrKeyFile,
|
||||
WOLFSSL_FILETYPE_PEM));
|
||||
|
||||
/* complete a normal QUIC handshake */
|
||||
QuicTestContext_init(&tclient, ctx_c, "client", verbose);
|
||||
QuicTestContext_init(&tserver, ctx_s, "server", verbose);
|
||||
QuicConversation_init(&conv, &tclient, &tserver);
|
||||
QuicConversation_do(&conv);
|
||||
|
||||
/* RFC 9001 section 6: a QUIC connection must not send a TLS KeyUpdate;
|
||||
* key updates are handled at the QUIC packet-protection layer. The
|
||||
* public wolfSSL_update_keys() must refuse on a QUIC connection. */
|
||||
ExpectIntEQ(wolfSSL_update_keys(tserver.ssl),
|
||||
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
||||
|
||||
/* RFC 9001 section 6: a TLS KeyUpdate handshake message must be rejected
|
||||
* as a fatal unexpected_message connection error when running over QUIC.
|
||||
* Feed a key_update (update_not_requested) as post-handshake CRYPTO data
|
||||
* and confirm the server refuses to process it. */
|
||||
len = fake_record(key_update, OPAQUE8_LEN, lbuffer);
|
||||
lbuffer[HANDSHAKE_HEADER_SZ] = update_not_requested;
|
||||
ExpectIntEQ(wolfSSL_provide_quic_data(tserver.ssl,
|
||||
wolfssl_encryption_application, lbuffer, len), WOLFSSL_SUCCESS);
|
||||
ret = wolfSSL_process_quic_post_handshake(tserver.ssl);
|
||||
ExpectIntEQ(ret, WC_NO_ERR_TRACE(SANITY_MSG_E));
|
||||
|
||||
QuicTestContext_free(&tclient);
|
||||
QuicTestContext_free(&tserver);
|
||||
|
||||
wolfSSL_CTX_free(ctx_c);
|
||||
wolfSSL_CTX_free(ctx_s);
|
||||
printf(" test_quic_key_update_rejected: %s\n",
|
||||
EXPECT_RESULT() ? pass : fail);
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
/* This has gotten a bit out of hand. */
|
||||
#if (defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && \
|
||||
(defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
|
||||
@@ -2005,6 +2055,7 @@ int QuicTest(void)
|
||||
#if !defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER)
|
||||
if ((ret = test_quic_server_hello(verbose)) != TEST_SUCCESS) goto leave;
|
||||
if ((ret = test_quic_server_hello_fail(verbose)) != TEST_SUCCESS) goto leave;
|
||||
if ((ret = test_quic_key_update_rejected(verbose)) != TEST_SUCCESS) goto leave;
|
||||
#ifdef REALLY_HAVE_ALPN_AND_SNI
|
||||
if ((ret = test_quic_alpn(verbose)) != TEST_SUCCESS) goto leave;
|
||||
#endif /* REALLY_HAVE_ALPN_AND_SNI */
|
||||
|
||||
@@ -1562,11 +1562,21 @@ int wc_CamelliaSetIV(wc_Camellia* cam, const byte* iv)
|
||||
}
|
||||
|
||||
|
||||
/* Returns 1 when a valid key has been configured, 0 otherwise. */
|
||||
static int CamelliaKeyIsSet(const wc_Camellia* cam)
|
||||
{
|
||||
return (cam->keySz == 128 || cam->keySz == 192 || cam->keySz == 256);
|
||||
}
|
||||
|
||||
|
||||
int wc_CamelliaEncryptDirect(wc_Camellia* cam, byte* out, const byte* in)
|
||||
{
|
||||
if (cam == NULL || out == NULL || in == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
if (!CamelliaKeyIsSet(cam)) {
|
||||
return MISSING_KEY;
|
||||
}
|
||||
Camellia_EncryptBlock(cam->keySz, in, cam->key, out);
|
||||
|
||||
return 0;
|
||||
@@ -1578,6 +1588,9 @@ int wc_CamelliaDecryptDirect(wc_Camellia* cam, byte* out, const byte* in)
|
||||
if (cam == NULL || out == NULL || in == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
if (!CamelliaKeyIsSet(cam)) {
|
||||
return MISSING_KEY;
|
||||
}
|
||||
Camellia_DecryptBlock(cam->keySz, in, cam->key, out);
|
||||
|
||||
return 0;
|
||||
@@ -1593,6 +1606,9 @@ int wc_CamelliaCbcEncrypt(wc_Camellia* cam, byte* out, const byte* in, word32 sz
|
||||
if (sz % WC_CAMELLIA_BLOCK_SIZE != 0) {
|
||||
return BAD_LENGTH_E;
|
||||
}
|
||||
if (!CamelliaKeyIsSet(cam)) {
|
||||
return MISSING_KEY;
|
||||
}
|
||||
blocks = sz / WC_CAMELLIA_BLOCK_SIZE;
|
||||
|
||||
while (blocks--) {
|
||||
@@ -1618,6 +1634,9 @@ int wc_CamelliaCbcDecrypt(wc_Camellia* cam, byte* out, const byte* in, word32 sz
|
||||
if (sz % WC_CAMELLIA_BLOCK_SIZE != 0) {
|
||||
return BAD_LENGTH_E;
|
||||
}
|
||||
if (!CamelliaKeyIsSet(cam)) {
|
||||
return MISSING_KEY;
|
||||
}
|
||||
blocks = sz / WC_CAMELLIA_BLOCK_SIZE;
|
||||
|
||||
while (blocks--) {
|
||||
|
||||
@@ -13266,6 +13266,11 @@ int wolfSSL_EVP_EncodeBlock(unsigned char *out, const unsigned char *in,
|
||||
if (inLen < 0)
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
|
||||
/* Reject lengths whose base64 output would overflow a positive int. This
|
||||
* also guards against reads far past the caller's input allocation. */
|
||||
if (inLen > (INT_MAX / 4) * 3)
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
|
||||
if (Base64_Encode_NoNl(in, (word32)inLen, out, &ret) == 0)
|
||||
return (int)ret;
|
||||
else
|
||||
@@ -13324,6 +13329,15 @@ int wolfSSL_EVP_EncodeUpdate(WOLFSSL_EVP_ENCODE_CTX* ctx,
|
||||
|
||||
*outl = 0;
|
||||
|
||||
if (inl < 0)
|
||||
return 0;
|
||||
|
||||
/* Reject lengths whose base64 output would overflow a positive int. This
|
||||
* also guards against reads far past the caller's input allocation. */
|
||||
if (inl > (INT_MAX / (BASE64_ENCODE_RESULT_BLOCK_SIZE + 1)) *
|
||||
BASE64_ENCODE_BLOCK_SIZE)
|
||||
return 0;
|
||||
|
||||
/* if the remaining data exists in the ctx, add input data to them
|
||||
* to create a block(48bytes) for encoding
|
||||
*/
|
||||
|
||||
+16
-8
@@ -171,6 +171,10 @@ int wc_Rc2EcbEncrypt(Rc2* rc2, byte* out, const byte* in, word32 sz)
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
if (rc2->keylen == 0) {
|
||||
return MISSING_KEY;
|
||||
}
|
||||
|
||||
r10 = (word16)((word16)in[1] << 8) | in[0]; /* R[0] */
|
||||
r32 = (word16)((word16)in[3] << 8) | in[2]; /* R[1] */
|
||||
r54 = (word16)((word16)in[5] << 8) | in[4]; /* R[2] */
|
||||
@@ -236,6 +240,10 @@ int wc_Rc2EcbDecrypt(Rc2* rc2, byte* out, const byte* in, word32 sz)
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
if (rc2->keylen == 0) {
|
||||
return MISSING_KEY;
|
||||
}
|
||||
|
||||
r0 = (word16)((word16)in[1] << 8) | in[0];
|
||||
r1 = (word16)((word16)in[3] << 8) | in[2];
|
||||
r2 = (word16)((word16)in[5] << 8) | in[4];
|
||||
@@ -285,14 +293,14 @@ int wc_Rc2CbcEncrypt(Rc2* rc2, byte* out, const byte* in, word32 sz)
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (sz == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sz % RC2_BLOCK_SIZE != 0) {
|
||||
return BAD_LENGTH_E;
|
||||
}
|
||||
|
||||
if (rc2->keylen == 0) {
|
||||
return MISSING_KEY;
|
||||
}
|
||||
|
||||
blocks = sz / RC2_BLOCK_SIZE;
|
||||
|
||||
while (blocks--) {
|
||||
@@ -320,14 +328,14 @@ int wc_Rc2CbcDecrypt(Rc2* rc2, byte* out, const byte* in, word32 sz)
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (sz == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sz % RC2_BLOCK_SIZE != 0) {
|
||||
return BAD_LENGTH_E;
|
||||
}
|
||||
|
||||
if (rc2->keylen == 0) {
|
||||
return MISSING_KEY;
|
||||
}
|
||||
|
||||
blocks = sz / RC2_BLOCK_SIZE;
|
||||
|
||||
while (blocks--) {
|
||||
|
||||
Reference in New Issue
Block a user