Example #1
0
def initiator(ephemeral_initiator_key, test_vectors):
    if test_vectors['I']['cred_type'] == 0:
        local_auth_key = None
        local_cred = cbor2.loads(test_vectors['I']['cred'])
    else:
        local_auth_key = CoseKey.decode(test_vectors['I']['cred'])
        local_cred = CoseKey.decode(test_vectors['I']['cred'])

    if test_vectors['R']['cred_type'] == 0:
        remote_auth_key = None
        remote_cred = cbor2.loads(test_vectors['R']['cred'])
    else:
        remote_auth_key = CoseKey.decode(test_vectors['R']['cred'])
        remote_cred = CoseKey.decode(test_vectors['R']['cred'])

    return Initiator(
        corr=test_vectors['S']['corr'],
        method=test_vectors['S']['method'],
        cred=(local_cred, local_auth_key),
        cred_idi=cbor2.loads(test_vectors['I']['cred_id']),
        auth_key=CoseKey.decode(test_vectors['I']['auth_key']),
        selected_cipher=test_vectors['I']['selected'],
        supported_ciphers=[CipherSuite.from_id(c) for c in test_vectors["I"]["supported"]],
        conn_idi=test_vectors['I']['conn_id'],
        remote_cred_cb=lambda x: (remote_cred, remote_auth_key),
        ephemeral_key=ephemeral_initiator_key,
    )
def add_kid(kid_b64, key_b64):
    kid = b64decode(kid_b64)
    asn1data = b64decode(key_b64)

    pub = serialization.load_der_public_key(asn1data)
    if (isinstance(pub, RSAPublicKey)):
        kids[kid_b64] = CoseKey.from_dict({
            KpKty:
            KtyRSA,
            KpAlg:
            Ps256,  # RSSASSA-PSS-with-SHA-256-and-MFG1
            RSAKpE:
            int_to_bytes(pub.public_numbers().e),
            RSAKpN:
            int_to_bytes(pub.public_numbers().n)
        })
    elif (isinstance(pub, EllipticCurvePublicKey)):
        kids[kid_b64] = CoseKey.from_dict({
            KpKty:
            KtyEC2,
            EC2KpCurve:
            P256,  # Ought o be pk.curve - but the two libs clash
            KpAlg:
            Es256,  # ecdsa-with-SHA256
            EC2KpX:
            pub.public_numbers().x.to_bytes(32, byteorder="big"),
            EC2KpY:
            pub.public_numbers().y.to_bytes(32, byteorder="big")
        })
    else:
        print(
            f"Skipping unexpected/unknown key type (keyid={kid_b64}, {pub.__class__.__name__}).",
            file=sys.stderr)
Example #3
0
def test_dict_valid_deletion():
    cose_key = {
        KpKty: KtyEC2,
        EC2KpD: p256_d,
        EC2KpX: p256_x,
        EC2KpY: p256_y,
        KpAlg: Es256,
        EC2KpCurve: P256,
        KpKeyOps: [SignOp]
    }

    key = CoseKey.from_dict(cose_key)
    del key[KpAlg]
    assert KpAlg not in key

    key = CoseKey.from_dict(cose_key)
    del key[3]
    assert KpAlg not in key

    key = CoseKey.from_dict(cose_key)
    del key[EC2KpD]
    assert EC2KpD not in key

    key = CoseKey.from_dict(cose_key)
    del key[-4]
    assert EC2KpD not in key

    key = CoseKey.from_dict(cose_key)
    del key[EC2KpY]
    assert EC2KpY not in key
    assert EC2KpX not in key
Example #4
0
def test_fail_on_missing_symkpk():
    cose_key = {KpKty: KtySymmetric, KpAlg: A128GCM}

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

    assert "SymKpK parameter cannot be None" in str(excinfo.value)
Example #5
0
def responder(ephemeral_responder_key, test_vectors):
    if test_vectors['R']['cred_type'] == 0:
        local_cred = cbor2.loads(test_vectors['R']['cred'])
        local_auth_key = None
    else:
        local_cred = CoseKey.decode(test_vectors['R']['cred'])
        local_auth_key = CoseKey.decode(test_vectors['R']['cred'])

    if test_vectors['I']['cred_type'] == 0:
        remote_cred = cbor2.loads(test_vectors['I']['cred'])
        remote_auth_key = None
    else:
        remote_cred = CoseKey.decode(test_vectors['I']['cred'])
        remote_auth_key = CoseKey.decode(test_vectors['I']['cred'])

    responder = Responder(
        conn_idr=test_vectors["R"]["conn_id"],
        cred_idr=cbor2.loads(test_vectors['R']['cred_id']),
        auth_key=CoseKey.decode(test_vectors['R']['auth_key']),
        cred=(local_cred, local_auth_key),
        supported_ciphers=[
            CipherSuite.from_id(c) for c in test_vectors["R"]["supported"]
        ],
        remote_cred_cb=lambda arg: (remote_cred, remote_auth_key),
        ephemeral_key=ephemeral_responder_key)
    responder.cred_idi = test_vectors['I']['cred_id']
    return responder
Example #6
0
def test_fail_on_missing_symkpk():
    cose_key = {KpKty: KtySymmetric, KpAlg: A128GCM}

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

    assert "COSE Symmetric Key must have an SymKpK attribute" in str(
        excinfo.value)
Example #7
0
def test_fail_on_missing_symmetric_kty(length):
    cose_key = {SymKpK: os.urandom(length)}

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

    assert "Could not decode CoseKey type, KpKty not set or unknown." in str(
        excinfo.value)
Example #8
0
def _dsc(config_env: Dict):
    if TEST_CONTEXT in config_env.keys(
    ) and CERTIFICATE in config_env[TEST_CONTEXT].keys():
        cert_code = config_env[TEST_CONTEXT][CERTIFICATE]
        x = y = e = n = None
        cert = x509.load_pem_x509_certificate(
            f'-----BEGIN CERTIFICATE-----\n{cert_code}\n-----END CERTIFICATE-----'
            .encode())

        fingerprint = cert.fingerprint(SHA256())
        keyid = fingerprint[0:8]

        if isinstance(cert.public_key(), rsa.RSAPublicKey):
            e = int_to_bytes(cert.public_key().public_numbers().e)
            n = int_to_bytes(cert.public_key().public_numbers().n)
        elif isinstance(cert.public_key(), ec.EllipticCurvePublicKey):
            x = int_to_bytes(cert.public_key().public_numbers().x)
            y = int_to_bytes(cert.public_key().public_numbers().y)
        else:
            raise Exception(
                f'Unsupported Certificate Algorithm: {cert.signature_algorithm_oid} for verification.'
            )
        try:
            dsc_supported_operations = {
                eku.dotted_string
                for eku in cert.extensions.get_extension_for_class(
                    x509.ExtendedKeyUsage).value
            }
        except ExtensionNotFound:
            dsc_supported_operations = set()
        dsc_not_valid_before = cert.not_valid_before.replace(
            tzinfo=timezone.utc)
        dsc_not_valid_after = cert.not_valid_after.replace(tzinfo=timezone.utc)
        key = None
        if x and y:
            key = CoseKey.from_dict({
                KpKeyOps: [VerifyOp],
                KpKty: KtyEC2,
                EC2KpCurve:
                P256,  # Ought o be pk.curve - but the two libs clash
                KpAlg: Es256,  # ECDSA using P-256 and SHA-256
                EC2KpX: x,
                EC2KpY: y,
            })
        elif e and n:
            key = CoseKey.from_dict({
                KpKeyOps: [VerifyOp],
                KpKty: KtyRSA,
                KpAlg: Ps256,  # RSASSA-PSS using SHA-256 and MGF1 with SHA-256
                RSAKpE: e,
                RSAKpN: n,
            })
        return key, keyid, dsc_supported_operations, dsc_not_valid_before, dsc_not_valid_after
Example #9
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)
Example #10
0
def test_dict_valid_deletion():
    cose_key = {
        KpKty: KtySymmetric,
        SymKpK: os.urandom(16),
        KpAlg: A128GCM,
        KpKeyOps: [EncryptOp]
    }

    key = CoseKey.from_dict(cose_key)
    del key[KpAlg]
    assert KpAlg not in key

    key = CoseKey.from_dict(cose_key)
    del key[3]
    assert KpAlg not in key
Example #11
0
def test_okp_public_keys_from_dicts(kty_attr, kty_value, crv_attr, crv_value, x_attr, x_value):
    # The public and private values used in this test do not form a valid elliptic curve key,
    # but we don't care about that here

    d = {kty_attr: kty_value, crv_attr: crv_value, x_attr: x_value}
    cose_key = CoseKey.from_dict(d)
    assert _is_valid_okp_key(cose_key)
Example #12
0
def test_fail_on_missing_crv_attr():
    cose_key = {KpKty: KtyOKP, OKPKpX: os.urandom(32), OKPKpD: os.urandom(32)}

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

    assert "COSE curve cannot be None" in str(excinfo.value)
Example #13
0
def test_dict_operations_on_ec2_key():
    cose_key = {
        KpKty: KtyEC2,
        EC2KpX: p256_x,
        KpAlg: Es256,
        EC2KpCurve: P256,
        KpKeyOps: [SignOp]
    }

    key = CoseKey.from_dict(cose_key)

    assert KpKty in key
    assert EC2KpD not in key
    assert EC2KpY in key
    assert 1 in key
    assert 3 in key
    assert KpAlg in key
    assert 'ALG' in key

    del key['ALG']

    key['subject_name'] = 'verifying key'
    assert 'subject_name' in key

    assert 'ALG' not in key
Example #14
0
def test_fail_on_missing_crv_attr():
    cose_key = {KpKty: KtyEC2, EC2KpX: p256_x, EC2KpY: p256_y}

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

    assert "COSE curve cannot be None" in str(excinfo.value)
Example #15
0
def test_fail_on_missing_crv_attr():
    cose_key = {KpKty: KtyEC2, EC2KpX: os.urandom(32), EC2KpY: os.urandom(32)}

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

    assert "COSE EC2 Key must have an EC2KpCurve attribute" in str(excinfo.value)
Example #16
0
def test_fail_on_missing_key_values_from_dict(crv):
    d = {'KTY': 'EC2', 'CURVE': 'P_384'}

    with pytest.raises(CoseInvalidKey) as excinfo:
        _ = CoseKey.from_dict(d)

    assert "Either the public values or the private value must be specified" in str(excinfo.value)
Example #17
0
def test_simple_mac0message():
    msg = Mac0Message(
        phdr={Algorithm: HMAC256},
        uhdr={KID: b'kid3'},
        payload='authenticated message'.encode('utf-8'))

    assert str(msg) == "<COSE_Mac0: [{'Algorithm': 'HMAC256'}, {'KID': b'kid3'}, b'authe' ... (21 B), b'' ... (0 B)]>"

    cose_key = {
        KpKty: KtySymmetric,
        SymKpK: unhexlify(b'000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f'),
        KpKeyOps: [MacCreateOp, MacVerifyOp]}

    cose_key = CoseKey.from_dict(cose_key)
    assert str(cose_key) == "<COSE_Key(Symmetric): {'SymKpK': \"b'\\\\x00\\\\x01\\\\x02\\\\x03\\\\x04' ... (32 B)\", " \
                            "'KpKty': 'KtySymmetric', 'KpKeyOps': ['MacCreateOp', 'MacVerifyOp']}>"

    msg.key = cose_key
    # the encode() function automatically computes the authentication tag
    encoded = msg.encode()
    assert hexlify(encoded) == b'd18443a10105a104446b6964335561757468656e74696361746564206d657373616765582019f' \
                               b'6c7d8ddfeaceea6ba4f1cafb563cbf3be157653e29f3258b2957cf23f4e17'

    # decode and authenticate tag
    decoded = CoseMessage.decode(encoded)
    assert str(decoded) == "<COSE_Mac0: [{'Algorithm': 'HMAC256'}, {'KID': b'kid3'}, b'authe' ... (21 B), " \
                           "b'\\x19\\xf6\\xc7\\xd8\\xdd' ... (32 B)]>"

    decoded.key = cose_key
    assert hexlify(decoded.payload) == b'61757468656e74696361746564206d657373616765'

    assert hexlify(decoded.auth_tag) == b'19f6c7d8ddfeaceea6ba4f1cafb563cbf3be157653e29f3258b2957cf23f4e17'

    assert decoded.verify_tag()
Example #18
0
def test_simple_sign1message():
    msg = Sign1Message(
        phdr={Algorithm: EdDSA, KID: b'kid2'},
        payload='signed message'.encode('utf-8')
    )

    assert str(msg) == "<COSE_Sign1: [{'Algorithm': 'EdDSA', 'KID': b'kid2'}, {}, b'signe' ... (14 B), b'' ... (0 B)]>"

    cose_key = {
        KpKty: KtyOKP,
        OKPKpCurve: Ed25519,
        KpKeyOps: [SignOp, VerifyOp],
        OKPKpD: unhexlify(b'9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60'),
        OKPKpX: unhexlify(b'd75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a')}

    cose_key = CoseKey.from_dict(cose_key)
    assert str(cose_key) == "<COSE_Key(OKPKey): {'OKPKpD': \"b'\\\\x9da\\\\xb1\\\\x9d\\\\xef' ... (32 B)\"," \
                            " 'OKPKpX': \"b'\\\\xd7Z\\\\x98\\\\x01\\\\x82' ... (32 B)\"," \
                            " 'OKPKpCurve': 'Ed25519', 'KpKty': 'KtyOKP', 'KpKeyOps': ['SignOp', 'VerifyOp']}>"

    msg.key = cose_key
    encoded = msg.encode()
    assert hexlify(encoded) == b'd28449a2012704446b696432a04e7369676e6564206d6573736167655840cc87665ffd3' \
                               b'fa33d96f3b606fcedeaef839423221872d0bfa196e069a189a607c2284924c3abb80e94' \
                               b'2466cd300cc5d18fe4e5ea1f3ebdb62ef8419109447d03'

    decoded = CoseMessage.decode(encoded)
    assert str(decoded) == "<COSE_Sign1: [{'Algorithm': 'EdDSA', 'KID': b'kid2'}, {}, b'signe' ... (14 B), " \
                           "b'\\xcc\\x87f_\\xfd' ... (64 B)]>"

    decoded.key = cose_key
    assert decoded.verify_signature()
    assert decoded.payload == b'signed message'
Example #19
0
def test_okp_key_construction(crv):
    key = OKPKey(crv=crv, x=os.urandom(32), d=os.urandom(32), optional_params={'ALG': 'EDDSA'})

    assert _is_valid_okp_key(key)

    serialized = key.encode()
    _ = CoseKey.decode(serialized)
Example #20
0
def test_simple_enc0message():
    msg = Enc0Message(
        phdr={Algorithm: A128GCM, IV: b'000102030405060708090a0b0c'},
        uhdr={KID: b'kid1'},
        payload='some secret message'.encode('utf-8'))

    assert str(msg) == "<COSE_Encrypt0: [{'Algorithm': 'A128GCM', 'IV': \"b'00010' ... (26 B)\"}, {'KID': b'kid1'}, " \
                       "b'some ' ... (19 B)]>"

    cose_key = {
        KpKty: KtySymmetric,
        SymKpK: unhexlify(b'000102030405060708090a0b0c0d0e0f'),
        KpKeyOps: [EncryptOp, DecryptOp]}

    cose_key = CoseKey.from_dict(cose_key)
    assert str(cose_key) == "<COSE_Key(Symmetric): {'SymKpK': \"b'\\\\x00\\\\x01\\\\x02\\\\x03\\\\x04' ... (16 B)\", " \
                            "'KpKty': 'KtySymmetric', 'KpKeyOps': ['EncryptOp', 'DecryptOp']}>"

    msg.key = cose_key

    # the encode() function performs the encryption automatically
    encoded = msg.encode()
    assert hexlify(encoded) == b'd0835820a2010105581a3030303130323033303430353036303730383039306130623063a104446b696' \
                               b'4315823cca3441a2464d240e09fe9ee0ea42a7852a4f41d9945325c1f8d3b1353b8eb83e6a62f'

    # decode and decrypt
    decoded = CoseMessage.decode(encoded)

    decoded.key = cose_key
    assert hexlify(decoded.payload) == b'cca3441a2464d240e09fe9ee0ea42a7852a4f41d9945325c1f8d3b1353b8eb83e6a62f'

    assert decoded.decrypt() == b'some secret message'
Example #21
0
def test_symmetric_key_example2():
    simple_dict = {
        'KTY': KtySymmetric,
        'ALG': A128GCM,
        'K': unhexlify(b'000102030405060708090a0b0c0d0e0f')}

    cose_key = CoseKey.from_dict(simple_dict)

    # encode/serialize key
    serialized_key = cose_key.encode()
    assert str(serialized_key) == \
           str(b'\xa3\x01\x04\x03\x01 P\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f')

    assert str(CoseKey.decode(serialized_key)) == "<COSE_Key(Symmetric): " \
                                                  "{'SymKpK': \"b'\\\\x00\\\\x01\\\\x02\\\\x03\\\\x04' ... (16 B)\", " \
                                                  "'KpKty': 'KtySymmetric', 'KpAlg': 'A128GCM'}>"
Example #22
0
def test_okp_key_generation_encoding_decoding(crv):
    trails = 256

    for i in range(trails):
        okp_test = OKPKey.generate_key(crv=crv)
        okp_encoded = okp_test.encode()
        okp_decoded = CoseKey.decode(okp_encoded)
        assert _is_valid_okp_key(okp_decoded)
Example #23
0
def test_ec2_key_generation_encoding_decoding(crv):
    trails = 256

    for i in range(trails):
        ec2_test = EC2Key.generate_key(crv=crv)
        ec2_encoded = ec2_test.encode()
        ec2_decoded = CoseKey.decode(ec2_encoded)
        assert _is_valid_ec2_key(ec2_decoded)
Example #24
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)
Example #25
0
def test_ec2_public_keys_from_dicts(kty_attr, kty_value, crv_attr, crv_value,
                                    x_attr, x_value, y_attr, y_value):
    dct = {
        kty_attr: kty_value,
        crv_attr: crv_value,
        x_attr: x_value,
        y_attr: y_value
    }
    cose_key = CoseKey.from_dict(dct)
    assert _is_valid_ec2_key(cose_key)
Example #26
0
def test_existing_non_empty_keyops_list():
    cose_key = {
        KpKty: KtySymmetric,
        SymKpK: os.urandom(16),
        KpAlg: A128GCM,
        KpKeyOps: [EncryptOp]
    }

    key = CoseKey.from_dict(cose_key)

    assert KpKeyOps in key
Example #27
0
def test_remove_empty_keyops_list():
    cose_key = {
        KpKty: KtySymmetric,
        SymKpK: os.urandom(16),
        KpAlg: A128GCM,
        KpKeyOps: []
    }

    key = CoseKey.from_dict(cose_key)

    assert KpKeyOps not in key
Example #28
0
def test_dict_invalid_deletion():
    cose_key = {
        KpKty: KtySymmetric,
        SymKpK: os.urandom(16),
        KpAlg: A128GCM,
        KpKeyOps: [EncryptOp]
    }

    key = CoseKey.from_dict(cose_key)

    with pytest.raises(CoseInvalidKey) as excinfo:
        del key[KpKty]
Example #29
0
def test_dict_operations_on_okp_key():
    cose_key = {KpKty: KtyOKP, OKPKpD: os.urandom(16), KpAlg: EdDSA, OKPKpCurve: Ed448, KpKeyOps: [SignOp]}

    key = CoseKey.from_dict(cose_key)

    assert KpKty in key
    assert OKPKpD in key
    assert OKPKpX not in key
    assert 1 in key
    assert -4 in key
    assert KpAlg in key
    assert 'ALG' in key
Example #30
0
def test_dict_operations_on_symmetric_key():
    cose_key = {
        KpKty: KtySymmetric,
        SymKpK: os.urandom(16),
        KpAlg: A128GCM,
        KpKeyOps: [EncryptOp]
    }

    key = CoseKey.from_dict(cose_key)

    assert KpKty in key
    assert 3 in key