diff options
author | Andrew Dolgov <[email protected]> | 2021-02-26 19:16:17 +0300 |
---|---|---|
committer | Andrew Dolgov <[email protected]> | 2021-02-26 19:16:17 +0300 |
commit | 3fd785654372d493c031d9b541ab33a881023a32 (patch) | |
tree | 0a76cb410217074378de3d7012b95754cd3c7e6f /vendor/spomky-labs/otphp/src/HOTP.php | |
parent | bc4475b6698f5a74e475674aa7af43253c459892 (diff) |
* switch to composer for qrcode and otp dependencies
* move most OTP-related stuff into userhelper
* remove old phpqrcode and otphp libraries
Diffstat (limited to 'vendor/spomky-labs/otphp/src/HOTP.php')
-rw-r--r-- | vendor/spomky-labs/otphp/src/HOTP.php | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/vendor/spomky-labs/otphp/src/HOTP.php b/vendor/spomky-labs/otphp/src/HOTP.php new file mode 100644 index 000000000..a2f4a2395 --- /dev/null +++ b/vendor/spomky-labs/otphp/src/HOTP.php @@ -0,0 +1,103 @@ +<?php + +declare(strict_types=1); + +/* + * The MIT License (MIT) + * + * Copyright (c) 2014-2019 Spomky-Labs + * + * This software may be modified and distributed under the terms + * of the MIT license. See the LICENSE file for details. + */ + +namespace OTPHP; + +use Assert\Assertion; + +final class HOTP extends OTP implements HOTPInterface +{ + protected function __construct(?string $secret, int $counter, string $digest, int $digits) + { + parent::__construct($secret, $digest, $digits); + $this->setCounter($counter); + } + + public static function create(?string $secret = null, int $counter = 0, string $digest = 'sha1', int $digits = 6): HOTPInterface + { + return new self($secret, $counter, $digest, $digits); + } + + protected function setCounter(int $counter): void + { + $this->setParameter('counter', $counter); + } + + public function getCounter(): int + { + return $this->getParameter('counter'); + } + + private function updateCounter(int $counter): void + { + $this->setCounter($counter); + } + + public function getProvisioningUri(): string + { + return $this->generateURI('hotp', ['counter' => $this->getCounter()]); + } + + /** + * If the counter is not provided, the OTP is verified at the actual counter. + */ + public function verify(string $otp, ?int $counter = null, ?int $window = null): bool + { + Assertion::greaterOrEqualThan($counter, 0, 'The counter must be at least 0.'); + + if (null === $counter) { + $counter = $this->getCounter(); + } elseif ($counter < $this->getCounter()) { + return false; + } + + return $this->verifyOtpWithWindow($otp, $counter, $window); + } + + private function getWindow(?int $window): int + { + return abs($window ?? 0); + } + + private function verifyOtpWithWindow(string $otp, int $counter, ?int $window): bool + { + $window = $this->getWindow($window); + + for ($i = $counter; $i <= $counter + $window; ++$i) { + if ($this->compareOTP($this->at($i), $otp)) { + $this->updateCounter($i + 1); + + return true; + } + } + + return false; + } + + /** + * @return array<string, mixed> + */ + protected function getParameterMap(): array + { + $v = array_merge( + parent::getParameterMap(), + ['counter' => function ($value): int { + Assertion::greaterOrEqualThan((int) $value, 0, 'Counter must be at least 0.'); + + return (int) $value; + }] + ); + + return $v; + } +} |