Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
91.49% |
43 / 47 |
|
80.00% |
4 / 5 |
CRAP | |
0.00% |
0 / 1 |
| helper | |
91.49% |
43 / 47 |
|
80.00% |
4 / 5 |
20.25 | |
0.00% |
0 / 1 |
| __construct | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| hash_encode64 | |
100.00% |
17 / 17 |
|
100.00% |
1 / 1 |
5 | |||
| unique_id | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
3 | |||
| get_random_salt | |
100.00% |
12 / 12 |
|
100.00% |
1 / 1 |
4 | |||
| string_compare | |
50.00% |
4 / 8 |
|
0.00% |
0 / 1 |
13.12 | |||
| 1 | <?php |
| 2 | /** |
| 3 | * |
| 4 | * This file is part of the phpBB Forum Software package. |
| 5 | * |
| 6 | * @copyright (c) phpBB Limited <https://www.phpbb.com> |
| 7 | * @license GNU General Public License, version 2 (GPL-2.0) |
| 8 | * |
| 9 | * For full copyright and license information, please see |
| 10 | * the docs/CREDITS.txt file. |
| 11 | * |
| 12 | */ |
| 13 | |
| 14 | namespace phpbb\passwords\driver; |
| 15 | |
| 16 | class helper |
| 17 | { |
| 18 | /** |
| 19 | * @var \phpbb\config\config |
| 20 | */ |
| 21 | protected $config; |
| 22 | |
| 23 | /** |
| 24 | * base64 alphabet |
| 25 | * @var string |
| 26 | */ |
| 27 | public $itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; |
| 28 | |
| 29 | /** |
| 30 | * Construct a driver helper object |
| 31 | * |
| 32 | * @param \phpbb\config\config $config phpBB configuration |
| 33 | */ |
| 34 | public function __construct(\phpbb\config\config $config) |
| 35 | { |
| 36 | $this->config = $config; |
| 37 | } |
| 38 | |
| 39 | /** |
| 40 | * Base64 encode hash |
| 41 | * |
| 42 | * @param string $input Input string |
| 43 | * @param int $count Input string length |
| 44 | * |
| 45 | * @return string base64 encoded string |
| 46 | */ |
| 47 | public function hash_encode64($input, $count) |
| 48 | { |
| 49 | $output = ''; |
| 50 | $i = 0; |
| 51 | |
| 52 | do |
| 53 | { |
| 54 | $value = ord($input[$i++]); |
| 55 | $output .= $this->itoa64[$value & 0x3f]; |
| 56 | |
| 57 | if ($i < $count) |
| 58 | { |
| 59 | $value |= ord($input[$i]) << 8; |
| 60 | } |
| 61 | |
| 62 | $output .= $this->itoa64[($value >> 6) & 0x3f]; |
| 63 | |
| 64 | if ($i++ >= $count) |
| 65 | { |
| 66 | break; |
| 67 | } |
| 68 | |
| 69 | if ($i < $count) |
| 70 | { |
| 71 | $value |= ord($input[$i]) << 16; |
| 72 | } |
| 73 | |
| 74 | $output .= $this->itoa64[($value >> 12) & 0x3f]; |
| 75 | |
| 76 | if ($i++ >= $count) |
| 77 | { |
| 78 | break; |
| 79 | } |
| 80 | |
| 81 | $output .= $this->itoa64[($value >> 18) & 0x3f]; |
| 82 | } |
| 83 | while ($i < $count); |
| 84 | |
| 85 | return $output; |
| 86 | } |
| 87 | |
| 88 | /** |
| 89 | * Return unique id |
| 90 | * |
| 91 | * @param string $extra Additional entropy |
| 92 | * |
| 93 | * @return string Unique id |
| 94 | */ |
| 95 | public function unique_id($extra = 'c') |
| 96 | { |
| 97 | static $dss_seeded = false; |
| 98 | |
| 99 | $val = $this->config['rand_seed'] . microtime(); |
| 100 | $val = md5($val); |
| 101 | $this->config['rand_seed'] = md5($this->config['rand_seed'] . $val . $extra); |
| 102 | |
| 103 | if ($dss_seeded !== true && ($this->config['rand_seed_last_update'] < time() - rand(1,10))) |
| 104 | { |
| 105 | $this->config->set('rand_seed_last_update', time()); |
| 106 | $this->config->set('rand_seed', $this->config['rand_seed']); |
| 107 | $dss_seeded = true; |
| 108 | } |
| 109 | |
| 110 | return substr($val, 4, 16); |
| 111 | } |
| 112 | |
| 113 | /** |
| 114 | * Get random salt with specified length |
| 115 | * |
| 116 | * @param int $length Salt length |
| 117 | * @param string $rand_seed Seed for random data (optional). For tests. |
| 118 | * |
| 119 | * @return string Random salt with specified length |
| 120 | */ |
| 121 | public function get_random_salt($length, $rand_seed = '/dev/urandom') |
| 122 | { |
| 123 | $random = ''; |
| 124 | |
| 125 | if (($fh = @fopen($rand_seed, 'rb'))) |
| 126 | { |
| 127 | $random = fread($fh, $length); |
| 128 | fclose($fh); |
| 129 | } |
| 130 | |
| 131 | if (strlen($random) < $length) |
| 132 | { |
| 133 | $random = ''; |
| 134 | $random_state = $this->unique_id(); |
| 135 | |
| 136 | for ($i = 0; $i < $length; $i += 16) |
| 137 | { |
| 138 | $random_state = md5($this->unique_id() . $random_state); |
| 139 | $random .= pack('H*', md5($random_state)); |
| 140 | } |
| 141 | $random = substr($random, 0, $length); |
| 142 | } |
| 143 | /** |
| 144 | * @psalm-suppress FalsableReturnStatement |
| 145 | */ |
| 146 | return $random; |
| 147 | } |
| 148 | |
| 149 | /** |
| 150 | * Compare two strings byte by byte |
| 151 | * |
| 152 | * @param string $string_a The first string |
| 153 | * @param string $string_b The second string |
| 154 | * |
| 155 | * @return bool True if strings are the same, false if not |
| 156 | */ |
| 157 | public function string_compare($string_a, $string_b) |
| 158 | { |
| 159 | // Return if input variables are not strings or if length does not match |
| 160 | if (!is_string($string_a) || !is_string($string_b) || strlen($string_a) != strlen($string_b)) |
| 161 | { |
| 162 | return false; |
| 163 | } |
| 164 | |
| 165 | // Use hash_equals() if it's available |
| 166 | if (function_exists('hash_equals')) |
| 167 | { |
| 168 | return hash_equals($string_a, $string_b); |
| 169 | } |
| 170 | |
| 171 | $difference = 0; |
| 172 | |
| 173 | for ($i = 0; $i < strlen($string_a) && $i < strlen($string_b); $i++) |
| 174 | { |
| 175 | $difference |= ord($string_a[$i]) ^ ord($string_b[$i]); |
| 176 | } |
| 177 | |
| 178 | return $difference === 0; |
| 179 | } |
| 180 | } |