cache keys to read them only once from the hard disc
This commit is contained in:
parent
10a0fc2856
commit
aea991c22e
4 changed files with 91 additions and 19 deletions
|
@ -35,6 +35,8 @@ class Keymanager {
|
|||
private static $encryption_base_dir = '/files_encryption';
|
||||
private static $public_key_dir = '/files_encryption/public_keys';
|
||||
|
||||
private static $key_cache = array(); // cache keys
|
||||
|
||||
/**
|
||||
* read key from hard disk
|
||||
*
|
||||
|
@ -42,15 +44,24 @@ class Keymanager {
|
|||
* @return string|bool either the key or false
|
||||
*/
|
||||
private static function getKey($path, $view) {
|
||||
$proxyStatus = \OC_FileProxy::$enabled;
|
||||
\OC_FileProxy::$enabled = false;
|
||||
|
||||
$key = false;
|
||||
if ($view->file_exists($path)) {
|
||||
$key = $view->file_get_contents($path);
|
||||
}
|
||||
|
||||
\OC_FileProxy::$enabled = $proxyStatus;
|
||||
if (isset(self::$key_cache[$path])) {
|
||||
$key = self::$key_cache[$path];
|
||||
} else {
|
||||
|
||||
$proxyStatus = \OC_FileProxy::$enabled;
|
||||
\OC_FileProxy::$enabled = false;
|
||||
|
||||
if ($view->file_exists($path)) {
|
||||
$key = $view->file_get_contents($path);
|
||||
self::$key_cache[$path] = $key;
|
||||
}
|
||||
|
||||
\OC_FileProxy::$enabled = $proxyStatus;
|
||||
|
||||
}
|
||||
|
||||
return $key;
|
||||
}
|
||||
|
@ -70,11 +81,17 @@ class Keymanager {
|
|||
\OC_FileProxy::$enabled = false;
|
||||
|
||||
self::keySetPreparation($view, $path);
|
||||
$result = $view->file_put_contents($path . '/' . $name, $key);
|
||||
$pathToKey = \OC\Files\Filesystem::normalizePath($path . '/' . $name);
|
||||
$result = $view->file_put_contents($pathToKey, $key);
|
||||
|
||||
\OC_FileProxy::$enabled = $proxyStatus;
|
||||
|
||||
return (is_int($result) && $result > 0) ? true : false;
|
||||
if (is_int($result) && $result > 0) {
|
||||
self::$key_cache[$pathToKey] = $key;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -209,6 +226,25 @@ class Keymanager {
|
|||
return $keyDir . $uid . '.shareKey';
|
||||
}
|
||||
|
||||
/**
|
||||
* delete key
|
||||
*
|
||||
* @param \OC\Files\View $view
|
||||
* @param string $path
|
||||
* @return boolean
|
||||
*/
|
||||
private static function deleteKey($view, $path) {
|
||||
$normalizedPath = \OC\Files\Filesystem::normalizePath($path);
|
||||
$result = $view->unlink($normalizedPath);
|
||||
|
||||
if ($result) {
|
||||
unset(self::$key_cache[$normalizedPath]);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* delete public key from a given user
|
||||
*
|
||||
|
@ -222,7 +258,7 @@ class Keymanager {
|
|||
|
||||
if (!\OCP\User::userExists($uid)) {
|
||||
$publicKey = self::$public_key_dir . '/' . $uid . '.publicKey';
|
||||
$result = $view->unlink($publicKey);
|
||||
self::deleteKey($view, $publicKey);
|
||||
}
|
||||
|
||||
return $result;
|
||||
|
@ -426,7 +462,7 @@ class Keymanager {
|
|||
foreach ($userIds as $userId) {
|
||||
if ($userId . '.shareKey' === $file) {
|
||||
\OCP\Util::writeLog('files_encryption', 'recursiveDelShareKey: delete share key: ' . $file, \OCP\Util::DEBUG);
|
||||
$view->unlink($dir . '/' . $file);
|
||||
self::deleteKey($view, $dir . '/' . $file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -84,6 +84,24 @@ class Keymanager extends TestCase {
|
|||
parent::tearDownAfterClass();
|
||||
}
|
||||
|
||||
function testKeyCacheUpdate() {
|
||||
$testUser = 'testKeyCacheUpdate';
|
||||
\OCA\Files_Encryption\Keymanager::setPublicKey('oldKey', $testUser);
|
||||
|
||||
$this->assertSame('oldKey',
|
||||
\OCA\Files_Encryption\Keymanager::getPublicKey($this->view, $testUser));
|
||||
|
||||
// update key
|
||||
\OCA\Files_Encryption\Keymanager::setPublicKey('newKey', $testUser);
|
||||
|
||||
$this->assertSame('newKey',
|
||||
\OCA\Files_Encryption\Keymanager::getPublicKey($this->view, $testUser));
|
||||
|
||||
// cleanup
|
||||
\OCA\Files_Encryption\Keymanager::deletePublicKey($this->view, $testUser);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @medium
|
||||
*/
|
||||
|
@ -306,13 +324,14 @@ class Keymanager extends TestCase {
|
|||
$this->view->file_put_contents('/' . self::TEST_USER . '/files/folder1/existingFile.txt', 'data');
|
||||
|
||||
// create folder structure for some dummy share key files
|
||||
$this->view->mkdir('/' . self::TEST_USER . '/files_encryption/share-keys/folder1');
|
||||
$this->view->mkdir('/' . self::TEST_USER . '/files_encryption/keys/folder1');
|
||||
$this->view->mkdir('/' . self::TEST_USER . '/files_encryption/keys/folder1/existingFile.txt');
|
||||
|
||||
// create some dummy share keys
|
||||
$this->view->file_put_contents('/' . self::TEST_USER . '/files_encryption/share-keys/folder1/existingFile.txt.user1.shareKey', 'data');
|
||||
$this->view->file_put_contents('/' . self::TEST_USER . '/files_encryption/share-keys/folder1/existingFile.txt.user2.shareKey', 'data');
|
||||
$this->view->file_put_contents('/' . self::TEST_USER . '/files_encryption/share-keys/folder1/existingFile.txt.user3.shareKey', 'data');
|
||||
$this->view->file_put_contents('/' . self::TEST_USER . '/files_encryption/share-keys/folder1/existingFile.txt.' . self::TEST_USER . '.shareKey', 'data');
|
||||
$this->view->file_put_contents('/' . self::TEST_USER . '/files_encryption/keys/folder1/existingFile.txt/user1.shareKey', 'data');
|
||||
$this->view->file_put_contents('/' . self::TEST_USER . '/files_encryption/keys/folder1/existingFile.txt/user2.shareKey', 'data');
|
||||
$this->view->file_put_contents('/' . self::TEST_USER . '/files_encryption/keys/folder1/existingFile.txt/user3.shareKey', 'data');
|
||||
$this->view->file_put_contents('/' . self::TEST_USER . '/files_encryption/keys/folder1/existingFile.txt/' . self::TEST_USER . '.shareKey', 'data');
|
||||
|
||||
// recursive delete share keys from user1 and user2
|
||||
\OCA\Files_Encryption\Keymanager::delShareKey($this->view,
|
||||
|
@ -324,15 +343,15 @@ class Keymanager extends TestCase {
|
|||
|
||||
// check if share keys from user1 and user2 are deleted
|
||||
$this->assertFalse($this->view->file_exists(
|
||||
'/' . self::TEST_USER . '/files_encryption/share-keys/folder1/existingFile.user1.shareKey'));
|
||||
'/' . self::TEST_USER . '/files_encryption/keys/folder1/existingFile/user1.shareKey'));
|
||||
$this->assertFalse($this->view->file_exists(
|
||||
'/' . self::TEST_USER . '/files_encryption/share-keys/folder1/existingFile.user2.shareKey'));
|
||||
'/' . self::TEST_USER . '/files_encryption/keys/folder1/existingFile/user2.shareKey'));
|
||||
|
||||
// check if share keys for user3 and owner
|
||||
$this->assertTrue($this->view->file_exists(
|
||||
'/' . self::TEST_USER . '/files_encryption/share-keys/folder1/existingFile.txt.' . self::TEST_USER . '.shareKey'));
|
||||
'/' . self::TEST_USER . '/files_encryption/keys/folder1/existingFile.txt/' . self::TEST_USER . '.shareKey'));
|
||||
$this->assertTrue($this->view->file_exists(
|
||||
'/' . self::TEST_USER . '/files_encryption/share-keys/folder1/existingFile.txt.user3.shareKey'));
|
||||
'/' . self::TEST_USER . '/files_encryption/keys/folder1/existingFile.txt/user3.shareKey'));
|
||||
// cleanup
|
||||
$this->view->deleteAll('/' . self::TEST_USER . '/files/folder1');
|
||||
|
||||
|
|
|
@ -79,4 +79,18 @@ abstract class TestCase extends \Test\TestCase {
|
|||
|
||||
parent::tearDownAfterClass();
|
||||
}
|
||||
|
||||
protected function tearDown() {
|
||||
parent::tearDown();
|
||||
$this->resetKeyCache();
|
||||
}
|
||||
|
||||
protected function resetKeyCache() {
|
||||
// reset key cache for every testrun
|
||||
$keyCache = new \ReflectionProperty('\OCA\Files_Encryption\Keymanager', 'key_cache');
|
||||
$keyCache->setAccessible(true);
|
||||
$keyCache->setValue(array());
|
||||
$keyCache->setAccessible(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -445,6 +445,9 @@ class Util extends TestCase {
|
|||
$this->view->rename($this->userId . '/files_encryption/keys/' . $file1 . '/fileKey',
|
||||
$this->userId . '/files_encryption/keys/' . $file1 . '/fileKey.moved');
|
||||
|
||||
// need to reset key cache that we don't use the cached key
|
||||
$this->resetKeyCache();
|
||||
|
||||
// decrypt all encrypted files
|
||||
$result = $util->decryptAll();
|
||||
|
||||
|
|
Loading…
Reference in a new issue