diff --git a/3rdparty b/3rdparty index a7b34d6f83..56934b1fc0 160000 --- a/3rdparty +++ b/3rdparty @@ -1 +1 @@ -Subproject commit a7b34d6f831c8fa363f389d27acd0150128fc0b9 +Subproject commit 56934b1fc0f15760690c7a28c6c6429ce6ce6bef diff --git a/apps/encryption/lib/crypto/crypt.php b/apps/encryption/lib/crypto/crypt.php index dbc0364a15..12e9008545 100644 --- a/apps/encryption/lib/crypto/crypt.php +++ b/apps/encryption/lib/crypto/crypt.php @@ -30,7 +30,6 @@ use OC\Encryption\Exceptions\DecryptionFailedException; use OC\Encryption\Exceptions\EncryptionFailedException; use OCA\Encryption\Exceptions\MultiKeyDecryptException; use OCA\Encryption\Exceptions\MultiKeyEncryptException; -use OCA\Encryption\Vendor\PBKDF2Fallback; use OCP\Encryption\Exceptions\GenericEncryptionException; use OCP\IConfig; use OCP\ILogger; @@ -293,28 +292,14 @@ class Crypt { $salt = hash('sha256', $uid . $instanceId . $instanceSecret, true); $keySize = $this->getKeySize($cipher); - if (function_exists('hash_pbkdf2')) { - $hash = hash_pbkdf2( - 'sha256', - $password, - $salt, - 100000, - $keySize, - true - ); - } else { - // fallback to 3rdparty lib for PHP <= 5.4. - // FIXME: Can be removed as soon as support for PHP 5.4 was dropped - $fallback = new PBKDF2Fallback(); - $hash = $fallback->pbkdf2( - 'sha256', - $password, - $salt, - 100000, - $keySize, - true - ); - } + $hash = hash_pbkdf2( + 'sha256', + $password, + $salt, + 100000, + $keySize, + true + ); return $hash; } diff --git a/apps/encryption/vendor/pbkdf2fallback.php b/apps/encryption/vendor/pbkdf2fallback.php deleted file mode 100644 index ca579f8e7d..0000000000 --- a/apps/encryption/vendor/pbkdf2fallback.php +++ /dev/null @@ -1,87 +0,0 @@ -dbHandler->getToken($url); - return StringUtils::equals($storedToken, $token); + return hash_equals($storedToken, $token); } } diff --git a/lib/private/appframework/http/request.php b/lib/private/appframework/http/request.php index 2bbb70db0f..6ba1d8f644 100644 --- a/lib/private/appframework/http/request.php +++ b/lib/private/appframework/http/request.php @@ -447,7 +447,7 @@ class Request implements \ArrayAccess, \Countable, IRequest { $deobfuscatedToken = base64_decode($obfuscatedToken) ^ $secret; // Check if the token is valid - if(\OCP\Security\StringUtils::equals($deobfuscatedToken, $this->items['requesttoken'])) { + if(hash_equals($deobfuscatedToken, $this->items['requesttoken'])) { return true; } else { return false; diff --git a/lib/private/log.php b/lib/private/log.php index ee5d61e98d..a722243dc6 100644 --- a/lib/private/log.php +++ b/lib/private/log.php @@ -227,7 +227,7 @@ class Log implements ILogger { $request = \OC::$server->getRequest(); // if token is found in the request change set the log condition to satisfied - if($request && StringUtils::equals($request->getParam('log_secret'), $logCondition['shared_secret'])) { + if($request && hash_equals($logCondition['shared_secret'], $request->getParam('log_secret'))) { $this->logConditionSatisfied = true; } } diff --git a/lib/private/security/crypto.php b/lib/private/security/crypto.php index 0bd34df3f3..46d0c750b2 100644 --- a/lib/private/security/crypto.php +++ b/lib/private/security/crypto.php @@ -123,7 +123,7 @@ class Crypto implements ICrypto { $this->cipher->setIV($iv); - if(!\OCP\Security\StringUtils::equals($this->calculateHMAC($parts[0].$parts[1], $password), $hmac)) { + if(!hash_equals($this->calculateHMAC($parts[0].$parts[1], $password), $hmac)) { throw new \Exception('HMAC does not match.'); } diff --git a/lib/private/security/hasher.php b/lib/private/security/hasher.php index a5dd22e5dc..318141b685 100644 --- a/lib/private/security/hasher.php +++ b/lib/private/security/hasher.php @@ -109,7 +109,7 @@ class Hasher implements IHasher { // Verify whether it matches a legacy PHPass or SHA1 string $hashLength = strlen($hash); if($hashLength === 60 && password_verify($message.$this->legacySalt, $hash) || - $hashLength === 40 && StringUtils::equals($hash, sha1($message))) { + $hashLength === 40 && hash_equals($hash, sha1($message))) { $newHash = $this->hash($message); return true; } diff --git a/lib/private/security/securerandom.php b/lib/private/security/securerandom.php index 87dca68985..24affbe898 100644 --- a/lib/private/security/securerandom.php +++ b/lib/private/security/securerandom.php @@ -27,25 +27,15 @@ use Sabre\DAV\Exception; use OCP\Security\ISecureRandom; /** - * Class SecureRandom provides a layer around RandomLib to generate - * secure random strings. For PHP 7 the native CSPRNG is used. + * Class SecureRandom provides a wrapper around the random_int function to generate + * secure random strings. For PHP 7 the native CSPRNG is used, older versions do + * use a fallback. * * Usage: - * \OC::$server->getSecureRandom()->getMediumStrengthGenerator()->generate(10); - * + * \OC::$server->getSecureRandom()->generate(10); * @package OC\Security */ class SecureRandom implements ISecureRandom { - - /** @var \RandomLib\Factory */ - var $factory; - /** @var \RandomLib\Generator */ - var $generator; - - function __construct() { - $this->factory = new RandomLib\Factory; - } - /** * Convenience method to get a low strength random number generator. * @@ -53,10 +43,10 @@ class SecureRandom implements ISecureRandom { * in a non-cryptographical setting. They are not strong enough to be * used as keys or salts. They are however useful for one-time use tokens. * + * @deprecated 9.0.0 Use \OC\Security\SecureRandom::generate directly or random_bytes() / random_int() * @return $this */ public function getLowStrengthGenerator() { - $this->generator = $this->factory->getLowStrengthGenerator(); return $this; } @@ -67,10 +57,10 @@ class SecureRandom implements ISecureRandom { * They are strong enough to be used as keys and salts. However, they do * take some time and resources to generate, so they should not be over-used * + * @deprecated 9.0.0 Use \OC\Security\SecureRandom::generate directly or random_bytes() / random_int() * @return $this */ public function getMediumStrengthGenerator() { - $this->generator = $this->factory->getMediumStrengthGenerator(); return $this; } @@ -80,26 +70,17 @@ class SecureRandom implements ISecureRandom { * @param string $characters An optional list of characters to use if no character list is * specified all valid base64 characters are used. * @return string - * @throws \Exception If the generator is not initialized. */ public function generate($length, $characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/') { - if(is_null($this->generator)) { - throw new \Exception('Generator is not initialized.'); + $maxCharIndex = strlen($characters) - 1; + $randomString = ''; + + while($length > 0) { + $randomNumber = random_int(0, $maxCharIndex); + $randomString .= $characters[$randomNumber]; + $length--; } - - if(function_exists('random_int')) { - $maxCharIndex = strlen($characters) - 1; - $randomString = ''; - - while($length > 0) { - $randomNumber = random_int(0, $maxCharIndex); - $randomString .= $characters[$randomNumber]; - $length--; - } - return $randomString; - } - - return $this->generator->generateString($length, $characters); + return $randomString; } } diff --git a/lib/private/security/stringutils.php b/lib/private/security/stringutils.php deleted file mode 100644 index fa4342a2b4..0000000000 --- a/lib/private/security/stringutils.php +++ /dev/null @@ -1,60 +0,0 @@ - - * @author Morris Jobke - * - * @copyright Copyright (c) 2015, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see - * - */ - -namespace OC\Security; - -class StringUtils { - - /** - * Compares whether two strings are equal. To prevent guessing of the string - * length this is done by comparing two hashes against each other and afterwards - * a comparison of the real string to prevent against the unlikely chance of - * collisions. - * - * Be aware that this function may leak whether the string to compare have a different - * length. - * - * @param string $expected The expected value - * @param string $input The input to compare against - * @return bool True if the two strings are equal, otherwise false. - */ - public static function equals($expected, $input) { - - if(!is_string($expected) || !is_string($input)) { - return false; - } - - if(function_exists('hash_equals')) { - return hash_equals($expected, $input); - } - - $randomString = \OC::$server->getSecureRandom()->getLowStrengthGenerator()->generate(10); - - if(hash('sha512', $expected.$randomString) === hash('sha512', $input.$randomString)) { - if($expected === $input) { - return true; - } - } - - return false; - } -} \ No newline at end of file diff --git a/lib/public/security/isecurerandom.php b/lib/public/security/isecurerandom.php index 1b72e4f437..8315d0f971 100644 --- a/lib/public/security/isecurerandom.php +++ b/lib/public/security/isecurerandom.php @@ -23,12 +23,12 @@ namespace OCP\Security; /** - * Class SecureRandom provides a layer around RandomLib to generate - * secure random strings. For PHP 7 the native CSPRNG is used. + * Class SecureRandom provides a wrapper around the random_int function to generate + * secure random strings. For PHP 7 the native CSPRNG is used, older versions do + * use a fallback. * * Usage: - * $rng = new \OC\Security\SecureRandom(); - * $randomString = $rng->getMediumStrengthGenerator()->generateString(30); + * \OC::$server->getSecureRandom()->generate(10); * * @package OCP\Security * @since 8.0.0 @@ -52,6 +52,7 @@ interface ISecureRandom { * * @return $this * @since 8.0.0 + * @deprecated 9.0.0 Use \OC\Security\SecureRandom::generate directly or random_bytes() / random_int() */ public function getLowStrengthGenerator(); @@ -64,6 +65,7 @@ interface ISecureRandom { * * @return $this * @since 8.0.0 + * @deprecated 9.0.0 Use \OC\Security\SecureRandom::generate directly or random_bytes() / random_int() */ public function getMediumStrengthGenerator(); @@ -73,7 +75,6 @@ interface ISecureRandom { * @param string $characters An optional list of characters to use if no character list is * specified all valid base64 characters are used. * @return string - * @throws \Exception If the generator is not initialized. * @since 8.0.0 */ public function generate($length, diff --git a/lib/public/security/stringutils.php b/lib/public/security/stringutils.php index 4f41fcf826..7cf12ea270 100644 --- a/lib/public/security/stringutils.php +++ b/lib/public/security/stringutils.php @@ -39,8 +39,9 @@ class StringUtils { * @param string $input The input to compare against * @return bool True if the two strings are equal, otherwise false. * @since 8.0.0 + * @deprecated 9.0.0 Use hash_equals */ public static function equals($expected, $input) { - return \OC\Security\StringUtils::equals($expected, $input); + return hash_equals($expected, $input); } } diff --git a/tests/lib/security/securerandom.php b/tests/lib/security/securerandom.php index d9bbd0e71e..af43764080 100644 --- a/tests/lib/security/securerandom.php +++ b/tests/lib/security/securerandom.php @@ -57,11 +57,10 @@ class SecureRandomTest extends \Test\TestCase { } /** - * @expectedException \Exception - * @expectedExceptionMessage Generator is not initialized + * @dataProvider stringGenerationProvider */ - function testUninitializedGenerate() { - $this->rng->generate(30); + function testUninitializedGenerate($length, $expectedLength) { + $this->assertEquals($expectedLength, strlen($this->rng->generate($length))); } /** diff --git a/tests/lib/security/stringutils.php b/tests/lib/security/stringutils.php deleted file mode 100644 index 060315debb..0000000000 --- a/tests/lib/security/stringutils.php +++ /dev/null @@ -1,38 +0,0 @@ - - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. - */ - -use \OC\Security\StringUtils; - -class StringUtilsTest extends \Test\TestCase { - - public function dataProvider() - { - return array( - array('Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt.', 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt.'), - array('', ''), - array('我看这本书。 我看這本書', '我看这本书。 我看這本書'), - array('GpKY9fSnWNJbES99zVGvA', 'GpKY9fSnWNJbES99zVGvA') - ); - } - - /** - * @dataProvider dataProvider - */ - function testWrongEquals($string) { - $this->assertFalse(StringUtils::equals($string, 'A Completely Wrong String')); - $this->assertFalse(StringUtils::equals($string, null)); - } - - /** - * @dataProvider dataProvider - */ - function testTrueEquals($string, $expected) { - $this->assertTrue(StringUtils::equals($string, $expected)); - } - -}