summaryrefslogtreecommitdiffstats
path: root/apps/encryption/lib/Crypto/Crypt.php
diff options
context:
space:
mode:
Diffstat (limited to 'apps/encryption/lib/Crypto/Crypt.php')
-rw-r--r--apps/encryption/lib/Crypto/Crypt.php47
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;
+ }
}