PluginProbe
The WP Remote WordPress Plugin / 6.76
The WP Remote WordPress Plugin v6.76
6.76 6.72 6.69 6.65 6.62 6.48 6.47 4.87 4.97 5.05 5.09 5.16 5.22 5.24 5.25 5.38 5.41 5.42 5.45 5.47 5.53 5.56 5.65 5.68 5.72 All 54 releases
wpremote / wp_2fa / time_otp.php

time_otp.php in The WP Remote WordPress Plugin 6.76, at wp_2fa/time_otp.php

57 lines 1.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if (!defined('ABSPATH')) exit;
3 if (!class_exists('WPRWP2FATimeOTP')) :
4
5 class WPRWP2FATimeOTP
6 {
7 private static $code_length = 6;
8
9 private static function getCode($secret_key, $time_slice) {
10 $time = chr(0).chr(0).chr(0).chr(0).pack('N*', $time_slice);
11 $hm = hash_hmac('SHA1', $time, $secret_key, true);
12 $offset = ord(substr($hm, -1)) & 0x0F;
13 $hashpart = substr($hm, $offset, 4);
14
15 $value = unpack('N', $hashpart);
16 $value = $value[1];
17 $value = $value & 0x7FFFFFFF;
18
19 $modulo = pow(10, self::$code_length);
20
21 return str_pad($value % $modulo, self::$code_length, '0', STR_PAD_LEFT);
22 }
23
24 public static function verifyCode($secret, $code, $discrepancy = 1, $current_time_slice = null) {
25 return self::matchingSlice($secret, $code, $discrepancy, $current_time_slice) !== null;
26 }
27
28 # Returns the time slice the code belongs to, so the caller can refuse one it
29 # has already accepted. Null when nothing matches.
30 public static function matchingSlice($secret, $code, $discrepancy = 1, $current_time_slice = null) {
31 if ($current_time_slice === null) {
32 $current_time_slice = intdiv(time(), 30);
33 }
34
35 if (strlen($code) != self::$code_length) {
36 return null;
37 }
38
39 # A secret that will not decode must never fall through to hash_hmac(),
40 # which would take the false as an empty key and produce a code anyone
41 # can compute from the clock alone.
42 $secret_key = WPRWP2FAUtils::base32Decode($secret);
43 if (!is_string($secret_key) || $secret_key === '') {
44 return null;
45 }
46
47 for ($i = -$discrepancy; $i <= $discrepancy; ++$i) {
48 $slice = intval($current_time_slice) + $i;
49 if (hash_equals(self::getCode($secret_key, $slice), $code)) {
50 return $slice;
51 }
52 }
53
54 return null;
55 }
56 }
57 endif;