Ejemplo n.º 1
0
def test_session():
    initiator = RLPxSession(ECCx(raw_privkey=mk_privkey('secret1')),
                            is_initiator=True)
    initiator_pubk = initiator.ecc.raw_pubkey
    responder = RLPxSession(ECCx(raw_privkey=mk_privkey('secret2')))
    responder_pubk = responder.ecc.raw_pubkey

    auth_msg = initiator.create_auth_message(remote_pubkey=responder_pubk)
    auth_msg_ct = initiator.encrypt_auth_message(auth_msg, responder_pubk)

    responder.decode_authentication(auth_msg_ct)
    auth_ack_msg = responder.create_auth_ack_message()
    auth_ack_msg_ct = responder.encrypt_auth_ack_message(
        auth_ack_msg, initiator_pubk)

    initiator.decode_auth_ack_message(auth_ack_msg_ct)

    initiator.setup_cipher()
    responder.setup_cipher()

    assert responder.ecdhe_shared_secret == initiator.ecdhe_shared_secret
    assert responder.token == initiator.token
    assert responder.aes_secret == initiator.aes_secret
    assert responder.mac_secret == initiator.mac_secret

    assert responder.egress_mac.digest() == initiator.ingress_mac.digest()
    assert responder.egress_mac.digest() == initiator.ingress_mac.digest()
    assert responder.ingress_mac.digest() == initiator.egress_mac.digest()
    assert responder.ingress_mac.digest() == initiator.egress_mac.digest()
    assert responder.mac_secret == initiator.mac_secret

    return initiator, responder
Ejemplo n.º 2
0
def test_auth_ack_is_eip8_for_eip8_auth():
    responder = RLPxSession(ECCx(raw_privkey=eip8_values['key_b']))
    responder.decode_authentication(eip8_handshakes[1]['auth'])
    assert responder.got_eip8_auth

    ack = responder.create_auth_ack_message(version=55)
    ack_ct = responder.encrypt_auth_ack_message(ack)

    initiator = RLPxSession(ECCx(raw_privkey=eip8_values['key_a']),
                            is_initiator=True)
    initiator.decode_auth_ack_message(ack_ct)
    assert initiator.got_eip8_ack
    assert initiator.remote_version == 55
Ejemplo n.º 3
0
def test_ecies_decrypt():
    tv = test_values
    from devp2p.crypto import ECCx
    e = ECCx(raw_privkey=tv['receiver_private_key'])
    _dec = e.ecies_decrypt(tv['auth_ciphertext'])
    assert len(_dec) == len(tv['auth_plaintext'])
    assert _dec == tv['auth_plaintext']
Ejemplo n.º 4
0
def test_pyelliptic_sig():
    priv_seed = 'test'
    priv_key = mk_privkey(priv_seed)
    my_pubkey = privtopub(priv_key)
    e = ECCx(my_pubkey, priv_key)
    msg = 'a'
    s = pyelliptic.ECC.sign(e, msg)
    assert s == pyelliptic.ECC.sign(e, msg)  # deterministic
Ejemplo n.º 5
0
 def __init__(self,
              ecc,
              is_initiator=False,
              token_by_pubkey=dict(),
              ephemeral_privkey=None):
     self.ecc = ecc
     self.is_initiator = is_initiator
     self.token_by_pubkey = token_by_pubkey
     self.ephemeral_ecc = ECCx(raw_privkey=ephemeral_privkey)
Ejemplo n.º 6
0
def test_pyelliptic_sig():
    priv_seed = 'test'
    priv_key = mk_privkey(priv_seed)
    my_pubkey = privtopub(priv_key)
    e = ECCx(raw_privkey=priv_key)
    msg = 'a'
    s = pyelliptic.ECC.sign(e, msg)
    s2 = pyelliptic.ECC.sign(e, msg)
    assert s != s2  # non deterministic
Ejemplo n.º 7
0
def test_eip8_handshake_messages():
    initiator = RLPxSession(ECCx(raw_privkey=eip8_values['key_a']),
                            is_initiator=True)
    responder = RLPxSession(ECCx(raw_privkey=eip8_values['key_b']))
    for handshake in eip8_handshakes:
        ack_rest = initiator.decode_auth_ack_message(handshake['ack'])
        assert initiator.remote_ephemeral_pubkey == eip8_values['eph_pub_b']
        assert initiator.responder_nonce == eip8_values['nonce_b']
        assert initiator.got_eip8_ack == handshake['eip8_format']
        assert initiator.remote_version == handshake['ack_version']
        assert ack_rest == b''

        auth_rest = responder.decode_authentication(handshake['auth'])
        assert responder.remote_ephemeral_pubkey == eip8_values['eph_pub_a']
        assert responder.initiator_nonce == eip8_values['nonce_a']
        assert responder.remote_pubkey == eip8_values['pub_a']
        assert responder.got_eip8_auth == handshake['eip8_format']
        assert auth_rest == b''
Ejemplo n.º 8
0
 def __init__(self, app):
     super(RNOService, self).__init__(app)
     log.info('Initializing RNO')
     self.config = app.config
     self.interrupt = Event()
     self.tx_queue = Queue()  # thread safe
     self.privkey_hex = self.config['eth']['privkey_hex'].decode('hex')
     self.my_addr = privtoaddr(self.privkey_hex)
     self.eccx = ECCx(None, self.privkey_hex)
Ejemplo n.º 9
0
    def create_auth_message(self,
                            remote_pubkey,
                            token=None,
                            ephemeral_privkey=None,
                            nonce=None):
        """
        1. initiator generates ecdhe-random and nonce and creates auth
        2. initiator connects to remote and sends auth

        New:
        E(remote-pubk,
            S(ephemeral-privk, ecdh-shared-secret ^ nonce) ||
            H(ephemeral-pubk) || pubk || nonce || 0x0
        )
        Known:
        E(remote-pubk,
            S(ephemeral-privk, token ^ nonce) || H(ephemeral-pubk) || pubk || nonce || 0x1)
        """

        if not token:  # new
            ecdh_shared_secret = self.node.get_ecdh_key(remote_pubkey)
            token = ecdh_shared_secret
            flag = 0x0
        else:
            flag = 0x1

        nonce = nonce or ienc(random.randint(0, 2**256 - 1))
        assert len(nonce) == 32

        token_xor_nonce = sxor(token, nonce)
        assert len(token_xor_nonce) == 32

        # generate session ephemeral key
        if not ephemeral_privkey:
            ephemeral_privkey = sha3(ienc(random.randint(0, 2**256 - 1)))

        self.ephemeral_ecc = ECCx(raw_privkey=ephemeral_privkey)
        ephemeral_pubkey = self.ephemeral_ecc.raw_pubkey

        assert len(ephemeral_pubkey) == 512 / 8
        # S(ephemeral-privk, ecdh-shared-secret ^ nonce)
        S = self.ephemeral_ecc.sign(token_xor_nonce)
        assert len(S) == 65

        # S || H(ephemeral-pubk) || pubk || nonce || 0x0
        auth_message = S + sha3(
            ephemeral_pubkey) + self.node.raw_pubkey + nonce + chr(flag)
        assert len(auth_message) == 65 + 32 + 64 + 32 + 1 == 194
        return auth_message
Ejemplo n.º 10
0
def test_eip8_key_derivation():
    responder = RLPxSession(ECCx(raw_privkey=eip8_values['key_b']),
                            ephemeral_privkey=eip8_values['eph_key_b'])
    responder.decode_authentication(eip8_handshakes[1]['auth'])
    ack = responder.create_auth_ack_message(nonce=eip8_values['nonce_b'])
    responder.encrypt_auth_ack_message(ack)

    responder.setup_cipher()
    want_aes_secret = decode_hex(
        b'80e8632c05fed6fc2a13b0f8d31a3cf645366239170ea067065aba8e28bac487')
    want_mac_secret = decode_hex(
        b'2ea74ec5dae199227dff1af715362700e989d889d7a493cb0639691efb8e5f98')
    assert responder.aes_secret == want_aes_secret
    assert responder.mac_secret == want_mac_secret

    responder.ingress_mac.update(b'foo')
    mac_digest = responder.ingress_mac.digest()
    want_mac_digest = decode_hex(
        b'0c7ec6340062cc46f5e9f1e3cf86f8c8c403c5a0964f5df0ebd34a75ddc86db5')
    assert mac_digest == want_mac_digest
Ejemplo n.º 11
0
 def __init__(self, ecc, is_initiator=False, ephemeral_privkey=None):
     self.ecc = ecc
     self.is_initiator = is_initiator
     self.ephemeral_ecc = ECCx(raw_privkey=ephemeral_privkey)
def test_handshake():
    tv = test_values

    initiator = RLPxSession(ECCx(raw_privkey=tv['initiator_private_key']),
                            is_initiator=True,
                            ephemeral_privkey=tv['initiator_ephemeral_private_key'])
    initiator_pubkey = initiator.ecc.raw_pubkey
    responder = RLPxSession(ECCx(raw_privkey=tv['receiver_private_key']),
                            ephemeral_privkey=tv['receiver_ephemeral_private_key'])
    responder_pubkey = responder.ecc.raw_pubkey

    # test encryption
    _enc = initiator.encrypt_auth_message(tv['auth_plaintext'], responder_pubkey)
    assert len(_enc) == len(tv['auth_ciphertext'])
    assert len(tv['auth_ciphertext']) == 113 + len(tv['auth_plaintext'])  # len

    # test auth_msg plain
    auth_msg = initiator.create_auth_message(remote_pubkey=responder_pubkey,
                                             ephemeral_privkey=tv['initiator_ephemeral_private_key'],
                                             nonce=tv['initiator_nonce'])

    # test auth_msg plain
    assert len(auth_msg) == len(tv['auth_plaintext']) == 194
    assert auth_msg[65:] == tv['auth_plaintext'][65:]  # starts with non deterministic k

    _auth_msg_cipher = initiator.encrypt_auth_message(auth_msg, responder_pubkey)

    # test shared
    responder.ecc.get_ecdh_key(initiator_pubkey) == \
        initiator.ecc.get_ecdh_key(responder_pubkey)

    # test decrypt
    assert auth_msg == responder.ecc.ecies_decrypt(_auth_msg_cipher)

    # check receive
    responder_ephemeral_pubkey = privtopub(tv['receiver_ephemeral_private_key'])
    auth_msg_cipher = tv['auth_ciphertext']
    auth_msg = responder.ecc.ecies_decrypt(auth_msg_cipher)
    assert auth_msg[65:] == tv['auth_plaintext'][65:]  # starts with non deterministic k

    responder.decode_authentication(auth_msg_cipher)
    auth_ack_msg = responder.create_auth_ack_message(responder_ephemeral_pubkey, nonce=tv['receiver_nonce'])
    assert auth_ack_msg == tv['authresp_plaintext']
    auth_ack_msg_cipher = responder.encrypt_auth_ack_message(auth_ack_msg, remote_pubkey=responder.remote_pubkey)

    # set auth ack msg cipher (needed later for mac calculation)
    responder.auth_ack = tv['authresp_ciphertext']

    responder.setup_cipher()
    assert responder.ecdhe_shared_secret == tv['ecdhe_shared_secret']
    assert len(responder.token) == len(tv['token'])
    assert responder.token == tv['token']
    assert responder.aes_secret == tv['aes_secret']
    assert responder.mac_secret == tv['mac_secret']

    assert responder.initiator_nonce == tv['initiator_nonce']
    assert responder.responder_nonce == tv['receiver_nonce']

    assert responder.auth_init == tv['auth_ciphertext']
    assert responder.auth_ack == tv['authresp_ciphertext']

    # test values are from initiator perspective?
    assert responder.ingress_mac.digest() == tv['initial_egress_MAC']
    assert responder.ingress_mac.digest() == tv['initial_egress_MAC']
    assert responder.egress_mac.digest() == tv['initial_ingress_MAC']
    assert responder.egress_mac.digest() == tv['initial_ingress_MAC']

    r = responder.decrypt(tv['initiator_hello_packet'])

    # unpack hello packet
    import struct
    import rlp
    import rlp.sedes as sedes
    from rlp.codec import consume_item

    header = r['header']
    frame_length = struct.unpack(b'>I', b'\x00' + header[:3])[0]

    header_sedes = sedes.List([sedes.big_endian_int, sedes.big_endian_int])
    header_data = rlp.decode(header[3:], strict=False, sedes=header_sedes)
    print('header', repr(header_data))

    # frame
    frame = r['frame']

    # normal: rlp(packet-type) [|| rlp(packet-data)] || padding
    packet_type, end = consume_item(frame, start=0)
    packet_type = rlp.decode(frame, sedes=sedes.big_endian_int, strict=False)
    print('packet_type', repr(packet_type))

    # decode hello body
    _sedes_capabilites_tuple = sedes.List([sedes.binary, sedes.big_endian_int])

    structure = [
        ('version', sedes.big_endian_int),
        ('client_version_string', sedes.big_endian_int),
        ('capabilities', sedes.CountableList(_sedes_capabilites_tuple)),
        ('listen_port', sedes.big_endian_int),
        ('remote_pubkey', sedes.binary)
    ]

    hello_sedes = sedes.List([x[1] for x in structure])
    frame_data = rlp.decode(frame[end:], sedes=hello_sedes)
    frame_data = dict((structure[i][0], x) for i, x in enumerate(frame_data))
    print('frame', frame_data)
Ejemplo n.º 13
0
 def __init__(self, privkey):
     self.ecc = ECCx(raw_privkey=privkey)