예제 #1
0
 def __init__(self, remote_ip, remote_port, local_ip="0.0.0.0"):
     local_port = remote_port + 20
     self.client = Client(remote_ip, remote_port)
     log(
         logging.info,
         self,
         self.__init__,
         "Connected on {}:{}".format(self.__class__.__name__,
         remote_ip, remote_port)
     )
     self.server = Server(local_ip, local_port)
     log(
         logging.info,
         self,
         self.__init__,
         "Connected on {}:{}".format(
             self.__class__.__name__,
             local_ip,
             local_port)
     )
     self._mutau_state = self.MUTUAL_AUTH_STATES[-1]
     self._session_key = None
     self._shared_key = None
     self._secret_value = random.randrange(
         320, 1<<(
         crypto.BLOCK_SIZE*crypto.TO_BITS)
     )
예제 #2
0
def decrypt(key, ct):
    """Decrypts ciphertext ``ct`` with ``key``"""
    # Decompose the ciphertext
    ct, nonce, mac = ct[:-BLOCK_SIZE*2], ct[-BLOCK_SIZE*2:-BLOCK_SIZE], \
                     ct[-BLOCK_SIZE:]
    log(
        logging.info,
        __name__,
        decrypt,
        "\nct: {}\n"
        "nonce: {}\n"
        "mac: {}\n".format(ct, nonce, mac)
    )
    
    # Check the MAC
    mac_key = derive_new_key(key)
    h = hmac.HMAC(mac_key, hashes.SHA256(), backend=BACKEND)
    h.update(ct + nonce)
    try :
        h.verify(mac)
    except:
        # This is just a hotfix so that the gui doesn't crash.
        # Idealy, the send and recv should have a header specifying
        # the number of bytes to send/receive
        raise DataIntegrityException()

    # Create the cipher with the extracted nonce
    cipher, _nonce = create_cipher(key, nonce=nonce)
    assert _nonce == nonce
    # Decrypt the plaintext
    decryptor = cipher.decryptor()
    pt = decryptor.update(ct) + decryptor.finalize()
    # Return the verified plaintext
    return pt
예제 #3
0
 def send(self, msg):
     log(
         logging.info,
         self,
         self.send,
         msg
     )
     self.conn.send(msg)
예제 #4
0
 def recv(self):
     msg = self.conn.recv(self.BUFSIZE)
     log(
         logging.info,
         self,
         self.recv,
         msg
     )
     return msg
예제 #5
0
 def send(self, message):
     if self.authenticated == True:
         log(
             logging.info,
             self,
             self.send, "Encrypting message '{}'...".format(
                 message,
                 self._session_key
             )
         )
         ct = crypto.encrypt(self._session_key, message)
         log(
             logging.info,
             self,
             self.send,
             "Message encrypted to ciphertext: {}".format(ct))
         log(
             logging.info,
             self,
             self.send,
             "Offering to send ciphertext..."
         )
         self.client.send(ct)
         log(
             logging.info,
             self,
             self.send,
             "Ciphertext sent."
         )
     else:
         raise NoAuthentication("No Authentication Established")
예제 #6
0
        def on_server_btn_start(instance):
            btn_start.disabled = True
            txt_secret.readonly = True
            txt_port.readonly = True

            print_console("Starting Server on port " + txt_port.text)
            self.bob = None
            while self.bob is None:
                try:
                    self.bob = ChatClientServer("0.0.0.0", int(txt_port.text))
                except socket.error as e:
                    log(
                        logging.warning,
                        self,
                        self.make_server_tab,
                        "Error occurred while trying to connect: " "socket.error: {}; retrying...".format(e),
                    )
                    sleep(1)
            print_console("Setting shared key to " + txt_secret.text)
            self.bob.set_shared_key(txt_secret.text.encode())
예제 #7
0
 def recv(self, nb=False):
     if self.authenticated == True:
         ct = self.server.recv() if not nb else self.server.nb_recv()
         if ct is None:
             return None
         log(
             logging.info,
             self,
             self.recv,
             "Ciphertext received: {}".format(ct)
         )
         pt = crypto.decrypt(self._session_key, ct)
         log(
             logging.info,
             self,
             self.recv,
             "Ciphertext decrypted to: {}".format(pt)
         )
         return pt
     else:
         raise NoAuthentication("No Authentication Established")
예제 #8
0
 def __init__(self, local_ip="0.0.0.0", local_port=8051):
     # Start server first, then client (opposite order from ChatClientClient
     self.server = Server(local_ip, local_port)
     log(
         logging.info,
         self,
         self.__init__,
         "{}.server connected on {}:{}".format(
             self.__class__.__name__, local_ip, local_port))
     remote_ip, _ = self.server.client_address
     remote_port = local_port + 20
     self.client = Client(remote_ip, remote_port)
     log(
         logging.info,
         self,
         self.__init__,
         "{}.client connected on {}:{}".format(
         self.__class__.__name__,
         remote_ip, remote_port))
     self._mutau_state = self.MUTUAL_AUTH_STATES[-1]
     self._secret_value = random.randrange(
         320, 1<<(
         crypto.BLOCK_SIZE*crypto.TO_BITS)
     )
예제 #9
0
        def on_client_btn_start(instance):
            if is_valid_ip(txt_ip.text):
                btn_start.disabled = True
                txt_secret.readonly = True
                txt_port.readonly = True
                txt_ip.readonly = True

                print_console("Starting Client on port " + txt_port.text)
                self.alice = None
                while self.alice is None:
                    try:
                        self.alice = ChatClientClient(txt_ip.text, int(txt_port.text))
                    except socket.error as e:
                        log(
                            logging.warning,
                            self,
                            self.make_client_tab,
                            "Error occurred while trying to connect: " "socket.error: {}; retrying...".format(e),
                        )
                        sleep(1)
                print_console("Setting shared key to " + txt_secret.text)
                self.alice.set_shared_key(txt_secret.text.encode())
            else:
                print_console("Please enter a valid IP address")
예제 #10
0
    def mutauth_step(self, reset=False):
        if reset:
            self._mutau_state = self.MUTUAL_AUTH_STATES[-1]
            return

        if self._shared_key is None:
            raise NoSharedKey("Shared key is not setup yet. Can't proceed")

        if self._mutau_state == self.MUTUAL_AUTH_STATES[-1]:
            log(
                logging.info,
                self,
                self.mutauth_step,
                "server receive client's ra"
            )
            self._Ra = self.server.recv()
            
            self._mutau_state = self.MUTUAL_AUTH_STATES[0]
        elif self._mutau_state == self.MUTUAL_AUTH_STATES[0]:
            # Send response: RB, E("Bob", RA, gb mod p, KAB)
            self._Rb = os.urandom(crypto.BLOCK_SIZE)
            gb_mod_p = pow(self._g, self._secret_value, self._p)
            pt = self._identifier + self._Ra + str(gb_mod_p)
            ct = crypto.encrypt(self._shared_key, pt)
            msg = self._Rb + ct
            self.client.send(msg)
            log(
                logging.info,
                self,
                self.mutauth_step,
                "server sends rb + its identifier, rb, and gb mod p"
            )

            self._mutau_state = self.MUTUAL_AUTH_STATES[1]
        elif self._mutau_state == self.MUTUAL_AUTH_STATES[1]:
            # Receive E("Alice", RB, ga mod p, KAB)
            ct = self.server.recv()
            pt = crypto.decrypt(self._shared_key, ct)
            identifier, rb, ga_mod_p = self.extract_auth_msg_parts(pt)
            log(
                logging.info,
                self,
                self.mutauth_step,
                "server receives client's identifier, rb, and ga mod p"
            )

            if rb != self._Rb:
                raise BeingAttacked("Trudy is attacking")
            if identifier == self._identifier:
                raise BeingAttacked("Trudy is doing replay attack")

            self._session_key = pow(long(ga_mod_p), self._secret_value, self._p)
            log(
                logging.info,
                self,
                self.mutauth_step,
                "server creates the session key"
            )

            self._mutau_state = self.MUTUAL_AUTH_STATES[2]
            self._session_key = crypto.derive_new_key(str(self._session_key))
        elif self._mutau_state == self.MUTUAL_AUTH_STATES[2]:
            raise StopIteration("Authentication completed successfully.")
예제 #11
0
    def mutauth_step(self, reset=False):
        """This method steps through mutual authentication 
            and key exchange using Diffie-Helman

        Each call to this method will perform one step out of the
         total steps necessary for authentication

        :param bool reset: If this is set, we reset back to step -1
        """
        if reset:
            self._mutau_state = self.MUTUAL_AUTH_STATES[-1]
            return

        if self._shared_key is None:
            raise NoSharedKey("Shared key is not setup yet. Can't proceed")

        if self._mutau_state == self.MUTUAL_AUTH_STATES[-1]:
            # Send our public key (Ra)
            self._Ra = os.urandom(crypto.BLOCK_SIZE)
            self.client.send(self._Ra)
            log(
                logging.info,
                self,
                self.mutauth_step,
                "Client sends Ra"
            )

            self._mutau_state = self.MUTUAL_AUTH_STATES[0]
        elif self._mutau_state == self.MUTUAL_AUTH_STATES[0]:
            # Get response: RB, E("Bob", RA, gb mod p, KAB)
            resp = self.server.recv()
            self._rb = resp[:crypto.BLOCK_SIZE]
            log(
                logging.info,
                self,
                self.mutauth_step,
                "client receives rb"
            )
            ct = resp[crypto.BLOCK_SIZE:]
            pt = crypto.decrypt(self._shared_key, ct)
            self._server_ident, ra, gb_mod_p = self.extract_auth_msg_parts(pt)
            log(
                logging.info,
                self,
                self.mutauth_step,
                "client receives identifier of server, ra, and gb mod p"
            )

            if ra != self._Ra:
                raise BeingAttacked("Trudy is attacking")

            self._session_key = pow(long(gb_mod_p), self._secret_value, self._p)
            log(
                logging.info,
                self,
                self.mutauth_step,
                "client creates the session key"
            )

            self._mutau_state = self.MUTUAL_AUTH_STATES[1]
        elif self._mutau_state == self.MUTUAL_AUTH_STATES[1]:
            # Send E("Alice", RB, ga mod p, KAB)

            # Client identifier can be anything other the the server's ident
            identifier = os.urandom(crypto.BLOCK_SIZE)
            while identifier == self._server_ident:
                identifier = os.urandom(crypto.BLOCK_SIZE)
            log(
                logging.info,
                self,
                self.mutauth_step,
                "client creates its identifier that's not the same as server's"
            )
 
            ga_mod_p = pow(self._g, self._secret_value, self._p)
            log(
                logging.info,
                self,
                self.mutauth_step,
                "client creates ga mod p"
            )
 
            pt = identifier + self._rb + str(ga_mod_p)
            log(
                logging.info,
                self,
                self.mutauth_step,
                "client sends its identifier, the server's rb, and ga mod p"
            )
 
            ct = crypto.encrypt(self._shared_key, pt) 
            self.client.send(ct)
            
            self._mutau_state = self.MUTUAL_AUTH_STATES[2]
            self._session_key = crypto.derive_new_key(str(self._session_key))
        elif self._mutau_state == self.MUTUAL_AUTH_STATES[2]:

            raise StopIteration("Authentication completed successfully.")