Rev 2 | Rev 5 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2 | Rev 4 | ||
---|---|---|---|
Line 19... | Line 19... | ||
19 | 19 | ||
20 | namespace ViaThinkSoft\RateLimitingChallenge; |
20 | namespace ViaThinkSoft\RateLimitingChallenge; |
21 | 21 | ||
22 | class ClientChallenge { |
22 | class ClientChallenge { |
23 | 23 | ||
24 | private static function sha3_512($password, $raw_output=false) { |
24 | private static function sha3_512($message, $raw_output=false) { |
25 | if (version_compare(PHP_VERSION, '7.1.0') >= 0) { |
25 | if (version_compare(PHP_VERSION, '7.1.0') >= 0) { |
26 | return hash('sha3-512', $password, $raw_output); |
26 | return hash('sha3-512', $message, $raw_output); |
27 | } else { |
27 | } else { |
28 | return \bb\Sha3\Sha3::hash($password, 512, $raw_output); |
28 | return \bb\Sha3\Sha3::hash($message, 512, $raw_output); |
29 | } |
29 | } |
30 | } |
30 | } |
31 | 31 | ||
- | 32 | private static function sha3_512_hmac($message, $key, $raw_output=false) { |
|
- | 33 | // RFC 2104 HMAC |
|
- | 34 | if (version_compare(PHP_VERSION, '7.1.0') >= 0) { |
|
- | 35 | return hash_hmac('sha3-512', $message, $key, $raw_output); |
|
- | 36 | } else { |
|
- | 37 | $blocksize = 576; // block size of sha-512! |
|
- | 38 | ||
- | 39 | if (strlen($key) > ($blocksize/8)) { |
|
- | 40 | $k_ = sha3_512($key,true); |
|
- | 41 | } else { |
|
- | 42 | $k_ = $key; |
|
- | 43 | } |
|
- | 44 | ||
- | 45 | $k_opad = str_repeat(chr(0x5C),($blocksize/8)); |
|
- | 46 | $k_ipad = str_repeat(chr(0x36),($blocksize/8)); |
|
- | 47 | for ($i=0; $i<strlen($k_); $i++) { |
|
- | 48 | $k_opad[$i] = $k_opad[$i] ^ $k_[$i]; |
|
- | 49 | $k_ipad[$i] = $k_ipad[$i] ^ $k_[$i]; |
|
- | 50 | } |
|
- | 51 | ||
- | 52 | return sha3_512($k_opad . sha3_512($k_ipad . $message, true)); |
|
- | 53 | } |
|
- | 54 | } |
|
- | 55 | ||
32 | public static function checkValidation($max_time=10) { |
56 | public static function checkValidation($max_time=10, $server_secret) { |
33 | 57 | ||
34 | if (!isset($_REQUEST['vts_validation_result'])) throw new Exception('No challenge response found'); |
58 | if (!isset($_REQUEST['vts_validation_result'])) throw new \Exception('No challenge response found'); |
35 | 59 | ||
36 | list($starttime, $ip_target, $challenge, $answer) = @json_decode($_REQUEST['vts_validation_result'], true); |
60 | list($starttime, $ip_target, $challenge, $answer, $challenge_integrity) = @json_decode($_REQUEST['vts_validation_result'], true); |
37 | 61 | ||
38 | if ($ip_target != $_SERVER['REMOTE_ADDR']) { |
62 | if ($ip_target != $_SERVER['REMOTE_ADDR']) { |
39 | throw new Exception('Wrong IP'); |
63 | throw new \Exception('Wrong IP'); |
40 | } else if (time()-$starttime > $max_time) { |
64 | } else if (time()-$starttime > $max_time) { |
41 | throw new Exception('Challenge expired'); |
65 | throw new \Exception('Challenge expired'); |
- | 66 | } else if ($challenge_integrity != self::sha3_512_hmac($challenge,$server_secret)) { |
|
- | 67 | throw new \Exception('Challenge integrity failed'); |
|
42 | } else if ($challenge !== self::sha3_512($starttime.'/'.$ip_target.'/'.$answer)) { |
68 | } else if ($challenge !== self::sha3_512($starttime.'/'.$ip_target.'/'.$answer)) { |
43 | throw new Exception('Wrong answer'); |
69 | throw new \Exception('Wrong answer'); |
44 | } else { |
70 | } else { |
45 | return true; |
71 | return true; |
46 | } |
72 | } |
47 | } |
73 | } |
48 | 74 | ||
49 | // This is only called by ajax_get_challenge.php |
75 | // This is only called by ajax_get_challenge.php |
50 | public static function createChallenge($complexity=500000) { |
76 | public static function createChallenge($complexity=500000, $server_secret) { |
51 | 77 | ||
52 | $min = 0; |
78 | $min = 0; |
53 | $max = $complexity; |
79 | $max = $complexity; |
54 | 80 | ||
55 | $starttime = time(); |
81 | $starttime = time(); |
Line 58... | Line 84... | ||
58 | 84 | ||
59 | $ip_target = $_SERVER['REMOTE_ADDR']; |
85 | $ip_target = $_SERVER['REMOTE_ADDR']; |
60 | 86 | ||
61 | $challenge = self::sha3_512($starttime.'/'.$ip_target.'/'.$random); |
87 | $challenge = self::sha3_512($starttime.'/'.$ip_target.'/'.$random); |
62 | 88 | ||
- | 89 | $challenge_integrity = self::sha3_512_hmac($challenge,$server_secret); |
|
- | 90 | ||
63 | $send_to_client = array($starttime, $ip_target, $challenge, $min, $max); |
91 | $send_to_client = array($starttime, $ip_target, $challenge, $min, $max, $challenge_integrity); |
64 | 92 | ||
65 | header('Content-Type:application/json'); |
93 | header('Content-Type:application/json'); |
66 | die(json_encode($send_to_client)); |
94 | die(json_encode($send_to_client)); |
67 | 95 | ||
68 | } |
96 | } |