Passed
Pull Request — master (#17)
by Jaime Pérez
02:00
created

Signature::setId()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 3
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\XMLSecurity\XML\ds;
6
7
use DOMElement;
8
use SimpleSAML\Assert\Assert;
9
use SimpleSAML\XML\Chunk;
10
use SimpleSAML\XML\Constants;
11
use SimpleSAML\XML\Exception\InvalidDOMElementException;
12
13
/**
14
 * Class representing a ds:Signature element.
15
 *
16
 * @package simplesamlphp/xml-security
17
 */
18
final class Signature extends AbstractDsElement
19
{
20
    /** @var \SimpleSAML\XMLSecurity\XML\ds\SignedInfo */
21
    protected SignedInfo $signedInfo;
22
23
    /** @var \SimpleSAML\XMLSecurity\XML\ds\SignatureValue */
24
    protected SignatureValue $signatureValue;
25
26
    /** @var \SimpleSAML\XMLSecurity\XML\ds\KeyInfo|null $keyInfo */
27
    protected ?KeyInfo $keyInfo;
28
29
    /** @var \SimpleSAML\XML\Chunk[] */
30
    protected array $objects;
31
32
    /** @var string|null */
33
    protected ?string $Id;
34
35
36
    /**
37
     * Signature constructor.
38
     *
39
     * @param \SimpleSAML\XMLSecurity\XML\ds\SignedInfo $signedInfo
40
     * @param \SimpleSAML\XMLSecurity\XML\ds\SignatureValue $signatureValue
41
     * @param \SimpleSAML\XMLSecurity\XML\ds\KeyInfo|null $keyInfo
42
     * @param \SimpleSAML\XML\Chunk[] $objects
43
     * @param string|null $Id
44
     */
45
    public function __construct(
46
        SignedInfo $signedInfo,
47
        SignatureValue $signatureValue,
48
        ?KeyInfo $keyInfo,
49
        array $objects = [],
50
        ?string $Id = null
51
    ) {
52
        $this->setSignedInfo($signedInfo);
53
        $this->setSignatureValue($signatureValue);
54
        $this->setKeyInfo($keyInfo);
55
        $this->setObjects($objects);
56
        $this->setId($Id);
57
    }
58
59
60
    /**
61
     * Get the Id used for this signature.
62
     *
63
     * @return string|null
64
     */
65
    public function getId(): ?string
66
    {
67
        return $this->Id;
68
    }
69
70
71
    /**
72
     * Set the Id used for this signature.
73
     *
74
     * @param string|null $Id
75
     */
76
    protected function setId(?string $Id): void
77
    {
78
        $this->Id = $Id;
79
    }
80
81
82
    /**
83
     * @param \SimpleSAML\XMLSecurity\XML\ds\SignedInfo
84
     */
85
    protected function setSignedInfo(SignedInfo $signedInfo): void
86
    {
87
        $this->signedInfo = $signedInfo;
88
    }
89
90
91
    /**
92
     * @return \SimpleSAML\XMLSecurity\XML\ds\SignedInfo
93
     */
94
    public function getSignedInfo(): SignedInfo
95
    {
96
        return $this->signedInfo;
97
    }
98
99
100
    /**
101
     * @param \SimpleSAML\XMLSecurity\XML\ds\SignatureValue
102
     */
103
    protected function setSignatureValue(SignatureValue $signatureValue): void
104
    {
105
        $this->signatureValue = $signatureValue;
106
    }
107
108
109
    /**
110
     * @return \SimpleSAML\XMLSecurity\XML\ds\SignatureValue
111
     */
112
    public function getSignatureValue(): SignatureValue
113
    {
114
        return $this->signatureValue;
115
    }
116
117
118
    /**
119
     * @param \SimpleSAML\XMLSecurity\XML\ds\KeyInfo|null
120
     */
121
    protected function setKeyInfo(?KeyInfo $keyInfo): void
122
    {
123
        $this->keyInfo = $keyInfo;
124
    }
125
126
127
    /**
128
     * @return \SimpleSAML\XMLSecurity\XML\ds\KeyInfo|null
129
     */
130
    public function getKeyInfo(): ?KeyInfo
131
    {
132
        return $this->keyInfo;
133
    }
134
135
136
    /**
137
     * Get the array of ds:Object elements attached to this signature.
138
     *
139
     * @return \SimpleSAML\XML\Chunk[]
140
     */
141
    public function getObjects(): array
142
    {
143
        return $this->objects;
144
    }
145
146
147
    /**
148
     * Set the array of ds:Object elements attached to this signature.
149
     *
150
     * @param \SimpleSAML\XML\Chunk[] $objects
151
     */
152
    protected function setObjects(array $objects): void
153
    {
154
        Assert::allIsInstanceOf($objects, Chunk::class);
155
156
        foreach ($objects as $o) {
157
            Assert::true(
158
                $o->getNamespaceURI() === Constants::NS_XDSIG
159
                && $o->getLocalName() === 'Object',
160
                'Only elements of type ds:Object are allowed.'
161
            );
162
        }
163
164
        $this->objects = $objects;
165
    }
166
167
168
    /**
169
     * Convert XML into a Signature element
170
     *
171
     * @param \DOMElement $xml
172
     * @return \SimpleSAML\XML\AbstractXMLElement
173
     *
174
     * @throws \SimpleSAML\XML\Exception\InvalidDOMElementException
175
     *   If the qualified name of the supplied element is wrong
176
     */
177
    public static function fromXML(DOMElement $xml): object
178
    {
179
        Assert::same($xml->localName, 'Signature', InvalidDOMElementException::class);
180
        Assert::same($xml->namespaceURI, Signature::NS, InvalidDOMElementException::class);
181
182
        $Id = self::getAttribute($xml, 'Id', null);
183
184
        $signedInfo = SignedInfo::getChildrenOfClass($xml);
185
        Assert::count($signedInfo, 1, 'ds:Signature needs exactly one ds:SignedInfo element.');
186
187
        $signatureValue = SignatureValue::getChildrenOfClass($xml);
188
        Assert::count($signatureValue, 1, 'ds:Signature needs exactly one ds:SignatureValue element.');
189
190
        $keyInfo = KeyInfo::getChildrenOfClass($xml);
191
        Assert::maxCount($keyInfo, 1, 'ds:Signature can hold a maximum of one ds:KeyInfo element.');
192
193
        $objects = [];
194
        foreach ($xml->childNodes as $o) {
195
            if (
196
                $o instanceof DOMElement
197
                && $o->namespaceURI === Constants::NS_XDSIG
198
                && $o->localName === 'Object'
199
            ) {
200
                $objects[] = Chunk::fromXML($o);
201
            }
202
        }
203
204
        return new self(
205
            array_pop($signedInfo),
206
            array_pop($signatureValue),
207
            empty($keyInfo) ? null : array_pop($keyInfo),
208
            $objects,
209
            $Id
210
        );
211
    }
212
213
214
    /**
215
     * Convert this Signature element to XML.
216
     *
217
     * @param \DOMElement|null $parent The element we should append this Signature element to.
218
     * @return \DOMElement
219
     */
220
    public function toXML(DOMElement $parent = null): DOMElement
221
    {
222
        $e = $this->instantiateParentElement($parent);
223
224
        if ($this->Id !== null) {
225
            $e->setAttribute('Id', $this->Id);
226
        }
227
228
        $this->signedInfo->toXML($e);
229
        $this->signatureValue->toXML($e);
230
231
        if ($this->keyInfo !== null) {
232
            $this->keyInfo->toXML($e);
233
        }
234
235
        foreach ($this->objects as $o) {
236
            $o->toXML($e);
237
        }
238
239
        return $e;
240
    }
241
}
242