OneTimePasswordValidator::validate()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 13
rs 9.8333
c 0
b 0
f 0
cc 4
nc 4
nop 1
1
<?php
2
3
/*
4
 * This file is part of the 2amigos/2fa-library project.
5
 *
6
 * (c) 2amigOS! <http://2amigos.us/>
7
 *
8
 * For the full copyright and license information, please view
9
 * the LICENSE file that was distributed with this source code.
10
 */
11
12
namespace Da\TwoFA\Validator;
13
14
use Da\TwoFA\Contracts\ValidatorInterface;
15
use Da\TwoFA\Traits\OathTrait;
16
17
class OneTimePasswordValidator implements ValidatorInterface
18
{
19
    use OathTrait;
20
21
    /**
22
     * @var string
23
     */
24
    protected $seed;
25
    /**
26
     * @var int
27
     */
28
    protected $cycles;
29
    /**
30
     * @var int
31
     */
32
    protected $startTime;
33
    /**
34
     * @var int
35
     */
36
    protected $time;
37
    /**
38
     * @var int|null
39
     */
40
    protected $previousTime;
41
42
    /**
43
     * OneTimePasswordValidator constructor.
44
     *
45
     * @param string   $seed
46
     * @param int      $cycles
47
     * @param int      $tokenLength
48
     * @param int      $startTime
49
     * @param int      $time
50
     * @param int|null $previousTime
51
     */
52
    public function __construct(
53
        string $seed,
54
        int $cycles,
55
        int $tokenLength,
56
        int $startTime,
57
        int $time,
58
        int $previousTime = null
59
    ) {
60
        $this->seed = $seed;
61
        $this->cycles = $cycles;
62
        $this->tokenLength = $tokenLength;
63
        $this->startTime = $startTime;
64
        $this->time = $time;
65
        $this->previousTime = $previousTime;
66
    }
67
68
    /**
69
     * Validates OTP. If `$previousTime` has been added, it will return the `$startTime`, otherwise it will return a
70
     * bool value. This is done to prevent an attacker to use the same key again.
71
     *
72
     * @param mixed $value
73
     *
74
     * @return bool|int
75
     */
76
    public function validate($value)
77
    {
78
        for (; $this->startTime <= $this->time + $this->cycles; $this->startTime++) {
79
            if (hash_equals($this->oathHotp($this->seed, $this->startTime), $value)) {
80
                return
81
                    null === $this->previousTime
82
                        ? true
83
                        : $this->startTime;
84
            }
85
        }
86
87
        return false;
88
    }
89
}
90