Passed
Push — master ( 10440f...06d808 )
by Pol
01:46
created

WopiProofValidator::__constructX()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 8
c 1
b 0
f 0
nc 1
nop 3
dl 0
loc 10
ccs 0
cts 8
cp 0
crap 2
rs 10
1
<?php
2
3
/**
4
 * For the full copyright and license information, please view
5
 * the LICENSE file that was distributed with this source code.
6
 */
7
8
declare(strict_types=1);
9
10
namespace ChampsLibres\WopiLib\Service;
11
12
use ChampsLibres\WopiLib\Discovery\WopiDiscoveryInterface;
13
use ChampsLibres\WopiLib\Service\Contract\WopiProofValidatorInterface;
14
use phpseclib3\Crypt\PublicKeyLoader;
15
use Psr\Http\Message\RequestInterface;
16
use Throwable;
17
18
use function strlen;
19
20
use const OPENSSL_ALGO_SHA256;
21
22
final class WopiProofValidator implements WopiProofValidatorInterface
23
{
24
    private WopiDiscoveryInterface $wopiDiscovery;
25
26 2
    public function __construct(WopiDiscoveryInterface $wopiDiscovery)
27
    {
28 2
        $this->wopiDiscovery = $wopiDiscovery;
29 2
    }
30
31 1
    public function isValid(RequestInterface $request): bool
32
    {
33 1
        $xWopiProof = $request->getHeaderLine('X-WOPI-Proof');
34 1
        $xWopiProofOld = $request->getHeaderLine('X-WOPI-ProofOld');
35 1
        $timestamp = $request->getHeaderLine('X-WOPI-Timestamp');
36
37 1
        $key = $this->wopiDiscovery->getPublicKey();
38 1
        $keyOld = $this->wopiDiscovery->getPublicKeyOld();
39
40 1
        $url = (string) $request->getUri();
41 1
        $params = [];
42 1
        parse_str($request->getUri()->getQuery(), $params);
43
44 1
        $expected = sprintf(
45 1
            '%s%s%s%s%s%s',
46 1
            pack('N', strlen($params['access_token'])),
47 1
            $params['access_token'],
48 1
            pack('N', strlen($url)),
49 1
            strtoupper($url),
50 1
            pack('N', 8),
51 1
            pack('J', $timestamp)
52
        );
53
54 1
        return $this->verify($expected, $xWopiProof, $key)
55 1
            || $this->verify($expected, $xWopiProofOld, $key)
56 1
            || $this->verify($expected, $xWopiProof, $keyOld);
57
    }
58
59
    /**
60
     * @param string $key The key in MSBLOB format
61
     */
62 1
    private function verify(string $expected, string $proof, string $key): bool
63
    {
64
        try {
65 1
            $key = PublicKeyLoader::loadPublicKey($key);
66
        } catch (Throwable $e) {
67
            return false;
68
        }
69
70 1
        return 1 === openssl_verify(
71
            $expected,
72 1
            base64_decode($proof, true),
73
            $key,
74 1
            OPENSSL_ALGO_SHA256
75
        );
76
    }
77
}
78