add initial support for ConnectionID DTLS extension

This commit is contained in:
Marco Oliverio
2022-08-10 16:39:44 +02:00
parent 171af05e96
commit cfbd061625
18 changed files with 874 additions and 101 deletions

View File

@ -290,6 +290,18 @@ if(WOLFSSL_DTLS13)
endif()
endif()
# DTLS ConnectionID support
add_option("WOLFSSL_DTLS_CID"
"Enables wolfSSL DTLS CID (default: disabled)"
"no" "yes;no")
if(WOLFSSL_DTLS_CID)
if(NOT WOLFSSL_DTLS13)
message(FATAL_ERROR "CID are supported only for DTLSv1.3")
endif()
list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_DTLS_CID")
endif()
# Post-handshake authentication
add_option("WOLFSSL_POSTAUTH"
"Enable wolfSSL Post-handshake Authentication (default: disabled)"

View File

@ -309,6 +309,7 @@
<ClCompile Include="..\..\src\tls.c" />
<ClCompile Include="..\..\src\tls13.c" />
<ClCompile Include="..\..\src\dtls13.c" />
<ClCompile Include="..\..\src\dtls.c" />
<ClCompile Include="..\..\wolfcrypt\src\wc_encrypt.c" />
<ClCompile Include="..\..\wolfcrypt\src\wolfmath.c" />
<ClCompile Include="..\..\wolfcrypt\src\wolfevent.c" />

View File

@ -279,6 +279,7 @@
<ClCompile Include="..\..\src\tls.c" />
<ClCompile Include="..\..\src\tls13.c" />
<ClCompile Include="..\..\src\dtls13.c" />
<ClCompile Include="..\..\src\dtls.c" />
<ClCompile Include="..\..\wolfcrypt\src\wc_encrypt.c" />
<ClCompile Include="..\..\wolfcrypt\src\wolfcrypt_first.c" />
<ClCompile Include="..\..\wolfcrypt\src\wolfcrypt_last.c" />

View File

@ -53,6 +53,9 @@ function(generate_build_flags)
if(WOLFSSL_SCTP OR WOLFSSL_USER_SETTINGS)
set(BUILD_SCTP "yes" PARENT_SCOPE)
endif()
if(WOLFSSL_DTLS_CID OR WOLFSSL_USER_SETTINGS)
set(BUILD_DTLS_COMMON "yes" PARENT_SCOPE)
endif()
set(BUILD_MCAST ${WOLFSSL_MCAST} PARENT_SCOPE)
set(BUILD_IPV6 ${WOLFSSL_IPV6} PARENT_SCOPE)
set(BUILD_LEAN_PSK ${WOLFSSL_LEAN_PSK} PARENT_SCOPE)
@ -843,6 +846,10 @@ function(generate_lib_src_list LIB_SOURCES)
if(BUILD_SNIFFER)
list(APPEND LIB_SOURCES src/sniffer.c)
endif()
if(BUILD_DTLS_COMMON)
list(APPEND LIB_SOURCES src/dtls.c)
endif()
endif()
endif()

View File

@ -3760,6 +3760,21 @@ then
fi
fi
# DTLS CID support
AC_ARG_ENABLE([dtlscid],
[AS_HELP_STRING([--enable-dtlscid],[Enable wolfSSL DTLS ConnectionID (default: disabled)])],
[ ENABLED_DTLS_CID=$enableval ],
[ ENABLED_DTLS_CID=no ]
)
if test "x$ENABLED_DTLS_CID" = "xyes"
then
if test "x$ENABLED_DTLS13" != "xyes"
then
AC_MSG_ERROR([You need to enable DTLSv1.3 to use DTLS ConnectionID])
fi
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_DTLS_CID"
fi
# CODING
AC_ARG_ENABLE([coding],
[AS_HELP_STRING([--enable-coding],[Enable Coding base 16/64 (default: enabled)])],
@ -8077,6 +8092,7 @@ AM_CONDITIONAL([BUILD_DO178],[test "x$ENABLED_DO178" = "xyes"])
AM_CONDITIONAL([BUILD_PSA],[test "x$ENABLED_PSA" = "xyes"])
AM_CONDITIONAL([BUILD_DTLS13],[test "x$ENABLED_DTLS13" = "xyes"])
AM_CONDITIONAL([BUILD_QUIC],[test "x$ENABLED_QUIC" = "xyes"])
AM_CONDITIONAL([BUILD_DTLS_CID],[test "x$ENABLED_DTLS_CID" = "xyes"])
if test "$ENABLED_REPRODUCIBLE_BUILD" != "yes" &&
(test "$ax_enable_debug" = "yes" ||

View File

@ -14365,4 +14365,149 @@ unsigned int wolfSSL_SESSION_get_max_early_data(const WOLFSSL_SESSION *s);
*/
int wolfSSL_CRYPTO_get_ex_new_index(int, void*, void*, void*, void*);
/*!
\brief Enable use of ConnectionID extensions for the SSL object. See RFC 9146
and RFC 9147
\return WOLFSSL_SUCCESS on success, error code otherwise
\param ssl A WOLFSSL object pointer
\sa wolfSSL_dtls_cid_is_enabled
\sa wolfSSL_dtls_cid_set
\sa wolfSSL_dtls_cid_get_rx_size
\sa wolfSSL_dtls_cid_get_rx
\sa wolfSSL_dtls_cid_get_tx_size
\sa wolfSSL_dtls_cid_get_tx
*/
int wolfSSL_dtls_cid_use(WOLFSSL* ssl);
/*!
\brief If invoked after the handshake is complete it checks if ConnectionID was
successfully negotiated for the SSL object. See RFC 9146 and RFC 9147
\return 1 if ConnectionID was correctly negotiated, 0 otherwise
\param ssl A WOLFSSL object pointer
\sa wolfSSL_dtls_cid_use
\sa wolfSSL_dtls_cid_set
\sa wolfSSL_dtls_cid_get_rx_size
\sa wolfSSL_dtls_cid_get_rx
\sa wolfSSL_dtls_cid_get_tx_size
\sa wolfSSL_dtls_cid_get_tx
*/
int wolfSSL_dtls_cid_is_enabled(WOLFSSL* ssl);
/*!
\brief Set the ConnectionID used by the other peer to send records in this
connection. See RFC 9146 and RFC 9147. The ConnectionID must be at maximum
DTLS_CID_MAX_SIZE, that is an tunable compile time define, and it can't
never be bigger than 255 bytes.
\return WOLFSSL_SUCCESS if ConnectionID was correctly set, error code otherwise
\param ssl A WOLFSSL object pointern
\param cid the ConnectionID to be used
\param size of the ConnectionID provided
\sa wolfSSL_dtls_cid_use
\sa wolfSSL_dtls_cid_is_enabled
\sa wolfSSL_dtls_cid_get_rx_size
\sa wolfSSL_dtls_cid_get_rx
\sa wolfSSL_dtls_cid_get_tx_size
\sa wolfSSL_dtls_cid_get_tx
*/
int wolfSSL_dtls_cid_set(WOLFSSL* ssl, unsigned char* cid,
unsigned int size);
/*!
\brief Get the size of the ConnectionID used by the other peer to send records
in this connection. See RFC 9146 and RFC 9147. The size is stored in the
parameter size.
\return WOLFSSL_SUCCESS if ConnectionID was correctly negotiated, error code
otherwise
\param ssl A WOLFSSL object pointern
\param size a pointer to an unsigned int where the size will be stored
\sa wolfSSL_dtls_cid_use
\sa wolfSSL_dtls_cid_is_enabled
\sa wolfSSL_dtls_cid_set
\sa wolfSSL_dtls_cid_get_rx
\sa wolfSSL_dtls_cid_get_tx_size
\sa wolfSSL_dtls_cid_get_tx
*/
int wolfSSL_dtls_cid_get_rx_size(WOLFSSL* ssl,
unsigned int* size);
/*!
\brief Copy the ConnectionID used by the other peer to send records in this
connection into the buffer pointed by the parameter buffer. See RFC 9146 and RFC
9147. The available space in the buffer need to be provided in bufferSz.
\return WOLFSSL_SUCCESS if ConnectionID was correctly copied, error code
otherwise
\param ssl A WOLFSSL object pointern
\param buffer A buffer where the ConnectionID will be copied
\param bufferSz available space in buffer
\sa wolfSSL_dtls_cid_use
\sa wolfSSL_dtls_cid_is_enabled
\sa wolfSSL_dtls_cid_set
\sa wolfSSL_dtls_cid_get_rx_size
\sa wolfSSL_dtls_cid_get_tx_size
\sa wolfSSL_dtls_cid_get_tx
*/
int wolfSSL_dtls_cid_get_rx(WOLFSSL* ssl, unsigned char* buffer,
unsigned int bufferSz);
/*!
\brief Get the size of the ConnectionID used to send records in this
connection. See RFC 9146 and RFC 9147. The size is stored in the parameter size.
\return WOLFSSL_SUCCESS if ConnectionID size was correctly stored, error
code otherwise
\param ssl A WOLFSSL object pointern
\param size a pointer to an unsigned int where the size will be stored
\sa wolfSSL_dtls_cid_use
\sa wolfSSL_dtls_cid_is_enabled
\sa wolfSSL_dtls_cid_set
\sa wolfSSL_dtls_cid_get_rx_size
\sa wolfSSL_dtls_cid_get_rx
\sa wolfSSL_dtls_cid_get_tx
*/
int wolfSSL_dtls_cid_get_tx_size(WOLFSSL* ssl, unsigned int* size);
/*!
\brief Copy the ConnectionID used when sending records in this connection into
the buffer pointer by the parameter buffer. See RFC 9146 and RFC 9147. The
available size need to be provided in bufferSz.
\return WOLFSSL_SUCCESS if ConnectionID was correctly copied, error code
otherwise
\param ssl A WOLFSSL object pointern
\param buffer A buffer where the ConnectionID will be copied
\param bufferSz available space in buffer
\sa wolfSSL_dtls_cid_use
\sa wolfSSL_dtls_cid_is_enabled
\sa wolfSSL_dtls_cid_set
\sa wolfSSL_dtls_cid_get_rx_size
\sa wolfSSL_dtls_cid_get_rx
\sa wolfSSL_dtls_cid_get_tx_size
*/
int wolfSSL_dtls_cid_get_tx(WOLFSSL* ssl, unsigned char* buffer,
unsigned int bufferSz);

368
src/dtls.c Normal file
View File

@ -0,0 +1,368 @@
/* dtls.c
*
* Copyright (C) 2006-2022 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <wolfssl/wolfcrypt/settings.h>
#if defined(WOLFSSL_DTLS_CID)
#include <wolfssl/error-ssl.h>
#include <wolfssl/internal.h>
#include <wolfssl/ssl.h>
typedef struct ConnectionID {
byte length;
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;
ret = (ConnectionID*)XMALLOC(sizeof(ConnectionID) + size, heap,
DYNAMIC_TYPE_TLSX);
if (ret == NULL)
return NULL;
ret->length = size;
XMEMCPY(ret->id, cid, size);
return ret;
}
static WC_INLINE CIDInfo* DtlsCidGetInfo(WOLFSSL* ssl)
{
return ssl->dtlsCidInfo;
}
static int DtlsCidGetSize(WOLFSSL* ssl, unsigned int* size, int rx)
{
ConnectionID* id;
CIDInfo* info;
if (ssl == NULL || size == NULL)
return BAD_FUNC_ARG;
info = DtlsCidGetInfo(ssl);
if (info == NULL)
return WOLFSSL_FAILURE;
id = rx ? info->rx : info->tx;
if (id == NULL) {
*size = 0;
return WOLFSSL_SUCCESS;
}
*size = id->length;
return WOLFSSL_SUCCESS;
}
static int DtlsCidGet(WOLFSSL* ssl, unsigned char* buf, int bufferSz, int rx)
{
ConnectionID* id;
CIDInfo* info;
if (ssl == NULL || buf == NULL)
return BAD_FUNC_ARG;
info = DtlsCidGetInfo(ssl);
if (info == NULL)
return WOLFSSL_FAILURE;
id = rx ? info->rx : info->tx;
if (id == NULL || id->length == 0)
return WOLFSSL_SUCCESS;
if (id->length > bufferSz)
return LENGTH_ERROR;
XMEMCPY(buf, id->id, id->length);
return WOLFSSL_SUCCESS;
}
static CIDInfo* DtlsCidGetInfoFromExt(byte* ext)
{
WOLFSSL** sslPtr;
WOLFSSL* ssl;
if (ext == NULL)
return NULL;
sslPtr = (WOLFSSL**)ext;
ssl = *sslPtr;
if (ssl == NULL)
return NULL;
return ssl->dtlsCidInfo;
}
static void DtlsCidUnsetInfoFromExt(byte* ext)
{
WOLFSSL** sslPtr;
WOLFSSL* ssl;
if (ext == NULL)
return;
sslPtr = (WOLFSSL**)ext;
ssl = *sslPtr;
if (ssl == NULL)
return;
ssl->dtlsCidInfo = NULL;
}
void TLSX_ConnectionID_Free(byte* ext, void* heap)
{
CIDInfo* info;
(void)heap;
info = DtlsCidGetInfoFromExt(ext);
if (info == NULL)
return;
if (info->rx != NULL)
XFREE(info->rx, heap, DYNAMIC_TYPE_TLSX);
if (info->tx != NULL)
XFREE(info->tx, heap, DYNAMIC_TYPE_TLSX);
XFREE(info, heap, DYNAMIC_TYPE_TLSX);
DtlsCidUnsetInfoFromExt(ext);
XFREE(ext, heap, DYANMIC_TYPE_TLSX);
}
word16 TLSX_ConnectionID_Write(byte* ext, byte* output)
{
CIDInfo* info;
info = DtlsCidGetInfoFromExt(ext);
if (info == NULL)
return 0;
/* empty CID */
if (info->rx == NULL) {
*output = 0;
return OPAQUE8_LEN;
}
*output = info->rx->length;
XMEMCPY(output + OPAQUE8_LEN, info->rx->id, info->rx->length);
return OPAQUE8_LEN + info->rx->length;
}
word16 TLSX_ConnectionID_GetSize(byte* ext)
{
CIDInfo* info = DtlsCidGetInfoFromExt(ext);
if (info == NULL)
return 0;
return info->rx == NULL ? OPAQUE8_LEN : OPAQUE8_LEN + info->rx->length;
}
int TLSX_ConnectionID_Use(WOLFSSL* ssl)
{
CIDInfo* info;
WOLFSSL** ext;
int ret;
ext = (WOLFSSL**)TLSX_Find(ssl->extensions, TLSX_CONNECTION_ID);
if (ext != NULL)
return 0;
info = (CIDInfo*)XMALLOC(sizeof(CIDInfo), ssl->heap, DYNAMIC_TYPE_TLSX);
if (info == NULL)
return MEMORY_ERROR;
ext = (WOLFSSL**)XMALLOC(sizeof(WOLFSSL**), ssl->heap, DYNAMIC_TYPE_TLSX);
if (ext == NULL) {
XFREE(info, ssl->heap, DYNAMIC_TYPE_TLSX);
return MEMORY_ERROR;
}
XMEMSET(info, 0, sizeof(CIDInfo));
/* CIDInfo needs to be accessed every time we send or receive a record. To
* avoid the cost of the extension lookup save a pointer to the structure
* inside the SSL object itself, and save a pointer to the SSL object in the
* extension. The extension freeing routine uses te pointer to the SSL
* object to find the structure and to set ssl->dtlsCidInfo pointer to NULL
* after freeing the structure. */
ssl->dtlsCidInfo = info;
*ext = ssl;
ret =
TLSX_Push(&ssl->extensions, TLSX_CONNECTION_ID, (void*)ext, ssl->heap);
if (ret != 0) {
XFREE(info, ssl->heap, DYNAMIC_TYPE_TLSX);
XFREE(ext, ssl->heap, DYNAMIC_TYPE_TLSX);
ssl->dtlsCidInfo = NULL;
return ret;
}
return 0;
}
int TLSX_ConnectionID_Parse(WOLFSSL* ssl, const byte* input, word16 length,
byte isRequest)
{
ConnectionID* id;
CIDInfo* info;
byte cidSize;
TLSX* ext;
ext = TLSX_Find(ssl->extensions, TLSX_CONNECTION_ID);
if (ext == NULL) {
/* CID not enabled */
if (isRequest) {
WOLFSSL_MSG("Received CID ext but it's not enabled, ignoring");
return 0;
}
else {
WOLFSSL_MSG("CID ext not requested by the Client, aborting");
return UNSUPPORTED_EXTENSION;
}
}
info = DtlsCidGetInfo(ssl);
if (info == NULL || info->tx != NULL)
return BAD_STATE_E;
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);
if (id == NULL)
return MEMORY_ERROR;
XMEMCPY(id->id, input + OPAQUE8_LEN, cidSize);
id->length = cidSize;
info->tx = id;
}
info->negotiated = 1;
if (isRequest)
ext->resp = 1;
return 0;
}
void DtlsCIDOnExtensionsParsed(WOLFSSL* ssl)
{
CIDInfo* info;
info = DtlsCidGetInfo(ssl);
if (info == NULL)
return;
if (!info->negotiated) {
TLSX_Remove(&ssl->extensions, TLSX_CONNECTION_ID, ssl->heap);
return;
}
}
byte DtlsCIDCheck(WOLFSSL* ssl, const byte* input, word16 inputSize)
{
CIDInfo* info;
info = DtlsCidGetInfo(ssl);
if (info == NULL || info->rx == NULL || info->rx->length == 0)
return 0;
if (inputSize < info->rx->length)
return 0;
return XMEMCMP(input, info->rx->id, info->rx->length) == 0;
}
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)
return ret;
return WOLFSSL_SUCCESS;
}
int wolfSSL_dtls_cid_is_enabled(WOLFSSL* ssl)
{
return DtlsCidGetInfo(ssl) != NULL;
}
int wolfSSL_dtls_cid_set(WOLFSSL* ssl, unsigned char* cid, unsigned int size)
{
ConnectionID* newCid;
CIDInfo* cidInfo;
if (!ssl->options.useDtlsCID)
return WOLFSSL_FAILURE;
cidInfo = DtlsCidGetInfo(ssl);
if (cidInfo == NULL)
return WOLFSSL_FAILURE;
if (cidInfo->rx != NULL) {
XFREE(cidInfo->rx, ssl->heap, DYNAMIC_TYPE_TLSX);
cidInfo->rx = NULL;
}
/* empty CID */
if (size == 0)
return WOLFSSL_SUCCESS;
if (size > DTLS_CID_MAX_SIZE)
return LENGTH_ERROR;
newCid = DtlsCidNew(cid, (byte)size, ssl->heap);
if (newCid == NULL)
return MEMORY_ERROR;
cidInfo->rx = newCid;
return WOLFSSL_SUCCESS;
}
int wolfSSL_dtls_cid_get_rx_size(WOLFSSL* ssl, unsigned int* size)
{
return DtlsCidGetSize(ssl, size, 1);
}
int wolfSSL_dtls_cid_get_rx(WOLFSSL* ssl, unsigned char* buf,
unsigned int bufferSz)
{
return DtlsCidGet(ssl, buf, bufferSz, 1);
}
int wolfSSL_dtls_cid_get_tx_size(WOLFSSL* ssl, unsigned int* size)
{
return DtlsCidGetSize(ssl, size, 0);
}
int wolfSSL_dtls_cid_get_tx(WOLFSSL* ssl, unsigned char* buf,
unsigned int bufferSz)
{
return DtlsCidGet(ssl, buf, bufferSz, 0);
}
#endif /* WOLFSSL_DTLS_CID */

View File

@ -88,28 +88,6 @@ typedef struct Dtls13RecordPlaintextHeader {
byte length[2];
} Dtls13RecordPlaintextHeader;
/**
* struct Dtls13RecordCiphertextHeader: represent the header of protected
* DTLSv1.3 used in wolfSSL
* @unifiedHdrflags: the first three bits are always 001, then CID bit: if
* setted the header contains a CID, S bit: if setted the header contains the 16
* LSBs of sequence number length, otherwise only the 8 LSBs are present, then
* the L bit: if present the length of the record is present, lastly EE: the
* last two bits of the epoch
* @sequenceNumber: 16 LSBs of the sequence number
* @length: length of the record
*
* DTLSv1.3 uses a variable length header, this struct represent only the
* representation used by wolfSSL, where CID is never present (not supported),
* the 16 LSBs of the sequence number and the length are always present.
*/
typedef struct Dtls13RecordCiphertextHeader {
/* 0 0 1 C S L E E */
byte unifiedHdrFlags;
byte sequenceNumber[2];
byte length[2];
} Dtls13RecordCiphertextHeader;
/* size of the len field in the unified header */
#define DTLS13_LEN_SIZE 2
/* size of the mask used to encrypt/decrypt Record Number */
@ -484,7 +462,7 @@ static int Dtls13SendFragment(WOLFSSL* ssl, byte* output, word16 output_size,
return BUFFER_ERROR;
isProtected = Dtls13TypeIsEncrypted(handshakeType);
recordHeaderLength = Dtls13GetRlHeaderLength(isProtected);
recordHeaderLength = Dtls13GetRlHeaderLength(ssl, isProtected);
if (length <= recordHeaderLength)
return BUFFER_ERROR;
@ -829,7 +807,7 @@ static int Dtls13SendOneFragmentRtx(WOLFSSL* ssl,
int ret;
isProtected = Dtls13TypeIsEncrypted(handshakeType);
recordHeaderLength = Dtls13GetRlHeaderLength(isProtected);
recordHeaderLength = Dtls13GetRlHeaderLength(ssl, isProtected);
rtxRecord = Dtls13RtxNewRecord(ssl, message + recordHeaderLength,
(word16)(length - recordHeaderLength), handshakeType,
@ -860,7 +838,7 @@ static int Dtls13SendFragmentedInternal(WOLFSSL* ssl)
isEncrypted = Dtls13TypeIsEncrypted(
(enum HandShakeType)ssl->dtls13FragHandshakeType);
rlHeaderLength = Dtls13GetRlHeaderLength(isEncrypted);
rlHeaderLength = Dtls13GetRlHeaderLength(ssl, isEncrypted);
maxFragment = wolfSSL_GetMaxFragSize(ssl, MAX_RECORD_SIZE);
remainingSize = ssl->dtls13MessageLength - ssl->dtls13FragOffset;
@ -933,7 +911,7 @@ static int Dtls13SendFragmented(WOLFSSL* ssl, byte* message, word16 length,
}
isEncrypted = Dtls13TypeIsEncrypted(handshake_type);
rlHeaderLength = Dtls13GetRlHeaderLength(isEncrypted);
rlHeaderLength = Dtls13GetRlHeaderLength(ssl, isEncrypted);
if (length < rlHeaderLength)
return INCOMPLETE_DATA;
@ -970,6 +948,96 @@ static WC_INLINE word8 Dtls13GetEpochBits(w64wrapper epoch)
return w64GetLow32(epoch) & EE_MASK;
}
#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;
int ret;
if (!wolfSSL_dtls_cid_is_enabled(ssl))
return 0;
cidSize = Dtls13GetCidTxSize(ssl);
/* no cid */
if (cidSize == 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);
if (ret != WOLFSSL_SUCCESS)
return ret;
*idx += cidSize;
return 0;
}
static int Dtls13UnifiedHeaderParseCID(WOLFSSL* ssl, byte flags,
const byte* input, word16 inputSize, word16* idx)
{
unsigned int _cidSz;
int ret;
if (flags & DTLS13_CID_BIT) {
if (!wolfSSL_dtls_cid_is_enabled(ssl)) {
WOLFSSL_MSG("CID while no negotiated CID, ignoring");
return DTLS_CID_ERROR;
}
if (!DtlsCIDCheck(ssl, input + *idx, inputSize - *idx)) {
WOLFSSL_MSG("Not matching or wrong CID, ignoring");
return DTLS_CID_ERROR;
}
ret = wolfSSL_dtls_cid_get_rx_size(ssl, &_cidSz);
if (ret != WOLFSSL_SUCCESS)
return ret;
*idx += _cidSz;
return 0;
}
/* CID not present */
if (wolfSSL_dtls_cid_is_enabled(ssl)) {
ret = wolfSSL_dtls_cid_get_rx_size(ssl, &_cidSz);
if (ret != WOLFSSL_SUCCESS)
return ret;
if (_cidSz != 0) {
WOLFSSL_MSG("expecting CID, ignoring");
return DTLS_CID_ERROR;
}
}
return 0;
}
#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 */
/**
* dtls13RlAddCiphertextHeader() - add record layer header in the buffer
* @ssl: ssl object
@ -978,8 +1046,9 @@ static WC_INLINE word8 Dtls13GetEpochBits(w64wrapper epoch)
*/
int Dtls13RlAddCiphertextHeader(WOLFSSL* ssl, byte* out, word16 length)
{
Dtls13RecordCiphertextHeader* hdr;
word16 seqNumber;
word16 seqNumber, idx;
byte* flags;
int ret;
if (out == NULL)
return BAD_FUNC_ARG;
@ -987,20 +1056,27 @@ int Dtls13RlAddCiphertextHeader(WOLFSSL* ssl, byte* out, word16 length)
if (ssl->dtls13EncryptEpoch == NULL)
return BAD_STATE_E;
hdr = (Dtls13RecordCiphertextHeader*)out;
flags = out;
hdr->unifiedHdrFlags = DTLS13_FIXED_BITS;
hdr->unifiedHdrFlags |=
Dtls13GetEpochBits(ssl->dtls13EncryptEpoch->epochNumber);
/* header fixed bits */
*flags = DTLS13_FIXED_BITS;
/* epoch bits */
*flags |= Dtls13GetEpochBits(ssl->dtls13EncryptEpoch->epochNumber);
idx = DTLS13_HDR_FLAGS_SIZE;
ret = Dtls13AddCID(ssl, flags, out, &idx);
if (ret != 0)
return ret;
/* include 16-bit seq */
hdr->unifiedHdrFlags |= DTLS13_SEQ_LEN_BIT;
*flags |= DTLS13_SEQ_LEN_BIT;
/* include 16-bit length */
hdr->unifiedHdrFlags |= DTLS13_LEN_BIT;
*flags |= DTLS13_LEN_BIT;
seqNumber = (word16)w64GetLow32(ssl->dtls13EncryptEpoch->nextSeqNumber);
c16toa(seqNumber, hdr->sequenceNumber);
c16toa(length, hdr->length);
c16toa(seqNumber, out + idx);
idx += OPAQUE16_LEN;
c16toa(length, out + idx);
return 0;
}
@ -1041,19 +1117,21 @@ int Dtls13EncryptRecordNumber(WOLFSSL* ssl, byte* hdr, word16 recordLength)
{
int seqLength;
int hdrLength;
int cidSz;
if (ssl == NULL || hdr == NULL)
return BAD_FUNC_ARG;
/* we need at least a 16 bytes of ciphertext to encrypt record number see
4.2.3*/
if (recordLength < Dtls13GetRlHeaderLength(1) + DTLS13_MIN_CIPHERTEXT)
if (recordLength < Dtls13GetRlHeaderLength(ssl, 1) + DTLS13_MIN_CIPHERTEXT)
return BUFFER_ERROR;
seqLength = (*hdr & DTLS13_LEN_BIT) ? DTLS13_SEQ_16_LEN : DTLS13_SEQ_8_LEN;
/* header flags + seq number */
hdrLength = 1 + seqLength;
cidSz = Dtls13GetCidTxSize(ssl);
/* header flags + seq number + CID size*/
hdrLength = OPAQUE8_LEN + seqLength + cidSz;
/* length present */
if (*hdr & DTLS13_LEN_BIT)
@ -1061,7 +1139,7 @@ int Dtls13EncryptRecordNumber(WOLFSSL* ssl, byte* hdr, word16 recordLength)
return Dtls13EncryptDecryptRecordNumber(ssl,
/* seq number offset */
hdr + 1,
hdr + OPAQUE8_LEN + cidSz,
/* seq size */
seqLength,
/* cipher text */
@ -1075,27 +1153,28 @@ int Dtls13EncryptRecordNumber(WOLFSSL* ssl, byte* hdr, word16 recordLength)
*
* returns the length of the record layer header in bytes.
*/
word16 Dtls13GetRlHeaderLength(byte isEncrypted)
word16 Dtls13GetRlHeaderLength(WOLFSSL* ssl, byte isEncrypted)
{
/* the function looks useless but allow to support variable length unified
header in the future */
(void)ssl;
if (!isEncrypted)
return DTLS_RECORD_HEADER_SZ;
return DTLS13_UNIFIED_HEADER_SIZE;
return DTLS13_UNIFIED_HEADER_SIZE + Dtls13GetCidTxSize(ssl);
}
/**
* Dtls13GetHeadersLength() - return length of record + handshake header
* @ssl: ssl oject
* @type: type of handshake in the message
*/
word16 Dtls13GetHeadersLength(enum HandShakeType type)
word16 Dtls13GetHeadersLength(WOLFSSL* ssl, enum HandShakeType type)
{
byte isEncrypted;
isEncrypted = Dtls13TypeIsEncrypted(type);
return Dtls13GetRlHeaderLength(isEncrypted) + DTLS_HANDSHAKE_HEADER_SZ;
return Dtls13GetRlHeaderLength(ssl, isEncrypted) + DTLS_HANDSHAKE_HEADER_SZ;
}
/**
@ -1200,18 +1279,15 @@ int Dtls13ReconstructEpochNumber(WOLFSSL* ssl, byte epochBits,
return SEQUENCE_ERROR;
}
int Dtls13GetUnifiedHeaderSize(const byte input, word16* size)
int Dtls13GetUnifiedHeaderSize(WOLFSSL* ssl, const byte input, word16* size)
{
(void)ssl;
if (size == NULL)
return BAD_FUNC_ARG;
if (input & DTLS13_CID_BIT) {
WOLFSSL_MSG("DTLS1.3 header with connection ID. Not supported");
return WOLFSSL_NOT_IMPLEMENTED;
}
/* flags (1) + seq 8bit (1) */
*size = OPAQUE8_LEN + OPAQUE8_LEN;
/* flags (1) + CID + seq 8bit (1) */
*size = OPAQUE8_LEN + Dtls13GetCidRxSize(ssl) + OPAQUE8_LEN;
if (input & DTLS13_SEQ_LEN_BIT)
*size += OPAQUE8_LEN;
if (input & DTLS13_LEN_BIT)
@ -1237,23 +1313,24 @@ int Dtls13ParseUnifiedRecordLayer(WOLFSSL* ssl, const byte* input,
{
byte seqLen, hasLength;
byte* seqNum;
byte flags;
word16 idx;
int ret;
if (input == NULL || inputSize == 0)
if (input == NULL || inputSize < DTLS13_HDR_FLAGS_SIZE)
return BAD_FUNC_ARG;
if (*input & DTLS13_CID_BIT) {
WOLFSSL_MSG("DTLS1.3 header with connection ID. Not supported");
return WOLFSSL_NOT_IMPLEMENTED;
}
flags = *input;
idx = DTLS13_HDR_FLAGS_SIZE;
ret = Dtls13UnifiedHeaderParseCID(ssl, flags, input, inputSize, &idx);
if (ret != 0)
return ret;
seqLen = (*input & DTLS13_SEQ_LEN_BIT) != 0 ? DTLS13_SEQ_16_LEN
: DTLS13_SEQ_8_LEN;
hasLength = *input & DTLS13_LEN_BIT;
hdrInfo->epochBits = *input & EE_MASK;
seqNum = (byte*)input + idx;
seqLen = (flags & DTLS13_SEQ_LEN_BIT) != 0 ? DTLS13_SEQ_16_LEN
: DTLS13_SEQ_8_LEN;
hasLength = flags & DTLS13_LEN_BIT;
hdrInfo->epochBits = flags & EE_MASK;
idx += seqLen;
@ -1278,8 +1355,6 @@ int Dtls13ParseUnifiedRecordLayer(WOLFSSL* ssl, const byte* input,
if (hdrInfo->recordLength < DTLS13_RN_MASK_SIZE)
return LENGTH_ERROR;
seqNum = (byte*)(input + DTLS13_HDR_FLAGS_SIZE);
ret = Dtls13EncryptDecryptRecordNumber(ssl, seqNum, seqLen, input + idx,
DEPROTECT);
if (ret != 0)
@ -1356,7 +1431,7 @@ static int Dtls13RtxSendBuffered(WOLFSSL* ssl)
isLast = r->next == NULL;
WOLFSSL_MSG("Dtls13Rtx One Record");
headerLength = Dtls13GetRlHeaderLength(!w64IsZero(r->epoch));
headerLength = Dtls13GetRlHeaderLength(ssl, !w64IsZero(r->epoch));
sendSz = r->length + headerLength;
@ -1569,7 +1644,7 @@ int Dtls13AddHeaders(byte* output, word32 length, enum HandShakeType hsType,
int isEncrypted;
isEncrypted = Dtls13TypeIsEncrypted(hsType);
handshakeOffset = Dtls13GetRlHeaderLength(isEncrypted);
handshakeOffset = Dtls13GetRlHeaderLength(ssl, isEncrypted);
/* The record header is placed by either Dtls13HandshakeSend() or
BuildTls13Message() */
@ -2126,10 +2201,9 @@ static int Dtls13WriteAckMessage(WOLFSSL* ssl,
if (w64IsZero(ssl->dtls13EncryptEpoch->epochNumber)) {
/* unprotected ACK */
headerLength = DTLS_RECORD_HEADER_SZ;
;
}
else {
headerLength = Dtls13GetRlHeaderLength(1);
headerLength = Dtls13GetRlHeaderLength(ssl, 1);
sendSz += MAX_MSG_EXTRA;
}
@ -2438,7 +2512,7 @@ int SendDtls13Ack(WOLFSSL* ssl)
outputSize = ssl->buffers.outputBuffer.bufferSize -
ssl->buffers.outputBuffer.length;
headerSize = Dtls13GetRlHeaderLength(1);
headerSize = Dtls13GetRlHeaderLength(ssl, 1);
ret = BuildTls13Message(ssl, output, outputSize, output + headerSize,
length, ack, 0, 0, 0);

View File

@ -704,6 +704,10 @@ if BUILD_QUIC
src_libwolfssl_la_SOURCES += src/quic.c
endif
if BUILD_DTLS_CID
src_libwolfssl_la_SOURCES += src/dtls.c
endif
endif !BUILD_CRYPTONLY

View File

@ -7911,7 +7911,8 @@ void FreeHandshakeResources(WOLFSSL* ssl)
#endif /* HAVE_PK_CALLBACKS */
#if defined(HAVE_TLS_EXTENSIONS) && !defined(HAVE_SNI) && \
!defined(NO_TLS) && !defined(HAVE_ALPN) && !defined(WOLFSSL_POST_HANDSHAKE_AUTH)
!defined(NO_TLS) && !defined(HAVE_ALPN) && !defined(WOLFSSL_POST_HANDSHAKE_AUTH) && \
!defined(WOLFSSL_DTLS_CID)
/* Some extensions need to be kept for post-handshake querying. */
TLSX_FreeAll(ssl->extensions, ssl->heap);
ssl->extensions = NULL;
@ -9103,7 +9104,7 @@ int HashOutput(WOLFSSL* ssl, const byte* output, int sz, int ivSz)
if (IsAtLeastTLSv1_3(ssl->version)) {
#ifdef WOLFSSL_DTLS13
word16 dtls_record_extra;
dtls_record_extra = Dtls13GetRlHeaderLength(IsEncryptionOn(ssl, 1));
dtls_record_extra = Dtls13GetRlHeaderLength(ssl, IsEncryptionOn(ssl, 1));
dtls_record_extra -= RECORD_HEADER_SZ;
adj += dtls_record_extra;
@ -9947,7 +9948,7 @@ static int GetDtls13RecordHeader(WOLFSSL* ssl, const byte* input,
return SEQUENCE_ERROR;
}
ret = Dtls13GetUnifiedHeaderSize(
ret = Dtls13GetUnifiedHeaderSize(ssl,
*(input+*inOutIdx), &ssl->dtls13CurRlLength);
if (ret != 0)
return ret;
@ -10018,7 +10019,7 @@ static int GetDtlsRecordHeader(WOLFSSL* ssl, const byte* input,
/* version 1.3 already negotiated */
if (ssl->options.tls1_3) {
ret = GetDtls13RecordHeader(ssl, input, inOutIdx, rh, size);
if (ret == 0 || ret != SEQUENCE_ERROR)
if (ret == 0 || ret != SEQUENCE_ERROR || ret != DTLS_CID_ERROR)
return ret;
}
@ -18777,8 +18778,9 @@ int ProcessReplyEx(WOLFSSL* ssl, int allowSocketErr)
&ssl->curRL, &ssl->curSize);
#ifdef WOLFSSL_DTLS
if (ssl->options.dtls && ret == SEQUENCE_ERROR) {
WOLFSSL_MSG("Silently dropping out of order DTLS message");
if (ssl->options.dtls &&
(ret == SEQUENCE_ERROR || ret == DTLS_CID_ERROR)) {
WOLFSSL_MSG("Silently dropping DTLS message");
ssl->options.processReply = doProcessInit;
ssl->buffers.inputBuffer.length = 0;
ssl->buffers.inputBuffer.idx = 0;
@ -22846,6 +22848,8 @@ const char* wolfSSL_ERR_reason_error_string(unsigned long e)
case QUIC_TP_MISSING_E:
return "QUIC transport parameter not set";
#endif
case DTLS_CID_ERROR:
return "DTLS ConnectionID mismatch or missing";
default :
return "unknown error number";
@ -32705,6 +32709,11 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
*inOutIdx = begin + helloSz; /* skip extensions */
}
#ifdef WOLFSSL_DTLS_CID
if (ssl->options.useDtlsCID)
DtlsCIDOnExtensionsParsed(ssl);
#endif /* WOLFSSL_DTLS_CID */
ssl->options.clientState = CLIENT_HELLO_COMPLETE;
ssl->options.haveSessionId = 1;

View File

@ -10487,6 +10487,18 @@ static int TLSX_QuicTP_Parse(WOLFSSL *ssl, const byte *input, size_t len, int ex
#endif /* WOLFSSL_QUIC */
#if defined(WOLFSSL_DTLS_CID)
#define CID_GET_SIZE TLSX_ConnectionID_GetSize
#define CID_WRITE TLSX_ConnectionID_Write
#define CID_PARSE TLSX_ConnectionID_Parse
#define CID_FREE TLSX_ConnectionID_Free
#else
#define CID_GET_SIZE(a) 0
#define CID_WRITE(a, b) 0
#define CID_PARSE(a, b, c, d) 0
#define CID_FREE(a, b) 0
#endif /* defined(WOLFSSL_DTLS_CID) */
/******************************************************************************/
/* TLS Extensions Framework */
/******************************************************************************/
@ -10637,6 +10649,12 @@ void TLSX_FreeAll(TLSX* list, void* heap)
break;
#endif
#ifdef WOLFSSL_DTLS_CID
case TLSX_CONNECTION_ID:
CID_FREE((byte*)extension->data, heap);
break;
#endif /* WOLFSSL_DTLS_CID */
default:
break;
}
@ -10800,6 +10818,11 @@ static int TLSX_GetSize(TLSX* list, byte* semaphore, byte msgType,
length += QTP_GET_SIZE(extension);
break;
#endif
#ifdef WOLFSSL_DTLS_CID
case TLSX_CONNECTION_ID:
length += CID_GET_SIZE((byte*)extension->data);
break;
#endif /* WOLFSSL_DTLS_CID */
default:
break;
}
@ -10997,6 +11020,12 @@ static int TLSX_Write(TLSX* list, byte* output, byte* semaphore,
output + offset);
break;
#endif
#ifdef WOLFSSL_DTLS_CID
case TLSX_CONNECTION_ID:
offset += CID_WRITE((byte*)extension->data, output+offset);
break;
#endif /* WOLFSSL_DTLS_CID */
default:
break;
}
@ -11912,6 +11941,9 @@ 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 /* WOLFSSL_DTLS_CID */
}
#if !defined(WOLFSSL_NO_TLS12) || !defined(NO_OLD_TLS)
else {
@ -11965,6 +11997,9 @@ int TLSX_GetResponseSize(WOLFSSL* ssl, byte msgType, word16* pLength)
#if defined(HAVE_SERVER_RENEGOTIATION_INFO)
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_RENEGOTIATION_INFO));
#endif
#ifdef WOLFSSL_DTLS_CID
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_CONNECTION_ID));
#endif /* WOLFSSL_DTLS_CID */
break;
#ifdef WOLFSSL_EARLY_DATA
@ -12040,6 +12075,9 @@ 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 */
}
#if !defined(WOLFSSL_NO_TLS12) || !defined(NO_OLD_TLS)
else {
@ -12091,6 +12129,9 @@ int TLSX_WriteResponse(WOLFSSL *ssl, byte* output, byte msgType, word16* pOffset
#if defined(HAVE_SERVER_RENEGOTIATION_INFO)
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_RENEGOTIATION_INFO));
#endif
#ifdef WOLFSSL_DTLS_CID
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_CONNECTION_ID));
#endif /* WOLFSSL_DTLS_CID */
break;
#ifdef WOLFSSL_EARLY_DATA
@ -12731,6 +12772,20 @@ int TLSX_Parse(WOLFSSL* ssl, const byte* input, word16 length, byte msgType,
}
break;
#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;
WOLFSSL_MSG("ConnectionID extension received");
ret = CID_PARSE(ssl, input + offset, size, isRequest);
break;
#endif /* defined(WOLFSSL_DTLS_CID) */
default:
WOLFSSL_MSG("Unknown TLS extension type");
}

View File

@ -2591,7 +2591,7 @@ int BuildTls13Message(WOLFSSL* ssl, byte* output, int outSz, const byte* input,
args->headerSz = RECORD_HEADER_SZ;
#ifdef WOLFSSL_DTLS13
if (ssl->options.dtls)
args->headerSz = Dtls13GetRlHeaderLength(1);
args->headerSz = Dtls13GetRlHeaderLength(ssl, 1);
#endif /* WOLFSSL_DTLS13 */
args->sz = args->headerSz + inSz;
@ -3252,8 +3252,8 @@ static int WritePSKBinders(WOLFSSL* ssl, byte* output, word32 idx)
/* Hash truncated ClientHello - up to binders. */
#ifdef WOLFSSL_DTLS13
if (ssl->options.dtls)
ret = Dtls13HashHandshake(ssl, output + Dtls13GetRlHeaderLength(0),
idx - Dtls13GetRlHeaderLength(0));
ret = Dtls13HashHandshake(ssl, output + Dtls13GetRlHeaderLength(ssl, 0),
idx - Dtls13GetRlHeaderLength(ssl, 0));
else
#endif /* WOLFSSL_DTLS13 */
ret = HashOutput(ssl, output, idx, 0);
@ -3659,11 +3659,11 @@ int SendTls13ClientHello(WOLFSSL* ssl)
#endif
{
#ifdef WOLFSSL_DTLS13
if (ssl->options.dtls)
ret = Dtls13HashHandshake(ssl,
args->output + Dtls13GetRlHeaderLength(0),
args->idx - Dtls13GetRlHeaderLength(0));
else
if (ssl->options.dtls)
ret = Dtls13HashHandshake(ssl,
args->output + Dtls13GetRlHeaderLength(ssl, 0),
args->idx - Dtls13GetRlHeaderLength(ssl, 0));
else
#endif /* WOLFSSL_DTLS13 */
ret = HashOutput(ssl, args->output, args->idx, 0);
}
@ -4081,6 +4081,11 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
args->idx += args->totalExtSz;
}
#ifdef WOLFSSL_DTLS_CID
if (ssl->options.useDtlsCID)
DtlsCIDOnExtensionsParsed(ssl);
#endif /* WOLFSSL_DTLS_CID */
*inOutIdx = args->idx;
ssl->options.serverState = SERVER_HELLO_COMPLETE;
@ -5513,6 +5518,11 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
goto exit_dch;
}
#ifdef WOLFSSL_DTLS_CID
if (ssl->options.useDtlsCID)
DtlsCIDOnExtensionsParsed(ssl);
#endif /* WOLFSSL_DTLS_CID */
#ifdef HAVE_SNI
if ((ret = SNI_Callback(ssl)) != 0)
return ret;
@ -5841,8 +5851,8 @@ int SendTls13ServerHello(WOLFSSL* ssl, byte extMsgType)
#ifdef WOLFSSL_DTLS13
if (ssl->options.dtls) {
ret = Dtls13HashHandshake(ssl,
output + Dtls13GetRlHeaderLength(0) ,
sendSz - Dtls13GetRlHeaderLength(0));
output + Dtls13GetRlHeaderLength(ssl, 0) ,
sendSz - Dtls13GetRlHeaderLength(ssl, 0));
}
else
#endif /* WOLFSSL_DTLS13 */
@ -5913,7 +5923,7 @@ static int SendTls13EncryptedExtensions(WOLFSSL* ssl)
#ifdef WOLFSSL_DTLS13
if (ssl->options.dtls) {
idx = Dtls13GetHeadersLength(encrypted_extensions);
idx = Dtls13GetHeadersLength(ssl, encrypted_extensions);
}
else
#endif /* WOLFSSL_DTLS13 */
@ -6081,7 +6091,7 @@ static int SendTls13CertificateRequest(WOLFSSL* ssl, byte* reqCtx,
i = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
#ifdef WOLFSSL_DTLS13
if (ssl->options.dtls)
i = Dtls13GetRlHeaderLength(1) + DTLS_HANDSHAKE_HEADER_SZ;
i = Dtls13GetRlHeaderLength(ssl, 1) + DTLS_HANDSHAKE_HEADER_SZ;
#endif /* WOLFSSL_DTLS13 */
reqSz = (word16)(OPAQUE8_LEN + reqCtxLen);
@ -6810,7 +6820,7 @@ static int SendTls13Certificate(WOLFSSL* ssl)
#ifdef WOLFSSL_DTLS13
if (ssl->options.dtls) {
i = Dtls13GetRlHeaderLength(1);
i = Dtls13GetRlHeaderLength(ssl, 1);
sendSz = (int)i;
}
#endif /* WOLFSSL_DTLS13 */
@ -7051,7 +7061,7 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl)
#ifdef WOLFSSL_DTLS13
/* can be negative */
if (ssl->options.dtls)
recordLayerHdrExtra = Dtls13GetRlHeaderLength(1) - RECORD_HEADER_SZ;
recordLayerHdrExtra = Dtls13GetRlHeaderLength(ssl, 1) - RECORD_HEADER_SZ;
else
recordLayerHdrExtra = 0;
@ -8325,7 +8335,7 @@ static int SendTls13Finished(WOLFSSL* ssl)
#ifdef WOLFSSL_DTLS13
if (isDtls)
input = output + Dtls13GetRlHeaderLength(1);
input = output + Dtls13GetRlHeaderLength(ssl, 1);
#endif /* WOLFSSL_DTLS13 */
AddTls13HandShakeHeader(input, finishedSz, 0, finishedSz, finished, ssl);
@ -8384,7 +8394,8 @@ static int SendTls13Finished(WOLFSSL* ssl)
#ifdef WOLFSSL_DTLS13
if (isDtls) {
dtlsRet = Dtls13HandshakeSend(ssl, output, outputSz,
Dtls13GetRlHeaderLength(1) + headerSz + finishedSz, finished, 1);
Dtls13GetRlHeaderLength(ssl, 1) + headerSz + finishedSz, finished,
1);
if (dtlsRet != 0 && dtlsRet != WANT_WRITE)
return ret;
@ -8562,7 +8573,7 @@ static int SendTls13KeyUpdate(WOLFSSL* ssl)
#ifdef WOLFSSL_DTLS13
if (ssl->options.dtls)
i = Dtls13GetRlHeaderLength(1) + DTLS_HANDSHAKE_HEADER_SZ;
i = Dtls13GetRlHeaderLength(ssl, 1) + DTLS_HANDSHAKE_HEADER_SZ;
#endif /* WOLFSSL_DTLS13 */
outputSz = OPAQUE8_LEN + MAX_MSG_EXTRA;
@ -8577,7 +8588,7 @@ static int SendTls13KeyUpdate(WOLFSSL* ssl)
#ifdef WOLFSSL_DTLS13
if (ssl->options.dtls)
input = output + Dtls13GetRlHeaderLength(1);
input = output + Dtls13GetRlHeaderLength(ssl, 1);
#endif /* WOLFSSL_DTLS13 */
AddTls13Headers(output, OPAQUE8_LEN, key_update, ssl);
@ -8595,7 +8606,8 @@ static int SendTls13KeyUpdate(WOLFSSL* ssl)
#ifdef WOLFSSL_DTLS13
if (ssl->options.dtls) {
ret = Dtls13HandshakeSend(ssl, output, outputSz,
OPAQUE8_LEN + Dtls13GetRlHeaderLength(1) + DTLS_HANDSHAKE_HEADER_SZ,
OPAQUE8_LEN + Dtls13GetRlHeaderLength(ssl, 1) +
DTLS_HANDSHAKE_HEADER_SZ,
key_update, 0);
}
else
@ -9083,7 +9095,7 @@ static int SendTls13NewSessionTicket(WOLFSSL* ssl)
#ifdef WOLFSSL_DTLS13
if (ssl->options.dtls)
idx = Dtls13GetRlHeaderLength(1) + DTLS_HANDSHAKE_HEADER_SZ;
idx = Dtls13GetRlHeaderLength(ssl, 1) + DTLS_HANDSHAKE_HEADER_SZ;
#endif /* WOLFSSL_DTLS13 */
#ifdef WOLFSSL_TLS13_TICKET_BEFORE_FINISHED

View File

@ -159,6 +159,10 @@
RelativePath=".\src\dtls13.c"
>
</File>
<File
RelativePath=".\src\dtls.c"
>
</File>
<File
RelativePath=".\src\internal.c"
>

View File

@ -278,6 +278,7 @@
<ItemGroup>
<ClCompile Include="src\crl.c" />
<ClCompile Include="src\dtls13.c" />
<ClCompile Include="src\dtls.c" />
<ClCompile Include="src\internal.c" />
<ClCompile Include="src\wolfio.c" />
<ClCompile Include="src\keys.c" />

View File

@ -179,6 +179,7 @@ enum wolfSSL_ErrorCodes {
QUIC_TP_MISSING_E = -452, /* QUIC transport parameter missing */
DILITHIUM_KEY_SIZE_E = -453, /* Wrong key size for Dilithium. */
DTLS_CID_ERROR = -454, /* Wrong or missing CID */
/* add strings to wolfSSL_ERR_reason_error_string in internal.c !!!!! */
/* begin negotiation parameter errors */

View File

@ -1239,6 +1239,22 @@ enum {
#define ENCRYPT_BASE_BITS 4096
#endif
#ifdef WOLFSSL_DTLS_CID
#ifndef DTLS_CID_MAX_SIZE
/* DTLSv1.3 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 2
#endif
#else
#undef DTLS_CID_MAX_SIZE
#define DTLS_CID_MAX_SIZE 0
#endif /* WOLFSSL_DTLS_CID */
#if DTLS_CID_MAX_SIZE > 255
#error "Max size for DTLS CID is 255 bytes"
#endif
enum Misc {
CIPHER_BYTE = 0x00, /* Default ciphers */
ECC_BYTE = 0xC0, /* ECC first cipher suite byte */
@ -1360,7 +1376,8 @@ 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) */
DTLS_UNIFIED_HEADER_MIN_SZ = 2,
DTLS_RECVD_RL_HEADER_MAX_SZ = 5, /* flags + seq_number(2) + length(20) */
/* flags + seq_number(2) + length(2) + CID */
DTLS_RECVD_RL_HEADER_MAX_SZ = 5 + DTLS_CID_MAX_SIZE,
DTLS_RECORD_HEADER_MAX_SZ = 13,
DTLS_HANDSHAKE_EXTRA = 8, /* diff from normal */
DTLS_RECORD_EXTRA = 8, /* diff from normal */
@ -2454,6 +2471,9 @@ typedef enum {
TLSX_SIGNATURE_ALGORITHMS_CERT = 0x0032,
#endif
TLSX_KEY_SHARE = 0x0033,
#if defined(WOLFSSL_DTLS_CID)
TLSX_CONNECTION_ID = 0x0036,
#endif /* defined(WOLFSSL_DTLS_CID) */
#ifdef WOLFSSL_QUIC
TLSX_KEY_QUIC_TP_PARAMS = 0x0039, /* RFC 9001, ch. 8.2 */
#endif
@ -2926,6 +2946,17 @@ enum KeyUpdateRequest {
};
#endif /* WOLFSSL_TLS13 */
#ifdef WOLFSSL_DTLS_CID
WOLFSSL_LOCAL void TLSX_ConnectionID_Free(byte* ext, void* heap);
WOLFSSL_LOCAL word16 TLSX_ConnectionID_Write(byte* ext, byte* output);
WOLFSSL_LOCAL word16 TLSX_ConnectionID_GetSize(byte* ext);
WOLFSSL_LOCAL int TLSX_ConnectionID_Use(WOLFSSL* ssl);
WOLFSSL_LOCAL int TLSX_ConnectionID_Parse(WOLFSSL* ssl, const byte* input,
word16 length, byte isRequest);
WOLFSSL_LOCAL void DtlsCIDOnExtensionsParsed(WOLFSSL* ssl);
WOLFSSL_LOCAL byte DtlsCIDCheck(WOLFSSL* ssl, const byte* input,
word16 inputSize);
#endif /* WOLFSSL_DTLS_CID */
#ifdef OPENSSL_EXTRA
enum SetCBIO {
@ -4090,6 +4121,9 @@ typedef struct Options {
#ifdef WOLFSSL_TLS13
byte oldMinor; /* client preferred version < TLS 1.3 */
#endif
#ifdef WOLFSSL_DTLS_CID
byte useDtlsCID:1;
#endif /* WOLFSSL_DTLS_CID */
} Options;
typedef struct Arrays {
@ -4623,6 +4657,10 @@ typedef struct Dtls13Rtx {
#endif /* WOLFSSL_DTLS13 */
#ifdef WOLFSSL_DTLS_CID
typedef struct CIDInfo CIDInfo;
#endif /* WOLFSSL_DTLS_CID */
/* wolfSSL ssl type */
struct WOLFSSL {
WOLFSSL_CTX* ctx;
@ -4851,6 +4889,10 @@ struct WOLFSSL {
word16 dtls13ClientHelloSz;
#endif /* WOLFSSL_DTLS13 */
#ifdef WOLFSSL_DTLS_CID
CIDInfo *dtlsCidInfo;
#endif /* WOLFSSL_DTLS_CID */
#endif /* WOLFSSL_DTLS */
#ifdef WOLFSSL_CALLBACKS
TimeoutInfo timeoutInfo; /* info saved during handshake */
@ -5650,8 +5692,9 @@ WOLFSSL_LOCAL int Dtls13SetRecordNumberKeys(WOLFSSL* ssl,
WOLFSSL_LOCAL int Dtls13AddHeaders(byte* output, word32 length,
enum HandShakeType hs_type, WOLFSSL* ssl);
WOLFSSL_LOCAL word16 Dtls13GetHeadersLength(enum HandShakeType type);
WOLFSSL_LOCAL word16 Dtls13GetRlHeaderLength(byte is_encrypted);
WOLFSSL_LOCAL word16 Dtls13GetHeadersLength(WOLFSSL *ssl,
enum HandShakeType type);
WOLFSSL_LOCAL word16 Dtls13GetRlHeaderLength(WOLFSSL *ssl, byte is_encrypted);
WOLFSSL_LOCAL int Dtls13RlAddCiphertextHeader(WOLFSSL* ssl, byte* out,
word16 length);
WOLFSSL_LOCAL int Dtls13RlAddPlaintextHeader(WOLFSSL* ssl, byte* out,
@ -5659,7 +5702,8 @@ WOLFSSL_LOCAL int Dtls13RlAddPlaintextHeader(WOLFSSL* ssl, byte* out,
WOLFSSL_LOCAL int Dtls13EncryptRecordNumber(WOLFSSL* ssl, byte* hdr,
word16 recordLength);
WOLFSSL_LOCAL int Dtls13IsUnifiedHeader(byte header_flags);
WOLFSSL_LOCAL int Dtls13GetUnifiedHeaderSize(const byte input, word16* size);
WOLFSSL_LOCAL int Dtls13GetUnifiedHeaderSize(WOLFSSL* ssl, const byte input,
word16* size);
WOLFSSL_LOCAL int Dtls13ParseUnifiedRecordLayer(WOLFSSL* ssl, const byte* input,
word16 input_size, Dtls13UnifiedHdrInfo* hdrInfo);
WOLFSSL_LOCAL int Dtls13HandshakeSend(WOLFSSL* ssl, byte* output,

View File

@ -5108,6 +5108,21 @@ WOLFSSL_API int wolfSSL_CRYPTO_get_ex_new_index(int class_index, long argl, void
WOLFSSL_CRYPTO_EX_free* free_func);
#endif /* HAVE_EX_DATA || WOLFSSL_WPAS_SMALL */
#if defined(WOLFSSL_DTLS_CID)
WOLFSSL_API int wolfSSL_dtls_cid_use(WOLFSSL* ssl);
WOLFSSL_API int wolfSSL_dtls_cid_is_enabled(WOLFSSL* ssl);
WOLFSSL_API int wolfSSL_dtls_cid_set(WOLFSSL* ssl, unsigned char* cid,
unsigned int size);
WOLFSSL_API int wolfSSL_dtls_cid_get_rx_size(WOLFSSL* ssl,
unsigned int* size);
WOLFSSL_API int wolfSSL_dtls_cid_get_rx(WOLFSSL* ssl, unsigned char* buffer,
unsigned int bufferSz);
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);
#endif /* defined(WOLFSSL_DTLS_CID) */
/* */
#define SSL2_VERSION 0x0002
#define SSL3_VERSION 0x0300

View File

@ -2775,6 +2775,10 @@ extern void uITRON4_free(void *p) ;
#error "DTLS v1.3 requires both WOLFSSL_TLS13 and WOLFSSL_DTLS"
#endif
#if defined(WOLFSSL_DTLS_CID) && !defined(WOLFSSL_DTLS13)
#error "ConnectionID is supported for DTLSv1.3 only"
#endif
/* RSA Key Checking is disabled by default unless WOLFSSL_RSA_KEY_CHECK is
* defined or FIPS v2 3389, FIPS v5 or later.
* Not allowed for: