/** * Decrypt a keyfile * @param string $filePath * @param string $privateKey * @return false|string */ private function decryptKeyfile($filePath, $privateKey) { // Get the encrypted keyfile $encKeyfile = Keymanager::getFileKey($this->view, $this, $filePath); // The file has a shareKey and must use it for decryption $shareKey = Keymanager::getShareKey($this->view, $this->keyId, $this, $filePath); $plainKeyfile = Crypt::multiKeyDecrypt($encKeyfile, $shareKey, $privateKey); return $plainKeyfile; }
/** * decrypt given file with recovery key and encrypt it again to the owner and his new key * @param string $file * @param string $privateKey recovery key to decrypt the file */ private function recoverFile($file, $privateKey) { $sharingEnabled = \OCP\Share::isEnabled(); // Find out who, if anyone, is sharing the file if ($sharingEnabled) { $result = \OCP\Share::getUsersSharingFile($file, $this->userId, true); $userIds = $result['users']; $userIds[] = $this->recoveryKeyId; if ($result['public']) { $userIds[] = $this->publicShareKeyId; } } else { $userIds = array($this->userId, $this->recoveryKeyId); } $filteredUids = $this->filterShareReadyUsers($userIds); //decrypt file key $encKeyfile = Keymanager::getFileKey($this->view, $this, $file); $shareKey = Keymanager::getShareKey($this->view, $this->recoveryKeyId, $this, $file); $plainKeyfile = Crypt::multiKeyDecrypt($encKeyfile, $shareKey, $privateKey); // encrypt file key again to all users, this time with the new public key for the recovered use $userPubKeys = Keymanager::getPublicKeys($this->view, $filteredUids['ready']); $multiEncKey = Crypt::multiKeyEncrypt($plainKeyfile, $userPubKeys); Keymanager::setFileKey($this->view, $this, $file, $multiEncKey['data']); Keymanager::setShareKeys($this->view, $this, $file, $multiEncKey['keys']); }
/** * @brief Fetch the plain encryption key for the file and set it as plainKey property * @internal param bool $generate if true, a new key will be generated if none can be found * @return bool true on key found and set, false on key not found and new key generated and set */ public function getKey() { // Check if key is already set if (isset($this->plainKey) && isset($this->encKeyfile)) { return true; } // Fetch and decrypt keyfile // Fetch existing keyfile $this->encKeyfile = Keymanager::getFileKey($this->rootView, $this->userId, $this->relPath); // If a keyfile already exists if ($this->encKeyfile) { // if there is no valid private key return false if ($this->privateKey === false) { // if private key is not valid redirect user to a error page \OCA\Encryption\Helper::redirectToErrorPage(); return false; } $shareKey = Keymanager::getShareKey($this->rootView, $this->userId, $this->relPath); $this->plainKey = Crypt::multiKeyDecrypt($this->encKeyfile, $shareKey, $this->privateKey); return true; } else { return false; } }
/** * Fetch the plain encryption key for the file and set it as plainKey property * @internal param bool $generate if true, a new key will be generated if none can be found * @return bool true on key found and set, false on key not found and new key generated and set */ public function getKey() { // Check if key is already set if (isset($this->plainKey) && isset($this->encKeyfile)) { return true; } // Fetch and decrypt keyfile // Fetch existing keyfile $util = new \OCA\Encryption\Util($this->rootView, $this->userId); $this->encKeyfile = Keymanager::getFileKey($this->rootView, $util, $this->relPath); // If a keyfile already exists if ($this->encKeyfile) { $shareKey = Keymanager::getShareKey($this->rootView, $this->keyId, $util, $this->relPath); // if there is no valid private key return false if ($this->privateKey === false) { // if private key is not valid redirect user to a error page \OCA\Encryption\Helper::redirectToErrorPage($this->session); return false; } if ($shareKey === false) { // if no share key is available redirect user to a error page \OCA\Encryption\Helper::redirectToErrorPage($this->session, \OCA\Encryption\Crypt::ENCRYPTION_NO_SHARE_KEY_FOUND); return false; } $this->plainKey = Crypt::multiKeyDecrypt($this->encKeyfile, $shareKey, $this->privateKey); return true; } else { $this->newFile = true; return false; } }
/** * @brief Decrypt a keyfile without knowing how it was encrypted * @param string $filePath * @param string $fileOwner * @param string $privateKey * @return bool|string * @note Checks whether file was encrypted with openssl_seal or * openssl_encrypt, and decrypts accrdingly * @note This was used when 2 types of encryption for keyfiles was used, * but now we've switched to exclusively using openssl_seal() */ public function decryptUnknownKeyfile($filePath, $fileOwner, $privateKey) { // Get the encrypted keyfile // NOTE: the keyfile format depends on how it was encrypted! At // this stage we don't know how it was encrypted $encKeyfile = Keymanager::getFileKey($this->view, $this->userId, $filePath); // We need to decrypt the keyfile // Has the file been shared yet? if ($this->userId === $fileOwner && !Keymanager::getShareKey($this->view, $this->userId, $filePath)) { // The file has no shareKey, and its keyfile must be // decrypted conventionally $plainKeyfile = Crypt::keyDecrypt($encKeyfile, $privateKey); } else { // The file has a shareKey and must use it for decryption $shareKey = Keymanager::getShareKey($this->view, $this->userId, $filePath); $plainKeyfile = Crypt::multiKeyDecrypt($encKeyfile, $shareKey, $privateKey); } return $plainKeyfile; }