Mbed forum

DTLS Role Exchange

mbed_tls

(simon bernard) #1

Hi,

I would like to know if this is possible to make mbedTLS works as a DTLS client and server on the same address/port? (using PSK, RPK and X509)

Maybe this sounds a bit strange and I will give some context to understand.

I’m working on LWM2M protocol which is based on CoAP and DTLS. LWM2M supports PSK, RPK and X509.

I’m currently searching how to handle server failover in “server initiated mode”.

Here is a brief explanation of how it works.

  1. The device has an static/fixed IP address/port.
  2. The device establishes DTLS connection.
  3. The device registers to the server (server has also a static/fixed IP address/port)
  4. Later, server sends request to a registered client.

If the server still have a DTLS connection to the device there is no issue !
Now imagine the DTLS connection is lost (e.g. crash/reboot), we still know the device address (registration is persisted) but we don’t have any DTLS connection to it.

So a solution could be to make the server act as a DTLS client and so the device should act as a DTLS server.

Just to let you know, the java scandium library from californium can act like this.

Here a wireshark capture done with scandium at device(port 36038) and server(port 5684) side. (using PSK)

No.  Time          Source       Destination  SrcPort DesPort Protocol Length Info
   1 0.000000000   127.0.0.1    127.0.0.1    36038   5684    DTLSv1.2 133    Client Hello
   2 0.000359644   127.0.0.1    127.0.0.1    5684    36038   DTLSv1.2 102    Hello Verify Request
   3 0.005001722   127.0.0.1    127.0.0.1    36038   5684    DTLSv1.2 165    Client Hello
   4 0.005626495   127.0.0.1    127.0.0.1    5684    36038   DTLSv1.2 162    Server Hello, Server Hello Done
   5 0.042162424   127.0.0.1    127.0.0.1    36038   5684    DTLSv1.2 147    Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message 
   6 0.061195906   127.0.0.1    127.0.0.1    5684    36038   DTLSv1.2 109    Change Cipher Spec, Encrypted Handshake Message
   7 0.062815631   127.0.0.1    127.0.0.1    36038   5684    DTLSv1.2 179    Application Data (LWM2M REGISTER request from device)
   8 0.081334961   127.0.0.1    127.0.0.1    5684    36038   DTLSv1.2 97     Application Data (LWM2M REGISTER response from server)
   9 8.483287786   127.0.0.1    127.0.0.1    5684    36038   DTLSv1.2 90     Application Data (LWM2M READ request from server)
  10 8.496936449   127.0.0.1    127.0.0.1    36038   5684    DTLSv1.2 213    Application Data (LWM2M READ response from client)
###  LWM2M Server (5684) Reboot and so lost its DTLS connection to LWM2M device (36038), ...
###  ... LWM2M Server will establish a new connection and so act as a DTLS client. 
  11 24.079310967  127.0.0.1    127.0.0.1    5684    36038   DTLSv1.2 151    Client Hello
  12 24.080362291  127.0.0.1    127.0.0.1    36038   5684    DTLSv1.2 102    Hello Verify Request
  13 24.083452354  127.0.0.1    127.0.0.1    5684    36038   DTLSv1.2 183    Client Hello
  14 24.085327257  127.0.0.1    127.0.0.1    36038   5684    DTLSv1.2 162    Server Hello, Server Hello Done
  15 24.110637371  127.0.0.1    127.0.0.1    5684    36038   DTLSv1.2 147    Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message 
  16 24.111419901  127.0.0.1    127.0.0.1    36038   5684    DTLSv1.2 109    Change Cipher Spec, Encrypted Handshake Message 
  17 24.113519322  127.0.0.1    127.0.0.1    5684    36038   DTLSv1.2 92     Application Data (LWM2M READ request from server)
  18 24.114368265  127.0.0.1    127.0.0.1    36038   5684    DTLSv1.2 108    Application Data (LWM2M READ response from client)

(Ron Eldor) #2

Hi @sbernard
Thank you for your interest in Mbed TLS!
If your intention is to have the same object act both as a client and as a server, this is not supported in mbed TLS, unfortunately.
As you can see, when you configure your peer, you set it as either MBEDTLES_IS_CLIENT or MBEDTLS_IS_SERVER, but not both.
Have you considered using session resumption? I believe this should handle your use case.
Regards,
Mbed TLS team member
Ron


(simon bernard) #3

Hi @roneld01,

Have you considered using session resumption?

Unfortunately, this will not handle my use case. As explained above, the server lost the connection and it want to initiate a new connection. In that case there is no way to use session resumption… :confused:

If your intention is to have the same object act both as a client and as a server, this is not supported in mbed TLS, unfortunately.

I currently searching if this kind of behavior make sense and also if it is frequently supported.
For now, I know that scandium (java) support it and I currently experiment tinyDTLS © which seems to be able to do that too. (at least not so far)

Could we imagine that Mbed TLS supports this one day ? Does it imply massive changes in MbedTLS ?

Thx again.


(Ron Eldor) #4

Hi @sbernard

Unfortunately, this will not handle my use case. As explained above, the server lost the connection and it want to initiate a new connection. In that case there is no way to use session resumption… :confused:

Right, in your case, you want the server to initiate the reconnection
This isn’t really part of the DTLS protocool. Is this some proprietary protocol? Do you control both peers? If so, have you considered having your own protocol on top of DTLS, that the server will send to the client a “reconnect message” , and then the client we renegotite a handshake?

Could we imagine that Mbed TLS supports this one day ? Does it imply massive changes in MbedTLS ?

I cna’t say at the moment, we will need to think about it, but it will require not a few changes to support this.
Have you considered having in your server two tls contexts? One for acting as server and one for acting as client? This means though, that you will have two separate DTLS sessions , which is probably not what you want. Perhaps, both the device and server can act as server and client?
Regards


(simon bernard) #5

This isn’t really part of the DTLS protocool.

Maybe, I’m wrong but I see nothing in the TLS/DTLS RFC which really forbid it, but I can understand that this is a bit off the beaten track. (I maybe missed something too)

(I’m not expert, but I can imagine some peer to peer application where this could make sense to act as both client and server)

Is this some proprietary protocol?

No, it isn’t. LWM2M is standard hosted by the open mobile alliance(OMA).

Do you control both peers?

I am one of the main developer of Leshan : an open source implementation of LWM2M in java.
So this is not really the spirit. The LWM2M specification define some use cases and as developer I try to make the specification works in real world. LWM2M is young and sometime everything is not really well thought.
So currently to solve the issue I raised above, I can not see another solution than having both DTLS peer which act as client/server role. I ask this at OMA to have their opinion but for now this is “radio silence”.

So I’m experimenting this idea and sounding out DTLS developers.
I try to understand if this idea make sense and if this is doable.

As I said, I succeed to make it works with scandium which are used at client and server side for Leshan (java).
But the idea is to have an interoperable solution, so I target some popular DTLS C implementation for IoT.

So I tried with tinyDTLS and I finally succeed to make it works with it. And I try to see with you if this could make sense. :smiley:

If so, have you considered having your own protocol on top of DTLS, that the server will send to the client a “reconnect message” , and then the client we renegotite a handshake?

Clearly out of the LWM2M specification… :confused:

I cna’t say at the moment, we will need to think about it, but it will require not a few changes to support this.

I would be happy to have your opinion about the relevance of all of this. Let me know if you plan to support it. I could also share my java command line tool to help you to check this kind of use case.

Have you considered having in your server two tls contexts? One for acting as server and one for acting as client? This means though, that you will have two separate DTLS sessions , which is probably not what you want.

Clearly out of the LWM2M specification too :confused:

Perhaps, both the device and server can act as server and client?

That’s exactly the idea having 2 peers which use only one address/IP port and could act both as DTLS server and client. (exactly as I show in the wireshark capture of my first post)


(Ron Eldor) #6

@sbernard Thanks for the clarification.

Maybe, I’m wrong but I see nothing in the TLS/DTLS RFC which really forbid it, but I can understand that this is a bit off the beaten track. (I maybe missed something too)

Perhaps the DTLS standard doesn’t specify this specifically, but in practice, a device cannot act as a client and a server at the same time.

However, since the connection was disconnected, what blocks you from terminating your ssl context, and reinitiating it as a client? This is possible in Mbed TLS
You can configure your device to be both client and server, but not simultaneously.
Regards


(simon bernard) #7

Perhaps the DTLS standard doesn’t specify this specifically, but in practice, a device cannot act as a client and a server at the same time.

I don’t know exactly what you mean about “a device cannot act being client and server at the same time”.

But if you are talking at what I described above, In practice this works with some existing implementation.

For example, http://tinydtls.sourceforge.net/group__dtls__usage.html says that :

"A DTLS client is constructed like a server but needs to actively setup a new session by calling dtls_connect() at some point. "

And this is exactly this idea. Once the DTLS connection is established, the DTLS client will act as a Server, meaning that if it receive a CLIENT_HELLO it is able to handle it, by sending an HELLO_VERIFY_REQUEST and once cookie is validate, it will continue the handshake like any other DTLS server.


(Ron Eldor) #8

Hi @sbernard

"A DTLS client is constructed like a server but needs to actively setup a new session by calling dtls_connect() at some point. "

this is exactly what I meant that the device cannot act as a client and a server at the same time. You need to actively set up a new connection, which means that you actually act as a client.
This is also what I meant in my last comment:

what blocks you from terminating your ssl context, and reinitiating it as a client? This is possible in Mbed TLS

in Mbed TLS, once connectoin terminates, you can initialize your ssl context in your device as a client, and behave as a client, in the TLS layer.
Regards