1<?php 2 3/** 4 * Nonce-related functionality. 5 * 6 * @package OpenID 7 */ 8 9/** 10 * Need CryptUtil to generate random strings. 11 */ 12require_once 'Auth/OpenID/CryptUtil.php'; 13 14/** 15 * This is the characters that the nonces are made from. 16 */ 17define('Auth_OpenID_Nonce_CHRS',"abcdefghijklmnopqrstuvwxyz" . 18 "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"); 19 20// Keep nonces for five hours (allow five hours for the combination of 21// request time and clock skew). This is probably way more than is 22// necessary, but there is not much overhead in storing nonces. 23global $Auth_OpenID_SKEW; 24$Auth_OpenID_SKEW = 60 * 60 * 5; 25 26define('Auth_OpenID_Nonce_REGEX', 27 '/(\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)Z(.*)/'); 28 29define('Auth_OpenID_Nonce_TIME_FMT', 30 '%Y-%m-%dT%H:%M:%SZ'); 31 32function Auth_OpenID_splitNonce($nonce_string) 33{ 34 // Extract a timestamp from the given nonce string 35 $result = preg_match(Auth_OpenID_Nonce_REGEX, $nonce_string, $matches); 36 if ($result != 1 || count($matches) != 8) { 37 return null; 38 } 39 40 list(, 41 $tm_year, 42 $tm_mon, 43 $tm_mday, 44 $tm_hour, 45 $tm_min, 46 $tm_sec, 47 $uniquifier) = $matches; 48 49 $timestamp = 50 @gmmktime($tm_hour, $tm_min, $tm_sec, $tm_mon, $tm_mday, $tm_year); 51 52 if ($timestamp === false || $timestamp < 0) { 53 return null; 54 } 55 56 return [$timestamp, $uniquifier]; 57} 58 59function Auth_OpenID_checkTimestamp($nonce_string, 60 $allowed_skew = null, 61 $now = null) 62{ 63 // Is the timestamp that is part of the specified nonce string 64 // within the allowed clock-skew of the current time? 65 global $Auth_OpenID_SKEW; 66 67 if ($allowed_skew === null) { 68 $allowed_skew = $Auth_OpenID_SKEW; 69 } 70 71 $parts = Auth_OpenID_splitNonce($nonce_string); 72 if ($parts == null) { 73 return false; 74 } 75 76 if ($now === null) { 77 $now = time(); 78 } 79 80 $stamp = $parts[0]; 81 82 // Time after which we should not use the nonce 83 $past = $now - $allowed_skew; 84 85 // Time that is too far in the future for us to allow 86 $future = $now + $allowed_skew; 87 88 // the stamp is not too far in the future and is not too far 89 // in the past 90 return (($past <= $stamp) && ($stamp <= $future)); 91} 92 93function Auth_OpenID_mkNonce($when = null) 94{ 95 // Generate a nonce with the current timestamp 96 $salt = Auth_OpenID_CryptUtil::randomString( 97 6, Auth_OpenID_Nonce_CHRS); 98 if ($when === null) { 99 // It's safe to call time() with no arguments; it returns a 100 // GMT unix timestamp on PHP 4 and PHP 5. gmmktime() with no 101 // args returns a local unix timestamp on PHP 4, so don't use 102 // that. 103 $when = time(); 104 } 105 $time_str = gmstrftime(Auth_OpenID_Nonce_TIME_FMT, $when); 106 return $time_str . $salt; 107} 108 109