Esempio n. 1
0
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
Esempio n. 2
0
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
Esempio n. 3
0
    def from_dict(cls, cose_key: dict) -> 'OKPKey':
        """
        Returns an initialized COSE Key object of type OKPKey.

        :param cose_key: Dictionary containing COSE Key parameters and there values.

        :return: an initialized OKPKey key
        """
        _optional_params = {}

        # extract and remove items from dict, if not found return default value
        x = CoseKey._extract_from_dict(cose_key, OKPKpX)
        d = CoseKey._extract_from_dict(cose_key, OKPKpD)
        curve = CoseKey._extract_from_dict(cose_key, OKPKpCurve, None)

        _optional_params.update(cose_key)
        CoseKey._remove_from_dict(_optional_params, OKPKpX)
        CoseKey._remove_from_dict(_optional_params, OKPKpD)
        CoseKey._remove_from_dict(_optional_params, OKPKpCurve)

        return cls(crv=curve,
                   x=x,
                   d=d,
                   optional_params=_optional_params,
                   allow_unknown_key_attrs=True)
Esempio n. 4
0
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')
Esempio n. 5
0
    def from_dict(cls, cose_key: dict) -> 'SymmetricKey':
        """
        Returns an initialized COSE Key object of type SymmetricKey.

        :param cose_key: Dict containing COSE Key parameters and their values.

        :return: an initialized COSE SymmetricKey object
        """
        _optional_params = {}

        k = CoseKey._extract_from_dict(cose_key, SymKpK)

        _optional_params.update(cose_key)
        CoseKey._remove_from_dict(_optional_params, SymKpK)

        return cls(k=k,
                   optional_params=_optional_params,
                   allow_unknown_key_attrs=True)
Esempio n. 6
0
def test_encrypt0_decoding(test_encrypt0):
    test_input = test_encrypt0['input']
    test_output = test_encrypt0['output']

    msg = CoseMessage.decode(cbor2.dumps(test_output['result']))

    assert msg.phdr == test_input['protected']
    assert msg.uhdr == test_input['unprotected']

    key = CoseKey.from_dict(test_encrypt0["cek"])
    key.key_ops = [DecryptOp]
    msg.key = key

    assert msg.decrypt() == test_input['plaintext']
Esempio n. 7
0
def test_encrypt0_decoding(test_mac0):
    test_input = test_mac0['input']
    test_output = test_mac0['output']

    msg = CoseMessage.decode(cbor2.dumps(test_output['result']))
    msg.external_aad = test_input['external_aad']

    key = CoseKey.from_dict(test_mac0["cek"])
    key.key_ops = [MacVerifyOp]
    msg.key = key

    assert msg.phdr == test_input['protected']
    assert msg.uhdr == test_input['unprotected']

    assert msg.verify_tag()
Esempio n. 8
0
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
Esempio n. 9
0
def test_sign1_decoding(test_sign1):
    test_input = test_sign1['input']
    test_output = test_sign1['output']

    msg = CoseMessage.decode(cbor2.dumps(test_output['result']))
    msg.external_aad = test_input['external_aad']

    key = CoseKey.from_dict(test_sign1["cek"])
    key.key_ops = [VerifyOp]
    msg.key = key

    assert msg.phdr == test_input['protected']
    assert msg.uhdr == test_input['unprotected']

    assert msg.verify_signature()
Esempio n. 10
0
def test_encrypt_direct_encryption_decoding(test_encrypt_direct_encryption_files):
    test_output = test_encrypt_direct_encryption_files['output']
    test_input = test_encrypt_direct_encryption_files['input']

    msg = CoseMessage.decode(cbor2.dumps((test_output['result'])))

    key = CoseKey.from_dict(test_encrypt_direct_encryption_files["cek"])
    key.key_ops = [DecryptOp]

    msg.key = key

    assert msg.phdr == test_input['protected']
    assert msg.uhdr == test_input['unprotected']

    for r in msg.recipients:
        assert msg.decrypt(r) == test_input['plaintext']
Esempio n. 11
0
    def _parse_credentials(
        cred: Union[CBOR, Callable]
    ) -> Tuple[Union[CBOR, Callable], Union[Key, Callable]]:
        if isinstance(cred, bytes):

            if isinstance(cbor2.loads(cred), dict):
                # this is an RPK
                cose_key = CoseKey.decode(cbor2.loads(cred))
                return cred, cose_key

            else:
                # TODO: update when test vectors for CBOR encoded certificates are correct
                return cred, None
        else:

            return cred, cred
Esempio n. 12
0
def test_mac_direct_encryption_decoding(test_mac_direct_encryption_files):
    test_output = test_mac_direct_encryption_files['output']
    test_input = test_mac_direct_encryption_files['input']

    msg = CoseMessage.decode(cbor2.dumps((test_output['result'])))
    msg.external_aad = test_input['external_aad']

    key = CoseKey.from_dict(test_mac_direct_encryption_files["cek"])
    key.key_ops = [MacVerifyOp]

    msg.key = key

    assert msg.phdr == test_input['protected']
    assert msg.uhdr == test_input['unprotected']

    for r in msg.recipients:
        assert msg.verify_tag(r)
Esempio n. 13
0
def test_encrypt_direct_encryption_encoding(test_encrypt_direct_encryption_files):
    test_input = test_encrypt_direct_encryption_files['input']
    test_output = test_encrypt_direct_encryption_files['output']

    recipients = _setup_direct_encryption_recipients(test_input['recipients'])

    msg = EncMessage(test_input['protected'], test_input['unprotected'], test_input['plaintext'], recipients=recipients)

    key = CoseKey.from_dict(test_encrypt_direct_encryption_files["cek"])
    key.key_ops = [EncryptOp]

    msg.key = key

    assert msg.phdr_encoded == test_output['protected']
    assert msg.uhdr_encoded == test_output['unprotected']

    assert msg._enc_structure == test_output['structure']

    assert cbor2.loads(msg.encode()) == test_output['result']
Esempio n. 14
0
def test_mac0_encoding(test_mac0):
    test_input = test_mac0['input']
    test_output = test_mac0['output']

    msg = Mac0Message(phdr=test_input['protected'],
                      uhdr=test_input['unprotected'],
                      payload=test_input['plaintext'],
                      external_aad=test_input['external_aad'])

    assert msg.phdr_encoded == test_output['protected']
    assert msg.uhdr_encoded == test_output['unprotected']

    assert msg._mac_structure == test_output['structure']

    key = CoseKey.from_dict(test_mac0["cek"])
    key.key_ops = [MacCreateOp, MacVerifyOp]
    msg.key = key

    assert msg.compute_tag() == test_output['tag']
    assert cbor2.loads(
        msg.encode(tag=test_mac0['cbor_tag'])) == test_output['result']
Esempio n. 15
0
def test_encrypt0_encoding(test_encrypt0):
    test_input = test_encrypt0['input']
    test_output = test_encrypt0['output']

    msg = Enc0Message(
        phdr=test_input['protected'],
        uhdr=test_input['unprotected'],
        payload=test_input['plaintext'],
        external_aad=test_input['external_aad'])

    assert msg.phdr_encoded == test_output['protected']
    assert msg.uhdr_encoded == test_output['unprotected']

    assert msg._enc_structure == test_output['structure']

    key = CoseKey.from_dict(test_encrypt0["cek"])
    key.key_ops = [EncryptOp, DecryptOp]
    msg.key = key

    assert msg.encrypt() == test_output['ciphertext']
    assert cbor2.loads(msg.encode()) == test_output['result']
Esempio n. 16
0
def test_sign1_encoding(test_sign1):
    test_input = test_sign1['input']
    test_output = test_sign1['output']

    msg = Sign1Message(phdr=test_input['protected'],
                       uhdr=test_input['unprotected'],
                       payload=test_input['plaintext'],
                       external_aad=test_input['external_aad'])

    assert msg.phdr_encoded == test_output['protected']
    assert msg.uhdr_encoded == test_output['unprotected']

    assert msg._sig_structure == test_output['structure']

    key = CoseKey.from_dict(test_sign1["cek"])
    key.key_ops = [SignOp, VerifyOp]
    msg.key = key

    assert msg.compute_signature() == test_output['signature']
    assert cbor2.loads(
        msg.encode(tag=test_sign1['cbor_tag'])) == test_output['result']
Esempio n. 17
0
def test_encrypt0_round_trip(test_encrypt0):
    test_input = test_encrypt0['input']
    test_output = test_encrypt0['output']

    key = CoseKey.from_dict(test_encrypt0["cek"])
    key.key_ops = [DecryptOp, EncryptOp]

    msg = Enc0Message(
        phdr=test_input['protected'],
        uhdr=test_input['unprotected'],
        payload=test_input['plaintext'],
        external_aad=test_input['external_aad'],
        key=key)

    assert msg.encrypt() == test_output['ciphertext']
    assert cbor2.loads(msg.encode()) == test_output['result']

    msg = msg.encode()
    msg = CoseMessage.decode(msg)
    msg.key = key

    assert msg.decrypt() == test_input['plaintext']
Esempio n. 18
0
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(
Esempio n. 19
0
    # 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']
                  )
Esempio n. 20
0
    def from_dict(cls, cose_key: dict) -> 'RSAKey':
        """
        Returns an initialized COSE Key object of type RSAKey.

        :param cose_key: Dict containing COSE Key parameters and there values.
        :return: an initialized RSAKey key
        """
        _optional_params = {}

        e = CoseKey._extract_from_dict(cose_key, RSAKpE)
        n = CoseKey._extract_from_dict(cose_key, RSAKpN)
        d = CoseKey._extract_from_dict(cose_key, RSAKpD)
        p = CoseKey._extract_from_dict(cose_key, RSAKpP)
        q = CoseKey._extract_from_dict(cose_key, RSAKpQ)
        dp = CoseKey._extract_from_dict(cose_key, RSAKpDP)
        dq = CoseKey._extract_from_dict(cose_key, RSAKpDQ)
        qinv = CoseKey._extract_from_dict(cose_key, RSAKpQInv)
        other = CoseKey._extract_from_dict(cose_key, RSAKpOther, [])
        r_i = CoseKey._extract_from_dict(cose_key, RSAKpRi)
        d_i = CoseKey._extract_from_dict(cose_key, RSAKpDi)
        t_i = CoseKey._extract_from_dict(cose_key, RSAKpTi)

        _optional_params.update(cose_key)
        CoseKey._remove_from_dict(_optional_params, RSAKpE)
        CoseKey._remove_from_dict(_optional_params, RSAKpN)
        CoseKey._remove_from_dict(_optional_params, RSAKpD)
        CoseKey._remove_from_dict(_optional_params, RSAKpP)
        CoseKey._remove_from_dict(_optional_params, RSAKpQ)
        CoseKey._remove_from_dict(_optional_params, RSAKpDP)
        CoseKey._remove_from_dict(_optional_params, RSAKpDQ)
        CoseKey._remove_from_dict(_optional_params, RSAKpQInv)
        CoseKey._remove_from_dict(_optional_params, RSAKpOther)
        CoseKey._remove_from_dict(_optional_params, RSAKpQInv)
        CoseKey._remove_from_dict(_optional_params, RSAKpRi)
        CoseKey._remove_from_dict(_optional_params, RSAKpDi)
        CoseKey._remove_from_dict(_optional_params, RSAKpTi)

        return cls(e=e,
                   n=n,
                   d=d,
                   p=p,
                   q=q,
                   dp=dp,
                   dq=dq,
                   qinv=qinv,
                   other=other,
                   r_i=r_i,
                   d_i=d_i,
                   t_i=t_i,
                   optional_params=_optional_params,
                   allow_unknown_key_attrs=True)
Esempio n. 21
0
def test_cosekey_decode(encoded_key_obj):
    key = CoseKey.decode(encoded_key_obj)
    assert type(key) == EC2
    assert key.kty == KTY.EC2
    assert key.crv == CoseEllipticCurves.P_256