Skip to content
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

DTLS: Add server side stateless and CID QoL API #8224

Merged
merged 12 commits into from
Dec 23, 2024

Conversation

julek-wolfssl
Copy link
Member

  • wolfDTLS_accept_stateless - statelessly listen for incoming connections
  • wolfSSL_inject - insert data into WOLFSSL object
  • wolfSSL_SSL(Enable|Disable)Read - enable/disable reading from IO
  • wolfSSL_get_wfd - get the write side file descriptor
  • wolfSSL_dtls_set_pending_peer - set the pending peer that will be upgraded to regular peer when we successfully de-protect a DTLS record
  • wolfSSL_dtls_get0_peer - zero copy access to the peer address
  • wolfSSL_is_stateful - boolean to check if we have entered stateful processing
  • wolfSSL_dtls_cid_get0_rx - zero copy access to the rx cid
  • wolfSSL_dtls_cid_get0_tx - zero copy access to the tx cid
  • wolfSSL_dtls_cid_parse - extract cid from a datagram/message

Copy link
Contributor

@rizlik rizlik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a big step in the right direction but there are things unclear. These comments are considering wolfSSL/wolfssl-examples#472 as the user of the changes in this PR.

  1. what's the purpose of splitting the fd in write and read?

  2. I don't get why we should use the pendingPeer and the example doesn't use it. It looks complicate and there is code that get hit after we copy the pendingPeer to the current Peer that it doesn't look doing nothing other than flipping the processPendingRecord bit.

  3. I don't see much gain in using wolfSSL_accept_stateless.
    AFAIU it just boils down in a) disabling read so that it can return before reading from the socket and b) to return after a good CH. a) avoids dropping other peer messages that can be received in the EmbedRecvFrom. But, as shown in the example, the server has already to read the messages itself outside of the wolfSSL to do proper demux. I wonder if then this is superfluous.

I would suggest of using a custom internal field like the pendingPeer, but called, as you suggested, currentRecordPeer.
Until the ssl is stateless, this is set on recvfrom, but no filtering happens bc of this.
It's used as the destination of the HRR/HVR and to compute the cookie.
It's not used anywhere else and it's not automatically copied over the other peer.
This way an ssl object can be used to reply to the CHs w/o cookies.
If we got a CH w/ valid cookie we can then leverage our existing goodch callback to set the right peer for sending and continue the connection.
If the application wants to demux, it needs to manage the reading from the socket itself anyway.

Just to recap, my suggestion are:

  • In EmbedRecvFrom to set a "peer to send the HRR/HRV" to if we are in a stateless
  • Application needs to use ChGoodCB to set the proper peer (is it already like this?)
  • Make clear that application needs to manage the read itself if it wants to demux over a single socket

The new APIs (inject, parse_cid) allows the application to manage the connection with a good tradeoff of complexity and control imo.

doc/dox_comments/header_files/ssl.h Outdated Show resolved Hide resolved
doc/dox_comments/header_files/ssl.h Outdated Show resolved Hide resolved
src/dtls.c Outdated Show resolved Hide resolved
src/ssl.c Show resolved Hide resolved
src/ssl.c Outdated Show resolved Hide resolved
src/internal.c Outdated Show resolved Hide resolved
src/ssl.c Show resolved Hide resolved
src/dtls.c Outdated Show resolved Hide resolved
@julek-wolfssl
Copy link
Member Author

what's the purpose of splitting the fd in write and read?

It was always split. I just added a getter for that field.

I don't get why we should use the pendingPeer and the example doesn't use it. It looks complicate and there is code that get hit after we copy the pendingPeer to the current Peer that it doesn't look doing nothing other than flipping the processPendingRecord bit.
[...]
It's used as the destination of the HRR/HVR and to compute the cookie.

The pending peer is used in the example when CID's are used. The bit flipping is just to make sure that the pending peer is only valid for the next parsed record. We already have a good mechanism for cookie calculation, there is no need to change it. The pendingPeer is used in conjunction with CID's to validate the incoming record before updating the peer address. An off-path attacker sending records with the CID set can change the address if we don't first attempt to de-protect the record. Attempting to de-protect an off-path attacker's packets should fail and we will reject the pendingPeer internally without any extra help from the application needed.

I don't see much gain in using wolfSSL_accept_stateless.

You're the one who suggested adding it :D. I think it makes sense to have it to abstract away from the user the complexity of the stateless handling.

But, as shown in the example, the server has already to read the messages itself outside of the wolfSSL to do proper demux. I wonder if then this is superfluous.

But we also support a server object that reads from the network directly. We have to support that use case as well. This API helps a lot with that case to make sure no records are lost.

To respond to the suggestions:

In EmbedRecvFrom to set a "peer to send the HRR/HRV" to if we are in a stateless

Adding.

Application needs to use ChGoodCB to set the proper peer (is it already like this?)

It does not need to do that. It calls wolfSSL_dtls_set_peer for peers during the connection process. wolfSSL_dtls_set_pending_peer is used during the connection with CID's.

Make clear that application needs to manage the read itself if it wants to demux over a single socket

I think that is clear from the example. Where do you think we need more documentation?

src/internal.c Outdated Show resolved Hide resolved
src/dtls.c Outdated Show resolved Hide resolved
@julek-wolfssl julek-wolfssl force-pushed the dtls-server-demux branch 5 times, most recently from 6a1039b to 5977bdb Compare December 12, 2024 18:36
@julek-wolfssl julek-wolfssl requested a review from rizlik December 12, 2024 18:45
Copy link
Contributor

@rizlik rizlik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks better, thanks!

src/internal.c Show resolved Hide resolved
src/internal.c Show resolved Hide resolved
@julek-wolfssl julek-wolfssl requested a review from rizlik December 16, 2024 17:06
@julek-wolfssl julek-wolfssl force-pushed the dtls-server-demux branch 2 times, most recently from 6c298b9 to f95bd20 Compare December 17, 2024 10:17
@julek-wolfssl
Copy link
Member Author

@douzzer Learned to count and fixed the overflow. Fixed the clang-tidy errors too.

@julek-wolfssl julek-wolfssl assigned douzzer and unassigned rizlik and julek-wolfssl Dec 19, 2024
rizlik
rizlik previously approved these changes Dec 19, 2024
douzzer
douzzer previously approved these changes Dec 19, 2024
@douzzer douzzer assigned JacobBarthelmeh and unassigned douzzer Dec 19, 2024
@JacobBarthelmeh JacobBarthelmeh removed their assignment Dec 20, 2024
…O_SOCK), not just defined(WOLFSSL_DTLS_CID).

tests/api.c: in test_dtls12_basic_connection_id(), omit chacha20 suites if defined(HAVE_FIPS), and fix gate on DHE-PSK-NULL-SHA256.
@douzzer douzzer dismissed stale reviews from JacobBarthelmeh and themself via 9d3e477 December 20, 2024 23:27
@JacobBarthelmeh JacobBarthelmeh merged commit 2409971 into wolfSSL:master Dec 23, 2024
148 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants