Passed
Push — master ( c0a3a7...3b84a4 )
by Jeroen
58:51
created

engine/classes/ElggCrypto.php (1 issue)

Checks if the types of the passed arguments in a function/method call are compatible.

Bug Minor
1
<?php
2
3
/**
4
 * Cryptographic services
5
 *
6
 * @access private
7
 */
8
class ElggCrypto {
9
10
	/**
11
	 * Character set for temp passwords (no risk of embedded profanity/glyphs that look similar)
12
	 */
13
	const CHARS_PASSWORD = 'bcdfghjklmnpqrstvwxyz2346789';
14
15
	/**
16
	 * Character set for hexadecimal
17
	 */
18
	const CHARS_HEX = '0123456789abcdef';
19
20
	/**
21
	 * Generate a random string of specified length.
22
	 *
23
	 * Uses supplied character list for generating the new string.
24
	 * If no character list provided - uses Base64 URL character set.
25
	 *
26
	 * @param int         $length Desired length of the string
27
	 * @param string|null $chars  Characters to be chosen from randomly. If not given, the Base64 URL
28
	 *                            charset will be used.
29
	 *
30
	 * @return string The random string
31
	 *
32
	 * @throws InvalidArgumentException
33
	 *
34
	 * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
35
	 * @license   http://framework.zend.com/license/new-bsd New BSD License
36
	 *
37
	 * @see https://github.com/zendframework/zf2/blob/master/library/Zend/Math/Rand.php#L179
38
	 */
39 4598
	public function getRandomString($length, $chars = null) {
40 4598
		if ($length < 1) {
41
			throw new \InvalidArgumentException('Length should be >= 1');
42
		}
43
44 4598
		if (empty($chars)) {
45 4459
			$numBytes = ceil($length * 0.75);
46 4459
			$bytes    = random_bytes($numBytes);
0 ignored issues
show
$numBytes of type double is incompatible with the type integer expected by parameter $length of random_bytes(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

46
			$bytes    = random_bytes(/** @scrutinizer ignore-type */ $numBytes);
Loading history...
47 4459
			$string = substr(rtrim(base64_encode($bytes), '='), 0, $length);
48
49
			// Base64 URL
50 4459
			return strtr($string, '+/', '-_');
51
		}
52
53 154
		if ($chars == self::CHARS_HEX) {
54
			// hex is easy
55
			$bytes = random_bytes(ceil($length / 2));
56
			return substr(bin2hex($bytes), 0, $length);
57
		}
58
59 154
		$listLen = strlen($chars);
60
61 154
		if ($listLen == 1) {
62
			return str_repeat($chars, $length);
63
		}
64
65 154
		$bytes  = random_bytes($length);
66 154
		$pos    = 0;
67 154
		$result = '';
68 154
		for ($i = 0; $i < $length; $i++) {
69 154
			$pos     = ($pos + ord($bytes[$i])) % $listLen;
70 154
			$result .= $chars[$pos];
71
		}
72
73 154
		return $result;
74
	}
75
76
	/**
77
	 * Are two strings equal (compared in constant time)?
78
	 *
79
	 * @param string $str1 First string to compare
80
	 * @param string $str2 Second string to compare
81
	 *
82
	 * @return bool
83
	 *
84
	 * Based on password_verify in PasswordCompat
85
	 * @author Anthony Ferrara <[email protected]>
86
	 * @license http://www.opensource.org/licenses/mit-license.html MIT License
87
	 * @copyright 2012 The Authors
88
	 */
89 81
	public function areEqual($str1, $str2) {
90 81
		$len1 = $this->strlen($str1);
91 81
		$len2 = $this->strlen($str2);
92 81
		if ($len1 !== $len2) {
93 2
			return false;
94
		}
95
96 80
		$status = 0;
97 80
		for ($i = 0; $i < $len1; $i++) {
98 80
			$status |= (ord($str1[$i]) ^ ord($str2[$i]));
99
		}
100
101 80
		return $status === 0;
102
	}
103
104
	/**
105
	 * Count the number of bytes in a string
106
	 *
107
	 * We cannot simply use strlen() for this, because it might be overwritten by the mbstring extension.
108
	 * In this case, strlen() will count the number of *characters* based on the internal encoding. A
109
	 * sequence of bytes might be regarded as a single multibyte character.
110
	 *
111
	 * Use elgg_strlen() to count UTF-characters instead of bytes.
112
	 *
113
	 * @param string $binary_string The input string
114
	 *
115
	 * @return int The number of bytes
116
	 *
117
	 * From PasswordCompat\binary\_strlen
118
	 * @author Anthony Ferrara <[email protected]>
119
	 * @license http://www.opensource.org/licenses/mit-license.html MIT License
120
	 * @copyright 2012 The Authors
121
	 */
122 81
	protected function strlen($binary_string) {
123 81
		if (function_exists('mb_strlen')) {
124 81
			return mb_strlen($binary_string, '8bit');
125
		}
126
		return strlen($binary_string);
127
	}
128
}
129