1 <?php |
1 <?php |
2 /** |
2 /** |
3 * Random_* Compatibility Library |
3 * Random_* Compatibility Library |
4 * for using the new PHP 7 random_* API in PHP 5 projects |
4 * for using the new PHP 7 random_* API in PHP 5 projects |
5 * |
5 * |
6 * @version 2.0.10 |
6 * @version 2.0.17 |
7 * @released 2017-03-13 |
7 * @released 2018-07-04 |
8 * |
8 * |
9 * The MIT License (MIT) |
9 * The MIT License (MIT) |
10 * |
10 * |
11 * Copyright (c) 2015 - 2017 Paragon Initiative Enterprises |
11 * Copyright (c) 2015 - 2018 Paragon Initiative Enterprises |
12 * |
12 * |
13 * Permission is hereby granted, free of charge, to any person obtaining a copy |
13 * Permission is hereby granted, free of charge, to any person obtaining a copy |
14 * of this software and associated documentation files (the "Software"), to deal |
14 * of this software and associated documentation files (the "Software"), to deal |
15 * in the Software without restriction, including without limitation the rights |
15 * in the Software without restriction, including without limitation the rights |
16 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
16 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
52 define('RANDOM_COMPAT_READ_BUFFER', 8); |
52 define('RANDOM_COMPAT_READ_BUFFER', 8); |
53 } |
53 } |
54 |
54 |
55 $RandomCompatDIR = dirname(__FILE__); |
55 $RandomCompatDIR = dirname(__FILE__); |
56 |
56 |
57 require_once $RandomCompatDIR . '/byte_safe_strings.php'; |
57 require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'byte_safe_strings.php'; |
58 require_once $RandomCompatDIR . '/cast_to_int.php'; |
58 require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'cast_to_int.php'; |
59 require_once $RandomCompatDIR . '/error_polyfill.php'; |
59 require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'error_polyfill.php'; |
60 |
60 |
61 if (!is_callable('random_bytes')) { |
61 if (!is_callable('random_bytes')) { |
62 /** |
62 /** |
63 * PHP 5.2.0 - 5.6.x way to implement random_bytes() |
63 * PHP 5.2.0 - 5.6.x way to implement random_bytes() |
64 * |
64 * |
74 * See RATIONALE.md for our reasoning behind this particular order |
74 * See RATIONALE.md for our reasoning behind this particular order |
75 */ |
75 */ |
76 if (extension_loaded('libsodium')) { |
76 if (extension_loaded('libsodium')) { |
77 // See random_bytes_libsodium.php |
77 // See random_bytes_libsodium.php |
78 if (PHP_VERSION_ID >= 50300 && is_callable('\\Sodium\\randombytes_buf')) { |
78 if (PHP_VERSION_ID >= 50300 && is_callable('\\Sodium\\randombytes_buf')) { |
79 require_once $RandomCompatDIR . '/random_bytes_libsodium.php'; |
79 require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'random_bytes_libsodium.php'; |
80 } elseif (method_exists('Sodium', 'randombytes_buf')) { |
80 } elseif (method_exists('Sodium', 'randombytes_buf')) { |
81 require_once $RandomCompatDIR . '/random_bytes_libsodium_legacy.php'; |
81 require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'random_bytes_libsodium_legacy.php'; |
82 } |
82 } |
83 } |
83 } |
84 |
84 |
85 /** |
85 /** |
86 * Reading directly from /dev/urandom: |
86 * Reading directly from /dev/urandom: |
115 // can read it at this point. If the PHP environment is going to |
115 // can read it at this point. If the PHP environment is going to |
116 // panic over trying to see if the file can be read in the first |
116 // panic over trying to see if the file can be read in the first |
117 // place, that is not helpful to us here. |
117 // place, that is not helpful to us here. |
118 |
118 |
119 // See random_bytes_dev_urandom.php |
119 // See random_bytes_dev_urandom.php |
120 require_once $RandomCompatDIR . '/random_bytes_dev_urandom.php'; |
120 require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'random_bytes_dev_urandom.php'; |
121 } |
121 } |
122 // Unset variables after use |
122 // Unset variables after use |
123 $RandomCompat_basedir = null; |
123 $RandomCompat_basedir = null; |
124 } else { |
124 } else { |
125 $RandomCompatUrandom = false; |
125 $RandomCompatUrandom = false; |
157 ) |
157 ) |
158 && |
158 && |
159 extension_loaded('mcrypt') |
159 extension_loaded('mcrypt') |
160 ) { |
160 ) { |
161 // See random_bytes_mcrypt.php |
161 // See random_bytes_mcrypt.php |
162 require_once $RandomCompatDIR . '/random_bytes_mcrypt.php'; |
162 require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'random_bytes_mcrypt.php'; |
163 } |
163 } |
164 $RandomCompatUrandom = null; |
164 $RandomCompatUrandom = null; |
165 |
165 |
166 /** |
166 /** |
167 * This is a Windows-specific fallback, for when the mcrypt extension |
167 * This is a Windows-specific fallback, for when the mcrypt extension |
180 ); |
180 ); |
181 |
181 |
182 if (!in_array('com', $RandomCompat_disabled_classes)) { |
182 if (!in_array('com', $RandomCompat_disabled_classes)) { |
183 try { |
183 try { |
184 $RandomCompatCOMtest = new COM('CAPICOM.Utilities.1'); |
184 $RandomCompatCOMtest = new COM('CAPICOM.Utilities.1'); |
185 if (method_exists($RandomCompatCOMtest, 'GetRandom')) { |
185 /** @psalm-suppress TypeDoesNotContainType */ |
|
186 if (is_callable(array($RandomCompatCOMtest, 'GetRandom'))) { |
186 // See random_bytes_com_dotnet.php |
187 // See random_bytes_com_dotnet.php |
187 require_once $RandomCompatDIR . '/random_bytes_com_dotnet.php'; |
188 require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'random_bytes_com_dotnet.php'; |
188 } |
189 } |
189 } catch (com_exception $e) { |
190 } catch (com_exception $e) { |
190 // Don't try to use it. |
191 // Don't try to use it. |
191 } |
192 } |
192 } |
193 } |
201 /** |
202 /** |
202 * We don't have any more options, so let's throw an exception right now |
203 * We don't have any more options, so let's throw an exception right now |
203 * and hope the developer won't let it fail silently. |
204 * and hope the developer won't let it fail silently. |
204 * |
205 * |
205 * @param mixed $length |
206 * @param mixed $length |
206 * @return void |
207 * @psalm-suppress InvalidReturnType |
207 * @throws Exception |
208 * @throws Exception |
|
209 * @return string |
208 */ |
210 */ |
209 function random_bytes($length) |
211 function random_bytes($length) |
210 { |
212 { |
211 unset($length); // Suppress "variable not used" warnings. |
213 unset($length); // Suppress "variable not used" warnings. |
212 throw new Exception( |
214 throw new Exception( |
213 'There is no suitable CSPRNG installed on your system' |
215 'There is no suitable CSPRNG installed on your system' |
214 ); |
216 ); |
|
217 return ''; |
215 } |
218 } |
216 } |
219 } |
217 } |
220 } |
218 |
221 |
219 if (!is_callable('random_int')) { |
222 if (!is_callable('random_int')) { |
220 require_once $RandomCompatDIR . '/random_int.php'; |
223 require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'random_int.php'; |
221 } |
224 } |
222 |
225 |
223 $RandomCompatDIR = null; |
226 $RandomCompatDIR = null; |