summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Core/Util/Prng.php43
-rw-r--r--Core/Util/SeedProviderInterface.php37
-rwxr-xr-xTests/Core/Util/PrngTest.php4
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);