openwsn-berkeley / py-edhoc

Python implementation of EDHOC
BSD 3-Clause "New" or "Revised" License
5 stars 6 forks source link

Processing API: Accept messages #11

Open chrysn opened 3 years ago

chrysn commented 3 years ago

Functions like finish and create_message_two currently take messages as bytes.

Typical usage is that the application needs to decode the message beforehand anyway -- in the m1 case to pick out method, correlation and supported suites (to pick suitable own credentials), and in the m3 case to get the c_r to find the right responder.

Given that, I suggest these should take the decoded message instead. (For compatibility or the cases where things are hardcoded, there may stay an option to pass in bytes too, but for consistency it's probably better to always make the application do the decoding).

(This is a bit of a note-to-self as I don't want to rewrite the API while I have other things in the air; can provide a PR for this at a later stage).

TimothyClaeys commented 3 years ago

Hi @chrysn, so far I've neglected the case where there could be multiple exchanges going on at the same time. This is why I took in the received message as bytes and decoded everything inside the API calls (create_message_two, create_message_three, ...). Just to be clear are you suggesting something like this:

  1. application decodes CBOR sequence and extracts connection identifier (if applicable) and authentication method (for message 1)
  2. It passes to the EDHOC engine:
    • an EDHOC processing context (which it has fetched with the connection identifier or other connection identifying information such as the CoAP token or five tuple)
    • the decoded CBOR sequence (for example as a list of decoded CBOR elements)
    • and the credentials it has selected (based on authentication method in message 1)
chrysn commented 3 years ago

Not exactly,

  1. application decodes CBOR sequence and extracts connection identifier (if applicable) and authentication method (for message 1)
  1. application turns data into the appropriate message (eg.
m1 = messages.MessageOne.decode(request.payload))

With the initial null addition, there may become a helper function to decide whether it's m1 or m3, or it looks at the stream on its own, or MessageOne.decode becomes particularly fallible.

Somewhere inbetween it picks a few pieces out of message 1 (method, supported algorithms; also factoring in data like the Uri-Host in the CoAP case), and picks an C_R to assign (based on multiple considerations, one of them being which exchanges are active, another being which OSCORE IDs are currently being used).

  1. It passes to the EDHOC engine:
  1. it passes that message to the engine:
- msg_2 = resp.create_message_two(request.payload)
+ msg_2 = resp.create_message_two(m1)

I'd try to keep the details of which responders are around out of the library, there are too many considerations in there (see above). Then it only becomes a matter of feeding messages to the one created object.