Use constant time encoding / decoding of security critical code (#3699)
authorJoshua Rüsweg <ruesweg@woltlab.com>
Fri, 6 Nov 2020 16:00:10 +0000 (17:00 +0100)
committerGitHub <noreply@github.com>
Fri, 6 Nov 2020 16:00:10 +0000 (17:00 +0100)
* Use `Hex::decode` to convert hex2bin
Previously we used the internal PHP function `hex2bin` which has the problem with cache-timing leaks. The Hex class converts the given string without cache-timing leaks.

* Use `Hex::encode` to convert bin2hex
Previously we used the internal PHP function `bin2hex` which has the problem with cache-timing leaks. The Hex class converts the given string without cache-timing leaks.

37 files changed:
wcfsetup/install/files/lib/action/FacebookAuthAction.class.php
wcfsetup/install/files/lib/action/GithubAuthAction.class.php
wcfsetup/install/files/lib/action/GoogleAuthAction.class.php
wcfsetup/install/files/lib/action/TwitterAuthAction.class.php
wcfsetup/install/files/lib/data/style/StyleAction.class.php
wcfsetup/install/files/lib/data/user/UserAction.class.php
wcfsetup/install/files/lib/data/user/UserEditor.class.php
wcfsetup/install/files/lib/form/LostPasswordForm.class.php
wcfsetup/install/files/lib/form/RegisterForm.class.php
wcfsetup/install/files/lib/system/cronjob/DailyMailNotificationCronjob.class.php
wcfsetup/install/files/lib/system/email/Email.class.php
wcfsetup/install/files/lib/system/email/mime/AbstractMultipartMimePart.class.php
wcfsetup/install/files/lib/system/package/PackageInstallationDispatcher.class.php
wcfsetup/install/files/lib/system/session/SessionHandler.class.php
wcfsetup/install/files/lib/system/user/authentication/password/algorithm/CryptMD5.class.php
wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Ipb2.class.php
wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Ipb3.class.php
wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Joomla1.class.php
wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Joomla2.class.php
wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Joomla3.class.php
wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Mybb1.class.php
wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Phpfox3.class.php
wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Smf1.class.php
wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Smf2.class.php
wcfsetup/install/files/lib/system/user/authentication/password/algorithm/TPhpass.class.php
wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Vb3.class.php
wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Vb4.class.php
wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Vb5.class.php
wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Wcf1.class.php
wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Wcf1e.class.php
wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Xf1.class.php
wcfsetup/install/files/lib/system/user/notification/TestableUserNotificationEventHandler.class.php
wcfsetup/install/files/lib/system/user/notification/UserNotificationHandler.class.php
wcfsetup/install/files/lib/system/worker/SendNewPasswordWorker.class.php
wcfsetup/install/files/lib/util/FileUtil.class.php
wcfsetup/install/files/lib/util/HTTPRequest.class.php
wcfsetup/install/files/lib/util/StringUtil.class.php

index f2133ef5620775364a556559ea78d313a5904f17..38b6da7cdeb2c0ef2a3510239dc4782a95eafc50 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\action;
+use ParagonIE\ConstantTime\Hex;
 use wcf\data\user\User;
 use wcf\data\user\UserEditor;
 use wcf\system\exception\IllegalLinkException;
@@ -145,7 +146,7 @@ class FacebookAuthAction extends AbstractAction {
                }
                
                // start auth by redirecting to facebook
-               $token = bin2hex(\random_bytes(20));
+               $token = Hex::encode(\random_bytes(20));
                WCF::getSession()->register('__facebookInit', $token);
                HeaderUtil::redirect("https://www.facebook.com/dialog/oauth?client_id=".StringUtil::trim(FACEBOOK_PUBLIC_KEY). "&redirect_uri=".rawurlencode($callbackURL)."&state=".$token."&scope=email");
                $this->executed();
index a7d850b5518502578c281cdf50c664c8cbf6b9c9..873f3b839a4252d494f0b2091105e56afea767ba 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\action;
+use ParagonIE\ConstantTime\Hex;
 use wcf\data\user\User;
 use wcf\data\user\UserEditor;
 use wcf\system\exception\IllegalLinkException;
@@ -160,7 +161,7 @@ class GithubAuthAction extends AbstractAction {
                }
                
                // start auth by redirecting to github
-               $token = bin2hex(\random_bytes(20));
+               $token = Hex::encode(\random_bytes(20));
                WCF::getSession()->register('__githubInit', $token);
                HeaderUtil::redirect("https://github.com/login/oauth/authorize?client_id=".rawurlencode(StringUtil::trim(GITHUB_PUBLIC_KEY))."&scope=".rawurlencode('user:email')."&state=".$token);
                $this->executed();
index 396dfa70bb3457a3543f3f5cfb21284b8edddb16..57159330f83a042fcf75370851b7006e28dc996f 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\action;
+use ParagonIE\ConstantTime\Hex;
 use wcf\data\user\User;
 use wcf\data\user\UserEditor;
 use wcf\system\exception\IllegalLinkException;
@@ -148,7 +149,7 @@ class GoogleAuthAction extends AbstractAction {
                }
                
                // start auth by redirecting to google
-               $token = bin2hex(\random_bytes(20));
+               $token = Hex::encode(\random_bytes(20));
                WCF::getSession()->register('__googleInit', $token);
                HeaderUtil::redirect("https://accounts.google.com/o/oauth2/auth?client_id=".rawurlencode(StringUtil::trim(GOOGLE_PUBLIC_KEY)). "&redirect_uri=".rawurlencode($callbackURL)."&state=".$token."&scope=profile+openid+email&response_type=code");
                $this->executed();
index e0d0e3e68af8fc852831a2b1c0e1b94d7aaa7b7e..59c84735a6cec50b8b376564d94c01364ba3a8e7 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\action;
+use ParagonIE\ConstantTime\Hex;
 use wcf\data\user\User;
 use wcf\data\user\UserEditor;
 use wcf\system\exception\IllegalLinkException;
@@ -57,7 +58,7 @@ class TwitterAuthAction extends AbstractAction {
                                // fetch access_token
                                $oauthHeader = [
                                        'oauth_consumer_key' => StringUtil::trim(TWITTER_PUBLIC_KEY),
-                                       'oauth_nonce' => bin2hex(\random_bytes(20)),
+                                       'oauth_nonce' => Hex::encode(\random_bytes(20)),
                                        'oauth_signature_method' => 'HMAC-SHA1',
                                        'oauth_timestamp' => TIME_NOW,
                                        'oauth_version' => '1.0',
@@ -114,7 +115,7 @@ class TwitterAuthAction extends AbstractAction {
                                        try {
                                                $oauthHeader = [
                                                        'oauth_consumer_key' => StringUtil::trim(TWITTER_PUBLIC_KEY),
-                                                       'oauth_nonce' => bin2hex(\random_bytes(20)),
+                                                       'oauth_nonce' => Hex::encode(\random_bytes(20)),
                                                        'oauth_signature_method' => 'HMAC-SHA1',
                                                        'oauth_timestamp' => TIME_NOW,
                                                        'oauth_version' => '1.0',
@@ -167,7 +168,7 @@ class TwitterAuthAction extends AbstractAction {
                        $oauthHeader = [
                                'oauth_callback' => $callbackURL,
                                'oauth_consumer_key' => StringUtil::trim(TWITTER_PUBLIC_KEY),
-                               'oauth_nonce' => bin2hex(\random_bytes(20)),
+                               'oauth_nonce' => Hex::encode(\random_bytes(20)),
                                'oauth_signature_method' => 'HMAC-SHA1',
                                'oauth_timestamp' => TIME_NOW,
                                'oauth_version' => '1.0'
index 4bf7800b3a16774518080c3ee3d49b02d0333e58..bbf2b5b9750c25a1c3673aabc3ebd95dad7b6ea8 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\data\style;
+use ParagonIE\ConstantTime\Hex;
 use wcf\data\TDatabaseObjectToggle;
 use wcf\data\user\UserAction;
 use wcf\data\AbstractDatabaseObjectAction;
@@ -193,7 +194,7 @@ class StyleAction extends AbstractDatabaseObjectAction implements IToggleAction
                                if ($file !== null) {
                                        $fileLocation = $file->getLocation();
                                        $extension = pathinfo($file->getFilename(), PATHINFO_EXTENSION);
-                                       $newName = $type.'-'.\bin2hex(\random_bytes(4)).'.'.$extension;
+                                       $newName = $type.'-'.Hex::encode(\random_bytes(4)).'.'.$extension;
                                        $newLocation = $style->getAssetPath().$newName;
                                        rename($fileLocation, $newLocation);
                                        $this->parameters['variables'][$type] = $newName;
index 772e2b3e9af22d9fdece1467937fc195533e2b96..c13eb933cbd07b9889f49a81f13b311216efffcc 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\data\user;
+use ParagonIE\ConstantTime\Hex;
 use wcf\data\object\type\ObjectTypeCache;
 use wcf\data\user\avatar\UserAvatarAction;
 use wcf\data\user\group\UserGroup;
@@ -672,7 +673,7 @@ class UserAction extends AbstractDatabaseObjectAction implements IClipboardActio
                foreach ($this->objects as $object) {
                        (new UserAction([$object], 'update', [
                                'data' => [
-                                       'emailConfirmed' => bin2hex(\random_bytes(20))
+                                       'emailConfirmed' => Hex::encode(\random_bytes(20))
                                ]
                        ]))->executeAction();
                }
@@ -743,7 +744,7 @@ class UserAction extends AbstractDatabaseObjectAction implements IClipboardActio
                $action = new UserAction($this->objects, 'update', [
                        'data' => [
                                'activationCode' => UserRegistrationUtil::getActivationCode(),
-                               'emailConfirmed' => bin2hex(\random_bytes(20)),
+                               'emailConfirmed' => Hex::encode(\random_bytes(20)),
                        ],
                        'removeGroups' => UserGroup::getGroupIDsByType([UserGroup::USERS])
                ]);
@@ -1113,7 +1114,7 @@ class UserAction extends AbstractDatabaseObjectAction implements IClipboardActio
                foreach ($this->objects as $object) {
                        $action = new UserAction([$object], 'update', [
                                'data' => [
-                                       'emailConfirmed' => bin2hex(\random_bytes(20))
+                                       'emailConfirmed' => Hex::encode(\random_bytes(20))
                                ]
                        ]);
                        $action->executeAction();
index f9d7642be49db5692fc49699abd1bfc3556a2f65..8000688446a34c1310cf90e1fb0958f8e8479291 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\data\user;
+use ParagonIE\ConstantTime\Hex;
 use wcf\data\user\group\UserGroup;
 use wcf\data\DatabaseObjectEditor;
 use wcf\data\IEditableCachedObject;
@@ -63,7 +64,7 @@ class UserEditor extends DatabaseObjectEditor implements IEditableCachedObject {
                }
                
                // create accessToken for AbstractAuthedPage
-               $parameters['accessToken'] = bin2hex(\random_bytes(20));
+               $parameters['accessToken'] = Hex::encode(\random_bytes(20));
                
                // handle registration date
                if (!isset($parameters['registrationDate'])) $parameters['registrationDate'] = TIME_NOW;
@@ -93,7 +94,7 @@ class UserEditor extends DatabaseObjectEditor implements IEditableCachedObject {
        public function update(array $parameters = []) {
                if (array_key_exists('password', $parameters) && $parameters['password'] !== '') {
                        $parameters['password'] = self::getPasswordHash($parameters['password']);
-                       $parameters['accessToken'] = bin2hex(\random_bytes(20));
+                       $parameters['accessToken'] = Hex::encode(\random_bytes(20));
                        
                        // update accessToken
                        $this->accessToken = $parameters['accessToken'];
index 56120d5a0025fb5217d135e63b71d8ee9ffe9b2a..6364a8454dca8d58bdaac83d43ce0487f5f044f4 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\form;
+use ParagonIE\ConstantTime\Hex;
 use wcf\data\user\User;
 use wcf\data\user\UserAction;
 use wcf\system\email\mime\MimePartFacade;
@@ -101,7 +102,7 @@ class LostPasswordForm extends AbstractCaptchaForm {
                parent::save();
                
                // generate a new lost password key
-               $lostPasswordKey = bin2hex(\random_bytes(20));
+               $lostPasswordKey = Hex::encode(\random_bytes(20));
                
                // save key and request time in database
                $this->objectAction = new UserAction([$this->user], 'update', [
index 1c02be1c0b6907df98751903ef6f3b2cb9735a43..11d0454b074dd0b35a03f7e798a3b62a3bdf7ec9 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\form;
+use ParagonIE\ConstantTime\Hex;
 use wcf\acp\form\UserAddForm;
 use wcf\data\blacklist\entry\BlacklistEntry;
 use wcf\data\object\type\ObjectType;
@@ -392,7 +393,7 @@ class RegisterForm extends UserAddForm {
                                                if (isset($facebookData['gender']) && User::getUserOptionID('gender') !== null) $saveOptions[User::getUserOptionID('gender')] = ($facebookData['gender'] == 'male' ? UserProfile::GENDER_MALE : UserProfile::GENDER_FEMALE);
                                                
                                                if (isset($facebookData['birthday']) && User::getUserOptionID('birthday') !== null) {
-                                                       list($month, $day, $year) = explode('/', $facebookData['birthday']);
+                                                       [$month, $day, $year] = explode('/', $facebookData['birthday']);
                                                        $saveOptions[User::getUserOptionID('birthday')] = $year.'-'.$month.'-'.$day;
                                                }
                                                if (isset($facebookData['location']) && User::getUserOptionID('location') !== null) $saveOptions[User::getUserOptionID('location')] = $facebookData['location']['name'];
@@ -435,7 +436,7 @@ class RegisterForm extends UserAddForm {
                        }
                        
                        // create fake password
-                       $this->password = bin2hex(\random_bytes(20));
+                       $this->password = Hex::encode(\random_bytes(20));
                }
 
                $eventParameters = [
@@ -453,7 +454,7 @@ class RegisterForm extends UserAddForm {
                $addDefaultGroups = true;
                if (!empty($this->blacklistMatches) || (REGISTER_ACTIVATION_METHOD & User::REGISTER_ACTIVATION_USER && !$registerVia3rdParty) || (REGISTER_ACTIVATION_METHOD & User::REGISTER_ACTIVATION_ADMIN)) {
                        $activationCode = UserRegistrationUtil::getActivationCode();
-                       $emailConfirmCode = bin2hex(\random_bytes(20));
+                       $emailConfirmCode = Hex::encode(\random_bytes(20));
                        $this->additionalFields['activationCode'] = $activationCode;
                        $this->additionalFields['emailConfirmed'] = $emailConfirmCode;
                        $addDefaultGroups = false;
index 89040ef1cc539401609bc149c54cd9252ee9d8aa..ec6be23f0de92661e1fbcccc2ccc06aaf61d6631 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\system\cronjob;
+use ParagonIE\ConstantTime\Hex;
 use wcf\data\cronjob\Cronjob;
 use wcf\data\user\notification\event\UserNotificationEventList;
 use wcf\data\user\notification\UserNotification;
@@ -203,7 +204,7 @@ class DailyMailNotificationCronjob extends AbstractCronjob {
                        
                        // generate token if not present
                        if (!$user->notificationMailToken) {
-                               $token = bin2hex(\random_bytes(10));
+                               $token = Hex::encode(\random_bytes(10));
                                $editor = new UserEditor($user);
                                $editor->update(['notificationMailToken' => $token]);
                                
index 18919c5be3926a409a02d6d448596a7a037fe943..15af59d45a16da48b0fd57fa8b90f4c2adecd86d 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\system\email;
+use ParagonIE\ConstantTime\Hex;
 use wcf\system\application\ApplicationHandler;
 use wcf\system\background\job\AbstractBackgroundJob;
 use wcf\system\background\job\EmailDeliveryBackgroundJob;
@@ -199,7 +200,7 @@ class Email {
         */
        public function getMessageID() {
                if ($this->messageID === null) {
-                       $this->messageID = bin2hex(\random_bytes(20));
+                       $this->messageID = Hex::encode(\random_bytes(20));
                }
                
                return '<'.$this->messageID.'@'.self::getHost().'>';
@@ -533,7 +534,7 @@ class Email {
         */
        public function getHeaderString() {
                return implode("\r\n", array_map(function ($item) {
-                       list($name, $value) = $item;
+                       [$name, $value] = $item;
                        
                        switch ($name) {
                                case 'message-id':
index 0653c785766421c8ed6bd01e15c96d5473837034..fcb373c54a1de3da93e5667e4da8d8877d72ec16 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\system\email\mime;
+use ParagonIE\ConstantTime\Hex;
 use wcf\system\email\Mailbox;
 use wcf\util\StringUtil;
 
@@ -29,7 +30,7 @@ abstract class AbstractMultipartMimePart extends AbstractMimePart implements IRe
         * Sets the multipart boundary.
         */
        public function __construct() {
-               $this->boundary = "WoltLab_Suite=_".bin2hex(\random_bytes(20));
+               $this->boundary = "WoltLab_Suite=_".Hex::encode(\random_bytes(20));
                $this->parts = new \SplObjectStorage();
        }
        
index ba709ea7ff991f8275b9658e6b3f5d2b3286fad8..ae209f262e79c4233bcd82808365c3698e4594cb 100644 (file)
@@ -232,12 +232,16 @@ class PackageInstallationDispatcher {
                                        ]);
                                        
                                        $statement->execute([
+                                               // We do not use the cache-timing safe class Hex, because we run the 
+                                               // function during the setup.
                                                $signatureSecret = \bin2hex(\random_bytes(20)),
                                                'signature_secret'
                                        ]);
                                        \define('SIGNATURE_SECRET', $signatureSecret);
                                        HeaderUtil::setCookie(
                                                'acp_session',
+                                               // We do not use the cache-timing safe class Hex, because we run the 
+                                               // function during the setup.
                                                CryptoUtil::createSignedString(\hex2bin(WCF::getSession()->sessionID))
                                        );
                                        
index 66cf6e8273353e5365a0f43c9305da377464067d..64e6269dfde70ab5095809252e285b9d0b00939a 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\system\session;
+use ParagonIE\ConstantTime\Hex;
 use wcf\data\session\Session as LegacySession;
 use wcf\data\session\SessionEditor;
 use wcf\data\user\User;
@@ -209,7 +210,7 @@ final class SessionHandler extends SingletonFactory {
                                return null;
                        }
                        
-                       return \bin2hex($compressedSessionId);
+                       return Hex::encode($compressedSessionId);
                }
                
                return null;
@@ -223,7 +224,7 @@ final class SessionHandler extends SingletonFactory {
                        return $sessionID;
                }
                
-               return CryptoUtil::createSignedString(\hex2bin($sessionID));
+               return CryptoUtil::createSignedString(Hex::decode($sessionID));
        }
        
        /**
@@ -334,7 +335,7 @@ final class SessionHandler extends SingletonFactory {
                                $xsrfToken = CryptoUtil::createSignedString(\random_bytes(16));
                        }
                        else {
-                               $xsrfToken = \bin2hex(\random_bytes(16));
+                               $xsrfToken = Hex::encode(\random_bytes(16));
                        }
                        
                        // We construct the cookie manually instead of using HeaderUtil::setCookie(), because:
@@ -531,7 +532,7 @@ final class SessionHandler extends SingletonFactory {
         * Creates a new session.
         */
        protected function create() {
-               $this->sessionID = \bin2hex(\random_bytes(20));
+               $this->sessionID = Hex::encode(\random_bytes(20));
                
                // Create new session.
                $sql = "INSERT INTO     wcf".WCF_N."_".($this->isACP ? 'acp' : 'user')."_session
index fea77e8cf1e61fc106ff6fa54380170288e36b6d..04ccc4ba45ac8d4ad426f0957d81ae964790ad79 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\system\user\authentication\password\algorithm;
+use ParagonIE\ConstantTime\Hex;
 use wcf\system\user\authentication\password\IPasswordAlgorithm;
 
 /**
@@ -27,7 +28,7 @@ final class CryptMD5 implements IPasswordAlgorithm {
         * @inheritDoc
         */
        public function hash(string $password): string {
-               $salt = '$1$'.\bin2hex(\random_bytes(6)).'$';
+               $salt = '$1$'.Hex::encode(\random_bytes(6)).'$';
                
                return $this->hashWithSalt($password, $salt);
        }
index 0e0c5ac9aa2e321f6c6f9a75c3aa151a41d21db3..11acd3f52d1f24b2da2cc8a46ff832e107359a76 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\system\user\authentication\password\algorithm;
+use ParagonIE\ConstantTime\Hex;
 use wcf\system\user\authentication\password\IPasswordAlgorithm;
 
 /**
@@ -25,7 +26,7 @@ final class Ipb2 implements IPasswordAlgorithm {
         * @inheritDoc
         */
        public function hash(string $password): string {
-               $salt = \bin2hex(\random_bytes(20));
+               $salt = Hex::encode(\random_bytes(20));
                
                return $this->hashWithSalt($password, $salt).':'.$salt;
        }
index ddd8fb3ec5fda2cd02600c210e62c5303451b5d6..da46cdc7d878667000bfcad0431f1ee48486f3b6 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\system\user\authentication\password\algorithm;
+use ParagonIE\ConstantTime\Hex;
 use wcf\system\user\authentication\password\IPasswordAlgorithm;
 
 /**
@@ -25,7 +26,7 @@ final class Ipb3 implements IPasswordAlgorithm {
         * @inheritDoc
         */
        public function hash(string $password): string {
-               $salt = \bin2hex(\random_bytes(20));
+               $salt = Hex::encode(\random_bytes(20));
                
                return $this->hashWithSalt($password, $salt).':'.$salt;
        }
index 6be64299bd5d64c722ae085d1686a4609dec96a3..e924b88de236d904958f8d9e69db016871424361 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\system\user\authentication\password\algorithm;
+use ParagonIE\ConstantTime\Hex;
 use wcf\system\user\authentication\password\IPasswordAlgorithm;
 
 /**
@@ -25,7 +26,7 @@ final class Joomla1 implements IPasswordAlgorithm {
         * @inheritDoc
         */
        public function hash(string $password): string {
-               $salt = \bin2hex(\random_bytes(20));
+               $salt = Hex::encode(\random_bytes(20));
                
                return $this->hashWithSalt($password, $salt).':'.$salt;
        }
index 1a5bf50487041b5a63e8fa424b00d3ca69b4055b..da73f714d26e1ea8279bf43dba2677b8ebdc0b17 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\system\user\authentication\password\algorithm;
+use ParagonIE\ConstantTime\Hex;
 use wcf\system\user\authentication\password\IPasswordAlgorithm;
 
 /**
@@ -25,7 +26,7 @@ final class Joomla2 implements IPasswordAlgorithm {
         * @inheritDoc
         */
        public function hash(string $password): string {
-               $salt = \bin2hex(\random_bytes(20));
+               $salt = Hex::encode(\random_bytes(20));
                
                return $this->hashWithSalt($password, $salt).':'.$salt;
        }
index 4c24b74ce86c087e49fed3d1858df481b21482d6..670535a106cb7210ed786ce79d769cc4facb8210 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\system\user\authentication\password\algorithm;
+use ParagonIE\ConstantTime\Hex;
 use wcf\system\user\authentication\password\IPasswordAlgorithm;
 
 /**
@@ -25,7 +26,7 @@ final class Joomla3 implements IPasswordAlgorithm {
         * @inheritDoc
         */
        public function hash(string $password): string {
-               $salt = \bin2hex(\random_bytes(20));
+               $salt = Hex::encode(\random_bytes(20));
                
                return $this->hashWithSalt($password, $salt).':'.$salt;
        }
index df4a579d8cdecf0562786cb1f7ee06960485028c..cf59295d7784a827b0eb27dc08b291860918b827 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\system\user\authentication\password\algorithm;
+use ParagonIE\ConstantTime\Hex;
 use wcf\system\user\authentication\password\IPasswordAlgorithm;
 
 /**
@@ -25,7 +26,7 @@ final class Mybb1 implements IPasswordAlgorithm {
         * @inheritDoc
         */
        public function hash(string $password): string {
-               $salt = \bin2hex(\random_bytes(20));
+               $salt = Hex::encode(\random_bytes(20));
                
                return $this->hashWithSalt($password, $salt).':'.$salt;
        }
index cd00be386ec734c4b92aa8be28b558f66d0dab86..05faa8c719aa7287ae4de70d1e838163068eafec 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\system\user\authentication\password\algorithm;
+use ParagonIE\ConstantTime\Hex;
 use wcf\system\user\authentication\password\IPasswordAlgorithm;
 
 /**
@@ -25,7 +26,7 @@ final class Phpfox3 implements IPasswordAlgorithm {
         * @inheritDoc
         */
        public function hash(string $password): string {
-               $salt = \bin2hex(\random_bytes(20));
+               $salt = Hex::encode(\random_bytes(20));
                
                return $this->hashWithSalt($password, $salt).':'.$salt;
        }
index 2603994af74f411897b966b09d78f10d76362354..97a3be0b5a20d72d7a3f797e3d74c00eeb4b7df0 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\system\user\authentication\password\algorithm;
+use ParagonIE\ConstantTime\Hex;
 use wcf\system\user\authentication\password\IPasswordAlgorithm;
 
 /**
@@ -25,7 +26,7 @@ final class Smf1 implements IPasswordAlgorithm {
         * @inheritDoc
         */
        public function hash(string $password): string {
-               $salt = \bin2hex(\random_bytes(20));
+               $salt = Hex::encode(\random_bytes(20));
                
                return $this->hashWithSalt($password, $salt).':'.$salt;
        }
index c18c15c565442fd16631375ff0200cb404875fb2..605553295ca2cd6b675804f3b6f1ad3fcdc375f9 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\system\user\authentication\password\algorithm;
+use ParagonIE\ConstantTime\Hex;
 use wcf\system\user\authentication\password\IPasswordAlgorithm;
 
 /**
@@ -25,7 +26,7 @@ final class Smf2 implements IPasswordAlgorithm {
         * @inheritDoc
         */
        public function hash(string $password): string {
-               $salt = \bin2hex(\random_bytes(20));
+               $salt = Hex::encode(\random_bytes(20));
                
                return $this->hashWithSalt($password, $salt).':'.$salt;
        }
index 9a71d0ceda08ab668bd0afd70b3997ad0cc41a7b..d3363f10d8419e1c18fdd351b8b751552181d2d9 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\system\user\authentication\password\algorithm;
+use ParagonIE\ConstantTime\Hex;
 
 /**
  * Implementation of the PHPASS password algorithm.
@@ -104,7 +105,7 @@ trait TPhpass {
         */
        public function hash(string $password): string {
                $settings = '$H$8';
-               $settings .= \bin2hex(\random_bytes(4));
+               $settings .= Hex::encode(\random_bytes(4));
                
                return $this->hashPhpass($password, $settings).':';
        }
index 24546c4fe1ee6bcfa7ec2024075678207c96039b..2848e1426467f421c595b15677e09087619edaed 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\system\user\authentication\password\algorithm;
+use ParagonIE\ConstantTime\Hex;
 use wcf\system\user\authentication\password\IPasswordAlgorithm;
 
 /**
@@ -25,7 +26,7 @@ final class Vb3 implements IPasswordAlgorithm {
         * @inheritDoc
         */
        public function hash(string $password): string {
-               $salt = \bin2hex(\random_bytes(20));
+               $salt = Hex::encode(\random_bytes(20));
                
                return $this->hashWithSalt($password, $salt).':'.$salt;
        }
index 0aa3375082536f2bfc3491e389e1e0b675bee544..94b66dded1b997309a8feaec9c9f7eae83c82a7b 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\system\user\authentication\password\algorithm;
+use ParagonIE\ConstantTime\Hex;
 use wcf\system\user\authentication\password\IPasswordAlgorithm;
 
 /**
@@ -25,7 +26,7 @@ final class Vb4 implements IPasswordAlgorithm {
         * @inheritDoc
         */
        public function hash(string $password): string {
-               $salt = \bin2hex(\random_bytes(20));
+               $salt = Hex::encode(\random_bytes(20));
                
                return $this->hashWithSalt($password, $salt).':'.$salt;
        }
index f911776c909593adc71053e833359991efd81bf7..b7968df6ab89ea7eaf786c08175a4cdf984c9f94 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\system\user\authentication\password\algorithm;
+use ParagonIE\ConstantTime\Hex;
 use wcf\system\user\authentication\password\IPasswordAlgorithm;
 
 /**
@@ -25,7 +26,7 @@ final class Vb5 implements IPasswordAlgorithm {
         * @inheritDoc
         */
        public function hash(string $password): string {
-               $salt = \bin2hex(\random_bytes(20));
+               $salt = Hex::encode(\random_bytes(20));
                
                return $this->hashWithSalt($password, $salt).':'.$salt;
        }
index c2ea2fb30210c5f22001caa7672bd5ef19064b78..802a794179b48536e37a324a4bccafeb55dc01f0 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\system\user\authentication\password\algorithm;
+use ParagonIE\ConstantTime\Hex;
 use wcf\system\user\authentication\password\IPasswordAlgorithm;
 
 /**
@@ -25,7 +26,7 @@ final class Wcf1 implements IPasswordAlgorithm {
         * @inheritDoc
         */
        public function hash(string $password): string {
-               $salt = \bin2hex(\random_bytes(20));
+               $salt = Hex::encode(\random_bytes(20));
                
                return $this->hashWithSalt($password, $salt).':'.$salt;
        }
index b449f6cd7e84f021b795c9681920b94ccbebba47..b7ca07e7940b64a1d16c64d0bfcf57ed1df89411 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\system\user\authentication\password\algorithm;
+use ParagonIE\ConstantTime\Hex;
 use wcf\system\user\authentication\password\IPasswordAlgorithm;
 
 /**
@@ -59,7 +60,7 @@ final class Wcf1e implements IPasswordAlgorithm {
         * @inheritDoc
         */
        public function hash(string $password): string {
-               $salt = \bin2hex(\random_bytes(20));
+               $salt = Hex::encode(\random_bytes(20));
                
                return $this->hashWithSalt($password, $salt).':'.$salt;
        }
index d170488b9b50e08ba65ebafe885582201dd5d0bf..c3fbd00353a8736f252a3d7cad4942c858664644 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\system\user\authentication\password\algorithm;
+use ParagonIE\ConstantTime\Hex;
 use wcf\system\user\authentication\password\IPasswordAlgorithm;
 
 /**
@@ -29,7 +30,7 @@ final class Xf1 implements IPasswordAlgorithm {
         * @inheritDoc
         */
        public function hash(string $password): string {
-               $salt = \bin2hex(\random_bytes(20));
+               $salt = Hex::encode(\random_bytes(20));
                
                return $this->hashWithSalt($password, $salt).':'.$salt;
        }
index 0d8c526ab87e425ea003c6fcdff1ea143e8d0b30..fc3c6ddcf2566a1120b16b4bef6b546e710a68c7 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\system\user\notification;
+use ParagonIE\ConstantTime\Hex;
 use wcf\data\language\Language;
 use wcf\data\user\notification\event\UserNotificationEvent;
 use wcf\data\user\notification\UserNotification;
@@ -75,7 +76,7 @@ class TestableUserNotificationEventHandler extends SingletonFactory {
                                        'data' => [
                                                'email' => $username . '@example.com',
                                                'languageID' => $languages[array_rand($languages)]->languageID,
-                                               'password' => \bin2hex(\random_bytes(16)),
+                                               'password' => Hex::encode(\random_bytes(16)),
                                                'registrationDate' => TIME_NOW - 24 * 3600 * random_int(10, 1000),
                                                'username' => $username
                                        ]
index 577efecbfdda567e1c7fe51c7bd9cd9bf4c8bc64..f8e8a49d0f733621563cae8a4167d88c231e3f38 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\system\user\notification;
+use ParagonIE\ConstantTime\Hex;
 use wcf\data\object\type\ObjectType;
 use wcf\data\object\type\ObjectTypeCache;
 use wcf\data\user\notification\event\recipient\UserNotificationEventRecipientList;
@@ -683,7 +684,7 @@ class UserNotificationHandler extends SingletonFactory {
                
                // generate token if not present
                if (!$user->notificationMailToken) {
-                       $token = bin2hex(\random_bytes(10));
+                       $token = Hex::encode(\random_bytes(10));
                        $editor = new UserEditor($user);
                        $editor->update(['notificationMailToken' => $token]);
                        
index 87c93fb92eb12754d464839640b00cc1cfebb0ea..dbbba5b21a8fe90f4228f8c07edd832b9885c933 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\system\worker;
+use ParagonIE\ConstantTime\Hex;
 use wcf\data\user\User;
 use wcf\data\user\UserAction;
 use wcf\data\user\UserEditor;
@@ -93,7 +94,7 @@ class SendNewPasswordWorker extends AbstractWorker {
         * @param       UserEditor      $userEditor
         */
        protected function resetPassword(UserEditor $userEditor) {
-               $lostPasswordKey = bin2hex(\random_bytes(20));
+               $lostPasswordKey = Hex::encode(\random_bytes(20));
                $lastLostPasswordRequestTime = TIME_NOW;
                $userAction = new UserAction([$userEditor], 'update', [
                        'data' => [
index cbb148e0a0026b5ffdb41cd95dbfb61e9c739449..95b998227bf181fdfc3e90c4f60072c515a09eaf 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\util;
+use ParagonIE\ConstantTime\Hex;
 use wcf\system\exception\SystemException;
 use wcf\system\io\File;
 use wcf\system\io\GZipFile;
@@ -119,7 +120,7 @@ final class FileUtil {
        public static function getTemporaryFilename($prefix = 'tmpFile_', $extension = '', $dir = TMP_DIR) {
                $dir = self::addTrailingSlash($dir);
                do {
-                       $tmpFile = $dir.$prefix.bin2hex(\random_bytes(20)).$extension;
+                       $tmpFile = $dir.$prefix.Hex::encode(\random_bytes(20)).$extension;
                }
                while (file_exists($tmpFile));
                
index 447d4f794d52cdaa9286fd06ff84368460f0bc27..ae805508138229430b3f34f34000255335132051 100644 (file)
@@ -4,6 +4,7 @@ use GuzzleHttp\Exception\BadResponseException;
 use GuzzleHttp\Exception\TooManyRedirectsException;
 use GuzzleHttp\Exception\TransferException;
 use GuzzleHttp\Psr7\Request;
+use ParagonIE\ConstantTime\Hex;
 use Psr\Http\Message\RequestInterface;
 use Psr\Http\Message\ResponseInterface;
 use Psr\Http\Message\UriInterface;
@@ -111,7 +112,7 @@ final class HTTPRequest {
                                $this->addHeader('content-type', 'application/x-www-form-urlencoded');
                        }
                        else {
-                               $boundary = bin2hex(\random_bytes(20));
+                               $boundary = Hex::encode(\random_bytes(20));
                                $this->addHeader('content-type', 'multipart/form-data; boundary='.$boundary);
                                
                                // source of the iterators: http://stackoverflow.com/a/7623716/782822
index ecdc8301131a3b6c18b43df450d291582d070336..c47c347fc4d36ca3e5435afb5d5f82847c430170 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\util;
+use ParagonIE\ConstantTime\Hex;
 use wcf\system\application\ApplicationHandler;
 use wcf\system\request\RouteHandler;
 use wcf\system\WCF;
@@ -47,7 +48,7 @@ final class StringUtil {
         * @return      string
         */
        public static function getRandomID() {
-               return \bin2hex(\random_bytes(20));
+               return Hex::encode(\random_bytes(20));
        }
        
        /**