PluginProbe
Patchstack – WordPress & Plugins Security / 2.1.6
Patchstack – WordPress & Plugins Security v2.1.6
2.3.7 trunk 2.1.0 2.1.1 2.1.10 2.1.11 2.1.12 2.1.13 2.1.14 2.1.15 2.1.16 2.1.17 2.1.18 2.1.19 2.1.2 2.1.20 2.1.21 2.1.22 2.1.23 2.1.24 2.1.25 2.1.3 2.1.4 2.1.5 2.1.6 All 49 releases
← All changes | includes/2fa/rfc6238.php +93 -128 trunk2.1.6 View file →
@@ -1,128 +1,93 @@
1 -<?php
2 -
3 -// Do not allow the file to be called directly.
4 -if ( ! defined( 'ABSPATH' ) ) {
5 - exit;
6 -}
7 -
8 -require_once dirname( __FILE__ ) . '/base32.php';
9 -
10 -class TokenAuth6238 {
11 -
12 - /**
13 - * Verify the code & token.
14 - *
15 - * @param string $secretkey Secret clue (base 32).
16 - * @return bool True if success, false if failure
17 - */
18 - public static function verify( $secretkey, $code, $rangein30s = 3 ) {
19 - $key = Base32Static::decode( $secretkey );
20 - $unixtimestamp = time() / 30;
21 -
22 - // Without a valid decoded key there is nothing to verify against, and
23 - // passing an empty key to hash_hmac() is deprecated on PHP 8.1+.
24 - if ( ! is_string( $key ) || $key === '' ) {
25 - return false;
26 - }
27 -
28 - for ( $i = -( $rangein30s ); $i <= $rangein30s; $i++ ) {
29 - $checktime = (int) ( $unixtimestamp + $i );
30 - $thiskey = self::oath_hotp( $key, $checktime );
31 -
32 - // oath_truncate() returns an int, so zero-pad to 6 digits to match the
33 - // codes authenticator apps display (e.g. "012345").
34 - $computed = str_pad( (string) self::oath_truncate( $thiskey, 6 ), 6, '0', STR_PAD_LEFT );
35 - if ( self::stringEquals( $computed, (string) $code ) ) {
36 - return true;
37 - }
38 - }
39 -
40 - return false;
41 - }
42 -
43 - /**
44 - * Generate the random clue/key.
45 - *
46 - * @param integer $length
47 - * @return string
48 - */
49 - public static function generateRandomClue( $length = 16 ) {
50 - if ( function_exists( 'random_bytes' ) ) {
51 - return Base32Static::encode( random_bytes( 10 ) );
52 - }
53 -
54 - require_once dirname( __FILE__ ) . '/polyfill/lib/random.php';
55 - return Base32Static::encode( random_bytes( 10 ) );
56 - }
57 -
58 - /**
59 - *
60 - * @param string $key
61 - * @param integer $counter
62 - * @return string
63 - */
64 - private static function oath_hotp( $key, $counter ) {
65 - $cur_counter = [ 0, 0, 0, 0, 0, 0, 0, 0 ];
66 -
67 - for ( $i = 7; $i >= 0; $i-- ) { // C for unsigned char, * for repeating to the end of the input data
68 - $cur_counter[ $i ] = pack( 'C*', $counter );
69 - $counter = $counter >> 8;
70 - }
71 -
72 - $binary = implode( $cur_counter );
73 -
74 - // Pad to 8 characters
75 - $binary = str_pad( $binary, 8, chr( 0 ), STR_PAD_LEFT );
76 - return hash_hmac( 'sha1', $binary, $key );
77 - }
78 -
79 - /**
80 - * Truncate
81 - *
82 - * @param string $hash
83 - * @param integer $length
84 - * @return boolean
85 - */
86 - private static function oath_truncate( $hash, $length = 6 ) {
87 - $hashcharacters = str_split( $hash, 2 );
88 -
89 - for ( $j = 0; $j < count( $hashcharacters ); $j++ ) {
90 - $hmac_result[] = hexdec( $hashcharacters[ $j ] );
91 - }
92 -
93 - $offset = $hmac_result[19] & 0xf;
94 - return (
95 - ( ( $hmac_result[ $offset + 0 ] & 0x7f ) << 24 ) |
96 - ( ( $hmac_result[ $offset + 1 ] & 0xff ) << 16 ) |
97 - ( ( $hmac_result[ $offset + 2 ] & 0xff ) << 8 ) |
98 - ( $hmac_result[ $offset + 3 ] & 0xff )
99 - ) % pow( 10, $length );
100 - }
101 -
102 - /**
103 - * Compare 2 strings with each other.
104 - *
105 - * @param string $own
106 - * @param string $user
107 - * @return boolean
108 - */
109 - private static function stringEquals( $own, $user ) {
110 - if ( function_exists( 'hash_equals' ) ) {
111 - return hash_equals( $own, $user );
112 - }
113 -
114 - $safeLen = strlen( $own );
115 - $userLen = strlen( $user );
116 -
117 - if ( $userLen != $safeLen ) {
118 - return false;
119 - }
120 -
121 - $result = 0;
122 - for ( $i = 0; $i < $userLen; $i++ ) {
123 - $result |= ( ord( $own[$i] ) ^ ord( $user[$i] ) );
124 - }
125 -
126 - return $result === 0;
127 - }
128 -}
1 +<?php
2 +
3 +// Do not allow the file to be called directly.
4 +if ( ! defined( 'ABSPATH' ) ) {
5 + exit;
6 +}
7 +
8 +require_once dirname( __FILE__ ) . '/base32.php';
9 +
10 +class TokenAuth6238 {
11 +
12 + /**
13 + * Verify the code & token.
14 + *
15 + * @param string $secretkey Secret clue (base 32).
16 + * @return bool True if success, false if failure
17 + */
18 + public static function verify( $secretkey, $code, $rangein30s = 3 ) {
19 + $key = base32static::decode( $secretkey );
20 + $unixtimestamp = time() / 30;
21 +
22 + for ( $i = -( $rangein30s ); $i <= $rangein30s; $i++ ) {
23 + $checktime = (int) ( $unixtimestamp + $i );
24 + $thiskey = self::oath_hotp( $key, $checktime );
25 +
26 + if ( (int) $code == self::oath_truncate( $thiskey, 6 ) ) {
27 + return true;
28 + }
29 + }
30 +
31 + return false;
32 + }
33 +
34 + /**
35 + * Generate the random clue/key.
36 + *
37 + * @param integer $length
38 + * @return string
39 + */
40 + public static function generateRandomClue( $length = 16 ) {
41 + $b32 = '234567QWERTYUIOPASDFGHJKLZXCVBNM';
42 + $s = '';
43 + for ( $i = 0; $i < $length; $i++ ) {
44 + $s .= $b32[ mt_rand( 0, 31 ) ];
45 + }
46 +
47 + return $s;
48 + }
49 +
50 + /**
51 + *
52 + * @param string $key
53 + * @param integer $counter
54 + * @return string
55 + */
56 + private static function oath_hotp( $key, $counter ) {
57 + $cur_counter = array( 0, 0, 0, 0, 0, 0, 0, 0 );
58 +
59 + for ( $i = 7; $i >= 0; $i-- ) { // C for unsigned char, * for repeating to the end of the input data
60 + $cur_counter[ $i ] = pack( 'C*', $counter );
61 + $counter = $counter >> 8;
62 + }
63 +
64 + $binary = implode( $cur_counter );
65 +
66 + // Pad to 8 characters
67 + str_pad( $binary, 8, chr( 0 ), STR_PAD_LEFT );
68 + return hash_hmac( 'sha1', $binary, $key );
69 + }
70 +
71 + /**
72 + * Truncate
73 + *
74 + * @param string $hash
75 + * @param integer $length
76 + * @return boolean
77 + */
78 + private static function oath_truncate( $hash, $length = 6 ) {
79 + $hashcharacters = str_split( $hash, 2 );
80 +
81 + for ( $j = 0; $j < count( $hashcharacters ); $j++ ) {
82 + $hmac_result[] = hexdec( $hashcharacters[ $j ] );
83 + }
84 +
85 + $offset = $hmac_result[19] & 0xf;
86 + return (
87 + ( ( $hmac_result[ $offset + 0 ] & 0x7f ) << 24 ) |
88 + ( ( $hmac_result[ $offset + 1 ] & 0xff ) << 16 ) |
89 + ( ( $hmac_result[ $offset + 2 ] & 0xff ) << 8 ) |
90 + ( $hmac_result[ $offset + 3 ] & 0xff )
91 + ) % pow( 10, $length );
92 + }
93 +}