commit
e87dac66ac
@ -138,13 +138,16 @@ static int NonBlockingSSL_Connect(WOLFSSL* ssl)
|
||||
else
|
||||
#endif
|
||||
{
|
||||
#ifdef WOLFSSL_DTLS
|
||||
currTimeout = wolfSSL_dtls_get_current_timeout(ssl);
|
||||
#endif
|
||||
select_ret = tcp_select(sockfd, currTimeout);
|
||||
if (error != WOLFSSL_ERROR_WANT_WRITE) {
|
||||
#ifdef WOLFSSL_DTLS
|
||||
currTimeout = wolfSSL_dtls_get_current_timeout(ssl);
|
||||
#endif
|
||||
select_ret = tcp_select(sockfd, currTimeout);
|
||||
}
|
||||
}
|
||||
|
||||
if ((select_ret == TEST_RECV_READY) || (select_ret == TEST_ERROR_READY)
|
||||
if ((select_ret == TEST_RECV_READY) || (select_ret == TEST_SEND_READY)
|
||||
|| (select_ret == TEST_ERROR_READY)
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
|| error == WC_PENDING_E
|
||||
#endif
|
||||
@ -156,6 +159,13 @@ static int NonBlockingSSL_Connect(WOLFSSL* ssl)
|
||||
#endif
|
||||
error = wolfSSL_get_error(ssl, 0);
|
||||
elapsedSec = 0; /* reset elapsed */
|
||||
if (error == WOLFSSL_ERROR_WANT_WRITE) {
|
||||
/* Do a send select here. */
|
||||
select_ret = tcp_select_tx(sockfd, 1);
|
||||
if (select_ret == TEST_TIMEOUT) {
|
||||
error = WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (select_ret == TEST_TIMEOUT && !wolfSSL_dtls(ssl)) {
|
||||
error = WOLFSSL_ERROR_WANT_READ;
|
||||
|
@ -115,6 +115,138 @@ static void err_sys_ex(int out, const char* msg)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef WOLFSSL_DTLS
|
||||
|
||||
/* Translates return codes returned from
|
||||
* send() and recv() if need be.
|
||||
*/
|
||||
static WC_INLINE int TranslateReturnCode(int old, int sd)
|
||||
{
|
||||
(void)sd;
|
||||
|
||||
#if defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
|
||||
if (old == 0) {
|
||||
errno = SOCKET_EWOULDBLOCK;
|
||||
return -1; /* convert to BSD style wouldblock as error */
|
||||
}
|
||||
|
||||
if (old < 0) {
|
||||
errno = RTCS_geterror(sd);
|
||||
if (errno == RTCSERR_TCP_CONN_CLOSING)
|
||||
return 0; /* convert to BSD style closing */
|
||||
if (errno == RTCSERR_TCP_CONN_RLSD)
|
||||
errno = SOCKET_ECONNRESET;
|
||||
if (errno == RTCSERR_TCP_TIMED_OUT)
|
||||
errno = SOCKET_EAGAIN;
|
||||
}
|
||||
#endif
|
||||
|
||||
return old;
|
||||
}
|
||||
|
||||
static WC_INLINE int wolfSSL_LastError(void)
|
||||
{
|
||||
#ifdef USE_WINDOWS_API
|
||||
return WSAGetLastError();
|
||||
#elif defined(EBSNET)
|
||||
return xn_getlasterror();
|
||||
#else
|
||||
return errno;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* wolfSSL Sock Addr */
|
||||
struct WOLFSSL_TEST_SOCKADDR {
|
||||
unsigned int sz; /* sockaddr size */
|
||||
SOCKADDR_IN_T sa; /* pointer to the sockaddr_in or sockaddr_in6 */
|
||||
};
|
||||
|
||||
typedef struct WOLFSSL_TEST_DTLS_CTX {
|
||||
struct WOLFSSL_TEST_SOCKADDR peer;
|
||||
int rfd;
|
||||
int wfd;
|
||||
int failOnce;
|
||||
word32 blockSeq;
|
||||
} WOLFSSL_TEST_DTLS_CTX;
|
||||
|
||||
|
||||
static WC_INLINE int PeekSeq(const char* buf, word32* seq)
|
||||
{
|
||||
const char* c = buf + 3;
|
||||
|
||||
if ((c[0] | c[1] | c[2] | c[3]) == 0) {
|
||||
*seq = (c[4] << 24) | (c[5] << 16) | (c[6] << 8) | c[7];
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* The send embedded callback
|
||||
* return : nb bytes sent, or error
|
||||
*/
|
||||
static int TestEmbedSendTo(WOLFSSL* ssl, char *buf, int sz, void *ctx)
|
||||
{
|
||||
WOLFSSL_TEST_DTLS_CTX* dtlsCtx = (WOLFSSL_TEST_DTLS_CTX*)ctx;
|
||||
int sd = dtlsCtx->wfd;
|
||||
int sent;
|
||||
int len = sz;
|
||||
int err;
|
||||
|
||||
(void)ssl;
|
||||
|
||||
WOLFSSL_ENTER("TestEmbedSendTo()");
|
||||
|
||||
if (dtlsCtx->failOnce) {
|
||||
word32 seq = 0;
|
||||
|
||||
if (PeekSeq(buf, &seq) && seq == dtlsCtx->blockSeq) {
|
||||
dtlsCtx->failOnce = 0;
|
||||
WOLFSSL_MSG("Forcing WANT_WRITE");
|
||||
return WOLFSSL_CBIO_ERR_WANT_WRITE;
|
||||
}
|
||||
}
|
||||
|
||||
sent = (int)sendto(sd, &buf[sz - len], len, 0,
|
||||
(const SOCKADDR*)&dtlsCtx->peer.sa,
|
||||
dtlsCtx->peer.sz);
|
||||
|
||||
sent = TranslateReturnCode(sent, sd);
|
||||
|
||||
if (sent < 0) {
|
||||
err = wolfSSL_LastError();
|
||||
WOLFSSL_MSG("Embed Send To error");
|
||||
|
||||
if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) {
|
||||
WOLFSSL_MSG("\tWould Block");
|
||||
return WOLFSSL_CBIO_ERR_WANT_WRITE;
|
||||
}
|
||||
else if (err == SOCKET_ECONNRESET) {
|
||||
WOLFSSL_MSG("\tConnection reset");
|
||||
return WOLFSSL_CBIO_ERR_CONN_RST;
|
||||
}
|
||||
else if (err == SOCKET_EINTR) {
|
||||
WOLFSSL_MSG("\tSocket interrupted");
|
||||
return WOLFSSL_CBIO_ERR_ISR;
|
||||
}
|
||||
else if (err == SOCKET_EPIPE) {
|
||||
WOLFSSL_MSG("\tSocket EPIPE");
|
||||
return WOLFSSL_CBIO_ERR_CONN_CLOSE;
|
||||
}
|
||||
else {
|
||||
WOLFSSL_MSG("\tGeneral error");
|
||||
return WOLFSSL_CBIO_ERR_GENERAL;
|
||||
}
|
||||
}
|
||||
|
||||
return sent;
|
||||
}
|
||||
|
||||
#endif /* WOLFSSL_DTLS */
|
||||
|
||||
|
||||
static int NonBlockingSSL_Accept(SSL* ssl)
|
||||
{
|
||||
#ifndef WOLFSSL_CALLBACKS
|
||||
@ -149,13 +281,16 @@ static int NonBlockingSSL_Accept(SSL* ssl)
|
||||
else
|
||||
#endif
|
||||
{
|
||||
#ifdef WOLFSSL_DTLS
|
||||
currTimeout = wolfSSL_dtls_get_current_timeout(ssl);
|
||||
#endif
|
||||
select_ret = tcp_select(sockfd, currTimeout);
|
||||
if (error != WOLFSSL_ERROR_WANT_WRITE) {
|
||||
#ifdef WOLFSSL_DTLS
|
||||
currTimeout = wolfSSL_dtls_get_current_timeout(ssl);
|
||||
#endif
|
||||
select_ret = tcp_select(sockfd, currTimeout);
|
||||
}
|
||||
}
|
||||
|
||||
if ((select_ret == TEST_RECV_READY) || (select_ret == TEST_ERROR_READY)
|
||||
if ((select_ret == TEST_RECV_READY) || (select_ret == TEST_SEND_READY)
|
||||
|| (select_ret == TEST_ERROR_READY)
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
|| error == WC_PENDING_E
|
||||
#endif
|
||||
@ -167,6 +302,12 @@ static int NonBlockingSSL_Accept(SSL* ssl)
|
||||
srvHandShakeCB, srvTimeoutCB, srvTo);
|
||||
#endif
|
||||
error = SSL_get_error(ssl, 0);
|
||||
if (error == WOLFSSL_ERROR_WANT_WRITE) {
|
||||
/* Do a select here. */
|
||||
select_ret = tcp_select_tx(sockfd, 1);
|
||||
if (select_ret == TEST_TIMEOUT)
|
||||
error = WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
else if (select_ret == TEST_TIMEOUT && !wolfSSL_dtls(ssl)) {
|
||||
error = WOLFSSL_ERROR_WANT_READ;
|
||||
@ -678,6 +819,9 @@ static void Usage(void)
|
||||
!defined(HAVE_SELFTEST) && !defined(WOLFSSL_OLD_PRIME_CHECK)
|
||||
printf("-2 Disable DH Prime check\n");
|
||||
#endif
|
||||
#ifdef WOLFSSL_DTLS
|
||||
printf("-4 <seq> DTLS fake would-block for message seq\n");
|
||||
#endif
|
||||
#ifdef WOLFSSL_MULTICAST
|
||||
printf("%s", msg[++msgId]); /* -3 */
|
||||
#endif
|
||||
@ -719,6 +863,10 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
|
||||
int dtlsUDP = 0;
|
||||
int dtlsSCTP = 0;
|
||||
int doMcast = 0;
|
||||
#ifdef WOLFSSL_DTLS
|
||||
int doBlockSeq = 0;
|
||||
WOLFSSL_TEST_DTLS_CTX dtlsCtx;
|
||||
#endif
|
||||
int needDH = 0;
|
||||
int useNtruKey = 0;
|
||||
int nonBlocking = 0;
|
||||
@ -863,7 +1011,7 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
|
||||
while ((ch = mygetopt(argc, argv, "?"
|
||||
"abc:defgijk:l:mnop:q:rstuv:wxy"
|
||||
"A:B:C:D:E:GH:IJKL:MNO:PQR:S:TUVYZ:"
|
||||
"01:23:")) != -1) {
|
||||
"01:23:4:")) != -1) {
|
||||
switch (ch) {
|
||||
case '?' :
|
||||
if(myoptarg!=NULL) {
|
||||
@ -1219,6 +1367,14 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
|
||||
#endif
|
||||
break;
|
||||
|
||||
case '4' :
|
||||
#ifdef WOLFSSL_DTLS
|
||||
XMEMSET(&dtlsCtx, 0, sizeof(dtlsCtx));
|
||||
doBlockSeq = 1;
|
||||
dtlsCtx.blockSeq = atoi(myoptarg);
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
Usage();
|
||||
XEXIT_T(MY_EX_USAGE);
|
||||
@ -1598,6 +1754,14 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
|
||||
#endif
|
||||
}
|
||||
|
||||
if (doDTLS && dtlsUDP) {
|
||||
#ifdef WOLFSSL_DTLS
|
||||
if (doBlockSeq) {
|
||||
wolfSSL_CTX_SetIOSend(ctx, TestEmbedSendTo);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAVE_PK_CALLBACKS
|
||||
if (pkCallbacks)
|
||||
SetupPkCallbacks(ctx);
|
||||
@ -1807,12 +1971,22 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
|
||||
/* For DTLS, peek at the next datagram so we can get the client's
|
||||
* address and set it into the ssl object later to generate the
|
||||
* cookie. */
|
||||
n = (int)recvfrom(sockfd, (char*)b, sizeof(b), MSG_PEEK,
|
||||
n = (int)recvfrom(clientfd, (char*)b, sizeof(b), MSG_PEEK,
|
||||
(struct sockaddr*)&cliaddr, &len);
|
||||
if (n <= 0)
|
||||
err_sys_ex(runWithErrors, "recvfrom failed");
|
||||
|
||||
wolfSSL_dtls_set_peer(ssl, &cliaddr, len);
|
||||
if (doBlockSeq) {
|
||||
XMEMCPY(&dtlsCtx.peer.sa, &cliaddr, len);
|
||||
dtlsCtx.peer.sz = len;
|
||||
dtlsCtx.wfd = clientfd;
|
||||
dtlsCtx.failOnce = 1;
|
||||
|
||||
wolfSSL_SetIOWriteCtx(ssl, &dtlsCtx);
|
||||
}
|
||||
else {
|
||||
wolfSSL_dtls_set_peer(ssl, &cliaddr, len);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if ((usePsk == 0 || usePskPlus) || useAnon == 1 || cipherList != NULL
|
||||
|
@ -6003,8 +6003,12 @@ int DtlsMsgPoolSave(WOLFSSL* ssl, const byte* data, word32 dataSz)
|
||||
DtlsMsg* item;
|
||||
int ret = 0;
|
||||
|
||||
if (ssl->dtls_tx_msg_list_sz > DTLS_POOL_SZ)
|
||||
WOLFSSL_ENTER("DtlsMsgPoolSave()");
|
||||
|
||||
if (ssl->dtls_tx_msg_list_sz > DTLS_POOL_SZ) {
|
||||
WOLFSSL_ERROR(DTLS_POOL_SZ_E);
|
||||
return DTLS_POOL_SZ_E;
|
||||
}
|
||||
|
||||
item = DtlsMsgNew(dataSz, ssl->heap);
|
||||
|
||||
@ -6027,6 +6031,7 @@ int DtlsMsgPoolSave(WOLFSSL* ssl, const byte* data, word32 dataSz)
|
||||
else
|
||||
ret = MEMORY_E;
|
||||
|
||||
WOLFSSL_LEAVE("DtlsMsgPoolSave()", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -6039,6 +6044,7 @@ int DtlsMsgPoolTimeout(WOLFSSL* ssl)
|
||||
ssl->dtls_timeout *= DTLS_TIMEOUT_MULTIPLIER;
|
||||
result = 0;
|
||||
}
|
||||
WOLFSSL_LEAVE("DtlsMsgPoolTimeout()", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -6047,9 +6053,11 @@ int DtlsMsgPoolTimeout(WOLFSSL* ssl)
|
||||
* value. */
|
||||
void DtlsMsgPoolReset(WOLFSSL* ssl)
|
||||
{
|
||||
WOLFSSL_ENTER("DtlsMsgPoolReset()");
|
||||
if (ssl->dtls_tx_msg_list) {
|
||||
DtlsMsgListDelete(ssl->dtls_tx_msg_list, ssl->heap);
|
||||
ssl->dtls_tx_msg_list = NULL;
|
||||
ssl->dtls_tx_msg = NULL;
|
||||
ssl->dtls_tx_msg_list_sz = 0;
|
||||
ssl->dtls_timeout = ssl->dtls_timeout_init;
|
||||
}
|
||||
@ -6078,9 +6086,25 @@ int VerifyForDtlsMsgPoolSend(WOLFSSL* ssl, byte type, word32 fragOffset)
|
||||
int DtlsMsgPoolSend(WOLFSSL* ssl, int sendOnlyFirstPacket)
|
||||
{
|
||||
int ret = 0;
|
||||
DtlsMsg* pool = ssl->dtls_tx_msg_list;
|
||||
DtlsMsg* pool;
|
||||
|
||||
WOLFSSL_ENTER("DtlsMsgPoolSend()");
|
||||
|
||||
pool = ssl->dtls_tx_msg == NULL ? ssl->dtls_tx_msg_list : ssl->dtls_tx_msg;
|
||||
|
||||
if (pool != NULL) {
|
||||
if ((ssl->options.side == WOLFSSL_SERVER_END &&
|
||||
!(ssl->options.acceptState == SERVER_HELLO_DONE ||
|
||||
ssl->options.acceptState == ACCEPT_FINISHED_DONE)) ||
|
||||
(ssl->options.side == WOLFSSL_CLIENT_END &&
|
||||
!(ssl->options.connectState == CLIENT_HELLO_SENT ||
|
||||
ssl->options.connectState == HELLO_AGAIN_REPLY ||
|
||||
ssl->options.connectState == FINISHED_DONE))) {
|
||||
|
||||
WOLFSSL_ERROR(DTLS_RETX_OVER_TX);
|
||||
ssl->error = DTLS_RETX_OVER_TX;
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
|
||||
while (pool != NULL) {
|
||||
if (pool->seq == 0) {
|
||||
@ -6098,8 +6122,10 @@ int DtlsMsgPoolSend(WOLFSSL* ssl, int sendOnlyFirstPacket)
|
||||
|
||||
WriteSEQ(ssl, epochOrder, dtls->sequence_number);
|
||||
DtlsSEQIncrement(ssl, epochOrder);
|
||||
if ((ret = CheckAvailableSize(ssl, pool->sz)) != 0)
|
||||
if ((ret = CheckAvailableSize(ssl, pool->sz)) != 0) {
|
||||
WOLFSSL_ERROR(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
XMEMCPY(ssl->buffers.outputBuffer.buffer,
|
||||
pool->buf, pool->sz);
|
||||
@ -6115,21 +6141,26 @@ int DtlsMsgPoolSend(WOLFSSL* ssl, int sendOnlyFirstPacket)
|
||||
inputSz = pool->sz;
|
||||
sendSz = inputSz + MAX_MSG_EXTRA;
|
||||
|
||||
if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
|
||||
if ((ret = CheckAvailableSize(ssl, sendSz)) != 0) {
|
||||
WOLFSSL_ERROR(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
output = ssl->buffers.outputBuffer.buffer +
|
||||
ssl->buffers.outputBuffer.length;
|
||||
sendSz = BuildMessage(ssl, output, sendSz, input, inputSz,
|
||||
handshake, 0, 0, 0);
|
||||
if (sendSz < 0)
|
||||
if (sendSz < 0) {
|
||||
WOLFSSL_ERROR(BUILD_MSG_ERROR);
|
||||
return BUILD_MSG_ERROR;
|
||||
}
|
||||
|
||||
ssl->buffers.outputBuffer.length += sendSz;
|
||||
}
|
||||
|
||||
ret = SendBuffered(ssl);
|
||||
if (ret < 0) {
|
||||
WOLFSSL_ERROR(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -6148,9 +6179,11 @@ int DtlsMsgPoolSend(WOLFSSL* ssl, int sendOnlyFirstPacket)
|
||||
}
|
||||
else
|
||||
pool = pool->next;
|
||||
ssl->dtls_tx_msg = pool;
|
||||
}
|
||||
}
|
||||
|
||||
WOLFSSL_LEAVE("DtlsMsgPoolSend()", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -7094,6 +7127,7 @@ static int GetRecordHeader(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
if (IsDtlsNotSctpMode(ssl) &&
|
||||
(!DtlsCheckWindow(ssl) ||
|
||||
(ssl->options.handShakeDone && ssl->keys.curEpoch == 0))) {
|
||||
WOLFSSL_LEAVE("GetRecordHeader()", SEQUENCE_ERROR);
|
||||
return SEQUENCE_ERROR;
|
||||
}
|
||||
#endif
|
||||
@ -7186,8 +7220,10 @@ static int GetDtlsHandShakeHeader(WOLFSSL* ssl, const byte* input,
|
||||
word32 idx = *inOutIdx;
|
||||
|
||||
*inOutIdx += HANDSHAKE_HEADER_SZ + DTLS_HANDSHAKE_EXTRA;
|
||||
if (*inOutIdx > totalSz)
|
||||
if (*inOutIdx > totalSz) {
|
||||
WOLFSSL_ERROR(BUFFER_E);
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
*type = input[idx++];
|
||||
c24to32(input + idx, size);
|
||||
@ -7203,8 +7239,10 @@ static int GetDtlsHandShakeHeader(WOLFSSL* ssl, const byte* input,
|
||||
if (ssl->curRL.pvMajor != ssl->version.major ||
|
||||
ssl->curRL.pvMinor != ssl->version.minor) {
|
||||
|
||||
if (*type != client_hello && *type != hello_verify_request)
|
||||
if (*type != client_hello && *type != hello_verify_request) {
|
||||
WOLFSSL_ERROR(VERSION_ERROR);
|
||||
return VERSION_ERROR;
|
||||
}
|
||||
else {
|
||||
WOLFSSL_MSG("DTLS Handshake ignoring hello or verify version");
|
||||
}
|
||||
@ -10551,10 +10589,17 @@ static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type)
|
||||
|
||||
#ifndef NO_WOLFSSL_CLIENT
|
||||
if (ssl->options.side == WOLFSSL_CLIENT_END) {
|
||||
if (!ssl->options.resuming &&
|
||||
ssl->msgsReceived.got_server_hello_done == 0) {
|
||||
WOLFSSL_MSG("No ServerHelloDone before ChangeCipher");
|
||||
return OUT_OF_ORDER_E;
|
||||
if (!ssl->options.resuming) {
|
||||
if (ssl->msgsReceived.got_server_hello_done == 0) {
|
||||
WOLFSSL_MSG("No ServerHelloDone before ChangeCipher");
|
||||
return OUT_OF_ORDER_E;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (ssl->msgsReceived.got_server_hello == 0) {
|
||||
WOLFSSL_MSG("No ServerHello before ChangeCipher on Resume");
|
||||
return OUT_OF_ORDER_E;
|
||||
}
|
||||
}
|
||||
#ifdef HAVE_SESSION_TICKET
|
||||
if (ssl->expect_session_ticket) {
|
||||
@ -11240,6 +11285,8 @@ static int DtlsMsgDrain(WOLFSSL* ssl)
|
||||
DtlsMsg* item = ssl->dtls_rx_msg_list;
|
||||
int ret = 0;
|
||||
|
||||
WOLFSSL_ENTER("DtlsMsgDrain()");
|
||||
|
||||
/* While there is an item in the store list, and it is the expected
|
||||
* message, and it is complete, and there hasn't been an error in the
|
||||
* last message... */
|
||||
@ -11263,6 +11310,7 @@ static int DtlsMsgDrain(WOLFSSL* ssl)
|
||||
ssl->dtls_rx_msg_list_sz--;
|
||||
}
|
||||
|
||||
WOLFSSL_LEAVE("DtlsMsgDrain()", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -11290,12 +11338,16 @@ static int DoDtlsHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||
|
||||
/* parse header */
|
||||
if (GetDtlsHandShakeHeader(ssl, input, inOutIdx, &type,
|
||||
&size, &fragOffset, &fragSz, totalSz) != 0)
|
||||
&size, &fragOffset, &fragSz, totalSz) != 0) {
|
||||
WOLFSSL_ERROR(PARSE_ERROR);
|
||||
return PARSE_ERROR;
|
||||
}
|
||||
|
||||
/* check that we have complete fragment */
|
||||
if (*inOutIdx + fragSz > totalSz)
|
||||
if (*inOutIdx + fragSz > totalSz) {
|
||||
WOLFSSL_ERROR(INCOMPLETE_DATA);
|
||||
return INCOMPLETE_DATA;
|
||||
}
|
||||
|
||||
/* Check the handshake sequence number first. If out of order,
|
||||
* add the current message to the list. If the message is in order,
|
||||
@ -11340,6 +11392,7 @@ static int DoDtlsHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||
*inOutIdx += fragSz;
|
||||
if(type == finished ) {
|
||||
if (*inOutIdx + ssl->keys.padSz > totalSz) {
|
||||
WOLFSSL_ERROR(BUFFER_E);
|
||||
return BUFFER_E;
|
||||
}
|
||||
*inOutIdx += ssl->keys.padSz;
|
||||
@ -13170,8 +13223,10 @@ int ProcessReply(WOLFSSL* ssl)
|
||||
ret = BUFFER_ERROR;
|
||||
#endif
|
||||
}
|
||||
if (ret != 0)
|
||||
if (ret != 0) {
|
||||
WOLFSSL_ERROR(ret);
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
|
||||
case change_cipher_spec:
|
||||
@ -13446,6 +13501,7 @@ int SendChangeCipher(WOLFSSL* ssl)
|
||||
|
||||
#ifdef WOLFSSL_DTLS
|
||||
if (IsDtlsNotSctpMode(ssl)) {
|
||||
DtlsSEQIncrement(ssl, CUR_ORDER);
|
||||
if ((ret = DtlsMsgPoolSave(ssl, output, sendSz)) != 0)
|
||||
return ret;
|
||||
}
|
||||
@ -15796,6 +15852,9 @@ const char* wolfSSL_ERR_reason_error_string(unsigned long e)
|
||||
case EXT_MISSING:
|
||||
return "Required TLS extension missing";
|
||||
|
||||
case DTLS_RETX_OVER_TX:
|
||||
return "DTLS interrupting flight transmit with retransmit";
|
||||
|
||||
default :
|
||||
return "unknown error number";
|
||||
}
|
||||
|
26
src/ssl.c
26
src/ssl.c
@ -8768,6 +8768,8 @@ int wolfSSL_dtls_get_current_timeout(WOLFSSL* ssl)
|
||||
int timeout = 0;
|
||||
if (ssl)
|
||||
timeout = ssl->dtls_timeout;
|
||||
|
||||
WOLFSSL_LEAVE("wolfSSL_dtls_get_current_timeout()", timeout);
|
||||
return timeout;
|
||||
}
|
||||
|
||||
@ -8810,6 +8812,7 @@ int wolfSSL_dtls_set_timeout_max(WOLFSSL* ssl, int timeout)
|
||||
int wolfSSL_dtls_got_timeout(WOLFSSL* ssl)
|
||||
{
|
||||
int result = WOLFSSL_SUCCESS;
|
||||
WOLFSSL_ENTER("wolfSSL_dtls_got_timeout()");
|
||||
|
||||
if (ssl == NULL)
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
@ -8819,9 +8822,32 @@ int wolfSSL_dtls_got_timeout(WOLFSSL* ssl)
|
||||
|
||||
result = WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
|
||||
WOLFSSL_LEAVE("wolfSSL_dtls_got_timeout()", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* retransmit all the saves messages, WOLFSSL_SUCCESS on ok */
|
||||
int wolfSSL_dtls_retransmit(WOLFSSL* ssl)
|
||||
{
|
||||
WOLFSSL_ENTER("wolfSSL_dtls_retransmit()");
|
||||
|
||||
if (ssl == NULL)
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
|
||||
if (!ssl->options.handShakeDone) {
|
||||
int result = DtlsMsgPoolSend(ssl, 0);
|
||||
if (result < 0) {
|
||||
ssl->error = result;
|
||||
WOLFSSL_ERROR(result);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* DTLS */
|
||||
#endif /* LEANPSK */
|
||||
|
||||
|
@ -163,6 +163,7 @@ enum wolfSSL_ErrorCodes {
|
||||
EXT_MISSING = -428, /* Required extension not found */
|
||||
UNSUPPORTED_EXTENSION = -429, /* TLSX not requested by client */
|
||||
PRF_MISSING = -430, /* PRF not compiled in */
|
||||
DTLS_RETX_OVER_TX = -431, /* Retransmit DTLS flight over */
|
||||
/* add strings to wolfSSL_ERR_reason_error_string in internal.c !!!!! */
|
||||
|
||||
/* begin negotiation parameter errors */
|
||||
|
@ -3741,6 +3741,7 @@ struct WOLFSSL {
|
||||
word32 dtls_tx_msg_list_sz;
|
||||
word32 dtls_rx_msg_list_sz;
|
||||
DtlsMsg* dtls_tx_msg_list;
|
||||
DtlsMsg* dtls_tx_msg;
|
||||
DtlsMsg* dtls_rx_msg_list;
|
||||
void* IOCB_CookieCtx; /* gen cookie ctx */
|
||||
word32 dtls_expected_rx;
|
||||
|
@ -723,6 +723,7 @@ WOLFSSL_API int wolfSSL_dtls_get_current_timeout(WOLFSSL* ssl);
|
||||
WOLFSSL_API int wolfSSL_dtls_set_timeout_init(WOLFSSL* ssl, int);
|
||||
WOLFSSL_API int wolfSSL_dtls_set_timeout_max(WOLFSSL* ssl, int);
|
||||
WOLFSSL_API int wolfSSL_dtls_got_timeout(WOLFSSL* ssl);
|
||||
WOLFSSL_API int wolfSSL_dtls_retransmit(WOLFSSL*);
|
||||
WOLFSSL_API int wolfSSL_dtls(WOLFSSL* ssl);
|
||||
|
||||
WOLFSSL_API int wolfSSL_dtls_set_peer(WOLFSSL*, void*, unsigned int);
|
||||
|
@ -909,15 +909,18 @@ enum {
|
||||
TEST_SELECT_FAIL,
|
||||
TEST_TIMEOUT,
|
||||
TEST_RECV_READY,
|
||||
TEST_SEND_READY,
|
||||
TEST_ERROR_READY
|
||||
};
|
||||
|
||||
|
||||
#if !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_KEIL_TCP_NET) && \
|
||||
!defined(WOLFSSL_TIRTOS)
|
||||
static WC_INLINE int tcp_select(SOCKET_T socketfd, int to_sec)
|
||||
static WC_INLINE int tcp_select_ex(SOCKET_T socketfd, int to_sec, int rx)
|
||||
{
|
||||
fd_set recvfds, errfds;
|
||||
fd_set fds, errfds;
|
||||
fd_set* recvfds = NULL;
|
||||
fd_set* sendfds = NULL;
|
||||
SOCKET_T nfds = socketfd + 1;
|
||||
#if !defined(__INTEGRITY)
|
||||
struct timeval timeout = {(to_sec > 0) ? to_sec : 0, 0};
|
||||
@ -926,32 +929,56 @@ static WC_INLINE int tcp_select(SOCKET_T socketfd, int to_sec)
|
||||
#endif
|
||||
int result;
|
||||
|
||||
FD_ZERO(&recvfds);
|
||||
FD_SET(socketfd, &recvfds);
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(socketfd, &fds);
|
||||
FD_ZERO(&errfds);
|
||||
FD_SET(socketfd, &errfds);
|
||||
|
||||
if (rx)
|
||||
recvfds = &fds;
|
||||
else
|
||||
sendfds = &fds;
|
||||
|
||||
#if defined(__INTEGRITY)
|
||||
timeout.tv_sec = (long long)(to_sec > 0) ? to_sec : 0, 0;
|
||||
#endif
|
||||
result = select(nfds, &recvfds, NULL, &errfds, &timeout);
|
||||
result = select(nfds, recvfds, sendfds, &errfds, &timeout);
|
||||
|
||||
if (result == 0)
|
||||
return TEST_TIMEOUT;
|
||||
else if (result > 0) {
|
||||
if (FD_ISSET(socketfd, &recvfds))
|
||||
return TEST_RECV_READY;
|
||||
if (FD_ISSET(socketfd, &fds)) {
|
||||
if (rx)
|
||||
return TEST_RECV_READY;
|
||||
else
|
||||
return TEST_SEND_READY;
|
||||
}
|
||||
else if(FD_ISSET(socketfd, &errfds))
|
||||
return TEST_ERROR_READY;
|
||||
}
|
||||
|
||||
return TEST_SELECT_FAIL;
|
||||
}
|
||||
|
||||
static WC_INLINE int tcp_select(SOCKET_T socketfd, int to_sec)
|
||||
{
|
||||
return tcp_select_ex(socketfd, to_sec, 1);
|
||||
}
|
||||
|
||||
static WC_INLINE int tcp_select_tx(SOCKET_T socketfd, int to_sec)
|
||||
{
|
||||
return tcp_select_ex(socketfd, to_sec, 0);
|
||||
}
|
||||
|
||||
#elif defined(WOLFSSL_TIRTOS) || defined(WOLFSSL_KEIL_TCP_NET)
|
||||
static WC_INLINE int tcp_select(SOCKET_T socketfd, int to_sec)
|
||||
{
|
||||
return TEST_RECV_READY;
|
||||
}
|
||||
static WC_INLINE int tcp_select_tx(SOCKET_T socketfd, int to_sec)
|
||||
{
|
||||
return TEST_SEND_READY;
|
||||
}
|
||||
#endif /* !WOLFSSL_MDK_ARM */
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user