Handle DTLS Hello packets without creating state.
Version
v5.1.1
Description
I have a use case where wolfSSL is used in a server process (built on top of asio). This process handles DTLS 1.2 connections.
I would like not to maintain a WOLFSSL object for each unverified Client Hello packet received ie. Client Hello packets without a cookie. The reason is that an attack using spoofed source addresses would make it trivial to exhaust the servers resources.
Flow diagram explaining the desired behavior
client ---ClientHello(no cookie)-------------> server
client <---HelloVerificationRequest(cookie)--- server (no state/connection is maintained in the server yet)
client ---ClientHello(with valid cookie)----> server (The server creates and maintains state/connection)
.... rest of the handshake
I have read the documentation and the source code, there does not seem to be a way to obtain the desired behavior.
I have made an experiment where the WOLFSSL obejct is freed if a HelloVerificationRequest is sent. But in that case the message_seq in the handshake is incompatible with what e.g. a MbedTLS client expects. The DTLS standard does not explicitly state what the message_seq in the handshake packet should be in that scenario, but 1 is a good guess. Currently WOLFSSL sends 0 if the first packet handled by a WOLFSSL object is a ClientHello with a valid cookie.
Is it possible to share the test application that illustrates the issue?
I do unfortunately not have a suitable test application which shows my issue.
I can try to clarify what the functionality I'm looking for is like:
The openssl equivalent for the functionality is called DTLSv1_listen https://www.openssl.org/docs/man1.1.1/man3/DTLSv1_listen.html
In the DTLS 1.2 RFC it is described in section 4.2.1 https://datatracker.ietf.org/doc/html/rfc6347#section-4.2.1
... without retaining any per-client state on the server. ....
@ejohnstown you asked for a way to illustrate the issue. I have made an example illustrating it with the server and client example coming with wolfSSL.
- configure and build wolfssl with dtls.
./configure --enable-dtls - run the server and client as
./examples/server/server -u -iand./examples/client/client -u - dump a client hello packet from the test above.
16fefd000000000000000000a80100009c000000000000009cfefd1c9558e6b5df6b87f03281ab59adcb584269185d56c64ae4d37dbea01215f80100000030c02cc02bc030c02f009f009ecca9cca8ccaac027c023c028c024c00ac009c014c013006b006700390033cc14cc13cc1501000042000d0020001e06030503040302030806080b0805080a0804080906010501040103010201000b00020100000a000c000a001900180017001501000016000000170000
- send the packet from 3 to the server.
echo '16fefd000000000000000000a80100009c000000000000009cfefd1c9558e6b5df6b87f03281ab59adcb584269185d56c64ae4d37dbea01215f80100000030c02cc02bc030c02f009f009ecca9cca8ccaac027c023c028c024c00ac009c014c013006b006700390033cc14cc13cc1501000042000d0020001e06030503040302030806080b0805080a0804080906010501040103010201000b00020100000a000c000a001900180017001501000016000000170000' | xxd -r -p | nc -u 127.0.0.1 11111
- try to invoke the client example again and see that the server is not responding as the single "connection resource" in the server is blocked by the packet from 4.
The example server isn't exactly a full fledged server. It is trying to allow one connection and then will only recvfrom that single IP tuple. The function DoClientHello should definitely work without holding state. A single DTLS object should reflexively send the HelloVerifyRequest on a ClientHello without the cookie.
I would agree it is difficult to tell when an incoming ClientHello does have the cookie beyond letting the handshake finish.
The idea you are proposing is close to what I tried to do. The problem with that idea is that wolfSSL sends the message sequence 0 instead of 1 in the second ServerHello handshake packet. This is probably because it is the first packet sent in that handshake context, but from the clients perspective it is the second packet received from the server.