diff options
-rw-r--r-- | Auth/OpenID/Consumer/Consumer.php | 2 | ||||
-rw-r--r-- | Auth/OpenID/CryptUtil.php | 263 | ||||
-rw-r--r-- | Auth/OpenID/DiffieHellman.php | 8 | ||||
-rw-r--r-- | Auth/OpenID/OIDUtil.php | 20 | ||||
-rw-r--r-- | Tests/Auth/OpenID/Consumer.php | 2 | ||||
-rw-r--r-- | Tests/Auth/OpenID/CryptUtil.php | 8 | ||||
-rw-r--r-- | Tests/Auth/OpenID/DiffieHellman.php | 4 |
7 files changed, 161 insertions, 146 deletions
diff --git a/Auth/OpenID/Consumer/Consumer.php b/Auth/OpenID/Consumer/Consumer.php index a7f978f..c039aa8 100644 --- a/Auth/OpenID/Consumer/Consumer.php +++ b/Auth/OpenID/Consumer/Consumer.php @@ -954,7 +954,7 @@ class Auth_OpenID_Consumer { return null; } - $spub = Auth_OpenID_CryptUtil::base64ToLong( + $spub = Auth_OpenID_base64ToLong( $results['dh_server_public']); $enc_mac_key = Auth_OpenID_CryptUtil::fromBase64( diff --git a/Auth/OpenID/CryptUtil.php b/Auth/OpenID/CryptUtil.php index bef0090..ab4775d 100644 --- a/Auth/OpenID/CryptUtil.php +++ b/Auth/OpenID/CryptUtil.php @@ -41,7 +41,7 @@ if (!defined('Auth_OpenID_RAND_SOURCE')) { function Auth_OpenID_longToBinary($long) { - $lib =& Auth_OpenID_MathLibrary::getLibWrapper(); + $lib =& Auth_OpenID_getMathLib(); $cmp = $lib->cmp($long, 0); if ($cmp < 0) { @@ -107,6 +107,54 @@ function Auth_OpenID_longToBase64($long) } /** + * Converts a base64-encoded string to a long number. + * + * @param string $str A base64-encoded string + * @return integer $long A long number + */ +function Auth_OpenID_base64ToLong($str) +{ + return Auth_OpenID_binaryToLong(base64_decode($str)); +} + +/** + * Given a binary string, returns the binary string converted to a + * long number. + * + * @param string $binary The binary version of a long number, + * probably as a result of calling longToBinary + * @return integer $long The long number equivalent of the binary + * string $str + */ +function Auth_OpenID_binaryToLong($str) +{ + $lib =& Auth_OpenID_getMathLib(); + + if ($str === null) { + return null; + } + + // Use array_merge to return a zero-indexed array instead of a + // one-indexed array. + $bytes = array_merge(unpack('C*', $str)); + + $n = $lib->init(0); + + if ($bytes && ($bytes[0] > 127)) { + trigger_error("bytesToNum works only for positive integers.", + E_USER_WARNING); + return null; + } + + foreach ($bytes as $byte) { + $n = $lib->mul($n, pow(2, 8)); + $n = $lib->add($n, $byte); + } + + return $n; +} + +/** * Auth_OpenID_CryptUtil houses static utility functions. * * @package OpenID @@ -224,43 +272,6 @@ class Auth_OpenID_CryptUtil { * @return integer $long The long number equivalent of the binary * string $str */ - function binaryToLong($str) - { - $lib =& Auth_OpenID_MathLibrary::getLibWrapper(); - - if ($str === null) { - return null; - } - - // Use array_merge to return a zero-indexed array instead of a - // one-indexed array. - $bytes = array_merge(unpack('C*', $str)); - - $n = $lib->init(0); - - if ($bytes && ($bytes[0] > 127)) { - trigger_error("bytesToNum works only for positive integers.", - E_USER_WARNING); - return null; - } - - foreach ($bytes as $byte) { - $n = $lib->mul($n, pow(2, 8)); - $n = $lib->add($n, $byte); - } - - return $n; - } - - /** - * Given a binary string, returns the binary string converted to a - * long number. - * - * @param string $binary The binary version of a long number, - * probably as a result of calling longToBinary - * @return integer $long The long number equivalent of the binary - * string $str - */ function binaryToLong_platform($str) { if ($str === null) { @@ -272,18 +283,6 @@ class Auth_OpenID_CryptUtil { } /** - * Converts a base64-encoded string to a long number. - * - * @param string $str A base64-encoded string - * @return integer $long A long number - */ - function base64ToLong($str) - { - return Auth_OpenID_CryptUtil::binaryToLong( - Auth_OpenID_CryptUtil::fromBase64($str)); - } - - /** * Given two strings of equal length, computes the exclusive-OR of * the two strings' ordinal values and returns the resulting * string. @@ -342,7 +341,7 @@ class Auth_OpenID_CryptUtil { { static $Auth_OpenID_CryptUtil_duplicate_cache = array(); - $lib =& Auth_OpenID_MathLibrary::getLibWrapper(); + $lib =& Auth_OpenID_getMathLib(); if ($stop == null) { $stop = $start; @@ -380,7 +379,7 @@ class Auth_OpenID_CryptUtil { while (1) { $bytes = "\x00" . Auth_OpenID_CryptUtil::getBytes($nbytes); - $n = Auth_OpenID_CryptUtil::binaryToLong($bytes); + $n = Auth_OpenID_binaryToLong($bytes); // Keep looping if this value is in the low duplicated // range if ($lib->cmp($n, $duplicate) >= 0) { @@ -648,8 +647,6 @@ class Auth_OpenID_GmpMathWrapper extends Auth_OpenID_MathWrapper { } -$_Auth_OpenID___mathLibrary = null; - /** * Define the supported extensions. An extension array has keys * 'modules', 'extension', and 'class'. 'modules' is an array of PHP @@ -672,97 +669,95 @@ $_Auth_OpenID_supported_extensions = array( 'class' => 'Auth_OpenID_BcMathWrapper') ); - /** - * Auth_OpenID_MathLibrary checks for the presence of long number - * extension modules and returns an instance of Auth_OpenID_MathWrapper - * which exposes the module's functionality. - * - * @static - * @package OpenID - */ -class Auth_OpenID_MathLibrary { +function Auth_OpenID_detectMathLibrary($exts) +{ + $loaded = false; - /** - * A method to access an available long number implementation. - * - * Checks for the existence of an extension module described by - * the local Auth_OpenID_supported_extensions array and returns an - * instance of a wrapper for that extension module. If no - * extension module is found, an instance of - * Auth_OpenID_MathWrapper is returned, which wraps the native PHP - * integer implementation. The proper calling convention for this - * method is $lib =& Auth_OpenID_MathLibrary::getLibWrapper(). - * - * This function checks for the existence of specific long number - * implementations in the following order: GMP followed by BCmath. - * - * @return Auth_OpenID_MathWrapper $instance An instance of - * Auth_OpenID_MathWrapper or one of its subclasses - */ - function &getLibWrapper() - { - // The instance of Auth_OpenID_MathWrapper that we choose to - // supply will be stored here, so that subseqent calls to this - // method will return a reference to the same object. - global $_Auth_OpenID___mathLibrary; - - if (defined('Auth_OpenID_NO_MATH_SUPPORT')) { - $_Auth_OpenID___mathLibrary = null; - return $_Auth_OpenID___mathLibrary; + foreach ($exts as $extension) { + // See if the extension specified is already loaded. + if ($extension['extension'] && + extension_loaded($extension['extension'])) { + $loaded = true; } - global $_Auth_OpenID_supported_extensions; - - // If this method has not been called before, look at - // $Auth_OpenID_supported_extensions and try to find an - // extension that works. - if (!$_Auth_OpenID___mathLibrary) { - $loaded = false; - $tried = array(); - - foreach ($_Auth_OpenID_supported_extensions as $extension) { - $tried[] = $extension['extension']; - - // See if the extension specified is already loaded. - if ($extension['extension'] && - extension_loaded($extension['extension'])) { + // Try to load dynamic modules. + if (!$loaded) { + foreach ($extension['modules'] as $module) { + if (@dl($module . "." . PHP_SHLIB_SUFFIX)) { $loaded = true; - } - - // Try to load dynamic modules. - if (!$loaded) { - foreach ($extension['modules'] as $module) { - if (@dl($module . "." . PHP_SHLIB_SUFFIX)) { - $loaded = true; - break; - } - } - } - - // If the load succeeded, supply an instance of - // Auth_OpenID_MathWrapper which wraps the specified - // module's functionality. - if ($loaded) { - $classname = $extension['class']; - $_Auth_OpenID___mathLibrary = new $classname(); break; } } + } - // If no extensions were found, fall back to - // Auth_OpenID_MathWrapper so at least some platform-size - // math can be performed. - if (!$_Auth_OpenID___mathLibrary) { - $triedstr = implode(", ", $tried); - $msg = 'This PHP installation has no big integer math ' . - 'library. Define Auth_OpenID_NO_MATH_SUPPORT to use ' . - 'this library in dumb mode. Tried: ' . $triedstr; - trigger_error($msg, E_USER_ERROR); - } + // If the load succeeded, supply an instance of + // Auth_OpenID_MathWrapper which wraps the specified + // module's functionality. + if ($loaded) { + return $extension['class']; } + } - return $_Auth_OpenID___mathLibrary; + return false; +} + +/** + * Auth_OpenID_getMathLib checks for the presence of long number + * extension modules and returns an instance of Auth_OpenID_MathWrapper + * which exposes the module's functionality. + * + * Checks for the existence of an extension module described by the + * local Auth_OpenID_supported_extensions array and returns an + * instance of a wrapper for that extension module. If no extension + * module is found, an instance of Auth_OpenID_MathWrapper is + * returned, which wraps the native PHP integer implementation. The + * proper calling convention for this method is $lib =& + * Auth_OpenID_getMathLib(). + * + * This function checks for the existence of specific long number + * implementations in the following order: GMP followed by BCmath. + * + * @return Auth_OpenID_MathWrapper $instance An instance of + * Auth_OpenID_MathWrapper or one of its subclasses + * + * @package OpenID + */ +function &Auth_OpenID_getMathLib() +{ + // The instance of Auth_OpenID_MathWrapper that we choose to + // supply will be stored here, so that subseqent calls to this + // method will return a reference to the same object. + static $lib = null; + + if (isset($lib)) { + return $lib; + } + + if (defined('Auth_OpenID_NO_MATH_SUPPORT')) { + return null; } + + // If this method has not been called before, look at + // $Auth_OpenID_supported_extensions and try to find an + // extension that works. + global $_Auth_OpenID_supported_extensions; + $ext = Auth_OpenID_detectMathLibrary($_Auth_OpenID_supported_extensions); + if ($ext === false) { + $tried = array(); + foreach ($_Auth_OpenID_supported_extensions as $extinfo) { + $tried[] = $extinfo['extension']; + } + $triedstr = implode(", ", $tried); + $msg = 'This PHP installation has no big integer math ' . + 'library. Define Auth_OpenID_NO_MATH_SUPPORT to use ' . + 'this library in dumb mode. Tried: ' . $triedstr; + trigger_error($msg, E_USER_ERROR); + } + + // Instantiate a new wrapper + $lib = new $ext(); + + return $lib; } ?>
\ No newline at end of file diff --git a/Auth/OpenID/DiffieHellman.php b/Auth/OpenID/DiffieHellman.php index f3894ab..2e0fa2a 100644 --- a/Auth/OpenID/DiffieHellman.php +++ b/Auth/OpenID/DiffieHellman.php @@ -43,11 +43,11 @@ class Auth_OpenID_DiffieHellman { function fromBase64($mod, $gen) { if ($mod !== null) { - $mod = Auth_OpenID_CryptUtil::base64ToLong($mod); + $mod = Auth_OpenID_base64ToLong($mod); } if ($gen !== null) { - $gen = Auth_OpenID_CryptUtil::base64ToLong($gen); + $gen = Auth_OpenID_base64ToLong($gen); } return new Auth_OpenID_DiffieHellman($mod, $gen); @@ -59,13 +59,13 @@ class Auth_OpenID_DiffieHellman { global $_Auth_OpenID_DEFAULT_MOD, $_Auth_OpenID_DEFAULT_GEN; - $this->lib =& Auth_OpenID_MathLibrary::getLibWrapper(); + $this->lib =& Auth_OpenID_getMathLib(); if (!$this->lib) { // This should NEVER occur because even if no math // extensions can be found, we should get an instance of // Auth_OpenID_MathWrapper, but if there's a bug in - // Auth_OpenID_MathLibrary::getLibWrapper, it might. + // Auth_OpenID_getMathLib, it might. trigger_error("Big integer fallback implementation unavailable.", E_USER_ERROR); } diff --git a/Auth/OpenID/OIDUtil.php b/Auth/OpenID/OIDUtil.php index 5107bf8..7b23bac 100644 --- a/Auth/OpenID/OIDUtil.php +++ b/Auth/OpenID/OIDUtil.php @@ -62,6 +62,26 @@ function Auth_OpenID_log($message, $unused_level = 0) } /** + * Rename specified query arguments back to 'openid.' from 'openid_' + * + * @param array $args An associative array of URL query arguments + * + * @param array $allowed A set of strings indicating which 'openid_' + * keys should be renamed. + */ +function Auth_OpenID_fixArgs(&$args, $allowed) +{ + foreach ($allowed as $key_ext) { + $key = 'openid_' . $key_ext; + if (isset($args[$key])) { + $val = $args[$key]; + unset($args[$key]); + $args['openid.' . $key_ext] = $val; + } + } +} + +/** * Implements the PHP 5 'http_build_query' functionality. * * @param array $data Either an array key/value pairs or an array of diff --git a/Tests/Auth/OpenID/Consumer.php b/Tests/Auth/OpenID/Consumer.php index bb73733..c0aa74f 100644 --- a/Tests/Auth/OpenID/Consumer.php +++ b/Tests/Auth/OpenID/Consumer.php @@ -61,7 +61,7 @@ function Auth_OpenID_associate($qs, $assoc_secret, $assoc_handle) Auth_OpenID_array_get($query_data, 'openid.dh_modulus', null), Auth_OpenID_array_get($query_data, 'openid.dh_gen', null)); - $composite = Auth_OpenID_CryptUtil::base64ToLong( + $composite = Auth_OpenID_base64ToLong( $query_data['openid.dh_consumer_public']); $enc_mac_key = Auth_OpenID_CryptUtil::toBase64( diff --git a/Tests/Auth/OpenID/CryptUtil.php b/Tests/Auth/OpenID/CryptUtil.php index a392c50..f57455a 100644 --- a/Tests/Auth/OpenID/CryptUtil.php +++ b/Tests/Auth/OpenID/CryptUtil.php @@ -137,7 +137,7 @@ class Tests_Auth_OpenID_BinLongConvertRnd extends PHPUnit_TestCase { } $s = Auth_OpenID_longToBinary($n); $this->assertTrue(is_string($s)); - $n_prime = Auth_OpenID_CryptUtil::binaryToLong($s); + $n_prime = Auth_OpenID_binaryToLong($s); $this->assertEquals($this->lib->cmp($n, $n_prime), 0); } } @@ -156,7 +156,7 @@ class Tests_Auth_OpenID_BinLongConvert extends PHPUnit_TestCase { function runTest() { - $n_prime = Auth_OpenID_CryptUtil::binaryToLong($this->bin); + $n_prime = Auth_OpenID_binaryToLong($this->bin); $s_prime = Auth_OpenID_longToBinary($this->lng); $this->assertEquals($this->lib->cmp($this->lng, $n_prime), 0); $this->assertTrue($this->bin == $s_prime); @@ -177,7 +177,7 @@ class Tests_Auth_OpenID_Base64ToLong extends PHPUnit_TestCase { function runTest() { - $actual = Auth_OpenID_CryptUtil::base64ToLong($this->b64); + $actual = Auth_OpenID_base64ToLong($this->b64); $this->assertTrue($this->lib->cmp($this->num, $actual) == 0); } } @@ -246,7 +246,7 @@ class Tests_Auth_OpenID_CryptUtil extends PHPUnit_TestSuite { if (!defined('Auth_OpenID_NO_MATH_SUPPORT')) { $this->addTestSuite('Tests_Auth_OpenID_BigInt'); - $lib =& Auth_OpenID_MathLibrary::getLibWrapper(); + $lib =& Auth_OpenID_getMathLib(); $max = Auth_OpenID_CryptUtil::maxint(); $upper = defined('Tests_Auth_OpenID_thorough') ? 499 : 3; diff --git a/Tests/Auth/OpenID/DiffieHellman.php b/Tests/Auth/OpenID/DiffieHellman.php index 57704a7..5e43174 100644 --- a/Tests/Auth/OpenID/DiffieHellman.php +++ b/Tests/Auth/OpenID/DiffieHellman.php @@ -40,7 +40,7 @@ class Tests_Auth_OpenID_DiffieHellman_Private extends PHPUnit_TestCase { function runTest() { - $lib =& Auth_OpenID_MathLibrary::getLibWrapper(); + $lib =& Auth_OpenID_getMathLib(); $dh = new Auth_OpenID_DiffieHellman(null, null, $this->input); $this->assertEquals($lib->cmp($this->expected, $dh->getPublicKey()), 0); } @@ -57,7 +57,7 @@ class Tests_Auth_OpenID_DiffieHellman_Exch extends PHPUnit_TestCase { function runTest() { - $lib =& Auth_OpenID_MathLibrary::getLibWrapper(); + $lib =& Auth_OpenID_getMathLib(); $shared = $lib->init($this->shared); $dh1 = new Auth_OpenID_DiffieHellman(null, null, $this->p1); $dh2 = new Auth_OpenID_DiffieHellman(null, null, $this->p2); |