Skip to content

Commit

Permalink
If we're rocking PHP 7, this library should be a NOP
Browse files Browse the repository at this point in the history
  • Loading branch information
paragonie-scott committed Sep 7, 2015
1 parent 59e7857 commit 90da7f3
Show file tree
Hide file tree
Showing 6 changed files with 72,852 additions and 52 deletions.
12 changes: 6 additions & 6 deletions ERRATA.md
Expand Up @@ -9,9 +9,8 @@ The order is:
3. `COM('CAPICOM.Utilities.1')->GetRandom()`
4. `openssl_random_pseudo_bytes()`

We read `/dev/urandom` first (if it exists).
This is the preferred file to read for random data for cryptographic
purposes for BSD and Linux.
We read `/dev/urandom` first (if it exists). This is the preferred file to read
for random data for cryptographic purposes for BSD and Linux.

Despite [strongly urging people not to use mcrypt in their projects](https://paragonie.com/blog/2015/05/if-you-re-typing-word-mcrypt-into-your-code-you-re-doing-it-wrong),
because libmcrypt is abandonware and the API puts too much responsibility on the
Expand All @@ -28,8 +27,9 @@ and is not part `libmcrypt`. It actually does the right thing:

If we're on Windows and don't have access to `mcrypt`, we use `CAPICOM.Utilities.1`.

Finally, we use `openssl_random_pseudo_bytes()` **as a last resort**. Internally,
this function calls `RAND_pseudo_bytes()`, which has been [deprecated](https://github.com/paragonie/random_compat/issues/5)
Finally, we use `openssl_random_pseudo_bytes()` **as a last resort**, due to
[PHP bug #70014](https://bugs.php.net/bug.php?id=70014). Internally, this
function calls `RAND_pseudo_bytes()`, which has been [deprecated](https://github.com/paragonie/random_compat/issues/5)
by the OpenSSL team. Furthermore, [it might silently return weak random data](https://github.com/paragonie/random_compat/issues/6#issuecomment-119564973)
if it is called before OpenSSL's **userspace** CSPRNG is seeded. Also,
[you want the OS CSPRNG, not a userspace CSPRNG](http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers/).
[you want the OS CSPRNG, not a userspace CSPRNG](http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers/).
8 changes: 8 additions & 0 deletions lib/error_polyfill.php
Expand Up @@ -30,10 +30,18 @@
interface Throwable
{
public function getMessage();
public function getCode();
public function getFile();
public function getLine();
public function getTrace();
public function getTraceAsString();
public function getPrevious();
public function __toString();
}
}

if (!class_exists('Error', false)) {
// We can't really avoid making this extend Exception in PHP 5.
class Error extends Exception implements Throwable
{

Expand Down
88 changes: 44 additions & 44 deletions lib/random.php
Expand Up @@ -26,55 +26,55 @@
* SOFTWARE.
*/

if (!defined('RANDOM_COMPAT_READ_BUFFER')) {
define('RANDOM_COMPAT_READ_BUFFER', 8);
}
if (!defined('PHP_VERSION_ID')) {
// This constant was introduced in PHP 5.2.7
$version = explode('.', PHP_VERSION);
define('PHP_VERSION_ID', ($version[0] * 10000 + $version[1] * 100 + $version[2]));
}

require_once "error_polyfill.php";
require_once "byte_safe_strings.php";

if (!function_exists('random_bytes')) {
/**
* PHP 5.2.0 - 5.6.x way to implement random_bytes()
*
* We use conditional statements here to define the function in accordance
* to the operating environment. It's a micro-optimization.
*
* In order of preference:
* 1. fread() /dev/urandom if available
* 2. mcrypt_create_iv($bytes, MCRYPT_CREATE_IV)
* 3. COM('CAPICOM.Utilities.1')->GetRandom()
* 4. openssl_random_pseudo_bytes()
*
* See ERRATA.md for our reasoning behind this particular order
*/
if (!ini_get('open_basedir') && is_readable('/dev/urandom')) {
// See random_bytes_dev_urandom.php
require_once "random_bytes_dev_urandom.php";
} elseif (PHP_VERSION_ID >= 50307 && function_exists('mcrypt_create_iv')) {
// See random_bytes_mcrypt.php
require_once "random_bytes_mcrypt.php";
} elseif (extension_loaded('com_dotnet')) {
// See random_bytes_com_dotnet.php
require_once "random_bytes_com_dotnet.php";
} elseif (function_exists('openssl_random_pseudo_bytes')) {
// See random_bytes_openssl.php
require_once "random_bytes_openssl.php";
} else {
if (PHP_VERSION_ID < 70000) {
if (!defined('RANDOM_COMPAT_READ_BUFFER')) {
define('RANDOM_COMPAT_READ_BUFFER', 8);
}
require_once "byte_safe_strings.php";
require_once "error_polyfill.php";
if (!function_exists('random_bytes')) {
/**
* We don't have any more options, so let's throw an exception right now
* and hope the developer won't let it fail silently.
* PHP 5.2.0 - 5.6.x way to implement random_bytes()
*
* We use conditional statements here to define the function in accordance
* to the operating environment. It's a micro-optimization.
*
* In order of preference:
* 1. fread() /dev/urandom if available
* 2. mcrypt_create_iv($bytes, MCRYPT_CREATE_IV)
* 3. COM('CAPICOM.Utilities.1')->GetRandom()
* 4. openssl_random_pseudo_bytes()
*
* See ERRATA.md for our reasoning behind this particular order
*/
throw new Exception(
'There is no suitable CSPRNG installed on your system'
);
if (!ini_get('open_basedir') && is_readable('/dev/urandom')) {
// See random_bytes_dev_urandom.php
require_once "random_bytes_dev_urandom.php";
} elseif (PHP_VERSION_ID >= 50307 && function_exists('mcrypt_create_iv')) {
// See random_bytes_mcrypt.php
require_once "random_bytes_mcrypt.php";
} elseif (extension_loaded('com_dotnet')) {
// See random_bytes_com_dotnet.php
require_once "random_bytes_com_dotnet.php";
} elseif (function_exists('openssl_random_pseudo_bytes')) {
// See random_bytes_openssl.php
require_once "random_bytes_openssl.php";
} else {
/**
* We don't have any more options, so let's throw an exception right now
* and hope the developer won't let it fail silently.
*/
throw new Exception(
'There is no suitable CSPRNG installed on your system'
);
}
}
if (!function_exists('random_int')) {
require_once "random_int.php";
}
}
if (!function_exists('random_int')) {
require_once "random_int.php";
}

0 comments on commit 90da7f3

Please sign in to comment.