Carsten,
As an arbitrary sample point, the pycose library (which I consider to be quite 
full-featured) does account for an optional "payload" (the generic data content 
of any layer) in its base class `CoseMessage` [1] but the logic within the 
derived class `CoseRecipient` [2] appears to not properly deal with the 
possibility of a null ciphertext (the "payload" of the recipient class). So 
this may actually be a bug report against pycose if one of those examples is 
converted to use null instead of empty-bstr ciphertext and fed in as a test 
case.

The cbor2 library is used underneath for encoding/decoding, which will handle 
null vs empty cases properly but the pycose logic will need to properly handle 
if/when null values are allowed by the logical COSE data model (both when 
decoding and processing messages and when creating and encoding them).

[1] 
https://github.com/TimothyClaeys/pycose/blob/master/pycose/messages/cosemessage.py#L87
[2] 
https://github.com/TimothyClaeys/pycose/blob/master/pycose/messages/recipient.py#L196

> -----Original Message-----
> From: Carsten Bormann <[email protected]>
> Sent: Tuesday, July 14, 2026 9:14 AM
> To: Sipos, Brian J. <[email protected]>
> Cc: [email protected]
> Subject: Re: [COSE] [EXT] Re: RFC 9052 clarification on recipient ciphertext
> 
> APL external email warning: Verify sender [email protected] before clicking links
> or attachments
> 
> On 2026-07-14, at 14:46, Sipos, Brian J. <[email protected]> wrote:
> >
> > The root of the problem is the question “is the decoder-processor
> supposed to treat null value any differently?
> 
> For those interested in the history, here is what Jim Schaad said in
> <http://mailarchive.ietf.org/arch/msg/cose/vfJ6mfHXq7bu6fw_sLD7f6XSiks>
> about a similar case:
> 
> >> "For body_protected and sign_protected, if the fields are not present
> >> in their corresponding maps, an bstr of length zero should be used."
> >>
> >> Should? The encoding of this is interop-critical. Also, why not use
> >> NULL for absent field here?
> >
> > This is a lower case should and does have the same 2119 language meaning
> (see the text in 1.1 about natural language).  However 'is' will work just as
> well.
> >
> > I could just as easily use NULL, but there is no size or conception 
> > difference.
> The change from NULL to an empty bstr came about from the idea at one
> point during using arrays that it might be easier to do the parsing if the 
> empty
> binary string was used instead.  It might also make checking of types easier.
> This change got copied down into the structure to be signed as it made the
> code easier (just copy the item).  As I said, I am not wedded to either way.
> 
> I don’t know how that discussion continued, but it shows that Jim viewed null
> and the empty byte string in that case as interchangeable and the choice to
> be subject to minutiae such as ease of parsing.
> Now in that case, a choice was apparently made:
> 
>    empty_or_serialized_map = bstr .cbor header_map / bstr .size 0
> 
> Maybe the discrepancy in the case here, ciphertext (text explicitly says “nil"
> [null] and examples show empty byte string) is an incompletely executed
> change, or maybe the examples are just showing an incorrect transfer of the
> …_protected decision to ciphertext.
> 
> At this point, I’d like to hear from more implementers…
> 
> Grüße, Carsten
> 

Attachment: smime.p7s
Description: S/MIME cryptographic signature

_______________________________________________
COSE mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to