-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
pkg/tinydtls: handling of close_notify #16422
Conversation
Removed |
This looks reasonable - is there any drawback to merging this? |
Nonetheless, it should be noted in the documentation before merge. I don't know from any more drawbacks by merging this. This does not fix the root cause, and there are still situations which lead to a not successful handshake we cannot address right now. To fix those, we need to refactor this completely. |
Just to mention one situation we still do not address right now: When we close a session, send the But again: This is a problem even without this PR. |
Maybe add a comment about the shortcomings of this solution, but if it's better than the status quo, I don't see a reason not to merge it. |
Maybe @obgm can also have a look? |
Thanks @miri64 for bringing this to my attention. I agree with @janosbrodbeck in his assessment of the situation and the benefits and risks of merging this PR. Note that tinydtls has had some changes recently, especially eclipse-tinydtls/tinydtls#53 which changed the close_notify alert level from fatal to warning. IMO this has no direct effect on the issue that dealt with in this PR. I also recommend updating pkg/tinydtls soon (there are a few important PRs under review that I also recommend waiting for, though). |
ea71798
to
449a664
Compare
I've added a note to the function documentation about the force reset. And I removed the draft state now. |
449a664
to
0b8ba3b
Compare
* @note For tinyDTLS this function destroys the session object right after notifying the remote | ||
* peer about the closing. This is an interim solution, preventing endlessly blocked session | ||
* slots, but allows as a consequence truncation attacks. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe link the tinyDTLS issue here as well, so we can track this in case this somehow gets resolved: eclipse-tinydtls/tinydtls#95
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea! Squashed it right away.
I also watch the upstream changes to look out for fixes. A solution on tinyDTLS side would be the best of course. Just have to be careful later when supporting further DTLS stacks that they behave similarly.
0b8ba3b
to
c016b84
Compare
Let me ask about the motivation to "close" the session: When/why is that done?
The reason for this question is simple:
The close may get lost, and so doesn't really help. 4.2.8 is in my opinion the only right way to do it. (In my Californium - Interoperability Tests it seems, that only mbedtls does 4.2.8 proper, openssl, gnutls and tinydtls (without PR 89) fails.) |
I'm still very confused about that and UDP. e.g. Wiki
There is just nothing as a TCP FIN for UDP. So, any references, what that attack means for UDP? |
Yes, 4.2.8 is a crucial problem part here. With this workaround, we can run into the problem that we force close a session and cannot re-establish the session with the same peer until the other side timeouts/resets the session on their side. I mentioned this problem in comment #16422 (comment). To be honest, I consider 4.2.8 as a MUST and not a SHOULD for a DTLS stack, especially when used on constrained devices. But this is and was a problem even without this workaround, since we do not get informed by the API right now if the closing was successful (= ACK from the remote part). In the case closing was unsuccessful, it could make tinyDTLS unusable in the long run without noticing by the application. This workaround should never stay forever, it's only supposed to be a temporary solution for clients, so they don't become unusable over time if the close_notify is not ACK-ed. |
:-) :-) :-) I always read MUST, I overseen the SHOULD ... :-) :-) :-)
Yes, agreed. But even with a working "close_notify", everyone must be aware, that dtls-server, which don't implement 4.2.8 are always a bad choice. Assuming NATs, your "ip-endpoint" may have even been used by a other peer without close before. |
That's actually a good question, what this means for UPD. I've taken the truncation part directly out of the TLS RFC. I'm honestly also too little in the picture, what it takes for truncation attacks all to effectively exploit. |
I wrote a e-mail to the tls-mailing list. |
Contribution description
Right now
sock_dtls_session_destroy()
does not do all the time what the API states.RIOT/sys/include/net/sock/dtls.h
Line 699 in 08f1f97
The sock implementation for tinyDTLS only initiates closing of a session, which results in sending a
close_notify
. But when the remote peer never ACK's the closing (e.g. not receiving or not answering), the session slot is blocked until device reboot. TinyDTLS endlessly stays in aSTATE_CLOSING
session state for that peer and there is no way of resetting a peer with the current DTLS sock API.The main problem is that
sock_dtls_session_destroy()
does not allow a return value for feedback. This is easily fixable...but currently it is not possible to get the success of the session closing procedure for tinyDTLS since it only sends theclose_notify
and then returns.I've looked into e.g. wolfSSL and their session close function seems to work a bit different: They send the
close_notify
and block for a short time and then return the success at this point of time. The user can decide how to handle a possible failure, e.g. try again or simply destroy the session object. DTLS libraries like wolfSSL, mbedTLS, tinyDTLS provide two distinct functions for that: session_close and peer_reset (= freeing of the peer object).Our DTLS sock API should also provide two functions for that (and allow a return value!). No single function can provide a solution for all needs here. How dangerous that is shows the current WIP wolfSSL implementation (#15698) for the sock API of @pokgak. In the current WIP approach
sock_dtls_session_destroy()
tries to close the session two times (recommended by wolfSSL), and when it fails two times it just returns. There is no way to tell the user that the session is not destroyed. And since there is also no force destroy, you cannot destroy the session.Road to fix this:
close_notify
was sent by tinyDTLS. It's allowed by the RFC, but mentions the possibility of truncation attack.But the current alternative is to live with the possibility of getting entire unusable peer slots in tinyDTLS (not detectable on user level). Note, in wireless networks it is not that unlikely that packets are not received depending on the link.
session_destroy
should be renamed tosession_close
. For tinyDTLS we need to find a solution to provide feedback.session_get_status()
would also make sense.I would suggest this PR as an interim solution.
Feedback or other opinions are appreciated.
Testing procedure
Issues/PRs references
#16108