Subversion Repositories php_clientchallenge

Rev

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
}