On Thursday, 26 October 2017 06:03:41 PDT Carsten Bormann wrote:
> On Oct 26, 2017, at 03:40, Thiago Macieira <[email protected]>
wrote:
> > Also note that COSE requires that the protected maps also conform to the
> > canonical format (RFC 7049 section 3.9), but our map doesn't.
>
> Actually, COSE doesn’t require that.
You're right, that's not the protected map exactly that requires it, but
effectively by construction you'd do that.
> The fact that we didn’t want to require canonicalization of the map is the
> exact reason we use cbor-in-cbor: The sender can encode in any way you
> want, but the resulting exact byte string becomes part of the signed
> message.
Then you forgot to remove the wording for that.
RFC 8159 section 14 "CBOR Encoder Restrictions" says
o The restriction applies to the encoding of the Sig_structure, the
Enc_structure, and the MAC_structure.
o The rules for "Canonical CBOR" (Section 3.9 of RFC 7049) MUST be
used in these locations. [...]
Because the same protected map appears in both these three structures and in
the actual payload, any implementation that is attempting to save memory will
just copy from one point to the other. So, as I said, effectively this makes
the pmap canonical.
In any case, this CBOR-in-CBOR makes it extremely hard to make an
implementation that streams out the content, without memory allocation and
with as much zero-copy as it can. To do it, you need to either:
1) save the pmap to a scratch buffer, then memcpy it twice
2) backtrack in the streaming: that is, first encode a Byte String information
for a MUCH bigger entity since you don't know the size, then encode the
protected map, calculate the size of that map, backtrack to where you encoded
the long byte string and patch it with the actual size. And then memcpy it to
the {Enc,Sig,MAC}_Structure, since it needs to be canonical.
3) [the solution I chose] break down the {Enc,Sig,MAC}_Structures so that
instead of sending a linear buffer, the encoding/signing/verifying function
gets a struct iovec array. That way, we can create the structures in canonical
form without memcpy. Then we encode the pmap only once as a Byte String to the
payload.
In my mind, that choice is a design flaw in COSE.
--
Thiago Macieira - thiago.macieira (AT) intel.com
Software Architect - Intel Open Source Technology Center
_______________________________________________
iotivity-dev mailing list
[email protected]
https://lists.iotivity.org/mailman/listinfo/iotivity-dev