Skip to content

Commit 33e30d9

Browse files
ChristophWurstbackportbot[bot]
authored andcommitted
fix(migration): Decrypt ownCloud secrets v2
Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at> [skip ci]
1 parent 4875f32 commit 33e30d9

File tree

1 file changed

+29
-3
lines changed

1 file changed

+29
-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);

0 commit comments

Comments
 (0)