diff options
Diffstat (limited to 'apps/encryption/lib/Recovery.php')
-rw-r--r-- | apps/encryption/lib/Recovery.php | 157 |
1 files changed, 44 insertions, 113 deletions
diff --git a/apps/encryption/lib/Recovery.php b/apps/encryption/lib/Recovery.php index 17533e7b114..38e78f5e822 100644 --- a/apps/encryption/lib/Recovery.php +++ b/apps/encryption/lib/Recovery.php @@ -1,102 +1,43 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Björn Schießle <bjoern@schiessle.org> - * @author Clark Tomlinson <fallen013@gmail.com> - * @author Lukas Reschke <lukas@statuscode.ch> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ - namespace OCA\Encryption; - +use OC\Files\View; use OCA\Encryption\Crypto\Crypt; -use OCP\Encryption\Keys\IStorage; +use OCP\Encryption\IFile; use OCP\IConfig; use OCP\IUser; use OCP\IUserSession; use OCP\PreConditionNotMetException; -use OCP\Security\ISecureRandom; -use OC\Files\View; -use OCP\Encryption\IFile; class Recovery { - - /** * @var null|IUser */ protected $user; - /** - * @var Crypt - */ - protected $crypt; - /** - * @var ISecureRandom - */ - private $random; - /** - * @var KeyManager - */ - private $keyManager; - /** - * @var IConfig - */ - private $config; - /** - * @var IStorage - */ - private $keyStorage; - /** - * @var View - */ - private $view; - /** - * @var IFile - */ - private $file; /** - * @param IUserSession $user + * @param IUserSession $userSession * @param Crypt $crypt - * @param ISecureRandom $random * @param KeyManager $keyManager * @param IConfig $config - * @param IStorage $keyStorage * @param IFile $file * @param View $view */ - public function __construct(IUserSession $user, - Crypt $crypt, - ISecureRandom $random, - KeyManager $keyManager, - IConfig $config, - IStorage $keyStorage, - IFile $file, - View $view) { - $this->user = ($user && $user->isLoggedIn()) ? $user->getUser() : false; - $this->crypt = $crypt; - $this->random = $random; - $this->keyManager = $keyManager; - $this->config = $config; - $this->keyStorage = $keyStorage; - $this->view = $view; - $this->file = $file; + public function __construct( + IUserSession $userSession, + protected Crypt $crypt, + private KeyManager $keyManager, + private IConfig $config, + private IFile $file, + private View $view, + ) { + $this->user = ($userSession->isLoggedIn()) ? $userSession->getUser() : null; } /** @@ -109,7 +50,7 @@ class Recovery { if (!$keyManager->recoveryKeyExists()) { $keyPair = $this->crypt->createKeyPair(); - if(!is_array($keyPair)) { + if (!is_array($keyPair)) { return false; } @@ -117,7 +58,7 @@ class Recovery { } if ($keyManager->checkRecoveryPassword($password)) { - $appConfig->setAppValue('encryption', 'recoveryAdminEnabled', 1); + $appConfig->setAppValue('encryption', 'recoveryAdminEnabled', '1'); return true; } @@ -134,7 +75,7 @@ class Recovery { public function changeRecoveryKeyPassword($newPassword, $oldPassword) { $recoveryKey = $this->keyManager->getSystemPrivateKey($this->keyManager->getRecoveryKeyId()); $decryptedRecoveryKey = $this->crypt->decryptPrivateKey($recoveryKey, $oldPassword); - if($decryptedRecoveryKey === false) { + if ($decryptedRecoveryKey === false) { return false; } $encryptedRecoveryKey = $this->crypt->encryptPrivateKey($decryptedRecoveryKey, $newPassword); @@ -155,7 +96,7 @@ class Recovery { if ($keyManager->checkRecoveryPassword($recoveryPassword)) { // Set recoveryAdmin as disabled - $this->config->setAppValue('encryption', 'recoveryAdminEnabled', 0); + $this->config->setAppValue('encryption', 'recoveryAdminEnabled', '0'); return true; } return false; @@ -169,7 +110,7 @@ class Recovery { * @return bool */ public function isRecoveryEnabledForUser($user = '') { - $uid = empty($user) ? $this->user->getUID() : $user; + $uid = $user === '' ? $this->user->getUID() : $user; $recoveryMode = $this->config->getUserValue($uid, 'encryption', 'recoveryEnabled', @@ -184,7 +125,7 @@ class Recovery { * @return bool */ public function isRecoveryKeyEnabled() { - $enabled = $this->config->getAppValue('encryption', 'recoveryAdminEnabled', 0); + $enabled = $this->config->getAppValue('encryption', 'recoveryAdminEnabled', '0'); return ($enabled === '1'); } @@ -194,7 +135,6 @@ class Recovery { * @return bool */ public function setRecoveryForUser($value) { - try { $this->config->setUserValue($this->user->getUID(), 'encryption', @@ -215,27 +155,29 @@ class Recovery { /** * add recovery key to all encrypted files - * @param string $path */ - private function addRecoveryKeys($path) { + private function addRecoveryKeys(string $path): void { $dirContent = $this->view->getDirectoryContent($path); foreach ($dirContent as $item) { $filePath = $item->getPath(); if ($item['type'] === 'dir') { $this->addRecoveryKeys($filePath . '/'); } else { - $fileKey = $this->keyManager->getFileKey($filePath, $this->user->getUID()); + $fileKey = $this->keyManager->getFileKey($filePath, $this->user->getUID(), null); if (!empty($fileKey)) { $accessList = $this->file->getAccessList($filePath); - $publicKeys = array(); + $publicKeys = []; foreach ($accessList['users'] as $uid) { $publicKeys[$uid] = $this->keyManager->getPublicKey($uid); } $publicKeys = $this->keyManager->addSystemKeys($accessList, $publicKeys, $this->user->getUID()); - $encryptedKeyfiles = $this->crypt->multiKeyEncrypt($fileKey, $publicKeys); - $this->keyManager->setAllFileKeys($filePath, $encryptedKeyfiles); + $shareKeys = $this->crypt->multiKeyEncrypt($fileKey, $publicKeys); + $this->keyManager->deleteLegacyFileKey($filePath); + foreach ($shareKeys as $uid => $keyFile) { + $this->keyManager->setShareKey($filePath, $uid, $keyFile); + } } } } @@ -243,9 +185,8 @@ class Recovery { /** * remove recovery key to all encrypted files - * @param string $path */ - private function removeRecoveryKeys($path) { + private function removeRecoveryKeys(string $path): void { $dirContent = $this->view->getDirectoryContent($path); foreach ($dirContent as $item) { $filePath = $item->getPath(); @@ -259,27 +200,20 @@ class Recovery { /** * recover users files with the recovery key - * - * @param string $recoveryPassword - * @param string $user */ - public function recoverUsersFiles($recoveryPassword, $user) { + public function recoverUsersFiles(string $recoveryPassword, string $user): void { $encryptedKey = $this->keyManager->getSystemPrivateKey($this->keyManager->getRecoveryKeyId()); $privateKey = $this->crypt->decryptPrivateKey($encryptedKey, $recoveryPassword); - if($privateKey !== false) { + if ($privateKey !== false) { $this->recoverAllFiles('/' . $user . '/files/', $privateKey, $user); } } /** * recover users files - * - * @param string $path - * @param string $privateKey - * @param string $uid */ - private function recoverAllFiles($path, $privateKey, $uid) { + private function recoverAllFiles(string $path, string $privateKey, string $uid): void { $dirContent = $this->view->getDirectoryContent($path); foreach ($dirContent as $item) { @@ -291,40 +225,37 @@ class Recovery { $this->recoverFile($filePath, $privateKey, $uid); } } - } /** * recover file - * - * @param string $path - * @param string $privateKey - * @param string $uid */ - private function recoverFile($path, $privateKey, $uid) { + private function recoverFile(string $path, string $privateKey, string $uid): void { $encryptedFileKey = $this->keyManager->getEncryptedFileKey($path); $shareKey = $this->keyManager->getShareKey($path, $this->keyManager->getRecoveryKeyId()); if ($encryptedFileKey && $shareKey && $privateKey) { - $fileKey = $this->crypt->multiKeyDecrypt($encryptedFileKey, + $fileKey = $this->crypt->multiKeyDecryptLegacy($encryptedFileKey, $shareKey, $privateKey); + } elseif ($shareKey && $privateKey) { + $fileKey = $this->crypt->multiKeyDecrypt($shareKey, $privateKey); } if (!empty($fileKey)) { $accessList = $this->file->getAccessList($path); - $publicKeys = array(); + $publicKeys = []; foreach ($accessList['users'] as $user) { $publicKeys[$user] = $this->keyManager->getPublicKey($user); } $publicKeys = $this->keyManager->addSystemKeys($accessList, $publicKeys, $uid); - $encryptedKeyfiles = $this->crypt->multiKeyEncrypt($fileKey, $publicKeys); - $this->keyManager->setAllFileKeys($path, $encryptedKeyfiles); + $shareKeys = $this->crypt->multiKeyEncrypt($fileKey, $publicKeys); + $this->keyManager->deleteLegacyFileKey($path); + foreach ($shareKeys as $uid => $keyFile) { + $this->keyManager->setShareKey($path, $uid, $keyFile); + } } - } - - } |