-
Notifications
You must be signed in to change notification settings - Fork 6.5k
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
net: sockets: tls: Implement DTLS Connection ID socket option #36738
Conversation
The TLS/DTLS handshake in most cases is a blocking process, therefore the underlying socket should be in a blocking mode to prevent busy looping in the handshake thread. Fix this by clearing the O_NONBLOCK flag on the underlying socket before the handshake, and restoring it afterards. Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
Add Kconfig option for `config-tls-generic.h` to enable DTLS Connection ID extension. Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
Implement TLS_DTLS_CONNECTION_ID socket option, which enables to use Connection ID extension for the DTLS session. The option allows to set the value and the length of the CID to use with `setsockopt()` function. Setting the CID length to 0, enables the extension but does not send the own CID to the peer, as described in the specification. Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
cdf2afc
to
f2078a5
Compare
Some general comments: During the specification process, the way the MAC is calculated has changed with draft-ietf-tls-dtls-connection-id, 09. In order to provide a migration path, a new hello extension id has been emitted for the new MAC, see IANA, Hello-Extensions. With that, 53 for the old MAC for a interim time, 54 with the new MAC. Californium (CoAP/DTLS 1.2 base for Leshan) will be adapted within the next week before the upcoming 3.0.0 release. I will support the old value 53 with the old MAC and the 54 with the new MAC. I guess mbedtls will also adapt. With that: really cool that this PR has been prepared!
Sometimes I'm not sure, how people use UDP. So, in my experience, I open a UDP socket and potentially communicate with a couple of other peers. Assuming "co-located servers", and maybe not aware of that co-location, requires separate UDP-Sockets on the client-side. So, if the CID is passed in, that socket seems to be only useful for one other peer, but not to exchange messages with more peers. |
That's the assumption for the DTLS socket, which this option is intended for. Currently, we allocate a single Anyway, assuming that we might want to implement multiple DLTS session handling on a single socket in the future, perhaps it would indeed be a better idea to specify only CID length by the option, and let the DTLS socket randomize CID before handshake? This should be more future-proof solution, and it seems that Leshan Demo Server for instance already works in this way. You seem to have a great knowledge about this extension, what'd be your recomendation? |
That's not bad, it should just be clear. I'm not sure, how many device will send messages to more than a few server (e.g. LwM2M Bootstrap- and Data-Management-Server) and so the drawback is small. For clients I prefer doing it that way (1 socket 1 peer), otherwise errors resulting from co-located servers may be hard to detect.
Yes, there I have implemented it as callback in Californium.
Recently I was added to the list of authors of that upcoming DTLS connection ID RFC, Version 10 (Achim Kraus). The implementation in Eclipse/Californium (that's what Eclipse/Leshan uses) was developed by me. For the server-side it's mandatory to provide more than one CID, otherwise it will only be able to serve for one client. Using a callback enables also to use CIDs with variable length, if the internal encoding of the CID supports that (outside of the RFC, e.g. 1 byte as length, or in CoAP style, first nibble as length, if 15, length in the next nibble + 15).
I would recommend to try to add a similar callback as Californium, but for that I have to talk with the mbedtls developers. I'm not sure, if that will be successful (and currently I'm too busy with Californium 3.0). Until that, I think using that approach providing a single CID for a client-socket will do it. Please obey, that there is also a case, where the client uses a empty "CID". That means, the client provides to send records to the server using a CID requested by the server, but will not use it receiving records from the server. Either try to support it, or document, that only "none-empty CID" can be used. |
Ok, thank you for the feedback, let's keep it as it is for now then. I'm expecting the PR is going to sit there for a while, so I might change this in the feature if needed.
Actually, this is already supported, I've tried to explain this in the socket option description:
Perhaps it's not clear enough? |
Clearly my bad, I missed to view the PR before writing that. Sorry for that. |
Is it easy/possible to test this PR with a "Thingy91"? Checkout the PR and compile a CoAP/DTLS example for the "Thingy91"? |
It should be possible, but not that easy I'm afraid. First off, the sample should be built within NCS, as vanilla Zepyr does not contain the modem library to handle networking on nRF91. So you'd need to checkout the latest sdk-nrf master branch, and call Next, you need to cherry-pick the commits from this PR into the local Zephyr instance. Finally, the sample would need extra configs to work with nRF91 and offloading (I'm assuming the lwm2m_client from Zephyr tree, connecting to public Leshan):
I'm having some LTE connectivity issues right now, so I cannot confirm 100% it's all that is needed though. And finally, in the sample itself, you need to set the |
Yes, I think, everyone is afraid, that using something fresh developed in a new different context is not that easy :-). Thanks for all the advice and hints. Hope I find some time at the weekend. |
I was able to apply the PR to my setup and it compiles. |
You're right, the NCS LwM2M sample uses DTLS from the modem by default. In order to use DTLS implementation from Zephyr you need to disable TLS offloading with the following option:
Then you need some extra configs to configure mbedTLS (I guess the configuration could be copied from the upstream sample). Additionally, it'd be needed to register DTLS psk/id with |
This pull request has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this pull request will automatically be closed in 14 days. Note, that you can always re-open a closed pull request at any time. |
Two updates: mbedtls - Allow configuring MBEDTLS_TLS_EXT_CID at compile time or mbedtls - 2.x backport: Allow configuring MBEDTLS_TLS_EXT_CID at compile time enables to build mbedtls now without modyfing the sources. And mbedtls-PR - CID update to RFC 9146 is prepared, but not sure, when that could be merged. FMPOV, the deprecated variant with an external compile time switch will currently be best way, at least until |
@boaks Thank you for the news! It's good to hear that the RFC is near completion. It should be pretty straightforward to add Kconfig option which allows to use deprecated CID value. It seems however we'd need to wait for the mbed TLS relase to get configurable CID on the mbed TLS side - we''ve just updated recently to 3.0.0 in Zephyr. |
Yes, I missed that a mbedtls release will be required. |
This pull request has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this pull request will automatically be closed in 14 days. Note, that you can always re-open a closed pull request at any time. |
I'm currently waiting for zephyrproject-rtos/mbedtls#35 (mbed TLS 3.1 update), once we get this in I plan to revive this PR and pull it out of draft. |
The main issue here is mbedTLS. At that point I started November 2020 mbedtls - Please adjust MBEDTLS_TLS_EXT_CID to 53 and since Summer 2021, it's now possible to use 53. However, the draft RFC9146 has undergone a "cryptographic hygiene" cleanup (starting September 2020, with tls - mailing list ) and so the MAC has changed (again) and in order to support time-limited backwards compatibility (time to migrate), also a new IANA code point 54 was assigned. All that is reflected and implemented in the open source project Eclipse/Californium (and so also in Eclipse/Leshan) with the version 3.0.0 last year. For mbedtls it is still on the way, see mbedtls - Update DTLS CID implementation to comply with the "final" draft. and PR 5061. I don't know, when this will be ready. Using the deprecated code point 53 and the deprecated MAC is only recommended for early tests. An alternative, but not at the modem-socket level, is using Eclipse/tinyDtls CID and the modem socket in UDP. I've adapted the nRF9160 UDP sample to use tinyDtls and for me it works quite well. You can run from battery over a (small) couple of weeks, depending on the number of messages you want. RTT from LTE-M PSM is fast, about 1-2s (average, depending on the network provider). I still plan to publish that thingy 91 / tinydtls sampel client, but for now, I'm busy again with Californium. Let me end: |
Just to mention: |
Per zephyrproject-rtos/zephyr#36738. Updated CID value with latest from: https://www.iana.org/assignments/tls-extensiontype-values/ tls-extensiontype-values.xhtml#tls-extensiontype-values-1 Signed-off-by: Pete Skeggs <peter.skeggs@nordicsemi.no>
Per zephyrproject-rtos/zephyr#36738. Updated CID value with latest from: https://www.iana.org/assignments/tls-extensiontype-values/ tls-extensiontype-values.xhtml#tls-extensiontype-values-1 Enable use of SNI without x509. Signed-off-by: Pete Skeggs <peter.skeggs@nordicsemi.no>
Updated CID value with latest from: https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml. Signed-off-by: Pete Skeggs <peter.skeggs@nordicsemi.no>
Per zephyrproject-rtos/zephyr#36738. Updated CID value with latest from: https://www.iana.org/assignments/tls-extensiontype-values/ tls-extensiontype-values.xhtml Signed-off-by: Pete Skeggs <peter.skeggs@nordicsemi.no>
Per zephyrproject-rtos/zephyr#36738. Updated CID value with latest from: https://www.iana.org/assignments/tls-extensiontype-values/ tls-extensiontype-values.xhtml Signed-off-by: Pete Skeggs <peter.skeggs@nordicsemi.no>
Per zephyrproject-rtos/zephyr#36738. Updated CID value with latest from: https://www.iana.org/assignments/tls-extensiontype-values/ tls-extensiontype-values.xhtml ref: NCSDK-15193 Signed-off-by: Pete Skeggs <peter.skeggs@nordicsemi.no> Signed-off-by: Frank Audun Kvamtrø <frank.kvamtro@nordicsemi.no>
Per zephyrproject-rtos/zephyr#36738. Updated CID value with latest from: https://www.iana.org/assignments/tls-extensiontype-values/ tls-extensiontype-values.xhtml ref: NCSDK-15193 Signed-off-by: Pete Skeggs <peter.skeggs@nordicsemi.no> Signed-off-by: Frank Audun Kvamtrø <frank.kvamtro@nordicsemi.no>
This pull request has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this pull request will automatically be closed in 14 days. Note, that you can always re-open a closed pull request at any time. |
zephyrproject-rtos/mbedtls/pull/35 is merged. I tested mbedtls 3.1 against Eclipse/Californium and it works well. Looking forward to see this PR continued. Edited: |
Updated CID value with latest from: https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml. Signed-off-by: Pete Skeggs <peter.skeggs@nordicsemi.no>
Per zephyrproject-rtos/zephyr#36738. Updated CID value with latest from: https://www.iana.org/assignments/tls-extensiontype-values/ tls-extensiontype-values.xhtml ref: NCSDK-15193 Signed-off-by: Pete Skeggs <peter.skeggs@nordicsemi.no> Signed-off-by: Frank Audun Kvamtrø <frank.kvamtro@nordicsemi.no>
Per zephyrproject-rtos/zephyr#36738. Updated CID value with latest from: https://www.iana.org/assignments/tls-extensiontype-values/ tls-extensiontype-values.xhtml ref: NCSDK-15193 Signed-off-by: Pete Skeggs <peter.skeggs@nordicsemi.no> Signed-off-by: Frank Audun Kvamtrø <frank.kvamtro@nordicsemi.no>
Per zephyrproject-rtos/zephyr#36738. Updated CID value with latest from: https://www.iana.org/assignments/tls-extensiontype-values/ tls-extensiontype-values.xhtml ref: NCSDK-15193 Signed-off-by: Pete Skeggs <peter.skeggs@nordicsemi.no> Signed-off-by: Frank Audun Kvamtrø <frank.kvamtro@nordicsemi.no>
This pull request has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this pull request will automatically be closed in 14 days. Note, that you can always re-open a closed pull request at any time. |
Per zephyrproject-rtos/zephyr#36738. Updated CID value with latest from: https://www.iana.org/assignments/tls-extensiontype-values/ tls-extensiontype-values.xhtml ref: NCSDK-15193 Signed-off-by: Pete Skeggs <peter.skeggs@nordicsemi.no> Signed-off-by: Frank Audun Kvamtrø <frank.kvamtro@nordicsemi.no> (cherry picked from commit fcf5f41)
This pull request has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this pull request will automatically be closed in 14 days. Note, that you can always re-open a closed pull request at any time. |
Right now mbtls starts to support RFC 9146. Mbed-TLS/mbedtls#6264 is merged. Maybe the right time to reopen it? |
Per zephyrproject-rtos/zephyr#36738. Updated CID value with latest from: https://www.iana.org/assignments/tls-extensiontype-values/ tls-extensiontype-values.xhtml ref: NCSDK-15193 Signed-off-by: Pete Skeggs <peter.skeggs@nordicsemi.no> Signed-off-by: Frank Audun Kvamtrø <frank.kvamtro@nordicsemi.no> (cherry picked from commit fcf5f41) (cherry picked from commit 6330645)
This PR implements DTLS Connection ID socket option which allows to configure the use of Connection ID extension for DTLS session. Opening the PR early as a RFC, to collect some feedback on the option format.
In the current implementation, it's assumed that the application generates the CID value, and passes it to a socket with
setsockopt()
. An alternative that I've considered was to provide only the CID length with the option, and allowing the secure socket implementation to randomize the CID value before the handshake. I've chosen the former however, as it gives the option more flexibility (for example using a predefined CID value for testing).While the implementation on the Zephyr side can be considered as complete, I've encountered a few issues with mbed TLS itself:
There's a bug in mbed TLS that causes NULL pointer dereference, if some extra configs are not enabled. The issue is already reported in the upstream mbed TLS repository, and fix submitted (see Bugfix: Fix the usage of ssl context after it's nullified Mbed-TLS/mbedtls#3991). As a workaround for the issue, one can enable
CONFIG_MBEDTLS_SSL_EXPORT_KEYS
along withCONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID
to prevent the NULL pointer dereference.Currently, mbed TLS uses an old CID extension identifier, as the value changed between different CID spec drafts. In result, the extension record is not recognized by other parties, like Leshan or Wireshark. Again, a fix for the issue is already posted, still on a PR though (see Allow configuring MBEDTLS_TLS_EXT_CID at compile time Mbed-TLS/mbedtls#4413). As a workaround for the issue, you need to update the MBEDTLS_TLS_EXT_CID value manually for now:
Given the above, I think we shouldn't rush with this PR, and postpone its integration until the aforementioned issues are fixed on the mbed TLS side (and upmerged into Zephyr fork).
With the above workarounds, one can simply enable the CID usage for the DTLS session with a single
setsockopt()
call:or
if we don't want to specify own CID on the Zephyr part. The latter will result in an empty CID record, notifying the PR that the Zephyr part is ready to process the peer's CID, but does not want to use one.
Note, that the PR carries an extra commit, fixing the HS on non-blocking sockets. It's already posted as a separate PR, but I've included it here as it was needed for testing with LwM2M.