You are not logged in. Please login or register.
Active topics Unanswered topics
Welcome to the wolfSSL Forums!
Please post questions or comments you have about wolfSSL products here. It is helpful to be as descriptive as possible when asking your questions.
References
Stable Releases - download stable product releases.
Development Branch - latest development branch on GitHub.
wolfSSL Manual - wolfSSL (formerly CyaSSL) product manual and API reference.
Search options
Using wolfSSL in client mode and resuming a DTLS session, there is no mechanism to retransmit the last message flight if it gets lost. This is the flight that contains the Change Cipher Spec message.
Currently the way to recover from this seems to be to realise that the connection doesn't work and restart the negotiation from scratch.
Are there any plans to implement this mechanism?
The relevant section from RFC 6347 is:
In addition, for at least twice the default MSL defined for [TCP],
when in the FINISHED state, the node that transmits the last flight
(the server in an ordinary handshake or the client in a resumed
handshake) MUST respond to a retransmit of the peer's last flight
with a retransmit of the last flight. This avoids deadlock
conditions if the last flight gets lost. This requirement applies to
DTLS 1.0 as well, and though not explicit in [DTLS1], it was always
required for the state machine to function correctly.
Cheers,
Jonas
Hi,
Your solution to the second (epoch) issue isn't going to work. The record layer sequence number should be incremented also on retransmitted packets, says the RFC. What's less clear is what to do with epoch/sequence number on the Finished message; if the receiver never got the CCS+Finished flight, did the epoch change ever happen? What OpenSSL does here is to send Finished with the new epoch, but wait until the other end has answered before actually changing its state. The result is that the Finished message of the initial handshake is always sent as epoch 1, seqno 0, no matter how many retransmissions are made. I don't know how mature that DTLS implementation is, but to me it feels like a sensible way to go about epochs and sequence numbers.
I have implemented this and tested it against the OpenSSL example server, dropping different packets during the handshake: https://github.com/JonasNorling/cyassl/ … c903aadd26. I have posted a GitHub pull request.
Thanks John!
While digging through the DTLS code (2.6.0) I've found two other things that got me scratching my head:
1. SendFinished stores the Finished message twice in the pool: first something is saved by BuildMessage and then SendFinished calls DtlsPoolSave directly. It looks like BuildMessage shouldn't do that, and the resulting message on the wire is broken.
2. The epoch is incremented in an inconsistent way. When a ChangeCipherSpec is transmitted in the regular manner it is sent with the old epoch, and the next message uses the new epoch number. When DtlsPoolSend makes a retransmission of a ChangeCipherSpec the epoch is incremented first and the the CCS message uses the new epoch.
We have had problems with wolfSSL embedded ssl 2.6 crashing after negotiations fail. It turns out that it tried to free a buffer that was never malloced, and I traced the problem to DtlsPoolSend. It should call CheckAvalaibleSize() [sic], shouldn't it?
The below patch (on wolfssl-2.6.0) appears to solve the problem. Looking at the code, building without LARGE_STATIC_BUFFERS (which is what I do) makes things worse.
Index: cyassl/src/internal.c
===================================================================
--- cyassl.orig/src/internal.c 2013-05-08 15:22:15.704663345 +0200
+++ cyassl/src/internal.c 2013-05-08 15:24:14.716658339 +0200
@@ -1791,6 +1791,7 @@
int DtlsPoolSend(CYASSL* ssl)
{
+ int ret;
DtlsPool *pool = ssl->dtls_pool;
if (pool != NULL && pool->used > 0) {
@@ -1807,6 +1808,9 @@
c16toa(ssl->keys.dtls_epoch, dtls->epoch);
c32to48(ssl->keys.dtls_sequence_number++, dtls->sequence_number);
+ if ((ret = CheckAvalaibleSize(ssl, buf->length)) != 0)
+ return ret;
+
XMEMCPY(ssl->buffers.outputBuffer.buffer, buf->buffer, buf->length);
ssl->buffers.outputBuffer.idx = 0;
ssl->buffers.outputBuffer.length = buf->length;
Posts found: 4
Generated in 0.015 seconds (95% PHP - 5% DB) with 4 queries