Esempio n. 1
0
    def __init__(self, cred_idr, cred, auth_key):
        super().__init__()
        # test with static connection identifier and static ephemeral key

        self.ephemeral_key = OKP(
            crv=CoseEllipticCurves.X25519,
            x=unhexlify(
                "71a3d599c21da18902a1aea810b2b6382ccd8d5f9bf0195281754c5ebcaf301e"
            ),
            d=unhexlify(
                "fd8cd877c9ea386e6af34ff7e606c4b64ca831c8ba33134fd4cd7167cabaecda"
            ))

        self.cred_idr = cred_idr
        self.cred = cred
        self.auth_key = auth_key
        self.supported = [
            CipherSuite.SUITE_0, CipherSuite.SUITE_1, CipherSuite.SUITE_2,
            CipherSuite.SUITE_3
        ]

        self.resp = self.create_responder()

        with open(self.cred_store, 'rb') as h:
            self.credentials_storage = pickle.load(h)
Esempio n. 2
0
    def remote_pubkey(self) -> Key:
        """ Returns the remote ephemeral public key. """

        if self.cipher_suite.dh_curve in [CoseEllipticCurves.X448, CoseEllipticCurves.X25519]:
            return OKP(x=self.g_x, crv=self.cipher_suite.dh_curve)
        else:
            # TODO: implement NIST curves
            pass
Esempio n. 3
0
def setup_dh_key(selected_cipher: int, private_bytes: bytes):
    if CipherSuite(selected_cipher).dh_curve in [
            CoseEllipticCurves.X448, CoseEllipticCurves.X25519
    ]:
        return OKP(d=private_bytes, crv=CipherSuite(selected_cipher).dh_curve)
    elif CipherSuite(selected_cipher).dh_curve in [CoseEllipticCurves.P_256]:
        return EC2(d=private_bytes,
                   crv=CipherSuite(selected_cipher).sign_curve)
    else:
        raise ValueError("Illegal DH keys.")
Esempio n. 4
0
    def local_pubkey(self) -> Key:
        """ Returns the local ephemeral public key. """

        if self.cipher_suite.dh_curve in [
                CoseEllipticCurves.X448, CoseEllipticCurves.X25519
        ]:
            return OKP(x=self.g_x, crv=self.cipher_suite.dh_curve)
        else:
            # TODO:
            pass
Esempio n. 5
0
def setup_sign_key(selected_cipher: int, private_bytes: bytes):
    if CipherSuite(selected_cipher).sign_curve in [
            CoseEllipticCurves.ED448, CoseEllipticCurves.ED25519
    ]:
        return OKP(d=private_bytes,
                   crv=CipherSuite(selected_cipher).sign_curve,
                   alg=CipherSuite(selected_cipher).sign_alg)
    elif CipherSuite(selected_cipher).sign_alg == CoseAlgorithms.ES256:
        return EC2(d=private_bytes,
                   alg=CoseAlgorithms.ES256,
                   crv=CipherSuite(selected_cipher).sign_curve)
    else:
        raise ValueError("Illegal signing keys.")
def test_initiator_message3(initiator, test_vectors):
    initiator.msg_1 = MessageOne.decode(test_vectors['I']['message_1'])
    initiator.msg_2 = MessageTwo.decode(test_vectors['R']['message_2'])

    crv = CoseEllipticCurves(CipherSuite(initiator._selected_cipher).dh_curve)
    hash_func = config_cose(CipherSuite(initiator._selected_cipher).hash).hash

    assert initiator.data_2 == test_vectors['R']['data_2']
    assert initiator._th2_input == test_vectors['R']['input_th_2']
    assert initiator._prk2e == test_vectors['R']['prk_2e']
    assert initiator._prk3e2m == test_vectors['R']['prk_3e2m']
    assert initiator.transcript(
        hash_func, initiator._th2_input) == test_vectors['R']['th_2']

    assert initiator._decrypt(
        initiator.msg_2.ciphertext) == test_vectors['R']['p_2e']

    assert initiator.shared_secret(initiator.ephemeral_key,
                                   OKP(x=initiator.g_y,
                                       crv=crv)) == test_vectors['S']['g_xy']
    assert initiator.data_3 == test_vectors['I']['data_3']
    assert initiator._th3_input == test_vectors['I']['input_th_3']
    assert initiator.transcript(
        hash_func, initiator._th3_input) == test_vectors['I']['th_3']
    assert initiator.cred_id == test_vectors['I']['id_cred']
    assert initiator._prk4x3m == test_vectors['I']['prk_4x3m']
    assert initiator._external_aad(
        initiator._th3_input,
        initiator.aad3_cb) == test_vectors['I']['eaad_3m']
    assert initiator._hkdf3(16, 'K_3m',
                            initiator._prk4x3m) == test_vectors['I']['k_3m']
    assert initiator._hkdf3(13, 'IV_3m',
                            initiator._prk4x3m) == test_vectors['I']['iv_3m']
    assert initiator._mac(initiator._hkdf3, 'K_3m', 16, 'IV_3m', 13,
                          initiator._th3_input, initiator._prk4x3m,
                          initiator.aad2_cb) == test_vectors['I']['mac3']
    assert initiator.signature_or_mac3(
        test_vectors['I']['mac3']) == test_vectors['I']['sign_or_mac3']
    assert initiator._p_3ae == test_vectors['I']['p_3ae']
    assert initiator._hkdf3(16, 'K_3ae',
                            initiator._prk3e2m) == test_vectors['I']['k_3ae']
    assert initiator._hkdf3(13, 'IV_3ae',
                            initiator._prk3e2m) == test_vectors['I']['iv_3ae']
    assert initiator.ciphertext_3 == test_vectors['I']['ciphertext_3']

    assert initiator.create_message_three(
        test_vectors['R']['message_2']) == test_vectors['I']['message_3']
def test_responder_message2(responder, test_vectors):
    responder.msg_1 = MessageOne.decode(test_vectors['I']['message_1'])

    hash_func = config_cose(CipherSuite(
        responder.msg_1.selected_cipher).hash).hash
    crv = CoseEllipticCurves(
        CipherSuite(responder.msg_1.selected_cipher).dh_curve)

    assert responder.shared_secret(responder.ephemeral_key,
                                   OKP(x=responder.g_x,
                                       crv=crv)) == test_vectors['S']['g_xy']
    assert responder._prk2e == test_vectors['R']['prk_2e']
    assert responder._prk3e2m == test_vectors['R']['prk_3e2m']
    assert responder.data_2 == test_vectors['R']['data_2']
    assert responder._th2_input == test_vectors['R']['input_th_2']
    assert responder.cred_id == test_vectors['R']['id_cred']
    assert responder.transcript(
        hash_func, responder._th2_input) == test_vectors['R']['th_2']
    assert responder._external_aad(
        responder._th2_input,
        responder.aad2_cb) == test_vectors['R']['eaad_2m']
    assert responder._hkdf2(
        16, 'K_2m', prk=responder._prk3e2m) == test_vectors['R']['k_2m']
    assert responder._hkdf2(
        13, 'IV_2m', prk=responder._prk3e2m) == test_vectors['R']['iv_2m']
    assert responder._mac(responder._hkdf2, 'K_2m', 16, 'IV_2m', 13,
                          responder._th2_input, responder._prk3e2m,
                          responder.aad2_cb) == test_vectors['R']['mac2']
    assert responder.signature_or_mac2(
        test_vectors['R']['mac2']) == test_vectors['R']['sign_or_mac2']
    assert responder._p_2e == test_vectors['R']['p_2e']
    assert responder._hkdf2(len(responder._p_2e), 'K_2e',
                            prk=responder._prk2e) == test_vectors['R']['k_2e']
    assert responder.ciphertext_2 == test_vectors['R']['ciphertext_2']

    assert responder.create_message_two(
        test_vectors['I']['message_1']) == test_vectors['R']['message_2']
Esempio n. 8
0
    def _generate_ephemeral_key(self) -> None:
        """
        Generate a new ephemeral key if the key was not already set.

        :return: None
        """

        if self.ephemeral_key is not None:
            return

        chosen_suite = CipherSuite(self.cipher_suite)

        if chosen_suite.dh_curve in [
                CoseEllipticCurves.X25519, CoseEllipticCurves.X448
        ]:
            self.ephemeral_key = OKP.generate_key(
                CoseAlgorithms.DIRECT,
                curve_type=chosen_suite.dh_curve,
                key_ops=KeyOps.SIGN)
        else:
            self.ephemeral_key = EC2.generate_key(
                CoseAlgorithms.DIRECT,
                curve_type=chosen_suite.dh_curve,
                key_ops=KeyOps.SIGN)
Esempio n. 9
0
async def main():
    parser = argparse.ArgumentParser()

    # 51.75.194.248
    parser.add_argument("ip", help="IP address of EDHOC responder", type=str)
    parser.add_argument("--epk",
                        help="Use a preset ephemeral key",
                        action="store_true")

    args = parser.parse_args()

    context = await Context.create_client_context()

    supported = [CipherSuite.SUITE_0]

    if args.epk:
        ephemeral_key = OKP(
            crv=CoseEllipticCurves.X25519,
            x=unhexlify(
                "898ff79a02067a16ea1eccb90fa52246f5aa4dd6ec076bba0259d904b7ec8b0c"
            ),
            d=unhexlify(
                "8f781a095372f85b6d9f6109ae422611734d7dbfa0069a2df2935bb2e053bf35"
            ))
    else:
        ephemeral_key = None

    init = Initiator(corr=Correlation.CORR_1,
                     method=Method.SIGN_SIGN,
                     conn_idi=unhexlify(b''),
                     cred_idi=cred_id,
                     auth_key=private_key,
                     cred=cert,
                     peer_cred=get_peer_cred,
                     supported_ciphers=supported,
                     selected_cipher=CipherSuite.SUITE_0,
                     ephemeral_key=ephemeral_key)

    msg_1 = init.create_message_one()
    # assert msg_1 == unhexlify(b"01005820898ff79a02067a16ea1eccb90fa52246f5aa4dd6ec076bba0259d904b7ec8b0c40")

    request = Message(code=Code.POST,
                      payload=msg_1,
                      uri=f"coap://{args.ip}/.well-known/edhoc")

    logging.info("POST (%s)  %s", init.edhoc_state, request.payload)
    response = await context.request(request).response

    logging.info("CHANGED (%s)  %s", init.edhoc_state, response.payload)
    msg_3 = init.create_message_three(response.payload)
    # assert msg_3 == unhexlify(_msg_3)

    logging.info("POST (%s)  %s", init.edhoc_state, request.payload)
    request = Message(code=Code.POST,
                      payload=msg_3,
                      uri=f"coap://{args.ip}/.well-known/edhoc")
    response = await context.request(request).response

    conn_idi, conn_idr, aead, hashf = init.finalize()

    logging.info('EDHOC key exchange successfully completed:')
    logging.info(f" - connection IDr: {conn_idr}")
    logging.info(f" - connection IDi: {conn_idi}")
    logging.info(f" - aead algorithm: {CoseAlgorithms(aead)}")
    logging.info(f" - hash algorithm: {CoseAlgorithms(hashf)}")

    logging.info(
        f" - OSCORE secret : {init.exporter('OSCORE Master Secret', 16)}")
    logging.info(
        f" - OSCORE salt   : {init.exporter('OSCORE Master Salt', 8)}")
Esempio n. 10
0
from aiocoap.numbers.codes import Code
from cose import CoseEllipticCurves, CoseAlgorithms, OKP, CoseHeaderKeys

from edhoc.definitions import CipherSuite, Correlation, Method
from edhoc.roles.edhoc import CoseHeaderMap
from edhoc.roles.initiator import Initiator

logging.basicConfig(level=logging.INFO)

_msg_3 = b'1358582d88ff86da47482c0dfa559ac824a4a783d870c9dba47805e8aafbad6974c49646586503fa9bbf3e00012c037eaf56e45' \
         b'e301920839b813a53f6d4c557480f6c797d5b76f0e462f5f57a3db6d2b50c32319f340f4ac5af9a'

# private signature key
private_key = OKP(
    crv=CoseEllipticCurves.ED25519,
    alg=CoseAlgorithms.EDDSA,
    d=unhexlify(
        "2ffce7a0b2b825d397d0cb54f746e3da3f27596ee06b5371481dc0e012bc34d7"))

# certificate (should contain the pubkey but is just a random string)
cert = "5865fa34b22a9ca4a1e12924eae1d1766088098449cb848ffc795f88afc49cbe8afdd1ba009f21675e8f6c77a4a2c30195601f6f0a" \
       "0852978bd43d28207d44486502ff7bdda632c788370016b8965bdb2074bff82e5a20e09bec21f8406e86442b87ec3ff245b7"

cert = unhexlify(cert)

cred_id = cbor2.loads(unhexlify(b"a11822822e485b786988439ebcf2"))

with open("cred_store.pickle", 'rb') as h:
    credentials_storage = pickle.load(h)

Esempio n. 11
0
def ephemeral_initiator_key(test_vectors):
    return OKP(x=test_vectors['I']['g_x'],
               d=test_vectors['I']['x'],
               crv=CipherSuite(test_vectors['I']['selected']).dh_curve)
Esempio n. 12
0
def ephemeral_responder_key(test_vectors):
    return OKP(x=test_vectors['R']['g_y'],
               d=test_vectors['R']['y'],
               crv=CipherSuite(test_vectors['I']['selected']).dh_curve)
Esempio n. 13
0
from edhoc.definitions import CipherSuite, EdhocState
from edhoc.exceptions import EdhocException
from edhoc.roles.edhoc import CoseHeaderMap
from edhoc.roles.responder import Responder

logging.basicConfig(level=logging.INFO)
logging.getLogger("coap-server").setLevel(logging.INFO)

_msg_2 = b"582071a3d599c21da18902a1aea810b2b6382ccd8d5f9bf0195281754c5ebcaf301e13585099d53801a725bfd6a4e71d0484b755e" \
         b"c383df77a916ec0dbc02bba7c21a200807b4f585f728b671ad678a43aacd33b78ebd566cd004fc6f1d406f01d9704e705b21552a9" \
         b"eb28ea316ab65037d717862e"

# private signature key
private_key = OKP(
    crv=CoseEllipticCurves.ED25519,
    alg=CoseAlgorithms.EDDSA,
    d=unhexlify(
        "df69274d713296e246306365372b4683ced5381bfcadcd440a24c391d2fedb94"))

# certificate (should contain the pubkey but is just a random string)
cert = "586e47624dc9cdc6824b2a4c52e95ec9d6b0534b71c2b49e4bf9031500cee6869979c297bb5a8b381e98db714108415e5c50db78974c" \
       "271579b01633a3ef6271be5c225eb28f9cf6180b5a6af31e80209a085cfbf95f3fdcf9b18b693d6c0e0d0ffb8e3f9a32a50859ecd0bf" \
       "cff2c218"
cert = unhexlify(cert)

cred_id = cbor2.loads(unhexlify(b"a11822822e48fc79990f2431a3f5"))


class EdhocResponder(resource.Resource):
    cred_store = "cred_store.pickle"
Esempio n. 14
0
def test_okp_key_generation():
    key = OKP.generate_key(CoseAlgorithms.EDDSA, KeyOps.SIGN,
                           CoseEllipticCurves.X25519)
    assert isinstance(key, OKP)