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 18if (!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 26class 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