コード例 #1
0
 def _create_cose_key(self, hkdf, key_len: int, label: str, prk: bytes,
                      ops: List[Type['KEYOPS']]) -> SymmetricKey:
     return SymmetricKey(k=hkdf(key_len, label, prk),
                         optional_params={
                             KpKeyOps: ops,
                             KpAlg: self.cipher_suite.aead
                         })
コード例 #2
0
def test_symmetric_key_generation_encoding_decoding(length):
    trails = 10

    for i in range(trails):
        sym_test = SymmetricKey.generate_key(length)
        sym_encoded = sym_test.encode()
        sym_decoded = CoseKey.decode(sym_encoded)
        assert _is_valid_symmetric_key(sym_decoded)
コード例 #3
0
def test_fail_on_invalid_symmetric_key_length():
    cose_key = {KpKty: KtySymmetric, SymKpK: os.urandom(17)}

    with pytest.raises(CoseInvalidKey) as excinfo:
        CoseKey.from_dict(cose_key)

    assert "Key length should be either 16, 24, or 32 bytes" in str(
        excinfo.value)

    with pytest.raises(CoseInvalidKey) as excinfo:
        _ = SymmetricKey(k=os.urandom(17))

    assert "Key length should be either 16, 24, or 32 bytes" in str(
        excinfo.value)
コード例 #4
0
    def test(self):
        print('\nTest: ' + __name__ + '.' + type(self).__name__)
        # 256-bit key
        key = SymmetricKey(k=binascii.unhexlify(
            '13BF9CEAD057C0ACA2C9E52471CA4B19DDFAF4C0784E3F3E8E3999DBAE4CE45C'
        ),
                           optional_params={
                               keyparam.KpKid:
                               b'ExampleKey',
                               keyparam.KpKeyOps:
                               [keyops.MacCreateOp, keyops.MacVerifyOp],
                           })
        print('Key: {}'.format(encode_diagnostic(cbor2.loads(key.encode()))))

        # Primary block
        prim_dec = self._get_primary_item()
        prim_enc = cbor2.dumps(prim_dec)
        print('Primary Block: {}'.format(encode_diagnostic(prim_dec)))
        print('Encoded: {}'.format(encode_diagnostic(prim_enc)))

        # Block-to-MAC
        target_dec = self._get_target_item()
        target_enc = cbor2.dumps(target_dec)
        content_plaintext = target_dec[4]
        print('Target Block: {}'.format(encode_diagnostic(target_dec)))
        print('Plaintext: {}'.format(encode_diagnostic(content_plaintext)))

        # Combined AAD
        ext_aad_dec = self._get_aad_item()
        ext_aad_enc = cbor2.dumps(ext_aad_dec)
        print('External AAD: {}'.format(encode_diagnostic(ext_aad_dec)))
        print('Encoded: {}'.format(encode_diagnostic(ext_aad_enc)))

        msg_obj = Mac0Message(
            phdr={
                headers.Algorithm: algorithms.HMAC256,
            },
            uhdr={
                headers.KID: key.kid,
            },
            payload=content_plaintext,
            # Non-encoded parameters
            external_aad=ext_aad_enc,
        )
        msg_obj.key = key

        # COSE internal structure
        cose_struct_enc = msg_obj._mac_structure
        cose_struct_dec = cbor2.loads(cose_struct_enc)
        print('COSE Structure: {}'.format(encode_diagnostic(cose_struct_dec)))
        print('Encoded: {}'.format(encode_diagnostic(cose_struct_enc)))

        # Encoded message
        message_enc = msg_obj.encode(tag=False)
        message_dec = cbor2.loads(message_enc)
        # Detach the payload
        content_signature = message_dec[2]
        message_dec[2] = None
        self._print_message(message_dec, recipient_idx=4)
        message_enc = cbor2.dumps(message_dec)

        # ASB structure
        asb_dec = self._get_asb_item([msg_obj.cbor_tag, message_enc])
        asb_enc = self._get_asb_enc(asb_dec)
        print('ASB: {}'.format(encode_diagnostic(asb_dec)))
        print('Encoded: {}'.format(encode_diagnostic(asb_enc)))

        bpsec_dec = self._get_bpsec_item(
            block_type=BlockType.BIB,
            asb_dec=asb_dec,
        )
        bpsec_enc = cbor2.dumps(bpsec_dec)
        print('BPSec block: {}'.format(encode_diagnostic(bpsec_dec)))
        print('Encoded: {}'.format(encode_diagnostic(bpsec_enc)))

        # Change from detached payload
        message_dec[2] = content_signature
        decode_obj = Mac0Message.from_cose_obj(message_dec)
        decode_obj.external_aad = ext_aad_enc
        decode_obj.key = key

        verify_valid = decode_obj.verify_tag()
        self.assertTrue(verify_valid)
        print('Loopback verify:', verify_valid)

        bundle = self._assemble_bundle([prim_enc, bpsec_enc, target_enc])
        print('Total bundle: {}'.format(encode_diagnostic(bundle)))
コード例 #5
0
def test_symmetric_key_construction(length):
    key = SymmetricKey(k=os.urandom(length))

    assert _is_valid_symmetric_key(key)
コード例 #6
0
def test_symmetric_key_generation(length):
    key = SymmetricKey.generate_key(length)

    assert _is_valid_symmetric_key(key)
コード例 #7
0
def test_unknown_key_attribute():
    key = SymmetricKey(k=os.urandom(32),
                       optional_params={"subject_name": "signing key"})

    assert "subject_name" in key
    assert key['subject_name'] == "signing key"
コード例 #8
0
    def test(self):
        print('\nTest: ' + __name__ + '.' + type(self).__name__)
        # 256-bit key encryption key
        kek = SymmetricKey(k=binascii.unhexlify(
            '0E8A982B921D1086241798032FEDC1F883EAB72E4E43BB2D11CFAE38AD7A972E'
        ),
                           optional_params={
                               keyparam.KpKid: b'ExampleKEK',
                               keyparam.KpKeyOps:
                               [keyops.WrapOp, keyops.UnwrapOp],
                           })
        print('KEK: {}'.format(encode_diagnostic(cbor2.loads(kek.encode()))))
        # 256-bit content encryption key
        cek = SymmetricKey(k=binascii.unhexlify(
            '13BF9CEAD057C0ACA2C9E52471CA4B19DDFAF4C0784E3F3E8E3999DBAE4CE45C'
        ),
                           optional_params={
                               keyparam.KpKid:
                               b'ExampleCEK',
                               keyparam.KpKeyOps:
                               [keyops.EncryptOp, keyops.DecryptOp],
                           })
        print('CEK: {}'.format(encode_diagnostic(cbor2.loads(cek.encode()))))
        # session IV
        iv = binascii.unhexlify('6F3093EBA5D85143C3DC484A')
        print('IV: {}'.format(binascii.hexlify(iv)))

        # Primary block
        prim_dec = self._get_primary_item()
        prim_enc = cbor2.dumps(prim_dec)
        print('Primary Block: {}'.format(encode_diagnostic(prim_dec)))
        print('Encoded: {}'.format(encode_diagnostic(prim_enc)))

        # Security target block
        target_dec = self._get_target_item()
        content_plaintext = target_dec[4]
        print('Target Block: {}'.format(encode_diagnostic(target_dec)))
        print('Plaintext: {}'.format(encode_diagnostic(content_plaintext)))

        # Combined AAD
        ext_aad_dec = self._get_aad_item()
        ext_aad_enc = cbor2.dumps(ext_aad_dec)
        print('External AAD: {}'.format(encode_diagnostic(ext_aad_dec)))
        print('Encoded: {}'.format(encode_diagnostic(ext_aad_enc)))

        msg_obj = EncMessage(
            phdr={
                headers.Algorithm: algorithms.A256GCM,
            },
            uhdr={
                headers.IV: iv,
            },
            payload=content_plaintext,
            recipients=[
                KeyWrap(
                    uhdr={
                        headers.Algorithm: algorithms.A256KW,
                        headers.KID: kek.kid,
                    },
                    payload=cek.k,
                ),
            ],
            # Non-encoded parameters
            external_aad=ext_aad_enc,
        )
        msg_obj.recipients[0].key = kek

        # COSE internal structure
        cose_struct_enc = msg_obj._enc_structure
        cose_struct_dec = cbor2.loads(cose_struct_enc)
        print('COSE Structure: {}'.format(encode_diagnostic(cose_struct_dec)))
        print('Encoded: {}'.format(encode_diagnostic(cose_struct_enc)))

        # Encoded message
        message_enc = msg_obj.encode(tag=False)
        message_dec = cbor2.loads(message_enc)
        # Detach the payload
        content_ciphertext = message_dec[2]
        message_dec[2] = None
        self._print_message(message_dec, recipient_idx=3)
        print('Ciphertext: {}'.format(encode_diagnostic(content_ciphertext)))
        message_enc = cbor2.dumps(message_dec)

        # ASB structure
        asb_dec = self._get_asb_item([msg_obj.cbor_tag, message_enc])
        asb_enc = self._get_asb_enc(asb_dec)
        print('ASB: {}'.format(encode_diagnostic(asb_dec)))
        print('Encoded: {}'.format(encode_diagnostic(asb_enc)))

        bpsec_dec = self._get_bpsec_item(
            block_type=BlockType.BCB,
            asb_dec=asb_dec,
        )
        bpsec_enc = cbor2.dumps(bpsec_dec)
        print('BPSec block: {}'.format(encode_diagnostic(bpsec_dec)))
        print('Encoded: {}'.format(encode_diagnostic(bpsec_enc)))

        # Change from detached payload
        message_dec[2] = content_ciphertext
        decode_obj = EncMessage.from_cose_obj(message_dec)
        decode_obj.external_aad = ext_aad_enc

        recip = decode_obj.recipients[0]
        recip.key = kek
        decode_plaintext = decode_obj.decrypt(recipient=recip)
        print('Loopback plaintext:', encode_diagnostic(decode_plaintext))
        self.assertEqual(content_plaintext, decode_plaintext)

        print('Loopback CEK:',
              encode_diagnostic(cbor2.loads(decode_obj.key.encode())))
        self.assertEqual(cek.k, decode_obj.key.k)

        target_dec[4] = content_ciphertext
        target_enc = cbor2.dumps(target_dec)
        bundle = self._assemble_bundle([prim_enc, bpsec_enc, target_enc])
        print('Total bundle: {}'.format(encode_diagnostic(bundle)))
コード例 #9
0
ファイル: test_attributes.py プロジェクト: BrianSipos/pycose
def test_unknown_header_attribute_encoding_decoding():
    msg = Enc0Message(phdr={
        Algorithm: AESCCM1664128,
        "Custom-Header-Attr1": 7879
    },
                      uhdr={
                          KID: 8,
                          IV: unhexlify(b'00000000000000000000000000'),
                          "Custom-Header-Attr2": 879
                      })
    msg.key = SymmetricKey.generate_key(key_len=16)

    assert "Custom-Header-Attr1" in msg.phdr
    assert "Custom-Header-Attr2" in msg.uhdr

    msg = msg.encode()

    msg_decoded = CoseMessage.decode(msg)
    assert "Custom-Header-Attr1" in msg_decoded.phdr
    assert "Custom-Header-Attr2" in msg_decoded.uhdr

    msg = EncMessage(phdr={
        Algorithm: AESCCM1664128,
        "Custom-Header-Attr1": 7879
    },
                     uhdr={
                         KID: 8,
                         IV: unhexlify(b'00000000000000000000000000'),
                         "Custom-Header-Attr2": 878
                     },
                     recipients=[
                         DirectEncryption(uhdr={
                             Algorithm: Direct,
                             "Custom-Header-Attr3": 9999
                         })
                     ])
    msg.key = SymmetricKey.generate_key(key_len=16)

    assert "Custom-Header-Attr1" in msg.phdr
    assert "Custom-Header-Attr2" in msg.uhdr
    assert "Custom-Header-Attr3" in msg.recipients[0].uhdr

    msg = msg.encode()

    msg_decoded = CoseMessage.decode(msg)
    assert "Custom-Header-Attr1" in msg_decoded.phdr
    assert "Custom-Header-Attr2" in msg_decoded.uhdr
    assert "Custom-Header-Attr3" in msg_decoded.recipients[0].uhdr

    msg = Mac0Message(phdr={
        Algorithm: HMAC256,
        "Custom-Header-Attr1": 7879
    },
                      uhdr={
                          KID: 8,
                          IV: unhexlify(b'00000000000000000000000000'),
                          "Custom-Header-Attr2": 878
                      })
    msg.key = SymmetricKey.generate_key(key_len=16)

    assert "Custom-Header-Attr1" in msg.phdr
    assert "Custom-Header-Attr2" in msg.uhdr

    msg = msg.encode()

    msg_decoded = CoseMessage.decode(msg)

    assert "Custom-Header-Attr1" in msg_decoded.phdr
    assert "Custom-Header-Attr2" in msg_decoded.uhdr

    msg = MacMessage(phdr={
        Algorithm: HMAC256,
        "Custom-Header-Attr1": 7879
    },
                     uhdr={
                         KID: 8,
                         IV: unhexlify(b'00000000000000000000000000'),
                         "Custom-Header-Attr2": 878
                     },
                     recipients=[
                         DirectEncryption(uhdr={
                             Algorithm: Direct,
                             "Custom-Header-Attr3": 9999
                         })
                     ])
    msg.key = SymmetricKey.generate_key(key_len=16)

    assert "Custom-Header-Attr1" in msg.phdr
    assert "Custom-Header-Attr2" in msg.uhdr
    assert "Custom-Header-Attr3" in msg.recipients[0].uhdr

    msg = msg.encode()

    msg_decoded = CoseMessage.decode(msg)
    assert "Custom-Header-Attr1" in msg_decoded.phdr
    assert "Custom-Header-Attr2" in msg_decoded.uhdr
    assert "Custom-Header-Attr3" in msg_decoded.recipients[0].uhdr

    msg = SignMessage(phdr={"Custom-Header-Attr1": 7879},
                      uhdr={
                          KID: 8,
                          IV: unhexlify(b'00000000000000000000000000'),
                          "Custom-Header-Attr2": 878
                      },
                      signers=[
                          CoseSignature(phdr={
                              Algorithm: Es256,
                              "Custom-Header-Attr3": 9999
                          },
                                        key=EC2Key.generate_key(crv=P256))
                      ])

    assert "Custom-Header-Attr1" in msg.phdr
    assert "Custom-Header-Attr2" in msg.uhdr

    msg = msg.encode()

    msg_decoded = CoseMessage.decode(msg)

    assert "Custom-Header-Attr1" in msg_decoded.phdr
    assert "Custom-Header-Attr2" in msg_decoded.uhdr
    assert "Custom-Header-Attr3" in msg_decoded.signers[0].phdr

    msg = Sign1Message(phdr={
        Algorithm: Es256,
        "Custom-Header-Attr1": 7879
    },
                       uhdr={
                           KID: 8,
                           "Custom-Header-Attr2": 878
                       })
    msg.key = EC2Key.generate_key(crv=P256)

    assert "Custom-Header-Attr1" in msg.phdr
    assert "Custom-Header-Attr2" in msg.uhdr

    msg = msg.encode()

    msg_decoded = CoseMessage.decode(msg)
    assert "Custom-Header-Attr1" in msg_decoded.phdr
    assert "Custom-Header-Attr2" in msg_decoded.uhdr
コード例 #10
0
    def test(self):
        print('\nTest: ' + __name__ + '.' + type(self).__name__)
        private_key = EC2Key(
            crv=curves.P256,
            x=binascii.unhexlify(
                '44c1fa63b84f172b50541339c50beb0e630241ecb4eebbddb8b5e4fe0a1787a8'
            ),
            y=binascii.unhexlify(
                '059451c7630d95d0b550acbd02e979b3f4f74e645b74715fafbc1639960a0c7a'
            ),
            d=binascii.unhexlify(
                'dd6e7d8c4c0e0c0bd3ae1b4a2fa86b9a09b7efee4a233772cf5189786ea63842'
            ),
            optional_params={
                keyparam.KpKid: b'ExampleEC2',
                keyparam.KpKeyOps: [keyops.DeriveKeyOp],
            })
        print('Private Key: {}'.format(
            encode_diagnostic(cbor2.loads(private_key.encode()))))
        # 256-bit content encryption key
        cek = SymmetricKey(k=binascii.unhexlify(
            '13BF9CEAD057C0ACA2C9E52471CA4B19DDFAF4C0784E3F3E8E3999DBAE4CE45C'
        ),
                           optional_params={
                               keyparam.KpKid:
                               b'ExampleCEK',
                               keyparam.KpKeyOps:
                               [keyops.EncryptOp, keyops.DecryptOp],
                           })
        print('CEK: {}'.format(encode_diagnostic(cbor2.loads(cek.encode()))))
        # session IV
        iv = binascii.unhexlify('6F3093EBA5D85143C3DC484A')
        print('IV: {}'.format(binascii.hexlify(iv)))

        # Would be random ephemeral key, but test constant
        sender_key = EC2Key(
            crv=curves.P256,
            x=binascii.unhexlify(
                'fedaba748882050d1bef8ba992911898f554450952070aeb4788ca57d1df6bcc'
            ),
            y=binascii.unhexlify(
                'ceaa8e7ff4751a4f81c70e98f1713378b0bd82a1414a2f493c1c9c0670f28d62'
            ),
            d=binascii.unhexlify(
                'a2e4ed4f2e21842999b0e9ebdaad7465efd5c29bd5761f5c20880f9d9c3b122a'
            ),
        )
        print('Sender Private Key: {}'.format(
            encode_diagnostic(cbor2.loads(sender_key.encode()))))
        sender_public = EC2Key(crv=sender_key.crv,
                               x=sender_key.x,
                               y=sender_key.y)

        # Primary block
        prim_dec = self._get_primary_item()
        prim_enc = cbor2.dumps(prim_dec)
        print('Primary Block: {}'.format(encode_diagnostic(prim_dec)))
        print('Encoded: {}'.format(encode_diagnostic(prim_enc)))

        # Security target block
        target_dec = self._get_target_item()
        content_plaintext = target_dec[4]
        print('Target Block: {}'.format(encode_diagnostic(target_dec)))
        print('Plaintext: {}'.format(encode_diagnostic(content_plaintext)))

        # Combined AAD
        ext_aad_dec = self._get_aad_item()
        ext_aad_enc = cbor2.dumps(ext_aad_dec)
        print('External AAD: {}'.format(encode_diagnostic(ext_aad_dec)))
        print('Encoded: {}'.format(encode_diagnostic(ext_aad_enc)))

        msg_obj = EncMessage(
            phdr={
                headers.Algorithm: algorithms.A256GCM,
            },
            uhdr={
                headers.IV: iv,
            },
            payload=content_plaintext,
            recipients=[
                KeyAgreementWithKeyWrap(
                    uhdr={
                        headers.Algorithm: algorithms.EcdhEsA256KW,
                        headers.KID: private_key.kid,
                        headers.EphemeralKey: sender_public,
                    },
                    payload=cek.k,
                ),
            ],
            # Non-encoded parameters
            external_aad=ext_aad_enc,
        )
        recip = msg_obj.recipients[0]
        recip.key = sender_key
        recip.local_attrs = {
            headers.StaticKey: private_key,
        }

        # COSE internal structure
        cose_struct_enc = msg_obj._enc_structure
        cose_struct_dec = cbor2.loads(cose_struct_enc)
        print('COSE Structure: {}'.format(encode_diagnostic(cose_struct_dec)))
        print('Encoded: {}'.format(encode_diagnostic(cose_struct_enc)))

        # Encoded message
        message_enc = msg_obj.encode(tag=False)
        message_dec = cbor2.loads(message_enc)
        # Detach the payload
        content_ciphertext = message_dec[2]
        message_dec[2] = None
        self._print_message(message_dec, recipient_idx=3)
        print('Ciphertext: {}'.format(encode_diagnostic(content_ciphertext)))
        message_enc = cbor2.dumps(message_dec)

        # ASB structure
        asb_dec = self._get_asb_item([msg_obj.cbor_tag, message_enc])
        asb_enc = self._get_asb_enc(asb_dec)
        print('ASB: {}'.format(encode_diagnostic(asb_dec)))
        print('Encoded: {}'.format(encode_diagnostic(asb_enc)))

        bpsec_dec = self._get_bpsec_item(
            block_type=BlockType.BCB,
            asb_dec=asb_dec,
        )
        bpsec_enc = cbor2.dumps(bpsec_dec)
        print('BPSec block: {}'.format(encode_diagnostic(bpsec_dec)))
        print('Encoded: {}'.format(encode_diagnostic(bpsec_enc)))

        # Change from detached payload
        message_dec[2] = content_ciphertext
        decode_obj = EncMessage.from_cose_obj(message_dec)
        decode_obj.external_aad = ext_aad_enc

        recip = decode_obj.recipients[0]
        recip.key = private_key
        decode_plaintext = decode_obj.decrypt(recipient=recip)
        print('Loopback plaintext:', encode_diagnostic(decode_plaintext))
        self.assertEqual(content_plaintext, decode_plaintext)

        print('Loopback CEK:',
              encode_diagnostic(cbor2.loads(decode_obj.key.encode())))
        self.assertEqual(cek.k, decode_obj.key.k)

        target_dec[4] = content_ciphertext
        target_enc = cbor2.dumps(target_dec)
        bundle = self._assemble_bundle([prim_enc, bpsec_enc, target_enc])
        print('Total bundle: {}'.format(encode_diagnostic(bundle)))
コード例 #11
0
    def test(self):
        print('\nTest: ' + __name__ + '.' + type(self).__name__)
        # 1024-bit key
        private_key = RSAKey(
            n=binascii.unhexlify(
                b'b0b5fd85f52c91844007443c9f9371980025f76d51fc9c67681231da610cb291ba637ce813bffdb2e9c653258607389ec97dad3db295fded67744ed620707db36804e74e56a494030a73608fc8d92f2f0578d2d85cc201ef0ff22d7835d2d147d3b90a6884276235a01c2be99dfc597f79554362fc1eb03639cac5ccaddb2925'
            ),
            e=binascii.unhexlify(b'010001'),
            d=binascii.unhexlify(
                b'9b5d26ad6445ef1aab80b809e4f329684e9912d556c4166f041d1b1fb93c04b4037ffd0dbe6f8a8a86e70bab6e0f6344983a9ada27ed9ff7de816fdeeb5e7be48e607ce5fda4581ca6338a9e019fb3689b28934192b6a190cdda910abb5a86a2f7b6f9cd5011049d8de52ddfef73aa06df401c55623ec196720f54920deb4f01'
            ),
            p=binascii.unhexlify(
                b'db22d94e7784a27b568cbf985307ea8d6430ff6b88c18a7086fd4f57a326572f2250c39e48a6f8e2201661c2dfe12c7386835b649714d050aa36123ec3d00e75'
            ),
            q=binascii.unhexlify(
                b'ce7016adc5f326b7520397c5978ee2f50e69279983d54c5d76f05bcd61de0879d7056c923540dff9cbae95dcc0e5e86b52b3c902dc9669c8021c69557effb9f1'
            ),
            dp=binascii.unhexlify(
                b'6a6fcaccea106a3b2e16bf18e57b7ad9a2488a4758ed68a8af686a194f0d585b7477760c738d6665aee0302bcf4237ad0530d83b4b86b887f5a4bdc7eea427e1'
            ),
            dq=binascii.unhexlify(
                b'28a4cae245b1dcb285142e027a1768b9c4af915b59285a93a0422c60e05edd9e57663afd023d169bd0ad3bd62da8563d231840802ebbf271ad70b8905ba3af91'
            ),
            qinv=binascii.unhexlify(
                b'07b5a61733896270a6bd2bb1654194c54e2bc0e061b543a4ed9fa73c4bc79c87148aa92a451c4ab8262b6377a9c7b97f869160ca6f5d853ee4b65f4f92865ca3'
            ),
            optional_params={
                keyparam.KpKid: b'ExampleRSA',
                keyparam.KpKeyOps: [keyops.WrapOp, keyops.UnwrapOp],
            })
        print('Private Key: {}'.format(
            encode_diagnostic(cbor2.loads(private_key.encode()))))
        # 256-bit content encryption key
        cek = SymmetricKey(k=binascii.unhexlify(
            '13BF9CEAD057C0ACA2C9E52471CA4B19DDFAF4C0784E3F3E8E3999DBAE4CE45C'
        ),
                           optional_params={
                               keyparam.KpKid:
                               b'ExampleCEK',
                               keyparam.KpKeyOps:
                               [keyops.EncryptOp, keyops.DecryptOp],
                           })
        print('CEK: {}'.format(encode_diagnostic(cbor2.loads(cek.encode()))))
        # session IV
        iv = binascii.unhexlify('6F3093EBA5D85143C3DC484A')
        print('IV: {}'.format(binascii.hexlify(iv)))

        # Primary block
        prim_dec = self._get_primary_item()
        prim_enc = cbor2.dumps(prim_dec)
        print('Primary Block: {}'.format(encode_diagnostic(prim_dec)))
        print('Encoded: {}'.format(encode_diagnostic(prim_enc)))

        # Security target block
        target_dec = self._get_target_item()
        content_plaintext = target_dec[4]
        print('Target Block: {}'.format(encode_diagnostic(target_dec)))
        print('Plaintext: {}'.format(encode_diagnostic(content_plaintext)))

        # Combined AAD
        ext_aad_dec = self._get_aad_item()
        ext_aad_enc = cbor2.dumps(ext_aad_dec)
        print('External AAD: {}'.format(encode_diagnostic(ext_aad_dec)))
        print('Encoded: {}'.format(encode_diagnostic(ext_aad_enc)))

        msg_obj = EncMessage(
            phdr={
                headers.Algorithm: algorithms.A256GCM,
            },
            uhdr={
                headers.IV: iv,
            },
            payload=content_plaintext,
            recipients=[
                KeyWrap(
                    uhdr={
                        headers.Algorithm: algorithms.RsaesOaepSha256,
                        headers.KID: private_key.kid,
                    },
                    payload=cek.k,
                ),
            ],
            # Non-encoded parameters
            external_aad=ext_aad_enc,
        )
        msg_obj.recipients[0].key = private_key

        # COSE internal structure
        cose_struct_enc = msg_obj._enc_structure
        cose_struct_dec = cbor2.loads(cose_struct_enc)
        print('COSE Structure: {}'.format(encode_diagnostic(cose_struct_dec)))
        print('Encoded: {}'.format(encode_diagnostic(cose_struct_enc)))

        # Encoded message
        message_enc = msg_obj.encode(tag=False)
        message_dec = cbor2.loads(message_enc)
        # Detach the payload
        content_ciphertext = message_dec[2]
        message_dec[2] = None
        self._print_message(message_dec, recipient_idx=3)
        print('Ciphertext: {}'.format(encode_diagnostic(content_ciphertext)))
        message_enc = cbor2.dumps(message_dec)

        # ASB structure
        asb_dec = self._get_asb_item([msg_obj.cbor_tag, message_enc])
        asb_enc = self._get_asb_enc(asb_dec)
        print('ASB: {}'.format(encode_diagnostic(asb_dec)))
        print('Encoded: {}'.format(encode_diagnostic(asb_enc)))

        bpsec_dec = self._get_bpsec_item(
            block_type=BlockType.BCB,
            asb_dec=asb_dec,
        )
        bpsec_enc = cbor2.dumps(bpsec_dec)
        print('BPSec block: {}'.format(encode_diagnostic(bpsec_dec)))
        print('Encoded: {}'.format(encode_diagnostic(bpsec_enc)))

        # Change from detached payload
        message_dec[2] = content_ciphertext
        decode_obj = EncMessage.from_cose_obj(message_dec)
        decode_obj.external_aad = ext_aad_enc

        recip = decode_obj.recipients[0]
        recip.key = private_key
        decode_plaintext = decode_obj.decrypt(recipient=recip)
        print('Loopback plaintext:', encode_diagnostic(decode_plaintext))
        self.assertEqual(content_plaintext, decode_plaintext)

        print('Loopback CEK:',
              encode_diagnostic(cbor2.loads(decode_obj.key.encode())))
        self.assertEqual(cek.k, decode_obj.key.k)

        target_dec[4] = content_ciphertext
        target_enc = cbor2.dumps(target_dec)
        bundle = self._assemble_bundle([prim_enc, bpsec_enc, target_enc])
        print('Total bundle: {}'.format(encode_diagnostic(bundle)))