From 5f6d47844a65425ff75d02733b75d262871a48d0 Mon Sep 17 00:00:00 2001 From: Brian Sipos Date: Wed, 17 Dec 2025 12:04:53 -0500 Subject: [PATCH] Convert and check for non-registered labels crit header parameter --- pycose/headers.py | 13 ++++++++++++- tests/test_attributes.py | 9 +++++---- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/pycose/headers.py b/pycose/headers.py index 692742b..0df6583 100644 --- a/pycose/headers.py +++ b/pycose/headers.py @@ -2,6 +2,7 @@ from typing import Any from pycose.utils import _CoseAttribute +from pycose.exceptions import CoseException class CoseHeaderAttribute(_CoseAttribute, ABC): @@ -179,7 +180,17 @@ def crit_is_array(value: Any): if not isinstance(value, list) or len(value) < 1 or not all(isinstance(x, (int, str)) for x in value): raise ValueError("CRITICAL should be a list with at least one integer or string element") - return value + translated_list = [] + non_registered = set() + for label in value: + try: + translated_list.append(CoseHeaderAttribute.from_id(label)) + except CoseException: + non_registered.add(label) + if non_registered: + raise ValueError(f"CRITICAL references unregistered header labels: {non_registered}") + + return translated_list def content_type_is_uint_or_tstr(value: Any): diff --git a/tests/test_attributes.py b/tests/test_attributes.py index 8f4a941..e2292e6 100644 --- a/tests/test_attributes.py +++ b/tests/test_attributes.py @@ -119,16 +119,16 @@ def test_cose_header_attribute_value_encoding(): assert decoded_msg.phdr[Algorithm] == AESCCM1664128 # critical - msg = Enc0Message(phdr={Algorithm: AESCCM1664128, "A": 42, Critical: [1, "A"]}, + msg = Enc0Message(phdr={Algorithm: AESCCM1664128, "A": 42, Critical: [1]}, uhdr={IV: urandom(13)}, payload=b'this is the payload', key=SymmetricKey.generate_key(16)) msg = msg.encode() - assert b"\x82\x01\x61\x41" in msg + assert b"\x02\x81\x01" in msg decoded_msg = Enc0Message.decode(msg) - assert decoded_msg.phdr[Critical] == [1, "A"] + assert decoded_msg.phdr[Critical] == [Algorithm] # content type as uint msg = Enc0Message(phdr={Algorithm: AESCCM1664128}, @@ -272,6 +272,7 @@ def test_allow_unknown_header_attribute_encoding_decoding(): assert "Custom-Header-Attr1" in msg_decoded.phdr assert "Custom-Header-Attr2" in msg_decoded.uhdr + def test_no_reencoding_of_protected_header(): # The following protected header encodes {Alg: Es256, "foo": 1}, however, # it is crafted such that it would not be emitted by cbor2. @@ -284,5 +285,5 @@ def test_no_reencoding_of_protected_header(): msg = msg.encode() msg_decoded = Sign1Message.decode(msg) - + assert msg_decoded.phdr_encoded == phdr_encoded