function test_cryptrand()
 {
     // It's possible, but HIGHLY unlikely that a correct
     // implementation will fail by returning the same number twice
     $s = Auth_OpenID_CryptUtil::getBytes(32);
     $t = Auth_OpenID_CryptUtil::getBytes(32);
     $this->assertEquals(Auth_OpenID::bytes($s), 32);
     $this->assertEquals(Auth_OpenID::bytes($t), 32);
     $this->assertFalse($s == $t);
 }
Example #2
0
 function xorSecret($composite, $secret, $hash_func)
 {
     $dh_shared = $this->getSharedSecret($composite);
     $dh_shared_str = $this->lib->longToBinary($dh_shared);
     $hash_dh_shared = $hash_func($dh_shared_str);
     $xsecret = "";
     for ($i = 0; $i < Auth_OpenID::bytes($secret); $i++) {
         $xsecret .= chr(ord($secret[$i]) ^ ord($hash_dh_shared[$i]));
     }
     return $xsecret;
 }
Example #3
0
/**
 * Compute an HMAC/SHA1 hash.
 *
 * @access private
 * @param string $key The HMAC key
 * @param string $text The message text to hash
 * @return string $mac The MAC
 */
function Auth_OpenID_HMACSHA1($key, $text)
{
    if (Auth_OpenID::bytes($key) > Auth_OpenID_SHA1_BLOCKSIZE) {
        $key = Auth_OpenID_SHA1($key, true);
    }
    $key = str_pad($key, Auth_OpenID_SHA1_BLOCKSIZE, chr(0x0));
    $ipad = str_repeat(chr(0x36), Auth_OpenID_SHA1_BLOCKSIZE);
    $opad = str_repeat(chr(0x5c), Auth_OpenID_SHA1_BLOCKSIZE);
    $hash1 = Auth_OpenID_SHA1(($key ^ $ipad) . $text, true);
    $hmac = Auth_OpenID_SHA1(($key ^ $opad) . $hash1, true);
    return $hmac;
}
Example #4
0
/**
 * Compute an HMAC/SHA1 hash.
 *
 * @access private
 * @param string $key The HMAC key
 * @param string $text The message text to hash
 * @return string $mac The MAC
 */
function Auth_OpenID_HMACSHA1($key, $text)
{
    if (Auth_OpenID::bytes($key) > Auth_OpenID_SHA1_BLOCKSIZE) {
        $key = Auth_OpenID_SHA1($key, true);
    }
    if (function_exists('hash_hmac') && function_exists('hash_algos') && in_array('sha1', hash_algos())) {
        return hash_hmac('sha1', $text, $key, true);
    }
    // Home-made solution
    $key = str_pad($key, Auth_OpenID_SHA1_BLOCKSIZE, chr(0x0));
    $ipad = str_repeat(chr(0x36), Auth_OpenID_SHA1_BLOCKSIZE);
    $opad = str_repeat(chr(0x5c), Auth_OpenID_SHA1_BLOCKSIZE);
    $hash1 = Auth_OpenID_SHA1(($key ^ $ipad) . $text, true);
    $hmac = Auth_OpenID_SHA1(($key ^ $opad) . $hash1, true);
    return $hmac;
}
Example #5
0
 /**
  * "Octifies" a binary string by returning a string with escaped
  * octal bytes.  This is used for preparing binary data for
  * PostgreSQL BYTEA fields.
  *
  * @access private
  */
 function _octify($str)
 {
     $result = "";
     for ($i = 0; $i < Auth_OpenID::bytes($str); $i++) {
         $ch = substr($str, $i, 1);
         if ($ch == "\\") {
             $result .= "\\\\\\\\";
         } else {
             if (ord($ch) == 0) {
                 $result .= "\\\\000";
             } else {
                 $result .= "\\" . strval(decoct(ord($ch)));
             }
         }
     }
     return $result;
 }
Example #6
0
 /**
  * Returns a random number in the specified range.  This function
  * accepts $start, $stop, and $step values of arbitrary magnitude
  * and will utilize the local large-number math library when
  * available.
  *
  * @param integer $start The start of the range, or the minimum
  * random number to return
  * @param integer $stop The end of the range, or the maximum
  * random number to return
  * @param integer $step The step size, such that $result - ($step
  * * N) = $start for some N
  * @return integer $result The resulting randomly-generated number
  */
 function rand($stop)
 {
     static $duplicate_cache = array();
     // Used as the key for the duplicate cache
     $rbytes = $this->longToBinary($stop);
     if (array_key_exists($rbytes, $duplicate_cache)) {
         list($duplicate, $nbytes) = $duplicate_cache[$rbytes];
     } else {
         if ($rbytes[0] == "") {
             $nbytes = Auth_OpenID::bytes($rbytes) - 1;
         } else {
             $nbytes = Auth_OpenID::bytes($rbytes);
         }
         $mxrand = $this->pow(256, $nbytes);
         // If we get a number less than this, then it is in the
         // duplicated range.
         $duplicate = $this->mod($mxrand, $stop);
         if (count($duplicate_cache) > 10) {
             $duplicate_cache = array();
         }
         $duplicate_cache[$rbytes] = array($duplicate, $nbytes);
     }
     do {
         $bytes = "" . Auth_OpenID_CryptUtil::getBytes($nbytes);
         $n = $this->binaryToLong($bytes);
         // Keep looping if this value is in the low duplicated range
     } while ($this->cmp($n, $duplicate) < 0);
     return $this->mod($n, $stop);
 }
Example #7
0
function detect_random($r, &$out)
{
    $out .= $r->h2('Cryptographic-quality randomness source');
    if (Auth_OpenID_RAND_SOURCE === null) {
        $out .= $r->p('Using (insecure) pseudorandom number source, because ' . 'Auth_OpenID_RAND_SOURCE has been defined as null.');
        return false;
    }
    $msg = 'The library will try to access ' . Auth_OpenID_RAND_SOURCE . ' as a source of random data. ';
    $numbytes = 6;
    $f = @fopen(Auth_OpenID_RAND_SOURCE, 'r');
    if ($f !== false) {
        $data = fread($f, $numbytes);
        $stat = fstat($f);
        $size = $stat['size'];
        fclose($f);
    } else {
        $data = null;
        $size = true;
    }
    if ($f !== false) {
        $dataok = Auth_OpenID::bytes($data) == $numbytes;
        $ok = $dataok && !$size;
        $msg .= 'It seems to exist ';
        if ($dataok) {
            $msg .= 'and be readable. Here is some hex data: ' . bin2hex($data) . '.';
        } else {
            $msg .= 'but reading data failed.';
        }
        if ($size) {
            $msg .= ' This is a ' . $size . ' byte file. Unless you know ' . 'what you are doing, it is likely that you are making a ' . 'mistake by using a regular file as a randomness source.';
        }
    } else {
        $msg .= Auth_OpenID_RAND_SOURCE . ' could not be opened. This could be because of restrictions on' . ' your PHP environment or that randomness source may not exist' . ' on this platform.';
        if (IS_WINDOWS) {
            $msg .= ' You seem to be running Windows. This library does not' . ' have access to a good source of randomness on Windows.';
        }
        $ok = false;
    }
    $out .= $r->p($msg);
    if (!$ok) {
        $out .= $r->p('To set a source of randomness, define Auth_OpenID_RAND_SOURCE ' . 'to the path to the randomness source. If your platform does ' . 'not provide a secure randomness source, the library can' . 'operate in pseudorandom mode, but it is then vulnerable to ' . 'theoretical attacks. If you wish to operate in pseudorandom ' . 'mode, define Auth_OpenID_RAND_SOURCE to null.');
        $out .= $r->p('You are running on:');
        $out .= $r->pre(php_uname());
        $out .= $r->p('There does not seem to be an available source ' . 'of randomness. On a Unix-like platform ' . '(including MacOS X), try /dev/random and ' . '/dev/urandom.');
    }
    return $ok;
}
Example #8
0
 function _readTestCases($test_file_name, $digest_len)
 {
     $lines = Tests_Auth_OpenID_readlines($test_file_name);
     $cases = array();
     $case = array();
     foreach ($lines as $line) {
         if ($line[0] == "#") {
             continue;
         }
         // Blank line separates test cases
         if ($line == "\n") {
             $cases[] = $case;
             $case = array();
         } else {
             $match = array();
             $pat = '/^([a-z0-9_-]+) =\\s+(.*?)\\n$/';
             if (!preg_match($pat, $line, $match)) {
                 trigger_error("Bad test input: {$line}", E_USER_ERROR);
             }
             $c = count($match);
             if ($c != 3) {
                 trigger_error("Wrong number of elements in parsed case: {$c}", E_USER_ERROR);
                 return false;
             }
             $key = $match[1];
             $value = $match[2];
             $case[$key] = $value;
         }
     }
     if (count($case)) {
         $cases[] = $case;
     }
     $final = array();
     // Normalize strings and check data integrity
     foreach ($cases as $case) {
         $clean = array();
         $clean["key"] = Tests_Auth_OpenID_HMAC::_strConvert($case["key"]);
         if (defined(@$case["key_len"])) {
             if (Auth_OpenID::bytes($clean["key"]) != $case["key_len"]) {
                 trigger_error("Bad key length", E_USER_ERROR);
             }
         }
         $clean["data"] = Tests_Auth_OpenID_HMAC::_strConvert($case["data"]);
         if (defined(@$case["data_len"])) {
             if (Auth_OpenID::bytes($clean["data"]) != $case["data_len"]) {
                 trigger_error("Bad data length", E_USER_ERROR);
             }
         }
         $clean["digest"] = Tests_Auth_OpenID_HMAC::_strConvert($case["digest"]);
         if (Auth_OpenID::bytes($clean["digest"]) != $digest_len) {
             $l = Auth_OpenID::bytes($clean["digest"]);
             trigger_error("Bad digest length: {$l}", E_USER_ERROR);
         }
         $clean['test_case'] = $case['test_case'];
         $final[] = $clean;
     }
     return $final;
 }