From 6cbb6ceba388ff46d35a21f6ebdf2fd86cb979bd Mon Sep 17 00:00:00 2001
From: Vincent Petry <pvince81@owncloud.com>
Date: Thu, 2 Mar 2017 16:11:01 +0100
Subject: Use master key for public links as well

---
 apps/encryption/lib/KeyManager.php       | 19 ++++++++++++----
 apps/encryption/tests/KeyManagerTest.php | 39 ++++++++++++++++----------------
 2 files changed, 35 insertions(+), 23 deletions(-)

diff --git a/apps/encryption/lib/KeyManager.php b/apps/encryption/lib/KeyManager.php
index 1e1f3231b8b..1b5df007962 100644
--- a/apps/encryption/lib/KeyManager.php
+++ b/apps/encryption/lib/KeyManager.php
@@ -399,17 +399,28 @@ class KeyManager {
 	 * @return string
 	 */
 	public function getFileKey($path, $uid) {
+		if ($uid === '') {
+			$uid = null;
+		}
+		$publicAccess = is_null($uid);
 		$encryptedFileKey = $this->keyStorage->getFileKey($path, $this->fileKeyId, Encryption::ID);
 
 		if (empty($encryptedFileKey)) {
 			return '';
 		}
 
-		if (!is_null($uid) && $this->util->isMasterKeyEnabled()) {
+		if ($this->util->isMasterKeyEnabled()) {
 			$uid = $this->getMasterKeyId();
-		}
-
-		if (is_null($uid)) {
+			$shareKey = $this->getShareKey($path, $uid);
+			if ($publicAccess) {
+				$privateKey = $this->getSystemPrivateKey($uid);
+				$privateKey = $this->crypt->decryptPrivateKey($privateKey, $this->getMasterKeyPassword(), $uid);
+			} else {
+				// when logged in, the master key is already decrypted in the session
+				$privateKey = $this->session->getPrivateKey();
+			}
+		} else if ($publicAccess) {
+			// use public share key for public links
 			$uid = $this->getPublicShareKeyId();
 			$shareKey = $this->getShareKey($path, $uid);
 			$privateKey = $this->keyStorage->getSystemUserKey($this->publicShareKeyId . '.privateKey', Encryption::ID);
diff --git a/apps/encryption/tests/KeyManagerTest.php b/apps/encryption/tests/KeyManagerTest.php
index f3c03529652..a9f0b06d738 100644
--- a/apps/encryption/tests/KeyManagerTest.php
+++ b/apps/encryption/tests/KeyManagerTest.php
@@ -349,6 +349,19 @@ class KeyManagerTest extends TestCase {
 		$this->assertTrue($this->instance->getEncryptedFileKey('/'));
 	}
 
+	public function dataTestGetFileKey() {
+		return [
+			['user1', false, 'privateKey', true],
+			['user1', false, false, ''],
+			['user1', true, 'privateKey', true],
+			['user1', true, false, ''],
+			[null, false, 'privateKey', true],
+			[null, false, false, ''],
+			[null, true, 'privateKey', true],
+			[null, true, false, '']
+		];
+	}
+
 	/**
 	 * @dataProvider dataTestGetFileKey
 	 *
@@ -363,6 +376,10 @@ class KeyManagerTest extends TestCase {
 
 		if ($isMasterKeyEnabled) {
 			$expectedUid = 'masterKeyId';
+			$this->configMock->expects($this->any())->method('getSystemValue')->with('secret')
+				->willReturn('password');
+		} else if (!$uid) {
+			$expectedUid = 'systemKeyId';
 		} else {
 			$expectedUid = $uid;
 		}
@@ -379,6 +396,9 @@ class KeyManagerTest extends TestCase {
 			->with($path, $expectedUid . '.shareKey', 'OC_DEFAULT_MODULE')
 			->willReturn(true);
 
+		$this->utilMock->expects($this->any())->method('isMasterKeyEnabled')
+			->willReturn($isMasterKeyEnabled);
+
 		if (is_null($uid)) {
 			$this->keyStorageMock->expects($this->once())
 				->method('getSystemUserKey')
@@ -389,8 +409,6 @@ class KeyManagerTest extends TestCase {
 		} else {
 			$this->keyStorageMock->expects($this->never())
 				->method('getSystemUserKey');
-			$this->utilMock->expects($this->once())->method('isMasterKeyEnabled')
-				->willReturn($isMasterKeyEnabled);
 			$this->sessionMock->expects($this->once())->method('getPrivateKey')->willReturn($privateKey);
 		}
 
@@ -409,23 +427,6 @@ class KeyManagerTest extends TestCase {
 
 	}
 
-	public function dataTestGetFileKey() {
-		return [
-			['user1', false, 'privateKey', true],
-			['user1', false, false, ''],
-			['user1', true, 'privateKey', true],
-			['user1', true, false, ''],
-			['', false, 'privateKey', true],
-			['', false, false, ''],
-			['', true, 'privateKey', true],
-			['', true, false, ''],
-			[null, false, 'privateKey', true],
-			[null, false, false, ''],
-			[null, true, 'privateKey', true],
-			[null, true, false, '']
-		];
-	}
-
 	public function testDeletePrivateKey() {
 		$this->keyStorageMock->expects($this->once())
 			->method('deleteUserKey')
-- 
cgit v1.2.3