Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement DTLS 1.2 Connection ID (CID) #7995

Merged
merged 4 commits into from
Oct 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/os-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
runs-on: ${{ matrix.os }}
Expand Down
5 changes: 1 addition & 4 deletions examples/client/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
5 changes: 1 addition & 4 deletions examples/server/server.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
107 changes: 65 additions & 42 deletions src/dtls.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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;
}

if (length < OPAQUE8_LEN)
return BUFFER_ERROR;

cidSize = *input;
if (cidSize + OPAQUE8_LEN > length)
return BUFFER_ERROR;
/* Should not be null if negotiated */
if (info->tx == NULL)
return BAD_STATE_E;

if (cidSize > 0) {
id = (ConnectionID*)XMALLOC(sizeof(*id) + cidSize, ssl->heap,
DYNAMIC_TYPE_TLSX);
/* 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;
}
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;
}

Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -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;
SparkiDev marked this conversation as resolved.
Show resolved Hide resolved
}
#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 */
39 changes: 9 additions & 30 deletions src/dtls13.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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 */

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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);
}

/**
Expand Down Expand Up @@ -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)
Expand Down
Loading