Rev 4 | Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
2 | daniel-mar | 1 | <?php |
2 | |||
3 | /* |
||
4 | * php_clientchallenge |
||
5 | * Copyright 2021 Daniel Marschall, ViaThinkSoft |
||
6 | * |
||
7 | * Licensed under the Apache License, Version 2.0 (the "License"); |
||
8 | * you may not use this file except in compliance with the License. |
||
9 | * You may obtain a copy of the License at |
||
10 | * |
||
11 | * http://www.apache.org/licenses/LICENSE-2.0 |
||
12 | * |
||
13 | * Unless required by applicable law or agreed to in writing, software |
||
14 | * distributed under the License is distributed on an "AS IS" BASIS, |
||
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||
16 | * See the License for the specific language governing permissions and |
||
17 | * limitations under the License. |
||
18 | */ |
||
19 | |||
20 | namespace ViaThinkSoft\RateLimitingChallenge; |
||
21 | |||
22 | class ClientChallenge { |
||
23 | |||
24 | private static function sha3_512($password, $raw_output=false) { |
||
25 | if (version_compare(PHP_VERSION, '7.1.0') >= 0) { |
||
26 | return hash('sha3-512', $password, $raw_output); |
||
27 | } else { |
||
28 | return \bb\Sha3\Sha3::hash($password, 512, $raw_output); |
||
29 | } |
||
30 | } |
||
31 | |||
32 | public static function checkValidation($max_time=10) { |
||
33 | |||
34 | if (!isset($_REQUEST['vts_validation_result'])) throw new Exception('No challenge response found'); |
||
35 | |||
36 | list($starttime, $ip_target, $challenge, $answer) = @json_decode($_REQUEST['vts_validation_result'], true); |
||
37 | |||
38 | if ($ip_target != $_SERVER['REMOTE_ADDR']) { |
||
39 | throw new Exception('Wrong IP'); |
||
40 | } else if (time()-$starttime > $max_time) { |
||
41 | throw new Exception('Challenge expired'); |
||
42 | } else if ($challenge !== self::sha3_512($starttime.'/'.$ip_target.'/'.$answer)) { |
||
43 | throw new Exception('Wrong answer'); |
||
44 | } else { |
||
45 | return true; |
||
46 | } |
||
47 | } |
||
48 | |||
49 | // This is only called by ajax_get_challenge.php |
||
50 | public static function createChallenge($complexity=500000) { |
||
51 | |||
52 | $min = 0; |
||
53 | $max = $complexity; |
||
54 | |||
55 | $starttime = time(); |
||
56 | |||
57 | $random = rand($min,$max); // TODO: cryptographic rand |
||
58 | |||
59 | $ip_target = $_SERVER['REMOTE_ADDR']; |
||
60 | |||
61 | $challenge = self::sha3_512($starttime.'/'.$ip_target.'/'.$random); |
||
62 | |||
63 | $send_to_client = array($starttime, $ip_target, $challenge, $min, $max); |
||
64 | |||
65 | header('Content-Type:application/json'); |
||
66 | die(json_encode($send_to_client)); |
||
67 | |||
68 | } |
||
69 | |||
70 | } |