aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Scherzinger <info@andy-scherzinger.de>2024-06-11 14:02:39 +0200
committerGitHub <noreply@github.com>2024-06-11 14:02:39 +0200
commit400d11d54f4598e672c0104da06490b5fe7a15f3 (patch)
treef66d28a726c07d9f77a098d1e123cdc4d6497e93
parent436663f3c7c3d0447afb8f89607a6a040a31bee3 (diff)
parent71188dc3f2b4eebf0e85356ebe7c6715ba752417 (diff)
downloadnextcloud-server-400d11d54f4598e672c0104da06490b5fe7a15f3.tar.gz
nextcloud-server-400d11d54f4598e672c0104da06490b5fe7a15f3.zip
Merge pull request #45777 from nextcloud/backport/45669/stable28
[stable28] fix: Autodetect legacy filekey instead of trusting the header for legacy header
-rw-r--r--apps/encryption/lib/Crypto/Encryption.php20
-rw-r--r--apps/encryption/lib/KeyManager.php11
-rw-r--r--apps/encryption/tests/Crypto/EncryptionTest.php35
3 files changed, 23 insertions, 43 deletions
diff --git a/apps/encryption/lib/Crypto/Encryption.php b/apps/encryption/lib/Crypto/Encryption.php
index 1481d3a9a23..9980def3388 100644
--- a/apps/encryption/lib/Crypto/Encryption.php
+++ b/apps/encryption/lib/Crypto/Encryption.php
@@ -80,8 +80,6 @@ class Encryption implements IEncryptionModule {
/** @var int Current version of the file */
private int $version = 0;
- private bool $useLegacyFileKey = true;
-
/** @var array remember encryption signature version */
private static $rememberVersion = [];
@@ -138,7 +136,6 @@ class Encryption implements IEncryptionModule {
$this->writeCache = '';
$this->useLegacyBase64Encoding = true;
- $this->useLegacyFileKey = ($header['useLegacyFileKey'] ?? 'true') !== 'false';
if (isset($header['encoding'])) {
$this->useLegacyBase64Encoding = $header['encoding'] !== Crypt::BINARY_ENCODING_FORMAT;
@@ -152,19 +149,10 @@ class Encryption implements IEncryptionModule {
}
}
- if ($this->session->decryptAllModeActivated()) {
- $shareKey = $this->keyManager->getShareKey($this->path, $this->session->getDecryptAllUid());
- if ($this->useLegacyFileKey) {
- $encryptedFileKey = $this->keyManager->getEncryptedFileKey($this->path);
- $this->fileKey = $this->crypt->multiKeyDecryptLegacy($encryptedFileKey,
- $shareKey,
- $this->session->getDecryptAllKey());
- } else {
- $this->fileKey = $this->crypt->multiKeyDecrypt($shareKey, $this->session->getDecryptAllKey());
- }
- } else {
- $this->fileKey = $this->keyManager->getFileKey($this->path, $this->user, $this->useLegacyFileKey);
- }
+ /* If useLegacyFileKey is not specified in header, auto-detect, to be safe */
+ $useLegacyFileKey = (($header['useLegacyFileKey'] ?? '') == 'false' ? false : null);
+
+ $this->fileKey = $this->keyManager->getFileKey($this->path, $this->user, $useLegacyFileKey, $this->session->decryptAllModeActivated());
// always use the version from the original file, also part files
// need to have a correct version number if they get moved over to the
diff --git a/apps/encryption/lib/KeyManager.php b/apps/encryption/lib/KeyManager.php
index 7d6380f3b83..f46faa8a0a1 100644
--- a/apps/encryption/lib/KeyManager.php
+++ b/apps/encryption/lib/KeyManager.php
@@ -367,12 +367,9 @@ class KeyManager {
}
/**
- * @param string $path
- * @param $uid
* @param ?bool $useLegacyFileKey null means try both
- * @return string
*/
- public function getFileKey(string $path, ?string $uid, ?bool $useLegacyFileKey): string {
+ public function getFileKey(string $path, ?string $uid, ?bool $useLegacyFileKey, bool $useDecryptAll = false): string {
if ($uid === '') {
$uid = null;
}
@@ -385,8 +382,10 @@ class KeyManager {
return '';
}
}
-
- if ($this->util->isMasterKeyEnabled()) {
+ if ($useDecryptAll) {
+ $shareKey = $this->getShareKey($path, $this->session->getDecryptAllUid());
+ $privateKey = $this->session->getDecryptAllKey();
+ } elseif ($this->util->isMasterKeyEnabled()) {
$uid = $this->getMasterKeyId();
$shareKey = $this->getShareKey($path, $uid);
if ($publicAccess) {
diff --git a/apps/encryption/tests/Crypto/EncryptionTest.php b/apps/encryption/tests/Crypto/EncryptionTest.php
index 115b9054278..427421def9c 100644
--- a/apps/encryption/tests/Crypto/EncryptionTest.php
+++ b/apps/encryption/tests/Crypto/EncryptionTest.php
@@ -122,6 +122,10 @@ class EncryptionTest extends TestCase {
* test if public key from one of the recipients is missing
*/
public function testEndUser1() {
+ $this->sessionMock->expects($this->once())
+ ->method('decryptAllModeActivated')
+ ->willReturn(false);
+
$this->instance->begin('/foo/bar', 'user1', 'r', [], ['users' => ['user1', 'user2', 'user3']]);
$this->endTest();
}
@@ -131,6 +135,10 @@ class EncryptionTest extends TestCase {
*
*/
public function testEndUser2() {
+ $this->sessionMock->expects($this->once())
+ ->method('decryptAllModeActivated')
+ ->willReturn(false);
+
$this->expectException(\OCA\Encryption\Exceptions\PublicKeyMissingException::class);
$this->instance->begin('/foo/bar', 'user2', 'r', [], ['users' => ['user1', 'user2', 'user3']]);
@@ -252,35 +260,16 @@ class EncryptionTest extends TestCase {
*/
public function testBeginDecryptAll() {
$path = '/user/files/foo.txt';
- $recoveryKeyId = 'recoveryKeyId';
- $recoveryShareKey = 'recoveryShareKey';
- $decryptAllKey = 'decryptAllKey';
$fileKey = 'fileKey';
$this->sessionMock->expects($this->once())
->method('decryptAllModeActivated')
->willReturn(true);
- $this->sessionMock->expects($this->once())
- ->method('getDecryptAllUid')
- ->willReturn($recoveryKeyId);
- $this->sessionMock->expects($this->once())
- ->method('getDecryptAllKey')
- ->willReturn($decryptAllKey);
-
- $this->keyManagerMock->expects($this->once())
- ->method('getEncryptedFileKey')
- ->willReturn('encryptedFileKey');
$this->keyManagerMock->expects($this->once())
- ->method('getShareKey')
- ->with($path, $recoveryKeyId)
- ->willReturn($recoveryShareKey);
- $this->cryptMock->expects($this->once())
- ->method('multiKeyDecryptLegacy')
- ->with('encryptedFileKey', $recoveryShareKey, $decryptAllKey)
+ ->method('getFileKey')
+ ->with($path, 'user', null, true)
->willReturn($fileKey);
- $this->keyManagerMock->expects($this->never())->method('getFileKey');
-
$this->instance->begin($path, 'user', 'r', [], []);
$this->assertSame($fileKey,
@@ -294,6 +283,10 @@ class EncryptionTest extends TestCase {
* and continue
*/
public function testBeginInitMasterKey() {
+ $this->sessionMock->expects($this->once())
+ ->method('decryptAllModeActivated')
+ ->willReturn(false);
+
$this->sessionMock->expects($this->once())->method('isReady')->willReturn(false);
$this->utilMock->expects($this->once())->method('isMasterKeyEnabled')
->willReturn(true);