From 854fd63ea907a870f1916d266e18aaba97820e32 Mon Sep 17 00:00:00 2001
From: Bjoern Schiessle <schiessle@owncloud.com>
Date: Fri, 7 Aug 2015 15:51:43 +0200
Subject: [PATCH] use uid as additional information for salt

---
 apps/encryption/controller/settingscontroller.php |  4 ++--
 apps/encryption/hooks/userhooks.php               |  4 ++--
 apps/encryption/lib/crypto/crypt.php              | 15 +++++++++------
 apps/encryption/lib/keymanager.php                |  8 +++-----
 apps/encryption/lib/recovery.php                  |  3 +--
 5 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/apps/encryption/controller/settingscontroller.php b/apps/encryption/controller/settingscontroller.php
index dbd960bb784..2a668f7cd4a 100644
--- a/apps/encryption/controller/settingscontroller.php
+++ b/apps/encryption/controller/settingscontroller.php
@@ -100,10 +100,10 @@ class SettingsController extends Controller {
 
 		if ($passwordCorrect !== false) {
 			$encryptedKey = $this->keyManager->getPrivateKey($uid);
-			$decryptedKey = $this->crypt->decryptPrivateKey($encryptedKey, $oldPassword);
+			$decryptedKey = $this->crypt->decryptPrivateKey($encryptedKey, $oldPassword, $uid);
 
 			if ($decryptedKey) {
-				$encryptedKey = $this->crypt->encryptPrivateKey($decryptedKey, $newPassword);
+				$encryptedKey = $this->crypt->encryptPrivateKey($decryptedKey, $newPassword, $uid);
 				$header = $this->crypt->generateHeader();
 				if ($encryptedKey) {
 					$this->keyManager->setPrivateKey($uid, $header . $encryptedKey);
diff --git a/apps/encryption/hooks/userhooks.php b/apps/encryption/hooks/userhooks.php
index 71c0435d200..8b6f17bec6d 100644
--- a/apps/encryption/hooks/userhooks.php
+++ b/apps/encryption/hooks/userhooks.php
@@ -220,7 +220,7 @@ class UserHooks implements IHook {
 		if ($user && $params['uid'] === $user->getUID() && $privateKey) {
 
 			// Encrypt private key with new user pwd as passphrase
-			$encryptedPrivateKey = $this->crypt->encryptPrivateKey($privateKey, $params['password']);
+			$encryptedPrivateKey = $this->crypt->encryptPrivateKey($privateKey, $params['password'], $params['uid']);
 
 			// Save private key
 			if ($encryptedPrivateKey) {
@@ -258,7 +258,7 @@ class UserHooks implements IHook {
 				$this->keyManager->setPublicKey($user, $keyPair['publicKey']);
 
 				// Encrypt private key with new password
-				$encryptedKey = $this->crypt->encryptPrivateKey($keyPair['privateKey'], $newUserPassword);
+				$encryptedKey = $this->crypt->encryptPrivateKey($keyPair['privateKey'], $newUserPassword, $user);
 
 				if ($encryptedKey) {
 					$this->keyManager->setPrivateKey($user, $this->crypt->generateHeader() . $encryptedKey);
diff --git a/apps/encryption/lib/crypto/crypt.php b/apps/encryption/lib/crypto/crypt.php
index eef16e51447..6c4c108f50a 100644
--- a/apps/encryption/lib/crypto/crypt.php
+++ b/apps/encryption/lib/crypto/crypt.php
@@ -285,12 +285,13 @@ class Crypt {
 	 *
 	 * @param string $password
 	 * @param string $cipher
+	 * @param string $uid only used for user keys
 	 * @return string
 	 */
-	protected function generatePasswordHash($password, $cipher) {
+	protected function generatePasswordHash($password, $cipher, $uid = '') {
 		$instanceId = $this->config->getSystemValue('instanceid');
 		$instanceSecret = $this->config->getSystemValue('secret');
-		$salt = hash('sha256', $instanceId . $instanceSecret, true);
+		$salt = hash('sha256', $uid . $instanceId . $instanceSecret, true);
 		$keySize = $this->getKeySize($cipher);
 
 		if (function_exists('hash_pbkdf2')) {
@@ -324,11 +325,12 @@ class Crypt {
 	 *
 	 * @param string $privateKey
 	 * @param string $password
+	 * @param string $uid for regular users, empty for system keys
 	 * @return bool|string
 	 */
-	public function encryptPrivateKey($privateKey, $password) {
+	public function encryptPrivateKey($privateKey, $password, $uid = '') {
 		$cipher = $this->getCipher();
-		$hash = $this->generatePasswordHash($password, $cipher);
+		$hash = $this->generatePasswordHash($password, $cipher, $uid);
 		$encryptedKey = $this->symmetricEncryptFileContent(
 			$privateKey,
 			$hash
@@ -340,9 +342,10 @@ class Crypt {
 	/**
 	 * @param string $privateKey
 	 * @param string $password
+	 * @param string $uid for regular users, empty for system keys
 	 * @return bool|string
 	 */
-	public function decryptPrivateKey($privateKey, $password = '') {
+	public function decryptPrivateKey($privateKey, $password = '', $uid = '') {
 
 		$header = $this->parseHeader($privateKey);
 
@@ -359,7 +362,7 @@ class Crypt {
 		}
 
 		if ($keyFormat === 'hash') {
-			$password = $this->generatePasswordHash($password, $cipher);
+			$password = $this->generatePasswordHash($password, $cipher, $uid);
 		}
 
 		// If we found a header we need to remove it from the key we want to decrypt
diff --git a/apps/encryption/lib/keymanager.php b/apps/encryption/lib/keymanager.php
index 47a8e7d391f..6c793e5964f 100644
--- a/apps/encryption/lib/keymanager.php
+++ b/apps/encryption/lib/keymanager.php
@@ -184,8 +184,7 @@ class KeyManager {
 	 */
 	public function checkRecoveryPassword($password) {
 		$recoveryKey = $this->keyStorage->getSystemUserKey($this->recoveryKeyId . '.privateKey', Encryption::ID);
-		$decryptedRecoveryKey = $this->crypt->decryptPrivateKey($recoveryKey,
-			$password);
+		$decryptedRecoveryKey = $this->crypt->decryptPrivateKey($recoveryKey, $password);
 
 		if ($decryptedRecoveryKey) {
 			return true;
@@ -203,7 +202,7 @@ class KeyManager {
 		// Save Public Key
 		$this->setPublicKey($uid, $keyPair['publicKey']);
 
-		$encryptedKey = $this->crypt->encryptPrivateKey($keyPair['privateKey'], $password);
+		$encryptedKey = $this->crypt->encryptPrivateKey($keyPair['privateKey'], $password, $uid);
 
 		$header = $this->crypt->generateHeader();
 
@@ -307,8 +306,7 @@ class KeyManager {
 
 		try {
 			$privateKey = $this->getPrivateKey($uid);
-			$privateKey = $this->crypt->decryptPrivateKey($privateKey,
-				$passPhrase);
+			$privateKey = $this->crypt->decryptPrivateKey($privateKey, $passPhrase, $uid);
 		} catch (PrivateKeyMissingException $e) {
 			return false;
 		} catch (DecryptionFailedException $e) {
diff --git a/apps/encryption/lib/recovery.php b/apps/encryption/lib/recovery.php
index e82ecca9d49..b22e3265628 100644
--- a/apps/encryption/lib/recovery.php
+++ b/apps/encryption/lib/recovery.php
@@ -263,8 +263,7 @@ class Recovery {
 	public function recoverUsersFiles($recoveryPassword, $user) {
 		$encryptedKey = $this->keyManager->getSystemPrivateKey($this->keyManager->getRecoveryKeyId());
 
-		$privateKey = $this->crypt->decryptPrivateKey($encryptedKey,
-			$recoveryPassword);
+		$privateKey = $this->crypt->decryptPrivateKey($encryptedKey, $recoveryPassword);
 
 		$this->recoverAllFiles('/' . $user . '/files/', $privateKey, $user);
 	}
-- 
GitLab