Esempio n. 1
0
def default_encoder(encoder, value):
    if isinstance(value, dt.timedelta):
        encoder.encode(
            cbor2.CBORTag(2001, (
                value.days, value.seconds, value.microseconds)))
    elif value is NoData:
        encoder.encode(cbor2.CBORTag(2002, None))
    else:
        raise cbor2.CBOREncodeError(
            'cannot serialize type %s' % value.__class__.__name__)
Esempio n. 2
0
    def encode(self,
               key: SymmetricKey,
               alg: Optional[CoseAlgorithms] = None,
               mac_params: Optional[List[RcptParams]] = None,
               tagged: bool = True,
               mac: bool = True) -> bytes:
        """ Encodes and protects the COSE_Mac message. """

        # encode/encrypt the base fields
        if mac:
            message = [self.encode_phdr(), self.encode_uhdr(), self.payload, self.compute_tag(alg=alg, key=key)]
        else:
            message = [self.encode_phdr(), self.encode_uhdr(), self.payload]

        if mac_params is None:
            mac_params = []

        if len(self.recipients) == len(mac_params):
            if len(mac_params) > 0:
                message.append(CoseRecipient.recursive_encode(self.recipients, mac_params))
        else:
            raise ValueError("List with cryptographic parameters should have the same length as the recipient list.")

        if tagged:
            message = cbor2.dumps(cbor2.CBORTag(self.cbor_tag, message))
        else:
            message = cbor2.dumps(message)

        return message
Esempio n. 3
0
    def encode(self,
               sign_params: Optional[List[SignerParams]] = None,
               tagged: bool = True) -> bytes:
        """ Encodes and protects the COSE_Sign message."""

        signers = []
        message = [self.encode_phdr(), self.encode_uhdr(), self.payload]

        if sign_params is None:
            sign_params = []

        if len(sign_params) == len(self.signers):
            for signer, p in zip(self.signers, sign_params):
                signers.append(signer.encode(p))
        else:
            raise ValueError(
                "List with cryptographic parameters should have the same length as the recipient list."
            )

        message.append(signers)

        if tagged:
            message = cbor2.dumps(cbor2.CBORTag(self.cbor_tag, message))
        else:
            message = cbor2.dumps(message)

        return message
Esempio n. 4
0
    def encode(self,
               private_key: Union[EC2, OKP],
               alg: Optional['CoseAlgorithms'] = None,
               curve: Optional['CoseEllipticCurves'] = None,
               tagged: bool = True,
               sign: bool = True) -> bytes:
        """ Encodes the message into a CBOR array with or without a CBOR tag. """

        if sign:
            message = [
                self.encode_phdr(),
                self.encode_uhdr(), self.payload,
                self.compute_signature(alg=alg,
                                       private_key=private_key,
                                       curve=curve)
            ]
        else:
            message = [self.encode_phdr(), self.encode_uhdr(), self.payload]

        if tagged:
            res = cbor2.dumps(cbor2.CBORTag(self.cbor_tag, message),
                              default=self._special_cbor_encoder)
        else:
            res = cbor2.dumps(message, default=self._special_cbor_encoder)

        return res
Esempio n. 5
0
    def encode(self, message: list, tag: bool = True, *args, **kwargs) -> CBOR:
        if tag:
            message = cbor2.dumps(cbor2.CBORTag(self.cbor_tag, message),
                                  default=self._custom_cbor_encoder)
        else:
            message = cbor2.dumps(message, default=self._custom_cbor_encoder)

        return message
Esempio n. 6
0
def default_encoder(encoder, obj):
    if not isinstance(obj, (Company, Employee)):
        raise Exception('cannot serialize type %s' % obj.__class__)

    serialized_state = encoder.encode_to_bytes(obj.__dict__)
    wrapped_state = [obj.__class__.__name__, serialized_state]
    with encoder.disable_value_sharing():
        encoder.encode(cbor2.CBORTag(CBOR_TAGNUM, wrapped_state))
Esempio n. 7
0
def binaryCborTag(value):
    ''' Encode CBOR as bytestring and tag the item.

    :param value: The CBOR item to encode.
    :return: The binary-enveloped item.
    '''
    # Tag 24: Encoded CBOR data item
    return cbor2.CBORTag(24, cbor2.dumps(value))
Esempio n. 8
0
def test_decoding_unknown_type():
    ctx = Context()
    pull = ctx.socket(PULL)
    push = ctx.socket(PUSH)
    pull.bind('inproc://foo')
    push.connect('inproc://foo')
    push.send(cbor2.dumps(cbor2.CBORTag(4000, None)))
    with pytest.raises(IOError):
        pull.recv_msg()
    push.close()
    pull.close()
Esempio n. 9
0
    def encode(self, tag: bool = True, sign: bool = True, *args, **kwargs) -> CBOR:
        """ Encodes the message into a CBOR array with or without a CBOR tag. """

        if sign:
            message = [self.phdr_encoded, self.uhdr_encoded, self.payload, self.compute_signature()]
        else:
            message = [self.phdr_encoded, self.uhdr_encoded, self.payload]

        if tag:
            res = cbor2.dumps(cbor2.CBORTag(self.cbor_tag, message), default=self._custom_cbor_encoder)
        else:
            res = cbor2.dumps(message, default=self._custom_cbor_encoder)

        return res
Esempio n. 10
0
 def test_cbor_pen(self):
     data = bytes.fromhex(p_test_vectors14[1].read_text().replace("\n", ""))
     struct = loads(data)
     struct2 = loads(struct.value[3])  # manifest
     struct3 = loads(struct2[3])  # common sequence
     struct4 = loads(struct3[4])  # override params
     self.assertEqual(struct4[0], 20)
     self.assertTrue(isinstance(struct4[1][1], bytes))
     struct4[1][1] = cbor2.CBORTag(
         112, struct4[1][1])  # Add the tag for cbor-pen
     struct3[4] = dumps(struct4)
     struct2[3] = dumps(struct3)
     struct.value[3] = dumps(struct2)
     data = dumps(struct)
     self.decode_string(data, p_manifest14, p_cose)
Esempio n. 11
0
 def test_map_bstr(self):
     args = [
         "zcbor", "--cddl",
         str(p_map_bstr_cddl), "convert", "--input",
         str(p_map_bstr_yaml), "-t", "map", "--output", "-"
     ]
     call1 = Popen(args, stdout=PIPE)
     stdout1, _ = call1.communicate()
     self.assertEqual(0, call1.returncode)
     self.assertEqual(
         dumps({
             "test": bytes.fromhex("1234abcd"),
             "test2": cbor2.CBORTag(1234, bytes.fromhex("1a2b3c4d")),
             ("test3", ): dumps(1234)
         }), stdout1)
Esempio n. 12
0
    def cbor_tag_encoder(self, encoder: cbor2.CBOREncoder, obj):
        try:
            typename, marshaller, wrap_state = self.serializer.marshallers[obj.__class__]
        except KeyError:
            raise LookupError('no marshaller found for type "{}"'
                              .format(qualified_name(type(obj)))) from None

        marshalled_state = marshaller(obj)
        if wrap_state:
            serialized_state = encoder.encode_to_bytes(marshalled_state)
            wrapped_state = [typename, serialized_state]
            with encoder.disable_value_sharing():
                encoder.encode(cbor2.CBORTag(self.type_tag, wrapped_state))
        else:
            encoder.encode(marshalled_state)
Esempio n. 13
0
    def encode(self, tag: bool = True, *args, **kwargs) -> bytes:
        """ Encodes and protects the COSE_Sign message. """

        message = [self.phdr_encoded, self.uhdr_encoded, self.payload]

        if len(self.signers):
            message.append([s.encode() for s in self.signers])

        if tag:
            message = cbor2.dumps(cbor2.CBORTag(self.cbor_tag, message),
                                  default=self._custom_cbor_encoder)
        else:
            message = cbor2.dumps(message, default=self._custom_cbor_encoder)

        return message
Esempio n. 14
0
    def encode(self,
               key: SymmetricKey,
               alg: Optional[CoseAlgorithms] = None,
               tagged: bool = True,
               mac: bool = True) -> bytes:
        """ Encode and protect the COSE_Mac0 message. """

        if mac:
            message = [self.encode_phdr(), self.encode_uhdr(), self.payload, self.compute_tag(alg=alg, key=key)]
        else:
            message = [self.encode_phdr(), self.encode_uhdr(), self.payload]

        if tagged:
            res = cbor2.dumps(cbor2.CBORTag(self.cbor_tag, message), default=self._special_cbor_encoder)
        else:
            res = cbor2.dumps(message, default=self._special_cbor_encoder)

        return res
Esempio n. 15
0
    def encode(self,
               nonce: bytes,
               key: SymmetricKey,
               alg: Optional[CoseAlgorithms] = None,
               enc_params: Optional[List[RcptParams]] = None,
               tagged: bool = True,
               encrypt: bool = True) -> bytes:
        """ Encodes and protects the COSE_Encrypt message """

        # encode/encrypt the base fields
        if encrypt:
            message = [
                self.encode_phdr(),
                self.encode_uhdr(),
                self.encrypt(nonce=nonce, key=key, alg=alg)
            ]
        else:
            message = [self.encode_phdr(), self.encode_uhdr(), self.payload]

        if enc_params is None:
            enc_params = []

        if len(self.recipients) == len(enc_params):
            if len(enc_params) > 0:
                message.append(
                    CoseRecipient.recursive_encode(self.recipients,
                                                   enc_params))
        else:
            raise ValueError(
                "List with cryptographic parameters should have the same length as the recipient list."
            )

        if tagged:
            message = cbor2.dumps(cbor2.CBORTag(self.cbor_tag, message),
                                  default=self._special_cbor_encoder)
        else:
            message = cbor2.dumps(message, default=self._special_cbor_encoder)

        return message
Esempio n. 16
0
    def encode(self,
               nonce: bytes,
               key: SymmetricKey,
               alg: Optional[CoseAlgorithms] = None,
               tagged: bool = True,
               encrypt: bool = True) -> bytes:
        """ Encode and protect the COSE_Encrypt0 message. """

        if encrypt:
            message = [
                self.encode_phdr(),
                self.encode_uhdr(),
                self.encrypt(nonce=nonce, alg=alg, key=key)
            ]
        else:
            message = [self.encode_phdr(), self.encode_uhdr(), self.payload]

        if tagged:
            res = cbor2.dumps(cbor2.CBORTag(self.cbor_tag, message))
        else:
            res = cbor2.dumps(message)

        return res
Esempio n. 17
0
 def to_suit(self):
     for k, f in self.fields.items():
         v = getattr(self, k, None)
         if v:
             return cbor.CBORTag(tag=f.suit_key, value=v.to_suit())
     return None
Esempio n. 18
0
class TestCOSE:
    """
    Tests for COSE.
    """
    def test_cose_constructor_with_options(self):
        ctx = COSE.new()
        assert isinstance(ctx, COSE)

    def test_cose_alg_auto_inclusion(self):
        ctx = COSE.new()
        ctx.alg_auto_inclusion = True
        assert ctx.alg_auto_inclusion is True

    def test_cose_kid_auto_inclusion(self):
        ctx = COSE.new()
        ctx.kid_auto_inclusion = True
        assert ctx.kid_auto_inclusion is True

    def test_cose_verify_kid(self):
        ctx = COSE.new()
        ctx.verify_kid = True
        assert ctx.verify_kid is True

    def test_cose_encode_and_decode_mac0_with_options(self):
        ctx = COSE.new(alg_auto_inclusion=True, kid_auto_inclusion=True)

        # MAC0
        mac_key = COSEKey.from_symmetric_key(alg="HS256", kid="01")
        encoded = ctx.encode_and_mac(b"Hello world!", mac_key)
        assert b"Hello world!" == ctx.decode(encoded, mac_key)

    def test_cose_encode_and_decode_mac_with_options(self):
        ctx = COSE.new(alg_auto_inclusion=True, kid_auto_inclusion=True)

        # MAC
        mac_key = COSEKey.from_symmetric_key(alg="HS256", kid="01")
        encoded = ctx.encode_and_mac(
            b"Hello world!",
            mac_key,
            recipients=[RecipientInterface(unprotected={
                1: -6,
                4: b"01"
            })],
        )
        assert b"Hello world!" == ctx.decode(encoded, mac_key)

    def test_cose_encode_and_decode_encrypt0_with_options(self):
        ctx = COSE.new(alg_auto_inclusion=True, kid_auto_inclusion=True)

        # Encrypt0
        enc_key = COSEKey.from_symmetric_key(alg="ChaCha20/Poly1305", kid="02")
        encoded = ctx.encode_and_encrypt(b"Hello world!", enc_key)
        assert b"Hello world!" == ctx.decode(encoded, enc_key)

    def test_cose_encode_and_decode_encrypt_with_options(self):
        ctx = COSE.new(alg_auto_inclusion=True, kid_auto_inclusion=True)

        # Encrypt
        enc_key = COSEKey.from_symmetric_key(alg="ChaCha20/Poly1305", kid="02")
        rec = Recipient.from_jwk({"alg": "direct", "kid": "02"})
        encoded = ctx.encode_and_encrypt(
            b"Hello world!",
            enc_key,
            recipients=[rec],
        )
        assert b"Hello world!" == ctx.decode(encoded, enc_key)

    def test_cose_encode_and_decode_signature1_with_options(self):
        ctx = COSE.new(alg_auto_inclusion=True, kid_auto_inclusion=True)

        # Signature1
        sig_key = COSEKey.from_jwk({
            "kty":
            "EC",
            "kid":
            "03",
            "crv":
            "P-256",
            "x":
            "usWxHK2PmfnHKwXPS54m0kTcGJ90UiglWiGahtagnv8",
            "y":
            "IBOL-C3BttVivg-lSreASjpkttcsz-1rb7btKLv8EX4",
            "d":
            "V8kgd2ZBRuh2dgyVINBUqpPDr7BOMGcF22CQMIUHtNM",
        })
        encoded = ctx.encode_and_sign(b"Hello world!", sig_key)
        assert b"Hello world!" == ctx.decode(encoded, sig_key)

    def test_cose_encode_and_decode_mac0_with_protected_bytes(self):
        ctx = COSE.new(kid_auto_inclusion=True)

        # MAC0
        mac_key = COSEKey.from_symmetric_key(alg="HS256", kid="01")
        encoded = ctx.encode_and_mac(b"Hello world!", mac_key, protected=b"a0")
        assert b"Hello world!" == ctx.decode(encoded, mac_key)

    def test_cose_encode_and_decode_mac_with_protected_bytes(self):
        ctx = COSE.new()

        # MAC
        mac_key = COSEKey.from_symmetric_key(alg="HS256", kid="01")
        encoded = ctx.encode_and_mac(
            b"Hello world!",
            mac_key,
            protected=b"a0",
            recipients=[RecipientInterface(unprotected={
                1: -6,
                4: b"01"
            })],
        )
        assert b"Hello world!" == ctx.decode(encoded, mac_key)

    def test_cose_encode_and_decode_encrypt0_with_protected_bytes(self):
        ctx = COSE.new(kid_auto_inclusion=True)

        # Encrypt0
        enc_key = COSEKey.from_symmetric_key(alg="ChaCha20/Poly1305", kid="02")
        encoded = ctx.encode_and_encrypt(b"Hello world!",
                                         enc_key,
                                         protected=b"a0")
        assert b"Hello world!" == ctx.decode(encoded, enc_key)

    def test_cose_encode_and_decode_encrypt_with_protected_bytes(self):
        ctx = COSE.new(kid_auto_inclusion=True)

        # Encrypt
        enc_key = COSEKey.from_symmetric_key(alg="ChaCha20/Poly1305", kid="02")
        encoded = ctx.encode_and_encrypt(
            b"Hello world!",
            enc_key,
            protected=b"a0",
            recipients=[RecipientInterface(unprotected={
                1: -6,
                4: b"02"
            })],
        )
        assert b"Hello world!" == ctx.decode(encoded, enc_key)

    def test_cose_encode_and_decode_signature1_with_protected_bytes(self):
        ctx = COSE.new(kid_auto_inclusion=True)

        # Signature1
        sig_key = COSEKey.from_jwk({
            "kty":
            "EC",
            "kid":
            "03",
            "crv":
            "P-256",
            "x":
            "usWxHK2PmfnHKwXPS54m0kTcGJ90UiglWiGahtagnv8",
            "y":
            "IBOL-C3BttVivg-lSreASjpkttcsz-1rb7btKLv8EX4",
            "d":
            "V8kgd2ZBRuh2dgyVINBUqpPDr7BOMGcF22CQMIUHtNM",
        })
        encoded = ctx.encode_and_sign(b"Hello world!",
                                      sig_key,
                                      protected=b"a0")
        assert b"Hello world!" == ctx.decode(encoded, sig_key)

    def test_cose_encode_and_decode_mac0_with_verify_kid(self):
        ctx = COSE.new(alg_auto_inclusion=True,
                       kid_auto_inclusion=True,
                       verify_kid=True)

        # MAC0
        mac_key = COSEKey.from_symmetric_key(alg="HS256", kid="01")
        encoded = ctx.encode_and_mac(b"Hello world!", mac_key)
        assert b"Hello world!" == ctx.decode(encoded, mac_key)

    def test_cose_encode_and_decode_mac0_without_kid_with_verify_kid(self):
        ctx = COSE.new(alg_auto_inclusion=True,
                       kid_auto_inclusion=True,
                       verify_kid=True)

        # MAC0
        mac_key = COSEKey.from_symmetric_key(alg="HS256")
        encoded = ctx.encode_and_mac(b"Hello world!", mac_key)
        with pytest.raises(ValueError) as err:
            ctx.decode(encoded, mac_key)
            pytest.fail("decode() should fail.")
        assert "kid should be specified." in str(err.value)

    def test_cose_encode_and_decode_with_recipient_builder(self):
        ctx = COSE.new()

        mac_key = COSEKey.from_symmetric_key(alg="HS256", kid="01")
        recipient = Recipient.from_jwk({
            "alg": "direct",
            "kid": "01",
        })
        encoded = ctx.encode_and_mac(
            b"Hello world!",
            mac_key,
            recipients=[recipient],
        )
        assert b"Hello world!" == ctx.decode(encoded, mac_key)

    def test_cose_constructor_with_invalid_kid_auto_inclusion(self):
        with pytest.raises(ValueError) as err:
            COSE.new(kid_auto_inclusion="xxx")
            pytest.fail("COSE() should fail.")
        assert "kid_auto_inclusion should be bool." in str(err.value)

    def test_cose_constructor_with_invalid_alg_auto_inclusion(self):
        with pytest.raises(ValueError) as err:
            COSE.new(alg_auto_inclusion="xxx")
            pytest.fail("COSE() should fail.")
        assert "alg_auto_inclusion should be bool." in str(err.value)

    def test_cose_constructor_with_invalid_verify_kid(self):
        with pytest.raises(ValueError) as err:
            COSE.new(verify_kid="xxx")
            pytest.fail("COSE() should fail.")
        assert "verify_kid should be bool." in str(err.value)

    def test_cose_constructor_with_invalid_ca_certs(self):
        with pytest.raises(ValueError) as err:
            COSE.new(ca_certs=b"xxx")
            pytest.fail("COSE() should fail.")
        assert "ca_certs should be str." in str(err.value)

    @pytest.mark.parametrize(
        "invalid, msg",
        [
            (
                {
                    "xxx": "yyy"
                },
                "Unsupported or unknown COSE header parameter: xxx.",
            ),
            (
                {
                    "alg": "xxx"
                },
                "Unsupported or unknown alg: xxx.",
            ),
        ],
    )
    def test_cose_encode_and_mac_with_invalid_protected(
            self, ctx, invalid, msg):
        key = COSEKey.from_symmetric_key(alg="HS256")
        with pytest.raises(ValueError) as err:
            ctx.encode_and_mac(b"This is the content.", key, protected=invalid)
            pytest.fail("encode_and_mac should fail.")
        assert msg in str(err.value)

    def test_cose_encode_and_mac_with_recipient_has_unsupported_alg(self, ctx):
        key = COSEKey.from_symmetric_key(alg="HS256")
        with pytest.raises(NotImplementedError) as err:
            ctx.encode_and_mac(
                b"This is the content.",
                key,
                recipients=[
                    RecipientInterface(unprotected={
                        1: 0,
                        4: b"our-secret"
                    })
                ],
            )
            pytest.fail("encode_and_mac should fail.")
        assert "Algorithms other than direct are not supported for recipients." in str(
            err.value)

    def test_cose_encode_and_encrypt_with_recipient_has_unsupported_alg(
            self, ctx):
        key = COSEKey.from_jwk({
            "kty": "oct",
            "alg": "AES-CCM-16-64-128",
            "kid": "our-secret",
            "use": "enc",
            "k": "hJtXIZ2uSN5kbQfbtTNWbg",
        })
        with pytest.raises(NotImplementedError) as err:
            ctx.encode_and_encrypt(
                b"This is the content.",
                key,
                nonce=bytes.fromhex("89F52F65A1C580933B5261A72F"),
                recipients=[
                    RecipientInterface(unprotected={
                        1: 0,
                        4: b"our-secret"
                    })
                ],
            )
            pytest.fail("encode_and_encrypt should fail.")
        assert "Algorithms other than direct are not supported for recipients." in str(
            err.value)

    def test_cose_encode_and_mac_with_invalid_payload(self, ctx):
        key = COSEKey.from_symmetric_key(alg="HS256")
        with pytest.raises(EncodeError) as err:
            ctx.encode_and_mac(datetime.datetime.now(), key, {}, {})
            pytest.fail("encode_and_mac should fail.")
        assert "Failed to encode." in str(err.value)

    @pytest.mark.parametrize(
        "invalid, msg",
        [
            (
                "invalid_string_data",
                "Invalid COSE format.",
            ),
            (
                {},
                "Invalid COSE format.",
            ),
            (
                [],
                "Invalid COSE format.",
            ),
            (
                123,
                "Invalid COSE format.",
            ),
            (
                cbor2.CBORTag(16, "invalid_string_data"),
                "Invalid Encrypt0 format.",
            ),
            (
                cbor2.CBORTag(16, {}),
                "Invalid Encrypt0 format.",
            ),
            (
                cbor2.CBORTag(16, []),
                "Invalid Encrypt0 format.",
            ),
            (
                cbor2.CBORTag(16, 123),
                "Invalid Encrypt0 format.",
            ),
            (
                cbor2.CBORTag(16, [b"", b"invalid byte data", b""]),
                "unprotected header should be dict.",
            ),
            (
                cbor2.CBORTag(16, [b"", "invalid string data", b""]),
                "unprotected header should be dict.",
            ),
            (
                cbor2.CBORTag(16, [b"", [], b""]),
                "unprotected header should be dict.",
            ),
            (
                cbor2.CBORTag(16, [b"", 123, b""]),
                "unprotected header should be dict.",
            ),
            (
                cbor2.dumps(CBORTag(96, [])),
                "Invalid Encrypt format.",
            ),
            (
                cbor2.dumps(CBORTag(96, {})),
                "Invalid Encrypt format.",
            ),
            (
                cbor2.dumps(CBORTag(96, b"")),
                "Invalid Encrypt format.",
            ),
            (
                cbor2.dumps(CBORTag(96, 123)),
                "Invalid Encrypt format.",
            ),
            (
                cbor2.dumps(CBORTag(96, [b"", b"", b""])),
                "Invalid Encrypt format.",
            ),
            (
                cbor2.dumps(CBORTag(96, [b"", b"", b"", [b""]])),
                "unprotected header should be dict.",
            ),
            (
                cbor2.CBORTag(17, "invalid_string_data"),
                "Invalid MAC0 format.",
            ),
            (
                cbor2.CBORTag(17, {}),
                "Invalid MAC0 format.",
            ),
            (
                cbor2.CBORTag(17, []),
                "Invalid MAC0 format.",
            ),
            (
                cbor2.CBORTag(17, 123),
                "Invalid MAC0 format.",
            ),
            (
                cbor2.CBORTag(97, "invalid_string_data"),
                "Invalid MAC format.",
            ),
            (
                cbor2.CBORTag(97, {}),
                "Invalid MAC format.",
            ),
            (
                cbor2.CBORTag(97, []),
                "Invalid MAC format.",
            ),
            (
                cbor2.CBORTag(97, 123),
                "Invalid MAC format.",
            ),
            (
                cbor2.CBORTag(18, "invalid_string_data"),
                "Invalid Signature1 format.",
            ),
            (
                cbor2.CBORTag(18, {}),
                "Invalid Signature1 format.",
            ),
            (
                cbor2.CBORTag(18, []),
                "Invalid Signature1 format.",
            ),
            (
                cbor2.CBORTag(18, 123),
                "Invalid Signature1 format.",
            ),
            (
                cbor2.dumps(CBORTag(98, [])),
                "Invalid Signature format.",
            ),
            (
                cbor2.dumps(CBORTag(98, {})),
                "Invalid Signature format.",
            ),
            (
                cbor2.dumps(CBORTag(98, b"")),
                "Invalid Signature format.",
            ),
            (
                cbor2.dumps(CBORTag(98, 123)),
                "Invalid Signature format.",
            ),
            (
                cbor2.dumps(CBORTag(98, [b"", b"", b"", b""])),
                "unprotected header should be dict.",
            ),
            (
                cbor2.dumps(CBORTag(98, [b"", b"", b"", [b""]])),
                "unprotected header should be dict.",
            ),
            (
                cbor2.dumps(CBORTag(98, [b"", {}, b"", b""])),
                "Invalid Signature format.",
            ),
            (
                cbor2.dumps(CBORTag(98, [b"", {}, b"", [b""]])),
                "Invalid Signature format.",
            ),
            (
                cbor2.dumps(CBORTag(98, [b"", {}, b"", [[b"", b"", b""]]])),
                "unprotected header in signature structure should be dict.",
            ),
        ],
    )
    def test_cose_decode_with_invalid_data(self, ctx, invalid, msg):
        with open(key_path("public_key_es256.pem")) as key_file:
            public_key = COSEKey.from_pem(key_file.read(), kid="01")

        with pytest.raises(ValueError) as err:
            ctx.decode(invalid, public_key)
            pytest.fail("decode should fail.")
        assert msg in str(err.value)

    def test_cose_decode_mac0_without_key_and_materials(self, ctx):
        key = COSEKey.from_symmetric_key(alg="HS256")
        encoded = cwt.encode({"iss": "coap://as.example"}, key)
        with pytest.raises(ValueError) as err:
            ctx.decode(encoded, b"")
            pytest.fail("decode should fail.")
        assert "key in keys should have COSEKeyInterface." in str(err.value)

    def test_cose_decode_mac0_with_multiple_keys_without_kid(self, ctx):
        key1 = COSEKey.from_symmetric_key(alg="HS256")
        key2 = COSEKey.from_symmetric_key(alg="HS256")
        encoded = ctx.encode_and_mac(b"Hello world!", key1)
        decoded = ctx.decode(encoded, [key1, key2])
        assert decoded == b"Hello world!"

    def test_cose_decode_mac0_with_different_multiple_keys(self, ctx):
        key1 = COSEKey.from_symmetric_key(alg="HS256")
        key2 = COSEKey.from_symmetric_key(alg="HS256")
        key3 = COSEKey.from_symmetric_key(alg="HS256")
        encoded = ctx.encode_and_mac(b"Hello world!", key1)
        with pytest.raises(VerifyError) as err:
            ctx.decode(encoded, [key2, key3])
            pytest.fail("decode() should fail.")
        assert "Failed to compare digest." in str(err.value)

    def test_cose_decode_mac0_with_different_multiple_keys_2(self):
        ctx = COSE.new(alg_auto_inclusion=True, kid_auto_inclusion=True)
        key1 = COSEKey.from_symmetric_key(alg="HS256", kid="01")
        key2 = COSEKey.from_symmetric_key(alg="HS256")
        key3 = COSEKey.from_symmetric_key(alg="HS256")
        encoded = ctx.encode_and_mac(b"Hello world!", key1)
        with pytest.raises(ValueError) as err:
            ctx.decode(encoded, [key2, key3])
            pytest.fail("decode() should fail.")
        assert "key is not found." in str(err.value)

    def test_cose_decode_mac0_with_multiple_kid(self):
        ctx = COSE.new(alg_auto_inclusion=True, kid_auto_inclusion=True)
        key1 = COSEKey.from_symmetric_key(alg="HS256", kid="01")
        key2 = COSEKey.from_symmetric_key(alg="HS256", kid="01")
        key3 = COSEKey.from_symmetric_key(alg="HS256", kid="02")
        encoded = ctx.encode_and_mac(b"Hello world!", key2)
        assert b"Hello world!" == ctx.decode(encoded, [key1, key2, key3])

    def test_cose_decode_mac_with_multiple_keys_without_kid(self, ctx):
        key = COSEKey.from_symmetric_key(alg="HS256")

        material1 = base64.urlsafe_b64encode(token_bytes(16)).decode()
        material2 = base64.urlsafe_b64encode(token_bytes(16)).decode()
        material3 = base64.urlsafe_b64encode(token_bytes(16)).decode()

        r1 = Recipient.from_jwk({
            "kty": "oct",
            "alg": "A128KW",
            "k": material1
        })
        r2 = Recipient.from_jwk({
            "kty": "oct",
            "alg": "A128KW",
            "k": material2
        })
        r1.apply(key)
        r2.apply(key)

        encoded = ctx.encode_and_mac(b"Hello world!", key, recipients=[r2, r1])

        shared_key1 = COSEKey.from_jwk({
            "kty": "oct",
            "alg": "A128KW",
            "k": material1
        })
        shared_key3 = COSEKey.from_jwk({
            "kty": "oct",
            "alg": "A128KW",
            "k": material3
        })
        assert b"Hello world!" == ctx.decode(encoded,
                                             keys=[shared_key3, shared_key1])

    def test_cose_decode_mac_with_multiple_keys_with_verify_kid(self):
        ctx = COSE.new(alg_auto_inclusion=True, verify_kid=True)
        key = COSEKey.from_symmetric_key(alg="HS256")

        material1 = base64.urlsafe_b64encode(token_bytes(16)).decode()
        material2 = base64.urlsafe_b64encode(token_bytes(16)).decode()
        material3 = base64.urlsafe_b64encode(token_bytes(16)).decode()

        r1 = Recipient.from_jwk({
            "kid": "01",
            "kty": "oct",
            "alg": "A128KW",
            "k": material1
        })
        r2 = Recipient.from_jwk({
            "kid": "02",
            "kty": "oct",
            "alg": "A128KW",
            "k": material2
        })
        r1.apply(key)
        r2.apply(key)

        encoded = ctx.encode_and_mac(b"Hello world!", key, recipients=[r2, r1])

        shared_key1 = COSEKey.from_jwk({
            "kid": "01",
            "kty": "oct",
            "alg": "A128KW",
            "k": material1
        })
        shared_key3 = COSEKey.from_jwk({
            "kid": "03",
            "kty": "oct",
            "alg": "A128KW",
            "k": material3
        })

        assert b"Hello world!" == ctx.decode(encoded,
                                             keys=[shared_key3, shared_key1])

    def test_cose_decode_mac_with_multiple_keys_with_verify_kid_and_protected_kid(
            self):
        ctx = COSE.new(alg_auto_inclusion=True, verify_kid=True)
        key = COSEKey.from_symmetric_key(alg="HS256")

        material1 = base64.urlsafe_b64encode(token_bytes(16)).decode()
        material2 = base64.urlsafe_b64encode(token_bytes(16)).decode()
        material3 = base64.urlsafe_b64encode(token_bytes(16)).decode()

        shared_key1 = COSEKey.from_jwk({
            "kty": "oct",
            "alg": "A128KW",
            "k": material1
        })
        shared_key2 = COSEKey.from_jwk({
            "kty": "oct",
            "alg": "A128KW",
            "k": material2
        })
        shared_key3 = COSEKey.from_jwk({
            "kty": "oct",
            "alg": "A128KW",
            "k": material3
        })

        r1 = Recipient.new(protected={1: -3, 4: b"01"}, sender_key=shared_key1)
        r2 = Recipient.new(protected={1: -3, 4: b"02"}, sender_key=shared_key2)
        r1.apply(key)
        r2.apply(key)

        encoded = ctx.encode_and_mac(b"Hello world!", key, recipients=[r2, r1])

        shared_key1 = COSEKey.from_jwk({
            "kid": "01",
            "kty": "oct",
            "alg": "A128KW",
            "k": material1
        })
        shared_key3 = COSEKey.from_jwk({
            "kid": "03",
            "kty": "oct",
            "alg": "A128KW",
            "k": material3
        })

        assert b"Hello world!" == ctx.decode(encoded,
                                             keys=[shared_key3, shared_key1])

    def test_cose_decode_mac_with_multiple_keys_without_kid_with_verify_kid(
            self):
        ctx = COSE.new(alg_auto_inclusion=True, verify_kid=True)
        key = COSEKey.from_symmetric_key(alg="HS256")

        material1 = base64.urlsafe_b64encode(token_bytes(16)).decode()
        material2 = base64.urlsafe_b64encode(token_bytes(16)).decode()
        material3 = base64.urlsafe_b64encode(token_bytes(16)).decode()

        r1 = Recipient.from_jwk({
            "kty": "oct",
            "alg": "A128KW",
            "k": material1
        })
        r2 = Recipient.from_jwk({
            "kty": "oct",
            "alg": "A128KW",
            "k": material2
        })
        r1.apply(key)
        r2.apply(key)

        encoded = ctx.encode_and_mac(b"Hello world!", key, recipients=[r2, r1])

        shared_key1 = COSEKey.from_jwk({
            "kty": "oct",
            "alg": "A128KW",
            "k": material1
        })
        shared_key3 = COSEKey.from_jwk({
            "kty": "oct",
            "alg": "A128KW",
            "k": material3
        })

        with pytest.raises(ValueError) as err:
            ctx.decode(encoded, keys=[shared_key3, shared_key1])
            pytest.fail("decode() should fail.")
        assert "kid should be specified in recipient." in str(err.value)

    def test_cose_decode_mac_with_multiple_keys_without_recipient_kid_with_verify_kid(
        self, ):
        ctx = COSE.new(alg_auto_inclusion=True, verify_kid=True)
        key = COSEKey.from_symmetric_key(alg="HS256")

        material1 = base64.urlsafe_b64encode(token_bytes(16)).decode()
        material2 = base64.urlsafe_b64encode(token_bytes(16)).decode()
        material3 = base64.urlsafe_b64encode(token_bytes(16)).decode()

        r1 = Recipient.from_jwk({
            "kty": "oct",
            "alg": "A128KW",
            "k": material1
        })
        r2 = Recipient.from_jwk({
            "kty": "oct",
            "alg": "A128KW",
            "k": material2
        })
        r1.apply(key)
        r2.apply(key)

        encoded = ctx.encode_and_mac(b"Hello world!", key, recipients=[r2, r1])

        shared_key1 = COSEKey.from_jwk({
            "kid": "01",
            "kty": "oct",
            "alg": "A128KW",
            "k": material1
        })
        shared_key3 = COSEKey.from_jwk({
            "kid": "02",
            "kty": "oct",
            "alg": "A128KW",
            "k": material3
        })

        with pytest.raises(ValueError) as err:
            ctx.decode(encoded, keys=[shared_key3, shared_key1])
            pytest.fail("decode() should fail.")
        assert "kid should be specified in recipient." in str(err.value)

    def test_cose_decode_mac_with_different_multiple_keys(self, ctx):
        ctx = COSE.new(alg_auto_inclusion=True, verify_kid=True)
        key = COSEKey.from_symmetric_key(alg="HS256")

        material1 = base64.urlsafe_b64encode(token_bytes(16)).decode()
        material2 = base64.urlsafe_b64encode(token_bytes(16)).decode()
        material3 = base64.urlsafe_b64encode(token_bytes(16)).decode()

        r2 = Recipient.from_jwk({
            "kid": "03",
            "kty": "oct",
            "alg": "A128KW",
            "k": material2
        })
        r2.apply(key)

        encoded = ctx.encode_and_mac(b"Hello world!", key, recipients=[r2])

        shared_key1 = COSEKey.from_jwk({
            "kid": "01",
            "kty": "oct",
            "alg": "A128KW",
            "k": material1
        })
        shared_key3 = COSEKey.from_jwk({
            "kid": "03",
            "kty": "oct",
            "alg": "A128KW",
            "k": material3
        })

        with pytest.raises(DecodeError) as err:
            ctx.decode(encoded, keys=[shared_key1, shared_key3])
            pytest.fail("decode() should fail.")
        assert "Failed to decode key." in str(err.value)

    def test_cose_decode_mac_with_different_multiple_keys_2(self):
        ctx = COSE.new(alg_auto_inclusion=True, verify_kid=True)
        key = COSEKey.from_symmetric_key(alg="HS256")

        material1 = base64.urlsafe_b64encode(token_bytes(16)).decode()
        material2 = base64.urlsafe_b64encode(token_bytes(16)).decode()
        material3 = base64.urlsafe_b64encode(token_bytes(16)).decode()

        r2 = Recipient.from_jwk({
            "kid": "03",
            "kty": "oct",
            "alg": "A128KW",
            "k": material2
        })
        r2.apply(key)

        encoded = ctx.encode_and_mac(b"Hello world!", key, recipients=[r2])

        shared_key1 = COSEKey.from_jwk({
            "kid": "01",
            "kty": "oct",
            "alg": "A128KW",
            "k": material1
        })
        shared_key3 = COSEKey.from_jwk({
            "kid": "02",
            "kty": "oct",
            "alg": "A128KW",
            "k": material3
        })

        with pytest.raises(ValueError) as err:
            ctx.decode(encoded, keys=[shared_key1, shared_key3])
            pytest.fail("decode() should fail.")
        assert "key is not found." in str(err.value)

    def test_cose_decode_mac_with_multiple_kid(self):
        ctx = COSE.new(alg_auto_inclusion=True, kid_auto_inclusion=True)
        key1 = COSEKey.from_symmetric_key(alg="HS256", kid="01")
        key2 = COSEKey.from_symmetric_key(alg="HS256", kid="01")
        key3 = COSEKey.from_symmetric_key(alg="HS256", kid="02")
        encoded = ctx.encode_and_mac(b"Hello world!", key2)
        decoded = ctx.decode(encoded, [key1, key2, key3])
        assert decoded == b"Hello world!"

    def test_cose_decode_encrypt0_with_multiple_keys_without_kid(self, ctx):
        key1 = COSEKey.from_symmetric_key(alg="ChaCha20/Poly1305")
        key2 = COSEKey.from_symmetric_key(alg="ChaCha20/Poly1305")
        encoded = ctx.encode_and_encrypt(b"Hello world!", key1)
        decoded = ctx.decode(encoded, [key2, key1])
        assert decoded == b"Hello world!"

    def test_cose_decode_encrypt0_with_different_multiple_keys(self, ctx):
        key1 = COSEKey.from_symmetric_key(alg="ChaCha20/Poly1305")
        key2 = COSEKey.from_symmetric_key(alg="ChaCha20/Poly1305")
        key3 = COSEKey.from_symmetric_key(alg="ChaCha20/Poly1305")
        encoded = ctx.encode_and_encrypt(b"Hello world!", key1)
        with pytest.raises(DecodeError) as err:
            ctx.decode(encoded, [key2, key3])
            pytest.fail("decode() should fail.")
        assert "Failed to decrypt." in str(err.value)

    def test_cose_decode_encrypt0_with_different_multiple_keys_2(self):
        ctx = COSE.new(alg_auto_inclusion=True, kid_auto_inclusion=True)
        key1 = COSEKey.from_symmetric_key(alg="ChaCha20/Poly1305", kid="01")
        key2 = COSEKey.from_symmetric_key(alg="ChaCha20/Poly1305")
        key3 = COSEKey.from_symmetric_key(alg="ChaCha20/Poly1305")
        encoded = ctx.encode_and_encrypt(b"Hello world!", key1)
        with pytest.raises(ValueError) as err:
            ctx.decode(encoded, [key2, key3])
            pytest.fail("decode() should fail.")
        assert "key is not found." in str(err.value)

    def test_cose_decode_encrypt0_with_multiple_kid(self):
        ctx = COSE.new(alg_auto_inclusion=True, kid_auto_inclusion=True)
        key1 = COSEKey.from_symmetric_key(alg="ChaCha20/Poly1305", kid="01")
        key2 = COSEKey.from_symmetric_key(alg="ChaCha20/Poly1305", kid="01")
        key3 = COSEKey.from_symmetric_key(alg="ChaCha20/Poly1305", kid="02")
        encoded = ctx.encode_and_encrypt(b"Hello world!", key2)
        decoded = ctx.decode(encoded, [key1, key2, key3])
        assert decoded == b"Hello world!"

    def test_cose_decode_encrypt_with_multiple_keys_with_verify_kid(self):
        ctx = COSE.new(alg_auto_inclusion=True, verify_kid=True)
        key = COSEKey.from_symmetric_key(alg="A128GCM")

        material1 = base64.urlsafe_b64encode(token_bytes(16)).decode()
        material2 = base64.urlsafe_b64encode(token_bytes(16)).decode()
        material3 = base64.urlsafe_b64encode(token_bytes(16)).decode()

        r1 = Recipient.from_jwk({
            "kid": "01",
            "kty": "oct",
            "alg": "A128KW",
            "k": material1
        })
        r2 = Recipient.from_jwk({
            "kid": "02",
            "kty": "oct",
            "alg": "A128KW",
            "k": material2
        })
        r1.apply(key)
        r2.apply(key)

        encoded = ctx.encode_and_encrypt(b"Hello world!",
                                         key,
                                         recipients=[r2, r1])

        shared_key1 = COSEKey.from_jwk({
            "kid": "01",
            "kty": "oct",
            "alg": "A128KW",
            "k": material1
        })
        shared_key3 = COSEKey.from_jwk({
            "kid": "03",
            "kty": "oct",
            "alg": "A128KW",
            "k": material3
        })

        assert b"Hello world!" == ctx.decode(encoded,
                                             keys=[shared_key3, shared_key1])

    def test_cose_decode_signature1_with_multiple_keys_without_kid(self, ctx):
        with open(key_path("public_key_es256.pem")) as key_file:
            key1 = COSEKey.from_pem(key_file.read())
        with open(key_path("public_key_ed25519.pem")) as key_file:
            key2 = COSEKey.from_pem(key_file.read())
        with open(key_path("private_key_ed25519.pem")) as key_file:
            private_key = COSEKey.from_pem(key_file.read())
        encoded = ctx.encode_and_sign(b"Hello world!", private_key)
        decoded = ctx.decode(encoded, [key1, key2])
        assert decoded == b"Hello world!"

    def test_cose_decode_signature1_with_ca_certs_without_kid(self):
        with open(key_path("cert_es256.pem")) as key_file:
            public_key = COSEKey.from_pem(key_file.read())
        with open(key_path("private_key_cert_es256.pem")) as key_file:
            private_key = COSEKey.from_pem(key_file.read())
        ctx = COSE.new(alg_auto_inclusion=True,
                       ca_certs=key_path("cacert.pem"))
        encoded = ctx.encode_and_sign(b"Hello world!", private_key)
        decoded = ctx.decode(encoded, [public_key])
        assert decoded == b"Hello world!"

    def test_cose_decode_signature1_with_different_multiple_keys(self, ctx):
        with open(key_path("public_key_es256.pem")) as key_file:
            key1 = COSEKey.from_pem(key_file.read())
        # with open(key_path("public_key_ed25519.pem")) as key_file:
        #     key2 = COSEKey.from_pem(key_file.read())
        with open(key_path("public_key_ed448.pem")) as key_file:
            key3 = COSEKey.from_pem(key_file.read())
        with open(key_path("private_key_ed25519.pem")) as key_file:
            private_key = COSEKey.from_pem(key_file.read())
        encoded = ctx.encode_and_sign(b"Hello world!", private_key)
        with pytest.raises(VerifyError) as err:
            ctx.decode(encoded, [key1, key3])
            pytest.fail("decode() should fail.")
        assert "Failed to verify." in str(err.value)

    def test_cose_decode_signature1_with_different_multiple_keys_2(self):
        ctx = COSE.new(alg_auto_inclusion=True, kid_auto_inclusion=True)
        with open(key_path("public_key_es256.pem")) as key_file:
            key1 = COSEKey.from_pem(key_file.read())
        # with open(key_path("public_key_ed25519.pem")) as key_file:
        #     key2 = COSEKey.from_pem(key_file.read())
        with open(key_path("public_key_ed448.pem")) as key_file:
            key3 = COSEKey.from_pem(key_file.read())
        with open(key_path("private_key_ed25519.pem")) as key_file:
            private_key = COSEKey.from_pem(key_file.read(), kid="01")
        encoded = ctx.encode_and_sign(b"Hello world!", private_key)
        with pytest.raises(ValueError) as err:
            ctx.decode(encoded, [key1, key3])
            pytest.fail("decode() should fail.")
        assert "key is not found." in str(err.value)

    def test_cose_decode_signature1_with_multiple_kid(self):
        ctx = COSE.new(alg_auto_inclusion=True, kid_auto_inclusion=True)
        with open(key_path("public_key_es256.pem")) as key_file:
            key1 = COSEKey.from_pem(key_file.read(), kid="01")
        with open(key_path("public_key_ed25519.pem")) as key_file:
            key2 = COSEKey.from_pem(key_file.read(), kid="01")
        with open(key_path("public_key_ed448.pem")) as key_file:
            key3 = COSEKey.from_pem(key_file.read(), kid="02")
        with open(key_path("private_key_ed25519.pem")) as key_file:
            private_key = COSEKey.from_pem(key_file.read(), kid="01")
        encoded = ctx.encode_and_sign(b"Hello world!", private_key)
        decoded = ctx.decode(encoded, [key1, key2, key3])
        assert decoded == b"Hello world!"

    def test_cose_decode_signature1_with_same_kid_bound_to_different_key(self):
        ctx = COSE.new(alg_auto_inclusion=True, kid_auto_inclusion=True)
        with open(key_path("public_key_es256.pem")) as key_file:
            key1 = COSEKey.from_pem(key_file.read(), kid="01")
        with open(key_path("public_key_ed25519.pem")) as key_file:
            key2 = COSEKey.from_pem(key_file.read(), kid="02")
        with open(key_path("public_key_ed448.pem")) as key_file:
            key3 = COSEKey.from_pem(key_file.read(), kid="03")
        with open(key_path("private_key_ed25519.pem")) as key_file:
            private_key = COSEKey.from_pem(key_file.read(), kid="01")
        encoded = ctx.encode_and_sign(b"Hello world!", private_key)
        with pytest.raises(VerifyError) as err:
            ctx.decode(encoded, [key1, key2, key3])
            pytest.fail("decode() should fail.")
        assert "Failed to verify." in str(err.value)

    def test_cose_decode_signature1_with_key_not_found(self, ctx):
        with open(key_path("public_key_es256.pem")) as key_file:
            key1 = COSEKey.from_pem(key_file.read(), kid="01")
        with open(key_path("public_key_ed25519.pem")) as key_file:
            key2 = COSEKey.from_pem(key_file.read(), kid="02")
        with open(key_path("private_key_ed25519.pem")) as key_file:
            private_key = COSEKey.from_pem(key_file.read(), kid="03")
        encoded = cwt.encode({"iss": "coap://as.example"}, private_key)
        with pytest.raises(ValueError) as err:
            ctx.decode(encoded, [key1, key2])
            pytest.fail("decode should fail.")
        assert "key is not found." in str(err.value)

    def test_cose_decode_signature_with_multiple_keys_without_kid(self, ctx):
        with open(key_path("public_key_es256.pem")) as key_file:
            key1 = COSEKey.from_pem(key_file.read())
        with open(key_path("public_key_ed25519.pem")) as key_file:
            key2 = COSEKey.from_pem(key_file.read())
        with open(key_path("private_key_ed25519.pem")) as key_file:
            signer = Signer.from_pem(key_file.read())
        encoded = ctx.encode_and_sign(b"Hello world!", signers=[signer])
        decoded = ctx.decode(encoded, [key1, key2])
        assert decoded == b"Hello world!"

    def test_cose_decode_signature_with_different_multiple_keys(self, ctx):
        with open(key_path("public_key_es256.pem")) as key_file:
            key1 = COSEKey.from_pem(key_file.read())
        # with open(key_path("public_key_ed25519.pem")) as key_file:
        #     key2 = COSEKey.from_pem(key_file.read())
        with open(key_path("public_key_ed448.pem")) as key_file:
            key3 = COSEKey.from_pem(key_file.read())
        with open(key_path("private_key_ed25519.pem")) as key_file:
            signer = Signer.from_pem(key_file.read())
        encoded = ctx.encode_and_sign(b"Hello world!", signers=[signer])
        with pytest.raises(VerifyError) as err:
            ctx.decode(encoded, [key1, key3])
            pytest.fail("decode() should fail.")
        assert "Failed to verify." in str(err.value)

    def test_cose_decode_signature_with_different_multiple_keys_2(self):
        ctx = COSE.new(alg_auto_inclusion=True, kid_auto_inclusion=True)
        with open(key_path("public_key_es256.pem")) as key_file:
            key1 = COSEKey.from_pem(key_file.read())
        # with open(key_path("public_key_ed25519.pem")) as key_file:
        #     key2 = COSEKey.from_pem(key_file.read())
        with open(key_path("public_key_ed448.pem")) as key_file:
            key3 = COSEKey.from_pem(key_file.read())
        with open(key_path("private_key_ed25519.pem")) as key_file:
            signer = Signer.from_pem(key_file.read(), kid="01")
        encoded = ctx.encode_and_sign(b"Hello world!", signers=[signer])
        with pytest.raises(ValueError) as err:
            ctx.decode(encoded, [key1, key3])
            pytest.fail("decode() should fail.")
        assert "key is not found." in str(err.value)

    def test_cose_decode_signature_with_multiple_kid(self):
        ctx = COSE.new(alg_auto_inclusion=True, kid_auto_inclusion=True)
        with open(key_path("public_key_es256.pem")) as key_file:
            key1 = COSEKey.from_pem(key_file.read(), kid="01")
        with open(key_path("public_key_ed25519.pem")) as key_file:
            key2 = COSEKey.from_pem(key_file.read(), kid="01")
        with open(key_path("public_key_ed448.pem")) as key_file:
            key3 = COSEKey.from_pem(key_file.read(), kid="02")
        with open(key_path("private_key_ed25519.pem")) as key_file:
            signer = Signer.from_pem(key_file.read(), kid="01")
        encoded = ctx.encode_and_sign(b"Hello world!", signers=[signer])
        decoded = ctx.decode(encoded, [key1, key2, key3])
        assert decoded == b"Hello world!"

    def test_cose_decode_signature_with_same_kid_bound_to_different_key(self):
        ctx = COSE.new(alg_auto_inclusion=True, kid_auto_inclusion=True)
        with open(key_path("public_key_es256.pem")) as key_file:
            key1 = COSEKey.from_pem(key_file.read(), kid="01")
        with open(key_path("public_key_ed25519.pem")) as key_file:
            key2 = COSEKey.from_pem(key_file.read(), kid="02")
        with open(key_path("public_key_ed448.pem")) as key_file:
            key3 = COSEKey.from_pem(key_file.read(), kid="03")
        with open(key_path("private_key_ed25519.pem")) as key_file:
            signer = Signer.from_pem(key_file.read(), kid="01")
        encoded = ctx.encode_and_sign(b"Hello world!", signers=[signer])
        with pytest.raises(VerifyError) as err:
            ctx.decode(encoded, [key1, key2, key3])
            pytest.fail("decode() should fail.")
        assert "Failed to verify." in str(err.value)

    def test_cose_decode_signature_with_key_not_found(self):
        ctx = COSE.new(alg_auto_inclusion=True, kid_auto_inclusion=True)
        with open(key_path("public_key_es256.pem")) as key_file:
            key1 = COSEKey.from_pem(key_file.read(), kid="01")
        with open(key_path("public_key_ed25519.pem")) as key_file:
            key2 = COSEKey.from_pem(key_file.read(), kid="02")
        with open(key_path("private_key_ed25519.pem")) as key_file:
            signer = Signer.from_pem(key_file.read(), kid="03")
        encoded = ctx.encode_and_sign(b"Hello world!", signers=[signer])
        with pytest.raises(ValueError) as err:
            ctx.decode(encoded, [key1, key2])
            pytest.fail("decode should fail.")
        assert "key is not found." in str(err.value)

    def test_cose_decode_ecdh_es_hkdf_256_without_context(self):
        with open(key_path("public_key_es256.pem")) as key_file:
            public_key = COSEKey.from_pem(key_file.read(), kid="01")
        recipient = Recipient.from_jwk({
            "kty": "EC",
            "crv": "P-256",
            "alg": "ECDH-ES+HKDF-256"
        })
        enc_key = recipient.apply(recipient_key=public_key,
                                  context={"alg": "A128GCM"})
        ctx = COSE.new(alg_auto_inclusion=True)
        encoded = ctx.encode_and_encrypt(
            b"This is the content.",
            key=enc_key,
            recipients=[recipient],
        )

        with open(key_path("private_key_es256.pem")) as key_file:
            private_key = COSEKey.from_pem(key_file.read(), kid="01")
        with pytest.raises(ValueError) as err:
            ctx.decode(encoded, private_key)
            pytest.fail("decode should fail.")
        assert "context should be set." in str(err.value)

    def test_cose_decode_ecdh_aes_key_wrap_without_context(self):
        with open(key_path("public_key_es256.pem")) as key_file:
            public_key = COSEKey.from_pem(key_file.read(), kid="01")
        enc_key = COSEKey.from_symmetric_key(alg="A128GCM")
        recipient = Recipient.from_jwk({
            "kty": "EC",
            "crv": "P-256",
            "alg": "ECDH-ES+A128KW"
        })
        recipient.apply(enc_key,
                        recipient_key=public_key,
                        context={"alg": "A128GCM"})
        ctx = COSE.new(alg_auto_inclusion=True)
        encoded = ctx.encode_and_encrypt(
            b"This is the content.",
            key=enc_key,
            recipients=[recipient],
        )

        with open(key_path("private_key_es256.pem")) as key_file:
            private_key = COSEKey.from_pem(key_file.read(), kid="01")
        with pytest.raises(ValueError) as err:
            ctx.decode(encoded, private_key)
            pytest.fail("decode should fail.")
        assert "context should be set." in str(err.value)
Esempio n. 19
0
def mk_cipherlink(t, val):
    if not val:
        return None
    return cbor2.CBORTag(GG_TAG_CIPHERLINK, t + val)
Esempio n. 20
0
def cborify(encoder, o):
    """Helper function to convert non-native types to CBOR serializable values."""
    if isinstance(o, datetime.timedelta):
        o: datetime.timedelta
        encoder.encode(cbor.CBORTag(1337, o.total_seconds()))