Merge pull request #7995 from julek-wolfssl/dtls12-cid

Implement DTLS 1.2 Connection ID (CID)
This commit is contained in:
Sean Parkinson 2024-10-02 09:00:59 +10:00 committed by GitHub
commit ac788ec40d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 1116 additions and 703 deletions

View File

@ -38,6 +38,8 @@ jobs:
'--enable-all --enable-dtls13 --enable-dtls-frag-ch',
'--enable-dtls --enable-dtls13 --enable-dtls-frag-ch
--enable-dtls-mtu',
'--enable-dtls --enable-dtlscid --enable-dtls13 --enable-secure-renegotiation
--enable-psk --enable-aesccm --enable-nullcipher CPPFLAGS=-DWOLFSSL_STATIC_RSA',
]
name: make check
if: github.repository_owner == 'wolfssl'

View File

@ -4184,10 +4184,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
printf("CID extension was negotiated\n");
ret = wolfSSL_dtls_cid_get_tx_size(ssl, &receivedCIDSz);
if (ret != WOLFSSL_SUCCESS)
err_sys("Can't get negotiated DTLS CID size\n");
if (receivedCIDSz > 0) {
if (ret == WOLFSSL_SUCCESS && receivedCIDSz > 0) {
ret = wolfSSL_dtls_cid_get_tx(ssl, receivedCID,
DTLS_CID_BUFFER_SIZE - 1);
if (ret != WOLFSSL_SUCCESS)

View File

@ -3595,10 +3595,7 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
unsigned int receivedCIDSz;
printf("CID extension was negotiated\n");
ret = wolfSSL_dtls_cid_get_tx_size(ssl, &receivedCIDSz);
if (ret != WOLFSSL_SUCCESS)
err_sys("Can't get negotiated DTLS CID size\n");
if (receivedCIDSz > 0) {
if (ret == WOLFSSL_SUCCESS && receivedCIDSz > 0) {
ret = wolfSSL_dtls_cid_get_tx(ssl, receivedCID,
DTLS_CID_BUFFER_SIZE - 1);
if (ret != WOLFSSL_SUCCESS)

View File

@ -1038,22 +1038,6 @@ int DoClientHelloStateless(WOLFSSL* ssl, const byte* input, word32 helloSz,
#if defined(WOLFSSL_DTLS_CID)
typedef struct ConnectionID {
byte length;
/* Ignore "nonstandard extension used : zero-sized array in struct/union"
* MSVC warning */
#ifdef _MSC_VER
#pragma warning(disable: 4200)
#endif
byte id[];
} ConnectionID;
typedef struct CIDInfo {
ConnectionID* tx;
ConnectionID* rx;
byte negotiated : 1;
} CIDInfo;
static ConnectionID* DtlsCidNew(const byte* cid, byte size, void* heap)
{
ConnectionID* ret;
@ -1231,9 +1215,8 @@ int TLSX_ConnectionID_Use(WOLFSSL* ssl)
int TLSX_ConnectionID_Parse(WOLFSSL* ssl, const byte* input, word16 length,
byte isRequest)
{
ConnectionID* id;
CIDInfo* info;
byte cidSize;
byte cidSz;
TLSX* ext;
ext = TLSX_Find(ssl->extensions, TLSX_CONNECTION_ID);
@ -1249,35 +1232,41 @@ int TLSX_ConnectionID_Parse(WOLFSSL* ssl, const byte* input, word16 length,
}
}
if (length < OPAQUE8_LEN)
return BUFFER_ERROR;
cidSz = *input;
if (cidSz + OPAQUE8_LEN > length)
return BUFFER_ERROR;
info = DtlsCidGetInfo(ssl);
if (info == NULL)
return BAD_STATE_E;
/* it may happen if we process two ClientHello because the server sent an
* HRR request */
if (info->tx != NULL) {
* HRR/HVR request */
if (info->tx != NULL || info->negotiated) {
if (ssl->options.side != WOLFSSL_SERVER_END &&
ssl->options.serverState != SERVER_HELLO_RETRY_REQUEST_COMPLETE)
ssl->options.serverState != SERVER_HELLO_RETRY_REQUEST_COMPLETE &&
!IsSCR(ssl))
return BAD_STATE_E;
XFREE(info->tx, ssl->heap, DYNAMIC_TYPE_TLSX);
info->tx = NULL;
/* Should not be null if negotiated */
if (info->tx == NULL)
return BAD_STATE_E;
/* For now we don't support changing the CID on a rehandshake */
if (cidSz != info->tx->length ||
XMEMCMP(info->tx->id, input + OPAQUE8_LEN, cidSz) != 0)
return DTLS_CID_ERROR;
}
if (length < OPAQUE8_LEN)
return BUFFER_ERROR;
cidSize = *input;
if (cidSize + OPAQUE8_LEN > length)
return BUFFER_ERROR;
if (cidSize > 0) {
id = (ConnectionID*)XMALLOC(sizeof(*id) + cidSize, ssl->heap,
DYNAMIC_TYPE_TLSX);
else if (cidSz > 0) {
ConnectionID* id = (ConnectionID*)XMALLOC(sizeof(*id) + cidSz,
ssl->heap, DYNAMIC_TYPE_TLSX);
if (id == NULL)
return MEMORY_ERROR;
XMEMCPY(id->id, input + OPAQUE8_LEN, cidSize);
id->length = cidSize;
XMEMCPY(id->id, input + OPAQUE8_LEN, cidSz);
id->length = cidSz;
info->tx = id;
}
@ -1317,10 +1306,6 @@ int wolfSSL_dtls_cid_use(WOLFSSL* ssl)
{
int ret;
/* CID is supported on DTLSv1.3 only */
if (!IsAtLeastTLSv1_3(ssl->version))
return WOLFSSL_FAILURE;
ssl->options.useDtlsCID = 1;
ret = TLSX_ConnectionID_Use(ssl);
if (ret != 0)
@ -1345,8 +1330,11 @@ int wolfSSL_dtls_cid_set(WOLFSSL* ssl, unsigned char* cid, unsigned int size)
if (cidInfo == NULL)
return WOLFSSL_FAILURE;
XFREE(cidInfo->rx, ssl->heap, DYNAMIC_TYPE_TLSX);
cidInfo->rx = NULL;
if (cidInfo->rx != NULL) {
WOLFSSL_MSG("wolfSSL doesn't support changing the CID during a "
"connection");
return WOLFSSL_FAILURE;
}
/* empty CID */
if (size == 0)
@ -1384,7 +1372,42 @@ int wolfSSL_dtls_cid_get_tx(WOLFSSL* ssl, unsigned char* buf,
return DtlsCidGet(ssl, buf, bufferSz, 0);
}
int wolfSSL_dtls_cid_max_size(void)
{
return DTLS_CID_MAX_SIZE;
}
#endif /* WOLFSSL_DTLS_CID */
byte DtlsGetCidTxSize(WOLFSSL* ssl)
{
#ifdef WOLFSSL_DTLS_CID
unsigned int cidSz;
int ret;
ret = wolfSSL_dtls_cid_get_tx_size(ssl, &cidSz);
if (ret != WOLFSSL_SUCCESS)
return 0;
return (byte)cidSz;
#else
(void)ssl;
return 0;
#endif
}
byte DtlsGetCidRxSize(WOLFSSL* ssl)
{
#ifdef WOLFSSL_DTLS_CID
unsigned int cidSz;
int ret;
ret = wolfSSL_dtls_cid_get_rx_size(ssl, &cidSz);
if (ret != WOLFSSL_SUCCESS)
return 0;
return (byte)cidSz;
#else
(void)ssl;
return 0;
#endif
}
#endif /* WOLFSSL_DTLS */
#endif /* WOLFCRYPT_ONLY */

View File

@ -1054,45 +1054,26 @@ static WC_INLINE word8 Dtls13GetEpochBits(w64wrapper epoch)
}
#ifdef WOLFSSL_DTLS_CID
static byte Dtls13GetCidTxSize(WOLFSSL* ssl)
{
unsigned int cidSz;
int ret;
ret = wolfSSL_dtls_cid_get_tx_size(ssl, &cidSz);
if (ret != WOLFSSL_SUCCESS)
return 0;
return (byte)cidSz;
}
static byte Dtls13GetCidRxSize(WOLFSSL* ssl)
{
unsigned int cidSz;
int ret;
ret = wolfSSL_dtls_cid_get_rx_size(ssl, &cidSz);
if (ret != WOLFSSL_SUCCESS)
return 0;
return (byte)cidSz;
}
static int Dtls13AddCID(WOLFSSL* ssl, byte* flags, byte* out, word16* idx)
{
byte cidSize;
byte cidSz;
int ret;
if (!wolfSSL_dtls_cid_is_enabled(ssl))
return 0;
cidSize = Dtls13GetCidTxSize(ssl);
cidSz = DtlsGetCidTxSize(ssl);
/* no cid */
if (cidSize == 0)
if (cidSz == 0)
return 0;
*flags |= DTLS13_CID_BIT;
/* we know that we have at least cidSize of space */
ret = wolfSSL_dtls_cid_get_tx(ssl, out + *idx, cidSize);
/* we know that we have at least cidSz of space */
ret = wolfSSL_dtls_cid_get_tx(ssl, out + *idx, cidSz);
if (ret != WOLFSSL_SUCCESS)
return ret;
*idx += cidSize;
*idx += cidSz;
return 0;
}
@ -1138,8 +1119,6 @@ static int Dtls13UnifiedHeaderParseCID(WOLFSSL* ssl, byte flags,
#else
#define Dtls13AddCID(a, b, c, d) 0
#define Dtls13GetCidRxSize(a) 0
#define Dtls13GetCidTxSize(a) 0
#define Dtls13UnifiedHeaderParseCID(a, b, c, d, e) 0
#endif /* WOLFSSL_DTLS_CID */
@ -1245,7 +1224,7 @@ int Dtls13EncryptRecordNumber(WOLFSSL* ssl, byte* hdr, word16 recordLength)
seqLength = (*hdr & DTLS13_LEN_BIT) ? DTLS13_SEQ_16_LEN : DTLS13_SEQ_8_LEN;
cidSz = Dtls13GetCidTxSize(ssl);
cidSz = DtlsGetCidTxSize(ssl);
/* header flags + seq number + CID size*/
hdrLength = OPAQUE8_LEN + seqLength + cidSz;
@ -1276,7 +1255,7 @@ word16 Dtls13GetRlHeaderLength(WOLFSSL* ssl, byte isEncrypted)
if (!isEncrypted)
return DTLS_RECORD_HEADER_SZ;
return DTLS13_UNIFIED_HEADER_SIZE + Dtls13GetCidTxSize(ssl);
return DTLS13_UNIFIED_HEADER_SIZE + DtlsGetCidTxSize(ssl);
}
/**
@ -1403,7 +1382,7 @@ int Dtls13GetUnifiedHeaderSize(WOLFSSL* ssl, const byte input, word16* size)
return BAD_FUNC_ARG;
/* flags (1) + CID + seq 8bit (1) */
*size = OPAQUE8_LEN + Dtls13GetCidRxSize(ssl) + OPAQUE8_LEN;
*size = OPAQUE8_LEN + DtlsGetCidRxSize(ssl) + OPAQUE8_LEN;
if (input & DTLS13_SEQ_LEN_BIT)
*size += OPAQUE8_LEN;
if (input & DTLS13_LEN_BIT)

File diff suppressed because it is too large Load Diff

View File

@ -6495,6 +6495,7 @@ doPart:
case ack:
/* TODO */
#endif /* WOLFSSL_DTLS13 */
case dtls12_cid:
case no_type:
default:
SetError(GOT_UNKNOWN_RECORD_STR, error, session, FATAL_ERROR_STATE);

View File

@ -4866,6 +4866,20 @@ int wolfSSL_GetVersion(const WOLFSSL* ssl)
break;
}
}
#ifdef WOLFSSL_DTLS
if (ssl->version.major == DTLS_MAJOR) {
switch (ssl->version.minor) {
case DTLS_MINOR :
return WOLFSSL_DTLSV1;
case DTLSv1_2_MINOR :
return WOLFSSL_DTLSV1_2;
case DTLSv1_3_MINOR :
return WOLFSSL_DTLSV1_3;
default:
break;
}
}
#endif /* WOLFSSL_DTLS */
return VERSION_ERROR;
}
@ -8983,11 +8997,11 @@ int wolfSSL_dtls_got_timeout(WOLFSSL* ssl)
int result = WOLFSSL_SUCCESS;
WOLFSSL_ENTER("wolfSSL_dtls_got_timeout");
if (ssl == NULL)
if (ssl == NULL || !ssl->options.dtls)
return WOLFSSL_FATAL_ERROR;
#ifdef WOLFSSL_DTLS13
if (ssl->options.dtls && IsAtLeastTLSv1_3(ssl->version)) {
if (IsAtLeastTLSv1_3(ssl->version)) {
result = Dtls13RtxTimeout(ssl);
if (result < 0) {
if (result == WC_NO_ERR_TRACE(WANT_WRITE))
@ -9001,7 +9015,8 @@ int wolfSSL_dtls_got_timeout(WOLFSSL* ssl)
}
#endif /* WOLFSSL_DTLS13 */
if ((IsSCR(ssl) || !ssl->options.handShakeDone)) {
/* Do we have any 1.2 messages stored? */
if (ssl->dtls_tx_msg_list != NULL || ssl->dtls_tx_msg != NULL) {
if (DtlsMsgPoolTimeout(ssl) < 0){
ssl->error = SOCKET_ERROR_E;
WOLFSSL_ERROR(ssl->error);
@ -13177,6 +13192,10 @@ size_t wolfSSL_get_client_random(const WOLFSSL* ssl, unsigned char* out,
ssl->keys.encryptionOn = 0;
XMEMSET(&ssl->msgsReceived, 0, sizeof(ssl->msgsReceived));
FreeCiphers(ssl);
InitCiphers(ssl);
InitCipherSpecs(&ssl->specs);
if (InitSSL_Suites(ssl) != WOLFSSL_SUCCESS)
return WOLFSSL_FAILURE;

240
src/tls.c
View File

@ -760,6 +760,15 @@ int wolfSSL_SetTlsHmacInner(WOLFSSL* ssl, byte* inner, word32 sz, int content,
if (ssl == NULL || inner == NULL)
return BAD_FUNC_ARG;
if (content == dtls12_cid
#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_DTLS_CID)
|| (ssl->options.dtls && DtlsGetCidTxSize(ssl) > 0)
#endif
) {
WOLFSSL_MSG("wolfSSL_SetTlsHmacInner doesn't support CID");
return BAD_FUNC_ARG;
}
XMEMSET(inner, 0, WOLFSSL_TLS_HMAC_INNER_SZ);
WriteSEQ(ssl, verify, inner);
@ -918,10 +927,11 @@ static int Hmac_OuterHash(Hmac* hmac, unsigned char* mac)
* in Message data.
* sz Size of the message data.
* header Constructed record header with length of handshake data.
* headerSz Length of header
* returns 0 on success, otherwise failure.
*/
static int Hmac_UpdateFinal_CT(Hmac* hmac, byte* digest, const byte* in,
word32 sz, int macLen, byte* header)
word32 sz, int macLen, byte* header, word32 headerSz)
{
byte lenBytes[8];
int i, j;
@ -982,7 +992,7 @@ static int Hmac_UpdateFinal_CT(Hmac* hmac, byte* digest, const byte* in,
blockMask = blockSz - 1;
/* Size of data to HMAC if padding length byte is zero. */
maxLen = WOLFSSL_TLS_HMAC_INNER_SZ + sz - 1 - macLen;
maxLen = headerSz + sz - 1 - macLen;
/* Complete data (including padding) has block for EOC and/or length. */
extraBlock = ctSetLTE((maxLen + padSz) & blockMask, padSz);
/* Total number of blocks for data including padding. */
@ -1016,11 +1026,10 @@ static int Hmac_UpdateFinal_CT(Hmac* hmac, byte* digest, const byte* in,
XMEMSET(hmac->innerHash, 0, macLen);
if (safeBlocks > 0) {
ret = Hmac_HashUpdate(hmac, header, WOLFSSL_TLS_HMAC_INNER_SZ);
ret = Hmac_HashUpdate(hmac, header, headerSz);
if (ret != 0)
return ret;
ret = Hmac_HashUpdate(hmac, in, safeBlocks * blockSz -
WOLFSSL_TLS_HMAC_INNER_SZ);
ret = Hmac_HashUpdate(hmac, in, safeBlocks * blockSz - headerSz);
if (ret != 0)
return ret;
}
@ -1039,10 +1048,10 @@ static int Hmac_UpdateFinal_CT(Hmac* hmac, byte* digest, const byte* in,
unsigned char pastEoc = ctMaskGT(j, eocIndex) & isEocBlock;
unsigned char b = 0;
if (k < WOLFSSL_TLS_HMAC_INNER_SZ)
if (k < headerSz)
b = header[k];
else if (k < maxLen)
b = in[k - WOLFSSL_TLS_HMAC_INNER_SZ];
b = in[k - headerSz];
k++;
b = ctMaskSel(atEoc, 0x80, b);
@ -1085,10 +1094,11 @@ static int Hmac_UpdateFinal_CT(Hmac* hmac, byte* digest, const byte* in,
* in Message data.
* sz Size of the message data.
* header Constructed record header with length of handshake data.
* headerSz Length of header
* returns 0 on success, otherwise failure.
*/
static int Hmac_UpdateFinal(Hmac* hmac, byte* digest, const byte* in,
word32 sz, byte* header)
word32 sz, byte* header, word32 headerSz)
{
byte dummy[WC_MAX_BLOCK_SIZE] = {0};
int ret = 0;
@ -1174,7 +1184,7 @@ static int Hmac_UpdateFinal(Hmac* hmac, byte* digest, const byte* in,
/* Calculate whole blocks. */
msgBlocks--;
ret = wc_HmacUpdate(hmac, header, WOLFSSL_TLS_HMAC_INNER_SZ);
ret = wc_HmacUpdate(hmac, header, headerSz);
if (ret == 0) {
/* Fill the rest of the block with any available data. */
word32 currSz = ctMaskLT((int)msgSz, blockSz) & msgSz;
@ -1210,11 +1220,66 @@ static int Hmac_UpdateFinal(Hmac* hmac, byte* digest, const byte* in,
#endif
#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_DTLS_CID)
#define TLS_HMAC_CID_SZ(s, v) \
((v) ? DtlsGetCidRxSize((s)) \
: DtlsGetCidTxSize((s)))
#define TLS_HMAC_CID(s, v, b, c) \
((v) ? wolfSSL_dtls_cid_get_rx((s), (b), (c)) \
: wolfSSL_dtls_cid_get_tx((s), (b), (c)))
#endif
static int TLS_hmac_SetInner(WOLFSSL* ssl, byte* inner, word32* innerSz,
word32 sz, int content, int verify, int epochOrder)
{
#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_DTLS_CID)
unsigned int cidSz = 0;
if (ssl->options.dtls && (cidSz = TLS_HMAC_CID_SZ(ssl, verify)) > 0) {
word32 idx = 0;
if (cidSz > DTLS_CID_MAX_SIZE) {
WOLFSSL_MSG("DTLS CID too large");
return DTLS_CID_ERROR;
}
XMEMSET(inner + idx, 0xFF, SEQ_SZ);
idx += SEQ_SZ;
inner[idx++] = dtls12_cid;
inner[idx++] = (byte)cidSz;
inner[idx++] = dtls12_cid;
inner[idx++] = ssl->version.major;
inner[idx++] = ssl->version.minor;
WriteSEQ(ssl, epochOrder, inner + idx);
idx += SEQ_SZ;
if (TLS_HMAC_CID(ssl, verify, inner + idx, cidSz) ==
WC_NO_ERR_TRACE(WOLFSSL_FAILURE)) {
WOLFSSL_MSG("DTLS CID write failed");
return DTLS_CID_ERROR;
}
idx += cidSz;
c16toa((word16)sz, inner + idx);
idx += LENGTH_SZ;
*innerSz = idx;
return 0;
}
#endif
*innerSz = WOLFSSL_TLS_HMAC_INNER_SZ;
return wolfSSL_SetTlsHmacInner(ssl, inner, sz, content,
!ssl->options.dtls ? verify : epochOrder);
}
#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_DTLS_CID)
#define TLS_HMAC_INNER_SZ WOLFSSL_TLS_HMAC_CID_INNER_SZ
#else
#define TLS_HMAC_INNER_SZ WOLFSSL_TLS_HMAC_INNER_SZ
#endif
int TLS_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz, int padSz,
int content, int verify, int epochOrder)
{
Hmac hmac;
byte myInner[WOLFSSL_TLS_HMAC_INNER_SZ];
byte myInner[TLS_HMAC_INNER_SZ];
word32 innerSz = TLS_HMAC_INNER_SZ;
int ret = 0;
const byte* macSecret = NULL;
word32 hashSz = 0;
@ -1242,10 +1307,10 @@ int TLS_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz, int padSz,
}
#endif
if (!ssl->options.dtls)
wolfSSL_SetTlsHmacInner(ssl, myInner, sz, content, verify);
else
wolfSSL_SetTlsHmacInner(ssl, myInner, sz, content, epochOrder);
ret = TLS_hmac_SetInner(ssl, myInner, &innerSz, sz, content, verify,
epochOrder);
if (ret != 0)
return ret;
ret = wc_HmacInit(&hmac, ssl->heap, ssl->devId);
if (ret != 0)
@ -1256,10 +1321,8 @@ int TLS_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz, int padSz,
if (ssl->options.dtls)
macSecret = wolfSSL_GetDtlsMacSecret(ssl, verify, epochOrder);
else
macSecret = wolfSSL_GetMacSecret(ssl, verify);
#else
macSecret = wolfSSL_GetMacSecret(ssl, verify);
#endif
macSecret = wolfSSL_GetMacSecret(ssl, verify);
ret = wc_HmacSetKey(&hmac, wolfSSL_GetHmacType(ssl),
macSecret,
ssl->specs.hash_size);
@ -1272,21 +1335,21 @@ int TLS_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz, int padSz,
#ifdef HAVE_BLAKE2
if (wolfSSL_GetHmacType(ssl) == WC_HASH_TYPE_BLAKE2B) {
ret = Hmac_UpdateFinal(&hmac, digest, in,
sz + hashSz + padSz + 1, myInner);
sz + hashSz + padSz + 1, myInner, innerSz);
}
else
#endif
{
ret = Hmac_UpdateFinal_CT(&hmac, digest, in,
sz + hashSz + padSz + 1, hashSz, myInner);
sz + hashSz + padSz + 1, hashSz, myInner, innerSz);
}
#else
ret = Hmac_UpdateFinal(&hmac, digest, in, sz + hashSz + padSz + 1,
myInner);
myInner, innerSz);
#endif
}
else {
ret = wc_HmacUpdate(&hmac, myInner, sizeof(myInner));
ret = wc_HmacUpdate(&hmac, myInner, innerSz);
if (ret == 0)
ret = wc_HmacUpdate(&hmac, in, sz); /* content */
if (ret == 0)
@ -12387,6 +12450,26 @@ void TLSX_FreeAll(TLSX* list, void* heap)
WOLFSSL_MSG("Encrypt-Then-Mac extension free");
break;
#endif
#if defined(WOLFSSL_TLS13) || !defined(WOLFSSL_NO_TLS12) || !defined(NO_OLD_TLS)
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
case TLSX_PRE_SHARED_KEY:
WOLFSSL_MSG("Pre-Shared Key extension free");
PSK_FREE_ALL((PreSharedKey*)extension->data, heap);
break;
#ifdef WOLFSSL_TLS13
case TLSX_PSK_KEY_EXCHANGE_MODES:
WOLFSSL_MSG("PSK Key Exchange Modes extension free");
break;
#endif
#endif
case TLSX_KEY_SHARE:
WOLFSSL_MSG("Key Share extension free");
KS_FREE_ALL((KeyShareEntry*)extension->data, heap);
break;
#endif
#ifdef WOLFSSL_TLS13
case TLSX_SUPPORTED_VERSIONS:
WOLFSSL_MSG("Supported Versions extension free");
@ -12399,17 +12482,6 @@ void TLSX_FreeAll(TLSX* list, void* heap)
break;
#endif
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
case TLSX_PRE_SHARED_KEY:
WOLFSSL_MSG("Pre-Shared Key extension free");
PSK_FREE_ALL((PreSharedKey*)extension->data, heap);
break;
case TLSX_PSK_KEY_EXCHANGE_MODES:
WOLFSSL_MSG("PSK Key Exchange Modes extension free");
break;
#endif
#ifdef WOLFSSL_EARLY_DATA
case TLSX_EARLY_DATA:
WOLFSSL_MSG("Early Data extension free");
@ -12427,11 +12499,6 @@ void TLSX_FreeAll(TLSX* list, void* heap)
WOLFSSL_MSG("Signature Algorithms extension free");
break;
#endif
case TLSX_KEY_SHARE:
WOLFSSL_MSG("Key Share extension free");
KS_FREE_ALL((KeyShareEntry*)extension->data, heap);
break;
#if !defined(NO_CERTS) && !defined(WOLFSSL_NO_CA_NAMES)
case TLSX_CERTIFICATE_AUTHORITIES:
WOLFSSL_MSG("Certificate Authorities extension free");
@ -12582,6 +12649,24 @@ static int TLSX_GetSize(TLSX* list, byte* semaphore, byte msgType,
ret = ETM_GET_SIZE(msgType, &length);
break;
#endif /* HAVE_ENCRYPT_THEN_MAC */
#if defined(WOLFSSL_TLS13) || !defined(WOLFSSL_NO_TLS12) || !defined(NO_OLD_TLS)
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
case TLSX_PRE_SHARED_KEY:
ret = PSK_GET_SIZE((PreSharedKey*)extension->data, msgType,
&length);
break;
#ifdef WOLFSSL_TLS13
case TLSX_PSK_KEY_EXCHANGE_MODES:
ret = PKM_GET_SIZE((byte)extension->val, msgType, &length);
break;
#endif
#endif
case TLSX_KEY_SHARE:
length += KS_GET_SIZE((KeyShareEntry*)extension->data, msgType);
break;
#endif
#ifdef WOLFSSL_TLS13
case TLSX_SUPPORTED_VERSIONS:
ret = SV_GET_SIZE(extension->data, msgType, &length);
@ -12593,17 +12678,6 @@ static int TLSX_GetSize(TLSX* list, byte* semaphore, byte msgType,
break;
#endif
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
case TLSX_PRE_SHARED_KEY:
ret = PSK_GET_SIZE((PreSharedKey*)extension->data, msgType,
&length);
break;
case TLSX_PSK_KEY_EXCHANGE_MODES:
ret = PKM_GET_SIZE((byte)extension->val, msgType, &length);
break;
#endif
#ifdef WOLFSSL_EARLY_DATA
case TLSX_EARLY_DATA:
ret = EDI_GET_SIZE(msgType, &length);
@ -12622,9 +12696,6 @@ static int TLSX_GetSize(TLSX* list, byte* semaphore, byte msgType,
break;
#endif
case TLSX_KEY_SHARE:
length += KS_GET_SIZE((KeyShareEntry*)extension->data, msgType);
break;
#if !defined(NO_CERTS) && !defined(WOLFSSL_NO_CA_NAMES)
case TLSX_CERTIFICATE_AUTHORITIES:
length += CAN_GET_SIZE(extension->data);
@ -12806,20 +12877,8 @@ static int TLSX_Write(TLSX* list, byte* output, byte* semaphore,
ret = ETM_WRITE(extension->data, output, msgType, &offset);
break;
#endif /* HAVE_ENCRYPT_THEN_MAC */
#ifdef WOLFSSL_TLS13
case TLSX_SUPPORTED_VERSIONS:
WOLFSSL_MSG("Supported Versions extension to write");
ret = SV_WRITE(extension->data, output + offset, msgType, &offset);
break;
#ifdef WOLFSSL_SEND_HRR_COOKIE
case TLSX_COOKIE:
WOLFSSL_MSG("Cookie extension to write");
ret = CKE_WRITE((Cookie*)extension->data, output + offset,
msgType, &offset);
break;
#endif
#if defined(WOLFSSL_TLS13) || !defined(WOLFSSL_NO_TLS12) || !defined(NO_OLD_TLS)
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
case TLSX_PRE_SHARED_KEY:
WOLFSSL_MSG("Pre-Shared Key extension to write");
@ -12827,11 +12886,33 @@ static int TLSX_Write(TLSX* list, byte* output, byte* semaphore,
msgType, &offset);
break;
#ifdef WOLFSSL_TLS13
case TLSX_PSK_KEY_EXCHANGE_MODES:
WOLFSSL_MSG("PSK Key Exchange Modes extension to write");
ret = PKM_WRITE((byte)extension->val, output + offset, msgType,
&offset);
break;
#endif
#endif
case TLSX_KEY_SHARE:
WOLFSSL_MSG("Key Share extension to write");
offset += KS_WRITE((KeyShareEntry*)extension->data,
output + offset, msgType);
break;
#endif
#ifdef WOLFSSL_TLS13
case TLSX_SUPPORTED_VERSIONS:
WOLFSSL_MSG("Supported Versions extension to write");
ret = SV_WRITE(extension->data, output + offset, msgType,
&offset);
break;
#ifdef WOLFSSL_SEND_HRR_COOKIE
case TLSX_COOKIE:
WOLFSSL_MSG("Cookie extension to write");
ret = CKE_WRITE((Cookie*)extension->data, output + offset,
msgType, &offset);
break;
#endif
#ifdef WOLFSSL_EARLY_DATA
@ -12856,11 +12937,6 @@ static int TLSX_Write(TLSX* list, byte* output, byte* semaphore,
break;
#endif
case TLSX_KEY_SHARE:
WOLFSSL_MSG("Key Share extension to write");
offset += KS_WRITE((KeyShareEntry*)extension->data,
output + offset, msgType);
break;
#if !defined(NO_CERTS) && !defined(WOLFSSL_NO_CA_NAMES)
case TLSX_CERTIFICATE_AUTHORITIES:
WOLFSSL_MSG("Certificate Authorities extension to write");
@ -14123,9 +14199,6 @@ int TLSX_GetResponseSize(WOLFSSL* ssl, byte msgType, word16* pLength)
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
#endif
#ifdef WOLFSSL_DTLS_CID
TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_CONNECTION_ID));
#endif
}
#if !defined(WOLFSSL_NO_TLS12) || !defined(NO_OLD_TLS)
else {
@ -14137,6 +14210,9 @@ int TLSX_GetResponseSize(WOLFSSL* ssl, byte msgType, word16* pLength)
#endif
}
#endif
#ifdef WOLFSSL_DTLS_CID
TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_CONNECTION_ID));
#endif
#endif /* WOLFSSL_TLS13 */
break;
@ -14250,7 +14326,7 @@ int TLSX_WriteResponse(WOLFSSL *ssl, byte* output, byte msgType, word16* pOffset
#ifndef NO_WOLFSSL_SERVER
case server_hello:
PF_VALIDATE_RESPONSE(ssl, semaphore);
#ifdef WOLFSSL_TLS13
#ifdef WOLFSSL_TLS13
if (IsAtLeastTLSv1_3(ssl->version)) {
XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
TURN_OFF(semaphore,
@ -14267,21 +14343,23 @@ int TLSX_WriteResponse(WOLFSSL *ssl, byte* output, byte msgType, word16* pOffset
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
#endif
#ifdef WOLFSSL_DTLS_CID
TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_CONNECTION_ID));
#endif /* WOLFSSL_DTLS_CID */
}
else
#endif /* WOLFSSL_TLS13 */
{
#if !defined(WOLFSSL_NO_TLS12) || !defined(NO_OLD_TLS)
else {
#ifdef HAVE_SUPPORTED_CURVES
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
#endif
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
#endif
}
#endif
#endif
WC_DO_NOTHING; /* avoid empty brackets */
}
#ifdef WOLFSSL_DTLS_CID
TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_CONNECTION_ID));
#endif /* WOLFSSL_DTLS_CID */
break;
#ifdef WOLFSSL_TLS13
@ -15187,10 +15265,6 @@ int TLSX_Parse(WOLFSSL* ssl, const byte* input, word16 length, byte msgType,
#endif /* WOLFSSL_QUIC */
#if defined(WOLFSSL_DTLS_CID)
case TLSX_CONNECTION_ID:
/* connection ID not supported in DTLSv1.2 */
if (!IsAtLeastTLSv1_3(ssl->version))
break;
if (msgType != client_hello && msgType != server_hello)
return EXT_NOT_ALLOWED;

View File

@ -92453,6 +92453,11 @@ static int test_wolfSSL_dtls13_null_cipher(void)
ExpectIntEQ(ssl_s->error, WC_NO_ERR_TRACE(WANT_READ));
}
ExpectIntEQ(wolfSSL_shutdown(ssl_c), WOLFSSL_SHUTDOWN_NOT_DONE);
ExpectIntEQ(wolfSSL_shutdown(ssl_s), WOLFSSL_SHUTDOWN_NOT_DONE);
ExpectIntEQ(wolfSSL_shutdown(ssl_c), 1);
ExpectIntEQ(wolfSSL_shutdown(ssl_s), 1);
wolfSSL_free(ssl_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_c);
@ -94168,6 +94173,350 @@ static int test_dtls_old_seq_number(void)
return EXPECT_RESULT();
}
static int test_dtls12_basic_connection_id(void)
{
EXPECT_DECLS;
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS_CID)
unsigned char client_cid[] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
unsigned char server_cid[] = { 0, 1, 2, 3, 4, 5 };
unsigned char readBuf[40];
const char* params[] = {
#ifndef NO_RSA
#ifndef NO_SHA256
#if defined(WOLFSSL_AES_128) && defined(WOLFSSL_STATIC_RSA)
"AES128-SHA256",
#ifdef HAVE_AESCCM
"AES128-CCM8",
#endif
"DHE-RSA-AES128-SHA256",
"ECDHE-RSA-AES128-SHA256",
#ifdef HAVE_AESGCM
"DHE-RSA-AES128-GCM-SHA256",
"ECDHE-RSA-AES128-GCM-SHA256",
#endif
#endif /* WOLFSSL_AES_128 && WOLFSSL_STATIC_RSA */
#endif /* NO_SHA256 */
#endif /* NO_RSA */
#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
"DHE-RSA-CHACHA20-POLY1305",
"DHE-RSA-CHACHA20-POLY1305-OLD",
"ECDHE-RSA-CHACHA20-POLY1305",
"ECDHE-RSA-CHACHA20-POLY1305-OLD",
#endif
#ifndef NO_PSK
"DHE-PSK-AES128-CBC-SHA256",
"DHE-PSK-AES256-GCM-SHA384",
#ifndef HAVE_NULL_CIPHER
"DHE-PSK-NULL-SHA256",
#endif
"DHE-PSK-AES128-CCM",
#endif
};
size_t i;
struct {
byte drop:1;
byte changeCID:1;
} run_params[] = {
{ .drop = 0, .changeCID = 0 },
{ .drop = 1, .changeCID = 0 },
{ .drop = 0, .changeCID = 1 },
};
/* We check if the side included the CID in their output */
#define CLIENT_CID() mymemmem(test_ctx.s_buff, test_ctx.s_len, \
client_cid, sizeof(client_cid))
#define SERVER_CID() mymemmem(test_ctx.c_buff, test_ctx.c_len, \
server_cid, sizeof(server_cid))
printf("\n");
for (i = 0; i < XELEM_CNT(params) && EXPECT_SUCCESS(); i++) {
size_t j;
for (j = 0; j < XELEM_CNT(run_params); j++) {
WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL;
WOLFSSL *ssl_c = NULL, *ssl_s = NULL;
struct test_memio_ctx test_ctx;
printf("Testing %s run #%ld ... ", params[i], j);
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c,
&ssl_s, wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method),
0);
ExpectIntEQ(wolfSSL_set_cipher_list(ssl_c, params[i]), 1);
ExpectIntEQ(wolfSSL_set_cipher_list(ssl_s, params[i]), 1);
ExpectIntEQ(wolfSSL_dtls_cid_use(ssl_c), 1);
ExpectIntEQ(wolfSSL_dtls_cid_set(ssl_c, server_cid,
sizeof(server_cid)), 1);
ExpectIntEQ(wolfSSL_dtls_cid_use(ssl_s), 1);
ExpectIntEQ(wolfSSL_dtls_cid_set(ssl_s, client_cid,
sizeof(client_cid)), 1);
#ifndef NO_PSK
if (XSTRSTR(params[i], "-PSK-") != NULL) {
wolfSSL_set_psk_client_callback(ssl_c, my_psk_client_cb);
wolfSSL_set_psk_server_callback(ssl_s, my_psk_server_cb);
}
#endif
#ifdef HAVE_SECURE_RENEGOTIATION
ExpectIntEQ(wolfSSL_UseSecureRenegotiation(ssl_c), 1);
ExpectIntEQ(wolfSSL_UseSecureRenegotiation(ssl_s), 1);
#endif
/* CH1 */
wolfSSL_SetLoggingPrefix("client");
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
ExpectNull(CLIENT_CID());
if (run_params[j].drop) {
test_ctx.c_len = test_ctx.s_len = 0;
ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_c), 1);
ExpectNull(CLIENT_CID());
}
/* HVR */
wolfSSL_SetLoggingPrefix("server");
ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
ExpectNull(SERVER_CID());
/* No point dropping HVR */
/* CH2 */
wolfSSL_SetLoggingPrefix("client");
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
ExpectNull(CLIENT_CID());
if (run_params[j].drop) {
test_ctx.c_len = test_ctx.s_len = 0;
ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_c), 1);
ExpectNull(CLIENT_CID());
}
/* Server first flight */
wolfSSL_SetLoggingPrefix("server");
ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
ExpectNull(SERVER_CID());
if (run_params[j].drop) {
test_ctx.c_len = test_ctx.s_len = 0;
ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_s), 1);
ExpectNull(SERVER_CID());
}
/* Client second flight */
wolfSSL_SetLoggingPrefix("client");
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
ExpectNotNull(CLIENT_CID());
if (run_params[j].drop) {
test_ctx.c_len = test_ctx.s_len = 0;
ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_c), 1);
ExpectNotNull(CLIENT_CID());
}
/* Server second flight */
wolfSSL_SetLoggingPrefix("server");
ExpectIntEQ(wolfSSL_negotiate(ssl_s), 1);
ExpectNotNull(SERVER_CID());
if (run_params[j].drop) {
test_ctx.c_len = test_ctx.s_len = 0;
ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_s), 1);
ExpectNotNull(SERVER_CID());
}
/* Client complete connection */
wolfSSL_SetLoggingPrefix("client");
ExpectIntEQ(wolfSSL_negotiate(ssl_c), 1);
ExpectNull(CLIENT_CID());
/* Write some data */
wolfSSL_SetLoggingPrefix("client");
ExpectIntEQ(wolfSSL_write(ssl_c, params[i],
(int)XSTRLEN(params[i])), XSTRLEN(params[i]));
ExpectNotNull(CLIENT_CID());
wolfSSL_SetLoggingPrefix("server");
ExpectIntEQ(wolfSSL_write(ssl_s, params[i],
(int)XSTRLEN(params[i])), XSTRLEN(params[i]));
ExpectNotNull(SERVER_CID());
/* Read the data */
wolfSSL_SetLoggingPrefix("client");
XMEMSET(readBuf, 0, sizeof(readBuf));
ExpectIntEQ(wolfSSL_read(ssl_c, readBuf, sizeof(readBuf)),
XSTRLEN(params[i]));
ExpectStrEQ(readBuf, params[i]);
XMEMSET(readBuf, 0, sizeof(readBuf));
wolfSSL_SetLoggingPrefix("server");
ExpectIntEQ(wolfSSL_read(ssl_s, readBuf, sizeof(readBuf)),
XSTRLEN(params[i]));
ExpectStrEQ(readBuf, params[i]);
/* Write short data */
wolfSSL_SetLoggingPrefix("client");
ExpectIntEQ(wolfSSL_write(ssl_c, params[i], 1), 1);
ExpectNotNull(CLIENT_CID());
wolfSSL_SetLoggingPrefix("server");
ExpectIntEQ(wolfSSL_write(ssl_s, params[i], 1), 1);
ExpectNotNull(SERVER_CID());
/* Read the short data */
XMEMSET(readBuf, 0, sizeof(readBuf));
wolfSSL_SetLoggingPrefix("client");
ExpectIntEQ(wolfSSL_read(ssl_c, readBuf, sizeof(readBuf)), 1);
ExpectIntEQ(readBuf[0], params[i][0]);
XMEMSET(readBuf, 0, sizeof(readBuf));
wolfSSL_SetLoggingPrefix("server");
ExpectIntEQ(wolfSSL_read(ssl_s, readBuf, sizeof(readBuf)), 1);
ExpectIntEQ(readBuf[0], params[i][0]);
#ifdef HAVE_SECURE_RENEGOTIATION
/* do two SCR's */
wolfSSL_SetLoggingPrefix("client");
ExpectIntEQ(wolfSSL_Rehandshake(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
ExpectIntEQ(wolfSSL_read(ssl_s, readBuf, sizeof(readBuf)), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
/* SCR's after the first one have extra internal logic */
wolfSSL_SetLoggingPrefix("client");
ExpectIntEQ(wolfSSL_Rehandshake(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
ExpectIntEQ(wolfSSL_read(ssl_s, readBuf, sizeof(readBuf)), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
if (run_params[j].changeCID) {
ExpectIntEQ(wolfSSL_dtls_cid_set(ssl_c, client_cid,
sizeof(client_cid)), 0);
/* Forcefully change the CID */
ssl_c->dtlsCidInfo->rx->id[0] = -1;
/* We need to init the rehandshake from the client, otherwise
* we won't be able to test changing the CID. It would be
* rejected by the record CID matching code. */
wolfSSL_SetLoggingPrefix("client");
ExpectIntEQ(wolfSSL_Rehandshake(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1),
WOLFSSL_ERROR_WANT_READ);
ExpectNotNull(CLIENT_CID());
ExpectIntEQ(wolfSSL_SSL_renegotiate_pending(ssl_c), 1);
/* Server first flight */
wolfSSL_SetLoggingPrefix("server");
ExpectIntEQ(wolfSSL_read(ssl_s, readBuf, sizeof(readBuf)), -1);
/* We expect the server to reject the CID change. */
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), DTLS_CID_ERROR);
goto loop_exit;
}
/* Server init'd SCR */
/* Server request */
wolfSSL_SetLoggingPrefix("server");
ExpectIntEQ(wolfSSL_Rehandshake(ssl_s), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
ExpectNotNull(SERVER_CID());
ExpectIntEQ(wolfSSL_SSL_renegotiate_pending(ssl_s), 1);
if (run_params[j].drop) {
test_ctx.c_len = test_ctx.s_len = 0;
ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_s), 1);
ExpectNotNull(SERVER_CID());
}
/* Init SCR on client side with the server's request */
/* CH no HVR on SCR */
XMEMSET(readBuf, 0, sizeof(readBuf));
wolfSSL_SetLoggingPrefix("client");
ExpectIntEQ(wolfSSL_read(ssl_c, readBuf, sizeof(readBuf)), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
ExpectNotNull(CLIENT_CID());
ExpectIntEQ(wolfSSL_SSL_renegotiate_pending(ssl_c), 1);
if (run_params[j].drop) {
test_ctx.c_len = test_ctx.s_len = 0;
ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_c), 1);
ExpectNotNull(CLIENT_CID());
}
/* Server first flight */
wolfSSL_SetLoggingPrefix("server");
ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
ExpectNotNull(SERVER_CID());
if (run_params[j].drop) {
test_ctx.c_len = test_ctx.s_len = 0;
ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_s), 1);
ExpectNotNull(SERVER_CID());
}
/* Client second flight */
wolfSSL_SetLoggingPrefix("client");
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
ExpectNotNull(CLIENT_CID());
if (run_params[j].drop) {
test_ctx.c_len = test_ctx.s_len = 0;
ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_c), 1);
ExpectNotNull(CLIENT_CID());
}
ExpectIntEQ(wolfSSL_write(ssl_c, params[i],
(int)XSTRLEN(params[i])), XSTRLEN(params[i]));
/* Server second flight */
wolfSSL_SetLoggingPrefix("server");
ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), APP_DATA_READY);
XMEMSET(readBuf, 0, sizeof(readBuf));
ExpectIntEQ(wolfSSL_read(ssl_s, readBuf, sizeof(readBuf)),
XSTRLEN(params[i]));
ExpectStrEQ(readBuf, params[i]);
if (!run_params[j].drop) {
ExpectIntEQ(wolfSSL_write(ssl_s, params[i],
(int)XSTRLEN(params[i])), XSTRLEN(params[i]));
}
ExpectIntEQ(wolfSSL_negotiate(ssl_s), 1);
ExpectNotNull(SERVER_CID());
if (run_params[j].drop) {
test_ctx.c_len = test_ctx.s_len = 0;
ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_s), 1);
ExpectNotNull(SERVER_CID());
}
/* Test loading old epoch */
/* Client complete connection */
wolfSSL_SetLoggingPrefix("client");
if (!run_params[j].drop) {
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), APP_DATA_READY);
XMEMSET(readBuf, 0, sizeof(readBuf));
ExpectIntEQ(wolfSSL_read(ssl_c, readBuf, sizeof(readBuf)),
XSTRLEN(params[i]));
ExpectStrEQ(readBuf, params[i]);
}
ExpectIntEQ(wolfSSL_negotiate(ssl_c), 1);
ExpectNull(CLIENT_CID());
ExpectIntEQ(wolfSSL_SSL_renegotiate_pending(ssl_c), 0);
ExpectIntEQ(wolfSSL_SSL_renegotiate_pending(ssl_s), 0);
#endif
/* Close connection */
wolfSSL_SetLoggingPrefix("client");
ExpectIntEQ(wolfSSL_shutdown(ssl_c), WOLFSSL_SHUTDOWN_NOT_DONE);
ExpectNotNull(CLIENT_CID());
wolfSSL_SetLoggingPrefix("server");
ExpectIntEQ(wolfSSL_shutdown(ssl_s), WOLFSSL_SHUTDOWN_NOT_DONE);
ExpectNotNull(SERVER_CID());
wolfSSL_SetLoggingPrefix("client");
ExpectIntEQ(wolfSSL_shutdown(ssl_c), 1);
wolfSSL_SetLoggingPrefix("server");
ExpectIntEQ(wolfSSL_shutdown(ssl_s), 1);
#ifdef HAVE_SECURE_RENEGOTIATION
loop_exit:
#endif
wolfSSL_SetLoggingPrefix(NULL);
wolfSSL_free(ssl_c);
wolfSSL_CTX_free(ctx_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_s);
if (EXPECT_SUCCESS())
printf("ok\n");
else
printf("failed\n");
}
}
#undef CLIENT_CID
#undef SERVER_CID
#endif
return EXPECT_RESULT();
}
static int test_dtls13_basic_connection_id(void)
{
EXPECT_DECLS;
@ -94252,10 +94601,10 @@ static int test_dtls13_basic_connection_id(void)
ExpectIntEQ(wolfSSL_negotiate(ssl_c), 1);
/* Write some data */
ExpectIntEQ(wolfSSL_write(ssl_c, params[i], XSTRLEN(params[i])),
ExpectIntEQ(wolfSSL_write(ssl_c, params[i], (int)XSTRLEN(params[i])),
XSTRLEN(params[i]));
ExpectNotNull(CLIENT_CID());
ExpectIntEQ(wolfSSL_write(ssl_s, params[i], XSTRLEN(params[i])),
ExpectIntEQ(wolfSSL_write(ssl_s, params[i], (int)XSTRLEN(params[i])),
XSTRLEN(params[i]));
ExpectNotNull(SERVER_CID());
/* Read the data */
@ -96707,6 +97056,7 @@ TEST_CASE testCases[] = {
TEST_DECL(test_dtls13_frag_ch_pq),
TEST_DECL(test_dtls_empty_keyshare_with_cookie),
TEST_DECL(test_dtls_old_seq_number),
TEST_DECL(test_dtls12_basic_connection_id),
TEST_DECL(test_dtls13_basic_connection_id),
TEST_DECL(test_tls13_pq_groups),
TEST_DECL(test_tls13_early_data),

View File

@ -1430,7 +1430,7 @@ enum {
#ifdef WOLFSSL_DTLS_CID
#ifndef DTLS_CID_MAX_SIZE
/* DTLSv1.3 parsing code copies the record header in a static buffer to decrypt
/* DTLS parsing code copies the record header in a static buffer to decrypt
* the record. Increasing the CID max size does increase also this buffer,
* impacting on per-session runtime memory footprint. */
#define DTLS_CID_MAX_SIZE 10
@ -1444,6 +1444,30 @@ enum {
#error "Max size for DTLS CID is 255 bytes"
#endif
/* Record Payload Protection Section 5
* https://www.rfc-editor.org/rfc/rfc9146.html#section-5 */
#define WOLFSSL_TLS_HMAC_CID_INNER_SZ \
(8 + /* seq_num_placeholder */ \
1 + /* tls12_cid */ \
1 + /* cid_length */ \
1 + /* tls12_cid */ \
2 + /* DTLSCiphertext.version */ \
2 + /* epoch */ \
6 + /* sequence_number */ \
DTLS_CID_MAX_SIZE + /* cid */ \
2) /* length_of_DTLSInnerPlaintext */
#define WOLFSSL_TLS_AEAD_CID_AAD_SZ \
(8 + /* seq_num_placeholder */ \
1 + /* tls12_cid */ \
1 + /* cid_length */ \
1 + /* tls12_cid */ \
2 + /* DTLSCiphertext.version */ \
2 + /* epoch */ \
6 + /* sequence_number */ \
DTLS_CID_MAX_SIZE + /* cid */ \
2) /* length_of_DTLSInnerPlaintext */
#ifndef MAX_TICKET_AGE_DIFF
/* maximum ticket age difference in seconds, 10 seconds */
#define MAX_TICKET_AGE_DIFF 10
@ -1650,6 +1674,7 @@ enum Misc {
DTLS_HANDSHAKE_HEADER_SZ = 12, /* normal + seq(2) + offset(3) + length(3) */
DTLS_RECORD_HEADER_SZ = 13, /* normal + epoch(2) + seq_num(6) */
DTLS12_CID_OFFSET = 11,
DTLS_UNIFIED_HEADER_MIN_SZ = 2,
/* flags + seq_number(2) + length(2) + CID */
DTLS_RECVD_RL_HEADER_MAX_SZ = 5 + DTLS_CID_MAX_SIZE,
@ -1750,6 +1775,7 @@ enum Misc {
CHACHA20_IMP_IV_SZ = 12, /* Size of ChaCha20 AEAD implicit IV */
CHACHA20_NONCE_SZ = 12, /* Size of ChacCha20 nonce */
CHACHA20_OLD_OFFSET = 4, /* Offset for seq # in old poly1305 */
CHACHA20_OFFSET = 4, /* Offset for seq # in poly1305 */
/* For any new implicit/explicit IV size adjust AEAD_MAX_***_SZ */
@ -1859,6 +1885,14 @@ enum Misc {
READ_PROTO = 0 /* reading a protocol message */
};
/* Size of the data to authenticate */
#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_DTLS_CID)
#define AEAD_AUTH_DATA_SZ WOLFSSL_TLS_AEAD_CID_AAD_SZ
#else
#define AEAD_AUTH_DATA_SZ 13
#endif
#define WOLFSSL_NAMED_GROUP_IS_FFHDE(group) \
(MIN_FFHDE_GROUP <= (group) && (group) <= MAX_FFHDE_GROUP)
#ifdef WOLFSSL_HAVE_KYBER
@ -2239,7 +2273,7 @@ WOLFSSL_LOCAL int ALPN_Select(WOLFSSL* ssl);
#endif
WOLFSSL_LOCAL int ChachaAEADEncrypt(WOLFSSL* ssl, byte* out, const byte* input,
word16 sz); /* needed by sniffer */
word16 sz, byte type); /* needed by sniffer */
WOLFSSL_LOCAL int ChachaAEADDecrypt(WOLFSSL* ssl, byte* plain, const byte* input,
word16 sz); /* needed by sniffer */
@ -2960,9 +2994,6 @@ typedef enum {
TLSX_EXTENDED_MASTER_SECRET = TLSXT_EXTENDED_MASTER_SECRET,
TLSX_SESSION_TICKET = TLSXT_SESSION_TICKET,
#ifdef WOLFSSL_TLS13
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
TLSX_PRE_SHARED_KEY = TLSXT_PRE_SHARED_KEY,
#endif
#ifdef WOLFSSL_EARLY_DATA
TLSX_EARLY_DATA = TLSXT_EARLY_DATA,
#endif
@ -2982,7 +3013,6 @@ typedef enum {
#if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
TLSX_SIGNATURE_ALGORITHMS_CERT = TLSXT_SIGNATURE_ALGORITHMS_CERT,
#endif
TLSX_KEY_SHARE = TLSXT_KEY_SHARE,
#if defined(WOLFSSL_DTLS_CID)
TLSX_CONNECTION_ID = TLSXT_CONNECTION_ID,
#endif /* defined(WOLFSSL_DTLS_CID) */
@ -2993,6 +3023,12 @@ typedef enum {
TLSX_ECH = TLSXT_ECH,
#endif
#endif
#if defined(WOLFSSL_TLS13) || !defined(WOLFSSL_NO_TLS12) || !defined(NO_OLD_TLS)
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
TLSX_PRE_SHARED_KEY = TLSXT_PRE_SHARED_KEY,
#endif
TLSX_KEY_SHARE = TLSXT_KEY_SHARE,
#endif
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_DUAL_ALG_CERTS)
TLSX_CKS = TLSXT_CKS,
#endif
@ -3658,6 +3694,8 @@ WOLFSSL_LOCAL void DtlsCIDOnExtensionsParsed(WOLFSSL* ssl);
WOLFSSL_LOCAL byte DtlsCIDCheck(WOLFSSL* ssl, const byte* input,
word16 inputSize);
#endif /* WOLFSSL_DTLS_CID */
WOLFSSL_LOCAL byte DtlsGetCidTxSize(WOLFSSL* ssl);
WOLFSSL_LOCAL byte DtlsGetCidRxSize(WOLFSSL* ssl);
#ifdef OPENSSL_EXTRA
enum SetCBIO {
@ -5480,6 +5518,7 @@ typedef struct BuildMsgArgs {
word32 headerSz;
word16 size;
word32 ivSz; /* TLSv1.1 IV */
byte type;
byte* iv;
ALIGN16 byte staticIvBuffer[MAX_IV_SZ];
} BuildMsgArgs;
@ -5626,7 +5665,21 @@ typedef struct Dtls13Rtx {
#endif /* WOLFSSL_DTLS13 */
#ifdef WOLFSSL_DTLS_CID
typedef struct CIDInfo CIDInfo;
typedef struct ConnectionID {
byte length;
/* Ignore "nonstandard extension used : zero-sized array in struct/union"
* MSVC warning */
#ifdef _MSC_VER
#pragma warning(disable: 4200)
#endif
byte id[];
} ConnectionID;
typedef struct CIDInfo {
ConnectionID* tx;
ConnectionID* rx;
byte negotiated : 1;
} CIDInfo;
#endif /* WOLFSSL_DTLS_CID */
/* The idea is to reuse the context suites object whenever possible to save
@ -6236,6 +6289,7 @@ enum ContentType {
alert = 21,
handshake = 22,
application_data = 23,
dtls12_cid = 25,
#ifdef WOLFSSL_DTLS13
ack = 26,
#endif /* WOLFSSL_DTLS13 */
@ -6525,6 +6579,7 @@ WOLFSSL_LOCAL void DoCertFatalAlert(WOLFSSL* ssl, int ret);
#endif
WOLFSSL_LOCAL int cipherExtraData(WOLFSSL* ssl);
WOLFSSL_LOCAL word32 MacSize(const WOLFSSL* ssl);
#ifndef NO_WOLFSSL_CLIENT
WOLFSSL_LOCAL int HaveUniqueSessionObj(WOLFSSL* ssl);

View File

@ -3394,7 +3394,7 @@ enum {
WOLFSSL_BLOCK_TYPE = 2,
WOLFSSL_STREAM_TYPE = 3,
WOLFSSL_AEAD_TYPE = 4,
WOLFSSL_TLS_HMAC_INNER_SZ = 13 /* SEQ_SZ + ENUM + VERSION_SZ + LEN_SZ */
WOLFSSL_TLS_HMAC_INNER_SZ = 13, /* SEQ_SZ + ENUM + VERSION_SZ + LEN_SZ */
};
/* for GetBulkCipher and internal use
@ -5476,6 +5476,7 @@ WOLFSSL_API int wolfSSL_dtls_cid_get_tx_size(WOLFSSL* ssl,
unsigned int* size);
WOLFSSL_API int wolfSSL_dtls_cid_get_tx(WOLFSSL* ssl, unsigned char* buffer,
unsigned int bufferSz);
WOLFSSL_API int wolfSSL_dtls_cid_max_size(void);
#endif /* defined(WOLFSSL_DTLS_CID) */
#ifdef WOLFSSL_DTLS_CH_FRAG

View File

@ -1853,7 +1853,8 @@ static WC_INLINE unsigned int my_psk_client_cb(WOLFSSL* ssl, const char* hint,
/* see internal.h MAX_PSK_ID_LEN for PSK identity limit */
XSTRNCPY(identity, kIdentityStr, id_max_len);
if (wolfSSL_GetVersion(ssl) < WOLFSSL_TLSV1_3) {
if (wolfSSL_GetVersion(ssl) != WOLFSSL_TLSV1_3 &&
wolfSSL_GetVersion(ssl) != WOLFSSL_DTLSV1_3) {
/* test key in hex is 0x1a2b3c4d , in decimal 439,041,101 , we're using
* unsigned binary */
key[0] = 0x1a;
@ -1897,7 +1898,8 @@ static WC_INLINE unsigned int my_psk_server_cb(WOLFSSL* ssl, const char* identit
if (XSTRCMP(identity, kIdentityStr) != 0)
return 0;
if (wolfSSL_GetVersion(ssl) < WOLFSSL_TLSV1_3) {
if (wolfSSL_GetVersion(ssl) != WOLFSSL_TLSV1_3 &&
wolfSSL_GetVersion(ssl) != WOLFSSL_DTLSV1_3) {
/* test key in hex is 0x1a2b3c4d , in decimal 439,041,101 , we're using
* unsigned binary */
key[0] = 0x1a;