1: <?php
2:
3: /**
4: * CryptUtil: A suite of wrapper utility functions for the OpenID
5: * library.
6: *
7: * PHP versions 4 and 5
8: *
9: * LICENSE: See the COPYING file included in this distribution.
10: *
11: * @access private
12: * @package OpenID
13: * @author JanRain, Inc. <openid@janrain.com>
14: * @copyright 2005-2008 Janrain, Inc.
15: * @license http://www.apache.org/licenses/LICENSE-2.0 Apache
16: */
17:
18: if (!defined('Auth_OpenID_RAND_SOURCE')) {
19: /**
20: * The filename for a source of random bytes. Define this yourself
21: * if you have a different source of randomness.
22: */
23: define('Auth_OpenID_RAND_SOURCE', '/dev/urandom');
24: }
25:
26: class Auth_OpenID_CryptUtil {
27: /**
28: * Get the specified number of random bytes.
29: *
30: * Attempts to use a cryptographically secure (not predictable)
31: * source of randomness if available. If there is no high-entropy
32: * randomness source available, it will fail. As a last resort,
33: * for non-critical systems, define
34: * <code>Auth_OpenID_RAND_SOURCE</code> as <code>null</code>, and
35: * the code will fall back on a pseudo-random number generator.
36: *
37: * @param int $num_bytes The length of the return value
38: * @return string $bytes random bytes
39: */
40: static function getBytes($num_bytes)
41: {
42: static $f = null;
43: $bytes = '';
44: if ($f === null) {
45: if (Auth_OpenID_RAND_SOURCE === null) {
46: $f = false;
47: } else {
48: $f = @fopen(Auth_OpenID_RAND_SOURCE, "r");
49: if ($f === false) {
50: $msg = 'Define Auth_OpenID_RAND_SOURCE as null to ' .
51: ' continue with an insecure random number generator.';
52: trigger_error($msg, E_USER_ERROR);
53: }
54: }
55: }
56: if ($f === false) {
57: // pseudorandom used
58: $bytes = '';
59: for ($i = 0; $i < $num_bytes; $i += 4) {
60: $bytes .= pack('L', mt_rand());
61: }
62: $bytes = substr($bytes, 0, $num_bytes);
63: } else {
64: $bytes = fread($f, $num_bytes);
65: }
66: return $bytes;
67: }
68:
69: /**
70: * Produce a string of length random bytes, chosen from chrs. If
71: * $chrs is null, the resulting string may contain any characters.
72: *
73: * @param integer $length The length of the resulting
74: * randomly-generated string
75: * @param string $chrs A string of characters from which to choose
76: * to build the new string
77: * @return string $result A string of randomly-chosen characters
78: * from $chrs
79: */
80: static function randomString($length, $population = null)
81: {
82: if ($population === null) {
83: return Auth_OpenID_CryptUtil::getBytes($length);
84: }
85:
86: $popsize = strlen($population);
87:
88: if ($popsize > 256) {
89: $msg = 'More than 256 characters supplied to ' . __FUNCTION__;
90: trigger_error($msg, E_USER_ERROR);
91: }
92:
93: $duplicate = 256 % $popsize;
94:
95: $str = "";
96: for ($i = 0; $i < $length; $i++) {
97: do {
98: $n = ord(Auth_OpenID_CryptUtil::getBytes(1));
99: } while ($n < $duplicate);
100:
101: $n %= $popsize;
102: $str .= $population[$n];
103: }
104:
105: return $str;
106: }
107:
108: static function constEq($s1, $s2)
109: {
110: if (strlen($s1) != strlen($s2)) {
111: return false;
112: }
113:
114: $result = true;
115: $length = strlen($s1);
116: for ($i = 0; $i < $length; $i++) {
117: $result &= ($s1[$i] == $s2[$i]);
118: }
119: return $result;
120: }
121: }
122:
123: