Example #1
0
 def to_endpoint(self):
     """
     struct Endpoint
     {
         unsigned network; // ipv4:4, ipv6:6
         unsigned transport; // tcp:6, udp:17
         unsigned address; // BE encoded 32-bit or 128-bit unsigned (layer3 address)
         unsigned port; // BE encoded 16-bit unsigned (layer4 port)
     }
     """
     transport = 6
     r = [utils.ienc(self._ip.version), utils.ienc(transport)]
     r += [self._ip.packed, utils.ienc(self.port)]
     return r
Example #2
0
 def to_endpoint(self):
     """
     struct Endpoint
     {
         unsigned network; // ipv4:4, ipv6:6
         unsigned transport; // tcp:6, udp:17
         unsigned address; // BE encoded 32-bit or 128-bit unsigned (layer3 address)
         unsigned port; // BE encoded 16-bit unsigned (layer4 port)
     }
     """
     transport = 6
     r = [utils.ienc(self._ip.version), utils.ienc(transport)]
     r += [self._ip.packed, struct.pack('>H', self.port)]
     return r
Example #3
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
Example #4
0
    def something():
        ##################

        # send authentication if not yet
        if not self._authentication_sent:
            remote_node = RemoteNode(remote_pubkey)  # FIXME LOOKUP
            self.send_authentication(remote_node)

            # - success -> AcknowledgeAuthentication
            self.acknowledge_authentication(other, remote_pubkey,
                                            remote_ecdhe_pubkey)

        # ecdhe_shared_secret = ecdh.agree(ecdhe-random, ecdhe-random-public)
        # Compute public key with the local private key and return a 512bits shared key
        ecdhe_shared_secret = self.ephemeral_ecc.get_ecdh_key(remote_pubkey)
        ecdhe_pubkey = self.ephemeral_ecc.get_pubkey()
        # shared-secret = sha3(ecdhe-shared-secret || sha3(nonce || remote-nonce))
        shared_secret = sha3(ecdhe_shared_secret +
                             sha3(ienc(self.nonce) + ienc(remote_nonce)))

        self.aes_secret = sha3(ecdhe_shared_secret + shared_secret)
        self.mac_secret = sha3(ecdhe_shared_secret + self.aes_secret)
        # egress-mac = sha3(mac-secret^nonce || auth)
        self.egress_mac = sha3(sxor(self.mac_secret, self.nonce) + ciphertext)
        # ingress-mac = sha3(mac-secret^remote-nonce || auth)
        self.ingress_mac = sha3(
            sxor(self.mac_secret, remote_nonce) + ciphertext)
        self.token = sha3(shared_secret)

        iv = pyelliptic.Cipher.gen_IV('aes-256-ctr')
        self.aes_enc = pyelliptic.Cipher(self.aes_secret,
                                         iv,
                                         1,
                                         ciphername='aes-256-ctr')
        self.aes_dec = pyelliptic.Cipher(self.aes_secret,
                                         iv,
                                         0,
                                         ciphername='aes-256-ctr')

        self.is_ready = True
Example #5
0
    def create_auth_message(self,
                            remote_pubkey,
                            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)
        """
        assert self.is_initiator
        if not self.ecc.is_valid_key(remote_pubkey):
            raise InvalidKeyError('invalid remote pubkey')
        self.remote_pubkey = remote_pubkey

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

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

        token_xor_nonce = sxor(token, self.initiator_nonce)
        assert len(token_xor_nonce) == 32

        ephemeral_pubkey = self.ephemeral_ecc.raw_pubkey
        assert len(ephemeral_pubkey) == 512 / 8
        if not self.ecc.is_valid_key(ephemeral_pubkey):
            raise InvalidKeyError('invalid ephemeral pubkey')

        # 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.ecc.raw_pubkey + \
            self.initiator_nonce + chr(flag)
        assert len(auth_message) == 65 + 32 + 64 + 32 + 1 == 194
        return auth_message
Example #6
0
    def create_auth_ack_message(self, ephemeral_pubkey=None, nonce=None, token_found=False):
        """
        authRecipient = E(remote-pubk, remote-ephemeral-pubk || nonce || 0x1) // token found
        authRecipient = E(remote-pubk, remote-ephemeral-pubk || nonce || 0x0) // token not found

        nonce and empehemeral-pubk are local!
        """
        assert not self.is_initiator
        ephemeral_pubkey = ephemeral_pubkey or self.ephemeral_ecc.raw_pubkey
        self.responder_nonce = nonce or sha3(ienc(random.randint(0, 2 ** 256 - 1)))

        flag = chr(1 if token_found else 0)
        msg = ephemeral_pubkey + self.responder_nonce + flag
        assert len(msg) == 64 + 32 + 1 == 97 == self.auth_ack_message_length
        return msg
Example #7
0
    def create_auth_message(self, remote_pubkey, 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)
        """
        assert self.is_initiator
        if not self.ecc.is_valid_key(remote_pubkey):
            raise InvalidKeyError('invalid remote pubkey')
        self.remote_pubkey = remote_pubkey

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

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

        token_xor_nonce = sxor(token, self.initiator_nonce)
        assert len(token_xor_nonce) == 32

        ephemeral_pubkey = self.ephemeral_ecc.raw_pubkey
        assert len(ephemeral_pubkey) == 512 / 8
        if not self.ecc.is_valid_key(ephemeral_pubkey):
            raise InvalidKeyError('invalid ephemeral pubkey')

        # 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.ecc.raw_pubkey + \
            self.initiator_nonce + chr(flag)
        assert len(auth_message) == 65 + 32 + 64 + 32 + 1 == 194
        return auth_message
Example #8
0
    def create_auth_ack_message(self,
                                ephemeral_pubkey=None,
                                nonce=None,
                                token_found=False):
        """
        authRecipient = E(remote-pubk, remote-ephemeral-pubk || nonce || 0x1) // token found
        authRecipient = E(remote-pubk, remote-ephemeral-pubk || nonce || 0x0) // token not found

        nonce and empehemeral-pubk are local!
        """
        assert not self.is_initiator
        ephemeral_pubkey = ephemeral_pubkey or self.ephemeral_ecc.raw_pubkey
        self.responder_nonce = nonce or sha3(
            ienc(random.randint(0, 2**256 - 1)))

        flag = chr(1 if token_found else 0)
        msg = ephemeral_pubkey + self.responder_nonce + flag
        assert len(msg) == 64 + 32 + 1 == 97 == self.auth_ack_message_length
        return msg
Example #9
0
    def create_auth_ack_message(self,
                                version=supported_rlpx_version,
                                eip8=False,
                                ephemeral_pubkey=None,
                                nonce=None):
        """
        authRecipient = E(remote-pubk, remote-ephemeral-pubk || nonce || 0x1) // token found
        authRecipient = E(remote-pubk, remote-ephemeral-pubk || nonce || 0x0) // token not found

        nonce, ephemeral_pubkey, version are local!
        """
        assert not self.is_initiator
        ephemeral_pubkey = ephemeral_pubkey or self.ephemeral_ecc.raw_pubkey
        self.responder_nonce = nonce or sha3(
            ienc(random.randint(0, 2**256 - 1)))
        if eip8 or self.got_eip8_auth:
            msg = self.create_eip8_auth_ack_message(ephemeral_pubkey,
                                                    self.responder_nonce,
                                                    version)
            assert len(msg) > 97
        else:
            msg = ephemeral_pubkey + self.responder_nonce + b'\x00'
            assert len(msg) == 97
        return msg
Example #10
0
 def to_binary(self):
     return list((self._ip.packed, utils.ienc(self.port)))
Example #11
0
 def to_binary(self):
     return list((self._ip.packed, utils.ienc(self.port)))