Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
91.49% covered (success)
91.49%
43 / 47
80.00% covered (warning)
80.00%
4 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
helper
91.49% covered (success)
91.49%
43 / 47
80.00% covered (warning)
80.00%
4 / 5
20.25
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hash_encode64
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
1 / 1
5
 unique_id
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
3
 get_random_salt
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
4
 string_compare
50.00% covered (danger)
50.00%
4 / 8
0.00% covered (danger)
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
14namespace phpbb\passwords\driver;
15
16class 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        return $random;
144    }
145
146    /**
147     * Compare two strings byte by byte
148     *
149     * @param string $string_a The first string
150     * @param string $string_b The second string
151     *
152     * @return bool True if strings are the same, false if not
153     */
154    public function string_compare($string_a, $string_b)
155    {
156        // Return if input variables are not strings or if length does not match
157        if (!is_string($string_a) || !is_string($string_b) || strlen($string_a) != strlen($string_b))
158        {
159            return false;
160        }
161
162        // Use hash_equals() if it's available
163        if (function_exists('hash_equals'))
164        {
165            return hash_equals($string_a, $string_b);
166        }
167
168        $difference = 0;
169
170        for ($i = 0; $i < strlen($string_a) && $i < strlen($string_b); $i++)
171        {
172            $difference |= ord($string_a[$i]) ^ ord($string_b[$i]);
173        }
174
175        return $difference === 0;
176    }
177}