diff options
author | Bjoern Schiessle <schiessle@owncloud.com> | 2015-04-01 14:24:56 +0200 |
---|---|---|
committer | Thomas Müller <thomas.mueller@tmit.eu> | 2015-04-07 13:30:30 +0200 |
commit | a057108c0c1ec77b6f61f6f387c0714c84653254 (patch) | |
tree | 97df67d9dc26852d6cc6c4163a5e3d20f00ee3aa /apps | |
parent | 51302d58120e9050fb8842cf63cef88620f74203 (diff) | |
download | nextcloud-server-a057108c0c1ec77b6f61f6f387c0714c84653254.tar.gz nextcloud-server-a057108c0c1ec77b6f61f6f387c0714c84653254.zip |
make recovery key work
Diffstat (limited to 'apps')
-rw-r--r-- | apps/encryption/appinfo/application.php | 1 | ||||
-rw-r--r-- | apps/encryption/controller/recoverycontroller.php | 3 | ||||
-rw-r--r-- | apps/encryption/hooks/userhooks.php | 23 | ||||
-rw-r--r-- | apps/encryption/lib/keymanager.php | 14 | ||||
-rw-r--r-- | apps/encryption/lib/recovery.php | 95 |
5 files changed, 82 insertions, 54 deletions
diff --git a/apps/encryption/appinfo/application.php b/apps/encryption/appinfo/application.php index 955146f7182..0d1bd0d6bed 100644 --- a/apps/encryption/appinfo/application.php +++ b/apps/encryption/appinfo/application.php @@ -75,6 +75,7 @@ class Application extends \OCP\AppFramework\App { $server->getUserSession(), $container->query('Util'), new \OCA\Encryption\Session($server->getSession()), + $container->query('Crypt'), $container->query('Recovery')) ]); diff --git a/apps/encryption/controller/recoverycontroller.php b/apps/encryption/controller/recoverycontroller.php index d115feb8e39..24d7f5a06ed 100644 --- a/apps/encryption/controller/recoverycontroller.php +++ b/apps/encryption/controller/recoverycontroller.php @@ -142,6 +142,9 @@ class RecoveryController extends Controller { } } + /** + * @NoAdminRequired + */ public function userSetRecovery($userEnableRecovery) { if ($userEnableRecovery === '0' || $userEnableRecovery === '1') { diff --git a/apps/encryption/hooks/userhooks.php b/apps/encryption/hooks/userhooks.php index 330d8a873ba..3b56135c36b 100644 --- a/apps/encryption/hooks/userhooks.php +++ b/apps/encryption/hooks/userhooks.php @@ -25,6 +25,7 @@ namespace OCA\Encryption\Hooks; use OCP\Util as OCUtil; use OCA\Encryption\Hooks\Contracts\IHook; use OCA\Encryption\KeyManager; +use OCA\Encryption\Crypto\Crypt; use OCA\Encryption\Users\Setup; use OCP\App; use OCP\ILogger; @@ -62,6 +63,10 @@ class UserHooks implements IHook { * @var Recovery */ private $recovery; + /** + * @var Crypt + */ + private $crypt; /** * UserHooks constructor. @@ -72,6 +77,7 @@ class UserHooks implements IHook { * @param IUserSession $user * @param Util $util * @param Session $session + * @param Crypt $crypt * @param Recovery $recovery */ public function __construct(KeyManager $keyManager, @@ -80,6 +86,7 @@ class UserHooks implements IHook { IUserSession $user, Util $util, Session $session, + Crypt $crypt, Recovery $recovery) { $this->keyManager = $keyManager; @@ -89,6 +96,7 @@ class UserHooks implements IHook { $this->util = $util; $this->session = $session; $this->recovery = $recovery; + $this->crypt = $crypt; } /** @@ -214,7 +222,7 @@ class UserHooks implements IHook { // Save private key if ($encryptedPrivateKey) { - $this->setPrivateKey($this->user->getUser()->getUID(), + $this->keyManager->setPrivateKey($this->user->getUser()->getUID(), $encryptedPrivateKey); } else { $this->log->error('Encryption could not update users encryption password'); @@ -231,28 +239,31 @@ class UserHooks implements IHook { // ...we have a recovery password and the user enabled the recovery key // ...encryption was activated for the first time (no keys exists) // ...the user doesn't have any files - if (($util->recoveryEnabledForUser() && $recoveryPassword) || !$this->userHasKeys($user) || !$util->userHasFiles($user) + if ( + ($this->recovery->isRecoveryEnabledForUser($user) && $recoveryPassword) + || !$this->keyManager->userHasKeys($user) + || !$this->util->userHasFiles($user) ) { // backup old keys - $this->backupAllKeys('recovery'); + //$this->backupAllKeys('recovery'); $newUserPassword = $params['password']; $keyPair = $this->crypt->createKeyPair(); // Save public key - $this->setPublicKey($user, $keyPair['publicKey']); + $this->keyManager->setPublicKey($user, $keyPair['publicKey']); // Encrypt private key with new password $encryptedKey = $this->crypt->symmetricEncryptFileContent($keyPair['privateKey'], $newUserPassword); if ($encryptedKey) { - $this->setPrivateKey($user, $encryptedKey); + $this->keyManager->setPrivateKey($user, $encryptedKey); if ($recoveryPassword) { // if recovery key is set we can re-encrypt the key files - $this->recovery->recoverUsersFiles($recoveryPassword); + $this->recovery->recoverUsersFiles($recoveryPassword, $user); } } else { $this->log->error('Encryption Could not update users encryption password'); diff --git a/apps/encryption/lib/keymanager.php b/apps/encryption/lib/keymanager.php index f3f96b9ef21..4c5cb1365ea 100644 --- a/apps/encryption/lib/keymanager.php +++ b/apps/encryption/lib/keymanager.php @@ -206,7 +206,6 @@ class KeyManager { if ($encryptedKey) { $this->setPrivateKey($uid, $encryptedKey); - $this->config->setAppValue('encryption', 'recoveryAdminEnabled', 0); return true; } return false; @@ -356,6 +355,19 @@ class KeyManager { } /** + * get the encrypted file key + * + * @param $path + * @return string + */ + public function getEncryptedFileKey($path) { + $encryptedFileKey = $this->keyStorage->getFileKey($path, + $this->fileKeyId); + + return $encryptedFileKey; + } + + /** * delete share key * * @param string $path diff --git a/apps/encryption/lib/recovery.php b/apps/encryption/lib/recovery.php index 4201b829ec9..34acdd0a6e3 100644 --- a/apps/encryption/lib/recovery.php +++ b/apps/encryption/lib/recovery.php @@ -156,10 +156,15 @@ class Recovery { } /** + * check if recovery is enabled for user + * + * @param string $user if no user is given we check the current logged-in user + * * @return bool */ - public function recoveryEnabledForUser() { - $recoveryMode = $this->config->getUserValue($this->user->getUID(), + public function isRecoveryEnabledForUser($user = '') { + $uid = empty($user) ? $this->user->getUID() : $user; + $recoveryMode = $this->config->getUserValue($uid, 'encryption', 'recoveryEnabled', 0); @@ -168,6 +173,17 @@ class Recovery { } /** + * check if recovery is key is enabled by the administrator + * + * @return bool + */ + public function isRecoveryKeyEnabled() { + $enabled = $this->config->getAppValue('encryption', 'recoveryAdminEnabled', 0); + + return ($enabled === '1'); + } + + /** * @param string $value * @return bool */ @@ -234,15 +250,18 @@ class Recovery { } /** - * @param $recoveryPassword + * recover users files with the recovery key + * + * @param string $recoveryPassword + * @param string $user */ - public function recoverUsersFiles($recoveryPassword) { - $encryptedKey = $this->keyManager->getSystemPrivateKey(); + public function recoverUsersFiles($recoveryPassword, $user) { + $encryptedKey = $this->keyManager->getSystemPrivateKey($this->keyManager->getRecoveryKeyId()); $privateKey = $this->crypt->decryptPrivateKey($encryptedKey, $recoveryPassword); - $this->recoverAllFiles('/', $privateKey); + $this->recoverAllFiles('/' . $user . '/files/', $privateKey); } /** @@ -250,12 +269,12 @@ class Recovery { * @param $privateKey */ private function recoverAllFiles($path, $privateKey) { - $dirContent = $this->files->getDirectoryContent($path); + $dirContent = $this->view->getDirectoryContent($path); foreach ($dirContent as $item) { // Get relative path from encryption/keyfiles - $filePath = substr($item['path'], strlen('encryption/keys')); - if ($this->files->is_dir($this->user->getUID() . '/files' . '/' . $filePath)) { + $filePath = $item->getPath(); + if ($this->view->is_dir($filePath)) { $this->recoverAllFiles($filePath . '/', $privateKey); } else { $this->recoverFile($filePath, $privateKey); @@ -265,50 +284,32 @@ class Recovery { } /** - * @param $filePath - * @param $privateKey + * @param string $path + * @param string $privateKey */ - private function recoverFile($filePath, $privateKey) { - $sharingEnabled = Share::isEnabled(); - $uid = $this->user->getUID(); - - // Find out who, if anyone, is sharing the file - if ($sharingEnabled) { - $result = Share::getUsersSharingFile($filePath, - $uid, - true); - $userIds = $result['users']; - $userIds[] = 'public'; - } else { - $userIds = [ - $uid, - $this->recoveryKeyId - ]; + private function recoverFile($path, $privateKey) { + $encryptedFileKey = $this->keyManager->getEncryptedFileKey($path); + $shareKey = $this->keyManager->getShareKey($path, $this->keyManager->getRecoveryKeyId()); + + if ($encryptedFileKey && $shareKey && $privateKey) { + $fileKey = $this->crypt->multiKeyDecrypt($encryptedFileKey, + $shareKey, + $privateKey); } - $filteredUids = $this->filterShareReadyUsers($userIds); - // Decrypt file key - $encKeyFile = $this->keyManager->getFileKey($filePath, - $uid); - - $shareKey = $this->keyManager->getShareKey($filePath, - $uid); - - $plainKeyFile = $this->crypt->multiKeyDecrypt($encKeyFile, - $shareKey, - $privateKey); + if (!empty($fileKey)) { + $accessList = $this->file->getAccessList($path); + $publicKeys = array(); + foreach ($accessList['users'] as $uid) { + $publicKeys[$uid] = $this->keyManager->getPublicKey($uid); + } - // Encrypt the file key again to all users, this time with the new publick keyt for the recovered user - $userPublicKeys = $this->keyManager->getPublicKeys($filteredUids['ready']); - $multiEncryptionKey = $this->crypt->multiKeyEncrypt($plainKeyFile, - $userPublicKeys); + $publicKeys = $this->keyManager->addSystemKeys($accessList, $publicKeys); - $this->keyManager->setFileKey($multiEncryptionKey['data'], - $uid); + $encryptedKeyfiles = $this->crypt->multiKeyEncrypt($fileKey, $publicKeys); + $this->keyManager->setAllFileKeys($path, $encryptedKeyfiles); + } - $this->keyManager->setShareKey($filePath, - $uid, - $multiEncryptionKey['keys']); } |