def _getCurrUsersPass_(): """ Gets the current users and passwords and returns a dictionary with the users and passwords. If file doesn't exist, it creates it with admin's details return: dict with users array (accesed by 'users' key) and passwords array (accessed by 'passwords' key) """ # if file doesn't exist, create file with admin details if not os.path.exists(USERS_FILE): ret = {'users': ["admin"], 'passwords': [ADMIN_PASS]} saveFile(USERS_FILE, "admin" + USER_PASS_DELIM + ADMIN_PASS + USER_DELIM) return ret # get users file contents curr_users_contents = readFile(USERS_FILE) users_passwords = curr_users_contents.split(USER_DELIM) ret = {'users': [], 'passwords': []} # init users and pass dict # seperate users from passwords for userPass in users_passwords: if not userPass: # if string is empty we're done break tmpArr = userPass.split(USER_PASS_DELIM) ret['users'].append(tmpArr[0]) ret['passwords'].append(tmpArr[1]) return ret
def upload_file(self, filename, fernet): """ Saves and uploads an encrypted version of the file named filename, if the file exists locally and no duplicate is on the drive param filename: Name of the file to be uploaded param fernet: The fernet object created in KeyManagementSystem class return: Filename of encrypted file, if file uploaded successfully, else None """ # add path to filename if needed prevFilename = filename filename = self.normaliseFilename(filename) # return None if file doesn't exist if not os.path.exists(filename): print("Error 404: File specified not found") return None # get the drive's main folder ID folderID = self._get_file_ID_(DRIVE_FOLDER, DRIVE_ROOT_ID) # Create and share folder on drive if it doesnt exist, and get folderID if folderID == None: folderID = self.__create_share_folder__() print("Created shared folder on drive") # Check if file with identical name is already on the drive encryptedFilename = prevFilename + ENCR_EXTENSION encryptedFileID = self._get_file_ID_(encryptedFilename, folderID) if encryptedFileID != None: # implies there's a file identically named print("This file is already up on the drive!") return None # Save encrypted file locally plain_text = readFile(filename) # getting file contents cipher_text = GoogleDriveAccess._encrypt_(plain_text, fernet) normEncryptedFilename = encryptedFilename normEncryptedFilename = self.normaliseFilename(normEncryptedFilename) saveFile(normEncryptedFilename, cipher_text) # Saving file locally # Upload encrypted file to google drive folder fileToUpload = self.drive.CreateFile({"title": encryptedFilename, "parents": [{"id": folderID}]}) fileToUpload.SetContentFile(normEncryptedFilename) # set file contents fileToUpload.Upload() # Delete local version of encrypted file here os.remove(normEncryptedFilename) return encryptedFilename
def save_new_users(users): """ Saves the new users to the relevant file, in proper format param users: Array of new users return: None """ # make content using array and delimiters content = "" for i in range(len(users)): content += users[i] + USER_DELIM # save the file saveFile(N_USERS_FILE, content)
def save_old_users(users_pass): """ Saves the old users to the relevant file, in proper format param users_pass: Dictionary containg arrays of old users and passwords return: None """ # make content using dictionary and delimiters content = "" for i in range(len(users_pass['users'])): content += users_pass['users'][i] + USER_PASS_DELIM content += users_pass['passwords'][i] + USER_DELIM # save the file saveFile(USERS_FILE, content)
def _getNewUsers_(): """ Reads contents of the new user files and gives back an array with new usernames. Create empty file if file doesn't exist return: Array with new usernames """ # Create emtpy file if it doesn't exist if not os.path.exists(N_USERS_FILE): saveFile(N_USERS_FILE, "") return [] # get new user's usernames new_users_contents = readFile(N_USERS_FILE) new_users = new_users_contents.split(USER_DELIM) return new_users[:-1] # ignore last empty element
def handle_new_user(username): """ Initialisation of a new user. Creates new folder for user files, generates private and public key and saves serialized private key, and also saves the encrypted symmetric key to user's folder, to be decrypted by the user's private key param username: username of the new user to be initialised return: the fernet """ driveAccess = GoogleDriveAccess( username ) # This creates a folder for the user, and also gives access to the drive # key pair generation and verification priv_key = rsa.generate_private_key(public_exponent=65537, key_size=2048, backend=default_backend()) pub_key = priv_key.public_key() # Serialization of private key for file storage priv_bytes = priv_key.private_bytes( encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.TraditionalOpenSSL, encryption_algorithm=serialization.NoEncryption()) # Save serialized private key to user's folder in plaintext folder_name = username + "_files/" filepath = folder_name + PRIV_KEY_FILE saveFile(filepath, priv_bytes) # encrypt (using user's pubkey) and save symmetric key to user's folder kms = KMS() encrypted_sym_key = pub_key.encrypt( kms.key, padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None)) filepath = folder_name + SHARED_KEY_FILE saveFile(filepath, encrypted_sym_key) # do what you do for the old user anywyay, and return the fernet it returns return handle_old_user(username)
def __generate_new_key__(self): """ Generates a new key (and fernet obj) and saves it to the file return: None """ # generate a key self.key = Fernet.generate_key() # create admin's directory if it doesn't exist if not os.path.isdir(ADMIN_FOLDER): os.mkdir(ADMIN_FOLDER) # save key to appropriate file in admin's directory saveFile(ADMIN_FOLDER + "/" + SHARED_KEY_FILE, self.key) # create fernet object self.fernet = Fernet(self.key) # create fernet obj # Broadcast the new key to everyone (method in group handler class) change_all_keys()
def download_file(self, filename, fernet): """ Downloads a file named filename from the drive and saves the decrypted version, if the file exists param filename: Name of the file to be downloaded param fernet: The fernet object created in KeyManagementSystem class return: Filename of decrypted file, if file downloaded successfully, else None """ # Add encrypt extension if it's not in filename if ENCR_EXTENSION not in filename: filename = filename + ENCR_EXTENSION # If drive's shared folder doesn't exist, return None folderID = self._get_file_ID_(DRIVE_FOLDER, DRIVE_ROOT_ID) if folderID == None: print("Error 404: Shared folder not found on drive") return None # Return None if file doesnt exist on drive fileID = self._get_file_ID_(filename, folderID) if fileID == None: print("Error 404: File specified does not exist on the drive") return None # Download encrypted file contents from google drive downloadedFile = self.drive.CreateFile({'id': fileID}) cipher_text = downloadedFile.GetContentString() # Get decrypted file data and save decrypted file locally plain_text = GoogleDriveAccess._decrypt_(cipher_text.encode('utf-8'), fernet) filename = self.normaliseFilename(filename) decryptedFilename = filename[ : -len(ENCR_EXTENSION)] saveFile(decryptedFilename, plain_text) return decryptedFilename