MDL-71421 core: deprecate openssl fallbacks in encryption library.

Since c66dc591 the PHP Sodium library is required, negating the need
for the OpenSSL equivalent. Remove fallbacks where possible, leaving
only the ability to decrypt legacy OpenSSL-encrypted content (with
debugging).
This commit is contained in:
Paul Holden
2023-08-01 12:10:36 +01:00
parent a1d5d1b2f7
commit c1c000aa15
4 changed files with 79 additions and 80 deletions
+29 -37
View File
@@ -14,14 +14,6 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Class used to encrypt or decrypt data.
*
* @package core
* @copyright 2020 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core;
/**
@@ -30,47 +22,51 @@ namespace core;
* @package core
* @copyright 2020 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @deprecated since Moodle 3.11 MDL-71420 - the openssl part of the class only.
* @todo MDL-71421 Remove the openssl part in Moodle 4.2.
*/
class encryption {
/** @var string Encryption method: Sodium */
const METHOD_SODIUM = 'sodium';
// TODO: MDL-71421 - Remove the following openssl constants and all uses once sodium becomes a requirement in Moodle 4.2.
/** @var string Encryption method: hand-coded OpenSSL (less safe) */
/**
* @var string Encryption method: hand-coded OpenSSL (less safe)
*
* @deprecated
*/
const METHOD_OPENSSL = 'openssl-aes-256-ctr';
/** @var string OpenSSL cipher method */
/**
* @var string OpenSSL cipher method
*
* @deprecated
*/
const OPENSSL_CIPHER = 'AES-256-CTR';
/**
* Checks if Sodium is installed.
*
* @return bool True if the Sodium extension is available
*
* @deprecated since Moodle 4.3 Sodium is always present
*/
public static function is_sodium_installed(): bool {
debugging(__FUNCTION__ . '() is deprecated, sodium is now always present', DEBUG_DEVELOPER);
return extension_loaded('sodium');
}
/**
* Gets the encryption method to use. We use the Sodium extension if it is installed, or
* otherwise, OpenSSL.
* Gets the encryption method to use
*
* @return string Current encryption method
*/
protected static function get_encryption_method(): string {
if (self::is_sodium_installed()) {
return self::METHOD_SODIUM;
} else {
return self::METHOD_OPENSSL;
}
return self::METHOD_SODIUM;
}
/**
* Creates a key for the server.
*
* Note we currently retain support for all methods, in order to decrypt legacy {@see METHOD_OPENSSL} content
*
* @param string|null $method Encryption method (only if you want to create a non-default key)
* @param bool $chmod If true, restricts the file access of the key
* @throws \moodle_exception If the server already has a key, or there is an error
@@ -178,6 +174,8 @@ class encryption {
/**
* Gets the length in bytes of the initial values data required.
*
* Note we currently retain support for all methods, in order to decrypt legacy {@see METHOD_OPENSSL} content
*
* @param string $method Crypto method
* @return int Length in bytes
*/
@@ -210,6 +208,12 @@ class encryption {
$method = self::get_encryption_method();
}
// We currently retain support for all methods, falling back to Sodium if deprecated OpenSSL is requested.
if ($method === self::METHOD_OPENSSL) {
debugging('Encryption using legacy OpenSSL is deprecated, reverting to Sodium', DEBUG_DEVELOPER);
$method = self::METHOD_SODIUM;
}
// Create IV.
$iv = random_bytes(self::get_iv_length($method));
@@ -223,22 +227,6 @@ class encryption {
}
break;
case self::METHOD_OPENSSL:
// This may not be a secure authenticated encryption implementation;
// administrators should enable the Sodium extension.
$key = self::get_key($method);
if (strlen($key) !== 32) {
throw new \moodle_exception('encryption_invalidkey', 'error');
}
$encrypted = @openssl_encrypt($data, self::OPENSSL_CIPHER, $key, OPENSSL_RAW_DATA, $iv);
if ($encrypted === false) {
throw new \moodle_exception('encryption_encryptfailed', 'error',
'', null, openssl_error_string());
}
$hmac = hash_hmac('sha256', $iv . $encrypted, $key, true);
$encrypted .= $hmac;
break;
default:
throw new \coding_exception('Unknown method: ' . $method);
}
@@ -251,6 +239,8 @@ class encryption {
/**
* Decrypts data using the server's key. The decryption works with either supported method.
*
* Note currently we retain support for all methods, in order to decrypt legacy {@see METHOD_OPENSSL} content
*
* @param string $data Data to decrypt
* @return string Decrypted data
*/
@@ -306,6 +296,8 @@ class encryption {
'', null, 'Integrity check failed');
}
debugging('Decryption using legacy OpenSSL is deprecated, please upgrade to Sodium', DEBUG_DEVELOPER);
$decrypted = @openssl_decrypt($encrypted, self::OPENSSL_CIPHER, $key, OPENSSL_RAW_DATA, $iv);
if ($decrypted === false) {
throw new \moodle_exception('encryption_decryptfailed', 'error',