Passed
Pull Request — master (#2)
by Jaime Pérez
03:26
created

SignedElementTrait::getValidatingCertificates()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 19
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 9
nc 5
nop 0
dl 0
loc 19
rs 9.9666
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\XMLSecurity\XML;
6
7
use Exception;
8
use SimpleSAML\Assert\Assert;
9
use SimpleSAML\XMLSecurity\XML\ds\Signature;
10
use SimpleSAML\XMLSecurity\XML\SignedElementInterface;
11
use SimpleSAML\XMLSecurity\XMLSecurityKey;
12
13
/**
14
 * Helper trait for processing signed elements.
15
 *
16
 * @package simplesamlphp/xml-security
17
 */
18
trait SignedElementTrait
19
{
20
    /**
21
     * The signature of this element.
22
     *
23
     * @var \SimpleSAML\XMLSecurity\XML\ds\Signature $signature
24
     */
25
    protected Signature $signature;
26
27
28
    /**
29
     * Get the signature element of this object.
30
     *
31
     * @return \SimpleSAML\XMLSecurity\XML\ds\Signature
32
     */
33
    public function getSignature(): ?Signature
34
    {
35
        return $this->signature;
36
    }
37
38
39
    /**
40
     * Initialize a signed element from XML.
41
     *
42
     * @param \SimpleSAML\XMLSecurity\XML\ds\Signature $signature The ds:Signature object
43
     */
44
    protected function setSignature(Signature $signature): void
45
    {
46
        $this->signature = $signature;
47
    }
48
49
50
    /**
51
     * Validate this element against a public key.
52
     *
53
     * true is returned on success, false is returned if we don't have any
54
     * signature we can validate. An exception is thrown if the signature
55
     * validation fails.
56
     *
57
     * @param  \SimpleSAML\XMLSecurity\XMLSecurityKey $key The key we should check against.
58
     * @return \SimpleSAML\XMLSecurity\XML\SignedElementInterface The Signed element if it was validated.
59
     * @throws \Exception
60
     */
61
    public function validate(XMLSecurityKey $key): SignedElementInterface
62
    {
63
        if ($this->signature === null) {
64
            throw new Exception("Unsigned element");
65
        }
66
67
        Assert::eq(
68
            $key->getAlgorithm(),
69
            $this->signature->getAlgorithm(),
0 ignored issues
show
Bug introduced by
The method getAlgorithm() does not exist on SimpleSAML\XMLSecurity\XML\ds\Signature. ( Ignorable by Annotation )

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

69
            $this->signature->/** @scrutinizer ignore-call */ 
70
                              getAlgorithm(),

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...
70
            'Algorithm provided in key does not match algorithm used in signature.'
71
        );
72
73
        // check the signature
74
        $signer = $this->signature->getSigner();
0 ignored issues
show
Bug introduced by
The method getSigner() does not exist on SimpleSAML\XMLSecurity\XML\ds\Signature. Did you maybe mean getSignedInfo()? ( Ignorable by Annotation )

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

74
        /** @scrutinizer ignore-call */ 
75
        $signer = $this->signature->getSigner();

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...
75
        if ($signer->verify($key) === 1) {
76
            return $this->getElement();
0 ignored issues
show
Bug introduced by
It seems like getElement() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

76
            return $this->/** @scrutinizer ignore-call */ getElement();
Loading history...
77
        }
78
79
        throw new Exception("Unable to validate Signature");
80
    }
81
82
83
    /**
84
     * Retrieve certificates that sign this element.
85
     *
86
     * @return array Array with certificates.
87
     * @throws \Exception if an error occurs while trying to extract the public key from a certificate.
88
     */
89
    public function getValidatingCertificates(): array
90
    {
91
        $ret = [];
92
        foreach ($this->signature->getCertificates() as $cert) {
0 ignored issues
show
Bug introduced by
The method getCertificates() does not exist on SimpleSAML\XMLSecurity\XML\ds\Signature. ( Ignorable by Annotation )

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

92
        foreach ($this->signature->/** @scrutinizer ignore-call */ getCertificates() as $cert) {

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...
93
            // extract the public key from the certificate for validation.
94
            $key = new XMLSecurityKey($this->signature->getAlgorithm(), ['type' => 'public']);
95
            $key->loadKey($cert);
96
97
            try {
98
                // check the signature.
99
                if ($this->validate($key)) {
100
                    $ret[] = $cert;
101
                }
102
            } catch (Exception $e) {
103
                // this certificate does not sign this element.
104
            }
105
        }
106
107
        return $ret;
108
    }
109
}
110