Passed
Pull Request — master (#18)
by
unknown
08:11
created

ChainValidator::validateCertificates()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 19
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
cc 4
eloc 16
c 0
b 0
f 0
nc 6
nop 1
dl 0
loc 19
ccs 0
cts 14
cp 0
crap 20
rs 9.7333
1
<?php
2
3
namespace MadWizard\WebAuthn\Pki;
4
5
use DateTimeImmutable;
6
use Exception;
7
use MadWizard\WebAuthn\Exception\VerificationException;
8
use Psr\Log\LoggerAwareInterface;
9
use Psr\Log\LoggerAwareTrait;
10
use Psr\Log\NullLogger;
11
use Sop\X509\Certificate\Certificate;
12
use Sop\X509\CertificationPath\CertificationPath;
13
use Sop\X509\CertificationPath\Exception\PathValidationException;
14
use Sop\X509\CertificationPath\PathValidation\PathValidationConfig;
15
16
final class ChainValidator implements ChainValidatorInterface, LoggerAwareInterface
17
{
18
    use LoggerAwareTrait;
19
20
    public const MAX_VALIDATION_LENGTH = 5;
21
22
    /**
23
     * @var CertificateStatusResolverInterface
24
     */
25
    private $statusResolver;
26
27 18
    public function __construct(CertificateStatusResolverInterface $statusResolver)
28
    {
29 18
        $this->statusResolver = $statusResolver;
30 18
        $this->logger = new NullLogger();
31 18
    }
32
33
    private function getReferenceDate(): DateTimeImmutable
34
    {
35
        return new DateTimeImmutable();
36
    }
37
38
    private function validateCertificates(X509Certificate ...$certificates): bool
39
    {
40
        try {
41
            $pathCerts = array_map(function (X509Certificate $c) {
42
                return Certificate::fromDER($c->asDer());
43
            }, $certificates);
44
            $path = new CertificationPath(...$pathCerts);
45
            $config = new PathValidationConfig($this->getReferenceDate(), self::MAX_VALIDATION_LENGTH);
46
        } catch (Exception $e) {
47
            throw new VerificationException(sprintf('Failed to validate certificate: %s', $e->getMessage()), 0, $e);
48
        }
49
        try {
50
            $path->validate($config);
51
            return true;
52
        } catch (PathValidationException $e) {
53
            $this->logger->debug(sprintf('Path validation of certificate failed: %s', $e->getMessage()));
0 ignored issues
show
Bug introduced by
The method debug() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

53
            $this->logger->/** @scrutinizer ignore-call */ 
54
                           debug(sprintf('Path validation of certificate failed: %s', $e->getMessage()));

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
54
            return false;
55
        } catch (Exception $e) {
56
            throw new VerificationException(sprintf('Failed to validate certificate: %s', $e->getMessage()), 0, $e);
57
        }
58
    }
59
60
    public function validateChain(X509Certificate ...$certificates): bool
61
    {
62
        if ($this->validateCertificates(...$certificates)) {
63
            $numCerts = count($certificates);
64
            for ($i = 1; $i < $numCerts; $i++) {
65
                if ($this->statusResolver->isRevoked($certificates[$i], ...array_slice($certificates, 0, $i))) {
66
                    return false;
67
                }
68
            }
69
            return true;
70
        }
71
        return false;
72
    }
73
}
74