generated from Nodarx/template
92e85aed47
Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
39 lines
1.6 KiB
PHP
39 lines
1.6 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
namespace KTXM\ServiceWopi\Host;
|
|
|
|
use phpseclib3\Crypt\RSA;
|
|
use phpseclib3\Math\BigInteger;
|
|
|
|
class ProofValidator
|
|
{
|
|
public function valid(array $keys, string $token, string $url, string $timestamp, string $proof, string $oldProof, int $now): bool
|
|
{
|
|
if (!preg_match('/^[0-9]{1,18}$/D', $timestamp)) { return false; }
|
|
$ticks = (int) $timestamp;
|
|
// .NET ticks: 100 ns since 0001-01-01. Bound both stale and future requests.
|
|
$seconds = intdiv($ticks, 10000000) - 62135596800;
|
|
if (abs($seconds - $now) > 1200) { return false; }
|
|
$url = strtoupper($url);
|
|
$data = pack('N', strlen($token)) . $token . pack('N', strlen($url)) . $url
|
|
. pack('N', 8) . pack('J', $ticks);
|
|
return $this->verify($keys, '', $proof, $data)
|
|
|| $this->verify($keys, '', $oldProof, $data)
|
|
|| $this->verify($keys, 'old', $proof, $data);
|
|
}
|
|
|
|
private function verify(array $keys, string $prefix, string $signature, string $data): bool
|
|
{
|
|
$signature = base64_decode($signature, true);
|
|
$modulus = base64_decode($keys[$prefix . 'modulus'] ?? '', true);
|
|
$exponent = base64_decode($keys[$prefix . 'exponent'] ?? '', true);
|
|
if (!$signature || !$modulus || !$exponent || strlen($modulus) > 1024 || strlen($exponent) > 8) { return false; }
|
|
try {
|
|
$key = RSA::loadPublicKey(['n' => new BigInteger($modulus, 256), 'e' => new BigInteger($exponent, 256)]);
|
|
return $key->withPadding(RSA::SIGNATURE_PKCS1)->withHash('sha256')->verify($data, $signature);
|
|
} catch (\Throwable) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|