mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-31 19:24:42 +02:00
Fragmentation for ServerKeyExchange and CeriticateVerify
- The `ssl->dtlsMtuSz` value is the maximum possible size of the DTLS record layer. We read `ssl->dtlsMtuSz + 100` in case peer has slightly different MTU set. - The `-u` option in the examples takes the value of the MTU size. - MTU tests are added in `tests/test-dtls-mtu.conf`
This commit is contained in:
@@ -1529,6 +1529,10 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
||||
size_t throughput = 0;
|
||||
int doDTLS = 0;
|
||||
int dtlsUDP = 0;
|
||||
#if (defined(WOLFSSL_SCTP) || defined(WOLFSSL_DTLS_MTU)) && \
|
||||
defined(WOLFSSL_DTLS)
|
||||
int dtlsMTU = 0;
|
||||
#endif
|
||||
int dtlsSCTP = 0;
|
||||
int doMcast = 0;
|
||||
int matchName = 0;
|
||||
@@ -1713,7 +1717,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
||||
#ifndef WOLFSSL_VXWORKS
|
||||
/* Not used: All used */
|
||||
while ((ch = mygetopt(argc, argv, "?:"
|
||||
"ab:c:defgh:i;jk:l:mnop:q:rstuv:wxyz"
|
||||
"ab:c:defgh:i;jk:l:mnop:q:rstu;v:wxyz"
|
||||
"A:B:CDE:F:GH:IJKL:M:NO:PQRS:TUVW:XYZ:"
|
||||
"01:23:45689"
|
||||
"@#")) != -1) {
|
||||
@@ -1753,6 +1757,10 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
||||
case 'u' :
|
||||
doDTLS = 1;
|
||||
dtlsUDP = 1;
|
||||
#if (defined(WOLFSSL_SCTP) || defined(WOLFSSL_DTLS_MTU)) && \
|
||||
defined(WOLFSSL_DTLS)
|
||||
dtlsMTU = atoi(myoptarg);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 'G' :
|
||||
@@ -2493,6 +2501,11 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
||||
|
||||
if (fewerPackets)
|
||||
wolfSSL_CTX_set_group_messages(ctx);
|
||||
#if (defined(WOLFSSL_SCTP) || defined(WOLFSSL_DTLS_MTU)) && \
|
||||
defined(WOLFSSL_DTLS)
|
||||
if (dtlsMTU)
|
||||
wolfSSL_CTX_dtls_set_mtu(ctx, dtlsMTU);
|
||||
#endif
|
||||
|
||||
#ifndef NO_DH
|
||||
if (wolfSSL_CTX_SetMinDhKey_Sz(ctx, (word16)minDhKeyBits)
|
||||
|
@@ -1027,6 +1027,10 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
|
||||
int useAnon = 0;
|
||||
int doDTLS = 0;
|
||||
int dtlsUDP = 0;
|
||||
#if (defined(WOLFSSL_SCTP) || defined(WOLFSSL_DTLS_MTU)) && \
|
||||
defined(WOLFSSL_DTLS)
|
||||
int dtlsMTU = 0;
|
||||
#endif
|
||||
int dtlsSCTP = 0;
|
||||
int doMcast = 0;
|
||||
#ifdef WOLFSSL_DTLS
|
||||
@@ -1220,7 +1224,7 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
|
||||
|
||||
/* Not Used: h, z, W, X, 7, 9 */
|
||||
while ((ch = mygetopt(argc, argv, "?:"
|
||||
"abc:defgijk:l:mnop:q:rstuv:wxy"
|
||||
"abc:defgijk:l:mnop:q:rstu;v:wxy"
|
||||
"A:B:C:D:E:FGH:IJKL:MNO:PQR:S:T;UVYZ:"
|
||||
"01:23:4:5689"
|
||||
"@#")) != -1) {
|
||||
@@ -1268,6 +1272,10 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
|
||||
case 'u' :
|
||||
doDTLS = 1;
|
||||
dtlsUDP = 1;
|
||||
#if (defined(WOLFSSL_SCTP) || defined(WOLFSSL_DTLS_MTU)) && \
|
||||
defined(WOLFSSL_DTLS)
|
||||
dtlsMTU = atoi(myoptarg);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 'G' :
|
||||
@@ -1884,6 +1892,11 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
|
||||
|
||||
if (fewerPackets)
|
||||
wolfSSL_CTX_set_group_messages(ctx);
|
||||
#if (defined(WOLFSSL_SCTP) || defined(WOLFSSL_DTLS_MTU)) && \
|
||||
defined(WOLFSSL_DTLS)
|
||||
if (dtlsMTU)
|
||||
wolfSSL_CTX_dtls_set_mtu(ctx, dtlsMTU);
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_SCTP
|
||||
if (dtlsSCTP)
|
||||
|
449
src/internal.c
449
src/internal.c
@@ -174,6 +174,8 @@ WOLFSSL_CALLBACKS needs LARGE_STATIC_BUFFERS, please add LARGE_STATIC_BUFFERS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static int cipherExtraData(WOLFSSL* ssl);
|
||||
|
||||
#ifdef WOLFSSL_DTLS
|
||||
static WC_INLINE int DtlsCheckWindow(WOLFSSL* ssl);
|
||||
static WC_INLINE int DtlsUpdateWindow(WOLFSSL* ssl);
|
||||
@@ -5849,7 +5851,9 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
|
||||
#endif
|
||||
#if defined(WOLFSSL_SCTP) || defined(WOLFSSL_DTLS_MTU)
|
||||
ssl->dtlsMtuSz = ctx->dtlsMtuSz;
|
||||
ssl->dtls_expected_rx = ssl->dtlsMtuSz;
|
||||
/* Add 100 bytes so that we can operate with slight difference
|
||||
* in set MTU size on each peer */
|
||||
ssl->dtls_expected_rx = ssl->dtlsMtuSz + 100;
|
||||
#else
|
||||
ssl->dtls_expected_rx = MAX_MTU;
|
||||
#endif
|
||||
@@ -7554,7 +7558,7 @@ int DtlsMsgPoolSend(WOLFSSL* ssl, int sendOnlyFirstPacket)
|
||||
|
||||
input = pool->buf;
|
||||
inputSz = pool->sz;
|
||||
sendSz = inputSz + MAX_MSG_EXTRA;
|
||||
sendSz = inputSz + cipherExtraData(ssl);
|
||||
|
||||
#ifdef HAVE_SECURE_RENEGOTIATION
|
||||
/*
|
||||
@@ -8144,6 +8148,162 @@ static void AddFragHeaders(byte* output, word32 fragSz, word32 fragOffset,
|
||||
AddHandShakeHeader(output + outputAdj, length, fragOffset, fragSz, type, ssl);
|
||||
}
|
||||
#endif /* NO_CERTS */
|
||||
|
||||
/**
|
||||
* Send the handshake message. This funcion handles fragmenting the message
|
||||
* so that it will fit into the desired MTU or the max fragment size.
|
||||
* @param ssl Connection object
|
||||
* @param input Input starting at the record layer header. This function
|
||||
* assumes that the appropriate record and handshake headers
|
||||
* are present. These headers must assume no fragmentation.
|
||||
* That is handled here.
|
||||
* @param inputSz Length of message excluding headers (this is the total
|
||||
* length of all fragments)
|
||||
* @param type Type of message being sent
|
||||
* @return 0 on success and negative otherwise
|
||||
*/
|
||||
static int SendHandshakeMsg(WOLFSSL* ssl, byte* input, word32 inputSz,
|
||||
enum HandShakeType type, const char* packetName)
|
||||
{
|
||||
int maxFrag;
|
||||
int ret = 0;
|
||||
int headerSz;
|
||||
|
||||
WOLFSSL_ENTER("SendHandshakeMsg");
|
||||
(void)type;
|
||||
(void)packetName;
|
||||
|
||||
if (ssl == NULL || input == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
#ifdef WOLFSSL_DTLS
|
||||
if (ssl->options.dtls)
|
||||
headerSz = DTLS_RECORD_HEADER_SZ + DTLS_HANDSHAKE_HEADER_SZ;
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* In TLS we send one handshake header in total, not one
|
||||
* per fragment like in DTLS. The handshake header should
|
||||
* already be in the input buffer. */
|
||||
inputSz += HANDSHAKE_HEADER_SZ;
|
||||
headerSz = RECORD_HEADER_SZ;
|
||||
}
|
||||
maxFrag = wolfSSL_GetMaxRecordSize(ssl, (int)inputSz);
|
||||
|
||||
/* Make sure input is not the ssl output buffer as this
|
||||
* function doesn't handle that */
|
||||
if (input >= ssl->buffers.outputBuffer.buffer &&
|
||||
input <= ssl->buffers.outputBuffer.buffer +
|
||||
ssl->buffers.outputBuffer.bufferSize) {
|
||||
WOLFSSL_MSG("Can't use output buffer for input in SendHandshakeMsg");
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
if (ssl->fragOffset == 0) {
|
||||
/* Hash it before the loop as we modify the input with
|
||||
* encryption on */
|
||||
ret = HashOutput(ssl, input, headerSz + (int)inputSz, 0);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
#ifdef WOLFSSL_DTLS
|
||||
/* Decrement msg number so that we continue to use the
|
||||
* same msg number for this msg */
|
||||
if (ssl->options.dtls)
|
||||
ssl->keys.dtls_handshake_number--;
|
||||
#endif
|
||||
}
|
||||
while (ssl->fragOffset < inputSz) {
|
||||
byte* output;
|
||||
int outputSz;
|
||||
byte* data = input + ssl->fragOffset + headerSz;
|
||||
word32 fragSz = (word32)maxFrag;
|
||||
if (inputSz - ssl->fragOffset < fragSz)
|
||||
fragSz = inputSz - ssl->fragOffset;
|
||||
|
||||
/* check for available size */
|
||||
outputSz = headerSz + fragSz;
|
||||
if (IsEncryptionOn(ssl, 1))
|
||||
outputSz += cipherExtraData(ssl);
|
||||
if ((ret = CheckAvailableSize(ssl, outputSz)) != 0)
|
||||
return ret;
|
||||
output = ssl->buffers.outputBuffer.buffer +
|
||||
ssl->buffers.outputBuffer.length;
|
||||
/* scan-build complains that this may be null */
|
||||
if (output == NULL)
|
||||
return MEMORY_E;
|
||||
|
||||
if (IsEncryptionOn(ssl, 1)) {
|
||||
/* First we need to add the fragment header ourselves.
|
||||
* We do this in the input to minimize allocations */
|
||||
int dataSz = (int)fragSz;
|
||||
#ifdef WOLFSSL_DTLS
|
||||
if (ssl->options.dtls) {
|
||||
data -= DTLS_HANDSHAKE_HEADER_SZ;
|
||||
dataSz += DTLS_HANDSHAKE_HEADER_SZ;
|
||||
AddHandShakeHeader(data,
|
||||
inputSz, ssl->fragOffset, fragSz, type, ssl);
|
||||
}
|
||||
if (ssl->options.dtls)
|
||||
ssl->keys.dtls_handshake_number--;
|
||||
if (IsDtlsNotSctpMode(ssl) &&
|
||||
(ret = DtlsMsgPoolSave(ssl, data,
|
||||
fragSz + DTLS_HANDSHAKE_HEADER_SZ, type))
|
||||
!= 0)
|
||||
return ret;
|
||||
#endif
|
||||
ret = BuildMessage(ssl, output, outputSz,
|
||||
data, dataSz, handshake, 0, 0, 0, CUR_ORDER);
|
||||
if (ret >= 0)
|
||||
outputSz = ret;
|
||||
else
|
||||
return ret;
|
||||
ret = 0;
|
||||
}
|
||||
else {
|
||||
#ifdef WOLFSSL_DTLS
|
||||
if (ssl->options.dtls)
|
||||
AddFragHeaders(output, fragSz, ssl->fragOffset,
|
||||
inputSz, type, ssl);
|
||||
else
|
||||
#endif
|
||||
AddRecordHeader(output, fragSz, handshake, ssl, CUR_ORDER);
|
||||
|
||||
XMEMCPY(output + headerSz, data, fragSz);
|
||||
#ifdef WOLFSSL_DTLS
|
||||
if (ssl->options.dtls) {
|
||||
ssl->keys.dtls_handshake_number--;
|
||||
DtlsSEQIncrement(ssl, CUR_ORDER);
|
||||
}
|
||||
if (IsDtlsNotSctpMode(ssl)) {
|
||||
if ((ret = DtlsMsgPoolSave(ssl, output, headerSz + fragSz,
|
||||
type)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
ssl->buffers.outputBuffer.length += outputSz;
|
||||
#if defined(WOLFSSL_CALLBACKS) || defined(OPENSSL_EXTRA)
|
||||
if (ssl->hsInfoOn) {
|
||||
AddPacketName(ssl, packetName);
|
||||
}
|
||||
if (ssl->toInfoOn) {
|
||||
AddPacketInfo(ssl, packetName, handshake,
|
||||
output, outputSz, WRITE_PROTO, ssl->heap);
|
||||
}
|
||||
#endif
|
||||
ssl->fragOffset += fragSz;
|
||||
if (!ssl->options.groupMessages)
|
||||
ret = SendBuffered(ssl);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
#ifdef WOLFSSL_DTLS
|
||||
/* Increment msg number once we sent all fragments */
|
||||
if (ssl->options.dtls)
|
||||
ssl->keys.dtls_handshake_number++;
|
||||
#endif
|
||||
ssl->fragOffset = 0;
|
||||
return ret;
|
||||
}
|
||||
#endif /* !WOLFSSL_NO_TLS12 */
|
||||
|
||||
|
||||
@@ -8509,14 +8669,31 @@ int CheckAvailableSize(WOLFSSL *ssl, int size)
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_DTLS
|
||||
if (ssl->options.dtls &&
|
||||
size + ssl->buffers.outputBuffer.length -
|
||||
ssl->buffers.outputBuffer.idx > ssl->dtls_expected_rx) {
|
||||
int ret;
|
||||
WOLFSSL_MSG("CheckAvailableSize() flushing buffer "
|
||||
"to make room for new message");
|
||||
if ((ret = SendBuffered(ssl)) != 0) {
|
||||
return ret;
|
||||
if (ssl->options.dtls) {
|
||||
if (size + ssl->buffers.outputBuffer.length -
|
||||
ssl->buffers.outputBuffer.idx >
|
||||
#if defined(WOLFSSL_SCTP) || defined(WOLFSSL_DTLS_MTU)
|
||||
ssl->dtlsMtuSz
|
||||
#else
|
||||
ssl->dtls_expected_rx
|
||||
#endif
|
||||
) {
|
||||
int ret;
|
||||
WOLFSSL_MSG("CheckAvailableSize() flushing buffer "
|
||||
"to make room for new message");
|
||||
if ((ret = SendBuffered(ssl)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
if (size > (int)
|
||||
#if defined(WOLFSSL_SCTP) || defined(WOLFSSL_DTLS_MTU)
|
||||
ssl->dtlsMtuSz
|
||||
#else
|
||||
ssl->dtls_expected_rx
|
||||
#endif
|
||||
) {
|
||||
WOLFSSL_MSG("CheckAvailableSize() called with size greater than MTU.");
|
||||
return DTLS_SIZE_ERROR;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -25031,14 +25208,12 @@ int SendCertificateVerify(WOLFSSL* ssl)
|
||||
args->sendSz += MAX_MSG_EXTRA;
|
||||
}
|
||||
|
||||
/* check for available size */
|
||||
if ((ret = CheckAvailableSize(ssl, args->sendSz)) != 0) {
|
||||
goto exit_scv;
|
||||
}
|
||||
|
||||
/* get output buffer */
|
||||
args->output = ssl->buffers.outputBuffer.buffer +
|
||||
ssl->buffers.outputBuffer.length;
|
||||
/* Use tmp buffer */
|
||||
args->input = (byte*)XMALLOC(args->sendSz,
|
||||
ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
|
||||
if (args->input == NULL)
|
||||
ERROR_OUT(MEMORY_E, exit_scv);
|
||||
args->output = args->input;
|
||||
|
||||
/* Advance state and proceed */
|
||||
ssl->options.asyncState = TLS_ASYNC_BUILD;
|
||||
@@ -25328,32 +25503,6 @@ int SendCertificateVerify(WOLFSSL* ssl)
|
||||
AddHeaders(args->output, (word32)args->length + args->extraSz +
|
||||
VERIFY_HEADER, certificate_verify, ssl);
|
||||
|
||||
args->sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ +
|
||||
(word32)args->length + args->extraSz + VERIFY_HEADER;
|
||||
|
||||
#ifdef WOLFSSL_DTLS
|
||||
if (ssl->options.dtls) {
|
||||
args->sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (IsEncryptionOn(ssl, 1)) {
|
||||
int recordHeaderSz = RECORD_HEADER_SZ;
|
||||
|
||||
if (ssl->options.dtls)
|
||||
recordHeaderSz += DTLS_RECORD_EXTRA;
|
||||
args->inputSz = args->sendSz - recordHeaderSz;
|
||||
/* build msg adds rec hdr */
|
||||
args->input = (byte*)XMALLOC(args->inputSz, ssl->heap,
|
||||
DYNAMIC_TYPE_IN_BUFFER);
|
||||
if (args->input == NULL) {
|
||||
ERROR_OUT(MEMORY_E, exit_scv);
|
||||
}
|
||||
|
||||
XMEMCPY(args->input, args->output + recordHeaderSz,
|
||||
args->inputSz);
|
||||
}
|
||||
|
||||
/* Advance state and proceed */
|
||||
ssl->options.asyncState = TLS_ASYNC_END;
|
||||
} /* case TLS_ASYNC_FINALIZE */
|
||||
@@ -25361,59 +25510,11 @@ int SendCertificateVerify(WOLFSSL* ssl)
|
||||
|
||||
case TLS_ASYNC_END:
|
||||
{
|
||||
if (IsEncryptionOn(ssl, 1)) {
|
||||
#ifdef WOLFSSL_DTLS
|
||||
if (IsDtlsNotSctpMode(ssl) &&
|
||||
(ret = DtlsMsgPoolSave(ssl, args->input, args->inputSz, certificate_verify)) != 0) {
|
||||
goto exit_scv;
|
||||
}
|
||||
#endif
|
||||
ret = BuildMessage(ssl, args->output,
|
||||
MAX_CERT_VERIFY_SZ + MAX_MSG_EXTRA,
|
||||
args->input, args->inputSz, handshake,
|
||||
1, 0, 1, CUR_ORDER);
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
if (ret == WC_PENDING_E)
|
||||
goto exit_scv;
|
||||
#endif
|
||||
|
||||
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)) {
|
||||
ret = DtlsMsgPoolSave(ssl, args->output, args->sendSz, certificate_verify);
|
||||
}
|
||||
if (ret == 0 && ssl->options.dtls)
|
||||
DtlsSEQIncrement(ssl, CUR_ORDER);
|
||||
#endif
|
||||
if (ret == 0)
|
||||
ret = HashOutput(ssl, args->output, args->sendSz, 0);
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
ret = SendHandshakeMsg(ssl, args->output, (word32)args->length + args->extraSz +
|
||||
VERIFY_HEADER, certificate_verify, "CertificateVerify");
|
||||
if (ret != 0)
|
||||
goto exit_scv;
|
||||
}
|
||||
|
||||
#if defined(WOLFSSL_CALLBACKS) || defined(OPENSSL_EXTRA)
|
||||
if (ssl->hsInfoOn)
|
||||
AddPacketName(ssl, "CertificateVerify");
|
||||
if (ssl->toInfoOn)
|
||||
AddPacketInfo(ssl, "CertificateVerify", handshake,
|
||||
args->output, args->sendSz, WRITE_PROTO, ssl->heap);
|
||||
#endif
|
||||
|
||||
ssl->buffers.outputBuffer.length += args->sendSz;
|
||||
|
||||
if (!ssl->options.groupMessages) {
|
||||
ret = SendBuffered(ssl);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -26306,14 +26407,12 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
args->sendSz += MAX_MSG_EXTRA;
|
||||
}
|
||||
|
||||
/* check for available size */
|
||||
if ((ret = CheckAvailableSize(ssl, args->sendSz)) != 0) {
|
||||
goto exit_sske;
|
||||
}
|
||||
|
||||
/* get output buffer */
|
||||
args->output = ssl->buffers.outputBuffer.buffer +
|
||||
ssl->buffers.outputBuffer.length;
|
||||
/* Use tmp buffer */
|
||||
args->input = (byte*)XMALLOC(args->sendSz,
|
||||
ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
|
||||
if (args->input == NULL)
|
||||
ERROR_OUT(MEMORY_E, exit_sske);
|
||||
args->output = args->input;
|
||||
|
||||
AddHeaders(args->output, args->length,
|
||||
server_key_exchange, ssl);
|
||||
@@ -26369,14 +26468,12 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
args->sendSz += MAX_MSG_EXTRA;
|
||||
}
|
||||
|
||||
/* check for available size */
|
||||
if ((ret = CheckAvailableSize(ssl, args->sendSz)) != 0) {
|
||||
goto exit_sske;
|
||||
}
|
||||
|
||||
/* get output buffer */
|
||||
args->output = ssl->buffers.outputBuffer.buffer +
|
||||
ssl->buffers.outputBuffer.length;
|
||||
/* Use tmp buffer */
|
||||
args->input = (byte*)XMALLOC(args->sendSz,
|
||||
ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
|
||||
if (args->input == NULL)
|
||||
ERROR_OUT(MEMORY_E, exit_sske);
|
||||
args->output = args->input;
|
||||
|
||||
AddHeaders(args->output, args->length,
|
||||
server_key_exchange, ssl);
|
||||
@@ -26487,14 +26584,12 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
args->sendSz += MAX_MSG_EXTRA;
|
||||
}
|
||||
|
||||
/* check for available size */
|
||||
if ((ret = CheckAvailableSize(ssl, args->sendSz)) != 0) {
|
||||
goto exit_sske;
|
||||
}
|
||||
|
||||
/* get output buffer */
|
||||
args->output = ssl->buffers.outputBuffer.buffer +
|
||||
ssl->buffers.outputBuffer.length;
|
||||
/* Use tmp buffer */
|
||||
args->input = (byte*)XMALLOC(args->sendSz,
|
||||
ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
|
||||
if (args->input == NULL)
|
||||
ERROR_OUT(MEMORY_E, exit_sske);
|
||||
args->output = args->input;
|
||||
|
||||
/* key data */
|
||||
c16toa((word16)hintLen, args->output + args->idx);
|
||||
@@ -26689,14 +26784,12 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
args->sendSz += MAX_MSG_EXTRA;
|
||||
}
|
||||
|
||||
/* check for available size */
|
||||
if ((ret = CheckAvailableSize(ssl, args->sendSz)) != 0) {
|
||||
goto exit_sske;
|
||||
}
|
||||
|
||||
/* get output buffer */
|
||||
args->output = ssl->buffers.outputBuffer.buffer +
|
||||
ssl->buffers.outputBuffer.length;
|
||||
/* Use tmp buffer */
|
||||
args->input = (byte*)XMALLOC(args->sendSz,
|
||||
ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
|
||||
if (args->input == NULL)
|
||||
ERROR_OUT(MEMORY_E, exit_sske);
|
||||
args->output = args->input;
|
||||
|
||||
/* record and message headers will be added below, when we're sure
|
||||
of the sig length */
|
||||
@@ -26933,14 +27026,12 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
args->sendSz += MAX_MSG_EXTRA;
|
||||
}
|
||||
|
||||
/* check for available size */
|
||||
if ((ret = CheckAvailableSize(ssl, args->sendSz)) != 0) {
|
||||
goto exit_sske;
|
||||
}
|
||||
|
||||
/* get output buffer */
|
||||
args->output = ssl->buffers.outputBuffer.buffer +
|
||||
ssl->buffers.outputBuffer.length;
|
||||
/* Use tmp buffer */
|
||||
args->input = (byte*)XMALLOC(args->sendSz,
|
||||
ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
|
||||
if (args->input == NULL)
|
||||
ERROR_OUT(MEMORY_E, exit_sske);
|
||||
args->output = args->input;
|
||||
|
||||
AddHeaders(args->output, args->length,
|
||||
server_key_exchange, ssl);
|
||||
@@ -27449,73 +27540,10 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
}
|
||||
#endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */
|
||||
|
||||
if (IsEncryptionOn(ssl, 1)) {
|
||||
args->inputSz = args->length + HANDSHAKE_HEADER_SZ;
|
||||
if (ssl->options.dtls)
|
||||
args->inputSz += DTLS_HANDSHAKE_EXTRA;
|
||||
args->input = (byte*)XMALLOC(args->inputSz, ssl->heap,
|
||||
DYNAMIC_TYPE_IN_BUFFER);
|
||||
if (args->input == NULL) {
|
||||
ERROR_OUT(MEMORY_E, exit_sske);
|
||||
}
|
||||
|
||||
if (args->output == NULL) {
|
||||
ERROR_OUT(BUFFER_ERROR, exit_sske);
|
||||
}
|
||||
|
||||
if (!ssl->options.dtls)
|
||||
XMEMCPY(args->input, args->output + RECORD_HEADER_SZ,
|
||||
args->inputSz);
|
||||
else
|
||||
XMEMCPY(args->input, args->output + DTLS_RECORD_HEADER_SZ,
|
||||
args->inputSz);
|
||||
|
||||
#ifdef WOLFSSL_DTLS
|
||||
if (IsDtlsNotSctpMode(ssl) &&
|
||||
(ret = DtlsMsgPoolSave(ssl, args->input, args->inputSz, server_key_exchange))
|
||||
!= 0) {
|
||||
goto exit_sske;
|
||||
}
|
||||
#endif
|
||||
ret = BuildMessage(ssl, args->output, args->sendSz,
|
||||
args->input, args->inputSz, handshake, 1, 0, 0, CUR_ORDER);
|
||||
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, server_key_exchange)) != 0) {
|
||||
goto exit_sske;
|
||||
}
|
||||
}
|
||||
|
||||
if (ssl->options.dtls)
|
||||
DtlsSEQIncrement(ssl, CUR_ORDER);
|
||||
#endif
|
||||
|
||||
ret = HashOutput(ssl, args->output, args->sendSz, 0);
|
||||
if (ret != 0) {
|
||||
goto exit_sske;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(WOLFSSL_CALLBACKS) || defined(OPENSSL_EXTRA)
|
||||
if (ssl->hsInfoOn) {
|
||||
AddPacketName(ssl, "ServerKeyExchange");
|
||||
}
|
||||
if (ssl->toInfoOn) {
|
||||
AddPacketInfo(ssl, "ServerKeyExchange", handshake,
|
||||
args->output, args->sendSz, WRITE_PROTO, ssl->heap);
|
||||
}
|
||||
#endif
|
||||
ret = SendHandshakeMsg(ssl, args->output, args->length,
|
||||
server_key_exchange, "ServerKeyExchange");
|
||||
if (ret != 0)
|
||||
goto exit_sske;
|
||||
|
||||
/* Advance state and proceed */
|
||||
ssl->options.asyncState = TLS_ASYNC_END;
|
||||
@@ -27524,11 +27552,6 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
|
||||
case TLS_ASYNC_END:
|
||||
{
|
||||
ssl->buffers.outputBuffer.length += args->sendSz;
|
||||
if (!ssl->options.groupMessages) {
|
||||
ret = SendBuffered(ssl);
|
||||
}
|
||||
|
||||
ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
|
||||
break;
|
||||
}
|
||||
@@ -31621,22 +31644,20 @@ int wolfSSL_GetMaxRecordSize(WOLFSSL* ssl, int maxFragment)
|
||||
#endif /* HAVE_MAX_FRAGMENT */
|
||||
#ifdef WOLFSSL_DTLS
|
||||
if (IsDtlsNotSctpMode(ssl)) {
|
||||
int cipherExtra = IsEncryptionOn(ssl, 1) ? cipherExtraData(ssl) : 0;
|
||||
if (maxFragment > MAX_UDP_SIZE) {
|
||||
maxFragment = MAX_UDP_SIZE;
|
||||
}
|
||||
if (maxFragment > MAX_MTU - COMP_EXTRA - DTLS_RECORD_HEADER_SZ -
|
||||
DTLS_HANDSHAKE_HEADER_SZ) {
|
||||
DTLS_HANDSHAKE_HEADER_SZ - cipherExtra) {
|
||||
maxFragment = MAX_MTU - COMP_EXTRA - DTLS_RECORD_HEADER_SZ -
|
||||
DTLS_HANDSHAKE_HEADER_SZ;
|
||||
DTLS_HANDSHAKE_HEADER_SZ - cipherExtra;
|
||||
}
|
||||
#if defined(WOLFSSL_DTLS_MTU)
|
||||
{
|
||||
int overheadSz = DTLS_RECORD_HEADER_SZ + DTLS_HANDSHAKE_HEADER_SZ +
|
||||
COMP_EXTRA;
|
||||
if (IsEncryptionOn(ssl, 1))
|
||||
overheadSz += cipherExtraData(ssl);
|
||||
if (maxFragment >
|
||||
ssl->dtlsMtuSz - overheadSz) {
|
||||
COMP_EXTRA + cipherExtra;
|
||||
if (maxFragment > ssl->dtlsMtuSz - overheadSz) {
|
||||
maxFragment = ssl->dtlsMtuSz - overheadSz;
|
||||
}
|
||||
}
|
||||
|
@@ -2043,7 +2043,9 @@ static int wolfSSL_read_internal(WOLFSSL* ssl, void* data, int sz, int peek)
|
||||
if (ssl->options.dtlsSctp)
|
||||
#endif
|
||||
#if defined(WOLFSSL_SCTP) || defined(WOLFSSL_DTLS_MTU)
|
||||
ssl->dtls_expected_rx = max(ssl->dtls_expected_rx, ssl->dtlsMtuSz);
|
||||
/* Add 100 bytes so that we can operate with slight difference
|
||||
* in set MTU size on each peer */
|
||||
ssl->dtls_expected_rx = max(ssl->dtls_expected_rx, ssl->dtlsMtuSz + 100);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
@@ -33,6 +33,7 @@ EXTRA_DIST += tests/test.conf \
|
||||
tests/test-dtls-fails.conf \
|
||||
tests/test-dtls-fails-cipher.conf \
|
||||
tests/test-dtls-group.conf \
|
||||
tests/test-dtls-mtu.conf \
|
||||
tests/test-dtls-reneg-client.conf \
|
||||
tests/test-dtls-reneg-server.conf \
|
||||
tests/test-dtls-resume.conf \
|
||||
|
@@ -978,6 +978,19 @@ int SuiteTest(int argc, char** argv)
|
||||
goto exit;
|
||||
}
|
||||
#endif
|
||||
#ifdef WOLFSSL_DTLS_MTU
|
||||
/* Add dtls different MTU size tests.
|
||||
* These also use grouping to force wolfSSL to
|
||||
* bounce off the MTU limit more */
|
||||
strcpy(argv0[1], "tests/test-dtls-mtu.conf");
|
||||
printf("starting dtls MTU tests\n");
|
||||
test_harness(&args);
|
||||
if (args.return_code != 0) {
|
||||
printf("error from script %d\n", args.return_code);
|
||||
args.return_code = EXIT_FAILURE;
|
||||
goto exit;
|
||||
}
|
||||
#endif
|
||||
#ifdef WOLFSSL_OLDTLS_SHA2_CIPHERSUITES
|
||||
/* add dtls extra suites */
|
||||
strcpy(argv0[1], "tests/test-dtls-sha2.conf");
|
||||
|
2151
tests/test-dtls-mtu.conf
Normal file
2151
tests/test-dtls-mtu.conf
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user