EDHOC in aiocoap¶
Introducing EDHOC¶
EDHOC (RFC9528) is a key establishment protocol that shares many desirable properties of OSCORE: It can use any CoAP transport (as well as HTTP), and can traverse and benefit from proxies without granting them access to the communication.
Using EDHOC in aiocoap¶
EDHOC credentials can be stored in the same JSON/CBOR/EDN based credentials files used with OSCORE and (D)TLS.
For a client, a single entry describes both the client-side and the server-side credentials, as well as the URI(s) for which to use them. For a server, the presented credential for any requested origin (URI excluding the path, as that is the information available during EDHOC) is stored in one record, and one record per client lists and labels the known peers.
EDHOC example¶
This example sets up encrypted access to the file server demo from the generic command line client.
On the server side, generate a key for the server:
$ aiocoap-keygen generate fileserver.cosekey --kid 0a --subject "s"
{14: {2: "s", 8: {1: {1: 2, 2: h'0a', -1: 1, -2: ..., -3: ...}}}}
Note
The KIDs and subject length limitations that make all those be single-byte are subject to ongoing development in aiocoap and lakers.
The output of this is a public key, which goes into the credential file you create next as fileserver.cred.diag
:
{
"coap://[::1]/*": { # replace with own pubic address
"edhoc-oscore": { # or leave for local testing
"suite": 2,
"method": 3,
"own_cred_style": "by-key-id",
"own_cred": ..., # replace dots with the {14:...}
# from before
"private_key_file": "fileserver.cosekey",
}
},
}
Now over to the client:
$ aiocoap-keygen generate client.cosekey --kid 01 --subject "c"
{14: {2: "c", 8: {1: {1: 2, 2: h'01', -1: 1, -2: ..., -3: ...}}}}
Likewise, create a credential file we call client.cred.diag
:
{
"coap://[::1]/*": {
"edhoc-oscore": {
"suite": 2,
"method": 3,
"own_cred_style": "by-key-id",
"own_cred": ..., # replace dots with the {14:...}
# from before
"private_key_file": "client.cosekey",
"peer_cred": ..., # replace with {...} from server
}
},
}
Finally, we have to extend the server’s fileserver.cred.diag
to accept this client –
we extend the last two lines to:
},
":ourclient": { "edhoc-oscore": {
"suite": 2,
"method": 3,
"peer_cred": ..., # replace dots with own_cred from client
}}
}
Finally we can start the fileserver:
$ ./aiocoap-fileserver --credentials fileserver.cred.diag
… and exchange data with EDHOC and OSCORE initiated by the client:
$ aiocoap-client "coap://[::1]/" --credentials client.cred.diag
# application/link-format content was re-formatted
</.git/>; ct=40,
</aiocoap/>; ct=40,
[...]
Warning
This is a rudimentary setup that is just enough to show how things work. This does not yet perform any authorization control: the file server will still let any unauthenticated client perform the same operations as the newly authenticated client.
Note
As EDHOC support is extended, the steps described here should be vastly simplified:
The credentials file format needs an overhaul: entering peers should become as easy as creating entries in an
.ssh/authorized_keys
file.Generating local identities should be more streamlined, with less copy-pasting involved.
The necessity of having a kid and a subject in keys for everything to work in the first place is subject to ongoing discussion.
unilateral authentication is supported by setting the peer’s credentials to {“unauthenticated”: true} – but that needs some more explaining as to the security consequences.