diff options
-rw-r--r-- | Core/Util/Prng.php | 43 | ||||
-rw-r--r-- | Core/Util/SeedProviderInterface.php | 37 | ||||
-rwxr-xr-x | Tests/Core/Util/PrngTest.php | 4 |
3 files changed, 30 insertions, 54 deletions
diff --git a/Core/Util/Prng.php b/Core/Util/Prng.php index ab8baa7..f3a0b24 100644 --- a/Core/Util/Prng.php +++ b/Core/Util/Prng.php @@ -16,6 +16,7 @@ use Symfony\Component\HttpKernel\Log\LoggerInterface; /** * A secure random number generator implementation. * + * @author Fabien Potencier <fabien@symfony.com> * @author Johannes M. Schmitt <schmittjoh@gmail.com> */ final class Prng @@ -25,7 +26,7 @@ final class Prng private $seed; private $seedUpdated; private $seedLastUpdatedAt; - private $seedProvider; + private $seedFile; /** * Constructor. @@ -33,12 +34,12 @@ final class Prng * Be aware that a guessable seed will severely compromise the PRNG * algorithm that is employed. * - * @param SeedProviderInterface $provider - * @param LoggerInterface $logger + * @param string $seedFile + * @param LoggerInterface $logger */ - public function __construct(SeedProviderInterface $provider = null, LoggerInterface $logger = null) + public function __construct($seedFile = null, LoggerInterface $logger = null) { - $this->seedProvider = $provider; + $this->seedFile = $seedFile; $this->logger = $logger; // determine whether to use OpenSSL @@ -77,11 +78,16 @@ final class Prng // initialize seed if (null === $this->seed) { - if (null === $this->seedProvider) { - throw new \RuntimeException('You need to specify a custom seed provider.'); + if (null === $this->seedFile) { + throw new \RuntimeException('You need to specify a file path to store the seed.'); } - list($this->seed, $this->seedLastUpdatedAt) = $this->seedProvider->loadSeed(); + if (is_file($this->seedFile)) { + list($this->seed, $this->seedLastUpdatedAt) = $this->readSeed(); + } else { + $this->seed = uniqid(mt_rand(), true); + $this->updateSeed(); + } } $bytes = ''; @@ -89,16 +95,23 @@ final class Prng static $incr = 1; $bytes .= hash('sha512', $incr++.$this->seed.uniqid(mt_rand(), true).$nbBytes, true); $this->seed = base64_encode(hash('sha512', $this->seed.$bytes.$nbBytes, true)); + $this->updateSeed(); + } - if (!$this->seedUpdated && $this->seedLastUpdatedAt->getTimestamp() < time() - mt_rand(1, 10)) { - if (null !== $this->seedProvider) { - $this->seedProvider->updateSeed($this->seed); - } + return substr($bytes, 0, $nbBytes); + } - $this->seedUpdated = true; - } + private function readSeed() + { + return json_decode(file_get_contents($this->seedFile)); + } + + private function updateSeed() + { + if (!$this->seedUpdated && $this->seedLastUpdatedAt < time() - mt_rand(1, 10)) { + file_put_contents($this->seedFile, json_encode(array($this->seed, microtime(true)))); } - return substr($bytes, 0, $nbBytes); + $this->seedUpdated = true; } } diff --git a/Core/Util/SeedProviderInterface.php b/Core/Util/SeedProviderInterface.php deleted file mode 100644 index dd960b9..0000000 --- a/Core/Util/SeedProviderInterface.php +++ /dev/null @@ -1,37 +0,0 @@ -<?php - -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier <fabien@symfony.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Core\Util; - -/** - * Seed Provider Interface. - * - * @author Johannes M. Schmitt <schmittjoh@gmail.com> - */ -interface SeedProviderInterface -{ - /** - * Loads the initial seed. - * - * Whatever is returned from this method, it should not be guessable. - * - * @return array of the format array(string, DateTime) where string is the - * initial seed, and DateTime is the last time it was updated - */ - function loadSeed(); - - /** - * Updates the seed. - * - * @param string $seed - */ - function updateSeed($seed); -} diff --git a/Tests/Core/Util/PrngTest.php b/Tests/Core/Util/PrngTest.php index 7c9b2e2..23afd30 100755 --- a/Tests/Core/Util/PrngTest.php +++ b/Tests/Core/Util/PrngTest.php @@ -147,11 +147,11 @@ class PrngTest extends \PHPUnit_Framework_TestCase $prngs = array(); // openssl with fallback - $prng = new Prng(new NullSeedProvider()); + $prng = new Prng(); $prngs[] = array($prng); // no-openssl with custom seed provider - $prng = new Prng(new NullSeedProvider()); + $prng = new Prng(sys_get_temp_dir().'/_sf2.seed'); $this->disableOpenSsl($prng); $prngs[] = array($prng); |