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 support #40

Open
Yamakaky opened this issue Dec 8, 2016 · 41 comments
Open

DTLS support #40

Yamakaky opened this issue Dec 8, 2016 · 41 comments

Comments

@Yamakaky
Copy link

Yamakaky commented Dec 8, 2016

Do you plan on supporting DTLS (TLS over UDP)?

@ctz
Copy link
Member

ctz commented Dec 10, 2016

No plans at the minute. I know it's used for some VPNs, webrtc and some iot things. What is your use case?

@Yamakaky
Copy link
Author

VPN ^^

@manuels
Copy link

manuels commented Jan 14, 2017

Would you see DTLS within the scope of this library (i.e. would you accept pull request)?

@manuels
Copy link

manuels commented Jan 16, 2017

I am currently playing around implementing DTLS. Would it be the best to do this on the tls13 branch?

@ctz
Copy link
Member

ctz commented Jan 16, 2017

Would you see DTLS within the scope of this library

Perhaps. I'm not sure some of the external APIs are really suitable, to the extent that it might make sense as a separate crate built from the same codebase.

Would it be the best to do this on the tls13 branch?

Yes. Though beware that this branch is still in major churn and is overdue a serious refactoring of server_hs.rs/client_hs.rs

@manuels
Copy link

manuels commented Jan 17, 2017

In case you are interested: https://github.com/manuels/rustls/tree/dtls12
(although I just implemented Payload data structures and parsers up until now)

  • Payload data structures and parsers
  • Deframer
  • Handshake Fragmenter
  • Handshake De-Fragmenter
  • Protocol logic

@ctz
Copy link
Member

ctz commented Jan 22, 2017

Looking good! 👍

@manuels
Copy link

manuels commented Jan 28, 2017

Ok, I figured out that the situation is a bit complex, and there are several ways to implement DTLS specific stuff. Since this decision can have quite an extensive impact on the codebase I'd like to discuss how to proceed.

The Problem

DTLS requires some additional fields in Message and HandshakeMessagePayload and ClientHelloPayload as well as an additional handshake message HelloVerifyRequest. Additionally handshakes can be fragmented on the handshake protocol level instead of the record layer level.
See the sketch where modifications are highlighted.

dtls

Possible Solutions

Options

The additional fields could be integrated as Options into the regular TLS data types and would just be ignored in the TLS implementation. E.g.

pub struct ClientHelloPayload {
    pub client_version: ProtocolVersion,
    pub random: Random,
    pub session_id: SessionID,
    pub cookie: Option<Cookie>, // <-- !!!
    pub cipher_suites: Vec<CipherSuite>,
    pub compression_methods: Vec<Compression>,
    pub extensions: Vec<ClientExtension>,
}

Traits

A TLS Message and a DTLS Message are quite similar and the overlapping code could be moved into a trait MessageTrait. This would probably be the most rusty solution, but it would also make the code a bit more complex if most functions have a generic argument type of MessageTrait.

Macros

If you want a TLS Message and a DTLS Message data type in the codebase the overlapping code could probably also be deduplicated by some macro magic. But again, it might make the codebase more complex if there are macros scattered everywhere.

Maybe you guys can up with a better idea. I would love to get some feedback to see how to continue with implementing DTLS!

@manuels
Copy link

manuels commented Feb 1, 2017

After some time thinking about it, I think it's worth renaming the current Message to TLSMessage and creating a Message trait that is implemented by by TLSMessage and a DTLSMessage.

Then all struct impls just need to be impl<Msg: Message+Codec> MyStruct. Any comments on this?

@ctz
Copy link
Member

ctz commented Feb 1, 2017

DTLS/TLSMessage sounds ok, but beware that some performance relies on Message being moved by value into the processing functions: so the traits will need to cover these cases by exposing (eg) take_payload.

sorry, i overlooked your earlier comment.

for ClientHelloPayload and the like, are the functions which process these likely to be mostly shared between TLS and DTLS? if they're vastly different, then having a ClientHelloPayloadDTLS subtype would suffice (like some of the TLS1.3 types). otherwise, optional elements would be ok.

@manuels
Copy link

manuels commented Feb 1, 2017

for ClientHelloPayload and the like, are the functions which process these likely to be mostly shared between TLS and DTLS?

They are basically the same. The DTLS version of ClientHelloPayload just adds an optional cookie.

@manuels
Copy link

manuels commented Feb 4, 2017

Hey @ctz, I've seen in your TODO project that you are refactoring the state machine.
Do you already have some WIP that you could push to a new branch to github, so I can see where this is going.
I am at the point that I'd have to adapt it to implement DTLS.
Would be great!

Thanks!

@ctz
Copy link
Member

ctz commented Feb 4, 2017

I don't have any wip branch for that yet. But I'll push one once I do and link it here.

@manuels
Copy link

manuels commented Feb 5, 2017

In case this is useful: I tried to summarize the TLS state machine a while a go: https://github.com/manuels/tls-state-machine
index2

@manuels
Copy link

manuels commented Feb 15, 2017

A quick update. I had to refactor the TLS specific code of SessionCommon into a StreamTransport struct. I will now proceed and implement a DatagramTransport struct with a similar but DTLS specific behaviour.

@manuels
Copy link

manuels commented Mar 21, 2017

I am wondering how the user should decide which protocol to use.

Either the instantiation of {Client,Server}Session takes a Trait parameter ala ClientSession<TLS> (or ClientSession<DTLS>) at compile time, or it will decided at runtime using the ProtocolVersion.
But right now I do not see, how to implement this without a lot of ClientSessionImpl -> ClientSessionImpl<M:Message> renaming in the code.

@ctz, do you have a comment on this?

@ctz
Copy link
Member

ctz commented Mar 21, 2017

How about separate DatagramClientSession/DatagramServerSession types? I'm assuming these types need some kind of extra methods for timed triggering of retransmits?

On the question of ClientSessionImpl, could we inject implementations of a trait that deals with the important differences between datagram/stream TLS? Like which type of message to use. Actually those traits could be quite big. Hm.

@opensourcegeek
Copy link

Just wondering if there has been any progress on this issue, I'm working on IoT and support for DTLS would be very handy.

@manuels
Copy link

manuels commented Dec 5, 2017

Wireguard solved my problems so far and I do not have time to work on DTLS currently.
Maybe that might change in a year's time or so...

@henriktorget
Copy link

henriktorget commented Feb 12, 2019

@manuels Do you have time to have a look at it now? I would love to see some progress on this implementation. Many IoT platforms need communication over DTLS for security. I would love to work on this, but this is way over my head.

@TotalKrill
Copy link

A DTLS implementation would be very awesome, I hope you find some time @manuels, seems like you were very close!

@TimonPost
Copy link
Contributor

It would be great to see DTLS support, is there any progress?

@zizhengtai
Copy link

Would really love to see DTLS implemented in Rustls. We need it for some WebRTC work and currently are forced to use OpenSSL.

@ctz
Copy link
Member

ctz commented Dec 15, 2019

Some plans for this, but have been waiting for DTLS1.3. That is nearing completion now.

@repi
Copy link

repi commented Oct 28, 2020

Any additional thoughts or updates on this? Something we've been interested in as well and investigating options for, cc @luna-duclos

@lachlansneff
Copy link

A pure-rust DTLS implementation would be fantastic for embedded usecases. Any further updates on this?

@djc
Copy link
Member

djc commented Jun 29, 2021

DTLS 1.3 looks like it is nearing completion, currently in the RFC editor's queue.

Meanwhile, for some use cases maybe QUIC + its datagram extension is a decent fit?

(If someone is interested in sponsoring DTLS 1.3 support, I'd be happy to connect.)

@maufl
Copy link

maufl commented Jun 30, 2021

I recently discovered https://github.com/webrtc-rs/dtls but I don't know whether it is already usable.

@summit-solutions
Copy link

Also since QUIC has progressed very well, which runs over UDP but uses TLS building blocks from the regular TCP TLS implementations, the requirement for DTLS (UDP) has ... well, diminished.

@lachlansneff
Copy link

I recently discovered https://github.com/webrtc-rs/dtls but I don't know whether it is already usable.

Unfortunately, that crate seems to be very tightly fused to std.

@markmandel
Copy link

I recently discovered https://github.com/webrtc-rs/dtls but I don't know whether it is already usable.

There are is a e2e test PR that shows it in action, but there seem to be a few structs that are missing. Not sure what is happening there.

@djc
Copy link
Member

djc commented Jun 30, 2021

Folks, it's useful to have a link to that crate here but further discussion about it seems off-topic for this issue.

@freswa
Copy link

freswa commented Oct 26, 2021

@ctz We'd like to sponsor DTLS for rustls including maintenance. @djc would be willing to help us implement it, but first we'd like to coordinate with you which version of DTLS (1.2/1.3) would be accepted for upstream and some implementation details too. How can we get in contact?

@ctz
Copy link
Member

ctz commented Nov 4, 2021

My feeling is that DTLS would need a totally different public API to rustls, to the extent that it doesn't really make sense to have it in the same crate (even as a cargo feature). What I would be open to is refactoring the core crate to allow reuse of the parts common between TLS/DTLS,. What I would never want to see in the core crate is stuff like https://github.com/openssl/openssl/blob/54b40531307fcaba1206e98f4cae73f0532fbdbb/ssl/record/ssl3_buffer.c#L45-L48 -- that would seem to me to be evidence of bad architecture.

As for actually making progress on this, the tlswg continue to alter the design, and I'm not sure writing a DTLS1.2-only implementation is a sensible idea at this point.

The other thing I'm aware of is that DTLS and embedded use cases often come hand-in-hand, so the DTLS crate would likely have to pay more attention to the constraints this brings.

@ShadowJonathan
Copy link
Contributor

While playing around with DTLS, I came to the conclusion that TLS and DTLS are working with two entirely different kinds of streams, and that knowledge about MTU, framing, and other items are important to a consuming DTLS (de)encryptor.

Thus, I concur this has to be a different API/crate, if it means it could consume a std UdpSocket, and correctly abstract it's framed send and recv over it.

@ShadowJonathan
Copy link
Contributor

ShadowJonathan commented Dec 5, 2021

For anyone curious about this development; i'm going to attempt to create an own implementation of this, as per ruma/lb#7, taking https://github.com/pion/dtls and this library as inspiration, at https://github.com/shadowjonathan/dustls

I know i'll be making mistakes, so i'm inviting people who are interested in this to help me out as well.

If there are any rustls maintainers reading this; Collaboration is appreciated, once/if i get the implementation up and close to something usable, i'm offering the repo to be adopted by the rustls org, including crates.io ownership and all.

I'll need recommendations on supported cipher suites, though for now it is a goal to be compatible with at least some of these cipher suites.

I'll initially be executing a rough API design as described here, though obviously it's open for discussion. This is going to be v1.2-only for the moment, providing a base implementation, until v1.3 is finalised, after which i'll take a look and consider how the library's API would have to be changed in order to accommodate it (if that'd be required).

Efforts are going to be here, though with me doing this in my free time, commits are going to be sporadic, help is appreciated.

@Ralith
Copy link
Contributor

Ralith commented Dec 5, 2021

Just off-hand, I'd highly recommend not trying to wrap a UdpSocket, but instead exposing methods to consume/write out datagrams. That will make testing simpler and less fragile, and make the interface more broadly applicable.

@djc
Copy link
Member

djc commented Dec 5, 2021

Agreed with @Ralith, would be nice to mimic the rustls API where possible. I might try reviewing your work as you go, if you want to tag me in PRs or something.

@ShadowJonathan
Copy link
Contributor

ShadowJonathan commented Dec 5, 2021

One of my goals is definitely to be as agnostic as possible to the underlying transport(s), only that they have to receive/send their IO in a framed fashion, and that hints like (P)MTU can be passed through.

would be nice to mimic the rustls API where possible.

From the rough API draft, "DTLSSessionMachine" already looks quite similar to ConnectionCommon, though i'll have to think through and study the rustls api surface before i can commit to what i'm thinking right now, but i'll definitely be trying to match a similar interface.

This was referenced Dec 7, 2021
@ShadowJonathan
Copy link
Contributor

ShadowJonathan commented Dec 10, 2021

@djc @ctz I'd like to collaborate a bit more closely on this (especially with the idea of such a core crate), so i can quickly ask some questions in the future, do y'all have any preferred IM handle i can contact you with? I'd personally prefer matrix: @jboi:jboi.nl, but my twitter DMs are also open as a point-of-contact.

@djc
Copy link
Member

djc commented Dec 10, 2021

Feel free to hit me up on Matrix or Twitter. On Matrix I'm @djc:mozilla.org I think.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests