diff options
Diffstat (limited to 'Core')
-rw-r--r-- | Core/Authentication/AuthenticationProviderManager.php | 6 | ||||
-rw-r--r-- | Core/Tests/Authentication/AuthenticationProviderManagerTest.php | 10 | ||||
-rw-r--r-- | Core/Util/StringUtils.php | 49 |
3 files changed, 54 insertions, 11 deletions
diff --git a/Core/Authentication/AuthenticationProviderManager.php b/Core/Authentication/AuthenticationProviderManager.php index f713e8f..16de8da 100644 --- a/Core/Authentication/AuthenticationProviderManager.php +++ b/Core/Authentication/AuthenticationProviderManager.php @@ -48,6 +48,12 @@ class AuthenticationProviderManager implements AuthenticationManagerInterface throw new \InvalidArgumentException('You must at least add one authentication provider.'); } + foreach ($providers as $provider) { + if (!$provider instanceof AuthenticationProviderInterface) { + throw new \InvalidArgumentException(sprintf('Provider "%s" must implement the AuthenticationProviderInterface.', get_class($provider))); + } + } + $this->providers = $providers; $this->eraseCredentials = (bool) $eraseCredentials; } diff --git a/Core/Tests/Authentication/AuthenticationProviderManagerTest.php b/Core/Tests/Authentication/AuthenticationProviderManagerTest.php index df25874..cc8b7c0 100644 --- a/Core/Tests/Authentication/AuthenticationProviderManagerTest.php +++ b/Core/Tests/Authentication/AuthenticationProviderManagerTest.php @@ -27,6 +27,16 @@ class AuthenticationProviderManagerTest extends \PHPUnit_Framework_TestCase new AuthenticationProviderManager(array()); } + /** + * @expectedException \InvalidArgumentException + */ + public function testAuthenticateWithProvidersWithIncorrectInterface() + { + new AuthenticationProviderManager(array( + new \stdClass(), + )); + } + public function testAuthenticateWhenNoProviderSupportsToken() { $manager = new AuthenticationProviderManager(array( diff --git a/Core/Util/StringUtils.php b/Core/Util/StringUtils.php index e8f3e3b..e68347f 100644 --- a/Core/Util/StringUtils.php +++ b/Core/Util/StringUtils.php @@ -38,29 +38,56 @@ class StringUtils */ public static function equals($knownString, $userInput) { - $knownString = (string) $knownString; - $userInput = (string) $userInput; + // Avoid making unnecessary duplications of secret data + if (!is_string($knownString)) { + $knownString = (string) $knownString; + } + + if (!is_string($userInput)) { + $userInput = (string) $userInput; + } if (function_exists('hash_equals')) { return hash_equals($knownString, $userInput); } - $knownLen = strlen($knownString); - $userLen = strlen($userInput); + $knownLen = self::safeStrlen($knownString); + $userLen = self::safeStrlen($userInput); - // Extend the known string to avoid uninitialized string offsets - $knownString .= $userInput; + if ($userLen !== $knownLen) { + return false; + } - // Set the result to the difference between the lengths - $result = $knownLen - $userLen; + $result = 0; - // Note that we ALWAYS iterate over the user-supplied length - // This is to mitigate leaking length information - for ($i = 0; $i < $userLen; $i++) { + for ($i = 0; $i < $knownLen; $i++) { $result |= (ord($knownString[$i]) ^ ord($userInput[$i])); } // They are only identical strings if $result is exactly 0... return 0 === $result; } + + /** + * Returns the number of bytes in a string. + * + * @param string $string The string whose length we wish to obtain + * + * @return int + */ + public static function safeStrlen($string) + { + // Premature optimization + // Since this cannot be changed at runtime, we can cache it + static $funcExists = null; + if (null === $funcExists) { + $funcExists = function_exists('mb_strlen'); + } + + if ($funcExists) { + return mb_strlen($string, '8bit'); + } + + return strlen($string); + } } |