Subversion Repositories php_clientchallenge

Rev

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
        }