blob: 62bc0cb1e1f48e8b3fab673dda0250bb78fb0f03 [file] [log] [blame]
Copybara botbe50d492023-11-30 00:16:42 +01001<?php
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14
15include_once("FixedByteNotation.php");
16
17
18class GoogleAuthenticator {
19 static $PASS_CODE_LENGTH = 6;
20 static $PIN_MODULO;
21 static $SECRET_LENGTH = 20;
22
23 public function __construct() {
24 self::$PIN_MODULO = pow(10, self::$PASS_CODE_LENGTH);
25 }
26
27 public function checkCode($secret,$code) {
28 $time = floor(time() / 30);
29 for ( $i = -1; $i <= 1; $i++) {
30
31 if ($this->getCode($secret,$time + $i) == $code) {
32 return true;
33 }
34 }
35
36 return false;
37
38 }
39
40 public function getCode($secret,$time = null) {
41
42 if (!$time) {
43 $time = floor(time() / 30);
44 }
45 $base32 = new FixedBitNotation(5, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', TRUE, TRUE);
46 $secret = $base32->decode($secret);
47
48 $time = pack("N", $time);
49 $time = str_pad($time,8, chr(0), STR_PAD_LEFT);
50
51 $hash = hash_hmac('sha1',$time,$secret,true);
52 $offset = ord(substr($hash,-1));
53 $offset = $offset & 0xF;
54
55 $truncatedHash = self::hashToInt($hash, $offset) & 0x7FFFFFFF;
56 $pinValue = str_pad($truncatedHash % self::$PIN_MODULO,6,"0",STR_PAD_LEFT);;
57 return $pinValue;
58 }
59
60 protected function hashToInt($bytes, $start) {
61 $input = substr($bytes, $start, strlen($bytes) - $start);
62 $val2 = unpack("N",substr($input,0,4));
63 return $val2[1];
64 }
65
66 public function getUrl($user, $hostname, $secret) {
67 $url = sprintf("otpauth://totp/%s@%s?secret=%s", $user, $hostname, $secret);
68 $encoder = "https://www.google.com/chart?chs=200x200&chld=M|0&cht=qr&chl=";
69 $encoderURL = sprintf( "%sotpauth://totp/%s@%s&secret=%s",$encoder, $user, $hostname, $secret);
70
71 return $encoderURL;
72
73 }
74
75 public function generateSecret() {
76 $secret = "";
77 for($i = 1; $i<= self::$SECRET_LENGTH;$i++) {
78 $c = random_int(0,255);
79 $secret .= pack("c",$c);
80 }
81 $base32 = new FixedBitNotation(5, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', TRUE, TRUE);
82 return $base32->encode($secret);
83
84
85 }
86
87}