Nonce.php 2.8 KB

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