summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
Diffstat (limited to 'apps')
-rw-r--r--apps/files_encryption/ajax/changeRecoveryPassword.php22
-rw-r--r--apps/files_encryption/ajax/updatePrivateKeyPassword.php54
-rw-r--r--apps/files_encryption/appinfo/app.php60
-rw-r--r--apps/files_encryption/files/error.php24
-rw-r--r--apps/files_encryption/hooks/hooks.php28
-rw-r--r--apps/files_encryption/js/settings-personal.js38
-rwxr-xr-xapps/files_encryption/lib/crypt.php54
-rwxr-xr-xapps/files_encryption/lib/helper.php23
-rw-r--r--apps/files_encryption/lib/proxy.php2
-rw-r--r--apps/files_encryption/lib/session.php15
-rw-r--r--apps/files_encryption/lib/stream.php82
-rw-r--r--apps/files_encryption/lib/util.php165
-rw-r--r--apps/files_encryption/settings-personal.php21
-rw-r--r--apps/files_encryption/templates/invalid_private_key.php10
-rw-r--r--apps/files_encryption/templates/settings-admin.php72
-rw-r--r--apps/files_encryption/templates/settings-personal.php43
-rwxr-xr-xapps/files_encryption/tests/crypt.php38
-rwxr-xr-xapps/files_encryption/tests/share.php9
-rwxr-xr-xapps/files_encryption/tests/util.php31
19 files changed, 533 insertions, 258 deletions
diff --git a/apps/files_encryption/ajax/changeRecoveryPassword.php b/apps/files_encryption/ajax/changeRecoveryPassword.php
index b0594f967ba..366f634a51c 100644
--- a/apps/files_encryption/ajax/changeRecoveryPassword.php
+++ b/apps/files_encryption/ajax/changeRecoveryPassword.php
@@ -22,28 +22,28 @@ $return = false;
$oldPassword = $_POST['oldPassword'];
$newPassword = $_POST['newPassword'];
+$view = new \OC\Files\View('/');
$util = new \OCA\Encryption\Util(new \OC_FilesystemView('/'), \OCP\User::getUser());
-$result = $util->checkRecoveryPassword($oldPassword);
+$proxyStatus = \OC_FileProxy::$enabled;
+\OC_FileProxy::$enabled = false;
-if ($result) {
- $keyId = $util->getRecoveryKeyId();
- $keyPath = '/owncloud_private_key/' . $keyId . '.private.key';
- $view = new \OC\Files\View('/');
+$keyId = $util->getRecoveryKeyId();
+$keyPath = '/owncloud_private_key/' . $keyId . '.private.key';
- $proxyStatus = \OC_FileProxy::$enabled;
- \OC_FileProxy::$enabled = false;
+$encryptedRecoveryKey = $view->file_get_contents($keyPath);
+$decryptedRecoveryKey = \OCA\Encryption\Crypt::decryptPrivateKey($encryptedRecoveryKey, $oldPassword);
+
+if ($decryptedRecoveryKey) {
- $encryptedRecoveryKey = $view->file_get_contents($keyPath);
- $decryptedRecoveryKey = \OCA\Encryption\Crypt::symmetricDecryptFileContent($encryptedRecoveryKey, $oldPassword);
$encryptedRecoveryKey = \OCA\Encryption\Crypt::symmetricEncryptFileContent($decryptedRecoveryKey, $newPassword);
$view->file_put_contents($keyPath, $encryptedRecoveryKey);
- \OC_FileProxy::$enabled = $proxyStatus;
-
$return = true;
}
+\OC_FileProxy::$enabled = $proxyStatus;
+
// success or failure
if ($return) {
\OCP\JSON::success(array('data' => array('message' => $l->t('Password successfully changed.'))));
diff --git a/apps/files_encryption/ajax/updatePrivateKeyPassword.php b/apps/files_encryption/ajax/updatePrivateKeyPassword.php
new file mode 100644
index 00000000000..6fd63dae9cd
--- /dev/null
+++ b/apps/files_encryption/ajax/updatePrivateKeyPassword.php
@@ -0,0 +1,54 @@
+<?php
+
+/**
+ * Copyright (c) 2013, Bjoern Schiessle <schiessle@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or later.
+ * See the COPYING-README file.
+ *
+ * @brief Script to change recovery key password
+ *
+ */
+
+use OCA\Encryption;
+
+\OCP\JSON::checkLoggedIn();
+\OCP\JSON::checkAppEnabled('files_encryption');
+\OCP\JSON::callCheck();
+
+$l = OC_L10N::get('core');
+
+$return = false;
+
+$oldPassword = $_POST['oldPassword'];
+$newPassword = $_POST['newPassword'];
+
+$view = new \OC\Files\View('/');
+$session = new \OCA\Encryption\Session($view);
+$user = \OCP\User::getUser();
+
+$proxyStatus = \OC_FileProxy::$enabled;
+\OC_FileProxy::$enabled = false;
+
+$keyPath = '/' . $user . '/files_encryption/' . $user . '.private.key';
+
+$encryptedKey = $view->file_get_contents($keyPath);
+$decryptedKey = \OCA\Encryption\Crypt::decryptPrivateKey($encryptedKey, $oldPassword);
+
+if ($decryptedKey) {
+
+ $encryptedKey = \OCA\Encryption\Crypt::symmetricEncryptFileContent($decryptedKey, $newPassword);
+ $view->file_put_contents($keyPath, $encryptedKey);
+
+ $session->setPrivateKey($decryptedKey);
+
+ $return = true;
+}
+
+\OC_FileProxy::$enabled = $proxyStatus;
+
+// success or failure
+if ($return) {
+ \OCP\JSON::success(array('data' => array('message' => $l->t('Private key password successfully updated.'))));
+} else {
+ \OCP\JSON::error(array('data' => array('message' => $l->t('Could not update the private key password. Maybe the old password was not correct.'))));
+} \ No newline at end of file
diff --git a/apps/files_encryption/appinfo/app.php b/apps/files_encryption/appinfo/app.php
index 99bdc2c2470..419bef1edef 100644
--- a/apps/files_encryption/appinfo/app.php
+++ b/apps/files_encryption/appinfo/app.php
@@ -10,45 +10,51 @@ OC::$CLASSPATH['OCA\Encryption\Session'] = 'files_encryption/lib/session.php';
OC::$CLASSPATH['OCA\Encryption\Capabilities'] = 'files_encryption/lib/capabilities.php';
OC::$CLASSPATH['OCA\Encryption\Helper'] = 'files_encryption/lib/helper.php';
-OC_FileProxy::register(new OCA\Encryption\Proxy());
+if (!OC_Config::getValue('maintenance', false)) {
+ OC_FileProxy::register(new OCA\Encryption\Proxy());
-// User related hooks
-OCA\Encryption\Helper::registerUserHooks();
+ // User related hooks
+ OCA\Encryption\Helper::registerUserHooks();
-// Sharing related hooks
-OCA\Encryption\Helper::registerShareHooks();
+ // Sharing related hooks
+ OCA\Encryption\Helper::registerShareHooks();
-// Filesystem related hooks
-OCA\Encryption\Helper::registerFilesystemHooks();
+ // Filesystem related hooks
+ OCA\Encryption\Helper::registerFilesystemHooks();
-stream_wrapper_register('crypt', 'OCA\Encryption\Stream');
+ stream_wrapper_register('crypt', 'OCA\Encryption\Stream');
-// check if we are logged in
-if (OCP\User::isLoggedIn()) {
+ // check if we are logged in
+ if (OCP\User::isLoggedIn()) {
- // ensure filesystem is loaded
- if(!\OC\Files\Filesystem::$loaded) {
- \OC_Util::setupFS();
- }
+ // ensure filesystem is loaded
+ if (!\OC\Files\Filesystem::$loaded) {
+ \OC_Util::setupFS();
+ }
- $view = new OC_FilesystemView('/');
- $session = new \OCA\Encryption\Session($view);
+ $view = new OC_FilesystemView('/');
+ $session = new \OCA\Encryption\Session($view);
- // check if user has a private key
- if (
- !$session->getPrivateKey(\OCP\USER::getUser())
- && OCA\Encryption\Crypt::mode() === 'server'
- ) {
+ $user = \OCP\USER::getUser();
+ // check if user has a private key
+ if (
+ !$view->file_exists('/' . $user . '/files_encryption/' . $user . '.private.key')
+ && OCA\Encryption\Crypt::mode() === 'server'
+ ) {
- // Force the user to log-in again if the encryption key isn't unlocked
- // (happens when a user is logged in before the encryption app is
- // enabled)
- OCP\User::logout();
+ // Force the user to log-in again if the encryption key isn't unlocked
+ // (happens when a user is logged in before the encryption app is
+ // enabled)
+ OCP\User::logout();
- header("Location: " . OC::$WEBROOT . '/');
+ header("Location: " . OC::$WEBROOT . '/');
- exit();
+ exit();
+ }
}
+} else {
+ // logout user if we are in maintenance to force re-login
+ OCP\User::logout();
}
// Register settings scripts
diff --git a/apps/files_encryption/files/error.php b/apps/files_encryption/files/error.php
new file mode 100644
index 00000000000..63c74e4e797
--- /dev/null
+++ b/apps/files_encryption/files/error.php
@@ -0,0 +1,24 @@
+<?php
+if (!isset($_)) { //also provide standalone error page
+ require_once '../../../lib/base.php';
+
+ $l = OC_L10N::get('files_encryption');
+
+ $errorMsg = $l->t('Your private key is not valid! Maybe your password was changed from outside. You can update your private key password in your personal settings to regain access to your files');
+
+ if(isset($_GET['p']) && $_GET['p'] === '1') {
+ header('HTTP/1.0 404 ' . $errorMsg);
+ }
+
+ // check if ajax request
+ if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
+ \OCP\JSON::error(array('data' => array('message' => $errorMsg)));
+ } else {
+ header('HTTP/1.0 404 ' . $errorMsg);
+ $tmpl = new OC_Template('files_encryption', 'invalid_private_key', 'guest');
+ $tmpl->printPage();
+ }
+
+ exit;
+}
+?>
diff --git a/apps/files_encryption/hooks/hooks.php b/apps/files_encryption/hooks/hooks.php
index c4b247da1ed..7698b95cfd3 100644
--- a/apps/files_encryption/hooks/hooks.php
+++ b/apps/files_encryption/hooks/hooks.php
@@ -60,17 +60,25 @@ class Hooks {
$encryptedKey = Keymanager::getPrivateKey($view, $params['uid']);
- $privateKey = Crypt::symmetricDecryptFileContent($encryptedKey, $params['password']);
+ $privateKey = Crypt::decryptPrivateKey($encryptedKey, $params['password']);
+
+ if ($privateKey === false) {
+ \OCP\Util::writeLog('Encryption library', 'Private key for user "' . $params['uid']
+ . '" is not valid! Maybe the user password was changed from outside if so please change it back to gain access', \OCP\Util::ERROR);
+ }
$session = new \OCA\Encryption\Session($view);
- $session->setPrivateKey($privateKey, $params['uid']);
+ $session->setPrivateKey($privateKey);
// Check if first-run file migration has already been performed
- $migrationCompleted = $util->getMigrationStatus();
+ $ready = false;
+ if ($util->getMigrationStatus() === Util::MIGRATION_OPEN) {
+ $ready = $util->beginMigration();
+ }
// If migration not yet done
- if (!$migrationCompleted) {
+ if ($ready) {
$userView = new \OC_FilesystemView('/' . $params['uid']);
@@ -81,7 +89,7 @@ class Hooks {
&& $encLegacyKey = $userView->file_get_contents('encryption.key')
) {
- $plainLegacyKey = Crypt::legacyBlockDecrypt($encLegacyKey, $params['password']);
+ $plainLegacyKey = Crypt::legacyDecrypt($encLegacyKey, $params['password']);
$session->setLegacyKey($plainLegacyKey);
@@ -102,7 +110,7 @@ class Hooks {
}
// Register successful migration in DB
- $util->setMigrationStatus(1);
+ $util->finishMigration();
}
@@ -157,7 +165,7 @@ class Hooks {
public static function setPassphrase($params) {
// Only attempt to change passphrase if server-side encryption
- // is in use (client-side encryption does not have access to
+ // is in use (client-side encryption does not have access to
// the necessary keys)
if (Crypt::mode() === 'server') {
@@ -342,7 +350,7 @@ class Hooks {
$sharingEnabled = \OCP\Share::isEnabled();
// get the path including mount point only if not a shared folder
- if(strncmp($path, '/Shared' , strlen('/Shared') !== 0)) {
+ if (strncmp($path, '/Shared', strlen('/Shared') !== 0)) {
// get path including the the storage mount point
$path = $util->getPathWithMountPoint($params['itemSource']);
}
@@ -419,14 +427,14 @@ class Hooks {
}
// get the path including mount point only if not a shared folder
- if(strncmp($path, '/Shared' , strlen('/Shared') !== 0)) {
+ if (strncmp($path, '/Shared', strlen('/Shared') !== 0)) {
// get path including the the storage mount point
$path = $util->getPathWithMountPoint($params['itemSource']);
}
// if we unshare a folder we need a list of all (sub-)files
if ($params['itemType'] === 'folder') {
- $allFiles = $util->getAllFiles( $path );
+ $allFiles = $util->getAllFiles($path);
} else {
$allFiles = array($path);
}
diff --git a/apps/files_encryption/js/settings-personal.js b/apps/files_encryption/js/settings-personal.js
index 312b672ad46..d6535a25b70 100644
--- a/apps/files_encryption/js/settings-personal.js
+++ b/apps/files_encryption/js/settings-personal.js
@@ -4,7 +4,25 @@
* See the COPYING-README file.
*/
+function updatePrivateKeyPasswd() {
+ var oldPrivateKeyPassword = $('input:password[id="oldPrivateKeyPassword"]').val();
+ var newPrivateKeyPassword = $('input:password[id="newPrivateKeyPassword"]').val();
+ OC.msg.startSaving('#encryption .msg');
+ $.post(
+ OC.filePath( 'files_encryption', 'ajax', 'updatePrivateKeyPassword.php' )
+ , { oldPassword: oldPrivateKeyPassword, newPassword: newPrivateKeyPassword }
+ , function( data ) {
+ if (data.status === "error") {
+ OC.msg.finishedSaving('#encryption .msg', data);
+ } else {
+ OC.msg.finishedSaving('#encryption .msg', data);
+ }
+ }
+ );
+}
+
$(document).ready(function(){
+
// Trigger ajax on recoveryAdmin status change
$( 'input:radio[name="userEnableRecovery"]' ).change(
function() {
@@ -57,4 +75,24 @@ $(document).ready(function(){
}
);
+
+ // update private key password
+
+ $('input:password[name="changePrivateKeyPassword"]').keyup(function(event) {
+ var oldPrivateKeyPassword = $('input:password[id="oldPrivateKeyPassword"]').val();
+ var newPrivateKeyPassword = $('input:password[id="newPrivateKeyPassword"]').val();
+ if (newPrivateKeyPassword !== '' && oldPrivateKeyPassword !== '' ) {
+ $('button:button[name="submitChangePrivateKeyPassword"]').removeAttr("disabled");
+ if(event.which === 13) {
+ updatePrivateKeyPasswd();
+ }
+ } else {
+ $('button:button[name="submitChangePrivateKeyPassword"]').attr("disabled", "true");
+ }
+ });
+
+ $('button:button[name="submitChangePrivateKeyPassword"]').click(function() {
+ updatePrivateKeyPasswd();
+ });
+
}); \ No newline at end of file
diff --git a/apps/files_encryption/lib/crypt.php b/apps/files_encryption/lib/crypt.php
index ddeb3590f60..cd41390d1c5 100755
--- a/apps/files_encryption/lib/crypt.php
+++ b/apps/files_encryption/lib/crypt.php
@@ -352,6 +352,34 @@ class Crypt {
}
/**
+ * @brief Decrypt private key and check if the result is a valid keyfile
+ * @param string $encryptedKey encrypted keyfile
+ * @param string $passphrase to decrypt keyfile
+ * @returns encrypted private key or false
+ *
+ * This function decrypts a file
+ */
+ public static function decryptPrivateKey($encryptedKey, $passphrase) {
+
+ $plainKey = self::symmetricDecryptFileContent($encryptedKey, $passphrase);
+
+ // check if this a valid private key
+ $res = openssl_pkey_get_private($plainKey);
+ if (is_resource($res)) {
+ $sslInfo = openssl_pkey_get_details($res);
+ if (!isset($sslInfo['key'])) {
+ $plainKey = false;
+ }
+ } else {
+ $plainKey = false;
+ }
+
+ return $plainKey;
+
+ }
+
+
+ /**
* @brief Creates symmetric keyfile content using a generated key
* @param string $plainContent content to be encrypted
* @returns array keys: key, encrypted
@@ -608,7 +636,7 @@ class Crypt {
*
* This function decrypts an content
*/
- private static function legacyDecrypt($content, $passphrase = '') {
+ public static function legacyDecrypt($content, $passphrase = '') {
$bf = self::getBlowfish($passphrase);
@@ -637,28 +665,4 @@ class Crypt {
}
}
- /**
- * @param $legacyEncryptedContent
- * @param $legacyPassphrase
- * @param $publicKeys
- * @return array
- */
- public static function legacyKeyRecryptKeyfile($legacyEncryptedContent, $legacyPassphrase, $publicKeys) {
-
- $decrypted = self::legacyBlockDecrypt($legacyEncryptedContent, $legacyPassphrase);
-
- // Encrypt plain data, generate keyfile & encrypted file
- $cryptedData = self::symmetricEncryptFileContentKeyfile($decrypted);
-
- // Encrypt plain keyfile to multiple sharefiles
- $multiEncrypted = Crypt::multiKeyEncrypt($cryptedData['key'], $publicKeys);
-
- return array(
- 'data' => $cryptedData['encrypted'],
- 'filekey' => $multiEncrypted['data'],
- 'sharekeys' => $multiEncrypted['keys']
- );
-
- }
-
} \ No newline at end of file
diff --git a/apps/files_encryption/lib/helper.php b/apps/files_encryption/lib/helper.php
index 184e1782494..a22c139c503 100755
--- a/apps/files_encryption/lib/helper.php
+++ b/apps/files_encryption/lib/helper.php
@@ -74,7 +74,7 @@ class Helper {
if (!$util->ready()) {
\OCP\Util::writeLog('Encryption library', 'User account "' . $util->getUserId()
- . '" is not ready for encryption; configuration started', \OCP\Util::DEBUG);
+ . '" is not ready for encryption; configuration started', \OCP\Util::DEBUG);
if (!$util->setupServerSide($password)) {
return false;
@@ -94,6 +94,7 @@ class Helper {
* @return bool
*/
public static function adminEnableRecovery($recoveryKeyId, $recoveryPassword) {
+
$view = new \OC\Files\View('/');
if ($recoveryKeyId === null) {
@@ -128,13 +129,6 @@ class Helper {
// Save private key
$view->file_put_contents('/owncloud_private_key/' . $recoveryKeyId . '.private.key', $encryptedPrivateKey);
- // create control file which let us check later on if the entered password was correct.
- $encryptedControlData = \OCA\Encryption\Crypt::keyEncrypt("ownCloud", $keypair['publicKey']);
- if (!$view->is_dir('/control-file')) {
- $view->mkdir('/control-file');
- }
- $view->file_put_contents('/control-file/controlfile.enc', $encryptedControlData);
-
\OC_FileProxy::$enabled = true;
// Set recoveryAdmin as enabled
@@ -201,4 +195,17 @@ class Helper {
return $relPath;
}
+
+ /**
+ * @brief redirect to a error page
+ */
+ public static function redirectToErrorPage() {
+ $location = \OC_Helper::linkToAbsolute('apps/files_encryption/files', 'error.php');
+ $post = 0;
+ if(count($_POST) > 0) {
+ $post = 1;
+ }
+ header('Location: ' . $location . '?p=' . $post);
+ exit();
+ }
} \ No newline at end of file
diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php
index 0df34a38bd7..735eba911a9 100644
--- a/apps/files_encryption/lib/proxy.php
+++ b/apps/files_encryption/lib/proxy.php
@@ -256,6 +256,8 @@ class Proxy extends \OC_FileProxy {
*/
public function postFopen($path, &$result) {
+ $path = \OC\Files\Filesystem::normalizePath($path);
+
if (!$result) {
return $result;
diff --git a/apps/files_encryption/lib/session.php b/apps/files_encryption/lib/session.php
index bff1737554b..1911386cd12 100644
--- a/apps/files_encryption/lib/session.php
+++ b/apps/files_encryption/lib/session.php
@@ -88,9 +88,10 @@ class Session {
$proxyStatus = \OC_FileProxy::$enabled;
\OC_FileProxy::$enabled = false;
- $encryptedKey = $this->view->file_get_contents( '/owncloud_private_key/' . $publicShareKeyId . '.private.key' );
- $privateKey = Crypt::symmetricDecryptFileContent( $encryptedKey, '' );
- $this->setPublicSharePrivateKey( $privateKey );
+ $encryptedKey = $this->view->file_get_contents(
+ '/owncloud_private_key/' . $publicShareKeyId . '.private.key');
+ $privateKey = Crypt::decryptPrivateKey($encryptedKey, '');
+ $this->setPublicSharePrivateKey($privateKey);
\OC_FileProxy::$enabled = $proxyStatus;
}
@@ -121,7 +122,7 @@ class Session {
if (\OCA\Encryption\Helper::isPublicAccess()) {
return $this->getPublicSharePrivateKey();
} else {
- if (!is_null( \OC::$session->get('privateKey') )) {
+ if (!is_null(\OC::$session->get('privateKey'))) {
return \OC::$session->get('privateKey');
} else {
return false;
@@ -136,7 +137,7 @@ class Session {
*/
public function setPublicSharePrivateKey($privateKey) {
- \OC::$session->set('publicSharePrivateKey', $privateKey);
+ \OC::$session->set('publicSharePrivateKey', $privateKey);
return true;
@@ -149,7 +150,7 @@ class Session {
*/
public function getPublicSharePrivateKey() {
- if (!is_null( \OC::$session->get('publicSharePrivateKey') )) {
+ if (!is_null(\OC::$session->get('publicSharePrivateKey'))) {
return \OC::$session->get('publicSharePrivateKey');
} else {
return false;
@@ -176,7 +177,7 @@ class Session {
*/
public function getLegacyKey() {
- if ( !is_null( \OC::$session->get('legacyKey') ) ) {
+ if (!is_null(\OC::$session->get('legacyKey'))) {
return \OC::$session->get('legacyKey');
diff --git a/apps/files_encryption/lib/stream.php b/apps/files_encryption/lib/stream.php
index 072c5286644..3c1eb2c5f5e 100644
--- a/apps/files_encryption/lib/stream.php
+++ b/apps/files_encryption/lib/stream.php
@@ -56,18 +56,21 @@ class Stream {
private $relPath; // rel path to users file dir
private $userId;
private $handle; // Resource returned by fopen
- private $path;
- private $readBuffer; // For streams that dont support seeking
private $meta = array(); // Header / meta for source stream
- private $count;
private $writeCache;
private $size;
private $unencryptedSize;
private $publicKey;
- private $keyfile;
private $encKeyfile;
- private static $view; // a fsview object set to user dir
+ /**
+ * @var \OC\Files\View
+ */
private $rootView; // a fsview object set to '/'
+ /**
+ * @var \OCA\Encryption\Session
+ */
+ private $session;
+ private $privateKey;
/**
* @param $path
@@ -82,6 +85,10 @@ class Stream {
$this->rootView = new \OC_FilesystemView('/');
}
+ $this->session = new \OCA\Encryption\Session($this->rootView);
+
+ $this->privateKey = $this->session->getPrivateKey($this->userId);
+
$util = new Util($this->rootView, \OCP\USER::getUser());
$this->userId = $util->getUserId();
@@ -109,6 +116,11 @@ class Stream {
} else {
+ if($this->privateKey === false) {
+ // if private key is not valid redirect user to a error page
+ \OCA\Encryption\Helper::redirectToErrorPage();
+ }
+
$this->size = $this->rootView->filesize($this->rawPath, $mode);
}
@@ -118,7 +130,7 @@ class Stream {
if (!is_resource($this->handle)) {
- \OCP\Util::writeLog('files_encryption', 'failed to open file "' . $this->rawPath . '"', \OCP\Util::ERROR);
+ \OCP\Util::writeLog('Encryption library', 'failed to open file "' . $this->rawPath . '"', \OCP\Util::ERROR);
} else {
@@ -156,7 +168,7 @@ class Stream {
// $count will always be 8192 https://bugs.php.net/bug.php?id=21641
// This makes this function a lot simpler, but will break this class if the above 'bug' gets 'fixed'
- \OCP\Util::writeLog('files_encryption', 'PHP "bug" 21641 no longer holds, decryption system requires refactoring', \OCP\Util::FATAL);
+ \OCP\Util::writeLog('Encryption library', 'PHP "bug" 21641 no longer holds, decryption system requires refactoring', \OCP\Util::FATAL);
die();
@@ -165,7 +177,7 @@ class Stream {
// Get the data from the file handle
$data = fread($this->handle, 8192);
- $result = '';
+ $result = null;
if (strlen($data)) {
@@ -175,10 +187,11 @@ class Stream {
throw new \Exception(
'Encryption key not found for "' . $this->rawPath . '" during attempted read via stream');
- }
+ } else {
- // Decrypt data
- $result = Crypt::symmetricDecryptFileContent($data, $this->plainKey);
+ // Decrypt data
+ $result = Crypt::symmetricDecryptFileContent($data, $this->plainKey);
+ }
}
@@ -228,13 +241,18 @@ class Stream {
// If a keyfile already exists
if ($this->encKeyfile) {
- $session = new \OCA\Encryption\Session( $this->rootView );
+ // 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();
- $privateKey = $session->getPrivateKey($this->userId);
+ return false;
+ }
$shareKey = Keymanager::getShareKey($this->rootView, $this->userId, $this->relPath);
- $this->plainKey = Crypt::multiKeyDecrypt($this->encKeyfile, $shareKey, $privateKey);
+ $this->plainKey = Crypt::multiKeyDecrypt($this->encKeyfile, $shareKey, $this->privateKey);
return true;
@@ -257,6 +275,12 @@ class Stream {
*/
public function stream_write($data) {
+ // if there is no valid private key return false
+ if ($this->privateKey === false) {
+ $this->size = 0;
+ return strlen($data);
+ }
+
// Disable the file proxies so that encryption is not
// automatically attempted when the file is written to disk -
// we are handling that separately here and we don't want to
@@ -424,6 +448,28 @@ class Stream {
$this->flush();
+ // if there is no valid private key return false
+ if ($this->privateKey === false) {
+
+ // cleanup
+ if ($this->meta['mode'] !== 'r' && $this->meta['mode'] !== 'rb') {
+
+ // Disable encryption proxy to prevent recursive calls
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
+
+ if ($this->rootView->file_exists($this->rawPath) && $this->size === 0) {
+ $this->rootView->unlink($this->rawPath);
+ }
+
+ // Re-enable proxy - our work is done
+ \OC_FileProxy::$enabled = $proxyStatus;
+ }
+
+ // if private key is not valid redirect user to a error page
+ \OCA\Encryption\Helper::redirectToErrorPage();
+ }
+
if (
$this->meta['mode'] !== 'r'
and $this->meta['mode'] !== 'rb'
@@ -450,16 +496,14 @@ class Stream {
// Encrypt enc key for all sharing users
$this->encKeyfiles = Crypt::multiKeyEncrypt($this->plainKey, $publicKeys);
- $view = new \OC_FilesystemView('/');
-
// Save the new encrypted file key
Keymanager::setFileKey($this->rootView, $this->relPath, $this->userId, $this->encKeyfiles['data']);
// Save the sharekeys
- Keymanager::setShareKeys($view, $this->relPath, $this->encKeyfiles['keys']);
+ Keymanager::setShareKeys($this->rootView, $this->relPath, $this->encKeyfiles['keys']);
// get file info
- $fileInfo = $view->getFileInfo($this->rawPath);
+ $fileInfo = $this->rootView->getFileInfo($this->rawPath);
if (!is_array($fileInfo)) {
$fileInfo = array();
}
@@ -473,7 +517,7 @@ class Stream {
$fileInfo['unencrypted_size'] = $this->unencryptedSize;
// set fileinfo
- $view->putFileInfo($this->rawPath, $fileInfo);
+ $this->rootView->putFileInfo($this->rawPath, $fileInfo);
}
return fclose($this->handle);
diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php
index a6711880c20..94defa726a9 100644
--- a/apps/files_encryption/lib/util.php
+++ b/apps/files_encryption/lib/util.php
@@ -96,10 +96,13 @@ class Util {
//// DONE: test new encryption with sharing
//// TODO: test new encryption with proxies
+ const MIGRATION_COMPLETED = 1; // migration to new encryption completed
+ const MIGRATION_IN_PROGRESS = -1; // migration is running
+ const MIGRATION_OPEN = 0; // user still needs to be migrated
+
private $view; // OC_FilesystemView object for filesystem operations
private $userId; // ID of the currently logged-in user
- private $pwd; // User Password
private $client; // Client side encryption mode flag
private $publicKeyDir; // Dir containing all public user keys
private $encryptionDir; // Dir containing user's files_encryption
@@ -302,7 +305,7 @@ class Util {
if (\OCP\DB::isError($result)) {
\OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR);
} else {
- if($result->numRows() > 0) {
+ if ($result->numRows() > 0) {
$row = $result->fetchRow();
if (isset($row['recovery_enabled'])) {
$recoveryEnabled[] = $row['recovery_enabled'];
@@ -442,7 +445,7 @@ class Util {
// If the file uses old
// encryption system
- } elseif ( Crypt::isLegacyEncryptedContent( $data, $relPath ) ) {
+ } elseif (Crypt::isLegacyEncryptedContent($data, $relPath)) {
$found['legacy'][] = array(
'name' => $file,
@@ -573,7 +576,9 @@ class Util {
// get relative path
$relativePath = \OCA\Encryption\Helper::stripUserFilesPath($path);
- if (isset($pathParts[2]) && $pathParts[2] === 'files' && $this->view->file_exists($path) && $this->isEncryptedPath($path)) {
+ if (isset($pathParts[2]) && $pathParts[2] === 'files' && $this->view->file_exists($path)
+ && $this->isEncryptedPath($path)
+ ) {
// get the size from filesystem
$fullPath = $this->view->getLocalFile($path);
@@ -643,7 +648,7 @@ class Util {
return $result;
}
-
+
/**
* @param $path
* @return bool
@@ -687,28 +692,32 @@ class Util {
$relPath = $plainFile['path'];
//relative to /data
- $rawPath = '/'.$this->userId . '/files/' . $plainFile['path'];
+ $rawPath = '/' . $this->userId . '/files/' . $plainFile['path'];
// Open plain file handle for binary reading
- $plainHandle = $this->view->fopen( $rawPath, 'rb' );
+ $plainHandle = $this->view->fopen($rawPath, 'rb');
// Open enc file handle for binary writing, with same filename as original plain file
- $encHandle = fopen( 'crypt://' . $relPath.'.tmp', 'wb' );
+ $encHandle = fopen('crypt://' . $relPath . '.tmp', 'wb');
// Move plain file to a temporary location
- $size = stream_copy_to_stream( $plainHandle, $encHandle );
+ $size = stream_copy_to_stream($plainHandle, $encHandle);
fclose($encHandle);
$fakeRoot = $this->view->getRoot();
- $this->view->chroot('/'.$this->userId.'/files');
+ $this->view->chroot('/' . $this->userId . '/files');
$this->view->rename($relPath . '.tmp', $relPath);
$this->view->chroot($fakeRoot);
// Add the file to the cache
- \OC\Files\Filesystem::putFileInfo( $relPath, array( 'encrypted' => true, 'size' => $size, 'unencrypted_size' => $size ) );
+ \OC\Files\Filesystem::putFileInfo($relPath, array(
+ 'encrypted' => true,
+ 'size' => $size,
+ 'unencrypted_size' => $size
+ ));
}
// Encrypt legacy encrypted files
@@ -722,40 +731,28 @@ class Util {
// Fetch data from file
$legacyData = $this->view->file_get_contents($legacyFile['path']);
- $sharingEnabled = \OCP\Share::isEnabled();
-
- // if file exists try to get sharing users
- if ($this->view->file_exists($legacyFile['path'])) {
- $uniqueUserIds = $this->getSharingUsersArray($sharingEnabled, $legacyFile['path'], $this->userId);
- } else {
- $uniqueUserIds[] = $this->userId;
- }
-
- // Fetch public keys for all users who will share the file
- $publicKeys = Keymanager::getPublicKeys($this->view, $uniqueUserIds);
-
- // Recrypt data, generate catfile
- $recrypted = Crypt::legacyKeyRecryptKeyfile( $legacyData, $legacyPassphrase, $publicKeys );
+ // decrypt data, generate catfile
+ $decrypted = Crypt::legacyBlockDecrypt($legacyData, $legacyPassphrase);
$rawPath = $legacyFile['path'];
- $relPath = \OCA\Encryption\Helper::stripUserFilesPath($rawPath);
- // Save keyfile
- Keymanager::setFileKey($this->view, $relPath, $this->userId, $recrypted['filekey']);
+ // enable proxy the ensure encryption is handled
+ \OC_FileProxy::$enabled = true;
+
+ // Open enc file handle for binary writing, with same filename as original plain file
+ $encHandle = $this->view->fopen( $rawPath, 'wb' );
- // Save sharekeys to user folders
- Keymanager::setShareKeys($this->view, $relPath, $recrypted['sharekeys']);
+ if (is_resource($encHandle)) {
- // Overwrite the existing file with the encrypted one
- $this->view->file_put_contents($rawPath, $recrypted['data']);
+ // write data to stream
+ fwrite($encHandle, $decrypted);
- $size = strlen($recrypted['data']);
+ // close stream
+ fclose($encHandle);
+ }
- // Add the file to the cache
- \OC\Files\Filesystem::putFileInfo($rawPath, array(
- 'encrypted' => true,
- 'size' => $size
- ), '');
+ // disable proxy to prevent file being encrypted twice
+ \OC_FileProxy::$enabled = false;
}
}
@@ -831,7 +828,7 @@ class Util {
if (\OCP\DB::isError($result)) {
\OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR);
} else {
- if($result->numRows() > 0) {
+ if ($result->numRows() > 0) {
$row = $result->fetchRow();
$path = substr($row['path'], strlen('files'));
}
@@ -1054,36 +1051,56 @@ class Util {
}
/**
- * @brief Set file migration status for user
- * @param $status
- * @return bool
+ * @brief start migration mode to initially encrypt users data
+ * @return boolean
*/
- public function setMigrationStatus($status) {
+ public function beginMigration() {
- $sql = 'UPDATE `*PREFIX*encryption` SET `migration_status` = ? WHERE `uid` = ?';
-
- $args = array(
- $status,
- $this->userId
- );
+ $return = false;
+ $sql = 'UPDATE `*PREFIX*encryption` SET `migration_status` = ? WHERE `uid` = ? and `migration_status` = ?';
+ $args = array(self::MIGRATION_IN_PROGRESS, $this->userId, self::MIGRATION_OPEN);
$query = \OCP\DB::prepare($sql);
+ $result = $query->execute($args);
+ $manipulatedRows = $result->numRows();
- if ($query->execute($args)) {
+ if ($manipulatedRows === 1) {
+ $return = true;
+ \OCP\Util::writeLog('Encryption library', "Start migration to encryption mode for " . $this->userId, \OCP\Util::INFO);
+ } else {
+ \OCP\Util::writeLog('Encryption library', "Could not activate migration mode for " . $this->userId . ". Probably another process already started the initial encryption", \OCP\Util::WARN);
+ }
- return true;
+ return $return;
+ }
- } else {
+ /**
+ * @brief close migration mode after users data has been encrypted successfully
+ * @return boolean
+ */
+ public function finishMigration() {
- return false;
+ $return = false;
+
+ $sql = 'UPDATE `*PREFIX*encryption` SET `migration_status` = ? WHERE `uid` = ? and `migration_status` = ?';
+ $args = array(self::MIGRATION_COMPLETED, $this->userId, self::MIGRATION_IN_PROGRESS);
+ $query = \OCP\DB::prepare($sql);
+ $result = $query->execute($args);
+ $manipulatedRows = $result->numRows();
+ if ($manipulatedRows === 1) {
+ $return = true;
+ \OCP\Util::writeLog('Encryption library', "Finish migration successfully for " . $this->userId, \OCP\Util::INFO);
+ } else {
+ \OCP\Util::writeLog('Encryption library', "Could not deactivate migration mode for " . $this->userId, \OCP\Util::WARN);
}
+ return $return;
}
/**
- * @brief Check whether pwd recovery is enabled for a given user
- * @return bool 1 = yes, 0 = no, false = no record
+ * @brief check if files are already migrated to the encryption system
+ * @return migration status, false = in case of no record
* @note If records are not being returned, check for a hidden space
* at the start of the uid in db
*/
@@ -1102,7 +1119,7 @@ class Util {
if (\OCP\DB::isError($result)) {
\OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR);
} else {
- if($result->numRows() > 0) {
+ if ($result->numRows() > 0) {
$row = $result->fetchRow();
if (isset($row['migration_status'])) {
$migrationStatus[] = $row['migration_status'];
@@ -1112,14 +1129,11 @@ class Util {
// If no record is found
if (empty($migrationStatus)) {
-
+ \OCP\Util::writeLog('Encryption library', "Could not get migration status for " . $this->userId . ", no record found", \OCP\Util::ERROR);
return false;
-
// If a record is found
} else {
-
- return $migrationStatus[0];
-
+ return (int)$migrationStatus[0];
}
}
@@ -1191,7 +1205,8 @@ class Util {
$result = array();
- $content = $this->view->getDirectoryContent(\OC\Files\Filesystem::normalizePath($this->userFilesDir . '/' . $dir));
+ $content = $this->view->getDirectoryContent(\OC\Files\Filesystem::normalizePath(
+ $this->userFilesDir . '/' . $dir));
// handling for re shared folders
$pathSplit = explode('/', $dir);
@@ -1252,7 +1267,7 @@ class Util {
if (\OCP\DB::isError($result)) {
\OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR);
} else {
- if($result->numRows() > 0) {
+ if ($result->numRows() > 0) {
$row = $result->fetchRow();
}
}
@@ -1278,7 +1293,7 @@ class Util {
if (\OCP\DB::isError($result)) {
\OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR);
} else {
- if($result->numRows() > 0) {
+ if ($result->numRows() > 0) {
$row = $result->fetchRow();
}
}
@@ -1303,7 +1318,7 @@ class Util {
if (\OCP\DB::isError($result)) {
\OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR);
} else {
- if($result->numRows() > 0) {
+ if ($result->numRows() > 0) {
$source = $result->fetchRow();
}
}
@@ -1324,7 +1339,7 @@ class Util {
if (\OCP\DB::isError($result)) {
\OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR);
} else {
- if($result->numRows() > 0) {
+ if ($result->numRows() > 0) {
$item = $result->fetchRow();
}
}
@@ -1372,26 +1387,24 @@ class Util {
*/
public function checkRecoveryPassword($password) {
+ $result = false;
$pathKey = '/owncloud_private_key/' . $this->recoveryKeyId . ".private.key";
- $pathControlData = '/control-file/controlfile.enc';
$proxyStatus = \OC_FileProxy::$enabled;
\OC_FileProxy::$enabled = false;
$recoveryKey = $this->view->file_get_contents($pathKey);
- $decryptedRecoveryKey = Crypt::symmetricDecryptFileContent($recoveryKey, $password);
+ $decryptedRecoveryKey = Crypt::decryptPrivateKey($recoveryKey, $password);
- $controlData = $this->view->file_get_contents($pathControlData);
- $decryptedControlData = Crypt::keyDecrypt($controlData, $decryptedRecoveryKey);
+ if ($decryptedRecoveryKey) {
+ $result = true;
+ }
\OC_FileProxy::$enabled = $proxyStatus;
- if ($decryptedControlData === 'ownCloud') {
- return true;
- }
- return false;
+ return $result;
}
/**
@@ -1520,7 +1533,7 @@ class Util {
$encryptedKey = $this->view->file_get_contents(
'/owncloud_private_key/' . $this->recoveryKeyId . '.private.key');
- $privateKey = Crypt::symmetricDecryptFileContent($encryptedKey, $recoveryPassword);
+ $privateKey = Crypt::decryptPrivateKey($encryptedKey, $recoveryPassword);
\OC_FileProxy::$enabled = $proxyStatus;
@@ -1536,7 +1549,7 @@ class Util {
list($storage, $internalPath) = \OC\Files\Cache\Cache::getById($id);
$mount = \OC\Files\Filesystem::getMountByStorageId($storage);
$mountPoint = $mount[0]->getMountPoint();
- $path = \OC\Files\Filesystem::normalizePath($mountPoint.'/'.$internalPath);
+ $path = \OC\Files\Filesystem::normalizePath($mountPoint . '/' . $internalPath);
// reformat the path to be relative e.g. /user/files/folder becomes /folder/
$relativePath = \OCA\Encryption\Helper::stripUserFilesPath($path);
diff --git a/apps/files_encryption/settings-personal.php b/apps/files_encryption/settings-personal.php
index 3e96565949b..fddc3ea5eee 100644
--- a/apps/files_encryption/settings-personal.php
+++ b/apps/files_encryption/settings-personal.php
@@ -14,15 +14,26 @@ $tmpl = new OCP\Template('files_encryption', 'settings-personal');
$user = \OCP\USER::getUser();
$view = new \OC_FilesystemView('/');
$util = new \OCA\Encryption\Util($view, $user);
+$session = new \OCA\Encryption\Session($view);
+
+$privateKeySet = ($session->getPrivateKey() !== false) ? true : false;
$recoveryAdminEnabled = OC_Appconfig::getValue('files_encryption', 'recoveryAdminEnabled');
$recoveryEnabledForUser = $util->recoveryEnabledForUser();
-\OCP\Util::addscript('files_encryption', 'settings-personal');
-\OCP\Util::addScript('settings', 'personal');
+$result = false;
+
+if ($recoveryAdminEnabled || !$privateKeySet) {
+
+ \OCP\Util::addscript('files_encryption', 'settings-personal');
+ \OCP\Util::addScript('settings', 'personal');
+
+ $tmpl->assign('recoveryEnabled', $recoveryAdminEnabled);
+ $tmpl->assign('recoveryEnabledForUser', $recoveryEnabledForUser);
+ $tmpl->assign('privateKeySet', $privateKeySet);
-$tmpl->assign('recoveryEnabled', $recoveryAdminEnabled);
-$tmpl->assign('recoveryEnabledForUser', $recoveryEnabledForUser);
+ $result = $tmpl->fetchPage();
+}
-return $tmpl->fetchPage();
+return $result;
diff --git a/apps/files_encryption/templates/invalid_private_key.php b/apps/files_encryption/templates/invalid_private_key.php
new file mode 100644
index 00000000000..5c086d6514c
--- /dev/null
+++ b/apps/files_encryption/templates/invalid_private_key.php
@@ -0,0 +1,10 @@
+<ul>
+ <li class='error'>
+ <?php $location = \OC_Helper::linkToRoute( "settings_personal" ).'#changePKPasswd' ?>
+
+ <?php p($l->t('Your private key is not valid! Maybe the your password was changed from outside.')); ?>
+ <br/>
+ <?php p($l->t('You can unlock your private key in your ')); ?> <a href="<?php echo $location?>"><?php p($l->t('personal settings')); ?>.</a>
+ <br/>
+ </li>
+</ul>
diff --git a/apps/files_encryption/templates/settings-admin.php b/apps/files_encryption/templates/settings-admin.php
index 18fea1845f4..c420b006c45 100644
--- a/apps/files_encryption/templates/settings-admin.php
+++ b/apps/files_encryption/templates/settings-admin.php
@@ -1,54 +1,56 @@
<form id="encryption">
<fieldset class="personalblock">
-
+
<p>
- <strong><?php p($l->t( 'Encryption' )); ?></strong>
- <br />
+ <strong><?php p($l->t('Encryption')); ?></strong>
+ <br/>
</p>
+
<p>
- <?php p($l->t( "Enable encryption passwords recovery key (allow sharing to recovery key):" )); ?>
- <br />
- <br />
- <input type="password" name="recoveryPassword" id="recoveryPassword" />
- <label for="recoveryPassword"><?php p($l->t( "Recovery account password" )); ?></label>
- <br />
- <input
- type='radio'
- name='adminEnableRecovery'
- value='1'
- <?php echo ( $_["recoveryEnabled"] == 1 ? 'checked="checked"' : 'disabled' ); ?> />
- <?php p($l->t( "Enabled" )); ?>
- <br />
-
- <input
- type='radio'
- name='adminEnableRecovery'
- value='0'
- <?php echo ( $_["recoveryEnabled"] == 0 ? 'checked="checked"' : 'disabled' ); ?> />
- <?php p($l->t( "Disabled" )); ?>
+ <?php p($l->t("Enable encryption passwords recovery key (allow sharing to recovery key):")); ?>
+ <br/>
+ <br/>
+ <input type="password" name="recoveryPassword" id="recoveryPassword"/>
+ <label for="recoveryPassword"><?php p($l->t("Recovery account password")); ?></label>
+ <br/>
+ <input
+ type='radio'
+ name='adminEnableRecovery'
+ value='1'
+ <?php echo($_["recoveryEnabled"] == 1 ? 'checked="checked"' : 'disabled'); ?> />
+ <?php p($l->t("Enabled")); ?>
+ <br/>
+
+ <input
+ type='radio'
+ name='adminEnableRecovery'
+ value='0'
+ <?php echo($_["recoveryEnabled"] == 0 ? 'checked="checked"' : 'disabled'); ?> />
+ <?php p($l->t("Disabled")); ?>
</p>
- <br /><br />
+ <br/><br/>
+
<p>
- <strong><?php p($l->t( "Change encryption passwords recovery key:" )); ?></strong>
- <br /><br />
- <input
+ <strong><?php p($l->t("Change encryption passwords recovery key:")); ?></strong>
+ <br/><br/>
+ <input
type="password"
name="changeRecoveryPassword"
id="oldRecoveryPassword"
- <?php echo ( $_["recoveryEnabled"] == 0 ? 'disabled' : '' ); ?> />
- <label for="oldRecoveryPassword"><?php p($l->t( "Old Recovery account password" )); ?></label>
- <br />
- <input
+ <?php echo($_["recoveryEnabled"] == 0 ? 'disabled' : ''); ?> />
+ <label for="oldRecoveryPassword"><?php p($l->t("Old Recovery account password")); ?></label>
+ <br/>
+ <input
type="password"
name="changeRecoveryPassword"
id="newRecoveryPassword"
- <?php echo ( $_["recoveryEnabled"] == 0 ? 'disabled' : '' ); ?> />
- <label for="newRecoveryPassword"><?php p($l->t( "New Recovery account password" )); ?></label>
- <br />
+ <?php echo($_["recoveryEnabled"] == 0 ? 'disabled' : ''); ?> />
+ <label for="newRecoveryPassword"><?php p($l->t("New Recovery account password")); ?></label>
+ <br/>
<button
type="button"
name="submitChangeRecoveryKey"
- disabled><?php p($l->t( "Change Password" )); ?>
+ disabled><?php p($l->t("Change Password")); ?>
</button>
<span class="msg"></span>
</p>
diff --git a/apps/files_encryption/templates/settings-personal.php b/apps/files_encryption/templates/settings-personal.php
index 04d6e79179e..38512453207 100644
--- a/apps/files_encryption/templates/settings-personal.php
+++ b/apps/files_encryption/templates/settings-personal.php
@@ -3,12 +3,48 @@
<legend>
<?php p( $l->t( 'Encryption' ) ); ?>
</legend>
+
+ <?php if ( ! $_["privateKeySet"] ): ?>
+ <p>
+ <a name="changePKPasswd" />
+ <label for="changePrivateKeyPasswd">
+ <?php p( $l->t( "Your private key password no longer match your log-in password:" ) ); ?>
+ </label>
+ <br />
+ <em><?php p( $l->t( "Set your old private key password to your current log-in password." ) ); ?>
+ <?php if ( $_["recoveryEnabledForUser"] ):
+ p( $l->t( " If you don't remember your old password you can ask your administrator to recover your files." ) );
+ endif; ?>
+ </em>
+ <br />
+ <input
+ type="password"
+ name="changePrivateKeyPassword"
+ id="oldPrivateKeyPassword" />
+ <label for="oldPrivateKeyPassword"><?php p($l->t( "Old log-in password" )); ?></label>
+ <br />
+ <input
+ type="password"
+ name="changePrivateKeyPassword"
+ id="newPrivateKeyPassword" />
+ <label for="newRecoveryPassword"><?php p($l->t( "Current log-in password" )); ?></label>
+ <br />
+ <button
+ type="button"
+ name="submitChangePrivateKeyPassword"
+ disabled><?php p($l->t( "Update Private Key Password" )); ?>
+ </button>
+ <span class="msg"></span>
+ </p>
+ <?php endif; ?>
+
+ <br />
- <?php if ( $_["recoveryEnabled"] ): ?>
+ <?php if ( $_["recoveryEnabled"] && $_["privateKeySet"] ): ?>
<p>
- <label for="userEnableRecovery"><?php p( $l->t( "Enable password recovery by sharing all files with your administrator:" ) ); ?></label>
+ <label for="userEnableRecovery"><?php p( $l->t( "Enable password recovery:" ) ); ?></label>
<br />
- <em><?php p( $l->t( "Enabling this option will allow you to reobtain access to your encrypted files if your password is lost" ) ); ?></em>
+ <em><?php p( $l->t( "Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" ) ); ?></em>
<br />
<input
type='radio'
@@ -28,6 +64,7 @@
<div id="recoveryEnabledError"><?php p( $l->t( 'Could not update file recovery' ) ); ?></div>
</p>
<?php endif; ?>
+
<br />
</fieldset>
</form>
diff --git a/apps/files_encryption/tests/crypt.php b/apps/files_encryption/tests/crypt.php
index 341904b1189..9b97df22d16 100755
--- a/apps/files_encryption/tests/crypt.php
+++ b/apps/files_encryption/tests/crypt.php
@@ -92,8 +92,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase {
// reset app files_trashbin
if ($this->stateFilesTrashbin) {
OC_App::enable('files_trashbin');
- }
- else {
+ } else {
OC_App::disable('files_trashbin');
}
}
@@ -240,6 +239,23 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase {
}
+ function testDecryptPrivateKey() {
+
+ // test successful decrypt
+ $crypted = Encryption\Crypt::symmetricEncryptFileContent($this->genPrivateKey, 'hat');
+
+ $decrypted = Encryption\Crypt::decryptPrivateKey($crypted, 'hat');
+
+ $this->assertEquals($this->genPrivateKey, $decrypted);
+
+ //test private key decrypt with wrong password
+ $wrongPasswd = Encryption\Crypt::decryptPrivateKey($crypted, 'hat2');
+
+ $this->assertEquals(false, $wrongPasswd);
+
+ }
+
+
/**
* @medium
*/
@@ -613,24 +629,6 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase {
/**
* @medium
- * @brief test decryption using legacy blowfish method
- * @depends testLegacyEncryptLong
- */
- function testLegacyKeyRecryptKeyfileEncrypt($crypted) {
-
- $recrypted = Encryption\Crypt::LegacyKeyRecryptKeyfile($crypted, $this->pass, array($this->genPublicKey));
-
- $this->assertNotEquals($this->dataLong, $recrypted['data']);
-
- return $recrypted;
-
- # TODO: search inencrypted text for actual content to ensure it
- # genuine transformation
-
- }
-
- /**
- * @medium
*/
function testRenameFile() {
diff --git a/apps/files_encryption/tests/share.php b/apps/files_encryption/tests/share.php
index 15dd5058ebb..6b530315859 100755
--- a/apps/files_encryption/tests/share.php
+++ b/apps/files_encryption/tests/share.php
@@ -111,8 +111,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase {
// reset app files_trashbin
if ($this->stateFilesTrashbin) {
OC_App::enable('files_trashbin');
- }
- else {
+ } else {
OC_App::disable('files_trashbin');
}
}
@@ -656,9 +655,6 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase {
\OCA\Encryption\Helper::adminEnableRecovery(null, 'test123');
$recoveryKeyId = OC_Appconfig::getValue('files_encryption', 'recoveryKeyId');
- // check if control file created
- $this->assertTrue($this->view->file_exists('/control-file/controlfile.enc'));
-
// login as admin
\Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1);
@@ -761,9 +757,6 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase {
\OCA\Encryption\Helper::adminEnableRecovery(null, 'test123');
$recoveryKeyId = OC_Appconfig::getValue('files_encryption', 'recoveryKeyId');
- // check if control file created
- $this->assertTrue($this->view->file_exists('/control-file/controlfile.enc'));
-
// login as user1
\Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2);
diff --git a/apps/files_encryption/tests/util.php b/apps/files_encryption/tests/util.php
index 6d6c8bca3dd..cb10befc8e4 100755
--- a/apps/files_encryption/tests/util.php
+++ b/apps/files_encryption/tests/util.php
@@ -75,7 +75,7 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase {
$this->legacyData = realpath(dirname(__FILE__) . '/legacy-text.txt');
$this->legacyEncryptedData = realpath(dirname(__FILE__) . '/legacy-encrypted-text.txt');
$this->legacyEncryptedDataKey = realpath(dirname(__FILE__) . '/encryption.key');
- $this->legacyKey = '30943623843030686906';
+ $this->legacyKey = "30943623843030686906\0\0\0\0";
$keypair = Encryption\Crypt::createKeypair();
@@ -182,8 +182,7 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase {
$params['uid'] = \Test_Encryption_Util::TEST_ENCRYPTION_UTIL_LEGACY_USER;
$params['password'] = \Test_Encryption_Util::TEST_ENCRYPTION_UTIL_LEGACY_USER;
- $util = new Encryption\Util($this->view, \Test_Encryption_Util::TEST_ENCRYPTION_UTIL_LEGACY_USER);
- $util->setMigrationStatus(0);
+ $this->setMigrationStatus(0, \Test_Encryption_Util::TEST_ENCRYPTION_UTIL_LEGACY_USER);
$this->assertTrue(OCA\Encryption\Hooks::login($params));
@@ -285,7 +284,7 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase {
$params['password'] = \Test_Encryption_Util::TEST_ENCRYPTION_UTIL_LEGACY_USER;
$util = new Encryption\Util($this->view, \Test_Encryption_Util::TEST_ENCRYPTION_UTIL_LEGACY_USER);
- $util->setMigrationStatus(0);
+ $this->setMigrationStatus(0, \Test_Encryption_Util::TEST_ENCRYPTION_UTIL_LEGACY_USER);
$this->assertTrue(OCA\Encryption\Hooks::login($params));
@@ -330,4 +329,28 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase {
$params['password'] = $password;
OCA\Encryption\Hooks::login($params);
}
+
+ /**
+ * helper function to set migration status to the right value
+ * to be able to test the migration path
+ *
+ * @param $status needed migration status for test
+ * @param $user for which user the status should be set
+ * @return boolean
+ */
+ private function setMigrationStatus($status, $user) {
+ $sql = 'UPDATE `*PREFIX*encryption` SET `migration_status` = ? WHERE `uid` = ?';
+ $args = array(
+ $status,
+ $user
+ );
+
+ $query = \OCP\DB::prepare($sql);
+ if ($query->execute($args)) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
}