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 if ($f === null) { 44 if (Auth_OpenID_RAND_SOURCE === null) { 45 $f = false; 46 } else { 47 $f = @fopen(Auth_OpenID_RAND_SOURCE, "r"); 48 if ($f === false) { 49 $msg = 'Define Auth_OpenID_RAND_SOURCE as null to ' . 50 ' continue with an insecure random number generator.'; 51 trigger_error($msg, E_USER_ERROR); 52 } 53 } 54 } 55 if ($f === false) { 56 // pseudorandom used 57 $bytes = ''; 58 for ($i = 0; $i < $num_bytes; $i += 4) { 59 $bytes .= pack('L', mt_rand()); 60 } 61 $bytes = substr($bytes, 0, $num_bytes); 62 } else { 63 $bytes = fread($f, $num_bytes); 64 } 65 return $bytes; 66 } 67 68 /** 69 * Produce a string of length random bytes, chosen from chrs. If 70 * $chrs is null, the resulting string may contain any characters. 71 * 72 * @param integer $length The length of the resulting 73 * randomly-generated string 74 * @param string|null $population A string of characters from which to choose 75 * to build the new string 76 * @return string $result A string of randomly-chosen characters 77 * from $chrs 78 */ 79 static function randomString($length, $population = null) 80 { 81 if ($population === null) { 82 return Auth_OpenID_CryptUtil::getBytes($length); 83 } 84 85 $popsize = strlen($population); 86 87 if ($popsize > 256) { 88 $msg = 'More than 256 characters supplied to ' . __FUNCTION__; 89 trigger_error($msg, E_USER_ERROR); 90 } 91 92 $duplicate = 256 % $popsize; 93 94 $str = ""; 95 for ($i = 0; $i < $length; $i++) { 96 do { 97 $n = ord(Auth_OpenID_CryptUtil::getBytes(1)); 98 } while ($n < $duplicate); 99 100 $n %= $popsize; 101 $str .= $population[$n]; 102 } 103 104 return $str; 105 } 106 107 static function constEq($s1, $s2) 108 { 109 if (strlen($s1) != strlen($s2)) { 110 return false; 111 } 112 113 $result = true; 114 $length = strlen($s1); 115 for ($i = 0; $i < $length; $i++) { 116 $result &= ($s1[$i] == $s2[$i]); 117 } 118 return $result; 119 } 120} 121 122