google / rust-async-coap

A flexible, asynchronous library for using and serving CoAP resources in Rust.
Apache License 2.0
48 stars 17 forks source link

DTLS support query #18

Open fdeantoni opened 4 years ago

fdeantoni commented 4 years ago

First of this project is absolutely amazing. It was really easy to create a server and client. I'm now experimenting to get this to work with DTLS.

In RFC-7252 Section 6 it indicates that a DTLS secured coap requests have a URI of coaps://. I checked the uri module but it seems coaps is not included. Is DTLS support something that is still a work in progress?

I did see in the crate documentation the following:

By implementing datagram::AsyncDatagramSocket, you can use the provided datagram-based back-end with whatever datagram-based network layer you might want, be it UDP, DTLS, or even SMS

If I read this correctly, DTLS support can be added by implementing the async_coap::LocalEndPoint trait. Is this correct?

darconeous commented 4 years ago

First of this project is absolutely amazing. It was really easy to create a server and client.

Thanks!

I'm now experimenting to get this to work with DTLS.

I haven't implemented DTLS support because at the time there was no good support for DTLS in Rust. That may have changed by now, I should look into the matter again.

If I read this correctly, DTLS support can be added by implementing the async_coap::LocalEndPoint trait. Is this correct?

Well... yes. Yes, that is technically true. It's just a "simple" matter of software, as they say. ;)

There are a few details that have yet to be worked out with respect to DTLS: specifically how sessions would work, how you specify the parameters of a new session, etc.

I suppose we could have a default case where we assume the client is anonymous and the server has an X.509 cert that authenticated, but that case isn't super useful for peer devices that just want to authenticate each other mutually with a shared secret—which is an important use case in IoT (especially Splot).

This is an issue that needs to be wrestled with sooner rather than later, so if you have any thoughts, suggestions, I'd love to hear them!

I need to take another look at Rustls to see how TLS/DTLS in general might be integrated.

darconeous commented 4 years ago

One thought was to strictly associate each DTLS session with a RemoteEndpoint instance, and that in the DTLS case it would have some additional trait which would allow you to introspect more into the session details.

But in that case you would really want to avoid using LocalEndpoint::send, because it wouldn't have any session information. I suppose we could add a session identifier to the LocalEndpoint::SocketAddr associated type, but that feels ugly. It also makes session tracking and cleanup much more tricky.

darconeous commented 4 years ago

To be clear though, the most straightforward way to implement DTLS support of the traditional PKI "anonymous-client/authenticated-server" sort is to implement a custom AsyncDatagramSocket and use DatagramLocalEndpoint (rather than implement LocalEndpoint), doing TLS session tracking inside of the "socket". This, of course, has all sorts of caveats and potential issues, but if you want the straightest path from one point to the other, this is likely it.

There may be a way to move such an implementation toward something more flexible later on, but honestly I think it would be a one-off. Perhaps I was being a little optimistic in the README. ;)

fdeantoni commented 4 years ago

Unfortunately DTLS support is not yet implemented in rust-tls (see issue 40), so the only option for now is to use rust-openssl.

Unfortunately I dont have any good ideas about this yet, I'm just experimenting first in setting up a basic coap based client/server implementation. So definitely I was looking at a traditional anonymous client / authenticated server implementation first. I created a basic working example of using openssl dtls here: https://gist.github.com/fdeantoni/a1df96cdd0cc84f79e08a116aa184b71

It is very basic in that it doesn't use async anywhere, but it does show the openssl dtls part working. So hopefully it will also work when using rust-async-coap :)

fdeantoni commented 4 years ago

I created a small experiment project (async-coap-dtls) with rust-openssl to create a dtls server and client using AsyncDatagramSocket. The implementation is far from efficient and there are for sure many things wrong with it, but in a simple scenario it seems to work ok I think.

lqf96 commented 4 years ago

The DTLS 1.3 spec is almost completed... I think we should prioritize this over DTLS 1.2 if we decide to work on this...

darconeous commented 4 years ago

Hopefully the delta between DTLS 1.2 support and DTLS 1.3 support is relatively small.

hubertmis commented 3 years ago

I created patches on top of @fdeantoni project that make server side non-blocking, what enables the user of this library to use DTLS and plain CoAP sockets in the same pool. Most probably I've broken client side meantime, because I was not testing it.

However, if anyone is interested in working non-blocking DTLS server implementation, here it is: https://github.com/hubertmis/async-coap-dtls/tree/test/server-library