Skip to content

Commit cc2ae19

Browse files
committed
Document the need for the code to be a string
1 parent 94571a2 commit cc2ae19

File tree

3 files changed

+14
-6
lines changed

3 files changed

+14
-6
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,9 @@ When the shared secret is added to the app, the app will be ready to start gener
9797
$result = $tfa->verifyCode($_SESSION['secret'], $_POST['verification']);
9898
````
9999

100-
`verifyCode()` will return either `true` (the code was valid) or `false` (the code was invalid; no points for you!). You may need to store `$secret` in a `$_SESSION` or other persistent storage between requests. The `verifyCode()` accepts, aside from `$secret` and `$code`, three more arguments. The first being `$discrepancy`. Since TOTP codes are based on time("slices") it is very important that the server (but also client) have a correct date/time. But because the two *may* differ a bit we usually allow a certain amount of leeway. Because generated codes are valid for a specific period (remember the `$period` argument in the `TwoFactorAuth`'s constructor?) we usually check the period directly before and the period directly after the current time when validating codes. So when the current time is `14:34:21`, which results in a 'current timeslice' of `14:34:00` to `14:34:30` we also calculate/verify the codes for `14:33:30` to `14:34:00` and for `14:34:30` to `14:35:00`. This gives us a 'window' of `14:33:30` to `14:35:00`. The `$discrepancy` argument specifies how many periods (or: timeslices) we check in either direction of the current time. The default `$discrepancy` of `1` results in (max.) 3 period checks: -1, current and +1 period. A `$discrepancy` of `4` would result in a larger window (or: bigger time difference between client and server) of -4, -3, -2, -1, current, +1, +2, +3 and +4 periods.
100+
If you do extra validations with your `$_POST` values, just make sure the code is still submitted as string - even if that's a numeric code, casting it to integer is unreliable. Also, you may need to store `$secret` in a `$_SESSION` or other persistent storage between requests. `verifyCode()` will return either `true` (the code was valid) or `false` (the code was invalid; no points for you!).
101+
102+
The `verifyCode()` accepts, aside from `$secret` and `$code`, three more arguments, with the first being `$discrepancy`. Since TOTP codes are based on time("slices") it is very important that the server (but also client) have a correct date/time. But because the two *may* differ a bit we usually allow a certain amount of leeway. Because generated codes are valid for a specific period (remember the `$period` argument in the `TwoFactorAuth`'s constructor?) we usually check the period directly before and the period directly after the current time when validating codes. So when the current time is `14:34:21`, which results in a 'current timeslice' of `14:34:00` to `14:34:30` we also calculate/verify the codes for `14:33:30` to `14:34:00` and for `14:34:30` to `14:35:00`. This gives us a 'window' of `14:33:30` to `14:35:00`. The `$discrepancy` argument specifies how many periods (or: timeslices) we check in either direction of the current time. The default `$discrepancy` of `1` results in (max.) 3 period checks: -1, current and +1 period. A `$discrepancy` of `4` would result in a larger window (or: bigger time difference between client and server) of -4, -3, -2, -1, current, +1, +2, +3 and +4 periods.
101103

102104
The second, `$time`, allows you to check a code for a specific point in time. This argument has no real practical use but can be handy for unittesting etc. The default value, `null`, means: use the current time.
103105

lib/TwoFactorAuth.php

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ public function createSecret($bits = 80, $requirecryptosecure = true)
6262

6363
/**
6464
* Calculate the code with given secret and point in time
65+
* @return string
6566
*/
6667
public function getCode($secret, $time = null)
6768
{
@@ -78,10 +79,16 @@ public function getCode($secret, $time = null)
7879

7980
/**
8081
* Check if the code is correct. This will accept codes starting from ($discrepancy * $period) sec ago to ($discrepancy * period) sec from now
82+
* @param string $secret
83+
* @param string $code This shouldn't be casted to integer - you may lose zeroes to the left
84+
* @param int $discrepancy
85+
* @param int|null $time
86+
* @param int $timeslice
87+
* @return bool
8188
*/
8289
public function verifyCode($secret, $code, $discrepancy = 1, $time = null, &$timeslice = 0)
8390
{
84-
$timetamp = $this->getTime($time);
91+
$timestamp = $this->getTime($time);
8592

8693
$timeslice = 0;
8794

@@ -90,7 +97,7 @@ public function verifyCode($secret, $code, $discrepancy = 1, $time = null, &$tim
9097
// of the match. Each iteration we either set the timeslice variable to the timeslice of the match
9198
// or set the value to itself. This is an effort to maintain constant execution time for the code.
9299
for ($i = -$discrepancy; $i <= $discrepancy; $i++) {
93-
$ts = $timetamp + ($i * $this->period);
100+
$ts = $timestamp + ($i * $this->period);
94101
$slice = $this->getTimeSlice($ts);
95102
$timeslice = $this->codeEquals($this->getCode($secret, $ts), $code) ? $slice : $timeslice;
96103
}
@@ -253,4 +260,4 @@ public function getTimeProvider()
253260
}
254261
return $this->timeprovider;
255262
}
256-
}
263+
}

tests/TwoFactorAuthTest.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,6 @@ public function testEnsureAllTimeProvidersReturnCorrectTime() {
136136
}
137137

138138
public function testVerifyCodeWorksCorrectly() {
139-
140139
$tfa = new TwoFactorAuth('Test', 6, 30);
141140
$this->assertEquals(true , $tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 1, 1426847190));
142141
$this->assertEquals(true , $tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 0, 1426847190 + 29)); //Test discrepancy
@@ -410,4 +409,4 @@ function __construct($time) {
410409
public function getTime() {
411410
return $this->time;
412411
}
413-
}
412+
}

0 commit comments

Comments
 (0)