예제 #1
0
    def receive_share(self, from_username, newname, message):
        (sign_encrypt_message,
         encrypt_message) = util.from_json_string(message)
        user_public_key = self.pks.get_public_key(from_username)

        right_sign = self.crypto.asymmetric_verify(encrypt_message,
                                                   sign_encrypt_message,
                                                   user_public_key)
        if not right_sign:
            raise IntegrityError
            # Message_from is [encrypt_key, mac_keys, share_node_keys, nonce]
        message_from = self.crypto.asymmetric_decrypt(encrypt_message,
                                                      self.private_key)
        message_from = util.from_json_string(message_from)
        key_node = self.node(message_from[2], message_from[0], message_from[1])
        # store the key_node in the server.\

        'Need to grab ivs for this file'
        share_node, share_iv = self.fetch_and_decrypt(message_from[2],
                                                      message_from[0],
                                                      message_from[1])
        # Recreate merkle tree
        data_node = share_node
        root_node = share_node
        while isinstance(data_node, self.node):
            root_node = data_node
            data_node, data_iv = self.fetch_and_decrypt(
                data_node.pointer, data_node.encryption, data_node.mac_keys)
            #if data_node is None:
            #    return data_node
        #self.merkle_tree = data_node
        #self.client_dictionary[newname] = {}
        self.encryption_ivs[newname] = []
        self.reconstruct_merkle(data_node, root_node.encryption,
                                root_node.mac_keys, newname)

        'Need to grab ivs for this file'

        key_node_id = self.crypto.symmetric_encrypt(
            self.crypto.cryptographic_hash(path_join(self.username, newname),
                                           'SHA256'),
            self.iv,
            'AES',
            'CBC',
            IV=None)
        file_iv = self.crypto.get_random_bytes(16)
        self.encrypt_and_put(key_node, key_node_id, self.iv, self.iv_mac,
                             file_iv)
        # Create user_list for file and upload to server.
        user_list = []
        userlist_iv = self.crypto.get_random_bytes(16)
        user_list_id = self.crypto.symmetric_encrypt(
            self.crypto.cryptographic_hash(
                path_join(self.username, newname) + "User_lists", "SHA"),
            self.iv,
            'AES',
            'CBC',
            IV=None)
        self.encrypt_and_put(user_list, user_list_id, self.iv, self.iv_mac,
                             userlist_iv)
예제 #2
0
    def receive_share(self, from_username, newname, message):
        # Replace with your implementation (not needed for Part 1)
        try:
            encrypted_keys_filename_string, signed_encrypted_keys_filename_string = util.from_json_string(
                message)
        except:
            raise IntegrityError()

        if self.crypto.asymmetric_verify(
                encrypted_keys_filename_string,
                signed_encrypted_keys_filename_string,
                self.pks.get_public_key(from_username)):
            decrypted_keys_filename_string = self.crypto.asymmetric_decrypt(
                encrypted_keys_filename_string, self.private_key)
            ka, ke, encrypted_original_filename = util.from_json_string(
                decrypted_keys_filename_string)

            k = self.get_unique_symmetric_key()
            encrypted_newfilename = self.crypto.message_authentication_code(
                newname, k, "MD5")
            half = int(len(encrypted_newfilename) / 4)
            encrypted_newfilename = encrypted_newfilename[:half]
            fid = path_join(self.username, encrypted_newfilename, "keys")
            keys_link = path_join(self.username, encrypted_original_filename,
                                  "keys")
            self.re_sign_keys(keys_link, from_username)
            self.storage_server.put(fid, "[POINTER] " + keys_link)

            uid = path_join(self.username, encrypted_newfilename)
            link = path_join(self.username, encrypted_original_filename)
            self.storage_server.put(uid, "[POINTER] " + link)
        else:
            raise IntegrityError()
예제 #3
0
 def fetch_and_decrypt(self, encrypted_id, key_encrypt, key_auth):
     string_data = self.storage_server.get(encrypted_id)
     ##print(string_data)
     if string_data is None:
         return None, None
     try:
         encrypt_node, sign_encrypt_node, file_iv = util.from_json_string(
             string_data)
     except ValueError:
         raise IntegrityError
     # Check encrypt_key_node signature
     string_encrypt_node = util.to_json_string([encrypt_node, file_iv])
     new_auth_encrypt_node = self.crypto.message_authentication_code(
         string_encrypt_node, key_auth, 'SHA512')
     if new_auth_encrypt_node != sign_encrypt_node:
         raise IntegrityError
         # Decrypt encrypt_key_node
     json_data = self.crypto.symmetric_decrypt(encrypt_node,
                                               key_encrypt,
                                               'AES',
                                               'CBC',
                                               IV=file_iv)
     data = util.from_json_string(json_data)
     if len(data) == 4 and data[3] == "node":
         data = self.node(data[0], data[1], data[2])
     elif len(data) == 6 and data[5] == "merkle-node":
         data = self.merkle_node(data[0], data[1], data[2], data[3],
                                 data[4])
     return data, file_iv
예제 #4
0
    def share(self, user, name):
        # Replace with your implementation (not needed for Part 1)
        random_key_for_dictionary = self.storage_server.get("dict_key")
        dictionary_items_as_string = self.storage_server.get("dict")

        if dictionary_items_as_string is None:
            return None
        dictionary_items_as_list = util.from_json_string(
            dictionary_items_as_string)
        dictionary_iv = dictionary_items_as_list[0]
        encrypted_dictionary = dictionary_items_as_list[1]
        decrypted_dictionary = self.crypto.symmetric_decrypt(
            encrypted_dictionary, random_key_for_dictionary, 'AES', 'CBC',
            dictionary_iv)
        actual_dictionary = util.from_json_string(decrypted_dictionary)

        random_keys = actual_dictionary.get(uid)
        if random_keys is None:
            return None
        random_id = random_keys[0]

        sharename = path_join(self.username, "sharewith", user, name)
        self.storage_server.put(sharename,
                                "[POINTER] " + path_join(self.username, name))
        return sharename
예제 #5
0
    def grabData(self, lst, e_key, m_key):
        """lst is the list of the top root node"""
        if len(lst) == 3:  # We hit a leaf node
            pkt = self.storage_server.get(lst[2])
            # Split the packet into the encrypted stuff and the mac that came along with it
            iv_encrypted_value, mac = pkt[:len(pkt) - 64], pkt[len(pkt) - 64:]

            # Recreate the mac using m_key and compare it with the one that came along with it
            try:
                testmac = self.crypto.message_authentication_code(
                    iv_encrypted_value, m_key, 'SHA256')
            except:
                raise IntegrityError
            if testmac != mac:
                raise IntegrityError

            # Split into iv and the encrypted file value and decrypt accordingly
            iv = iv_encrypted_value[:32]
            encrypted_value = iv_encrypted_value[32:]
            value = self.crypto.symmetric_decrypt(encrypted_value, e_key,
                                                  'AES', 'CBC', iv)
            return value

        else:  # Basically when len(lst) == 4
            pkt1 = self.storage_server.get(lst[2])
            pkt2 = self.storage_server.get(lst[3])
            # Split the packet into the encrypted stuff and the mac that came along with it
            iv_encrypted_value1, mac1 = pkt1[:len(pkt1) - 64], pkt1[len(pkt1) -
                                                                    64:]
            iv_encrypted_value2, mac2 = pkt2[:len(pkt2) - 64], pkt2[len(pkt2) -
                                                                    64:]

            # Recreate the mac using m_key and compare it with the one that came along with it
            try:
                testmac1 = self.crypto.message_authentication_code(
                    iv_encrypted_value1, m_key, 'SHA256')
                testmac2 = self.crypto.message_authentication_code(
                    iv_encrypted_value2, m_key, 'SHA256')
            except:
                raise IntegrityError
            if testmac1 != mac1 or testmac2 != mac2:
                raise IntegrityError

            # Split into iv and the encrypted file value and decrypt accordingly
            iv1 = iv_encrypted_value1[:32]
            iv2 = iv_encrypted_value2[:32]
            encrypted_value1 = iv_encrypted_value1[32:]
            encrypted_value2 = iv_encrypted_value2[32:]
            lst1 = from_json_string(
                self.crypto.symmetric_decrypt(encrypted_value1, e_key, 'AES',
                                              'CBC', iv1))
            lst2 = from_json_string(
                self.crypto.symmetric_decrypt(encrypted_value2, e_key, 'AES',
                                              'CBC', iv2))
            # print("left")
            # print(self.grabData(lst1, e_key, m_key))
            # print("right")
            # print(self.grabData(lst2, e_key, m_key))
            return self.grabData(lst1, e_key, m_key) + self.grabData(
                lst2, e_key, m_key)
예제 #6
0
    def download(self, name):
        # Replace with your implementation
        

        
        
        uid = self.resolve(path_join(self.username, name))
        random_key_for_dictionary = self.storage_server.get("dict_key")
        dictionary_items_as_string = self.storage_server.get("dict")
        
        if dictionary_items_as_string is None:
            return None
        dictionary_items_as_list = util.from_json_string(dictionary_items_as_string)
        dictionary_iv = dictionary_items_as_list[0]
        encrypted_dictionary = dictionary_items_as_list[1]
        ###############
        encrypted_dictionary_signature = dictionary_items_as_list[2]
        #if not self.crypto.asymmetric_verify(encrypted_dictionary, encrypted_dictionary_signature, self.private_key.publickey()):
            #raise IntegrityError()
            #pass
        ###############
        #encrypted_dictionary = dictionary_items_as_string
        #decrypted_dictionary = self.crypto.asymmetric_decrypt(encrypted_dictionary, self.private_key)
        decrypted_dictionary = self.crypto.symmetric_decrypt(encrypted_dictionary, random_key_for_dictionary, 'AES', 'CBC', dictionary_iv)
        actual_dictionary = util.from_json_string(decrypted_dictionary)
        #actual_dictionary = dictionary_items_as_list
        #print(uid)
        random_keys = actual_dictionary.get(uid)
        if random_keys is None:
            return None
        #random_key_for_name = random_keys[0]
        random_id = random_keys[0]
        random_key_for_value = random_keys[1]
        #resp = self.storage_server.get(uid)
        #encrypted_name = self.crypto.symmetric_encrypt(uid, random_key_for_name, 'AES')
        #resp = self.storage_server.get(encrypted_name)
        resp = self.storage_server.get(random_id)
        if resp is None:
            return None
        list_of_value_items_as_string = resp[7:]
        list_of_value_items = util.from_json_string(list_of_value_items_as_string)
        value_iv = list_of_value_items[0]
        
        encrypted_value = list_of_value_items[1]
        '''
        encrypted_value_signature = list_of_value_items[2]
        ###########
        signed_name_and_value = list_of_value_items[3]
        if not self.crypto.asymmetric_verify(random_id+encrypted_value, signed_name_and_value, self.private_key.publickey()):
            raise IntegrityError()
        ###########
        if not self.crypto.asymmetric_verify(encrypted_value, encrypted_value_signature, self.private_key.publickey()):
            raise IntegrityError()
            #pass
        '''
        decrypted_value = self.crypto.symmetric_decrypt(encrypted_value, random_key_for_value, 'AES', 'CBC', value_iv)
        return decrypted_value
예제 #7
0
    def download(self, name):
        # Replace with your implementation
        ka, ke = self.get_file_keys(name)
        k = self.get_unique_symmetric_key()
        cipher_name = self.crypto.message_authentication_code(name, k, "MD5")
        half = int(len(cipher_name) / 4)
        cipher_name = cipher_name[:half]
        uid = self.revolve(path_join(self.username, cipher_name))
        res = self.storage_server.get(uid)

        if not res:
            return None
        else:
            cipher_all_string = res[7:]
            try:
                IV, cipher_value, old_tag = util.from_json_string(
                    cipher_all_string)
            except:
                raise IntegrityError()

            new_tag = self.crypto.message_authentication_code(
                IV + cipher_value + uid, ka, "MD5")

            if old_tag != new_tag:
                raise IntegrityError()
            else:
                chunk_num_string = self.crypto.symmetric_decrypt(
                    cipher_value, ke, "AES", "CBC", IV)
                chunk_num = int(chunk_num_string)

        value = ""
        for i in range(chunk_num):
            uid_i = path_join(uid, str(i))
            res = self.storage_server.get(uid_i)

            if not res:
                return None
            else:
                cipher_all_string = res[7:]
                try:
                    IV, cipher_value, old_tag = util.from_json_string(
                        cipher_all_string)
                except:
                    raise IntegrityError()

                new_tag = self.crypto.message_authentication_code(
                    IV + cipher_value + uid_i, ka, "MD5")

                if old_tag != new_tag:
                    raise IntegrityError()
                else:
                    value += self.crypto.symmetric_decrypt(
                        cipher_value, ke, "AES", "CBC", IV)

        return value
예제 #8
0
    def share(self, user, name):
        # Replace with your implementation (not needed for Part 1)
        uid = path_join(self.username, name)
        username_keys = path_join(self.username, "dict_keys")
        username_dictionary = path_join(self.username, "dictionary")
        random_key_for_dictionary = self.storage_server.get(username_keys)
        #print(random_key_for_dictionary)
        random_key_for_dictionary = self.crypto.asymmetric_decrypt(random_key_for_dictionary, self.private_key)
        dictionary_items_as_string = self.storage_server.get(username_dictionary)

        #print(dictionary_items_as_string)
        if dictionary_items_as_string is None:
                return None
        dictionary_items_as_list = util.from_json_string(dictionary_items_as_string)
        dictionary_iv = dictionary_items_as_list[0]
        encrypted_dictionary = dictionary_items_as_list[1]
        decrypted_dictionary = self.crypto.symmetric_decrypt(encrypted_dictionary, random_key_for_dictionary, 'AES', 'CBC', dictionary_iv)
        actual_dictionary = util.from_json_string(decrypted_dictionary)

        random_keys = actual_dictionary.get(uid)
        #print(random_keys)
        if random_keys is None:
            return None
        random_id = random_keys[0]
        random_id_key = random_keys[1]
        random_id_mac = random_keys[2]


        e_key = self.crypto.asymmetric_encrypt(random_id_key, self.public_key_server.get_public_key(user))

        if self.storage_server.get(random_id+"shared_file") == None:
            shared_dict_as_string = util.to_json_string({self.username: None}) #SHADYYYYYYYYYYY; how do you initialize shizzzzzzzz
            #don't need to encrypt shared_dict since it's public info
            shared_dict_mac = self.crypto.message_authentication_code(shared_dict_as_string, random_id_key, 'SHA256')
            shared_dict_values = [shared_dict_as_string, shared_dict_mac]
            shared_dict_values_as_string = util.to_json_string(shared_dict_values)
            self.storage_server.put(random_id+"shared_file", shared_dict_values_as_string)

        shared_dict = self.storage_server.get(random_id+"shared_file")
        calculated_mac = self.crypto.message_authentication_code(shared_dict, random_id_key, 'SHA256')
        if calculated_mac != shared_dict[1]:
            raise IntegrityError() #is this the right error
        shared_dict = util.from_json_string(shared_dict)
        shared_dict[self.username] = shared_dict[self.username].append({user: None})

        msg_as_list = [random_id, e_key, random_id+"shared_file"]
        msg_as_string = util.to_json_string(msg_as_list)

        #they're not gonna test if you call share on something you don't own
        #return None if a user tries to download a file that they don't have access to, not IntegrityError()
        return msg_as_string
예제 #9
0
    def receive_share(self, from_username, newname, message):
        sender_pub_key = self.pks.get_public_key(from_username)

        try:
            output = util.from_json_string(message)
            crypted, sign = output
        except:
            raise IntegrityError()

        # DECRYPT RECEIVED MESSAGE
        if self.crypto.asymmetric_verify(crypted, sign, sender_pub_key):
            msg = self.crypto.asymmetric_decrypt(crypted, self.private_key)
            msg = util.from_json_string(msg)

            session_key = msg['session_key']
            file_id = msg['file_id']
        else:
            raise IntegrityError()

        # GET DIRECTORY KEYS
        directory_keys = self.get_directory_keys()
        sym_ke, sym_ka = directory_keys

        # GET DIRECTORY
        client_ID = path_join(self.username, "directory")
        resp = self.storage_server.get(client_ID)
        if resp is None:
            directory = {
                newname: {
                    "keys": session_key,
                    "shared": [],
                    "file_id": file_id
                }
            }
        else:
            directory = self.decrypt_directory(resp, sym_ke, sym_ka)
            directory[newname] = {
                "keys": session_key,
                "shared": [],
                "file_id": file_id
            }

        # can cache directory here
        self.directory[newname] = {
            "keys": session_key,
            "shared": [],
            "file_id": file_id
        }

        self.encrypt_directory(client_ID, directory, sym_ke, sym_ka)
예제 #10
0
파일: client.py 프로젝트: Sharabesh/CS161
    def init_dir_keys(self):
        self.dir_keys_loc = self.username + '/dir_keys'
        value = self.storage_server.get(self.dir_keys_loc)

        if not value:
            # key not already on the server
            self.dir_enc_key = self.crypto.get_random_bytes(32)
            self.dir_mac_key = self.crypto.get_random_bytes(32)

            dir_keys = {
                'dir_enc_key': self.dir_enc_key,
                'dir_mac_key': self.dir_mac_key
            }

            dir_keys_str = to_json_string(dir_keys)
            enc_value = self.crypto.asymmetric_encrypt(dir_keys_str,
                                                       self.private_key)
            sig = self.crypto.asymmetric_sign(self.dir_keys_loc + enc_value,
                                              self.private_key)

            dir_keys_pkg = {'enc_value': enc_value, 'sig': sig}

            value = to_json_string(dir_keys_pkg)

            if not self.storage_server.put(self.dir_keys_loc, value):
                # unable to upload sym_key to storage server
                raise IntegrityError

        else:
            # keys fetched from server
            try:
                dir_keys_pkg = from_json_string(value)
                sig = dir_keys_pkg['sig']
                enc_value = dir_keys_pkg['enc_value']

                if not self.crypto.asymmetric_verify(
                        self.dir_keys_loc + enc_value, sig, self.private_key):
                    raise IntegrityError

                dir_keys_str = self.crypto.asymmetric_decrypt(
                    enc_value, self.private_key)
                dir_keys = from_json_string(dir_keys_str)
                self.dir_enc_key = dir_keys['dir_enc_key']
                self.dir_mac_key = dir_keys['dir_mac_key']

            except (ValueError, TypeError, KeyError, CryptoError):
                # malformed key package
                raise IntegrityError
예제 #11
0
파일: client.py 프로젝트: Sharabesh/CS161
    def download(self, name):
        self.get_dir()
        if not name in self.dir:
            # file not part of user's dir
            return None

        file_record = self.dir[name]
        loc = file_record['loc']
        enc_key = file_record['enc_key']
        mac_key = file_record['mac_key']

        if file_record['is_gateway']:
            target = self.follow_gateways(file_record['loc'],
                                          file_record['enc_key'],
                                          file_record['mac_key'])
            enc_key = target['enc_key']
            mac_key = target['mac_key']
            meta_val = self.get(target['loc'], target['enc_key'],
                                target['mac_key'])
        else:
            meta_val = self.get(loc, enc_key, mac_key)

        if not meta_val:
            raise IntegrityError

        meta = from_json_string(meta_val)
        value, root_hash = self.download_merkle(meta['tree'], enc_key, mac_key)
        merkle = self.create_merkle(value)
        if merkle.hash != root_hash:
            raise IntegrityError
        return value
예제 #12
0
    def revoke(self, user, name):
        # Replace with your implementation (not needed for Part 1)
        old_keys = self.get_file_keys(name)
        old_ka, old_ke = old_keys
        k = self.get_unique_symmetric_key()
        cipher_name = self.crypto.message_authentication_code(name, k, "MD5")
        half = int(len(cipher_name) / 4)
        cipher_name = cipher_name[:half]
        interface_id = path_join(user, cipher_name)
        self.storage_server.delete(interface_id)

        new_keys = self.re_encrypt_file(name)
        new_ka, new_ke = new_keys

        owner, encrypted_original_filename = self.get_owner_and_encrypted_original_filename(
            name)
        share_id = path_join(self.username, encrypted_original_filename,
                             "shared_with")
        share_list_string = self.check_integrity_and_get_value(
            old_ka, share_id)
        share_list = util.from_json_string(share_list_string)

        if user in share_list:
            share_list.remove(user)

        self.re_distribute_keys(share_id, share_list,
                                encrypted_original_filename, old_ka, new_keys)
예제 #13
0
    def share(self, user, name):
        # Replace with your implementation (not needed for Part 1)
        keys = self.get_file_keys(name)
        ka, ke = keys
        file_info = self.get_owner_and_encrypted_original_filename(name)
        encrypted_original_filename = file_info[1]

        share_id = path_join(self.username, encrypted_original_filename,
                             "shared_with")
        share_list_string = self.storage_server.get(share_id)
        if share_list_string == None:
            share_list = [user]
        else:
            share_list_string = self.check_integrity_and_get_value(
                ka, share_id)
            share_list = util.from_json_string(share_list_string)
            share_list.append(user)

        share_list_string = util.to_json_string(share_list)
        self.MAC_and_store(share_list_string, ka, share_id)

        self.share_keys_with_user(user, encrypted_original_filename, keys)

        self.make_bridge(user, encrypted_original_filename)

        keys_filename = (ka, ke, encrypted_original_filename)
        keys_filename_string = util.to_json_string(keys_filename)
        encrypted_keys_filename_string = self.crypto.asymmetric_encrypt(
            keys_filename_string, self.pks.get_public_key(user))
        signed_encrypted_keys_filename_string = self.crypto.asymmetric_sign(
            encrypted_keys_filename_string, self.private_key)
        msg = util.to_json_string((encrypted_keys_filename_string,
                                   signed_encrypted_keys_filename_string))
        return msg
예제 #14
0
    def grab_sdirectory(self, enc_key, mac_key):
        """Returns the sharing directory in the form of a dictionary of this user"""

        # Grab the encrypted packet and divide it into the encrypted part and the mac
        packet = self.storage_server.get(path_join(self.username, "sdir"))
        iv_encrypted_dir, mac = packet[:len(packet) - 64], packet[len(packet) -
                                                                  64:]

        # Recreate the mac using mac_key and compare it with the one that came along with it
        try:
            testmac = self.crypto.message_authentication_code(
                iv_encrypted_dir, mac_key, 'SHA256')
        except:
            raise IntegrityError
        if testmac != mac:
            raise IntegrityError
        # If we reach here, we have verified that our directory is good

        try:
            # Split iv_encrypted_dir into an iv and the encrypted_dir
            iv = iv_encrypted_dir[:32]
            encrypted_dir = iv_encrypted_dir[32:]
            # Decrypt and also convert back into a python dictionary
            directory = from_json_string(
                self.crypto.symmetric_decrypt(encrypted_dir, enc_key, 'AES',
                                              'CBC', iv))
        except:
            raise IntegrityError

        return directory
예제 #15
0
 def receive_share(self, from_username, newname, message):
     # Replace with your implementation (not needed for Part 1)
     decryptedMessage = util.from_json_string(
         self.crypto.asymmetric_decrypt(message, self.private_key))
     fileID = decryptedMessage[0]
     key1 = decryptedMessage[1]
     key2 = decryptedMessage[2]
     # if no directory yet
     if self.storage_server.get(self.username + "/directory") is not None:
         encryptedDictionaryAndKey = util.from_json_string(
             self.storage_server.get(self.username + "/directory"))
         enDictionary = encryptedDictionaryAndKey[0]
         enKey = encryptedDictionaryAndKey[1]
         directoryKey = self.crypto.asymmetric_decrypt(
             enKey, self.private_key)
         dictionary = util.from_json_string(
             self.crypto.symmetric_decrypt(enDictionary, directoryKey,
                                           'AES'))
         dictionary[newname] = fileID
         decryptedDicKey = self.crypto.asymmetric_decrypt(
             ESymms, self.private_key)
         encryptedDictionary = self.crypto.symmetric_encrypt(
             util.to_json_string(dictionary), decryptedDicKey, 'AES')
         self.storage_server.put(
             self.username + "/directory",
             util.to_json_string((encryptedDictionary, enKey)))
     else:
         dictionary = {newname: fileID}
         dictionaryKey = self.crypto.get_random_bytes(16)
         encryptedDictionary = self.crypto.symmetric_encrypt(
             util.to_json_string(dictionary), dictionaryKey, 'AES')
         encryptionOfDictionaryKey = self.crypto.asymmetric_encrypt(
             dictionaryKey, self.pks.get_public_key(self.username))
         self.storage_server.put(
             self.username + "/directory",
             util.to_json_string(
                 (encryptedDictionary, encryptionOfDictionaryKey)))
     pubKey = self.pks.get_public_key(self.username)
     symmKeys = (key1, key2)
     encryptionOfSymmKeys = self.crypto.asymmetric_encrypt(
         util.to_json_string(symmKeys), pubKey)
     signedEncryptionOfSymmKeys = self.crypto.asymmetric_sign(
         encryptionOfSymmKeys, self.private_key)
     self.storage_server.put(
         self.username + "/dir_keys/" + fileID,
         util.to_json_string(
             (encryptionOfSymmKeys, signedEncryptionOfSymmKeys)))
예제 #16
0
    def safe_decrypt(self, resp):
        pub_key = self.private_key.publickey()

        try:
            key_info = util.from_json_string(resp)
            encrypted_keys = key_info["encrypted_keys"]
            signed_keys = key_info["signed_keys"]
        except:
            raise IntegrityError()

        if not self.crypto.asymmetric_verify(encrypted_keys, signed_keys,
                                             pub_key):
            raise IntegrityError()

        decrypted_keys = self.crypto.asymmetric_decrypt(
            encrypted_keys, self.private_key)
        return util.from_json_string(decrypted_keys)
예제 #17
0
    def get_file_keys(self, name):
        k = self.get_unique_symmetric_key()
        encrypted_filename = self.crypto.message_authentication_code(
            name, k, "MD5")
        half = int(len(encrypted_filename) / 4)
        encrypted_filename = encrypted_filename[:half]
        fid = self.revolve(path_join(self.username, encrypted_filename,
                                     "keys"))
        fkeys = self.storage_server.get(fid)

        if fkeys == None:
            return self.make_file_keys(fid)
        else:
            owner, encrypted_original_filename = self.get_owner_and_encrypted_original_filename(
                name)

            if self.username != owner:
                kid = path_join(self.username, encrypted_original_filename,
                                "keys")
                keys_string = self.storage_server.get(kid)
                if not keys_string:
                    return None
                else:
                    try:
                        encrypted_keys_string, signed_encrypted_keys_string = util.from_json_string(
                            keys_string[7:])
                    except:
                        raise IntegrityError()

                if self.crypto.asymmetric_verify(
                        encrypted_keys_string, signed_encrypted_keys_string,
                        self.pks.get_public_key(owner)):
                    keys_string = self.crypto.asymmetric_decrypt(
                        encrypted_keys_string, self.private_key)
                    self.sign_and_store(keys_string, self.username, kid)
                elif self.crypto.asymmetric_verify(
                        encrypted_keys_string, signed_encrypted_keys_string,
                        self.pks.get_public_key(self.username)):
                    pass
                else:
                    raise IntegrityError()

            keys_string = self.verify_signature_and_get_value(
                self.username, fid)
            keys = util.from_json_string(keys_string)
            return keys
예제 #18
0
파일: client.py 프로젝트: Sharabesh/CS161
    def efficient_update(self, merkle, node_loc, enc_key, mac_key, root=True):
        server_node_val = self.storage_server.get(node_loc)
        if not server_node_val:
            raise IntegrityError

        try:
            server_node = from_json_string(server_node_val)
            if root:
                server_node = from_json_string(server_node['value'])

            if merkle.hash == server_node['hash']:
                return

            node = {
                'hash': merkle.hash,
                'left': server_node['left'],
                'right': server_node['right'],
                'iv': None,
                'data': None
            }

            if merkle.data:
                node['iv'] = merkle.iv
                node['data'] = self.sym_enc(merkle.data, merkle.iv, enc_key)

            node_value = to_json_string(node)

            if root:
                if not self.put_no_enc(node_value, node_loc, mac_key):
                    raise IntegrityError

            else:
                if not self.storage_server.put(node_loc, node_value):
                    raise IntegrityError

            if merkle.left:
                self.efficient_update(merkle.left, server_node['left'],
                                      enc_key, mac_key, False)

            if merkle.right:
                self.efficient_update(merkle.right, server_node['right'],
                                      enc_key, mac_key, False)
        except:
            raise IntegrityError
예제 #19
0
    def decrypt_directory(self, resp, sym_ke, sym_ka):
        try:
            directory_info = util.from_json_string(resp)
            IV = directory_info['IV']
            encrypted_keys = directory_info["encrypted_keys"]
            signed_keys = directory_info["signed_keys"]
        except:
            raise IntegrityError()

        signed_dir = self.crypto.message_authentication_code(
            encrypted_keys, sym_ka, 'SHA256')
        if signed_dir != signed_keys:
            raise IntegrityError()

        directory = self.crypto.symmetric_decrypt(encrypted_keys, sym_ke,
                                                  'AES', 'CBC', IV)
        directory = util.from_json_string(directory)

        return directory
예제 #20
0
    def get_shared_info(
        self, uid, data_key, data_mac_key
    ):  #add stuff to decrypt the [DATA] [random_id, random_key] #get decrypted value of random_id
        try:
            list_of_data_items_as_string = self.storage_server.get(uid)[7:]
            list_of_data_items = util.from_json_string(
                list_of_data_items_as_string)

            data_iv = list_of_data_items[0]

            encrypted_data_as_string = list_of_data_items[1]

            data_mac = list_of_data_items[2]
            calculated_data_mac = self.crypto.message_authentication_code(
                encrypted_data_as_string, data_mac_key, 'SHA256')
            if calculated_data_mac != data_mac:
                raise IntegrityError()
            shared_info = self.crypto.symmetric_decrypt(
                encrypted_data_as_string, data_key, 'AES', 'CBC', data_iv)
            info_as_list = util.from_json_string(shared_info)
            random_id = info_as_list[0]
            random_key_for_value = info_as_list[1]
            random_key_for_value_mac = info_as_list[2]
            resp = self.storage_server.get(random_id)
            if resp is None:
                return None
            list_of_value_items_as_string = resp[7:]
            list_of_value_items = util.from_json_string(
                list_of_value_items_as_string)
            value_iv = list_of_value_items[0]
            encrypted_value = list_of_value_items[1]
            name_and_value_encrypt_mac = list_of_value_items[2]
            calculated_mac = self.crypto.message_authentication_code(
                random_id + encrypted_value, random_key_for_value_mac,
                'SHA256')
            if calculated_mac != name_and_value_encrypt_mac:
                raise IntegrityError()
            decrypted_value = self.crypto.symmetric_decrypt(
                encrypted_value, random_key_for_value, 'AES', 'CBC', value_iv)
            return decrypted_value
        except:
            raise IntegrityError()
예제 #21
0
    def retrieve_dict(self):
        username_dictionary = path_join(self.username, "dictionary")
        username_keys = path_join(self.username, "dict_keys")
        if self.storage_server.get(username_dictionary) is None:
            dictionary = {}
            return dictionary

        d_key = self.storage_server.get(username_keys)
        decrypted_d_key = self.crypto.asymmetric_decrypt(
            d_key, self.private_key)
        dictionary_items_as_string = self.storage_server.get(
            username_dictionary)
        dictionary_items_as_list = util.from_json_string(
            dictionary_items_as_string)
        the_iv = dictionary_items_as_list[0]
        dictionary = dictionary_items_as_list[1]
        dictionary = self.crypto.symmetric_decrypt(dictionary, decrypted_d_key,
                                                   'AES', 'CBC', the_iv)
        dictionary = util.from_json_string(dictionary)
        return dictionary
예제 #22
0
    def receive_share(self, from_username, newname, message):
        #print(message)
        message_as_list = util.from_json_string(message)
        sharename = message_as_list[0]
        data_key = message_as_list[1]
        data_mac_key = message_as_list[2]

        dictionary = None
        uid = self.resolve(path_join(self.username, newname))
        random_id = self.crypto.get_random_bytes(16)
        random_key_for_value = self.crypto.get_random_bytes(16)
        random_key_for_dictionary = self.crypto.get_random_bytes(16)
        random_key_for_value_mac = self.crypto.get_random_bytes(16)
        random_key_for_dict_mac = self.crypto.get_random_bytes(16)

        value_iv = self.crypto.get_random_bytes(16)
        encrypted_random_key_for_dictionary = self.crypto.asymmetric_encrypt(
            random_key_for_dictionary, self.private_key.publickey())
        username_keys = path_join(self.username, "dict_keys")
        username_dictionary = path_join(self.username, "dictionary")
        if self.storage_server.get(username_keys) is None:
            self.storage_server.put(username_keys,
                                    encrypted_random_key_for_dictionary)
        else:
            e_random_key_for_dictionary = self.storage_server.get(
                username_keys)
            random_key_for_dictionary = self.crypto.asymmetric_decrypt(
                e_random_key_for_dictionary, self.private_key)
        dictionary = self.retrieve_dict()

        dictionary[path_join(self.username, newname)] = [
            random_id, random_key_for_value, random_key_for_value_mac,
            data_key, data_mac_key
        ]

        dictionary_iv = self.crypto.get_random_bytes(16)
        dictionary_as_string = util.to_json_string(dictionary)
        dictionary_encrypt = self.crypto.symmetric_encrypt(
            dictionary_as_string, random_key_for_dictionary, 'AES', 'CBC',
            dictionary_iv)
        dictionary_encrypt_mac = self.crypto.message_authentication_code(
            dictionary_encrypt, random_key_for_dict_mac, 'SHA256')
        list_of_items = [
            dictionary_iv, dictionary_encrypt, dictionary_encrypt_mac
        ]
        list_of_items_as_string = util.to_json_string(list_of_items)
        self.storage_server.put(username_dictionary, list_of_items_as_string)

        #my_id = path_join(self.username, newname)
        my_id = random_id

        self.storage_server.put(
            my_id, "[POINTER] " +
            sharename)  #message[i] if we add more stuff to message
예제 #23
0
    def receive_share(self, from_username, newname, message):
        # Replace with your implementation (not needed for Part 1)
        '''
        d_key = self.storage_server.get("dict_key")
        dictionary_items_as_string = self.storage_server.get("dict")
        dictionary_items_as_list = util.from_json_string(dictionary_items_as_string)
        the_iv = dictionary_items_as_list[0]
        dictionary = dictionary_items_as_list[1]
        dictionary_signature = dictionary_items_as_list[2]
        dictionary = self.crypto.symmetric_decrypt(dictionary, d_key, 'AES', 'CBC', the_iv)
        dictionary = util.from_json_string(dictionary)
        random_id = self.crypto.get_random_bytes(16)
        random_key_for_value = self.crypto.get_random_bytes(16)
        dictionary[uid] = (random_id, random_key_for_value)
        '''
        d_key = self.storage_server.get("dict_key")
        dictionary_items_as_string = self.storage_server.get("dict")
        dictionary_items_as_list = util.from_json_string(dictionary_items_as_string)
        the_iv = dictionary_items_as_list[0]
        dictionary = dictionary_items_as_list[1]
        dictionary_signature = dictionary_items_as_list[2]
        dictionary = self.crypto.symmetric_decrypt(dictionary, d_key, 'AES', 'CBC', the_iv)
        dictionary = util.from_json_string(dictionary)

        from_users_random_id = dictionary.get(path_join(from_username, newname))

        my_id = path_join(self.username, newname)

        dictionary[my_id] = from_users_random_id

        dictionary_iv = self.crypto.get_random_bytes(16)
        string_dict = util.to_json_string(dictionary)

        dictionary_encrypt = self.crypto.symmetric_encrypt(string_dict, d_key, 'AES', 'CBC', dictionary_iv)

        list_of_items = [dictionary_iv, dictionary_encrypt, 'LOL']
        list_of_items_as_string = util.to_json_string(list_of_items)
        self.storage_server.put("dict", list_of_items_as_string)

        self.storage_server.put(my_id, "[POINTER] " + message)
예제 #24
0
파일: client.py 프로젝트: Sharabesh/CS161
    def get_dir(self):
        value = self.storage_server.get(self.dir_loc)
        if not value:
            return False

        try:
            dir_pkg = from_json_string(value)

            iv = dir_pkg['iv']
            mac = dir_pkg['mac']
            enc_value = dir_pkg['enc_value']

            if not self.verify_mac(self.dir_loc + iv + enc_value,
                                   self.dir_mac_key, mac):
                raise IntegrityError

            dir_str = self.sym_dec(enc_value, iv, self.dir_enc_key)
            self.dir = from_json_string(dir_str)
            return True

        except (ValueError, TypeError, KeyError, CryptoError):
            raise IntegrityError
예제 #25
0
    def share(self, user, name):
        # Replace with your implementation (not needed for Part 1)
        sharename = path_join(self.username, "sharewith", user, name)
        uid = path_join(self.username, name)
        random_key_for_dictionary = self.storage_server.get("dict_key")
        dictionary_items_as_string = self.storage_server.get("dict")
           
        if dictionary_items_as_string is None:
            return None
        dictionary_items_as_list = util.from_json_string(dictionary_items_as_string)
        dictionary_iv = dictionary_items_as_list[0]
        encrypted_dictionary = dictionary_items_as_list[1]
        encrypted_dictionary_signature = dictionary_items_as_list[2]
        decrypted_dictionary = self.crypto.symmetric_decrypt(encrypted_dictionary, random_key_for_dictionary, 'AES', 'CBC', dictionary_iv)
        actual_dictionary = util.from_json_string(decrypted_dictionary)
        random_keys = actual_dictionary.get(uid)
        #if random_keys is None:
            #return None
        random_id = random_keys[0]
        random_key_for_value = random_keys[1]
        '''
        #share_uid = path_join(user, name)
        actual_dictionary[uid] = (random_id, random_key_for_value)
    
        dictionary_iv = self.crypto.get_random_bytes(16)
        string_dict = util.to_json_string(actual_dictionary)
        dictionary_encrypt = self.crypto.symmetric_encrypt(string_dict, random_key_for_dictionary, 'AES', 'CBC', dictionary_iv)

        
        dictionary_encrypt_sign = self.crypto.asymmetric_sign(dictionary_encrypt, self.private_key)
        
        list_of_items = [dictionary_iv, dictionary_encrypt, dictionary_encrypt_sign]
        list_of_items_as_string = util.to_json_string(list_of_items)
        self.storage_server.put("dict", list_of_items_as_string)
        '''

        self.storage_server.put(sharename, "[POINTER] " + random_id)
        return sharename
예제 #26
0
파일: client.py 프로젝트: Sharabesh/CS161
    def follow_gateways(self, loc, enc_key, mac_key):
        """
        returns a link to the actual file, as well as the keys used to access it.
        """
        value = self.storage_server.get(loc)
        if not value:
            # we know we uploaded the file, and it was later deleted
            raise IntegrityError()

        try:
            pkg = from_json_string(value)

            iv = pkg['iv']
            mac = pkg['mac']
            enc_value = pkg['enc_value']

            if not self.verify_mac(loc + iv + enc_value, mac_key, mac):
                raise IntegrityError

            value = self.sym_dec(enc_value, iv, enc_key)
            gateway_record = from_json_string(value)
            next_loc = gateway_record['loc']
            next_enc_key = gateway_record['enc_key']
            next_mac_key = gateway_record['mac_key']

            if gateway_record['is_leaf']:
                return {
                    'loc': next_loc,
                    'mac_key': next_mac_key,
                    'enc_key': next_enc_key
                }
            else:
                return self.follow_gateways(next_loc, next_enc_key,
                                            next_mac_key)

        except (ValueError, TypeError, KeyError, CryptoError):
            raise IntegrityError
예제 #27
0
파일: client.py 프로젝트: Sharabesh/CS161
    def download_merkle(self, loc, enc_key, mac_key, root=True):
        server_node_val = self.storage_server.get(loc)
        if not server_node_val:
            raise IntegrityError

        try:
            server_node = from_json_string(server_node_val)

            if root:
                # check top hash validity
                node_pkg = server_node
                server_node = from_json_string(node_pkg['value'])
                if self.mac(loc + node_pkg['value'],
                            mac_key) != node_pkg['mac']:
                    raise IntegrityError

            data = ''

            if server_node['data']:
                data += self.sym_dec(server_node['data'], server_node['iv'],
                                     enc_key)

            if server_node['left']:
                data += self.download_merkle(server_node['left'], enc_key,
                                             mac_key, False)

            if server_node['right']:
                data += self.download_merkle(server_node['right'], enc_key,
                                             mac_key, False)

            if root:
                return (data, server_node['hash'])
            else:
                return data
        except:
            raise IntegrityError
예제 #28
0
파일: client.py 프로젝트: Sharabesh/CS161
    def receive_share(self, from_username, newname, message):
        # Replace with your implementation (not needed for Part 1)
        from_pub_key = self.pks.get_public_key(from_username)
        if not from_pub_key:
            return False

        try:
            msg = from_json_string(message)
            enc_value = msg['enc_value']
            enc_enc_key = msg['enc_enc_key']
            iv = msg['iv']
            sig = msg['sig']

            if not self.crypto.asymmetric_verify(enc_enc_key + iv + enc_value,
                                                 sig, from_pub_key):
                raise IntegrityError

            enc_key = self.crypto.asymmetric_decrypt(enc_enc_key,
                                                     self.private_key)
            value = self.sym_dec(enc_value, iv, enc_key)
            share_record = from_json_string(value)

            file_record = {
                'loc': share_record['loc'],
                'enc_key': share_record['enc_key'],
                'mac_key': share_record['mac_key'],
                'is_gateway': True,
                'shared': {}
            }

            self.get_dir()
            self.dir[newname] = file_record
            self.upload_dir()

        except (ValueError, TypeError, KeyError, CryptoError):
            raise IntegrityError
예제 #29
0
    def resolve(self, uid, e_key, m_key, mode=None):
        """Follows [P]'s until we reach the a None or [D] and return the data"""
        while True:
            pkt = self.storage_server.get(uid)
            if pkt is None:
                return None

            elif pkt.startswith("[P]"):
                uid = pkt[4:]

            else:
                # Split the packet into the encrypted stuff and the mac that came along with it
                iv_encrypted_value, mac = pkt[:len(pkt) - 64], pkt[len(pkt) -
                                                                   64:]

                # Recreate the mac using m_key and compare it with the one that came along with it
                try:
                    testmac = self.crypto.message_authentication_code(
                        iv_encrypted_value, m_key, 'SHA256')
                except:
                    raise IntegrityError
                if testmac != mac:
                    raise IntegrityError

                # Split into iv and the encrypted file value and decrypt accordingly
                iv = iv_encrypted_value[:32]
                encrypted_value = iv_encrypted_value[32:]
                value = self.crypto.symmetric_decrypt(encrypted_value, e_key,
                                                      'AES', 'CBC', iv)

                if value.startswith("[D]"):
                    if mode == "update":
                        return uid, e_key, m_key
                    else:
                        value = value[4:]
                        test_swap_check = value[:32]
                        value = value[
                            32:]  # This value should be a json stringed list

                        if test_swap_check != uid:
                            raise IntegrityError

                        return self.grabData(from_json_string(value), e_key,
                                             m_key)

                uid = value[:32]
                e_key = value[32:64]
                m_key = value[64:]
예제 #30
0
    def check_integrity_and_get_value(self, ka, data_id):
        all_value_string = self.storage_server.get(data_id)
        if not all_value_string:
            return None
        else:
            try:
                value_string, MACed_value_string = util.from_json_string(
                    all_value_string[7:])
            except:
                raise IntegrityError()

            if self.crypto.message_authentication_code(
                    value_string, ka, "MD5") == MACed_value_string:
                return value_string
            else:
                raise IntegrityError()