Skip to content

Commit 00ece13

Browse files
Merge pull request #49535 from nextcloud/backport/49523/stable28
[stable28] fix(migration): Decrypt ownCloud secrets v2
2 parents 4875f32 + a925e0b commit 00ece13

File tree

2 files changed

+42
-3
lines changed

2 files changed

+42
-3
lines changed

lib/private/Security/Crypto.php

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,25 @@ private function decryptWithoutSecret(string $authenticatedCiphertext, string $p
135135
throw new Exception('Authenticated ciphertext could not be decoded.');
136136
}
137137

138+
/*
139+
* Rearrange arguments for legacy ownCloud migrations
140+
*
141+
* The original scheme consistent of three parts. Nextcloud added a
142+
* fourth at the end as "2" or later "3", ownCloud added "v2" at the
143+
* beginning.
144+
*/
145+
$originalParts = $parts;
146+
$isOwnCloudV2Migration = $partCount === 4 && $originalParts[0] === 'v2';
147+
if ($isOwnCloudV2Migration) {
148+
$parts = [
149+
$parts[1],
150+
$parts[2],
151+
$parts[3],
152+
'2'
153+
];
154+
}
155+
156+
// Convert hex-encoded values to binary
138157
$ciphertext = $this->hex2bin($parts[0]);
139158
$iv = $parts[1];
140159
$hmac = $this->hex2bin($parts[2]);
@@ -145,7 +164,7 @@ private function decryptWithoutSecret(string $authenticatedCiphertext, string $p
145164
$iv = $this->hex2bin($iv);
146165
}
147166

148-
if ($version === '3') {
167+
if ($version === '3' || $isOwnCloudV2Migration) {
149168
$keyMaterial = hash_hkdf('sha512', $password);
150169
$encryptionKey = substr($keyMaterial, 0, 32);
151170
$hmacKey = substr($keyMaterial, 32);
@@ -154,8 +173,15 @@ private function decryptWithoutSecret(string $authenticatedCiphertext, string $p
154173
$this->cipher->setPassword($encryptionKey);
155174
$this->cipher->setIV($iv);
156175

157-
if (!hash_equals($this->calculateHMAC($parts[0] . $parts[1], $hmacKey), $hmac)) {
158-
throw new Exception('HMAC does not match.');
176+
if ($isOwnCloudV2Migration) {
177+
// ownCloud uses the binary IV for HMAC calculation
178+
if (!hash_equals($this->calculateHMAC($parts[0] . $iv, $hmacKey), $hmac)) {
179+
throw new Exception('HMAC does not match.');
180+
}
181+
} else {
182+
if (!hash_equals($this->calculateHMAC($parts[0] . $parts[1], $hmacKey), $hmac)) {
183+
throw new Exception('HMAC does not match.');
184+
}
159185
}
160186

161187
$result = $this->cipher->decrypt($ciphertext);

tests/lib/Security/CryptoTest.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,19 @@ public function testVersion2CiphertextDecryptsToCorrectPlaintext() {
8989
);
9090
}
9191

92+
/**
93+
* Test data taken from https://github.com/owncloud/core/blob/9deb8196b20354c8de0cd720ad4d18d52ccc96d8/tests/lib/Security/CryptoTest.php#L56-L60
94+
*/
95+
public function testOcVersion2CiphertextDecryptsToCorrectPlaintext() {
96+
$this->assertSame(
97+
'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt.',
98+
$this->crypto->decrypt(
99+
'v2|d57dbe4d1317cdf19d4ddc2df807f6b5d63ab1e119c46590ce54bae56a9cd3969168c4ec1600ac9758dd7e7afb9c4c962dd23072c1463add1d9c77c467723b37bb768ef00e3c50898e59247cbb59ce56b74ce5990648ffe9e40d0e95076c27a785bdcf32c219ea4ad5c316b1f12f48c1|6bd21db258a5e406a2c288a444de195f|a19111a4cf1a11ee95fc1734699c20964eaa05bb007e1cecc4cc6872f827a4b7deedc977c13b138d728d68116aa3d82f9673e20c7e447a9788aa3be994b67cd6',
100+
'ThisIsAVeryS3cur3P4ssw0rd'
101+
)
102+
);
103+
}
104+
92105
public function testVersion3CiphertextDecryptsToCorrectPlaintext() {
93106
$this->assertSame(
94107
'Another plaintext value that will be encrypted with version 3. It addresses the related key issue. Old ciphertexts should be decrypted properly, but only use the better version for encryption.',

0 commit comments

Comments
 (0)