From 4ce5669419c344de561f627592349773765b064c Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Wed, 8 Apr 2015 14:19:11 +0200 Subject: [PATCH] read cipher from key header and always write a key header if a new private key is stored --- apps/encryption/lib/crypto/crypt.php | 31 +++++++++++++++++++++------- apps/encryption/lib/keymanager.php | 6 ++++-- apps/encryption/lib/recovery.php | 1 + 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/apps/encryption/lib/crypto/crypt.php b/apps/encryption/lib/crypto/crypt.php index 6e1008d29a..f2ae8e6db2 100644 --- a/apps/encryption/lib/crypto/crypt.php +++ b/apps/encryption/lib/crypto/crypt.php @@ -37,6 +37,8 @@ use OCP\IUserSession; class Crypt { const DEFAULT_CIPHER = 'AES-256-CFB'; + // default cipher from old ownCloud versions + const LEGACY_CIPHER = 'AES-128-CFB'; const HEADER_START = 'HBEGIN'; const HEADER_END = 'HEND'; @@ -148,6 +150,16 @@ class Crypt { return $padded; } + /** + * generate header for encrypted file + */ + public function generateHeader() { + $cipher = $this->getCipher(); + $header = self::HEADER_START . ':cipher:' . $cipher . ':' . self::HEADER_END; + + return $header; + } + /** * @param string $plainContent * @param string $iv @@ -205,23 +217,28 @@ class Crypt { } /** - * @param string $recoveryKey + * @param string $privateKey * @param string $password * @return bool|string */ - public function decryptPrivateKey($recoveryKey, $password) { + public function decryptPrivateKey($privateKey, $password) { - $header = $this->parseHeader($recoveryKey); - $cipher = $this->getCipher(); + $header = $this->parseHeader($privateKey); + + if (isset($header['cipher'])) { + $cipher = $header['cipher']; + } else { + $cipher = self::LEGACY_CIPHER; + } // If we found a header we need to remove it from the key we want to decrypt if (!empty($header)) { - $recoveryKey = substr($recoveryKey, - strpos($recoveryKey, + $privateKey = substr($privateKey, + strpos($privateKey, self::HEADER_END) + strlen(self::HEADER_START)); } - $plainKey = $this->symmetricDecryptFileContent($recoveryKey, + $plainKey = $this->symmetricDecryptFileContent($privateKey, $password, $cipher); diff --git a/apps/encryption/lib/keymanager.php b/apps/encryption/lib/keymanager.php index 81bc082042..a280ea9bde 100644 --- a/apps/encryption/lib/keymanager.php +++ b/apps/encryption/lib/keymanager.php @@ -200,9 +200,10 @@ class KeyManager { $encryptedKey = $this->crypt->symmetricEncryptFileContent($keyPair['privateKey'], $password); + $header = $this->crypt->generateHeader(); if ($encryptedKey) { - $this->setPrivateKey($uid, $encryptedKey); + $this->setPrivateKey($uid, $header . $encryptedKey); return true; } return false; @@ -219,9 +220,10 @@ class KeyManager { $encryptedKey = $this->crypt->symmetricEncryptFileContent($keyPair['privateKey'], $password); + $header = $this->crypt->generateHeader(); if ($encryptedKey) { - $this->setSystemPrivateKey($this->getRecoveryKeyId(), $encryptedKey); + $this->setSystemPrivateKey($this->getRecoveryKeyId(), $header . $encryptedKey); return true; } return false; diff --git a/apps/encryption/lib/recovery.php b/apps/encryption/lib/recovery.php index 5c2ca67a2b..5c1e91866a 100644 --- a/apps/encryption/lib/recovery.php +++ b/apps/encryption/lib/recovery.php @@ -129,6 +129,7 @@ class Recovery { * * @param string $newPassword * @param string $oldPassword + * @return bool */ public function changeRecoveryKeyPassword($newPassword, $oldPassword) { $recoveryKey = $this->keyManager->getSystemPrivateKey($this->keyManager->getRecoveryKeyId());