%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /www/varak.net/nextcloud.varak.net/apps/twofactor_totp/vendor/rullzer/easytotp/src/
Upload File :
Create Path :
Current File : /www/varak.net/nextcloud.varak.net/apps/twofactor_totp/vendor/rullzer/easytotp/src/TOTP.php

<?php
declare(strict_types=1);
/**
 * @copyright Copyright (c) 2019, Roeland Jago Douma <roeland@famdouma.nl>
 *
 * @author Roeland Jago Douma <roeland@famdouma.nl>
 *
 * @license GNU AGPL version 3 or any later version
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

namespace EasyTOTP;

class TOTP implements TOTPInterface  {

	/** @var string */
	private $secret;
	/** @var int */
	private $digits;
	/** @var int */
	private $offset;
	/** @var int */
	private $timeStep;
	/** @var string */
	private $hashFunction;
	/** @var TimeService */
	private $timeService;

	public function __construct(string $secret, int $timeStep, int $digits, int $offset, string $hashFunction, TimeService $timeService) {
		$this->secret = $secret;
		$this->timeStep = $timeStep;
		$this->digits = $digits;
		$this->offset = $offset;
		$this->hashFunction = $hashFunction;
		$this->timeService = $timeService;
	}

	public function verify(string $otp, int $drift = 1, ?int $lastKnownCounter = null): TOTPResultInterface {
		$currentCounter = $this->getCurrentCounter();

		$start = $currentCounter - $drift;
		$end = $currentCounter + $drift;

		for ($i = $start; $i <= $end; $i++) {
			// Skip counters smaller than the minimum
			if ($lastKnownCounter !== null && $i <= $lastKnownCounter) {
				continue;
			}

			if (hash_equals($this->hotp($i), $otp)) {
				return new TOTPValidResult(
					$i,
					$i - $currentCounter
				);
			}
		}

		return new TOTPInvalidResult();
	}

	public function getDigits(): int {
		return $this->digits;
	}

	public function getHashFunction(): string {
		return $this->hashFunction;
	}

	public function getOffset(): int {
		return $this->offset;
	}

	public function getSecret(): string {
		return $this->secret;
	}

	public function getTimeStep(): int {
		return $this->timeStep;
	}

	private function binaryCounter(int $counter): string {
		if (PHP_INT_SIZE === 4) {
			/*
			 * Manually do 64bit magic
			 * This will do boom in 2038 ;)
			 */
			return pack('N*', 0) . pack('N*', $counter);
		}

		return pack('J', $counter);
	}

	/**
	 * See https://tools.ietf.org/html/rfc4226#section-5
	 */
	private function hotp(int $counter): string {
		$hash = hash_hmac(
			$this->hashFunction,
			$this->binaryCounter($counter),
			$this->secret,
			true
		);

		return str_pad((string)$this->truncate($hash), $this->digits, '0', STR_PAD_LEFT);
	}

	private function truncate(string $hash): int {
		$offset = \ord($hash[strlen($hash)-1]) & 0xf;

		return (
				((\ord($hash[$offset + 0]) & 0x7f) << 24) |
				((\ord($hash[$offset + 1]) & 0xff) << 16) |
				((\ord($hash[$offset + 2]) & 0xff) << 8) |
				(\ord($hash[$offset + 3]) & 0xff)
			) % (10 ** $this->digits);
	}

	private function getCurrentCounter(): int {
		return (int)floor(($this->timeService->getTime() + $this->offset) / $this->timeStep);
	}

}

Zerion Mini Shell 1.0