-
Notifications
You must be signed in to change notification settings - Fork 2k
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/sock_dtls: add public key verification #20048
net/sock_dtls: add public key verification #20048
Conversation
I'm wondering whether this feature should actually be opt-out instead. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some nits. Manually and successfully tested on native.
I found the code in the example to be confusing due to naming of the key variables and lack of comments. If you want to go the extra mile and and a bit of ✨ that would be neat but totally optional for this PR.
I gave it a try. It's still not perfect, but I think much clearer. I tried clearly splitting both sets of credentials. A bonus: now the client can actively use the PSK hint to decide on the key to use. |
} | ||
if (IS_ACTIVE(CONFIG_DTLS_PSK)) { | ||
/* make the new credential available to the sock */ | ||
if (sock_dtls_add_credential(&dtls_sock, SOCK_DTLS_CLIENT_TAG_1) < 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was always very confused about what's the idea behind credman.
Shouldn't a credential be associated with a host? So what does it mean to add multiple credentials to a socket?
At first I thought it would do the host <-> credential mapping, but that's not the case.
So what's the advantage of the credential IDs ('tags') as opposed to just passing pointers?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was always very confused about what's the idea behind credman.
Yeah, I know what you mean...
Shouldn't a credential be associated with a host? So what does it mean to add multiple credentials to a socket?
Not necessarily. I mean, you can already see the example of the server with more than one pair of keys. IMO one of the greatest problems of this module is that a credential is a single "private key" and 0 or more "client keys". Like I commented in the example, the way it currently works looks more like a keyring of client keys and your own.
So what's the advantage of the credential IDs ('tags') as opposed to just passing pointers?
In key management using tags is not uncommon, this is crucial for instance when integrating secure elements or other backends where the key is directly not reachable, but a tag is passed to the crypto backend. I'm not sure why this was the case for credman, as it clearly doesn't support any other backend than a buffer in memory.
IMO we are in need of a rethinking of the credentials management in RIOT. We would really benefit from:
- not only DTLS credentials (of course)
- possibility of multiple backends including secure elements
- more types of credentials
- ability to indicate scope and capabilities of the credentials
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @Einhornhool! Take a look at this comment please 🐅
(Also, maybe this comment should be an issue instead?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm most of the points in Leandros credentials requirement list could be handled by the PSA Crypto key management. It might be worth looking into patching tinydtls to use PSA for crypto operations and credential storage, instead of implementing the same features twice.
This needs a rebase |
30a9e0e
to
01b6e77
Compare
Rebased. I also modified a bit the example: the server only stores one client public key, but has two key pairs. It allows the user to select which one to use on the handshake. As the client knows both public keys form the server, any will work. I think this showcases a bit better the usage of the callbacks and multiple credentials. I also updated the docs including this and the new command. |
This is great! Way easier to understand! |
01b6e77
to
a57bdb7
Compare
Fixed and squashed! |
|
||
res = sock_dtls_establish_session(&udp_sock, &dtls_sock, &session, tag, | ||
&local, &remote, buf, sizeof(buf)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why move away from the sock_dtls_establish_session()
helper and open-code the handshake again?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because it doesn't allow me to register the extra credentials before initiating the handshake.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same with the callbacks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tbh I didn't quite understand the requirement when adding that helper, so if you think the API can be improved that would be great - leaving the handshake to the user seemed like a bad example.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm I don't feel like this example is bad. It's not overly complicated or lengthy, the reader should get along well.
While a single helper function is nice and clean, it is clear the existing one is insufficient for this particular task. Adjusting that helper would mess with an API that is out of scope for this PR.
- Can we resolve this comment on these terms?
- Do you think the API needs a rework? If so, we should open an issue for that.
- Makes me wonder, should we integrate credman closer with dtls?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, this shouldn't block this PR, I just took the opportunity to try to get some open questions about credman / DTLS answered 😅
I'd very much welcome an overhaul of credman as it seems still a bit unclear what it actually is and what's it's purpose.
Maybe it would also fit into PSA crypto?
a57bdb7
to
4321cf1
Compare
/** | ||
* @brief The identity hint of the PSK 0 | ||
*/ | ||
#define CLIENT_PSK_IDENTITY_0_HINT "Prefer_Id_0" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would the hint be something like a hostname / node ID or serial number?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is actually application-specific (https://datatracker.ietf.org/doc/html/rfc4279#section-5.2), so the content is not really restricted as long as it can be understood by the peer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, but since this is an example I think some comment of what this would be in a real-world use case would be valuable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
something like a hostname / node ID or serial number
This would somehow imply that the key is only to be used with a single client, this is not necessarily the case. Searching for examples I found this summary: https://stackoverflow.com/a/8753393/5633371 seems that many implementations send encoded information on how to derive the keys.
I think this hint is fine for the didactic purpose of the example: It's easily readable in code and when sniffing the handshake, and it describes its intention.
4321cf1
to
c424a76
Compare
Ping? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the ping.
@Teufelchen1 I see you approved this, any reason not to press the merge button?
082638b
to
9b18399
Compare
9b18399
to
6d9a9a3
Compare
Thanks for the review! |
Contribution description
This adds a pseudomodule to enable public key verification of peers. When
sock_dtls_verify_public_key
is enabled the public key sent by the peer is checked against the registered keys on the corresponding sock. The implementation for tinydtls is added, as well as the corresponding changes to use it on thedtls-sock
example.Testing procedure
Run
examples/dtls-sock
with ECC enabled, the public key should be verified. You can try removing the server's public key from the client, the connection should be aborted.Issues/PRs references
Loosely related to #19838