From 74384ce875b584b95e1bd65c75e45e036504c874 Mon Sep 17 00:00:00 2001 From: Paul Holden Date: Thu, 16 May 2024 20:54:35 +0100 Subject: [PATCH] MDL-81940 core: deprecate RC4 encryption library methods. Switch current usage to secure `\core\encryption` alternative. --- .upgradenotes/MDL-81940-2024053010202574.yml | 14 +++ lib/deprecatedlib.php | 89 ++++++++++++++++++++ lib/moodlelib.php | 81 ------------------ lib/sessionlib.php | 18 ++-- 4 files changed, 112 insertions(+), 90 deletions(-) create mode 100644 .upgradenotes/MDL-81940-2024053010202574.yml diff --git a/.upgradenotes/MDL-81940-2024053010202574.yml b/.upgradenotes/MDL-81940-2024053010202574.yml new file mode 100644 index 00000000000..dee32891107 --- /dev/null +++ b/.upgradenotes/MDL-81940-2024053010202574.yml @@ -0,0 +1,14 @@ +issueNumber: MDL-81940 +notes: + core: + - message: >- + The following methods have been deprecated, existing usage should switch + to secure `\core\encryption` library: + + + - `rc4encrypt` + + - `rc4decrypt` + + - `endecrypt` + type: deprecated diff --git a/lib/deprecatedlib.php b/lib/deprecatedlib.php index 8448f265117..77f7dacceb4 100644 --- a/lib/deprecatedlib.php +++ b/lib/deprecatedlib.php @@ -3118,6 +3118,95 @@ function random_bytes_emulate($length) { return random_bytes($length); } +/** + * rc4encrypt + * + * @param string $data Data to encrypt. + * @return string The now encrypted data. + * + * @deprecated since Moodle 4.5 - please do not use this function any more, {@see \core\encryption::encrypt} + */ +#[\core\attribute\deprecated('\core\encryption::encrypt', since: '4.5', mdl: 'MDL-81940')] +function rc4encrypt($data) { + // No initial deprecation notice here, as the following method triggers its own. + return endecrypt(get_site_identifier(), $data, ''); +} + +/** + * rc4decrypt + * + * @param string $data Data to decrypt. + * @return string The now decrypted data. + * + * @deprecated since Moodle 4.5 - please do not use this function any more, {@see \core\encryption::decrypt} + */ +#[\core\attribute\deprecated('\core\encryption::decrypt', since: '4.5', mdl: 'MDL-81940')] +function rc4decrypt($data) { + // No initial deprecation notice here, as the following method triggers its own. + return endecrypt(get_site_identifier(), $data, 'de'); +} + +/** + * Based on a class by Mukul Sabharwal [mukulsabharwal @ yahoo.com] + * + * @param string $pwd The password to use when encrypting or decrypting + * @param string $data The data to be decrypted/encrypted + * @param string $case Either 'de' for decrypt or '' for encrypt + * @return string + * + * @deprecated since Moodle 4.5 - please do not use this function any more, {@see \core\encryption} + */ +#[\core\attribute\deprecated(\core\encryption::class, since: '4.5', mdl: 'MDL-81940')] +function endecrypt($pwd, $data, $case) { + \core\deprecation::emit_deprecation_if_present(__FUNCTION__); + + if ($case == 'de') { + $data = urldecode($data); + } + + $key[] = ''; + $box[] = ''; + $pwdlength = strlen($pwd); + + for ($i = 0; $i <= 255; $i++) { + $key[$i] = ord(substr($pwd, ($i % $pwdlength), 1)); + $box[$i] = $i; + } + + $x = 0; + + for ($i = 0; $i <= 255; $i++) { + $x = ($x + $box[$i] + $key[$i]) % 256; + $tempswap = $box[$i]; + $box[$i] = $box[$x]; + $box[$x] = $tempswap; + } + + $cipher = ''; + + $a = 0; + $j = 0; + + for ($i = 0; $i < strlen($data); $i++) { + $a = ($a + 1) % 256; + $j = ($j + $box[$a]) % 256; + $temp = $box[$a]; + $box[$a] = $box[$j]; + $box[$j] = $temp; + $k = $box[(($box[$a] + $box[$j]) % 256)]; + $cipherby = ord(substr($data, $i, 1)) ^ $k; + $cipher .= chr($cipherby); + } + + if ($case == 'de') { + $cipher = urldecode(urlencode($cipher)); + } else { + $cipher = urlencode($cipher); + } + + return $cipher; +} + /** * @deprecated since Moodle 4.0 */ diff --git a/lib/moodlelib.php b/lib/moodlelib.php index ae17190f682..8d48fa6dc26 100644 --- a/lib/moodlelib.php +++ b/lib/moodlelib.php @@ -7294,87 +7294,6 @@ class emoticon_manager { } } -// ENCRYPTION. - -/** - * rc4encrypt - * - * @param string $data Data to encrypt. - * @return string The now encrypted data. - */ -function rc4encrypt($data) { - return endecrypt(get_site_identifier(), $data, ''); -} - -/** - * rc4decrypt - * - * @param string $data Data to decrypt. - * @return string The now decrypted data. - */ -function rc4decrypt($data) { - return endecrypt(get_site_identifier(), $data, 'de'); -} - -/** - * Based on a class by Mukul Sabharwal [mukulsabharwal @ yahoo.com] - * - * @todo Finish documenting this function - * - * @param string $pwd The password to use when encrypting or decrypting - * @param string $data The data to be decrypted/encrypted - * @param string $case Either 'de' for decrypt or '' for encrypt - * @return string - */ -function endecrypt ($pwd, $data, $case) { - - if ($case == 'de') { - $data = urldecode($data); - } - - $key[] = ''; - $box[] = ''; - $pwdlength = strlen($pwd); - - for ($i = 0; $i <= 255; $i++) { - $key[$i] = ord(substr($pwd, ($i % $pwdlength), 1)); - $box[$i] = $i; - } - - $x = 0; - - for ($i = 0; $i <= 255; $i++) { - $x = ($x + $box[$i] + $key[$i]) % 256; - $tempswap = $box[$i]; - $box[$i] = $box[$x]; - $box[$x] = $tempswap; - } - - $cipher = ''; - - $a = 0; - $j = 0; - - for ($i = 0; $i < strlen($data); $i++) { - $a = ($a + 1) % 256; - $j = ($j + $box[$a]) % 256; - $temp = $box[$a]; - $box[$a] = $box[$j]; - $box[$j] = $temp; - $k = $box[(($box[$a] + $box[$j]) % 256)]; - $cipherby = ord(substr($data, $i, 1)) ^ $k; - $cipher .= chr($cipherby); - } - - if ($case == 'de') { - $cipher = urldecode(urlencode($cipher)); - } else { - $cipher = urlencode($cipher); - } - - return $cipher; -} - // ENVIRONMENT CHECKING. /** diff --git a/lib/sessionlib.php b/lib/sessionlib.php index e01a9352d36..f7e63704417 100644 --- a/lib/sessionlib.php +++ b/lib/sessionlib.php @@ -103,10 +103,9 @@ function is_moodle_cookie_secure() { } /** - * Sets a moodle cookie with a weakly encrypted username + * Sets a Moodle cookie with an encrypted username * * @param string $username to encrypt and place in a cookie, '' means delete current cookie - * @return void */ function set_moodle_cookie($username) { global $CFG; @@ -134,12 +133,13 @@ function set_moodle_cookie($username) { if ($username !== '') { // Set username cookie for 60 days. - setcookie($cookiename, rc4encrypt($username), time() + (DAYSECS * 60), $CFG->sessioncookiepath, $CFG->sessioncookiedomain, $cookiesecure, $CFG->cookiehttponly); + setcookie($cookiename, \core\encryption::encrypt($username), time() + (DAYSECS * 60), $CFG->sessioncookiepath, + $CFG->sessioncookiedomain, $cookiesecure, $CFG->cookiehttponly); } } /** - * Gets a moodle cookie with a weakly encrypted username + * Gets a Moodle cookie with an encrypted username * * @return string username */ @@ -156,14 +156,14 @@ function get_moodle_cookie() { $cookiename = 'MOODLEID1_'.$CFG->sessioncookie; - if (empty($_COOKIE[$cookiename])) { - return ''; - } else { - $username = rc4decrypt($_COOKIE[$cookiename]); - if ($username === 'guest' or $username === 'nobody') { + try { + $username = \core\encryption::decrypt($_COOKIE[$cookiename] ?? ''); + if ($username === 'guest' || $username === 'nobody') { // backwards compatibility - we do not set these cookies any more $username = ''; } return $username; + } catch (\moodle_exception $ex) { + return ''; } }