Signature   A
last analyzed

Complexity

Total Complexity 11

Size/Duplication

Total Lines 159
Duplicated Lines 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 49
c 3
b 0
f 0
dl 0
loc 159
rs 10
wmc 11

8 Methods

Rating   Name   Duplication   Size   Complexity  
A toXML() 0 17 3
A fromXML() 0 49 2
A getKeyInfo() 0 3 1
A __construct() 0 9 1
A getObjects() 0 3 1
A getSignedInfo() 0 3 1
A getId() 0 3 1
A getSignatureValue() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\XMLSecurity\XML\ds;
6
7
use DOMElement;
8
use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait};
9
use SimpleSAML\XMLSchema\Exception\{InvalidDOMElementException, MissingElementException, TooManyElementsException};
10
use SimpleSAML\XMLSchema\Type\IDValue;
11
use SimpleSAML\XMLSecurity\Assert\Assert;
12
use SimpleSAML\XMLSecurity\Constants as C;
13
14
use function array_pop;
15
use function strval;
16
17
/**
18
 * Class representing a ds:Signature element.
19
 *
20
 * @package simplesamlphp/xml-security
21
 */
22
final class Signature extends AbstractDsElement implements SchemaValidatableElementInterface
23
{
24
    use SchemaValidatableElementTrait;
0 ignored issues
show
introduced by
The trait SimpleSAML\XML\SchemaValidatableElementTrait requires some properties which are not provided by SimpleSAML\XMLSecurity\XML\ds\Signature: $message, $line
Loading history...
25
26
    /**
27
     * Signature constructor.
28
     *
29
     * @param \SimpleSAML\XMLSecurity\XML\ds\SignedInfo $signedInfo
30
     * @param \SimpleSAML\XMLSecurity\XML\ds\SignatureValue $signatureValue
31
     * @param \SimpleSAML\XMLSecurity\XML\ds\KeyInfo|null $keyInfo
32
     * @param \SimpleSAML\XMLSecurity\XML\ds\DsObject[] $objects
33
     * @param \SimpleSAML\XMLSchema\Type\IDValue|null $Id
34
     */
35
    public function __construct(
36
        protected SignedInfo $signedInfo,
37
        protected SignatureValue $signatureValue,
38
        protected ?KeyInfo $keyInfo = null,
39
        protected array $objects = [],
40
        protected ?IDValue $Id = null,
41
    ) {
42
        Assert::maxCount($objects, C::UNBOUNDED_LIMIT);
43
        Assert::allIsInstanceOf($objects, DsObject::class);
44
    }
45
46
47
    /**
48
     * Get the Id used for this signature.
49
     *
50
     * @return \SimpleSAML\XMLSchema\Type\IDValue|null
51
     */
52
    public function getId(): ?IDValue
53
    {
54
        return $this->Id;
55
    }
56
57
58
    /**
59
     * @return \SimpleSAML\XMLSecurity\XML\ds\SignedInfo
60
     */
61
    public function getSignedInfo(): SignedInfo
62
    {
63
        return $this->signedInfo;
64
    }
65
66
67
    /**
68
     * @return \SimpleSAML\XMLSecurity\XML\ds\SignatureValue
69
     */
70
    public function getSignatureValue(): SignatureValue
71
    {
72
        return $this->signatureValue;
73
    }
74
75
76
    /**
77
     * @return \SimpleSAML\XMLSecurity\XML\ds\KeyInfo|null
78
     */
79
    public function getKeyInfo(): ?KeyInfo
80
    {
81
        return $this->keyInfo;
82
    }
83
84
85
    /**
86
     * Get the array of ds:Object elements attached to this signature.
87
     *
88
     * @return \SimpleSAML\XMLSecurity\XML\ds\DsObject[]
89
     */
90
    public function getObjects(): array
91
    {
92
        return $this->objects;
93
    }
94
95
96
    /**
97
     * Convert XML into a Signature element
98
     *
99
     * @param \DOMElement $xml
100
     * @return static
101
     *
102
     * @throws \SimpleSAML\XMLSchema\Exception\InvalidDOMElementException
103
     *   If the qualified name of the supplied element is wrong
104
     */
105
    public static function fromXML(DOMElement $xml): static
106
    {
107
        Assert::same($xml->localName, 'Signature', InvalidDOMElementException::class);
108
        Assert::same($xml->namespaceURI, Signature::NS, InvalidDOMElementException::class);
109
110
        $signedInfo = SignedInfo::getChildrenOfClass($xml);
111
        Assert::minCount(
112
            $signedInfo,
113
            1,
114
            'ds:Signature needs exactly one ds:SignedInfo element.',
115
            MissingElementException::class,
116
        );
117
        Assert::maxCount(
118
            $signedInfo,
119
            1,
120
            'ds:Signature needs exactly one ds:SignedInfo element.',
121
            TooManyElementsException::class,
122
        );
123
124
        $signatureValue = SignatureValue::getChildrenOfClass($xml);
125
        Assert::minCount(
126
            $signatureValue,
127
            1,
128
            'ds:Signature needs exactly one ds:SignatureValue element.',
129
            MissingElementException::class,
130
        );
131
        Assert::maxCount(
132
            $signatureValue,
133
            1,
134
            'ds:Signature needs exactly one ds:SignatureValue element.',
135
            TooManyElementsException::class,
136
        );
137
138
        $keyInfo = KeyInfo::getChildrenOfClass($xml);
139
        Assert::maxCount(
140
            $keyInfo,
141
            1,
142
            'ds:Signature can hold a maximum of one ds:KeyInfo element.',
143
            TooManyElementsException::class,
144
        );
145
146
        $objects = DsObject::getChildrenOfClass($xml);
147
148
        return new static(
149
            array_pop($signedInfo),
150
            array_pop($signatureValue),
151
            empty($keyInfo) ? null : array_pop($keyInfo),
152
            $objects,
153
            self::getOptionalAttribute($xml, 'Id', IDValue::class, null),
154
        );
155
    }
156
157
158
    /**
159
     * Convert this Signature element to XML.
160
     *
161
     * @param \DOMElement|null $parent The element we should append this Signature element to.
162
     * @return \DOMElement
163
     */
164
    public function toXML(?DOMElement $parent = null): DOMElement
165
    {
166
        $e = $this->instantiateParentElement($parent);
167
168
        if ($this->getId() !== null) {
169
            $e->setAttribute('Id', strval($this->getId()));
170
        }
171
172
        $this->getSignedInfo()->toXML($e);
173
        $this->getSignatureValue()->toXML($e);
174
        $this->getKeyInfo()?->toXML($e);
175
176
        foreach ($this->getObjects() as $o) {
177
            $o->toXML($e);
178
        }
179
180
        return $e;
181
    }
182
}
183