mirror of https://github.com/wolfSSL/wolfssl.git
DTLS: Add server side stateless and CID QoL API
- wolfDTLS_accept_stateless - statelessly listen for incoming connections - wolfSSL_inject - insert data into WOLFSSL object - wolfSSL_SSL(Enable|Disable)Read - enable/disable reading from IO - wolfSSL_get_wfd - get the write side file descriptor - wolfSSL_dtls_set_pending_peer - set the pending peer that will be upgraded to regular peer when we successfully de-protect a DTLS record - wolfSSL_dtls_get0_peer - zero copy access to the peer address - wolfSSL_is_stateful - boolean to check if we have entered stateful processing - wolfSSL_dtls_cid_get0_rx - zero copy access to the rx cid - wolfSSL_dtls_cid_get0_tx - zero copy access to the tx cid - wolfSSL_dtls_cid_parse - extract cid from a datagram/messagepull/8224/head
parent
ba050d6a3f
commit
daa57c492d
|
@ -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,52 @@ 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 +4010,40 @@ 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 +14283,35 @@ 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
|
||||
|
||||
\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 +15129,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 +15142,27 @@ 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 copied, 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_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 +15194,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 +15205,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);
|
||||
|
|
69
src/dtls.c
69
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)
|
||||
|
@ -1108,6 +1117,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 +1395,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 +1411,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;
|
||||
}
|
||||
|
||||
void wolfSSL_dtls_cid_parse(const unsigned char* msg, unsigned int msgSz,
|
||||
const unsigned char** cid, unsigned int cidSz)
|
||||
{
|
||||
if (cid == NULL)
|
||||
return;
|
||||
*cid = NULL;
|
||||
/* we need at least the first byte to check version */
|
||||
if (msg == NULL || cidSz == 0 || msgSz < OPAQUE8_LEN + cidSz)
|
||||
return;
|
||||
if (msg[0] == dtls12_cid) {
|
||||
/* DTLS 1.2 CID packet */
|
||||
if (msgSz < DTLS_RECORD_HEADER_SZ + cidSz)
|
||||
return;
|
||||
/* content type(1) + version(2) + epoch(2) + sequence(6) */
|
||||
*cid = msg + ENUM_LEN + VERSION_SZ + OPAQUE16_LEN + OPAQUE16_LEN +
|
||||
OPAQUE32_LEN;
|
||||
}
|
||||
else if (Dtls13UnifiedHeaderCIDPresent(msg[0])) {
|
||||
/* DTLS 1.3 CID packet */
|
||||
if (msgSz < OPAQUE8_LEN + cidSz)
|
||||
return;
|
||||
*cid = msg + OPAQUE8_LEN;
|
||||
}
|
||||
}
|
||||
#endif /* WOLFSSL_DTLS_CID */
|
||||
|
||||
byte DtlsGetCidTxSize(WOLFSSL* ssl)
|
||||
|
@ -1413,6 +1477,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
|
||||
|
|
|
@ -8261,6 +8261,11 @@ void wolfSSL_ResourceFree(WOLFSSL* ssl)
|
|||
}
|
||||
XFREE(ssl->buffers.dtlsCtx.peer.sa, ssl->heap, DYNAMIC_TYPE_SOCKADDR);
|
||||
ssl->buffers.dtlsCtx.peer.sa = NULL;
|
||||
#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,
|
||||
|
@ -11522,15 +11527,15 @@ 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 (cidSz != DtlsGetCidRxSize(ssl) ||
|
||||
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;
|
||||
}
|
||||
|
@ -11740,7 +11745,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;
|
||||
|
@ -21045,11 +21050,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)) {
|
||||
|
@ -21063,11 +21071,20 @@ 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) {
|
||||
return BUFFER_ERROR;
|
||||
}
|
||||
|
||||
/* check that no lengths or size values are negative */
|
||||
if (usedLength < 0 || maxLength < 0 || inSz <= 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) {
|
||||
|
@ -21541,6 +21558,23 @@ int ProcessReplyEx(WOLFSSL* ssl, int allowSocketErr)
|
|||
&ssl->curRL, &ssl->curSize);
|
||||
|
||||
#ifdef WOLFSSL_DTLS
|
||||
#ifdef WOLFSSL_DTLS_CID
|
||||
if (ssl->options.dtls) {
|
||||
if (!ssl->buffers.dtlsCtx.processingPendingRecord)
|
||||
ssl->buffers.dtlsCtx.processingPendingRecord = 1;
|
||||
else {
|
||||
ssl->buffers.dtlsCtx.processingPendingRecord = 0;
|
||||
if (ssl->buffers.dtlsCtx.pendingPeer.sa != NULL) {
|
||||
/* Clear the pending peer */
|
||||
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
|
||||
if (ssl->options.dtls && DtlsShouldDrop(ssl, ret)) {
|
||||
ssl->options.processReply = doProcessInit;
|
||||
ssl->buffers.inputBuffer.length = 0;
|
||||
|
@ -21965,8 +21999,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 */
|
||||
|
@ -21990,11 +22025,27 @@ 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) &&
|
||||
ssl->buffers.dtlsCtx.pendingPeer.sa != NULL) {
|
||||
XFREE(ssl->buffers.dtlsCtx.peer.sa, ssl->heap,
|
||||
DYNAMIC_TYPE_SOCKADDR);
|
||||
ssl->buffers.dtlsCtx.peer =
|
||||
ssl->buffers.dtlsCtx.pendingPeer;
|
||||
ssl->buffers.dtlsCtx.pendingPeer.sa = NULL;
|
||||
ssl->buffers.dtlsCtx.pendingPeer.sz = 0;
|
||||
ssl->buffers.dtlsCtx.pendingPeer.bufSz = 0;
|
||||
ssl->buffers.dtlsCtx.processingPendingRecord = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif /* WOLFSSL_DTLS13 */
|
||||
#endif /* WOLFSSL_DTLS */
|
||||
ssl->options.processReply = runProcessingOneMessage;
|
||||
FALL_THROUGH;
|
||||
|
||||
|
|
248
src/ssl.c
248
src/ssl.c
|
@ -1732,6 +1732,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)
|
||||
{
|
||||
|
@ -1864,38 +1875,51 @@ 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;
|
||||
ret = SockAddrSet(&ssl->buffers.dtlsCtx.peer, peer, peerSz, ssl->heap);
|
||||
if (ret == WOLFSSL_SUCCESS && !(peer == NULL || peerSz == 0))
|
||||
ssl->buffers.dtlsCtx.userSet = 1;
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
return WOLFSSL_FAILURE;
|
||||
else
|
||||
ssl->buffers.dtlsCtx.userSet = 0;
|
||||
return ret;
|
||||
#else
|
||||
(void)ssl;
|
||||
(void)peer;
|
||||
|
@ -1904,6 +1928,45 @@ int wolfSSL_dtls_set_peer(WOLFSSL* ssl, void* peer, unsigned int peerSz)
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_DTLS_CID
|
||||
int wolfSSL_dtls_set_pending_peer(WOLFSSL* ssl, void* peer, unsigned int peerSz)
|
||||
{
|
||||
#ifdef WOLFSSL_DTLS
|
||||
int ret = WOLFSSL_FAILURE;
|
||||
|
||||
if (ssl == NULL)
|
||||
return WOLFSSL_FAILURE;
|
||||
|
||||
if (ssl->buffers.dtlsCtx.peer.sa != NULL &&
|
||||
ssl->buffers.dtlsCtx.peer.sz == peerSz &&
|
||||
XMEMCMP(ssl->buffers.dtlsCtx.peer.sa, peer, peerSz) == 0) {
|
||||
/* 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;
|
||||
return ret;
|
||||
#else
|
||||
(void)ssl;
|
||||
(void)peer;
|
||||
(void)peerSz;
|
||||
return WOLFSSL_NOT_IMPLEMENTED;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
int wolfSSL_dtls_get_peer(WOLFSSL* ssl, void* peer, unsigned int* peerSz)
|
||||
{
|
||||
#ifdef WOLFSSL_DTLS
|
||||
|
@ -1927,6 +1990,27 @@ int wolfSSL_dtls_get_peer(WOLFSSL* ssl, void* peer, unsigned int* peerSz)
|
|||
#endif
|
||||
}
|
||||
|
||||
int wolfSSL_dtls_get0_peer(WOLFSSL* ssl, const void** peer,
|
||||
unsigned int* peerSz)
|
||||
{
|
||||
#ifdef WOLFSSL_DTLS
|
||||
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;
|
||||
(void)peerSz;
|
||||
return WOLFSSL_NOT_IMPLEMENTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if defined(WOLFSSL_SCTP) && defined(WOLFSSL_DTLS)
|
||||
|
||||
|
@ -2897,6 +2981,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_read_internal");
|
||||
|
||||
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;
|
||||
|
@ -9222,7 +9342,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);
|
||||
|
@ -9230,7 +9356,7 @@ int wolfSSL_dtls_retransmit(WOLFSSL* ssl)
|
|||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
|
||||
#endif /* DTLS */
|
||||
|
@ -10399,6 +10525,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 = 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");
|
||||
|
|
14
src/wolfio.c
14
src/wolfio.c
|
@ -2351,6 +2351,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)
|
||||
{
|
||||
|
|
197
tests/api.c
197
tests/api.c
|
@ -90313,7 +90313,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];
|
||||
|
||||
|
@ -90383,7 +90383,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 */
|
||||
|
@ -90445,7 +90445,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);
|
||||
|
@ -90550,7 +90550,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);
|
||||
}
|
||||
|
@ -90620,7 +90620,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));
|
||||
|
@ -90947,7 +90947,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 */
|
||||
|
@ -91018,7 +91018,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 */
|
||||
|
@ -93932,18 +93932,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);
|
||||
|
@ -100204,6 +100217,163 @@ 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++) {
|
||||
if (wolfSSL_negotiate(ssl_c) != 1) {
|
||||
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1),
|
||||
WOLFSSL_ERROR_WANT_READ);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
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)
|
||||
const unsigned char* cid = NULL;
|
||||
/* 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";
|
||||
/* 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";
|
||||
|
||||
wolfSSL_dtls_cid_parse(noCid, sizeof(noCid), &cid, 8);
|
||||
ExpectPtrEq(cid, NULL);
|
||||
wolfSSL_dtls_cid_parse(cid12, sizeof(cid12), &cid, 8);
|
||||
ExpectPtrEq(cid, cid12 + 11);
|
||||
wolfSSL_dtls_cid_parse(cid13, sizeof(cid13), &cid, 8);
|
||||
ExpectPtrEq(cid, cid13 + 1);
|
||||
|
||||
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
| Main
|
||||
|
@ -101607,6 +101777,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)
|
||||
};
|
||||
|
|
|
@ -2759,6 +2759,11 @@ struct WOLFSSL_SOCKADDR {
|
|||
|
||||
typedef struct WOLFSSL_DTLS_CTX {
|
||||
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;
|
||||
|
@ -2766,6 +2771,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;
|
||||
|
||||
|
||||
|
@ -3712,6 +3720,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);
|
||||
|
@ -5052,6 +5061,7 @@ struct Options {
|
|||
#if defined(HAVE_DANE)
|
||||
word16 useDANE:1;
|
||||
#endif /* HAVE_DANE */
|
||||
word16 disableRead:1;
|
||||
#ifdef WOLFSSL_DTLS
|
||||
byte haveMcast; /* using multicast ? */
|
||||
#endif
|
||||
|
|
|
@ -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);
|
||||
|
@ -4709,6 +4719,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*);
|
||||
|
@ -5844,11 +5855,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 void wolfSSL_dtls_cid_parse(const unsigned char* msg,
|
||||
unsigned int msgSz, const unsigned char** cid, 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