def setup_ec_receiver_keys(recipient: dict, received_key_obj) -> Tuple[EC2, EC2]: alg = recipient.get("protected", {}).get(CoseHeaderKeys.ALG) if alg is None: alg = recipient.get("unprotected", {}).get(CoseHeaderKeys.ALG) rcvr_static_key = EC2( kid=recipient['key'][CoseKey.Common.KID], crv=recipient['key'][EC2.EC2Prm.CRV], alg=alg, x=CoseKey.base64decode(recipient['key'][EC2.EC2Prm.X]), y=CoseKey.base64decode(recipient['key'][EC2.EC2Prm.Y]), d=CoseKey.base64decode(recipient['key'][EC2.EC2Prm.D]), ) # create CoseKey object for the sender key if 'sender_key' in recipient: sender_key = EC2( alg=alg, crv=recipient["sender_key"][EC2.EC2Prm.CRV], x=CoseKey.base64decode(recipient['sender_key'][EC2.EC2Prm.X]), y=CoseKey.base64decode(recipient['sender_key'][EC2.EC2Prm.Y])) else: sender_key = received_key_obj return rcvr_static_key, sender_key
def create_cose_key( key_type: Type[CoseKey], input_data: dict, alg: Optional[CoseAlgorithms] = None, usage: Optional[KeyOps] = None) -> Union[EC2, SymmetricKey, OKP]: if key_type == EC2: key = EC2( kid=input_data.get(CoseKey.Common.KID), key_ops=usage, alg=alg, crv=input_data.get(EC2.EC2Prm.CRV), x=CoseKey.base64decode(input_data.get(EC2.EC2Prm.X)), y=CoseKey.base64decode(input_data.get(EC2.EC2Prm.Y)), d=CoseKey.base64decode(input_data.get(EC2.EC2Prm.D)), ) elif key_type == SymmetricKey: key = SymmetricKey(kid=input_data.get(CoseKey.Common.KID), alg=alg, key_ops=usage, k=CoseKey.base64decode( input_data.get(SymmetricKey.SymPrm.K))) elif key_type == OKP: key = OKP( kid=input_data.get(CoseKey.Common.KID), alg=alg, key_ops=usage, crv=input_data.get(OKP.OKPPrm.CRV), x=unhexlify(input_data.get(OKP.OKPPrm.X)), d=unhexlify(input_data.get(OKP.OKPPrm.D)), ) else: raise Exception return key
def test_encrypt_hkdf_hmac_direct_decode( setup_encrypt_hkdf_hmac_direct_tests: tuple) -> None: _, test_input, test_output, test_intermediate, fail = setup_encrypt_hkdf_hmac_direct_tests # parse message and test for headers md: EncMessage = CoseMessage.decode(unhexlify(test_output)) assert md.phdr == extract_phdr(test_input, 'enveloped') assert md.uhdr == extract_uhdr(test_input, 'enveloped', 0) # check for external data and verify internal _enc_structure md.external_aad = unhexlify(test_input['enveloped'].get('external', b'')) assert md._enc_structure == unhexlify(test_intermediate['AAD_hex']) recipient = test_input['enveloped']['recipients'][0] assert md.recipients[0].phdr == recipient.get('protected', {}) # create HKDF contect v = PartyInfo( identity=md.recipients[0].uhdr.get(CoseHeaderKeys.PARTY_V_IDENTITY), nonce=md.recipients[0].uhdr.get(CoseHeaderKeys.PARTY_V_NONCE), other=md.recipients[0].uhdr.get(CoseHeaderKeys.PARTY_V_OTHER)) u = PartyInfo( identity=md.recipients[0].uhdr.get(CoseHeaderKeys.PARTY_U_IDENTITY), nonce=md.recipients[0].uhdr.get(CoseHeaderKeys.PARTY_U_NONCE), other=md.recipients[0].uhdr.get(CoseHeaderKeys.PARTY_U_OTHER)) public_data = test_input['enveloped']['recipients'][0].get( 'unsent', {}).get('pub_other') s = SuppPubInfo( len(test_intermediate['CEK_hex']) * 4, md.recipients[0].encode_phdr(), public_data.encode('utf-8') if public_data is not None else public_data) priv_data = test_input['enveloped']['recipients'][0].get('unsent', {}).get( 'priv_other', b'') hkdf_context = CoseKDFContext( md.phdr[CoseHeaderKeys.ALG], u, v, s, priv_data.encode('utf-8') if priv_data != b'' else priv_data) assert hkdf_context.encode() == unhexlify( test_intermediate["recipients"][0]['Context_hex']) # set shared secret key shared_secret = SymmetricKey( k=CoseKey.base64decode(test_input['enveloped']['recipients'][0]['key'][ SymmetricKey.SymPrm.K])) kek = md.recipients[0].derive_kek( shared_secret, alg=md.recipients[0].phdr[CoseHeaderKeys.ALG], context=hkdf_context, salt=md.recipients[0].uhdr.get(CoseHeaderKeys.SALT)) assert kek == unhexlify(test_intermediate["CEK_hex"]) cek = SymmetricKey(k=kek, alg=extract_alg(test_input['enveloped'])) assert md.decrypt(key=cek, nonce=extract_nonce( test_input, 0)) == test_input['plaintext'].encode('utf-8')
def _fix_header_algorithm_names(data: dict, key) -> None: try: header_dict = data[key] except KeyError: return temp = None if "epk" in header_dict: _fix_key_object(header_dict, "epk") temp = header_dict["epk"] if EC2.EC2Prm.X in temp and isinstance(temp[EC2.EC2Prm.X], str): temp[EC2.EC2Prm.X] = CoseKey.base64decode(temp[EC2.EC2Prm.X]) if EC2.EC2Prm.Y in temp and isinstance(temp[EC2.EC2Prm.Y], str): temp[EC2.EC2Prm.Y] = CoseKey.base64decode(temp[EC2.EC2Prm.Y]) del header_dict["epk"] header_dict = { k: (v if v not in algs_to_be_replaced else algs_to_be_replaced[v]) for k, v in header_dict.items() } if temp is not None: header_dict[CoseHeaderKeys.EPHEMERAL_KEY] = temp data[key] = header_dict
# set the key and decode the message key.key_ops = KeyOps.DECRYPT assert decoded.decrypt(key=key, nonce=original.uhdr[CoseHeaderKeys.IV]) == payload @mark.parametrize("phdr, uhdr, alg, key1, key2, nonce, expected", [ ({CoseHeaderKeys.ALG: CoseAlgorithms.AES_CCM_16_64_128}, {CoseHeaderKeys.IV: unhexlify(b'89F52F65A1C580933B5261A72F')}, None, SymmetricKey( kid=b'our-secret', alg=CoseAlgorithms.AES_CCM_16_64_128, key_ops=KeyOps.ENCRYPT, k=CoseKey.base64decode("hJtXIZ2uSN5kbQfbtTNWbg")), None, unhexlify("89F52F65A1C580933B5261A72F"), b'6899DA0A132BD2D2B9B10915743EE1F7B92A4680E7C51BDBC1B320EA',), ({CoseHeaderKeys.ALG: CoseAlgorithms.AES_CCM_16_64_128}, {}, CoseAlgorithms.AES_CCM_16_64_128, SymmetricKey( kid=b'our-secret', key_ops=KeyOps.ENCRYPT, k=CoseKey.base64decode("hJtXIZ2uSN5kbQfbtTNWbg")), None, unhexlify(b'89F52F65A1C580933B5261A72F'), b'6899DA0A132BD2D2B9B10915743EE1F7B92A4680E7C51BDBC1B320EA',), ], ids=['standalone_encryption_1', 'standalone_encryption_2'] )
from binascii import unhexlify from pytest import mark as m from cose import OKP from cose.attributes.algorithms import CoseAlgorithms, CoseEllipticCurves from cose.attributes.context import CoseKDFContext, PartyInfo, SuppPubInfo from cose.keys.cosekey import CoseKey, KTY, KeyOps from cose.keys.ec2 import EC2 from cose.keys.symmetric import SymmetricKey @m.parametrize("crv, x, y, expected", [ (CoseEllipticCurves.P_256, CoseKey.base64decode("Ze2loSV3wrroKUN_4zhwGhCqo3Xhu1td4QjeQ5wIVR0"), CoseKey.base64decode("HlLtdXARY_f55A3fnzQbPcm6hgr34Mp8p-nuzQCE0Zw"), { 1: 2, -1: 1, -2: unhexlify( b'98F50A4FF6C05861C8860D13A638EA56C3F5AD7590BBFBF054E1C7B4D91D6280' ), -3: unhexlify( b'F01400B089867804B8E9FC96C3932161F1934F4223069170D924B7E03BF822BB' ) }), (CoseEllipticCurves.P_521, CoseKey.base64decode(