diff options
Diffstat (limited to 'apps/encryption/lib/Crypto/Crypt.php')
-rw-r--r-- | apps/encryption/lib/Crypto/Crypt.php | 47 |
1 files changed, 36 insertions, 11 deletions
diff --git a/apps/encryption/lib/Crypto/Crypt.php b/apps/encryption/lib/Crypto/Crypt.php index 93120068c6a..f8ba3d69b80 100644 --- a/apps/encryption/lib/Crypto/Crypt.php +++ b/apps/encryption/lib/Crypto/Crypt.php @@ -77,6 +77,9 @@ class Crypt { public const HEADER_START = 'HBEGIN'; public const HEADER_END = 'HEND'; + // default encoding format, old Nextcloud versions used base64 + public const BINARY_ENCODING_FORMAT = 'binary'; + /** @var ILogger */ private $logger; @@ -96,6 +99,11 @@ class Crypt { private $supportLegacy; /** + * Use the legacy base64 encoding instead of the more space-efficient binary encoding. + */ + private bool $useLegacyBase64Encoding; + + /** * @param ILogger $logger * @param IUserSession $userSession * @param IConfig $config @@ -107,6 +115,7 @@ class Crypt { $this->config = $config; $this->l = $l; $this->supportLegacy = $this->config->getSystemValueBool('encryption.legacy_format_support', false); + $this->useLegacyBase64Encoding = $this->config->getSystemValueBool('encryption.use_legacy_base64_encoding', false); } /** @@ -215,12 +224,15 @@ class Crypt { throw new \InvalidArgumentException('key format "' . $keyFormat . '" is not supported'); } - $cipher = $this->getCipher(); - $header = self::HEADER_START - . ':cipher:' . $cipher - . ':keyFormat:' . $keyFormat - . ':' . self::HEADER_END; + . ':cipher:' . $this->getCipher() + . ':keyFormat:' . $keyFormat; + + if ($this->useLegacyBase64Encoding !== true) { + $header .= ':encoding:' . self::BINARY_ENCODING_FORMAT; + } + + $header .= ':' . self::HEADER_END; return $header; } @@ -234,10 +246,11 @@ class Crypt { * @throws EncryptionFailedException */ private function encrypt($plainContent, $iv, $passPhrase = '', $cipher = self::DEFAULT_CIPHER) { + $options = $this->useLegacyBase64Encoding ? 0 : OPENSSL_RAW_DATA; $encryptedContent = openssl_encrypt($plainContent, $cipher, $passPhrase, - 0, + $options, $iv); if (!$encryptedContent) { @@ -424,6 +437,8 @@ class Crypt { $password = $this->generatePasswordHash($password, $cipher, $uid); } + $binaryEncoding = isset($header['encoding']) && $header['encoding'] === self::BINARY_ENCODING_FORMAT; + // If we found a header we need to remove it from the key we want to decrypt if (!empty($header)) { $privateKey = substr($privateKey, @@ -435,7 +450,9 @@ class Crypt { $privateKey, $password, $cipher, - 0 + 0, + 0, + $binaryEncoding ); if ($this->isValidPrivateKey($plainKey) === false) { @@ -470,10 +487,11 @@ class Crypt { * @param string $cipher * @param int $version * @param int|string $position + * @param boolean $binaryEncoding * @return string * @throws DecryptionFailedException */ - public function symmetricDecryptFileContent($keyFileContents, $passPhrase, $cipher = self::DEFAULT_CIPHER, $version = 0, $position = 0) { + public function symmetricDecryptFileContent($keyFileContents, $passPhrase, $cipher = self::DEFAULT_CIPHER, $version = 0, $position = 0, bool $binaryEncoding = false) { if ($keyFileContents == '') { return ''; } @@ -493,7 +511,8 @@ class Crypt { return $this->decrypt($catFile['encrypted'], $catFile['iv'], $passPhrase, - $cipher); + $cipher, + $binaryEncoding); } /** @@ -610,14 +629,16 @@ class Crypt { * @param string $iv * @param string $passPhrase * @param string $cipher + * @param boolean $binaryEncoding * @return string * @throws DecryptionFailedException */ - private function decrypt($encryptedContent, $iv, $passPhrase = '', $cipher = self::DEFAULT_CIPHER) { + private function decrypt(string $encryptedContent, string $iv, string $passPhrase = '', string $cipher = self::DEFAULT_CIPHER, bool $binaryEncoding = false): string { + $options = $binaryEncoding === true ? OPENSSL_RAW_DATA : 0; $plainContent = openssl_decrypt($encryptedContent, $cipher, $passPhrase, - 0, + $options, $iv); if ($plainContent) { @@ -728,4 +749,8 @@ class Crypt { throw new MultiKeyEncryptException('multikeyencryption failed ' . openssl_error_string()); } } + + public function useLegacyBase64Encoding(): bool { + return $this->useLegacyBase64Encoding; + } } |