DTLS non-blocking scrwith example

This commit is contained in:
Juliusz Sosinowicz
2020-08-25 11:26:20 +02:00
parent d077efcbb3
commit 8b934624f5
6 changed files with 119 additions and 18 deletions

View File

@ -856,7 +856,8 @@ static int ClientWrite(WOLFSSL* ssl, const char* msg, int msgSz, const char* str
}
#endif
}
} while (err == WOLFSSL_ERROR_WANT_WRITE
} while (err == WOLFSSL_ERROR_WANT_WRITE ||
err == WOLFSSL_ERROR_WANT_READ
#ifdef WOLFSSL_ASYNC_CRYPT
|| err == WC_PENDING_E
#endif
@ -3089,8 +3090,53 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
#ifdef HAVE_SECURE_RENEGOTIATION
if (scr && forceScr) {
if (nonBlocking) {
printf("not doing secure renegotiation on example with"
" nonblocking yet\n");
if (!resumeScr) {
if ((ret = wolfSSL_Rehandshake(ssl)) != WOLFSSL_SUCCESS) {
err = wolfSSL_get_error(ssl, 0);
if (err == WOLFSSL_ERROR_WANT_READ ||
err == WOLFSSL_ERROR_WANT_WRITE) {
(void)ClientWrite(ssl,
"This is a fun message sent during renegotiation",
sizeof("This is a fun message sent during renegotiation"),
"", 1);
do {
if (err == APP_DATA_READY) {
if ((ret = wolfSSL_read(ssl, reply, sizeof(reply)-1)) < 0) {
err_sys("APP DATA should be present but error returned");
}
printf("Received message: %s\n", reply);
}
err = 0;
if ((ret = wolfSSL_connect(ssl)) != WOLFSSL_SUCCESS) {
err = wolfSSL_get_error(ssl, ret);
}
} while (ret != WOLFSSL_SUCCESS &&
(err == WOLFSSL_ERROR_WANT_READ ||
err == WOLFSSL_ERROR_WANT_WRITE ||
err == APP_DATA_READY));
if (ret != WOLFSSL_SUCCESS) {
err = wolfSSL_get_error(ssl, 0);
printf("wolfSSL_Rehandshake error %d, %s\n", err,
wolfSSL_ERR_error_string(err, buffer));
wolfSSL_free(ssl); ssl = NULL;
wolfSSL_CTX_free(ctx); ctx = NULL;
err_sys("non-blocking wolfSSL_Rehandshake failed");
}
printf("NON-BLOCKING RENEGOTIATION SUCCESSFUL\n");
}
else {
printf("wolfSSL_Rehandshake error %d, %s\n", err,
wolfSSL_ERR_error_string(err, buffer));
wolfSSL_free(ssl); ssl = NULL;
wolfSSL_CTX_free(ctx); ctx = NULL;
err_sys("non-blocking wolfSSL_Rehandshake failed");
}
}
}
else {
printf("not doing secure resumption with non-blocking");
}
} else {
if (!resumeScr) {
printf("Beginning secure renegotiation.\n");

View File

@ -345,7 +345,7 @@ static int NonBlockingSSL_Accept(SSL* ssl)
return ret;
}
/* Echo number of bytes specified by -e arg */
/* Echo number of bytes specified by -B arg */
int ServerEchoData(SSL* ssl, int clientfd, int echoData, int block,
size_t throughput)
{
@ -366,7 +366,10 @@ int ServerEchoData(SSL* ssl, int clientfd, int echoData, int block,
select_ret = tcp_select(clientfd, 1); /* Timeout=1 second */
if (select_ret == TEST_RECV_READY) {
len = min(block, (int)(throughput - xfer_bytes));
if (throughput)
len = min(block, (int)(throughput - xfer_bytes));
else
len = block;
rx_pos = 0;
if (throughput) {
@ -386,7 +389,8 @@ int ServerEchoData(SSL* ssl, int clientfd, int echoData, int block,
else
#endif
if (err != WOLFSSL_ERROR_WANT_READ &&
err != WOLFSSL_ERROR_ZERO_RETURN) {
err != WOLFSSL_ERROR_ZERO_RETURN &&
err != APP_DATA_READY) {
printf("SSL_read echo error %d\n", err);
err_sys_ex(runWithErrors, "SSL_read failed");
break;
@ -398,6 +402,8 @@ int ServerEchoData(SSL* ssl, int clientfd, int echoData, int block,
}
else {
rx_pos += ret;
if (!throughput)
break;
}
}
if (throughput) {
@ -408,7 +414,7 @@ int ServerEchoData(SSL* ssl, int clientfd, int echoData, int block,
/* Write data */
do {
err = 0; /* reset error */
ret = SSL_write(ssl, buffer, len);
ret = SSL_write(ssl, buffer, min(len, rx_pos));
if (ret <= 0) {
err = SSL_get_error(ssl, 0);
#ifdef WOLFSSL_ASYNC_CRYPT
@ -419,7 +425,7 @@ int ServerEchoData(SSL* ssl, int clientfd, int echoData, int block,
#endif
}
} while (err == WC_PENDING_E);
if (ret != len) {
if (ret != (int)min(len, rx_pos)) {
printf("SSL_write echo error %d\n", err);
err_sys_ex(runWithErrors, "SSL_write failed");
}

View File

@ -14587,6 +14587,27 @@ int DoApplicationData(WOLFSSL* ssl, byte* input, word32* inOutIdx)
#endif
*inOutIdx = idx;
#ifdef HAVE_SECURE_RENEGOTIATION
if (IsSCR(ssl)) {
/* If we are in a secure renegotiation then APP DATA is treated
* differently */
if (ssl->options.dtls) {
/* Reset the processReply state since
* we finished processing this message. */
ssl->options.processReply = doProcessInit;
return APP_DATA_READY;
}
else {
/* TODO should fail for TLS? */
ssl->buffers.clearOutputBuffer.buffer = NULL;
ssl->buffers.clearOutputBuffer.length = 0;
#ifdef WOLFSSL_EXTRA_ALERTS
SendAlert(ssl, alert_fatal, unexpected_message);
#endif
return OUT_OF_ORDER_E;
}
}
#endif
return 0;
}
@ -14867,6 +14888,9 @@ int ProcessReply(WOLFSSL* ssl)
#endif
if (ssl->error != 0 && ssl->error != WANT_READ && ssl->error != WANT_WRITE
#ifdef HAVE_SECURE_RENEGOTIATION
&& ssl->error != APP_DATA_READY
#endif
#ifdef WOLFSSL_ASYNC_CRYPT
&& ssl->error != WC_PENDING_E
#endif
@ -17595,14 +17619,15 @@ int DtlsCheckOrder(WOLFSSL* ssl, int order)
/* If secure renegotiation is disabled, this will always return false.
* Otherwise it checks to see if we are currently renegotiating. */
static WC_INLINE int IsSCR(WOLFSSL* ssl)
int IsSCR(WOLFSSL* ssl)
{
#ifndef HAVE_SECURE_RENEGOTIATION
(void)ssl;
#else /* HAVE_SECURE_RENEGOTIATION */
if (ssl->secure_renegotiation &&
ssl->secure_renegotiation->enabled &&
ssl->options.handShakeState != HANDSHAKE_DONE)
ssl->secure_renegotiation->enabled && /* Is SCR enabled? */
ssl->options.handShakeDone && /* At least one handshake done? */
ssl->options.handShakeState != HANDSHAKE_DONE) /* Currently handshaking? */
return 1;
#endif /* HAVE_SECURE_RENEGOTIATION */
return 0;
@ -17651,7 +17676,8 @@ int SendData(WOLFSSL* ssl, const void* data, int sz)
}
else
#endif
if (ssl->options.handShakeState != HANDSHAKE_DONE && !IsSCR(ssl)) {
if (ssl->options.handShakeState != HANDSHAKE_DONE &&
!ssl->options.dtls /* Allow data during renegotiation */ ) {
int err;
WOLFSSL_MSG("handshake not complete, trying to finish");
if ( (err = wolfSSL_negotiate(ssl)) != WOLFSSL_SUCCESS) {
@ -17838,10 +17864,18 @@ int ReceiveData(WOLFSSL* ssl, byte* output, int sz, int peek)
#ifdef HAVE_SECURE_RENEGOTIATION
startScr:
if (ssl->secure_renegotiation && ssl->secure_renegotiation->startScr) {
int ret;
int err;
WOLFSSL_MSG("Need to start scr, server requested");
if ( (err = wolfSSL_Rehandshake(ssl)) != WOLFSSL_SUCCESS)
return err;
if ( (ret = wolfSSL_Rehandshake(ssl)) != WOLFSSL_SUCCESS) {
err = wolfSSL_get_error(ssl, 0);
if (err == WOLFSSL_ERROR_WANT_READ ||
err == WOLFSSL_ERROR_WANT_WRITE ||
err == APP_DATA_READY)
ssl->secure_renegotiation->startScr = 0; /* only start once
* on non-blocking */
return ret;
}
ssl->secure_renegotiation->startScr = 0; /* only start once */
}
#endif
@ -17871,10 +17905,7 @@ startScr:
#endif
}
if (sz < (int)ssl->buffers.clearOutputBuffer.length)
size = sz;
else
size = ssl->buffers.clearOutputBuffer.length;
size = min(sz, ssl->buffers.clearOutputBuffer.length);
XMEMCPY(output, ssl->buffers.clearOutputBuffer.buffer, size);

View File

@ -2020,6 +2020,22 @@ static int wolfSSL_read_internal(WOLFSSL* ssl, void* data, int sz, int peek)
errno = 0;
#endif
#ifdef HAVE_SECURE_RENEGOTIATION
if (ssl->buffers.clearOutputBuffer.length > 0) {
int size = min(sz, ssl->buffers.clearOutputBuffer.length);
XMEMCPY(data, ssl->buffers.clearOutputBuffer.buffer, size);
if (peek == 0) {
ssl->buffers.clearOutputBuffer.length -= size;
ssl->buffers.clearOutputBuffer.buffer += size;
}
if (ssl->buffers.clearOutputBuffer.length == 0 &&
ssl->buffers.inputBuffer.dynamicFlag)
ShrinkInputBuffer(ssl, NO_FORCED_FREE);
WOLFSSL_LEAVE("wolfSSL_read_internal()", size);
return size;
}
#endif
#ifdef WOLFSSL_DTLS
if (ssl->options.dtls) {
ssl->dtls_expected_rx = max(sz + 100, MAX_MTU);

View File

@ -169,6 +169,7 @@ enum wolfSSL_ErrorCodes {
TLS13_SECRET_CB_E = -438, /* TLS1.3 secret Cb fcn failure */
DTLS_SIZE_ERROR = -439, /* Trying to send too much data */
NO_CERT_ERROR = -440, /* TLS1.3 - no cert set error */
APP_DATA_READY = -441, /* DTLS1.2 application data ready for read */
/* add strings to wolfSSL_ERR_reason_error_string in internal.c !!!!! */

View File

@ -4550,6 +4550,7 @@ WOLFSSL_LOCAL int GrowInputBuffer(WOLFSSL* ssl, int size, int usedLength);
WOLFSSL_LOCAL int IsDtlsMsgSCRKeys(WOLFSSL* ssl);
WOLFSSL_LOCAL int DtlsUseSCRKeys(WOLFSSL* ssl);
WOLFSSL_LOCAL int DtlsCheckOrder(WOLFSSL* ssl, int order);
WOLFSSL_LOCAL int IsSCR(WOLFSSL* ssl);
#endif
WOLFSSL_LOCAL void WriteSEQ(WOLFSSL* ssl, int verifyOrder, byte* out);