AbstractChainedValidator   A
last analyzed

Complexity

Total Complexity 6

Size/Duplication

Total Lines 60
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 22
dl 0
loc 60
rs 10
c 0
b 0
f 0
wmc 6

2 Methods

Rating   Name   Duplication   Size   Complexity  
A validateElementWithKeys() 0 37 5
A __construct() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\SAML2\Signature;
6
7
use Exception;
8
use Psr\Log\LoggerInterface;
9
use SimpleSAML\SAML2\Utilities\ArrayCollection;
10
use SimpleSAML\XMLSecurity\Alg\Signature\SignatureAlgorithmFactory;
11
use SimpleSAML\XMLSecurity\CryptoEncoding\PEM;
12
use SimpleSAML\XMLSecurity\Key\X509Certificate as X509;
13
use SimpleSAML\XMLSecurity\XML\SignedElementInterface;
14
15
use function sprintf;
16
17
abstract class AbstractChainedValidator implements ChainedValidator
18
{
19
    /**
20
     * Constructor for AbstractChainedValidator
21
     *
22
     * @param \Psr\Log\LoggerInterface $logger
23
     */
24
    public function __construct(
25
        protected LoggerInterface $logger,
26
    ) {
27
    }
28
29
30
    /**
31
     * BC compatible version of the signature check
32
     *
33
     * @param \SimpleSAML\XMLSecurity\XML\SignedElementInterface $element
34
     * @param \SimpleSAML\SAML2\Utilities\ArrayCollection $pemCandidates
35
     *
36
     * @throws \Exception
37
     *
38
     * @return bool
39
     */
40
    protected function validateElementWithKeys(
41
        SignedElementInterface $element,
42
        ArrayCollection $pemCandidates,
43
    ): bool {
44
        $lastException = null;
45
        foreach ($pemCandidates as $index => $candidateKey) {
46
            $cert = new X509(PEM::fromString($candidateKey->getCertificate()));
47
            $verifier = (new SignatureAlgorithmFactory([]))->getAlgorithm(
48
                $element->getSignature()?->getSignedInfo()->getSignatureMethod()->getAlgorithm(),
49
                $cert->getPublicKey(),
50
            );
51
52
            try {
53
                /*
54
                 * Make sure that we have a valid signature on either the response or the assertion.
55
                 */
56
                $result = $element->verify($verifier);
57
                if ($result) {
58
                    $this->logger->debug(sprintf('Validation with key "#%d" succeeded', $index));
59
                    return true;
60
                }
61
                $this->logger->debug(sprintf('Validation with key "#%d" failed without exception.', $index));
62
            } catch (Exception $e) {
63
                $this->logger->debug(sprintf(
64
                    'Validation with key "#%d" failed with exception: %s',
65
                    $index,
66
                    $e->getMessage(),
67
                ));
68
69
                $lastException = $e;
70
            }
71
        }
72
73
        if ($lastException !== null) {
74
            throw $lastException;
75
        } else {
76
            return false;
77
        }
78
    }
79
}
80