summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/encryption/appinfo/application.php11
-rw-r--r--apps/encryption/lib/keymanager.php24
-rw-r--r--apps/encryption/lib/recovery.php85
-rw-r--r--apps/encryption/lib/util.php97
-rw-r--r--apps/encryption/settings/settings-personal.php10
-rw-r--r--apps/encryption/tests/lib/KeyManagerTest.php88
6 files changed, 188 insertions, 127 deletions
diff --git a/apps/encryption/appinfo/application.php b/apps/encryption/appinfo/application.php
index 606c0cc5c49..f9b7a1c60da 100644
--- a/apps/encryption/appinfo/application.php
+++ b/apps/encryption/appinfo/application.php
@@ -127,7 +127,8 @@ class Application extends \OCP\AppFramework\App {
$server->getConfig(),
$server->getUserSession(),
$server->getSession(),
- $server->getLogger()
+ $server->getLogger(),
+ $c->query('Recovery')
);
});
@@ -168,13 +169,7 @@ class Application extends \OCP\AppFramework\App {
function (IAppContainer $c) {
$server = $c->getServer();
- return new Util(new View(),
- new Filesystem(),
- $c->query('Crypt'),
- $c->query('KeyManager'),
- $server->getLogger(),
- $server->getUserSession(),
- $server->getConfig()
+ return new Util(new View(), $c->query('Crypt'), $c->query('KeyManager'), $server->getLogger(), $server->getUserSession(), $server->getConfig()
);
});
diff --git a/apps/encryption/lib/keymanager.php b/apps/encryption/lib/keymanager.php
index d9b670c3f5a..cd983be17f9 100644
--- a/apps/encryption/lib/keymanager.php
+++ b/apps/encryption/lib/keymanager.php
@@ -27,8 +27,6 @@ use OC\Encryption\Exceptions\PrivateKeyMissingException;
use OC\Encryption\Exceptions\PublicKeyMissingException;
use OCA\Encryption\Crypto\Crypt;
use OCP\Encryption\Keys\IStorage;
-use OCP\ICache;
-use OCP\ICacheFactory;
use OCP\IConfig;
use OCP\ILogger;
use OCP\IUserSession;
@@ -86,6 +84,10 @@ class KeyManager {
* @var ILogger
*/
private $log;
+ /**
+ * @var Recovery
+ */
+ private $recovery;
/**
* @param IStorage $keyStorage
@@ -94,6 +96,7 @@ class KeyManager {
* @param IUserSession $userSession
* @param \OCP\ISession $session
* @param ILogger $log
+ * @param Recovery $recovery
*/
public function __construct(
IStorage $keyStorage,
@@ -101,7 +104,9 @@ class KeyManager {
IConfig $config,
IUserSession $userSession,
ISession $session,
- ILogger $log) {
+ ILogger $log,
+ Recovery $recovery
+ ) {
self::$session = $session;
$this->keyStorage = $keyStorage;
@@ -115,7 +120,9 @@ class KeyManager {
if (empty($this->publicShareKeyId)) {
$this->publicShareKeyId = 'pubShare_' . substr(md5(time()), 0, 8);
- $this->config->setAppValue('encryption', 'publicShareKeyId', $this->publicShareKeyId);
+ $this->config->setAppValue('encryption',
+ 'publicShareKeyId',
+ $this->publicShareKeyId);
$keyPair = $this->crypt->createKeyPair();
@@ -125,9 +132,11 @@ class KeyManager {
$keyPair['publicKey']);
// Encrypt private key empty passphrase
- $encryptedKey = $this->crypt->symmetricEncryptFileContent($keyPair['privateKey'], '');
+ $encryptedKey = $this->crypt->symmetricEncryptFileContent($keyPair['privateKey'],
+ '');
if ($encryptedKey) {
- $this->keyStorage->setSystemUserKey($this->publicShareKeyId . '.privateKey', $encryptedKey);
+ $this->keyStorage->setSystemUserKey($this->publicShareKeyId . '.privateKey',
+ $encryptedKey);
} else {
$this->log->error('Could not create public share keys');
}
@@ -136,6 +145,7 @@ class KeyManager {
$this->keyId = $userSession && $userSession->isLoggedIn() ? $userSession->getUser()->getUID() : false;
$this->log = $log;
+ $this->recovery = $recovery;
}
/**
@@ -386,7 +396,7 @@ class KeyManager {
$this->setPrivateKey($user, $encryptedKey);
if ($recoveryPassword) { // if recovery key is set we can re-encrypt the key files
- $util->recoverUsersFiles($recoveryPassword);
+ $this->recovery->recoverUsersFiles($recoveryPassword);
}
} else {
$this->log->error('Encryption Could not update users encryption password');
diff --git a/apps/encryption/lib/recovery.php b/apps/encryption/lib/recovery.php
index 457184b4b96..376d3ef83ba 100644
--- a/apps/encryption/lib/recovery.php
+++ b/apps/encryption/lib/recovery.php
@@ -29,6 +29,7 @@ use OCP\IUser;
use OCP\IUserSession;
use OCP\PreConditionNotMetException;
use OCP\Security\ISecureRandom;
+use OCP\Share;
class Recovery {
@@ -54,10 +55,12 @@ class Recovery {
*/
private $config;
/**
- * @var IEncryptionKeyStorage
+ * @var IStorage
*/
private $keyStorage;
+ private $recoveryKeyId;
+
/**
* @param IUserSession $user
* @param Crypt $crypt
@@ -90,7 +93,9 @@ class Recovery {
if ($recoveryKeyId === null) {
$recoveryKeyId = $this->random->getLowStrengthGenerator();
- $appConfig->setAppValue('encryption', 'recoveryKeyId', $recoveryKeyId);
+ $appConfig->setAppValue('encryption',
+ 'recoveryKeyId',
+ $recoveryKeyId);
}
$keyManager = $this->keyManager;
@@ -98,7 +103,9 @@ class Recovery {
if (!$keyManager->recoveryKeyExists()) {
$keyPair = $this->crypt->createKeyPair();
- return $this->keyManager->storeKeyPair($this->user->getUID(), $password, $keyPair);
+ return $this->keyManager->storeKeyPair($this->user->getUID(),
+ $password,
+ $keyPair);
}
if ($keyManager->checkRecoveryPassword($password)) {
@@ -143,6 +150,7 @@ class Recovery {
return ($recoveryMode === '1');
}
+
/**
* @param $enabled
* @return bool
@@ -165,12 +173,79 @@ class Recovery {
* @param $recoveryPassword
*/
public function recoverUsersFiles($recoveryPassword) {
- // todo: get system private key here
-// $this->keyManager->get
+ $encryptedKey = $this->keyManager->getSystemPrivateKey();
+
$privateKey = $this->crypt->decryptPrivateKey($encryptedKey,
$recoveryPassword);
$this->recoverAllFiles('/', $privateKey);
}
+ /**
+ * @param $path
+ * @param $privateKey
+ */
+ private function recoverAllFiles($path, $privateKey) {
+ $dirContent = $this->files->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)) {
+ $this->recoverAllFiles($filePath . '/', $privateKey);
+ } else {
+ $this->recoverFile($filePath, $privateKey);
+ }
+ }
+
+ }
+
+ /**
+ * @param $filePath
+ * @param $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
+ ];
+ }
+ $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);
+
+ // 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);
+
+ $this->keyManager->setFileKey($multiEncryptionKey['data'],
+ $uid);
+
+ $this->keyManager->setShareKey($filePath,
+ $uid,
+ $multiEncryptionKey['keys']);
+ }
+
+
}
diff --git a/apps/encryption/lib/util.php b/apps/encryption/lib/util.php
index 5fc08c6cc7d..45891be5dad 100644
--- a/apps/encryption/lib/util.php
+++ b/apps/encryption/lib/util.php
@@ -26,7 +26,6 @@ namespace OCA\Encryption;
use OC\Files\Filesystem;
use OC\Files\View;
use OCA\Encryption\Crypto\Crypt;
-use OCA\Files_Versions\Storage;
use OCP\App;
use OCP\IConfig;
use OCP\ILogger;
@@ -41,10 +40,6 @@ class Util {
*/
private $files;
/**
- * @var Filesystem
- */
- private $filesystem;
- /**
* @var Crypt
*/
private $crypt;
@@ -69,24 +64,20 @@ class Util {
* Util constructor.
*
* @param View $files
- * @param Filesystem $filesystem
* @param Crypt $crypt
* @param KeyManager $keyManager
* @param ILogger $logger
* @param IUserSession $userSession
* @param IConfig $config
*/
- public function __construct(
- View $files,
- Filesystem $filesystem,
- Crypt $crypt,
- KeyManager $keyManager,
- ILogger $logger,
- IUserSession $userSession,
- IConfig $config
+ public function __construct(View $files,
+ Crypt $crypt,
+ KeyManager $keyManager,
+ ILogger $logger,
+ IUserSession $userSession,
+ IConfig $config
) {
$this->files = $files;
- $this->filesystem = $filesystem;
$this->crypt = $crypt;
$this->keyManager = $keyManager;
$this->logger = $logger;
@@ -95,16 +86,6 @@ class Util {
}
/**
- * @param $filePath
- * @return array
- */
- private function splitPath($filePath) {
- $normalized = $this->filesystem->normalizePath($filePath);
-
- return explode('/', $normalized);
- }
-
- /**
* @return bool
*/
public function recoveryEnabledForUser() {
@@ -154,71 +135,5 @@ class Util {
return $this->files->file_exists($uid . '/files');
}
- /**
- * @param $path
- * @param $privateKey
- */
- private function recoverAllFiles($path, $privateKey) {
- // Todo relocate to storage
- $dirContent = $this->files->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)) {
- $this->recoverAllFiles($filePath . '/', $privateKey);
- } else {
- $this->recoverFile($filePath, $privateKey);
- }
- }
-
- }
-
- /**
- * @param $filePath
- * @param $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
- ];
- }
- $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);
-
- // 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);
-
- $this->keyManager->setFileKey($multiEncryptionKey['data'],
- $uid);
-
- $this->keyManager->setShareKey($filePath,
- $uid,
- $multiEncryptionKey['keys']);
- }
}
diff --git a/apps/encryption/settings/settings-personal.php b/apps/encryption/settings/settings-personal.php
index 3266351a07d..540897b829d 100644
--- a/apps/encryption/settings/settings-personal.php
+++ b/apps/encryption/settings/settings-personal.php
@@ -20,20 +20,14 @@ $keymanager = new \OCA\Encryption\KeyManager(
\OC::$server->getConfig(),
\OC::$server->getUserSession(),
\OC::$server->getSession(),
- \OC::$server->getLogger());
+ \OC::$server->getLogger(),);
$user = \OCP\User::getUser();
$view = new \OC\Files\View('/');
$util = new \OCA\Encryption\Util(
- new \OC\Files\View(),
- new \OC\Files\Filesystem(),
- $crypt,
- $keymanager,
- \OC::$server->getLogger(),
- \OC::$server->getUserSession(),
- \OC::$server->getConfig());
+ new \OC\Files\View(), $crypt, $keymanager, \OC::$server->getLogger(), \OC::$server->getUserSession(), \OC::$server->getConfig());
$session = \OC::$server->getSession();
diff --git a/apps/encryption/tests/lib/KeyManagerTest.php b/apps/encryption/tests/lib/KeyManagerTest.php
index ed6048d7642..510ab179888 100644
--- a/apps/encryption/tests/lib/KeyManagerTest.php
+++ b/apps/encryption/tests/lib/KeyManagerTest.php
@@ -10,26 +10,64 @@
namespace OCA\Encryption\Tests;
+use OC\Files\View;
use OCA\Encryption\KeyManager;
use Test\TestCase;
class KeyManagerTest extends TestCase {
/**
+ * @var bool
+ */
+ private static $trashbinState;
+ /**
* @var KeyManager
*/
private $instance;
/**
- * @var
+ * @var string
*/
- private $userId;
+ private static $testUser = 'test-keyManager-user.dot';
/**
* @var
*/
private $dummyKeys;
+ /**
+ * @var string
+ */
+ private $userId;
+ /**
+ * @var string
+ */
+ private $userPassword;
+ /**
+ * @var \OC\Files\View
+ */
+ private $view;
+ /**
+ * @var string
+ */
+ private $dataDir;
/**
*
*/
+ public static function setUpBeforeClass() {
+ parent::setUpBeforeClass();
+
+ // Remember files_trashbin state
+ self::$trashbinState = \OC_App::isEnabled('files_trashbin');
+
+ // We dont want tests with app files_trashbin enabled
+ \OC_App::disable('files_trashbin');
+
+ $userManager = \OC::$server->getUserManager();
+ $userManager->createUser(self::$testUser,
+ self::$testUser);
+
+ // Create test user
+ parent::loginAsUser(self::$testUser);
+ }
+
public function setUp() {
parent::setUp();
$keyStorageMock = $this->getMock('OCP\Encryption\Keys\IStorage');
@@ -47,18 +85,52 @@ class KeyManagerTest extends TestCase {
->will($this->returnValue('admin'));
$sessionMock = $this->getMock('OCP\ISession');
$logMock = $this->getMock('OCP\ILogger');
- $this->userId = 'admin';
+ $recoveryMock = $this->getMockBuilder('OCA\Encryption\Recovery')
+ ->disableOriginalConstructor()
+ ->getMock();
+
$this->instance = new KeyManager($keyStorageMock,
$cryptMock,
$configMock,
$userMock,
$sessionMock,
- $logMock);
+ $logMock,
+ $recoveryMock);
+
+ self::loginAsUser(self::$testUser);
+ $this->userId = self::$testUser;
+ $this->userPassword = self::$testUser;
+ $this->view = new View('/');
+
+ $this->dummyKeys = [
+ 'privateKey' => 'superinsecureprivatekey',
+ 'publicKey' => 'superinsecurepublickey'
+ ];
- $this->dummyKeys = ['public' => 'randomweakpublickeyhere',
- 'private' => 'randomweakprivatekeyhere'];
+
+ $userManager = \OC::$server->getUserManager();
+
+ $userHome = $userManager->get($this->userId)->getHome();
+
+ $this->dataDir = str_replace('/' . $this->userId, '', $userHome);
+ }
+
+ protected function tearDown() {
+ parent::tearDown();
+ $this->view->deleteAll('/' . self::$testUser . '/files_encryption/keys');
+ }
+
+ public static function tearDownAfterClass() {
+ parent::tearDownAfterClass();
+ // Cleanup Test user
+ \OC::$server->getUserManager()->get(self::$testUser)->delete();
+ // Reset app files_trashbin
+ if (self::$trashbinState) {
+ \OC_App::enable('files_trashbin');
+ }
}
+
/**
* @expectedException \OC\Encryption\Exceptions\PrivateKeyMissingException
*/
@@ -93,7 +165,7 @@ class KeyManagerTest extends TestCase {
public function testSetPublicKey() {
$this->assertTrue($this->instance->setPublicKey($this->userId,
- $this->dummyKeys['public']));
+ $this->dummyKeys['publicKey']));
}
/**
@@ -101,7 +173,7 @@ class KeyManagerTest extends TestCase {
*/
public function testSetPrivateKey() {
$this->assertTrue($this->instance->setPrivateKey($this->userId,
- $this->dummyKeys['private']));
+ $this->dummyKeys['privateKey']));
}
/**