mirror of
https://github.com/yiisoft/yii2.git
synced 2025-08-26 14:26:54 +08:00
use file_get_contents and not magic numbers
This commit is contained in:
@ -30,6 +30,11 @@ use Yii;
|
|||||||
*/
|
*/
|
||||||
class Security extends Component
|
class Security extends Component
|
||||||
{
|
{
|
||||||
|
const DEV_URANDOM = '/dev/urandom';
|
||||||
|
const SOURCE_MCRYPT = 'mcrypt';
|
||||||
|
const SOURCE_URANDOM = 'urandom';
|
||||||
|
const SOURCE_OPEN_SSL = 'OpenSSL';
|
||||||
|
const SOURCE_LIBRE_SSL = 'LibreSSL';
|
||||||
/**
|
/**
|
||||||
* @var string The cipher to use for encryption and decryption.
|
* @var string The cipher to use for encryption and decryption.
|
||||||
*/
|
*/
|
||||||
@ -455,7 +460,7 @@ class Security extends Component
|
|||||||
// The recent LibreSSL RNGs are faster and better than /dev/urandom.
|
// The recent LibreSSL RNGs are faster and better than /dev/urandom.
|
||||||
// Parse OPENSSL_VERSION_TEXT because OPENSSL_VERSION_NUMBER is no use for LibreSSL.
|
// Parse OPENSSL_VERSION_TEXT because OPENSSL_VERSION_NUMBER is no use for LibreSSL.
|
||||||
// https://bugs.php.net/bug.php?id=71143
|
// https://bugs.php.net/bug.php?id=71143
|
||||||
if ($this->_randomSource === 'LibreSSL'
|
if ($this->_randomSource === self::SOURCE_LIBRE_SSL
|
||||||
|| ($this->_randomSource === null
|
|| ($this->_randomSource === null
|
||||||
&& defined('OPENSSL_VERSION_TEXT')
|
&& defined('OPENSSL_VERSION_TEXT')
|
||||||
&& preg_match('{^LibreSSL (\d\d?)\.(\d\d?)\.(\d\d?)$}', OPENSSL_VERSION_TEXT, $matches)
|
&& preg_match('{^LibreSSL (\d\d?)\.(\d\d?)\.(\d\d?)$}', OPENSSL_VERSION_TEXT, $matches)
|
||||||
@ -468,7 +473,7 @@ class Security extends Component
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
if ($key !== false && StringHelper::byteLength($key) === $length) {
|
if ($key !== false && StringHelper::byteLength($key) === $length) {
|
||||||
$this->_randomSource = 'LibreSSL';
|
$this->_randomSource = self::SOURCE_LIBRE_SSL;
|
||||||
|
|
||||||
return $key;
|
return $key;
|
||||||
}
|
}
|
||||||
@ -478,14 +483,14 @@ class Security extends Component
|
|||||||
|
|
||||||
// mcrypt_create_iv() does not use libmcrypt. Since PHP 5.3.7 it directly reads
|
// mcrypt_create_iv() does not use libmcrypt. Since PHP 5.3.7 it directly reads
|
||||||
// CrypGenRandom on Windows. Elsewhere it directly reads /dev/urandom.
|
// CrypGenRandom on Windows. Elsewhere it directly reads /dev/urandom.
|
||||||
if ($this->_randomSource === 'mcrypt'
|
if ($this->_randomSource === self::SOURCE_MCRYPT
|
||||||
|| ($this->_randomSource === null
|
|| ($this->_randomSource === null
|
||||||
&& PHP_VERSION_ID >= 50307
|
&& PHP_VERSION_ID >= 50307
|
||||||
&& function_exists('mcrypt_create_iv'))
|
&& function_exists('mcrypt_create_iv'))
|
||||||
) {
|
) {
|
||||||
$key = mcrypt_create_iv($length, MCRYPT_DEV_URANDOM);
|
$key = mcrypt_create_iv($length, MCRYPT_DEV_URANDOM);
|
||||||
if (StringHelper::byteLength($key) === $length) {
|
if (StringHelper::byteLength($key) === $length) {
|
||||||
$this->_randomSource = 'mcrypt';
|
$this->_randomSource = self::SOURCE_MCRYPT;
|
||||||
|
|
||||||
return $key;
|
return $key;
|
||||||
}
|
}
|
||||||
@ -493,48 +498,21 @@ class Security extends Component
|
|||||||
$this->_randomSource = null;
|
$this->_randomSource = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If not on Windows, try reading from /dev/urandom device. If successful, cache
|
// If not on Windows, test for a /dev/urandom device.
|
||||||
// the file pointer in $this->_randomSource.
|
if ($this->_randomSource === null && DIRECTORY_SEPARATOR === '/') {
|
||||||
if (is_resource($this->_randomSource)
|
// Check it for speacial character device protection mode.
|
||||||
|| ($this->_randomSource === null
|
$lstat = @lstat(self::DEV_URANDOM);
|
||||||
&& DIRECTORY_SEPARATOR === '/'
|
$urandomDevice = $lstat !== false && ($lstat['mode'] & 0170000) === 020000;
|
||||||
&& @is_readable('/dev/urandom'))
|
} else {
|
||||||
) {
|
$urandomDevice = false;
|
||||||
// Either open /dev/urandom or get the cached file pointer.
|
}
|
||||||
if (is_resource($this->_randomSource)) {
|
if ($this->_randomSource === self::SOURCE_URANDOM || $urandomDevice) {
|
||||||
$urandomFile = $this->_randomSource;
|
$key = @file_get_contents(self::DEV_URANDOM, false, null, 0, $length);
|
||||||
} else {
|
|
||||||
$urandomFile = fopen('/dev/urandom', 'rb');
|
|
||||||
if ($urandomFile) {
|
|
||||||
// Check the file's inode protection mode is 'character special'.
|
|
||||||
// NOTE: octal integer literals!
|
|
||||||
$fstat = fstat($urandomFile);
|
|
||||||
if (($fstat['mode'] & 0170000) !== 020000) {
|
|
||||||
fclose($urandomFile);
|
|
||||||
$urandomFile = null;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$urandomFile = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($urandomFile !== null) {
|
if ($key !== false && StringHelper::byteLength($key) === $length) {
|
||||||
// $length could be large so read using a loop.
|
$this->_randomSource = self::SOURCE_URANDOM;
|
||||||
$key = '';
|
|
||||||
do {
|
|
||||||
$buffer = fread($urandomFile, $length);
|
|
||||||
if (!$buffer) {
|
|
||||||
$key = null;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
$key .= $buffer;
|
|
||||||
} while (StringHelper::byteLength($key) < $length);
|
|
||||||
|
|
||||||
if ($key !== null && StringHelper::byteLength($key) === $length) {
|
return $key;
|
||||||
$this->_randomSource = $urandomFile;
|
|
||||||
|
|
||||||
return $key;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->_randomSource = null;
|
$this->_randomSource = null;
|
||||||
@ -542,7 +520,7 @@ class Security extends Component
|
|||||||
|
|
||||||
// Since 5.4.0, openssl_random_pseudo_bytes() reads from CryptGenRandom on Windows instead
|
// Since 5.4.0, openssl_random_pseudo_bytes() reads from CryptGenRandom on Windows instead
|
||||||
// of using OpenSSL library. Don't use OpenSSL on other platforms.
|
// of using OpenSSL library. Don't use OpenSSL on other platforms.
|
||||||
if ($this->_randomSource === 'OpenSSL'
|
if ($this->_randomSource === self::SOURCE_OPEN_SSL
|
||||||
|| (DIRECTORY_SEPARATOR !== '/' && PHP_VERSION_ID >= 50400)
|
|| (DIRECTORY_SEPARATOR !== '/' && PHP_VERSION_ID >= 50400)
|
||||||
) {
|
) {
|
||||||
$key = openssl_random_pseudo_bytes($length, $cryptoStrong);
|
$key = openssl_random_pseudo_bytes($length, $cryptoStrong);
|
||||||
@ -552,7 +530,7 @@ class Security extends Component
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
if ($key !== false && StringHelper::byteLength($key) === $length) {
|
if ($key !== false && StringHelper::byteLength($key) === $length) {
|
||||||
$this->_randomSource = 'OpenSSL';
|
$this->_randomSource = self::SOURCE_OPEN_SSL;
|
||||||
|
|
||||||
return $key;
|
return $key;
|
||||||
}
|
}
|
||||||
|
@ -810,6 +810,28 @@ TEXT;
|
|||||||
$this->assertTrue($key1 != $key2);
|
$this->assertTrue($key1 != $key2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testGenerateRandomKeyURandom()
|
||||||
|
{
|
||||||
|
if (function_exists('random_bytes')) {
|
||||||
|
$this->markTestSkipped('This test can only work on platforms where random_bytes() function does not exist. You may disable it in php.ini for testing. http://php.net/manual/en/ini.core.php#ini.disable-functions');
|
||||||
|
}
|
||||||
|
if (PHP_VERSION_ID >= 50307 && function_exists('mcrypt_create_iv')) {
|
||||||
|
$this->markTestSkipped('This test can only work on platforms where mcrypt_create_iv() function does not exist. You may disable it in php.ini for testing. http://php.net/manual/en/ini.core.php#ini.disable-functions');
|
||||||
|
}
|
||||||
|
if (!@is_readable('/dev/urandom')) {
|
||||||
|
$this->markTestSkipped('/dev/urandom does not seem to exist on your system.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$length = 1024 * 1024;
|
||||||
|
$key1 = $this->security->generateRandomKey($length);
|
||||||
|
$this->assertInternalType('string', $key1);
|
||||||
|
$this->assertEquals($length, strlen($key1));
|
||||||
|
$key2 = $this->security->generateRandomKey($length);
|
||||||
|
$this->assertInternalType('string', $key2);
|
||||||
|
$this->assertEquals($length, strlen($key2));
|
||||||
|
$this->assertTrue($key1 != $key2);
|
||||||
|
}
|
||||||
|
|
||||||
public function testGenerateRandomString()
|
public function testGenerateRandomString()
|
||||||
{
|
{
|
||||||
$length = 21;
|
$length = 21;
|
||||||
|
Reference in New Issue
Block a user