mirror of https://github.com/wolfSSL/wolfssl.git
Merge pull request #8224 from julek-wolfssl/dtls-server-demux
DTLS: Add server side stateless and CID QoL APIpull/8312/head
commit
2409971b14
|
@ -78,4 +78,4 @@ jobs:
|
|||
run: |
|
||||
export LD_LIBRARY_PATH=$GITHUB_WORKSPACE/build-dir/lib:$LD_LIBRARY_PATH
|
||||
export SHELL=/bin/bash
|
||||
SOCAT=$GITHUB_WORKSPACE/socat-1.8.0.0/socat ./test.sh -t 0.5 --expect-fail 36,64,146,214,216,217,309,310,386,399,402,403,459,460,467,468,478,492,528,530
|
||||
SOCAT=$GITHUB_WORKSPACE/socat-1.8.0.0/socat ./test.sh -t 0.5 --expect-fail 36,64,146,214,216,217,309,310,386,399,402,403,459,460,467,468,475,478,492,528,530
|
||||
|
|
|
@ -1997,8 +1997,8 @@ const char* wolfSSL_get_cipher_name(WOLFSSL* ssl);
|
|||
/*!
|
||||
\ingroup IO
|
||||
|
||||
\brief This function returns the file descriptor (fd) used as the
|
||||
input/output facility for the SSL connection. Typically this
|
||||
\brief This function returns the read file descriptor (fd) used as the
|
||||
input facility for the SSL connection. Typically this
|
||||
will be a socket file descriptor.
|
||||
|
||||
\return fd If successful the call will return the SSL session file
|
||||
|
@ -2016,9 +2016,38 @@ const char* wolfSSL_get_cipher_name(WOLFSSL* ssl);
|
|||
\endcode
|
||||
|
||||
\sa wolfSSL_set_fd
|
||||
\sa wolfSSL_set_read_fd
|
||||
\sa wolfSSL_set_write_fd
|
||||
*/
|
||||
int wolfSSL_get_fd(const WOLFSSL*);
|
||||
|
||||
/*!
|
||||
\ingroup IO
|
||||
|
||||
\brief This function returns the write file descriptor (fd) used as the
|
||||
output facility for the SSL connection. Typically this
|
||||
will be a socket file descriptor.
|
||||
|
||||
\return fd If successful the call will return the SSL session file
|
||||
descriptor.
|
||||
|
||||
\param ssl pointer to the SSL session, created with wolfSSL_new().
|
||||
|
||||
_Example_
|
||||
\code
|
||||
int sockfd;
|
||||
WOLFSSL* ssl = 0;
|
||||
...
|
||||
sockfd = wolfSSL_get_wfd(ssl);
|
||||
...
|
||||
\endcode
|
||||
|
||||
\sa wolfSSL_set_fd
|
||||
\sa wolfSSL_set_read_fd
|
||||
\sa wolfSSL_set_write_fd
|
||||
*/
|
||||
int wolfSSL_get_wfd(const WOLFSSL*);
|
||||
|
||||
/*!
|
||||
\ingroup Setup
|
||||
|
||||
|
@ -2289,6 +2318,48 @@ int wolfSSL_peek(WOLFSSL* ssl, void* data, int sz);
|
|||
*/
|
||||
int wolfSSL_accept(WOLFSSL*);
|
||||
|
||||
/*!
|
||||
\ingroup IO
|
||||
|
||||
\brief This function is called on the server side and statelessly listens
|
||||
for an SSL client to initiate the DTLS handshake.
|
||||
|
||||
\return WOLFSSL_SUCCESS ClientHello containing a valid cookie was received.
|
||||
The connection can be continued with wolfSSL_accept().
|
||||
\return WOLFSSL_FAILURE The I/O layer returned WANT_READ. This is either
|
||||
because there is no data to read and we are using non-blocking sockets or
|
||||
we sent a cookie request and we are waiting for a reply. The user should
|
||||
call wolfDTLS_accept_stateless again after data becomes available in
|
||||
the I/O layer.
|
||||
\return WOLFSSL_FATAL_ERROR A fatal error occurred. The ssl object should be
|
||||
free'd and allocated again to continue.
|
||||
|
||||
\param ssl a pointer to a WOLFSSL structure, created using wolfSSL_new().
|
||||
|
||||
_Example_
|
||||
\code
|
||||
int ret = 0;
|
||||
int err = 0;
|
||||
WOLFSSL* ssl;
|
||||
...
|
||||
do {
|
||||
ret = wolfDTLS_accept_stateless(ssl);
|
||||
if (ret == WOLFSSL_FATAL_ERROR)
|
||||
// re-allocate the ssl object with wolfSSL_free() and wolfSSL_new()
|
||||
} while (ret != WOLFSSL_SUCCESS);
|
||||
ret = wolfSSL_accept(ssl);
|
||||
if (ret != SSL_SUCCESS) {
|
||||
err = wolfSSL_get_error(ssl, ret);
|
||||
printf(“error = %d, %s\n”, err, wolfSSL_ERR_error_string(err, buffer));
|
||||
}
|
||||
\endcode
|
||||
|
||||
\sa wolfSSL_accept
|
||||
\sa wolfSSL_get_error
|
||||
\sa wolfSSL_connect
|
||||
*/
|
||||
int wolfDTLS_accept_stateless(WOLFSSL* ssl);
|
||||
|
||||
/*!
|
||||
\ingroup Setup
|
||||
|
||||
|
@ -3856,12 +3927,53 @@ int wolfSSL_dtls(WOLFSSL* ssl);
|
|||
\endcode
|
||||
|
||||
\sa wolfSSL_dtls_get_current_timeout
|
||||
\sa wolfSSL_dtls_set_pending_peer
|
||||
\sa wolfSSL_dtls_get_peer
|
||||
\sa wolfSSL_dtls_got_timeout
|
||||
\sa wolfSSL_dtls
|
||||
*/
|
||||
int wolfSSL_dtls_set_peer(WOLFSSL* ssl, void* peer, unsigned int peerSz);
|
||||
|
||||
/*!
|
||||
\brief This function sets the pending DTLS peer, peer (sockaddr_in) with
|
||||
size of peerSz. This sets the pending peer that will be upgraded to a
|
||||
regular peer when we successfully de-protect the next record. This is useful
|
||||
in scenarios where the peer's address can change to avoid off-path attackers
|
||||
from changing the peer address. This should be used with Connection ID's to
|
||||
allow seamless and safe transition to a new peer address.
|
||||
|
||||
\return SSL_SUCCESS will be returned upon success.
|
||||
\return SSL_FAILURE will be returned upon failure.
|
||||
\return SSL_NOT_IMPLEMENTED will be returned if wolfSSL was not compiled
|
||||
with DTLS support.
|
||||
|
||||
\param ssl a pointer to a WOLFSSL structure, created using wolfSSL_new().
|
||||
\param peer pointer to peer’s sockaddr_in structure. If NULL then the peer
|
||||
information in ssl is cleared.
|
||||
\param peerSz size of the sockaddr_in structure pointed to by peer. If 0
|
||||
then the peer information in ssl is cleared.
|
||||
|
||||
_Example_
|
||||
\code
|
||||
int ret = 0;
|
||||
WOLFSSL* ssl;
|
||||
sockaddr_in addr;
|
||||
...
|
||||
ret = wolfSSL_dtls_set_pending_peer(ssl, &addr, sizeof(addr));
|
||||
if (ret != SSL_SUCCESS) {
|
||||
// failed to set DTLS peer
|
||||
}
|
||||
\endcode
|
||||
|
||||
\sa wolfSSL_dtls_get_current_timeout
|
||||
\sa wolfSSL_dtls_set_peer
|
||||
\sa wolfSSL_dtls_get_peer
|
||||
\sa wolfSSL_dtls_got_timeout
|
||||
\sa wolfSSL_dtls
|
||||
*/
|
||||
int wolfSSL_dtls_set_pending_peer(WOLFSSL* ssl, void* peer,
|
||||
unsigned int peerSz);
|
||||
|
||||
/*!
|
||||
\brief This function gets the sockaddr_in (of size peerSz) of the current
|
||||
DTLS peer. The function will compare peerSz to the actual DTLS peer size
|
||||
|
@ -3899,6 +4011,41 @@ int wolfSSL_dtls_set_peer(WOLFSSL* ssl, void* peer, unsigned int peerSz);
|
|||
*/
|
||||
int wolfSSL_dtls_get_peer(WOLFSSL* ssl, void* peer, unsigned int* peerSz);
|
||||
|
||||
/*!
|
||||
\brief This function gets the sockaddr_in (of size peerSz) of the current
|
||||
DTLS peer. This is a zero-copy alternative to wolfSSL_dtls_get_peer().
|
||||
|
||||
\return SSL_SUCCESS will be returned upon success.
|
||||
\return SSL_FAILURE will be returned upon failure.
|
||||
\return SSL_NOT_IMPLEMENTED will be returned if wolfSSL was not compiled
|
||||
with DTLS support.
|
||||
|
||||
\param ssl a pointer to a WOLFSSL structure, created using wolfSSL_new().
|
||||
\param peer pointer to return the internal buffer holding the peer address
|
||||
\param peerSz output the size of the actual sockaddr_in structure
|
||||
pointed to by peer.
|
||||
|
||||
_Example_
|
||||
\code
|
||||
int ret = 0;
|
||||
WOLFSSL* ssl;
|
||||
sockaddr_in* addr;
|
||||
unsigned int addrSz;
|
||||
...
|
||||
ret = wolfSSL_dtls_get_peer(ssl, &addr, &addrSz);
|
||||
if (ret != SSL_SUCCESS) {
|
||||
// failed to get DTLS peer
|
||||
}
|
||||
\endcode
|
||||
|
||||
\sa wolfSSL_dtls_get_current_timeout
|
||||
\sa wolfSSL_dtls_got_timeout
|
||||
\sa wolfSSL_dtls_set_peer
|
||||
\sa wolfSSL_dtls
|
||||
*/
|
||||
int wolfSSL_dtls_get0_peer(WOLFSSL* ssl, const void** peer,
|
||||
unsigned int* peerSz);
|
||||
|
||||
/*!
|
||||
\ingroup Debug
|
||||
|
||||
|
@ -14138,6 +14285,39 @@ int wolfSSL_write_early_data(WOLFSSL* ssl, const void* data,
|
|||
int wolfSSL_read_early_data(WOLFSSL* ssl, void* data, int sz,
|
||||
int* outSz);
|
||||
|
||||
/*!
|
||||
\ingroup IO
|
||||
|
||||
\brief This function is called to inject data into the WOLFSSL object. This
|
||||
is useful when data needs to be read from a single place and demultiplexed
|
||||
into multiple connections. The caller should then call wolfSSL_read() to
|
||||
extract the plaintext data from the WOLFSSL object.
|
||||
|
||||
\param [in] ssl a pointer to a WOLFSSL structure, created using
|
||||
wolfSSL_new().
|
||||
\param [in] data data to inject into the ssl object.
|
||||
\param [in] sz number of bytes of data to inject.
|
||||
|
||||
\return BAD_FUNC_ARG if any pointer parameter is NULL or sz <= 0
|
||||
\return APP_DATA_READY if there is application data left to read
|
||||
\return MEMORY_E if allocation fails
|
||||
\return WOLFSSL_SUCCESS on success
|
||||
|
||||
_Example_
|
||||
\code
|
||||
byte buf[2000]
|
||||
sz = recv(fd, buf, sizeof(buf), 0);
|
||||
if (sz <= 0)
|
||||
// error
|
||||
if (wolfSSL_inject(ssl, buf, sz) != WOLFSSL_SUCCESS)
|
||||
// error
|
||||
sz = wolfSSL_read(ssl, buf, sizeof(buf);
|
||||
\endcode
|
||||
|
||||
\sa wolfSSL_read
|
||||
*/
|
||||
int wolfSSL_inject(WOLFSSL* ssl, const void* data, int sz);
|
||||
|
||||
/*!
|
||||
\ingroup Setup
|
||||
|
||||
|
@ -14955,6 +15135,7 @@ connection into the buffer pointed by the parameter buffer. See RFC 9146 and RFC
|
|||
\param buffer A buffer where the ConnectionID will be copied
|
||||
\param bufferSz available space in buffer
|
||||
|
||||
\sa wolfSSL_dtls_cid_get0_rx
|
||||
\sa wolfSSL_dtls_cid_use
|
||||
\sa wolfSSL_dtls_cid_is_enabled
|
||||
\sa wolfSSL_dtls_cid_set
|
||||
|
@ -14967,6 +15148,26 @@ int wolfSSL_dtls_cid_get_rx(WOLFSSL* ssl, unsigned char* buffer,
|
|||
|
||||
/*!
|
||||
|
||||
\brief Get the ConnectionID used by the other peer. See RFC 9146 and RFC
|
||||
9147.
|
||||
|
||||
\return WOLFSSL_SUCCESS if ConnectionID was correctly set in cid.
|
||||
|
||||
\param ssl A WOLFSSL object pointern
|
||||
\param cid Pointer that will be set to the internal memory that holds the CID
|
||||
|
||||
\sa wolfSSL_dtls_cid_get_rx
|
||||
\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_get0_rx(WOLFSSL* ssl, unsigned char** cid);
|
||||
|
||||
/*!
|
||||
|
||||
\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.
|
||||
|
||||
|
@ -14998,6 +15199,7 @@ available size need to be provided in bufferSz.
|
|||
\param buffer A buffer where the ConnectionID will be copied
|
||||
\param bufferSz available space in buffer
|
||||
|
||||
\sa wolfSSL_dtls_cid_get0_tx
|
||||
\sa wolfSSL_dtls_cid_use
|
||||
\sa wolfSSL_dtls_cid_is_enabled
|
||||
\sa wolfSSL_dtls_cid_set
|
||||
|
@ -15008,6 +15210,50 @@ available size need to be provided in bufferSz.
|
|||
int wolfSSL_dtls_cid_get_tx(WOLFSSL* ssl, unsigned char* buffer,
|
||||
unsigned int bufferSz);
|
||||
|
||||
/*!
|
||||
|
||||
\brief Get the ConnectionID used when sending records in this connection. See
|
||||
RFC 9146 and RFC 9147.
|
||||
|
||||
\return WOLFSSL_SUCCESS if ConnectionID was correctly retrieved, error code
|
||||
otherwise
|
||||
|
||||
\param ssl A WOLFSSL object pointern
|
||||
\param cid Pointer that will be set to the internal memory that holds the CID
|
||||
|
||||
\sa wolfSSL_dtls_cid_get_tx
|
||||
\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_get0_tx(WOLFSSL* ssl, unsigned char** cid);
|
||||
|
||||
/*!
|
||||
|
||||
\brief Extract the ConnectionID from a record datagram/message. See
|
||||
RFC 9146 and RFC 9147.
|
||||
|
||||
\param msg buffer holding the datagram read from the network
|
||||
\param msgSz size of msg in bytes
|
||||
\param cid pointer to the start of the CID inside the msg buffer
|
||||
\param cidSz the expected size of the CID. The record layer does not have a CID
|
||||
size field so we have to know beforehand the size of the CID. It is recommended
|
||||
to use a constant CID for all connections.
|
||||
|
||||
\sa wolfSSL_dtls_cid_get_tx
|
||||
\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
|
||||
*/
|
||||
void wolfSSL_dtls_cid_parse(const unsigned char* msg, unsigned int msgSz,
|
||||
const unsigned char** cid, unsigned int cidSz);
|
||||
|
||||
/*!
|
||||
\ingroup TLS
|
||||
|
||||
|
|
|
@ -575,3 +575,46 @@ int wolfSSL_SetIO_ISOTP(WOLFSSL *ssl, isotp_wolfssl_ctx *ctx,
|
|||
can_recv_fn recv_fn, can_send_fn send_fn, can_delay_fn delay_fn,
|
||||
word32 receive_delay, char *receive_buffer, int receive_buffer_size,
|
||||
void *arg);
|
||||
|
||||
/*!
|
||||
\ingroup Setup
|
||||
|
||||
\brief This function disables reading from the IO layer.
|
||||
|
||||
\param ssl the wolfSSL context
|
||||
|
||||
_Example_
|
||||
\code
|
||||
WOLFSSL_CTX* ctx = wolfSSL_CTX_new(method);
|
||||
WOLFSSL* ssl = wolfSSL_new(ctx);
|
||||
wolfSSL_SSLDisableRead(ssl);
|
||||
\endcode
|
||||
|
||||
\sa wolfSSL_CTX_SetIORecv
|
||||
\sa wolfSSL_SSLSetIORecv
|
||||
\sa wolfSSL_SSLEnableRead
|
||||
*/
|
||||
void wolfSSL_SSLDisableRead(WOLFSSL *ssl);
|
||||
|
||||
/*!
|
||||
\ingroup Setup
|
||||
|
||||
\brief This function enables reading from the IO layer. Reading is enabled
|
||||
by default and should be used to undo wolfSSL_SSLDisableRead();
|
||||
|
||||
\param ssl the wolfSSL context
|
||||
|
||||
_Example_
|
||||
\code
|
||||
WOLFSSL_CTX* ctx = wolfSSL_CTX_new(method);
|
||||
WOLFSSL* ssl = wolfSSL_new(ctx);
|
||||
wolfSSL_SSLDisableRead(ssl);
|
||||
...
|
||||
wolfSSL_SSLEnableRead(ssl);
|
||||
\endcode
|
||||
|
||||
\sa wolfSSL_CTX_SetIORecv
|
||||
\sa wolfSSL_SSLSetIORecv
|
||||
\sa wolfSSL_SSLEnableRead
|
||||
*/
|
||||
void wolfSSL_SSLEnableRead(WOLFSSL *ssl);
|
||||
|
|
|
@ -2404,7 +2404,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
|||
err_sys("provided connection ID is too big");
|
||||
}
|
||||
else {
|
||||
strcpy(dtlsCID, myoptarg);
|
||||
XSTRLCPY(dtlsCID, myoptarg, DTLS_CID_BUFFER_SIZE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -2423,7 +2423,7 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
|
|||
err_sys("provided connection ID is too big");
|
||||
}
|
||||
else {
|
||||
strcpy(dtlsCID, myoptarg);
|
||||
XSTRLCPY(dtlsCID, myoptarg, DTLS_CID_BUFFER_SIZE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
70
src/dtls.c
70
src/dtls.c
|
@ -101,6 +101,15 @@ void DtlsResetState(WOLFSSL* ssl)
|
|||
ssl->options.tls = 0;
|
||||
ssl->options.tls1_1 = 0;
|
||||
ssl->options.tls1_3 = 0;
|
||||
#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_DTLS_CID)
|
||||
ssl->buffers.dtlsCtx.processingPendingRecord = 0;
|
||||
/* Clear the pending peer in case user set */
|
||||
XFREE(ssl->buffers.dtlsCtx.pendingPeer.sa, ssl->heap,
|
||||
DYNAMIC_TYPE_SOCKADDR);
|
||||
ssl->buffers.dtlsCtx.pendingPeer.sa = NULL;
|
||||
ssl->buffers.dtlsCtx.pendingPeer.sz = 0;
|
||||
ssl->buffers.dtlsCtx.pendingPeer.bufSz = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int DtlsIgnoreError(int err)
|
||||
|
@ -221,6 +230,7 @@ static int CreateDtls12Cookie(const WOLFSSL* ssl, const WolfSSL_CH* ch,
|
|||
ssl->buffers.dtlsCookieSecret.buffer,
|
||||
ssl->buffers.dtlsCookieSecret.length);
|
||||
if (ret == 0) {
|
||||
/* peerLock not necessary. Still in handshake phase. */
|
||||
ret = wc_HmacUpdate(&cookieHmac,
|
||||
(const byte*)ssl->buffers.dtlsCtx.peer.sa,
|
||||
ssl->buffers.dtlsCtx.peer.sz);
|
||||
|
@ -1108,6 +1118,26 @@ static int DtlsCidGet(WOLFSSL* ssl, unsigned char* buf, int bufferSz, int rx)
|
|||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
|
||||
static int DtlsCidGet0(WOLFSSL* ssl, unsigned char** cid, int rx)
|
||||
{
|
||||
ConnectionID* id;
|
||||
CIDInfo* info;
|
||||
|
||||
if (ssl == NULL || cid == 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;
|
||||
|
||||
*cid = id->id;
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
|
||||
static CIDInfo* DtlsCidGetInfoFromExt(byte* ext)
|
||||
{
|
||||
WOLFSSL** sslPtr;
|
||||
|
@ -1366,6 +1396,11 @@ int wolfSSL_dtls_cid_get_rx(WOLFSSL* ssl, unsigned char* buf,
|
|||
return DtlsCidGet(ssl, buf, bufferSz, 1);
|
||||
}
|
||||
|
||||
int wolfSSL_dtls_cid_get0_rx(WOLFSSL* ssl, unsigned char** cid)
|
||||
{
|
||||
return DtlsCidGet0(ssl, cid, 1);
|
||||
}
|
||||
|
||||
int wolfSSL_dtls_cid_get_tx_size(WOLFSSL* ssl, unsigned int* size)
|
||||
{
|
||||
return DtlsCidGetSize(ssl, size, 0);
|
||||
|
@ -1377,10 +1412,40 @@ int wolfSSL_dtls_cid_get_tx(WOLFSSL* ssl, unsigned char* buf,
|
|||
return DtlsCidGet(ssl, buf, bufferSz, 0);
|
||||
}
|
||||
|
||||
int wolfSSL_dtls_cid_get0_tx(WOLFSSL* ssl, unsigned char** cid)
|
||||
{
|
||||
return DtlsCidGet0(ssl, cid, 0);
|
||||
}
|
||||
|
||||
int wolfSSL_dtls_cid_max_size(void)
|
||||
{
|
||||
return DTLS_CID_MAX_SIZE;
|
||||
}
|
||||
|
||||
const unsigned char* wolfSSL_dtls_cid_parse(const unsigned char* msg,
|
||||
unsigned int msgSz, unsigned int cidSz)
|
||||
{
|
||||
/* we need at least the first byte to check version */
|
||||
if (msg == NULL || cidSz == 0 || msgSz < OPAQUE8_LEN + cidSz)
|
||||
return NULL;
|
||||
if (msg[0] == dtls12_cid) {
|
||||
/* DTLS 1.2 CID packet */
|
||||
if (msgSz < DTLS_RECORD_HEADER_SZ + cidSz)
|
||||
return NULL;
|
||||
/* content type(1) + version(2) + epoch(2) + sequence(6) */
|
||||
return msg + ENUM_LEN + VERSION_SZ + OPAQUE16_LEN + OPAQUE16_LEN +
|
||||
OPAQUE32_LEN;
|
||||
}
|
||||
#ifdef WOLFSSL_DTLS13
|
||||
else if (Dtls13UnifiedHeaderCIDPresent(msg[0])) {
|
||||
/* DTLS 1.3 CID packet */
|
||||
if (msgSz < OPAQUE8_LEN + cidSz)
|
||||
return NULL;
|
||||
return msg + OPAQUE8_LEN;
|
||||
}
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
#endif /* WOLFSSL_DTLS_CID */
|
||||
|
||||
byte DtlsGetCidTxSize(WOLFSSL* ssl)
|
||||
|
@ -1413,6 +1478,11 @@ byte DtlsGetCidRxSize(WOLFSSL* ssl)
|
|||
#endif
|
||||
}
|
||||
|
||||
byte wolfSSL_is_stateful(WOLFSSL* ssl)
|
||||
{
|
||||
return (byte)(ssl != NULL ? ssl->options.dtlsStateful : 0);
|
||||
}
|
||||
|
||||
#endif /* WOLFSSL_DTLS */
|
||||
|
||||
#endif /* WOLFCRYPT_ONLY */
|
||||
|
|
|
@ -1151,6 +1151,11 @@ static int Dtls13UnifiedHeaderParseCID(WOLFSSL* ssl, byte flags,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int Dtls13UnifiedHeaderCIDPresent(byte flags)
|
||||
{
|
||||
return Dtls13IsUnifiedHeader(flags) && (flags & DTLS13_CID_BIT);
|
||||
}
|
||||
|
||||
#else
|
||||
#define Dtls13AddCID(a, b, c, d) 0
|
||||
#define Dtls13UnifiedHeaderParseCID(a, b, c, d, e) 0
|
||||
|
|
149
src/internal.c
149
src/internal.c
|
@ -7621,6 +7621,11 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
|
|||
ssl->buffers.dtlsCtx.rfd = -1;
|
||||
ssl->buffers.dtlsCtx.wfd = -1;
|
||||
|
||||
#ifdef WOLFSSL_RW_THREADED
|
||||
if (wc_InitRwLock(&ssl->buffers.dtlsCtx.peerLock) != 0)
|
||||
return BAD_MUTEX_E;
|
||||
#endif
|
||||
|
||||
ssl->IOCB_ReadCtx = &ssl->buffers.dtlsCtx; /* prevent invalid pointer access if not */
|
||||
ssl->IOCB_WriteCtx = &ssl->buffers.dtlsCtx; /* correctly set */
|
||||
#else
|
||||
|
@ -8493,6 +8498,14 @@ void wolfSSL_ResourceFree(WOLFSSL* ssl)
|
|||
}
|
||||
XFREE(ssl->buffers.dtlsCtx.peer.sa, ssl->heap, DYNAMIC_TYPE_SOCKADDR);
|
||||
ssl->buffers.dtlsCtx.peer.sa = NULL;
|
||||
#ifdef WOLFSSL_RW_THREADED
|
||||
wc_FreeRwLock(&ssl->buffers.dtlsCtx.peerLock);
|
||||
#endif
|
||||
#ifdef WOLFSSL_DTLS_CID
|
||||
XFREE(ssl->buffers.dtlsCtx.pendingPeer.sa, ssl->heap,
|
||||
DYNAMIC_TYPE_SOCKADDR);
|
||||
ssl->buffers.dtlsCtx.pendingPeer.sa = NULL;
|
||||
#endif
|
||||
#ifndef NO_WOLFSSL_SERVER
|
||||
if (ssl->buffers.dtlsCookieSecret.buffer != NULL) {
|
||||
ForceZero(ssl->buffers.dtlsCookieSecret.buffer,
|
||||
|
@ -10813,7 +10826,7 @@ retry:
|
|||
}
|
||||
}
|
||||
#endif
|
||||
goto retry;
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
|
||||
case WC_NO_ERR_TRACE(WOLFSSL_CBIO_ERR_CONN_CLOSE):
|
||||
ssl->options.isClosed = 1;
|
||||
|
@ -11754,15 +11767,14 @@ static int GetDtlsRecordHeader(WOLFSSL* ssl, word32* inOutIdx,
|
|||
|
||||
#ifdef WOLFSSL_DTLS_CID
|
||||
if (rh->type == dtls12_cid) {
|
||||
byte cid[DTLS_CID_MAX_SIZE];
|
||||
byte* ourCid = NULL;
|
||||
if (ssl->buffers.inputBuffer.length - *inOutIdx <
|
||||
(word32)cidSz + LENGTH_SZ)
|
||||
return LENGTH_ERROR;
|
||||
if (cidSz > DTLS_CID_MAX_SIZE ||
|
||||
wolfSSL_dtls_cid_get_rx(ssl, cid, cidSz) != WOLFSSL_SUCCESS)
|
||||
if (wolfSSL_dtls_cid_get0_rx(ssl, &ourCid) != WOLFSSL_SUCCESS)
|
||||
return DTLS_CID_ERROR;
|
||||
if (XMEMCMP(ssl->buffers.inputBuffer.buffer + *inOutIdx,
|
||||
cid, cidSz) != 0)
|
||||
if (XMEMCMP(ssl->buffers.inputBuffer.buffer + *inOutIdx, ourCid, cidSz)
|
||||
!= 0)
|
||||
return DTLS_CID_ERROR;
|
||||
*inOutIdx += cidSz;
|
||||
}
|
||||
|
@ -11972,7 +11984,7 @@ int GetDtlsHandShakeHeader(WOLFSSL* ssl, const byte* input,
|
|||
{
|
||||
word32 idx = *inOutIdx;
|
||||
|
||||
*inOutIdx += HANDSHAKE_HEADER_SZ + DTLS_HANDSHAKE_EXTRA;
|
||||
*inOutIdx += DTLS_HANDSHAKE_HEADER_SZ;
|
||||
if (*inOutIdx > totalSz) {
|
||||
WOLFSSL_ERROR(BUFFER_E);
|
||||
return BUFFER_E;
|
||||
|
@ -21277,11 +21289,14 @@ static int GetInputData(WOLFSSL *ssl, word32 size)
|
|||
int usedLength;
|
||||
int dtlsExtra = 0;
|
||||
|
||||
if (ssl->options.disableRead)
|
||||
return WC_NO_ERR_TRACE(WANT_READ);
|
||||
|
||||
/* check max input length */
|
||||
usedLength = (int)(ssl->buffers.inputBuffer.length - ssl->buffers.inputBuffer.idx);
|
||||
maxLength = (int)(ssl->buffers.inputBuffer.bufferSize - (word32)usedLength);
|
||||
inSz = (int)(size - (word32)usedLength); /* from last partial read */
|
||||
usedLength = (int)(ssl->buffers.inputBuffer.length -
|
||||
ssl->buffers.inputBuffer.idx);
|
||||
maxLength = (int)(ssl->buffers.inputBuffer.bufferSize -
|
||||
(word32)usedLength);
|
||||
|
||||
#ifdef WOLFSSL_DTLS
|
||||
if (ssl->options.dtls && IsDtlsNotSctpMode(ssl)) {
|
||||
|
@ -21295,13 +21310,22 @@ static int GetInputData(WOLFSSL *ssl, word32 size)
|
|||
if (size < (word32)inSz)
|
||||
dtlsExtra = (int)(inSz - size);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
{
|
||||
/* check that no lengths or size values are negative */
|
||||
if (usedLength < 0 || maxLength < 0 || inSz <= 0) {
|
||||
if (usedLength < 0 || maxLength < 0) {
|
||||
return BUFFER_ERROR;
|
||||
}
|
||||
|
||||
/* Return if we have enough data already in the buffer */
|
||||
if (size <= (word32)usedLength) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
inSz = (int)(size - (word32)usedLength); /* from last partial read */
|
||||
}
|
||||
|
||||
if (inSz > maxLength) {
|
||||
if (GrowInputBuffer(ssl, (int)(size + (word32)dtlsExtra), usedLength) < 0)
|
||||
return MEMORY_E;
|
||||
|
@ -21533,7 +21557,8 @@ static int DtlsShouldDrop(WOLFSSL* ssl, int retcode)
|
|||
}
|
||||
#endif /* WOLFSSL_DTLS */
|
||||
|
||||
#if defined(WOLFSSL_TLS13) || defined(WOLFSSL_DTLS) && defined(WOLFSSL_DTLS_CID)
|
||||
#if defined(WOLFSSL_TLS13) || \
|
||||
(defined(WOLFSSL_DTLS) && defined(WOLFSSL_DTLS_CID))
|
||||
static int removeMsgInnerPadding(WOLFSSL* ssl)
|
||||
{
|
||||
word32 i = ssl->buffers.inputBuffer.idx +
|
||||
|
@ -21565,16 +21590,58 @@ static int removeMsgInnerPadding(WOLFSSL* ssl)
|
|||
}
|
||||
#endif
|
||||
|
||||
int ProcessReply(WOLFSSL* ssl)
|
||||
#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_DTLS_CID)
|
||||
static void dtlsClearPeer(WOLFSSL_SOCKADDR* peer)
|
||||
{
|
||||
return ProcessReplyEx(ssl, 0);
|
||||
XFREE(peer->sa, NULL, DYNAMIC_TYPE_SOCKADDR);
|
||||
peer->sa = NULL;
|
||||
peer->sz = 0;
|
||||
peer->bufSz = 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Handle pending peer during record processing.
|
||||
* @param ssl WOLFSSL object.
|
||||
* @param deprotected 0 when we have not decrypted the record yet
|
||||
* 1 when we have decrypted and verified the record
|
||||
*/
|
||||
static void dtlsProcessPendingPeer(WOLFSSL* ssl, int deprotected)
|
||||
{
|
||||
if (ssl->buffers.dtlsCtx.pendingPeer.sa != NULL) {
|
||||
if (!deprotected) {
|
||||
/* Here we have just read an entire record from the network. It is
|
||||
* still encrypted. If processingPendingRecord is set then that
|
||||
* means that an error occurred when processing the previous record.
|
||||
* In that case we should clear the pendingPeer because we only
|
||||
* want to allow it to be valid for one record. */
|
||||
if (ssl->buffers.dtlsCtx.processingPendingRecord) {
|
||||
/* Clear the pending peer. */
|
||||
dtlsClearPeer(&ssl->buffers.dtlsCtx.pendingPeer);
|
||||
}
|
||||
ssl->buffers.dtlsCtx.processingPendingRecord =
|
||||
!ssl->buffers.dtlsCtx.processingPendingRecord;
|
||||
}
|
||||
else {
|
||||
/* Pending peer present and record deprotected. Update the peer. */
|
||||
(void)wolfSSL_dtls_set_peer(ssl,
|
||||
&ssl->buffers.dtlsCtx.pendingPeer.sa,
|
||||
ssl->buffers.dtlsCtx.pendingPeer.sz);
|
||||
ssl->buffers.dtlsCtx.processingPendingRecord = 0;
|
||||
dtlsClearPeer(&ssl->buffers.dtlsCtx.pendingPeer);
|
||||
}
|
||||
}
|
||||
else {
|
||||
ssl->buffers.dtlsCtx.processingPendingRecord = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Process input requests. Return 0 is done, 1 is call again to complete, and
|
||||
negative number is error. If allowSocketErr is set, SOCKET_ERROR_E in
|
||||
ssl->error will be whitelisted. This is useful when the connection has been
|
||||
closed and the endpoint wants to check for an alert sent by the other end. */
|
||||
int ProcessReplyEx(WOLFSSL* ssl, int allowSocketErr)
|
||||
static int DoProcessReplyEx(WOLFSSL* ssl, int allowSocketErr)
|
||||
{
|
||||
int ret = 0, type = internal_error, readSz;
|
||||
int atomicUser = 0;
|
||||
|
@ -21773,6 +21840,10 @@ int ProcessReplyEx(WOLFSSL* ssl, int allowSocketErr)
|
|||
&ssl->curRL, &ssl->curSize);
|
||||
|
||||
#ifdef WOLFSSL_DTLS
|
||||
#ifdef WOLFSSL_DTLS_CID
|
||||
if (ssl->options.dtls)
|
||||
dtlsProcessPendingPeer(ssl, 0);
|
||||
#endif
|
||||
if (ssl->options.dtls && DtlsShouldDrop(ssl, ret)) {
|
||||
ssl->options.processReply = doProcessInit;
|
||||
ssl->buffers.inputBuffer.length = 0;
|
||||
|
@ -22152,7 +22223,8 @@ default:
|
|||
}
|
||||
|
||||
if (IsEncryptionOn(ssl, 0) && ssl->keys.decryptedCur == 1) {
|
||||
#if defined(WOLFSSL_TLS13) || defined(WOLFSSL_DTLS) && defined(WOLFSSL_DTLS_CID)
|
||||
#if defined(WOLFSSL_TLS13) || \
|
||||
(defined(WOLFSSL_DTLS) && defined(WOLFSSL_DTLS_CID))
|
||||
int removePadding = 0;
|
||||
if (ssl->options.tls1_3)
|
||||
removePadding = 1;
|
||||
|
@ -22197,8 +22269,9 @@ default:
|
|||
|
||||
/* the record layer is here */
|
||||
case runProcessingOneRecord:
|
||||
#ifdef WOLFSSL_DTLS13
|
||||
#ifdef WOLFSSL_DTLS
|
||||
if (ssl->options.dtls) {
|
||||
#ifdef WOLFSSL_DTLS13
|
||||
if (IsAtLeastTLSv1_3(ssl->version)) {
|
||||
if (!Dtls13CheckWindow(ssl)) {
|
||||
/* drop packet */
|
||||
|
@ -22222,11 +22295,18 @@ default:
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (IsDtlsNotSctpMode(ssl)) {
|
||||
else
|
||||
#endif /* WOLFSSL_DTLS13 */
|
||||
if (IsDtlsNotSctpMode(ssl)) {
|
||||
DtlsUpdateWindow(ssl);
|
||||
}
|
||||
#ifdef WOLFSSL_DTLS_CID
|
||||
/* Update the peer if we were able to de-protect the message */
|
||||
if (IsEncryptionOn(ssl, 0))
|
||||
dtlsProcessPendingPeer(ssl, 1);
|
||||
#endif
|
||||
}
|
||||
#endif /* WOLFSSL_DTLS13 */
|
||||
#endif /* WOLFSSL_DTLS */
|
||||
ssl->options.processReply = runProcessingOneMessage;
|
||||
FALL_THROUGH;
|
||||
|
||||
|
@ -22694,6 +22774,35 @@ default:
|
|||
}
|
||||
}
|
||||
|
||||
int ProcessReply(WOLFSSL* ssl)
|
||||
{
|
||||
return ProcessReplyEx(ssl, 0);
|
||||
}
|
||||
|
||||
int ProcessReplyEx(WOLFSSL* ssl, int allowSocketErr)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = DoProcessReplyEx(ssl, allowSocketErr);
|
||||
|
||||
#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_DTLS_CID)
|
||||
if (ssl->options.dtls) {
|
||||
/* Don't clear pending peer if we are going to re-enter
|
||||
* DoProcessReplyEx */
|
||||
if (ret != WC_NO_ERR_TRACE(WANT_READ)
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
&& ret != WC_NO_ERR_TRACE(WC_PENDING_E)
|
||||
#endif
|
||||
) {
|
||||
dtlsClearPeer(&ssl->buffers.dtlsCtx.pendingPeer);
|
||||
ssl->buffers.dtlsCtx.processingPendingRecord = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if !defined(WOLFSSL_NO_TLS12) || !defined(NO_OLD_TLS) || \
|
||||
(defined(WOLFSSL_TLS13) && defined(WOLFSSL_TLS13_MIDDLEBOX_COMPAT))
|
||||
int SendChangeCipher(WOLFSSL* ssl)
|
||||
|
|
281
src/ssl.c
281
src/ssl.c
|
@ -1767,6 +1767,17 @@ int wolfSSL_get_fd(const WOLFSSL* ssl)
|
|||
return fd;
|
||||
}
|
||||
|
||||
int wolfSSL_get_wfd(const WOLFSSL* ssl)
|
||||
{
|
||||
int fd = -1;
|
||||
WOLFSSL_ENTER("wolfSSL_get_fd");
|
||||
if (ssl) {
|
||||
fd = ssl->wfd;
|
||||
}
|
||||
WOLFSSL_LEAVE("wolfSSL_get_fd", fd);
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
||||
int wolfSSL_dtls(WOLFSSL* ssl)
|
||||
{
|
||||
|
@ -1899,38 +1910,58 @@ int wolfSSL_dtls_free_peer(void* addr)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_DTLS
|
||||
static int SockAddrSet(WOLFSSL_SOCKADDR* sockAddr, void* peer,
|
||||
unsigned int peerSz, void* heap)
|
||||
{
|
||||
if (peer == NULL || peerSz == 0) {
|
||||
if (sockAddr->sa != NULL)
|
||||
XFREE(sockAddr->sa, heap, DYNAMIC_TYPE_SOCKADDR);
|
||||
sockAddr->sa = NULL;
|
||||
sockAddr->sz = 0;
|
||||
sockAddr->bufSz = 0;
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
|
||||
if (peerSz > sockAddr->bufSz) {
|
||||
if (sockAddr->sa != NULL)
|
||||
XFREE(sockAddr->sa, heap, DYNAMIC_TYPE_SOCKADDR);
|
||||
sockAddr->sa =
|
||||
(void*)XMALLOC(peerSz, heap, DYNAMIC_TYPE_SOCKADDR);
|
||||
if (sockAddr->sa == NULL) {
|
||||
sockAddr->sz = 0;
|
||||
sockAddr->bufSz = 0;
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
sockAddr->bufSz = peerSz;
|
||||
}
|
||||
XMEMCPY(sockAddr->sa, peer, peerSz);
|
||||
sockAddr->sz = peerSz;
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
int wolfSSL_dtls_set_peer(WOLFSSL* ssl, void* peer, unsigned int peerSz)
|
||||
{
|
||||
#ifdef WOLFSSL_DTLS
|
||||
void* sa;
|
||||
int ret;
|
||||
|
||||
if (ssl == NULL)
|
||||
return WOLFSSL_FAILURE;
|
||||
|
||||
if (peer == NULL || peerSz == 0) {
|
||||
if (ssl->buffers.dtlsCtx.peer.sa != NULL)
|
||||
XFREE(ssl->buffers.dtlsCtx.peer.sa,ssl->heap,DYNAMIC_TYPE_SOCKADDR);
|
||||
ssl->buffers.dtlsCtx.peer.sa = NULL;
|
||||
ssl->buffers.dtlsCtx.peer.sz = 0;
|
||||
ssl->buffers.dtlsCtx.peer.bufSz = 0;
|
||||
ssl->buffers.dtlsCtx.userSet = 0;
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
|
||||
sa = (void*)XMALLOC(peerSz, ssl->heap, DYNAMIC_TYPE_SOCKADDR);
|
||||
if (sa != NULL) {
|
||||
if (ssl->buffers.dtlsCtx.peer.sa != NULL) {
|
||||
XFREE(ssl->buffers.dtlsCtx.peer.sa,ssl->heap,DYNAMIC_TYPE_SOCKADDR);
|
||||
ssl->buffers.dtlsCtx.peer.sa = NULL;
|
||||
}
|
||||
XMEMCPY(sa, peer, peerSz);
|
||||
ssl->buffers.dtlsCtx.peer.sa = sa;
|
||||
ssl->buffers.dtlsCtx.peer.sz = peerSz;
|
||||
ssl->buffers.dtlsCtx.peer.bufSz = peerSz;
|
||||
ssl->buffers.dtlsCtx.userSet = 1;
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
#ifdef WOLFSSL_RW_THREADED
|
||||
if (wc_LockRwLock_Wr(&ssl->buffers.dtlsCtx.peerLock) != 0)
|
||||
return WOLFSSL_FAILURE;
|
||||
#endif
|
||||
ret = SockAddrSet(&ssl->buffers.dtlsCtx.peer, peer, peerSz, ssl->heap);
|
||||
if (ret == WOLFSSL_SUCCESS && !(peer == NULL || peerSz == 0))
|
||||
ssl->buffers.dtlsCtx.userSet = 1;
|
||||
else
|
||||
ssl->buffers.dtlsCtx.userSet = 0;
|
||||
#ifdef WOLFSSL_RW_THREADED
|
||||
if (wc_UnLockRwLock(&ssl->buffers.dtlsCtx.peerLock) != 0)
|
||||
ret = WOLFSSL_FAILURE;
|
||||
#endif
|
||||
return ret;
|
||||
#else
|
||||
(void)ssl;
|
||||
(void)peer;
|
||||
|
@ -1939,21 +1970,97 @@ int wolfSSL_dtls_set_peer(WOLFSSL* ssl, void* peer, unsigned int peerSz)
|
|||
#endif
|
||||
}
|
||||
|
||||
#if defined(WOLFSSL_DTLS_CID) && !defined(WOLFSSL_NO_SOCK)
|
||||
int wolfSSL_dtls_set_pending_peer(WOLFSSL* ssl, void* peer, unsigned int peerSz)
|
||||
{
|
||||
#ifdef WOLFSSL_DTLS
|
||||
int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
|
||||
|
||||
if (ssl == NULL)
|
||||
return WOLFSSL_FAILURE;
|
||||
#ifdef WOLFSSL_RW_THREADED
|
||||
if (wc_LockRwLock_Rd(&ssl->buffers.dtlsCtx.peerLock) != 0)
|
||||
return WOLFSSL_FAILURE;
|
||||
#endif
|
||||
if (ssl->buffers.dtlsCtx.peer.sa != NULL &&
|
||||
ssl->buffers.dtlsCtx.peer.sz == peerSz &&
|
||||
sockAddrEqual((SOCKADDR_S*)ssl->buffers.dtlsCtx.peer.sa,
|
||||
(XSOCKLENT)ssl->buffers.dtlsCtx.peer.sz, (SOCKADDR_S*)peer,
|
||||
(XSOCKLENT)peerSz)) {
|
||||
/* Already the current peer. */
|
||||
if (ssl->buffers.dtlsCtx.pendingPeer.sa != NULL) {
|
||||
/* Clear any other pendingPeer */
|
||||
XFREE(ssl->buffers.dtlsCtx.pendingPeer.sa, ssl->heap,
|
||||
DYNAMIC_TYPE_SOCKADDR);
|
||||
ssl->buffers.dtlsCtx.pendingPeer.sa = NULL;
|
||||
ssl->buffers.dtlsCtx.pendingPeer.sz = 0;
|
||||
ssl->buffers.dtlsCtx.pendingPeer.bufSz = 0;
|
||||
}
|
||||
ret = WOLFSSL_SUCCESS;
|
||||
}
|
||||
else {
|
||||
ret = SockAddrSet(&ssl->buffers.dtlsCtx.pendingPeer, peer, peerSz,
|
||||
ssl->heap);
|
||||
}
|
||||
if (ret == WOLFSSL_SUCCESS)
|
||||
ssl->buffers.dtlsCtx.processingPendingRecord = 0;
|
||||
#ifdef WOLFSSL_RW_THREADED
|
||||
if (wc_UnLockRwLock(&ssl->buffers.dtlsCtx.peerLock) != 0)
|
||||
ret = WOLFSSL_FAILURE;
|
||||
#endif
|
||||
return ret;
|
||||
#else
|
||||
(void)ssl;
|
||||
(void)peer;
|
||||
(void)peerSz;
|
||||
return WOLFSSL_NOT_IMPLEMENTED;
|
||||
#endif
|
||||
}
|
||||
#endif /* WOLFSSL_DTLS_CID && !WOLFSSL_NO_SOCK */
|
||||
|
||||
int wolfSSL_dtls_get_peer(WOLFSSL* ssl, void* peer, unsigned int* peerSz)
|
||||
{
|
||||
#ifdef WOLFSSL_DTLS
|
||||
if (ssl == NULL) {
|
||||
int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
|
||||
if (ssl == NULL)
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_RW_THREADED
|
||||
if (wc_LockRwLock_Rd(&ssl->buffers.dtlsCtx.peerLock) != 0)
|
||||
return WOLFSSL_FAILURE;
|
||||
#endif
|
||||
if (peer != NULL && peerSz != NULL
|
||||
&& *peerSz >= ssl->buffers.dtlsCtx.peer.sz
|
||||
&& ssl->buffers.dtlsCtx.peer.sa != NULL) {
|
||||
*peerSz = ssl->buffers.dtlsCtx.peer.sz;
|
||||
XMEMCPY(peer, ssl->buffers.dtlsCtx.peer.sa, *peerSz);
|
||||
return WOLFSSL_SUCCESS;
|
||||
ret = WOLFSSL_SUCCESS;
|
||||
}
|
||||
#ifdef WOLFSSL_RW_THREADED
|
||||
if (wc_UnLockRwLock(&ssl->buffers.dtlsCtx.peerLock) != 0)
|
||||
ret = WOLFSSL_FAILURE;
|
||||
#endif
|
||||
return ret;
|
||||
#else
|
||||
(void)ssl;
|
||||
(void)peer;
|
||||
(void)peerSz;
|
||||
return WOLFSSL_NOT_IMPLEMENTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
int wolfSSL_dtls_get0_peer(WOLFSSL* ssl, const void** peer,
|
||||
unsigned int* peerSz)
|
||||
{
|
||||
#if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_RW_THREADED)
|
||||
if (ssl == NULL)
|
||||
return WOLFSSL_FAILURE;
|
||||
|
||||
if (peer == NULL || peerSz == NULL)
|
||||
return WOLFSSL_FAILURE;
|
||||
|
||||
*peer = ssl->buffers.dtlsCtx.peer.sa;
|
||||
*peerSz = ssl->buffers.dtlsCtx.peer.sz;
|
||||
return WOLFSSL_SUCCESS;
|
||||
#else
|
||||
(void)ssl;
|
||||
(void)peer;
|
||||
|
@ -2996,6 +3103,42 @@ int wolfSSL_write(WOLFSSL* ssl, const void* data, int sz)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int wolfSSL_inject(WOLFSSL* ssl, const void* data, int sz)
|
||||
{
|
||||
int maxLength;
|
||||
int usedLength;
|
||||
|
||||
WOLFSSL_ENTER("wolfSSL_inject");
|
||||
|
||||
if (ssl == NULL || data == NULL || sz <= 0)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
usedLength = (int)(ssl->buffers.inputBuffer.length -
|
||||
ssl->buffers.inputBuffer.idx);
|
||||
maxLength = (int)(ssl->buffers.inputBuffer.bufferSize -
|
||||
(word32)usedLength);
|
||||
|
||||
if (sz > maxLength) {
|
||||
/* Need to make space */
|
||||
int ret;
|
||||
if (ssl->buffers.clearOutputBuffer.length > 0) {
|
||||
/* clearOutputBuffer points into so reallocating inputBuffer will
|
||||
* invalidate clearOutputBuffer and lose app data */
|
||||
WOLFSSL_MSG("Can't inject while there is application data to read");
|
||||
return APP_DATA_READY;
|
||||
}
|
||||
ret = GrowInputBuffer(ssl, sz, usedLength);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
XMEMCPY(ssl->buffers.inputBuffer.buffer + ssl->buffers.inputBuffer.idx,
|
||||
data, sz);
|
||||
ssl->buffers.inputBuffer.length += sz;
|
||||
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
|
||||
static int wolfSSL_read_internal(WOLFSSL* ssl, void* data, int sz, int peek)
|
||||
{
|
||||
int ret;
|
||||
|
@ -9617,7 +9760,13 @@ int wolfSSL_dtls_retransmit(WOLFSSL* ssl)
|
|||
return WOLFSSL_FATAL_ERROR;
|
||||
|
||||
if (!ssl->options.handShakeDone) {
|
||||
int result = DtlsMsgPoolSend(ssl, 0);
|
||||
int result;
|
||||
#ifdef WOLFSSL_DTLS13
|
||||
if (IsAtLeastTLSv1_3(ssl->version))
|
||||
result = Dtls13DoScheduledWork(ssl);
|
||||
else
|
||||
#endif
|
||||
result = DtlsMsgPoolSend(ssl, 0);
|
||||
if (result < 0) {
|
||||
ssl->error = result;
|
||||
WOLFSSL_ERROR(result);
|
||||
|
@ -9625,7 +9774,7 @@ int wolfSSL_dtls_retransmit(WOLFSSL* ssl)
|
|||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
|
||||
#endif /* DTLS */
|
||||
|
@ -10794,6 +10943,76 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
|
|||
|
||||
|
||||
#if defined(WOLFSSL_DTLS) && !defined(NO_WOLFSSL_SERVER)
|
||||
struct chGoodDisableReadCbCtx {
|
||||
ClientHelloGoodCb userCb;
|
||||
void* userCtx;
|
||||
};
|
||||
|
||||
static int chGoodDisableReadCB(WOLFSSL* ssl, void* ctx)
|
||||
{
|
||||
struct chGoodDisableReadCbCtx* cb = (struct chGoodDisableReadCbCtx*)ctx;
|
||||
int ret = 0;
|
||||
if (cb->userCb != NULL)
|
||||
ret = cb->userCb(ssl, cb->userCtx);
|
||||
if (ret >= 0)
|
||||
wolfSSL_SSLDisableRead(ssl);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Statelessly listen for a connection
|
||||
* @param ssl The ssl object to use for listening to connections
|
||||
* @return WOLFSSL_SUCCESS - ClientHello containing a valid cookie was received
|
||||
* The connection can be continued with wolfSSL_accept
|
||||
* WOLFSSL_FAILURE - The I/O layer returned WANT_READ. This is either
|
||||
* because there is no data to read and we are using
|
||||
* non-blocking sockets or we sent a cookie request
|
||||
* and we are waiting for a reply. The user should
|
||||
* call wolfDTLS_accept_stateless again after data
|
||||
* becomes available in the I/O layer.
|
||||
* WOLFSSL_FATAL_ERROR - A fatal error occurred. The ssl object should
|
||||
* be free'd and allocated again to continue.
|
||||
*/
|
||||
int wolfDTLS_accept_stateless(WOLFSSL* ssl)
|
||||
{
|
||||
byte disableRead;
|
||||
int ret = WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR);
|
||||
struct chGoodDisableReadCbCtx cb;
|
||||
|
||||
WOLFSSL_ENTER("wolfDTLS_SetChGoodCb");
|
||||
|
||||
if (ssl == NULL)
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
|
||||
/* Save this to restore it later */
|
||||
disableRead = (byte)ssl->options.disableRead;
|
||||
cb.userCb = ssl->chGoodCb;
|
||||
cb.userCtx = ssl->chGoodCtx;
|
||||
|
||||
/* Register our own callback so that we can disable reading */
|
||||
if (wolfDTLS_SetChGoodCb(ssl, chGoodDisableReadCB, &cb) != WOLFSSL_SUCCESS)
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
|
||||
ret = wolfSSL_accept(ssl);
|
||||
/* restore user options */
|
||||
ssl->options.disableRead = disableRead;
|
||||
(void)wolfDTLS_SetChGoodCb(ssl, cb.userCb, cb.userCtx);
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
WOLFSSL_MSG("should not happen. maybe the user called "
|
||||
"wolfDTLS_accept_stateless instead of wolfSSL_accept");
|
||||
}
|
||||
else if (ssl->error == WC_NO_ERR_TRACE(WANT_READ)) {
|
||||
if (ssl->options.dtlsStateful)
|
||||
ret = WOLFSSL_SUCCESS;
|
||||
else
|
||||
ret = WOLFSSL_FAILURE;
|
||||
}
|
||||
else {
|
||||
ret = WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wolfDTLS_SetChGoodCb(WOLFSSL* ssl, ClientHelloGoodCb cb, void* user_ctx)
|
||||
{
|
||||
WOLFSSL_ENTER("wolfDTLS_SetChGoodCb");
|
||||
|
|
31
src/tls13.c
31
src/tls13.c
|
@ -2413,6 +2413,9 @@ static WC_INLINE void WriteSEQTls13(WOLFSSL* ssl, int verifyOrder, byte* out)
|
|||
if (seq[1] > ssl->keys.sequence_number_lo)
|
||||
ssl->keys.sequence_number_hi++;
|
||||
}
|
||||
#ifdef WOLFSSL_DEBUG_TLS
|
||||
WOLFSSL_MSG_EX("TLS 1.3 Write Sequence %d %d", seq[0], seq[1]);
|
||||
#endif
|
||||
|
||||
c32toa(seq[0], out);
|
||||
c32toa(seq[1], out + OPAQUE32_LEN);
|
||||
|
@ -2428,14 +2431,11 @@ static WC_INLINE void WriteSEQTls13(WOLFSSL* ssl, int verifyOrder, byte* out)
|
|||
static WC_INLINE void BuildTls13Nonce(WOLFSSL* ssl, byte* nonce, const byte* iv,
|
||||
int order)
|
||||
{
|
||||
int i;
|
||||
|
||||
int seq_offset = AEAD_NONCE_SZ - SEQ_SZ;
|
||||
/* The nonce is the IV with the sequence XORed into the last bytes. */
|
||||
WriteSEQTls13(ssl, order, nonce + AEAD_NONCE_SZ - SEQ_SZ);
|
||||
for (i = 0; i < AEAD_NONCE_SZ - SEQ_SZ; i++)
|
||||
nonce[i] = iv[i];
|
||||
for (; i < AEAD_NONCE_SZ; i++)
|
||||
nonce[i] ^= iv[i];
|
||||
WriteSEQTls13(ssl, order, nonce + seq_offset);
|
||||
XMEMCPY(nonce, iv, seq_offset);
|
||||
xorbuf(nonce + seq_offset, iv + seq_offset, SEQ_SZ);
|
||||
}
|
||||
|
||||
#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
|
||||
|
@ -3621,6 +3621,7 @@ int CreateCookieExt(const WOLFSSL* ssl, byte* hash, word16 hashSz,
|
|||
#ifdef WOLFSSL_DTLS13
|
||||
/* Tie cookie to peer address */
|
||||
if (ret == 0) {
|
||||
/* peerLock not necessary. Still in handshake phase. */
|
||||
if (ssl->options.dtls && ssl->buffers.dtlsCtx.peer.sz > 0) {
|
||||
ret = wc_HmacUpdate(&cookieHmac,
|
||||
(byte*)ssl->buffers.dtlsCtx.peer.sa,
|
||||
|
@ -6409,6 +6410,7 @@ int TlsCheckCookie(const WOLFSSL* ssl, const byte* cookie, word16 cookieSz)
|
|||
#ifdef WOLFSSL_DTLS13
|
||||
/* Tie cookie to peer address */
|
||||
if (ret == 0) {
|
||||
/* peerLock not necessary. Still in handshake phase. */
|
||||
if (ssl->options.dtls && ssl->buffers.dtlsCtx.peer.sz > 0) {
|
||||
ret = wc_HmacUpdate(&cookieHmac,
|
||||
(byte*)ssl->buffers.dtlsCtx.peer.sa,
|
||||
|
@ -10905,6 +10907,7 @@ int DoTls13Finished(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
|||
/* Force input exhaustion at ProcessReply by consuming padSz. */
|
||||
*inOutIdx += size + ssl->keys.padSz;
|
||||
|
||||
#ifndef NO_WOLFSSL_SERVER
|
||||
if (ssl->options.side == WOLFSSL_SERVER_END &&
|
||||
!ssl->options.handShakeDone) {
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
|
@ -10917,6 +10920,7 @@ int DoTls13Finished(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
|||
if ((ret = SetKeysSide(ssl, DECRYPT_SIDE_ONLY)) != 0)
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef NO_WOLFSSL_CLIENT
|
||||
if (ssl->options.side == WOLFSSL_CLIENT_END)
|
||||
|
@ -11149,14 +11153,14 @@ static int SendTls13Finished(WOLFSSL* ssl)
|
|||
!ssl->options.handShakeDone) {
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
if (ssl->earlyData != no_early_data) {
|
||||
if ((ret = DeriveTls13Keys(ssl, no_key, ENCRYPT_AND_DECRYPT_SIDE,
|
||||
if ((ret = DeriveTls13Keys(ssl, no_key, ENCRYPT_SIDE_ONLY,
|
||||
1)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* Setup keys for application data messages. */
|
||||
if ((ret = SetKeysSide(ssl, ENCRYPT_AND_DECRYPT_SIDE)) != 0)
|
||||
if ((ret = SetKeysSide(ssl, ENCRYPT_SIDE_ONLY)) != 0)
|
||||
return ret;
|
||||
|
||||
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
|
||||
|
@ -12831,12 +12835,21 @@ int DoTls13HandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
|||
ssl->earlyData == no_early_data)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
if (ssl->earlyData != no_early_data) {
|
||||
if ((ret = DeriveTls13Keys(ssl, no_key, DECRYPT_SIDE_ONLY,
|
||||
1)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if ((ret = DeriveTls13Keys(ssl, traffic_key,
|
||||
ENCRYPT_AND_DECRYPT_SIDE, 1)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
/* Setup keys for application data messages. */
|
||||
if ((ret = SetKeysSide(ssl, DECRYPT_SIDE_ONLY)) != 0)
|
||||
return ret;
|
||||
}
|
||||
#ifdef WOLFSSL_POST_HANDSHAKE_AUTH
|
||||
if (type == certificate_request &&
|
||||
|
|
119
src/wolfio.c
119
src/wolfio.c
|
@ -569,7 +569,7 @@ STATIC int nucyassl_sendto(INT sd, CHAR *buf, UINT16 sz, INT16 flags,
|
|||
#define DTLS_RECVFROM_FUNCTION recvfrom
|
||||
#endif
|
||||
|
||||
static int sockAddrEqual(
|
||||
int sockAddrEqual(
|
||||
SOCKADDR_S *a, XSOCKLENT aLen, SOCKADDR_S *b, XSOCKLENT bLen)
|
||||
{
|
||||
if (aLen != bLen)
|
||||
|
@ -660,8 +660,17 @@ int EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx)
|
|||
word32 invalidPeerPackets = 0;
|
||||
#endif
|
||||
int newPeer = 0;
|
||||
int ret = 0;
|
||||
|
||||
WOLFSSL_ENTER("EmbedReceiveFrom");
|
||||
(void)ret; /* possibly unused */
|
||||
|
||||
XMEMSET(&lclPeer, 0, sizeof(lclPeer));
|
||||
|
||||
#ifdef WOLFSSL_RW_THREADED
|
||||
if (wc_LockRwLock_Rd(&ssl->buffers.dtlsCtx.peerLock) != 0)
|
||||
return WOLFSSL_CBIO_ERR_GENERAL;
|
||||
#endif
|
||||
|
||||
if (dtlsCtx->connected) {
|
||||
peer = NULL;
|
||||
|
@ -670,33 +679,32 @@ int EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx)
|
|||
#ifndef WOLFSSL_IPV6
|
||||
if (PeerIsIpv6((SOCKADDR_S*)dtlsCtx->peer.sa, dtlsCtx->peer.sz)) {
|
||||
WOLFSSL_MSG("ipv6 dtls peer set but no ipv6 support compiled");
|
||||
return NOT_COMPILED_IN;
|
||||
ret = WOLFSSL_CBIO_ERR_GENERAL;
|
||||
}
|
||||
#endif
|
||||
peer = &lclPeer;
|
||||
XMEMSET(&lclPeer, 0, sizeof(lclPeer));
|
||||
peerSz = sizeof(lclPeer);
|
||||
}
|
||||
else {
|
||||
/* Store the peer address. It is used to calculate the DTLS cookie. */
|
||||
if (dtlsCtx->peer.sa == NULL) {
|
||||
dtlsCtx->peer.sa = (void*)XMALLOC(sizeof(SOCKADDR_S),
|
||||
ssl->heap, DYNAMIC_TYPE_SOCKADDR);
|
||||
dtlsCtx->peer.sz = 0;
|
||||
if (dtlsCtx->peer.sa != NULL)
|
||||
dtlsCtx->peer.bufSz = sizeof(SOCKADDR_S);
|
||||
else
|
||||
dtlsCtx->peer.bufSz = 0;
|
||||
newPeer = 1;
|
||||
peer = (SOCKADDR_S*)dtlsCtx->peer.sa;
|
||||
}
|
||||
else {
|
||||
newPeer = dtlsCtx->peer.sa == NULL || !ssl->options.dtlsStateful;
|
||||
peer = &lclPeer;
|
||||
XMEMCPY(peer, (SOCKADDR_S*)dtlsCtx->peer.sa, sizeof(lclPeer));
|
||||
if (dtlsCtx->peer.sa != NULL) {
|
||||
XMEMCPY(peer, (SOCKADDR_S*)dtlsCtx->peer.sa, MIN(sizeof(lclPeer),
|
||||
dtlsCtx->peer.sz));
|
||||
}
|
||||
peerSz = dtlsCtx->peer.bufSz;
|
||||
peerSz = sizeof(lclPeer);
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_RW_THREADED
|
||||
/* We make a copy above to avoid holding the lock for the entire function */
|
||||
if (wc_UnLockRwLock(&ssl->buffers.dtlsCtx.peerLock) != 0)
|
||||
return WOLFSSL_CBIO_ERR_GENERAL;
|
||||
#endif
|
||||
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
/* Don't use ssl->options.handShakeDone since it is true even if
|
||||
* we are in the process of renegotiation */
|
||||
doDtlsTimeout = ssl->options.handShakeState != HANDSHAKE_DONE;
|
||||
|
@ -705,12 +713,9 @@ int EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx)
|
|||
if (ssl->options.dtls && IsAtLeastTLSv1_3(ssl->version)) {
|
||||
doDtlsTimeout = doDtlsTimeout || ssl->dtls13Rtx.rtxRecords != NULL;
|
||||
#ifdef WOLFSSL_RW_THREADED
|
||||
{
|
||||
int ret = wc_LockMutex(&ssl->dtls13Rtx.mutex);
|
||||
if (ret < 0) {
|
||||
ret = wc_LockMutex(&ssl->dtls13Rtx.mutex);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
doDtlsTimeout = doDtlsTimeout ||
|
||||
(ssl->dtls13FastTimeout && ssl->dtls13Rtx.seenRecords != NULL);
|
||||
|
@ -781,26 +786,16 @@ int EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx)
|
|||
}
|
||||
#endif /* !NO_ASN_TIME */
|
||||
|
||||
recvd = (int)DTLS_RECVFROM_FUNCTION(sd, buf, (size_t)sz, ssl->rflags,
|
||||
(SOCKADDR*)peer, peer != NULL ? &peerSz : NULL);
|
||||
|
||||
/* From the RECV(2) man page
|
||||
{
|
||||
XSOCKLENT inPeerSz = peerSz;
|
||||
recvd = (int)DTLS_RECVFROM_FUNCTION(sd, buf, (size_t)sz,
|
||||
ssl->rflags, (SOCKADDR*)peer, peer != NULL ? &inPeerSz : NULL);
|
||||
/* Truncate peerSz. From the RECV(2) man page
|
||||
* The returned address is truncated if the buffer provided is too
|
||||
* small; in this case, addrlen will return a value greater than was
|
||||
* supplied to the call.
|
||||
*/
|
||||
if (dtlsCtx->connected) {
|
||||
/* No need to sanitize the value of peerSz */
|
||||
}
|
||||
else if (dtlsCtx->userSet) {
|
||||
/* Truncate peer size */
|
||||
if (peerSz > (XSOCKLENT)sizeof(lclPeer))
|
||||
peerSz = (XSOCKLENT)sizeof(lclPeer);
|
||||
}
|
||||
else {
|
||||
/* Truncate peer size */
|
||||
if (peerSz > (XSOCKLENT)dtlsCtx->peer.bufSz)
|
||||
peerSz = (XSOCKLENT)dtlsCtx->peer.bufSz;
|
||||
peerSz = MIN(peerSz, inPeerSz);
|
||||
}
|
||||
|
||||
recvd = TranslateIoReturnCode(recvd, sd, SOCKET_RECEIVING);
|
||||
|
@ -829,11 +824,23 @@ int EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx)
|
|||
}
|
||||
else if (dtlsCtx->userSet) {
|
||||
/* Check we received the packet from the correct peer */
|
||||
int ignore = 0;
|
||||
#ifdef WOLFSSL_RW_THREADED
|
||||
if (wc_LockRwLock_Rd(&ssl->buffers.dtlsCtx.peerLock) != 0)
|
||||
return WOLFSSL_CBIO_ERR_GENERAL;
|
||||
#endif
|
||||
if (dtlsCtx->peer.sz > 0 &&
|
||||
(peerSz != (XSOCKLENT)dtlsCtx->peer.sz ||
|
||||
!sockAddrEqual(peer, peerSz, (SOCKADDR_S*)dtlsCtx->peer.sa,
|
||||
dtlsCtx->peer.sz))) {
|
||||
WOLFSSL_MSG(" Ignored packet from invalid peer");
|
||||
ignore = 1;
|
||||
}
|
||||
#ifdef WOLFSSL_RW_THREADED
|
||||
if (wc_UnLockRwLock(&ssl->buffers.dtlsCtx.peerLock) != 0)
|
||||
return WOLFSSL_CBIO_ERR_GENERAL;
|
||||
#endif
|
||||
if (ignore) {
|
||||
#if defined(NO_ASN_TIME) && \
|
||||
!defined(DTLS_RECEIVEFROM_NO_TIMEOUT_ON_INVALID_PEER)
|
||||
if (doDtlsTimeout) {
|
||||
|
@ -849,13 +856,27 @@ int EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx)
|
|||
}
|
||||
else {
|
||||
if (newPeer) {
|
||||
/* Store size of saved address */
|
||||
dtlsCtx->peer.sz = peerSz;
|
||||
/* Store size of saved address. Locking handled internally. */
|
||||
if (wolfSSL_dtls_set_peer(ssl, peer, peerSz) != WOLFSSL_SUCCESS)
|
||||
return WOLFSSL_CBIO_ERR_GENERAL;
|
||||
}
|
||||
#ifndef WOLFSSL_PEER_ADDRESS_CHANGES
|
||||
else if ((dtlsCtx->peer.sz != (unsigned int)peerSz) ||
|
||||
(XMEMCMP(peer, dtlsCtx->peer.sa, peerSz) != 0)) {
|
||||
else {
|
||||
ret = 0;
|
||||
#ifdef WOLFSSL_RW_THREADED
|
||||
if (wc_LockRwLock_Rd(&ssl->buffers.dtlsCtx.peerLock) != 0)
|
||||
return WOLFSSL_CBIO_ERR_GENERAL;
|
||||
#endif
|
||||
if (!sockAddrEqual(peer, peerSz, (SOCKADDR_S*)dtlsCtx->peer.sa,
|
||||
dtlsCtx->peer.sz)) {
|
||||
ret = WOLFSSL_CBIO_ERR_GENERAL;
|
||||
}
|
||||
#ifdef WOLFSSL_RW_THREADED
|
||||
if (wc_UnLockRwLock(&ssl->buffers.dtlsCtx.peerLock) != 0)
|
||||
return WOLFSSL_CBIO_ERR_GENERAL;
|
||||
#endif
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -2351,6 +2372,20 @@ void wolfSSL_SSLSetIOSend(WOLFSSL *ssl, CallbackIOSend CBIOSend)
|
|||
}
|
||||
}
|
||||
|
||||
void wolfSSL_SSLDisableRead(WOLFSSL *ssl)
|
||||
{
|
||||
if (ssl) {
|
||||
ssl->options.disableRead = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void wolfSSL_SSLEnableRead(WOLFSSL *ssl)
|
||||
{
|
||||
if (ssl) {
|
||||
ssl->options.disableRead = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void wolfSSL_SetIOReadCtx(WOLFSSL* ssl, void *rctx)
|
||||
{
|
||||
|
|
219
tests/api.c
219
tests/api.c
|
@ -90317,7 +90317,7 @@ static void test_wolfSSL_dtls_plaintext_server(WOLFSSL* ssl)
|
|||
static void test_wolfSSL_dtls_plaintext_client(WOLFSSL* ssl)
|
||||
{
|
||||
byte ch[50];
|
||||
int fd = wolfSSL_get_fd(ssl);
|
||||
int fd = wolfSSL_get_wfd(ssl);
|
||||
byte msg[] = "This is a msg for the server";
|
||||
byte reply[40];
|
||||
|
||||
|
@ -90387,7 +90387,7 @@ static void test_wolfSSL_dtls12_fragments_spammer(WOLFSSL* ssl)
|
|||
size_t seq_offset = 0;
|
||||
size_t msg_offset = 0;
|
||||
int i;
|
||||
int fd = wolfSSL_get_fd(ssl);
|
||||
int fd = wolfSSL_get_wfd(ssl);
|
||||
int ret = wolfSSL_connect_cert(ssl); /* This gets us past the cookie */
|
||||
word32 seq_number = 100; /* start high so server definitely reads this */
|
||||
word16 msg_number = 50; /* start high so server has to buffer this */
|
||||
|
@ -90449,7 +90449,7 @@ static void test_wolfSSL_dtls13_fragments_spammer(WOLFSSL* ssl)
|
|||
byte b[150]; /* buffer for the messages to send */
|
||||
size_t idx = 0;
|
||||
size_t msg_offset = 0;
|
||||
int fd = wolfSSL_get_fd(ssl);
|
||||
int fd = wolfSSL_get_wfd(ssl);
|
||||
word16 msg_number = 10; /* start high so server has to buffer this */
|
||||
int ret = wolfSSL_connect_cert(ssl); /* This gets us past the cookie */
|
||||
AssertIntEQ(ret, 1);
|
||||
|
@ -90554,7 +90554,7 @@ static void test_wolfSSL_dtls_send_alert(WOLFSSL* ssl)
|
|||
0x46 /* protocol version */
|
||||
};
|
||||
|
||||
fd = wolfSSL_get_fd(ssl);
|
||||
fd = wolfSSL_get_wfd(ssl);
|
||||
ret = (int)send(fd, alert_msg, sizeof(alert_msg), 0);
|
||||
AssertIntGT(ret, 0);
|
||||
}
|
||||
|
@ -90624,7 +90624,7 @@ static void test_wolfSSL_send_bad_record(WOLFSSL* ssl)
|
|||
0x03, 0x18, 0x72
|
||||
};
|
||||
|
||||
fd = wolfSSL_get_fd(ssl);
|
||||
fd = wolfSSL_get_wfd(ssl);
|
||||
AssertIntGE(fd, 0);
|
||||
ret = (int)send(fd, bad_msg, sizeof(bad_msg), 0);
|
||||
AssertIntEQ(ret, sizeof(bad_msg));
|
||||
|
@ -90951,7 +90951,7 @@ static void test_wolfSSL_dtls_send_ch(WOLFSSL* ssl)
|
|||
0x31, 0x68, 0x4c
|
||||
};
|
||||
|
||||
fd = wolfSSL_get_fd(ssl);
|
||||
fd = wolfSSL_get_wfd(ssl);
|
||||
ret = (int)send(fd, ch_msg, sizeof(ch_msg), 0);
|
||||
AssertIntGT(ret, 0);
|
||||
/* consume the HRR otherwise handshake will fail */
|
||||
|
@ -91022,7 +91022,7 @@ static void test_wolfSSL_dtls_send_ch_with_invalid_cookie(WOLFSSL* ssl)
|
|||
0x02, 0x02, 0x2f
|
||||
};
|
||||
|
||||
fd = wolfSSL_get_fd(ssl);
|
||||
fd = wolfSSL_get_wfd(ssl);
|
||||
ret = (int)send(fd, ch_msh_invalid_cookie, sizeof(ch_msh_invalid_cookie), 0);
|
||||
AssertIntGT(ret, 0);
|
||||
/* should reply with an illegal_parameter reply */
|
||||
|
@ -94637,18 +94637,31 @@ static int test_wolfSSL_dtls_stateless2(void)
|
|||
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);
|
||||
ExpectNotNull(ssl_c2 = wolfSSL_new(ctx_c));
|
||||
wolfSSL_SetIOWriteCtx(ssl_c2, &test_ctx);
|
||||
wolfSSL_SetIOReadCtx(ssl_c2, &test_ctx);
|
||||
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, NULL, &ssl_c2, NULL,
|
||||
wolfDTLSv1_2_client_method, NULL), 0);
|
||||
ExpectFalse(wolfSSL_is_stateful(ssl_s));
|
||||
/* send CH */
|
||||
ExpectTrue((wolfSSL_connect(ssl_c2) == WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)) &&
|
||||
(ssl_c2->error == WC_NO_ERR_TRACE(WANT_READ)));
|
||||
ExpectTrue((wolfSSL_accept(ssl_s) == WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)) &&
|
||||
(ssl_s->error == WC_NO_ERR_TRACE(WANT_READ)));
|
||||
ExpectIntEQ(wolfDTLS_accept_stateless(ssl_s), WOLFSSL_FAILURE);
|
||||
ExpectFalse(wolfSSL_is_stateful(ssl_s));
|
||||
ExpectIntNE(test_ctx.c_len, 0);
|
||||
/* consume HRR */
|
||||
test_ctx.c_len = 0;
|
||||
/* send CH1 */
|
||||
ExpectIntEQ(wolfSSL_connect(ssl_c), WOLFSSL_FATAL_ERROR);
|
||||
ExpectIntEQ(wolfSSL_get_error(ssl_c, WOLFSSL_FATAL_ERROR),
|
||||
WOLFSSL_ERROR_WANT_READ);
|
||||
/* send HRR */
|
||||
ExpectIntEQ(wolfDTLS_accept_stateless(ssl_s), WOLFSSL_FAILURE);
|
||||
/* send CH2 */
|
||||
ExpectIntEQ(wolfSSL_connect(ssl_c), WOLFSSL_FATAL_ERROR);
|
||||
ExpectIntEQ(wolfSSL_get_error(ssl_c, WOLFSSL_FATAL_ERROR),
|
||||
WOLFSSL_ERROR_WANT_READ);
|
||||
/* send HRR */
|
||||
ExpectIntEQ(wolfDTLS_accept_stateless(ssl_s), WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
|
||||
ExpectTrue(wolfSSL_is_stateful(ssl_s));
|
||||
|
||||
wolfSSL_free(ssl_c2);
|
||||
wolfSSL_free(ssl_c);
|
||||
|
@ -99223,7 +99236,7 @@ static int test_dtls12_basic_connection_id(void)
|
|||
#endif /* WOLFSSL_AES_128 && WOLFSSL_STATIC_RSA */
|
||||
#endif /* NO_SHA256 */
|
||||
#endif /* NO_RSA */
|
||||
#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
|
||||
#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) && !defined(HAVE_FIPS)
|
||||
"DHE-RSA-CHACHA20-POLY1305",
|
||||
"DHE-RSA-CHACHA20-POLY1305-OLD",
|
||||
"ECDHE-RSA-CHACHA20-POLY1305",
|
||||
|
@ -99232,7 +99245,7 @@ static int test_dtls12_basic_connection_id(void)
|
|||
#ifndef NO_PSK
|
||||
"DHE-PSK-AES128-CBC-SHA256",
|
||||
"DHE-PSK-AES256-GCM-SHA384",
|
||||
#ifndef HAVE_NULL_CIPHER
|
||||
#ifdef HAVE_NULL_CIPHER
|
||||
"DHE-PSK-NULL-SHA256",
|
||||
#endif
|
||||
"DHE-PSK-AES128-CCM",
|
||||
|
@ -99550,7 +99563,7 @@ static int test_dtls13_basic_connection_id(void)
|
|||
&& 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, 6, 7, 8, 9 };
|
||||
unsigned char readBuf[30];
|
||||
unsigned char readBuf[50];
|
||||
const char* params[] = {
|
||||
#ifndef NO_SHA256
|
||||
#ifdef WOLFSSL_AES_128
|
||||
|
@ -99969,9 +99982,11 @@ static int test_tls13_early_data(void)
|
|||
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
|
||||
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
|
||||
params[i].client_meth, params[i].server_meth), 0);
|
||||
wolfSSL_SetLoggingPrefix("client");
|
||||
ExpectIntEQ(wolfSSL_set_session(ssl_c, sess), WOLFSSL_SUCCESS);
|
||||
#ifdef WOLFSSL_DTLS13
|
||||
if (params[i].isUdp) {
|
||||
wolfSSL_SetLoggingPrefix("server");
|
||||
#ifdef WOLFSSL_DTLS13_NO_HRR_ON_RESUME
|
||||
ExpectIntEQ(wolfSSL_dtls13_no_hrr_on_resume(ssl_s, 1), WOLFSSL_SUCCESS);
|
||||
#else
|
||||
|
@ -99983,6 +99998,7 @@ static int test_tls13_early_data(void)
|
|||
#endif
|
||||
|
||||
/* Test 0-RTT data */
|
||||
wolfSSL_SetLoggingPrefix("client");
|
||||
ExpectIntEQ(wolfSSL_write_early_data(ssl_c, msg, sizeof(msg),
|
||||
&written), sizeof(msg));
|
||||
ExpectIntEQ(written, sizeof(msg));
|
||||
|
@ -99994,6 +100010,7 @@ static int test_tls13_early_data(void)
|
|||
}
|
||||
|
||||
/* Read first 0-RTT data (if split otherwise entire data) */
|
||||
wolfSSL_SetLoggingPrefix("server");
|
||||
ExpectIntEQ(wolfSSL_read_early_data(ssl_s, msgBuf, sizeof(msgBuf),
|
||||
&read), sizeof(msg));
|
||||
ExpectIntEQ(read, sizeof(msg));
|
||||
|
@ -100011,6 +100028,7 @@ static int test_tls13_early_data(void)
|
|||
}
|
||||
|
||||
if (params[i].isUdp) {
|
||||
wolfSSL_SetLoggingPrefix("client");
|
||||
ExpectIntEQ(wolfSSL_connect(ssl_c), -1);
|
||||
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WC_NO_ERR_TRACE(APP_DATA_READY));
|
||||
|
||||
|
@ -100027,17 +100045,21 @@ static int test_tls13_early_data(void)
|
|||
* handshake status to us with non-blocking IO and we can't use
|
||||
* wolfSSL_accept as TLS layer may return ZERO_RETURN due to early data
|
||||
* parsing logic. */
|
||||
wolfSSL_SetLoggingPrefix("server");
|
||||
ExpectFalse(wolfSSL_is_init_finished(ssl_s));
|
||||
ExpectIntEQ(wolfSSL_read_early_data(ssl_s, msgBuf, sizeof(msgBuf),
|
||||
&read), 0);
|
||||
ExpectIntEQ(read, 0);
|
||||
ExpectTrue(wolfSSL_is_init_finished(ssl_s));
|
||||
|
||||
wolfSSL_SetLoggingPrefix("client");
|
||||
ExpectIntEQ(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
|
||||
}
|
||||
else {
|
||||
wolfSSL_SetLoggingPrefix("client");
|
||||
ExpectIntEQ(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
|
||||
|
||||
wolfSSL_SetLoggingPrefix("server");
|
||||
ExpectFalse(wolfSSL_is_init_finished(ssl_s));
|
||||
ExpectIntEQ(wolfSSL_read_early_data(ssl_s, msgBuf, sizeof(msgBuf),
|
||||
&read), 0);
|
||||
|
@ -100045,18 +100067,23 @@ static int test_tls13_early_data(void)
|
|||
ExpectTrue(wolfSSL_is_init_finished(ssl_s));
|
||||
|
||||
/* Read server 0.5-RTT data */
|
||||
wolfSSL_SetLoggingPrefix("client");
|
||||
ExpectIntEQ(wolfSSL_read(ssl_c, msgBuf, sizeof(msgBuf)), sizeof(msg4));
|
||||
ExpectStrEQ(msg4, msgBuf);
|
||||
}
|
||||
|
||||
/* Test bi-directional write */
|
||||
wolfSSL_SetLoggingPrefix("client");
|
||||
ExpectIntEQ(wolfSSL_write(ssl_c, msg2, sizeof(msg2)), sizeof(msg2));
|
||||
wolfSSL_SetLoggingPrefix("server");
|
||||
ExpectIntEQ(wolfSSL_read(ssl_s, msgBuf, sizeof(msgBuf)), sizeof(msg2));
|
||||
ExpectStrEQ(msg2, msgBuf);
|
||||
ExpectIntEQ(wolfSSL_write(ssl_s, msg3, sizeof(msg3)), sizeof(msg3));
|
||||
wolfSSL_SetLoggingPrefix("client");
|
||||
ExpectIntEQ(wolfSSL_read(ssl_c, msgBuf, sizeof(msgBuf)), sizeof(msg3));
|
||||
ExpectStrEQ(msg3, msgBuf);
|
||||
|
||||
wolfSSL_SetLoggingPrefix(NULL);
|
||||
ExpectTrue(wolfSSL_session_reused(ssl_c));
|
||||
ExpectTrue(wolfSSL_session_reused(ssl_s));
|
||||
|
||||
|
@ -100909,6 +100936,165 @@ static int test_ocsp_callback_fails(void)
|
|||
defined(HAVE_OCSP) && \
|
||||
defined(HAVE_CERTIFICATE_STATUS_REQUEST) */
|
||||
|
||||
#ifdef HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES
|
||||
static int test_wolfSSL_SSLDisableRead_recv(WOLFSSL *ssl, char *buf, int sz,
|
||||
void *ctx)
|
||||
{
|
||||
(void)ssl;
|
||||
(void)buf;
|
||||
(void)sz;
|
||||
(void)ctx;
|
||||
return WOLFSSL_CBIO_ERR_GENERAL;
|
||||
}
|
||||
|
||||
static int test_wolfSSL_SSLDisableRead(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
WOLFSSL_CTX *ctx_c = NULL;
|
||||
WOLFSSL *ssl_c = NULL;
|
||||
struct test_memio_ctx test_ctx;
|
||||
|
||||
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
|
||||
|
||||
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, NULL, &ssl_c, NULL,
|
||||
wolfTLS_client_method, NULL), 0);
|
||||
wolfSSL_SSLSetIORecv(ssl_c, test_wolfSSL_SSLDisableRead_recv);
|
||||
wolfSSL_SSLDisableRead(ssl_c);
|
||||
|
||||
/* Disabling reading should not even go into the IO layer */
|
||||
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
|
||||
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
|
||||
wolfSSL_SSLEnableRead(ssl_c);
|
||||
/* By enabling reading we should reach the IO that will return an error */
|
||||
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
|
||||
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), SOCKET_ERROR_E);
|
||||
|
||||
wolfSSL_free(ssl_c);
|
||||
wolfSSL_CTX_free(ctx_c);
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
#else
|
||||
static int test_wolfSSL_SSLDisableRead(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
#endif
|
||||
|
||||
static int test_wolfSSL_inject(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES)
|
||||
size_t i;
|
||||
struct {
|
||||
method_provider client_meth;
|
||||
method_provider server_meth;
|
||||
const char* tls_version;
|
||||
} params[] = {
|
||||
#if defined(WOLFSSL_TLS13)
|
||||
/* With WOLFSSL_TLS13_MIDDLEBOX_COMPAT a short ID will result in an error */
|
||||
{ wolfTLSv1_3_client_method, wolfTLSv1_3_server_method, "TLSv1_3" },
|
||||
#ifdef WOLFSSL_DTLS13
|
||||
{ wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method, "DTLSv1_3" },
|
||||
#endif
|
||||
#endif
|
||||
#ifndef WOLFSSL_NO_TLS12
|
||||
{ wolfTLSv1_2_client_method, wolfTLSv1_2_server_method, "TLSv1_2" },
|
||||
#ifdef WOLFSSL_DTLS
|
||||
{ wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method, "DTLSv1_2" },
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(NO_OLD_TLS)
|
||||
{ wolfTLSv1_1_client_method, wolfTLSv1_1_server_method, "TLSv1_1" },
|
||||
#ifdef WOLFSSL_DTLS
|
||||
{ wolfDTLSv1_client_method, wolfDTLSv1_server_method, "DTLSv1_0" },
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
for (i = 0; i < XELEM_CNT(params) && !EXPECT_FAIL(); i++) {
|
||||
WOLFSSL_CTX *ctx_c = NULL;
|
||||
WOLFSSL_CTX *ctx_s = NULL;
|
||||
WOLFSSL *ssl_c = NULL;
|
||||
WOLFSSL *ssl_s = NULL;
|
||||
struct test_memio_ctx test_ctx;
|
||||
WOLFSSL_ALERT_HISTORY h;
|
||||
int rounds;
|
||||
|
||||
printf("Testing %s\n", params[i].tls_version);
|
||||
|
||||
XMEMSET(&h, 0, sizeof(h));
|
||||
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
|
||||
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
|
||||
params[i].client_meth, params[i].server_meth), 0);
|
||||
|
||||
for (rounds = 0; rounds < 10 && EXPECT_SUCCESS(); rounds++) {
|
||||
wolfSSL_SetLoggingPrefix("client");
|
||||
if (wolfSSL_negotiate(ssl_c) != 1) {
|
||||
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1),
|
||||
WOLFSSL_ERROR_WANT_READ);
|
||||
}
|
||||
wolfSSL_SetLoggingPrefix("server");
|
||||
if (test_ctx.s_len > 0) {
|
||||
ExpectIntEQ(wolfSSL_inject(ssl_s, test_ctx.s_buff,
|
||||
test_ctx.s_len), 1);
|
||||
test_ctx.s_len = 0;
|
||||
}
|
||||
if (wolfSSL_negotiate(ssl_s) != 1) {
|
||||
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1),
|
||||
WOLFSSL_ERROR_WANT_READ);
|
||||
}
|
||||
wolfSSL_SetLoggingPrefix("client");
|
||||
if (test_ctx.c_len > 0) {
|
||||
ExpectIntEQ(wolfSSL_inject(ssl_c, test_ctx.c_buff,
|
||||
test_ctx.c_len), 1);
|
||||
test_ctx.c_len = 0;
|
||||
}
|
||||
wolfSSL_SetLoggingPrefix(NULL);
|
||||
}
|
||||
ExpectIntEQ(wolfSSL_negotiate(ssl_c), 1);
|
||||
ExpectIntEQ(wolfSSL_negotiate(ssl_s), 1);
|
||||
|
||||
wolfSSL_free(ssl_c);
|
||||
wolfSSL_free(ssl_s);
|
||||
wolfSSL_CTX_free(ctx_c);
|
||||
wolfSSL_CTX_free(ctx_s);
|
||||
}
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
static int test_wolfSSL_dtls_cid_parse(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_DTLS_CID)
|
||||
/* Taken from Wireshark. Right-click -> copy -> ... as escaped string */
|
||||
/* Plaintext ServerHelloDone. No CID. */
|
||||
byte noCid[] =
|
||||
"\x16\xfe\xfd\x00\x00\x00\x00\x00\x00\x00\x04\x00\x0c\x0e\x00\x00" \
|
||||
"\x00\x00\x04\x00\x00\x00\x00\x00\x00";
|
||||
/* 1.2 app data containing CID */
|
||||
byte cid12[] =
|
||||
"\x19\xfe\xfd\x00\x01\x00\x00\x00\x00\x00\x01\x77\xa3\x79\x34\xb3" \
|
||||
"\xf1\x1f\x34\x00\x1f\xdb\x8c\x28\x25\x9f\xe1\x02\x26\x77\x1c\x3a" \
|
||||
"\x50\x1b\x50\x99\xd0\xb5\x20\xd8\x2c\x2e\xaa\x36\x36\xe0\xb7\xb7" \
|
||||
"\xf7\x7d\xff\xb0";
|
||||
#ifdef WOLFSSL_DTLS13
|
||||
/* 1.3 app data containing CID */
|
||||
byte cid13[] =
|
||||
"\x3f\x70\x64\x04\xc6\xfb\x97\x21\xd9\x28\x27\x00\x17\xc1\x01\x86" \
|
||||
"\xe7\x23\x2c\xad\x65\x83\xa8\xf4\xbf\xbf\x7b\x25\x16\x80\x19\xc3" \
|
||||
"\x81\xda\xf5\x3f";
|
||||
#endif
|
||||
|
||||
ExpectPtrEq(wolfSSL_dtls_cid_parse(noCid, sizeof(noCid), 8), NULL);
|
||||
ExpectPtrEq(wolfSSL_dtls_cid_parse(cid12, sizeof(cid12), 8), cid12 + 11);
|
||||
#ifdef WOLFSSL_DTLS13
|
||||
ExpectPtrEq(wolfSSL_dtls_cid_parse(cid13, sizeof(cid13), 8), cid13 + 1);
|
||||
#endif
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
| Main
|
||||
|
@ -102316,6 +102502,9 @@ TEST_CASE testCases[] = {
|
|||
TEST_DECL(test_get_signature_nid),
|
||||
TEST_DECL(test_tls_cert_store_unchanged),
|
||||
TEST_DECL(test_wolfSSL_SendUserCanceled),
|
||||
TEST_DECL(test_wolfSSL_SSLDisableRead),
|
||||
TEST_DECL(test_wolfSSL_inject),
|
||||
TEST_DECL(test_wolfSSL_dtls_cid_parse),
|
||||
/* This test needs to stay at the end to clean up any caches allocated. */
|
||||
TEST_DECL(test_wolfSSL_Cleanup)
|
||||
};
|
||||
|
|
|
@ -2764,7 +2764,16 @@ struct WOLFSSL_SOCKADDR {
|
|||
};
|
||||
|
||||
typedef struct WOLFSSL_DTLS_CTX {
|
||||
#ifdef WOLFSSL_RW_THREADED
|
||||
/* Protect peer access after the handshake */
|
||||
wolfSSL_RwLock peerLock;
|
||||
#endif
|
||||
WOLFSSL_SOCKADDR peer;
|
||||
#ifdef WOLFSSL_DTLS_CID
|
||||
WOLFSSL_SOCKADDR pendingPeer; /* When using CID's, we don't want to update
|
||||
* the peer's address until we successfully
|
||||
* de-protect the record. */
|
||||
#endif
|
||||
int rfd;
|
||||
int wfd;
|
||||
byte userSet:1;
|
||||
|
@ -2772,6 +2781,9 @@ typedef struct WOLFSSL_DTLS_CTX {
|
|||
* connected (connect() and bind() both called).
|
||||
* This means that sendto and recvfrom do not need to
|
||||
* specify and store the peer address. */
|
||||
#ifdef WOLFSSL_DTLS_CID
|
||||
byte processingPendingRecord:1;
|
||||
#endif
|
||||
} WOLFSSL_DTLS_CTX;
|
||||
|
||||
|
||||
|
@ -3718,6 +3730,7 @@ WOLFSSL_LOCAL int TLSX_ConnectionID_Parse(WOLFSSL* ssl, const byte* input,
|
|||
WOLFSSL_LOCAL void DtlsCIDOnExtensionsParsed(WOLFSSL* ssl);
|
||||
WOLFSSL_LOCAL byte DtlsCIDCheck(WOLFSSL* ssl, const byte* input,
|
||||
word16 inputSize);
|
||||
WOLFSSL_LOCAL int Dtls13UnifiedHeaderCIDPresent(byte flags);
|
||||
#endif /* WOLFSSL_DTLS_CID */
|
||||
WOLFSSL_LOCAL byte DtlsGetCidTxSize(WOLFSSL* ssl);
|
||||
WOLFSSL_LOCAL byte DtlsGetCidRxSize(WOLFSSL* ssl);
|
||||
|
@ -5061,6 +5074,7 @@ struct Options {
|
|||
#if defined(HAVE_DANE)
|
||||
word16 useDANE:1;
|
||||
#endif /* HAVE_DANE */
|
||||
word16 disableRead:1;
|
||||
#ifdef WOLFSSL_DTLS
|
||||
byte haveMcast; /* using multicast ? */
|
||||
#endif
|
||||
|
@ -6729,6 +6743,10 @@ WOLFSSL_LOCAL word32 MacSize(const WOLFSSL* ssl);
|
|||
WOLFSSL_LOCAL int DoClientHelloStateless(WOLFSSL* ssl,
|
||||
const byte* input, word32 helloSz, byte isFirstCHFrag, byte* tls13);
|
||||
#endif /* !defined(NO_WOLFSSL_SERVER) */
|
||||
#if !defined(WOLFCRYPT_ONLY) && defined(USE_WOLFSSL_IO)
|
||||
WOLFSSL_LOCAL int sockAddrEqual(SOCKADDR_S *a, XSOCKLENT aLen,
|
||||
SOCKADDR_S *b, XSOCKLENT bLen);
|
||||
#endif
|
||||
#endif /* WOLFSSL_DTLS */
|
||||
|
||||
#if defined(HAVE_SECURE_RENEGOTIATION) && defined(WOLFSSL_DTLS)
|
||||
|
|
|
@ -1359,6 +1359,7 @@ WOLFSSL_API const char* wolfSSL_get_shared_ciphers(WOLFSSL* ssl, char* buf,
|
|||
int len);
|
||||
WOLFSSL_API const char* wolfSSL_get_curve_name(WOLFSSL* ssl);
|
||||
WOLFSSL_API int wolfSSL_get_fd(const WOLFSSL* ssl);
|
||||
WOLFSSL_API int wolfSSL_get_wfd(const WOLFSSL* ssl);
|
||||
/* please see note at top of README if you get an error from connect */
|
||||
WOLFSSL_ABI WOLFSSL_API int wolfSSL_connect(WOLFSSL* ssl);
|
||||
WOLFSSL_ABI WOLFSSL_API int wolfSSL_write(
|
||||
|
@ -1366,6 +1367,7 @@ WOLFSSL_ABI WOLFSSL_API int wolfSSL_write(
|
|||
WOLFSSL_ABI WOLFSSL_API int wolfSSL_read(WOLFSSL* ssl, void* data, int sz);
|
||||
WOLFSSL_API int wolfSSL_peek(WOLFSSL* ssl, void* data, int sz);
|
||||
WOLFSSL_ABI WOLFSSL_API int wolfSSL_accept(WOLFSSL* ssl);
|
||||
WOLFSSL_API int wolfSSL_inject(WOLFSSL* ssl, const void* data, int sz);
|
||||
WOLFSSL_API int wolfSSL_CTX_mutual_auth(WOLFSSL_CTX* ctx, int req);
|
||||
WOLFSSL_API int wolfSSL_mutual_auth(WOLFSSL* ssl, int req);
|
||||
|
||||
|
@ -1733,8 +1735,16 @@ WOLFSSL_API int wolfSSL_dtls(WOLFSSL* ssl);
|
|||
WOLFSSL_API void* wolfSSL_dtls_create_peer(int port, char* ip);
|
||||
WOLFSSL_API int wolfSSL_dtls_free_peer(void* addr);
|
||||
|
||||
WOLFSSL_API int wolfSSL_dtls_set_peer(WOLFSSL* ssl, void* peer, unsigned int peerSz);
|
||||
WOLFSSL_API int wolfSSL_dtls_get_peer(WOLFSSL* ssl, void* peer, unsigned int* peerSz);
|
||||
WOLFSSL_API int wolfSSL_dtls_set_peer(WOLFSSL* ssl, void* peer,
|
||||
unsigned int peerSz);
|
||||
WOLFSSL_API int wolfSSL_dtls_set_pending_peer(WOLFSSL* ssl, void* peer,
|
||||
unsigned int peerSz);
|
||||
WOLFSSL_API int wolfSSL_dtls_get_peer(WOLFSSL* ssl, void* peer,
|
||||
unsigned int* peerSz);
|
||||
WOLFSSL_API int wolfSSL_dtls_get0_peer(WOLFSSL* ssl, const void** peer,
|
||||
unsigned int* peerSz);
|
||||
|
||||
WOLFSSL_API byte wolfSSL_is_stateful(WOLFSSL* ssl);
|
||||
|
||||
#if defined(WOLFSSL_SCTP) && defined(WOLFSSL_DTLS)
|
||||
WOLFSSL_API int wolfSSL_CTX_dtls_set_sctp(WOLFSSL_CTX* ctx);
|
||||
|
@ -4727,6 +4737,7 @@ WOLFSSL_API int wolfSSL_CTX_DisableExtendedMasterSecret(WOLFSSL_CTX* ctx);
|
|||
|
||||
|
||||
#if defined(WOLFSSL_DTLS) && !defined(NO_WOLFSSL_SERVER)
|
||||
WOLFSSL_API int wolfDTLS_accept_stateless(WOLFSSL* ssl);
|
||||
/* notify user we parsed a verified ClientHello is done. This only has an effect
|
||||
* on the server end. */
|
||||
typedef int (*ClientHelloGoodCb)(WOLFSSL* ssl, void*);
|
||||
|
@ -5861,11 +5872,15 @@ 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_get0_rx(WOLFSSL* ssl, unsigned char** cid);
|
||||
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_get0_tx(WOLFSSL* ssl, unsigned char** cid);
|
||||
WOLFSSL_API int wolfSSL_dtls_cid_max_size(void);
|
||||
WOLFSSL_API const unsigned char* wolfSSL_dtls_cid_parse(const unsigned char* msg,
|
||||
unsigned int msgSz, unsigned int cidSz);
|
||||
#endif /* defined(WOLFSSL_DTLS_CID) */
|
||||
|
||||
#ifdef WOLFSSL_DTLS_CH_FRAG
|
||||
|
|
|
@ -611,6 +611,8 @@ WOLFSSL_API void wolfSSL_CTX_SetIORecv(WOLFSSL_CTX *ctx, CallbackIORecv CBIORecv
|
|||
WOLFSSL_API void wolfSSL_CTX_SetIOSend(WOLFSSL_CTX *ctx, CallbackIOSend CBIOSend);
|
||||
WOLFSSL_API void wolfSSL_SSLSetIORecv(WOLFSSL *ssl, CallbackIORecv CBIORecv);
|
||||
WOLFSSL_API void wolfSSL_SSLSetIOSend(WOLFSSL *ssl, CallbackIOSend CBIOSend);
|
||||
WOLFSSL_API void wolfSSL_SSLDisableRead(WOLFSSL *ssl);
|
||||
WOLFSSL_API void wolfSSL_SSLEnableRead(WOLFSSL *ssl);
|
||||
/* deprecated old name */
|
||||
#define wolfSSL_SetIORecv wolfSSL_CTX_SetIORecv
|
||||
#define wolfSSL_SetIOSend wolfSSL_CTX_SetIOSend
|
||||
|
|
Loading…
Reference in New Issue