Browse Source

Fix #17999: Fix skipping test case on PHP v >= 7.1 and LibreSSL version >= 2.15

tags/2.0.36
Deryabin Sergey 4 years ago committed by GitHub
parent
commit
7eb184eadb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 48
      framework/base/Security.php
  2. 8
      tests/framework/base/ExposedSecurity.php
  3. 15
      tests/framework/base/SecurityTest.php

48
framework/base/Security.php

@ -90,7 +90,38 @@ class Security extends Component
* @since 2.0.6
*/
public $passwordHashCost = 13;
/**
* @var boolean if LibreSSL should be used.
* The recent (> 2.1.5) LibreSSL RNGs are faster and likely better than /dev/urandom.
*/
private $_useLibreSSL;
/**
* @return boolean if LibreSSL should be used
* Use version is 2.1.5 or higher.
* @since 2.0.36
*/
protected function shouldUseLibreSSL()
{
if ($this->_useLibreSSL === null) {
// Parse OPENSSL_VERSION_TEXT because OPENSSL_VERSION_NUMBER is no use for LibreSSL.
// https://bugs.php.net/bug.php?id=71143
$this->_useLibreSSL = defined('OPENSSL_VERSION_TEXT')
&& preg_match('{^LibreSSL (\d\d?)\.(\d\d?)\.(\d\d?)$}', OPENSSL_VERSION_TEXT, $matches)
&& (10000 * $matches[1]) + (100 * $matches[2]) + $matches[3] >= 20105;
}
return $this->_useLibreSSL;
}
/**
* @return bool if operating system is Windows
*/
private function isWindows()
{
return DIRECTORY_SEPARATOR !== '/';
}
/**
* Encrypts data using a password.
@ -439,7 +470,6 @@ class Security extends Component
return false;
}
private $_useLibreSSL;
private $_randomFile;
/**
@ -468,22 +498,10 @@ class Security extends Component
}
// The recent LibreSSL RNGs are faster and likely better than /dev/urandom.
// Parse OPENSSL_VERSION_TEXT because OPENSSL_VERSION_NUMBER is no use for LibreSSL.
// https://bugs.php.net/bug.php?id=71143
if ($this->_useLibreSSL === null) {
$this->_useLibreSSL = defined('OPENSSL_VERSION_TEXT')
&& preg_match('{^LibreSSL (\d\d?)\.(\d\d?)\.(\d\d?)$}', OPENSSL_VERSION_TEXT, $matches)
&& (10000 * $matches[1]) + (100 * $matches[2]) + $matches[3] >= 20105;
}
// Since 5.4.0, openssl_random_pseudo_bytes() reads from CryptGenRandom on Windows instead
// of using OpenSSL library. LibreSSL is OK everywhere but don't use OpenSSL on non-Windows.
if (function_exists('openssl_random_pseudo_bytes')
&& ($this->_useLibreSSL
|| (
DIRECTORY_SEPARATOR !== '/'
&& substr_compare(PHP_OS, 'win', 0, 3, true) === 0
))
&& ($this->shouldUseLibreSSL() || $this->isWindows())
) {
$key = openssl_random_pseudo_bytes($length, $cryptoStrong);
if ($cryptoStrong === false) {
@ -506,7 +524,7 @@ class Security extends Component
}
// If not on Windows, try to open a random device.
if ($this->_randomFile === null && DIRECTORY_SEPARATOR === '/') {
if ($this->_randomFile === null && !$this->isWindows()) {
// urandom is a symlink to random on FreeBSD.
$device = PHP_OS === 'FreeBSD' ? '/dev/random' : '/dev/urandom';
// Check random device for special character device protection mode. Use lstat()

8
tests/framework/base/ExposedSecurity.php

@ -29,4 +29,12 @@ class ExposedSecurity extends Security
{
return parent::pbkdf2($algo, $password, $salt, $iterations, $length);
}
/**
* {@inheritdoc}
*/
public function shouldUseLibreSSL()
{
return parent::shouldUseLibreSSL();
}
}

15
tests/framework/base/SecurityTest.php

@ -96,6 +96,11 @@ class SecurityTest extends TestCase
parent::tearDown();
}
private function isWindows()
{
return DIRECTORY_SEPARATOR !== '/';
}
// Tests :
public function testHashData()
@ -943,13 +948,17 @@ TEXT;
}
}
// there is no /dev/urandom on windows so we expect this to fail
if (DIRECTORY_SEPARATOR === '\\' && $functions['random_bytes'] === false && $functions['openssl_random_pseudo_bytes'] === false && $functions['mcrypt_create_iv'] === false) {
if ($this->isWindows() && $functions['random_bytes'] === false && $functions['openssl_random_pseudo_bytes'] === false && $functions['mcrypt_create_iv'] === false) {
$this->expectException('yii\base\Exception');
$this->expectExceptionMessage('Unable to generate a random key');
}
// Function mcrypt_create_iv() is deprecated since PHP 7.1
if (version_compare(PHP_VERSION, '7.1.0alpha', '>=') && $functions['random_bytes'] === false && $functions['mcrypt_create_iv'] === true) {
$this->markTestSkipped('Function mcrypt_create_iv() is deprecated as of PHP 7.1');
if ($functions['openssl_random_pseudo_bytes'] === false) {
$this->markTestSkipped('Function mcrypt_create_iv() is deprecated as of PHP 7.1');
} elseif (!$this->security->getUseLibreSSL() && !$this->isWindows()) {
$this->markTestSkipped('Function openssl_random_pseudo_bytes need LibreSSL version >=2.1.5 or Windows system on server');
}
}
static::$functions = $functions;
@ -1013,7 +1022,7 @@ TEXT;
'DIRECTORY_SEPARATOR',
"ini_get('open_basedir')",
];
if (DIRECTORY_SEPARATOR === '/') {
if ($this->isWindows()) {
$tests[] = "sprintf('%o', lstat(PHP_OS === 'FreeBSD' ? '/dev/random' : '/dev/urandom')['mode'] & 0170000)";
$tests[] = "bin2hex(file_get_contents(PHP_OS === 'FreeBSD' ? '/dev/random' : '/dev/urandom', false, null, 0, 8))";
}

Loading…
Cancel
Save