Server Side Secure Renegotiation

1. Add enables to the example server for turning on secure renegotiation.
2. Add encryption assists to the handhshake message handler functions.
3. Add a hello request message function. Includes handshake timing pre/postambles.
pull/1941/head
John Safranek 2018-10-02 15:38:45 -07:00
parent 74eadf556e
commit d168d60ade
7 changed files with 410 additions and 91 deletions

View File

@ -613,6 +613,10 @@ static void Usage(void)
printf("%s", msg[++msgId]); /* -N */
printf("%s", msg[++msgId]); /* -S */
printf("%s", msg[++msgId]); /* -w */
#ifdef HAVE_SECURE_RENEGOTIATION
printf("-M Allow Secure Renegotiation\n");
printf("-m Force Server Initiated Secure Renegotiation\n");
#endif /* HAVE_SECURE_RENEGOTIATION */
#ifdef HAVE_OCSP
printf("%s", msg[++msgId]); /* -o */
printf("%s", msg[++msgId]); /* -O */
@ -780,6 +784,10 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
#ifdef WOLFSSL_EARLY_DATA
int earlyData = 0;
#endif
#ifdef HAVE_SECURE_RENEGOTIATION
int scr = 0;
int forceScr = 0;
#endif /* HAVE_SECURE_RENEGOTIATION */
#ifdef WOLFSSL_SEND_HRR_COOKIE
int hrrCookie = 0;
#endif
@ -851,10 +859,10 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
#ifdef WOLFSSL_VXWORKS
useAnyAddr = 1;
#else
/* Not Used: h, m, z, F, M, T, V, W, X */
while ((ch = mygetopt(argc, argv, "?:"
"abc:defgijk:l:nop:q:rstuv:wxy"
"A:B:C:D:E:GH:IJKL:NO:PQR:S:TUVYZ:"
/* Not Used: h, z, F, T, V, W, X */
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) {
switch (ch) {
case '?' :
@ -1161,6 +1169,19 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
#endif
break;
case 'M' :
#ifdef HAVE_SECURE_RENEGOTIATION
scr = 1;
#endif /* HAVE_SECURE_RENEGOTIATION */
break;
case 'm' :
#ifdef HAVE_SECURE_RENEGOTIATION
scr = 1;
forceScr = 1;
#endif /* HAVE_SECURE_RENEGOTIATION */
break;
case '0' :
#ifdef WOLFSSL_EARLY_DATA
earlyData = 1;
@ -1639,7 +1660,15 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
err_sys("unable to set mcast secret");
#endif
}
#if 0
#ifdef HAVE_SECURE_RENEGOTIATION
if (scr) {
if (wolfSSL_UseSecureRenegotiation(ssl) != WOLFSSL_SUCCESS) {
err_sys_ex(runWithErrors, "can't enable secure renegotiation");
}
}
#endif /* HAVE_SECURE_RENEGOTIATION */
#endif
#ifndef NO_HANDSHAKE_DONE_CB
wolfSSL_SetHsDoneCb(ssl, myHsDoneCb, NULL);
#endif
@ -1957,6 +1986,25 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
err = SSL_get_error(ssl, 0);
}
#if defined(HAVE_SECURE_RENEGOTIATION) && \
defined(HAVE_SERVER_RENEGOTIATION_INFO)
if (scr && forceScr) {
if (nonBlocking) {
printf("not doing secure renegotiation on example with"
" nonblocking yet");
} else {
if (wolfSSL_Rehandshake(ssl) != WOLFSSL_SUCCESS) {
err = wolfSSL_get_error(ssl, 0);
printf("err = %d, %s\n", err,
wolfSSL_ERR_error_string(err, buffer));
wolfSSL_free(ssl); ssl = NULL;
wolfSSL_CTX_free(ctx); ctx = NULL;
err_sys("wolfSSL_Rehandshake failed");
}
}
}
#endif /* HAVE_SECURE_RENEGOTIATION */
if (err != WOLFSSL_ERROR_ZERO_RETURN && echoData == 0 &&
throughput == 0) {
const char* write_msg;

View File

@ -4900,12 +4900,14 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
#endif
#ifdef HAVE_SECURE_RENEGOTIATION
if (ssl->options.side == WOLFSSL_CLIENT_END) {
/* use secure renegotiation by default (not recommend) */
#ifdef WOLFSSL_SECURE_RENEGOTIATION_ON_BY_DEFAULT
ret = wolfSSL_UseSecureRenegotiation(ssl);
if (ret != WOLFSSL_SUCCESS)
return ret;
#endif
}
#endif
return 0;
@ -10250,6 +10252,9 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx,
if (ret != 0)
SendAlert(ssl, alert_fatal, bad_certificate_status_response);
if (IsEncryptionOn(ssl, 0))
*inOutIdx += ssl->keys.padSz;
WOLFSSL_LEAVE("DoCertificateStatus", ret);
WOLFSSL_END(WC_FUNC_CERTIFICATE_STATUS_DO);
@ -10267,6 +10272,9 @@ static int DoHelloRequest(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
{
(void)input;
WOLFSSL_START(WC_FUNC_HELLO_REQUEST_DO);
WOLFSSL_ENTER("DoFinished");
if (size) /* must be 0 */
return BUFFER_ERROR;
@ -10285,6 +10293,8 @@ static int DoHelloRequest(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
#ifdef HAVE_SECURE_RENEGOTIATION
else if (ssl->secure_renegotiation && ssl->secure_renegotiation->enabled) {
ssl->secure_renegotiation->startScr = 1;
WOLFSSL_LEAVE("DoHelloRequest", 0);
WOLFSSL_END(WC_FUNC_HELLO_REQUEST_DO);
return 0;
}
#endif
@ -10330,6 +10340,7 @@ int DoFinished(WOLFSSL* ssl, const byte* input, word32* inOutIdx, word32 size,
else
XMEMCPY(ssl->secure_renegotiation->client_verify_data,
input + *inOutIdx, TLS_FINISHED_SZ);
ssl->secure_renegotiation->verifySet = 1;
}
#endif
@ -10699,6 +10710,28 @@ static int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx,
expectedIdx = *inOutIdx + size +
(ssl->keys.encryptionOn ? ssl->keys.padSz : 0);
#if !defined(WOLFSSL_NO_SERVER) && \
defined(HAVE_SECURE_RENEGOTIATION) && \
defined(HAVE_SERVER_RENEGOTIATION_INFO)
if (ssl->options.handShakeDone && type == client_hello &&
ssl->secure_renegotiation &&
ssl->secure_renegotiation->enabled)
{
WOLFSSL_MSG("Reset handshake state");
XMEMSET(&ssl->msgsReceived, 0, sizeof(MsgsReceived));
ssl->options.serverState = NULL_STATE;
ssl->options.clientState = NULL_STATE;
ssl->options.connectState = CONNECT_BEGIN;
ssl->options.acceptState = ACCEPT_BEGIN;
ssl->options.handShakeState = NULL_STATE;
ssl->secure_renegotiation->cache_status = SCR_CACHE_NEEDED;
ret = InitHandshakeHashes(ssl);
if (ret != 0)
return ret;
}
#endif
/* sanity check msg received */
if ( (ret = SanityCheckMsgReceived(ssl, type)) != 0) {
WOLFSSL_MSG("Sanity Check on handshake message type received failed");
@ -10881,6 +10914,13 @@ static int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx,
}
}
#endif
if (IsEncryptionOn(ssl, 0)) {
/* access beyond input + size should be checked against totalSz */
if (*inOutIdx + ssl->keys.padSz > totalSz)
return BUFFER_E;
*inOutIdx += ssl->keys.padSz;
}
break;
case client_key_exchange:
@ -14617,12 +14657,16 @@ int SendCertificateRequest(WOLFSSL* ssl)
sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ + reqSz;
if (!ssl->options.dtls) {
if (IsEncryptionOn(ssl, 1))
sendSz += MAX_MSG_EXTRA;
}
else {
#ifdef WOLFSSL_DTLS
if (ssl->options.dtls) {
sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
i += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
}
sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
i += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
#endif
}
/* check for available size */
if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
return ret;
@ -14675,18 +14719,34 @@ int SendCertificateRequest(WOLFSSL* ssl)
#endif
(void)i;
#ifdef WOLFSSL_DTLS
if (IsDtlsNotSctpMode(ssl)) {
if ((ret = DtlsMsgPoolSave(ssl, output, sendSz)) != 0)
if (IsEncryptionOn(ssl, 1)) {
byte* input;
int inputSz = i - RECORD_HEADER_SZ; /* build msg adds rec hdr */
input = (byte*)XMALLOC(inputSz, ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
if (input == NULL)
return MEMORY_E;
XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz);
sendSz = BuildMessage(ssl, output, sendSz, input, inputSz,
handshake, 1, 0, 0);
XFREE(input, ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
if (sendSz < 0)
return sendSz;
} else {
#ifdef WOLFSSL_DTLS
if (ssl->options.dtls)
DtlsSEQIncrement(ssl, CUR_ORDER);
if (IsDtlsNotSctpMode(ssl)) {
if ((ret = DtlsMsgPoolSave(ssl, output, sendSz)) != 0)
return ret;
}
#endif
ret = HashOutput(ssl, output, sendSz, 0);
if (ret != 0)
return ret;
}
if (ssl->options.dtls)
DtlsSEQIncrement(ssl, CUR_ORDER);
#endif
ret = HashOutput(ssl, output, sendSz, 0);
if (ret != 0)
return ret;
#if defined(WOLFSSL_CALLBACKS) || defined(OPENSSL_EXTRA)
if (ssl->hsInfoOn)
@ -15197,10 +15257,10 @@ int ReceiveData(WOLFSSL* ssl, byte* output, int sz, int peek)
startScr:
if (ssl->secure_renegotiation && ssl->secure_renegotiation->startScr) {
int err;
ssl->secure_renegotiation->startScr = 0; /* only start once */
WOLFSSL_MSG("Need to start scr, server requested");
if ( (err = wolfSSL_Rehandshake(ssl)) != WOLFSSL_SUCCESS)
return err;
ssl->secure_renegotiation->startScr = 0; /* only start once */
}
#endif
@ -17162,6 +17222,10 @@ exit_dpk:
return sendSz;
} else {
#ifdef WOLFSSL_DTLS
if (IsDtlsNotSctpMode(ssl)) {
if ((ret = DtlsMsgPoolSave(ssl, output, sendSz)) != 0)
return ret;
}
if (ssl->options.dtls)
DtlsSEQIncrement(ssl, CUR_ORDER);
#endif
@ -17170,13 +17234,6 @@ exit_dpk:
return ret;
}
#ifdef WOLFSSL_DTLS
if (IsDtlsNotSctpMode(ssl)) {
if ((ret = DtlsMsgPoolSave(ssl, output, sendSz)) != 0)
return ret;
}
#endif
ssl->options.clientState = CLIENT_HELLO_COMPLETE;
#ifdef OPENSSL_EXTRA
ssl->cbmode = SSL_CB_MODE_WRITE;
@ -21059,7 +21116,10 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
}
#endif /* WOLFSSL_DTLS */
/* check for available size */
if (IsEncryptionOn(ssl, 1))
sendSz += MAX_MSG_EXTRA;
/* check for avalaible size */
if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
return ret;
@ -21138,9 +21198,13 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
/* last, extensions */
#ifdef HAVE_TLS_EXTENSIONS
ret = TLSX_WriteResponse(ssl, output + idx, server_hello, NULL);
if (ret != 0)
return ret;
{
word16 offset = 0;
ret = TLSX_WriteResponse(ssl, output + idx, server_hello, &offset);
if (ret != 0)
return ret;
idx += offset;
}
#else
#ifdef HAVE_EXTENDED_MASTER
if (ssl->options.haveEMS) {
@ -21157,21 +21221,30 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
#endif
#endif
ssl->buffers.outputBuffer.length += sendSz;
#ifdef WOLFSSL_DTLS
if (IsDtlsNotSctpMode(ssl)) {
if ((ret = DtlsMsgPoolSave(ssl, output, sendSz)) != 0)
return ret;
}
if (IsEncryptionOn(ssl, 1)) {
byte* input;
int inputSz = idx - RECORD_HEADER_SZ; /* build msg adds rec hdr */
if (ssl->options.dtls) {
DtlsSEQIncrement(ssl, CUR_ORDER);
}
#endif
input = (byte*)XMALLOC(inputSz, ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
if (input == NULL)
return MEMORY_E;
ret = HashOutput(ssl, output, sendSz, 0);
if (ret != 0)
return ret;
XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz);
sendSz = BuildMessage(ssl, output, sendSz, input, inputSz,
handshake, 1, 0, 0);
XFREE(input, ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
if (sendSz < 0)
return sendSz;
} else {
#ifdef WOLFSSL_DTLS
if (ssl->options.dtls)
DtlsSEQIncrement(ssl, CUR_ORDER);
#endif
ret = HashOutput(ssl, output, sendSz, 0);
if (ret != 0)
return ret;
}
#if defined(WOLFSSL_CALLBACKS) || defined(OPENSSL_EXTRA)
if (ssl->hsInfoOn)
@ -21182,6 +21255,18 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
#endif
ssl->options.serverState = SERVER_HELLO_COMPLETE;
ssl->buffers.outputBuffer.length += sendSz;
#ifdef WOLFSSL_DTLS
if (IsDtlsNotSctpMode(ssl)) {
if ((ret = DtlsMsgPoolSave(ssl, output, sendSz)) != 0)
return ret;
}
if (ssl->options.dtls) {
DtlsSEQIncrement(ssl, CUR_ORDER);
}
#endif
if (ssl->options.groupMessages)
ret = 0;
@ -21294,6 +21379,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
#ifndef NO_RSA
byte* verifySig;
#endif
byte* input;
word32 idx;
word32 tmpSigSz;
word32 length;
@ -21309,6 +21395,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
word32 qshSz;
#endif
int sendSz;
int inputSz;
} SskeArgs;
static void FreeSskeArgs(WOLFSSL* ssl, void* pArgs)
@ -21606,6 +21693,11 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
args->idx += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
}
#endif
if (IsEncryptionOn(ssl, 1)) {
args->sendSz += MAX_MSG_EXTRA;
}
/* check for available size */
if ((ret = CheckAvailableSize(ssl, args->sendSz)) != 0) {
goto exit_sske;
@ -21665,6 +21757,10 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
}
#endif
if (IsEncryptionOn(ssl, 1)) {
args->sendSz += MAX_MSG_EXTRA;
}
/* check for available size */
if ((ret = CheckAvailableSize(ssl, args->sendSz)) != 0) {
goto exit_sske;
@ -21767,6 +21863,11 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
args->idx += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
}
#endif
if (IsEncryptionOn(ssl, 1)) {
args->sendSz += MAX_MSG_EXTRA;
}
/* check for available size */
if ((ret = CheckAvailableSize(ssl, args->sendSz)) != 0) {
goto exit_sske;
@ -21983,6 +22084,10 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
preSigIdx = args->idx;
}
#endif
if (IsEncryptionOn(ssl, 1)) {
args->sendSz += MAX_MSG_EXTRA;
}
/* check for available size */
if ((ret = CheckAvailableSize(ssl, args->sendSz)) != 0) {
goto exit_sske;
@ -22219,6 +22324,10 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
}
#endif
if (IsEncryptionOn(ssl, 1)) {
args->sendSz += MAX_MSG_EXTRA;
}
/* check for available size */
if ((ret = CheckAvailableSize(ssl, args->sendSz)) != 0) {
goto exit_sske;
@ -22697,20 +22806,45 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
}
#endif /* HAVE_ECC || HAVE_CURVE25519 */
#ifdef WOLFSSL_DTLS
if (IsDtlsNotSctpMode(ssl)) {
if ((ret = DtlsMsgPoolSave(ssl, args->output, args->sendSz)) != 0) {
goto exit_sske;
if (IsEncryptionOn(ssl, 1)) {
args->inputSz = args->length + HANDSHAKE_HEADER_SZ;
/* buildmsg adds rechdr */
args->input = (byte*)XMALLOC(args->inputSz, ssl->heap,
DYNAMIC_TYPE_IN_BUFFER);
if (args->input == NULL) {
ERROR_OUT(MEMORY_E, exit_sske);
}
XMEMCPY(args->input, args->output + RECORD_HEADER_SZ,
args->inputSz);
ret = BuildMessage(ssl, args->output, args->sendSz,
args->input, args->inputSz, handshake, 1, 0, 0);
XFREE(args->input, ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
args->input = NULL;
/* make sure its not double free'd on cleanup */
if (ret >= 0) {
args->sendSz = ret;
ret = 0;
}
}
else {
#ifdef WOLFSSL_DTLS
if (IsDtlsNotSctpMode(ssl)) {
if ((ret = DtlsMsgPoolSave(ssl,
args->output, args->sendSz)) != 0) {
goto exit_sske;
}
}
if (ssl->options.dtls)
DtlsSEQIncrement(ssl, CUR_ORDER);
#endif
if (ssl->options.dtls)
DtlsSEQIncrement(ssl, CUR_ORDER);
#endif
ret = HashOutput(ssl, args->output, args->sendSz, 0);
if (ret != 0) {
goto exit_sske;
ret = HashOutput(ssl, args->output, args->sendSz, 0);
if (ret != 0) {
goto exit_sske;
}
}
#if defined(WOLFSSL_CALLBACKS) || defined(OPENSSL_EXTRA)
@ -23745,6 +23879,12 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
}
ret = MatchSuite(ssl, &clSuites);
#ifdef HAVE_SECURE_RENEGOTIATION
if (ssl->secure_renegotiation && ssl->secure_renegotiation->enabled &&
IsEncryptionOn(ssl, 0)) {
ssl->secure_renegotiation->startScr = 1;
}
#endif
WOLFSSL_LEAVE("DoClientHello", ret);
WOLFSSL_END(WC_FUNC_CLIENT_HELLO_DO);
@ -24053,6 +24193,10 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
case TLS_ASYNC_FINALIZE:
{
if (IsEncryptionOn(ssl, 0)) {
args->idx += ssl->keys.padSz;
}
ssl->options.havePeerVerify = 1;
/* Set final index */
@ -24118,6 +24262,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
#endif
if (IsEncryptionOn(ssl, 1))
sendSz += MAX_MSG_EXTRA;
/* check for available size */
if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
return ret;
@ -24128,19 +24275,34 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
AddHeaders(output, 0, server_hello_done, ssl);
#ifdef WOLFSSL_DTLS
if (IsDtlsNotSctpMode(ssl)) {
if ((ret = DtlsMsgPoolSave(ssl, output, sendSz)) != 0)
return 0;
}
if (IsEncryptionOn(ssl, 1)) {
byte* input;
int inputSz = HANDSHAKE_HEADER_SZ; /* build msg adds rec hdr */
if (ssl->options.dtls)
DtlsSEQIncrement(ssl, CUR_ORDER);
#endif
input = (byte*)XMALLOC(inputSz, ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
if (input == NULL)
return MEMORY_E;
ret = HashOutput(ssl, output, sendSz, 0);
XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz);
sendSz = BuildMessage(ssl, output, sendSz, input, inputSz,
handshake, 1, 0, 0);
XFREE(input, ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
if (sendSz < 0)
return sendSz;
} else {
#ifdef WOLFSSL_DTLS
if (IsDtlsNotSctpMode(ssl)) {
if ((ret = DtlsMsgPoolSave(ssl, output, sendSz)) != 0)
return ret;
}
if (ssl->options.dtls)
DtlsSEQIncrement(ssl, CUR_ORDER);
#endif
ret = HashOutput(ssl, output, sendSz, 0);
if (ret != 0)
return ret;
}
#if defined(WOLFSSL_CALLBACKS) || defined(OPENSSL_EXTRA)
if (ssl->hsInfoOn)
@ -24409,12 +24571,16 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
length += ssl->session.ticketLen;
sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
if (!ssl->options.dtls) {
if (IsEncryptionOn(ssl, 1) && ssl->options.handShakeDone)
sendSz += MAX_MSG_EXTRA;
}
else {
#ifdef WOLFSSL_DTLS
if (ssl->options.dtls) {
sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
idx += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
}
#endif
}
/* check for available size */
if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
return ret;
@ -24435,19 +24601,38 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
/* ticket */
XMEMCPY(output + idx, ssl->session.ticket, ssl->session.ticketLen);
/* idx += ssl->session.ticketLen; */
idx += ssl->session.ticketLen;
#ifdef WOLFSSL_DTLS
if (ssl->options.dtls) {
if ((ret = DtlsMsgPoolSave(ssl, output, sendSz)) != 0)
return ret;
if (IsEncryptionOn(ssl, 1) && ssl->options.handShakeDone) {
byte* input;
int inputSz = idx - RECORD_HEADER_SZ; /* build msg adds rec hdr */
DtlsSEQIncrement(ssl, CUR_ORDER);
input = (byte*)XMALLOC(inputSz, ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
if (input == NULL)
return MEMORY_E;
XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz);
sendSz = BuildMessage(ssl, output, sendSz, input, inputSz,
handshake, 1, 0, 0);
XFREE(input, ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
if (sendSz < 0)
return sendSz;
}
else {
#ifdef WOLFSSL_DTLS
if (ssl->options.dtls) {
if ((ret = DtlsMsgPoolSave(ssl, output, sendSz)) != 0)
return ret;
DtlsSEQIncrement(ssl, CUR_ORDER);
}
#endif
ret = HashOutput(ssl, output, sendSz, 0);
if (ret != 0)
return ret;
}
#endif
ret = HashOutput(ssl, output, sendSz, 0);
if (ret != 0) return ret;
ssl->buffers.outputBuffer.length += sendSz;
ret = SendBuffered(ssl);
@ -24462,6 +24647,62 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
#ifndef WOLFSSL_NO_TLS12
#if defined(HAVE_SECURE_RENEGOTIATION) && \
defined(HAVE_SERVER_RENEGOTIATION_INFO) && \
!defined(WOLFSSL_NO_SERVER)
/* handle generation of server's hello_request (0) */
int SendHelloRequest(WOLFSSL* ssl)
{
byte* output;
int sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
int ret;
WOLFSSL_START(WC_FUNC_HELLO_REQUEST_SEND);
WOLFSSL_ENTER("SendHelloRequest");
if (IsEncryptionOn(ssl, 1))
sendSz += MAX_MSG_EXTRA;
/* check for available size */
if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
return ret;
/* get output buffer */
output = ssl->buffers.outputBuffer.buffer +
ssl->buffers.outputBuffer.length;
AddHeaders(output, 0, hello_request, ssl);
if (IsEncryptionOn(ssl, 1)) {
byte* input;
int inputSz = HANDSHAKE_HEADER_SZ; /* build msg adds rec hdr */
input = (byte*)XMALLOC(inputSz, ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
if (input == NULL)
return MEMORY_E;
XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz);
sendSz = BuildMessage(ssl, output, sendSz, input, inputSz,
handshake, 0, 0, 0);
XFREE(input, ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
if (sendSz < 0)
return sendSz;
}
ssl->buffers.outputBuffer.length += sendSz;
ret = SendBuffered(ssl);
WOLFSSL_LEAVE("SendHelloRequest", ret);
WOLFSSL_END(WC_FUNC_HELLO_REQUEST_SEND);
return ret;
}
#endif /* HAVE_SECURE_RENEGOTIATION && HAVE_SERVER_RENEGOTIATION_INFO */
#ifdef WOLFSSL_DTLS
/* handle generation of DTLS hello_verify_request (3) */
static int SendHelloVerifyRequest(WOLFSSL* ssl,
@ -25547,6 +25788,10 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
case TLS_ASYNC_FINALIZE:
{
if (IsEncryptionOn(ssl, 0)) {
args->idx += ssl->keys.padSz;
}
#ifdef HAVE_QSH
word16 name;

View File

@ -2390,6 +2390,12 @@ int wolfSSL_Rehandshake(WOLFSSL* ssl)
ssl->secure_renegotiation->cache_status = SCR_CACHE_NEEDED;
if (ssl->options.side == WOLFSSL_SERVER_END) {
ret = SendHelloRequest(ssl);
if (ret != 0)
return ret;
}
ret = InitHandshakeHashes(ssl);
if (ret !=0)
return ret;

View File

@ -34,7 +34,7 @@
#include <wolfssl/error-ssl.h>
#include <wolfssl/wolfcrypt/hmac.h>
#ifdef NO_INLINE
#include <wolfssl/wolfcrypt/misc.h>
#else
#define WOLFSSL_MISC_INCLUDED
#include <wolfcrypt/src/misc.c>
@ -4307,7 +4307,7 @@ static byte TLSX_SecureRenegotiation_GetSize(SecureRenegotiation* data,
byte length = OPAQUE8_LEN; /* empty info length */
/* data will be NULL for HAVE_SERVER_RENEGOTIATION_INFO only */
if (data && data->enabled) {
if (data && data->enabled && data->verifySet) {
/* client sends client_verify_data only */
length += TLS_FINISHED_SZ;
@ -4323,8 +4323,7 @@ static word16 TLSX_SecureRenegotiation_Write(SecureRenegotiation* data,
byte* output, int isRequest)
{
word16 offset = OPAQUE8_LEN; /* RenegotiationInfo length */
if (data && data->enabled) {
if (data && data->enabled && data->verifySet) {
/* client sends client_verify_data only */
XMEMCPY(output + offset, data->client_verify_data, TLS_FINISHED_SZ);
offset += TLS_FINISHED_SZ;
@ -4352,15 +4351,16 @@ static int TLSX_SecureRenegotiation_Parse(WOLFSSL* ssl, byte* input,
if (isRequest && *input == 0) {
#ifdef HAVE_SERVER_RENEGOTIATION_INFO
if (length == OPAQUE8_LEN) {
if (TLSX_Find(ssl->extensions,
TLSX_RENEGOTIATION_INFO) == NULL) {
ret = TLSX_AddEmptyRenegotiationInfo(&ssl->extensions,
ssl->heap);
if (ret == WOLFSSL_SUCCESS)
ret = 0;
} else {
ret = 0;
ret = TLSX_UseSecureRenegotiation(&ssl->extensions,
ssl->heap);
if (ret != WOLFSSL_SUCCESS)
return ret;
ret = 0;
TLSX* extension = TLSX_Find(ssl->extensions, TLSX_RENEGOTIATION_INFO);
if (extension) {
ssl->secure_renegotiation = (SecureRenegotiation*)extension->data;
extension->resp = 1;
ssl->secure_renegotiation->enabled = 1;
}
}
#else
@ -4378,8 +4378,19 @@ static int TLSX_SecureRenegotiation_Parse(WOLFSSL* ssl, byte* input,
else if (isRequest) {
#ifndef NO_WOLFSSL_SERVER
if (*input == TLS_FINISHED_SZ) {
/* TODO compare client_verify_data */
ret = 0;
input++; /* get past size */
/* validate client verify data */
if (XMEMCMP(input,
ssl->secure_renegotiation->client_verify_data,
TLS_FINISHED_SZ) == 0) {
WOLFSSL_MSG("SCR client verify data match");
ret = 0; /* verified */
TLSX_SetResponse(ssl, TLSX_RENEGOTIATION_INFO);
} else {
/* already in error state */
WOLFSSL_MSG("SCR client verify data Failure");
}
}
#endif
}

View File

@ -64,6 +64,8 @@ static struct wc_error_queue* wc_last_node;
static double wc_func_start[WC_FUNC_COUNT];
static double wc_func_time[WC_FUNC_COUNT] = { 0, };
static const char* wc_func_name[WC_FUNC_COUNT] = {
"SendHelloRequest",
"DoHelloRequest",
"SendClientHello",
"DoClientHello",
"SendServerHello",

View File

@ -2272,6 +2272,7 @@ enum key_cache_state {
/* Additional Connection State according to rfc5746 section 3.1 */
typedef struct SecureRenegotiation {
byte enabled; /* secure_renegotiation flag in rfc */
byte verifySet;
byte startScr; /* server requested client to start scr */
enum key_cache_state cache_status; /* track key cache state */
byte client_verify_data[TLS_FINISHED_SZ]; /* cached */
@ -2511,7 +2512,7 @@ struct WOLFSSL_CTX {
#ifdef HAVE_EXT_CACHE
byte internalCacheOff:1;
#endif
byte sendVerify; /* for client side (can not be single bit) */
byte sendVerify:2; /* for client side (can not be single bit) */
byte haveRSA:1; /* RSA available */
byte haveECC:1; /* ECC available */
byte haveDH:1; /* server DH parms set by user */
@ -4032,6 +4033,10 @@ WOLFSSL_LOCAL int SendCertificateRequest(WOLFSSL*);
|| defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
WOLFSSL_LOCAL int CreateOcspResponse(WOLFSSL*, OcspRequest**, buffer*);
#endif
#if defined(HAVE_SECURE_RENEGOTIATION) && \
defined(HAVE_SERVER_RENEGOTIATION_INFO)
WOLFSSL_LOCAL int SendHelloRequest(WOLFSSL*);
#endif
WOLFSSL_LOCAL int SendCertificateStatus(WOLFSSL*);
WOLFSSL_LOCAL int SendServerKeyExchange(WOLFSSL*);
WOLFSSL_LOCAL int SendBuffered(WOLFSSL*);

View File

@ -51,7 +51,9 @@ enum wc_LogLevels {
* Do not use WOLFSSL_FUNC_TIME in production code.
*/
enum wc_FuncNum {
WC_FUNC_CLIENT_HELLO_SEND = 0,
WC_FUNC_HELLO_REQUEST_SEND = 0,
WC_FUNC_HELLO_REQUEST_DO,
WC_FUNC_CLIENT_HELLO_SEND,
WC_FUNC_CLIENT_HELLO_DO,
WC_FUNC_SERVER_HELLO_SEND,
WC_FUNC_SERVER_HELLO_DO,