Issues (88)

src/XML/ds/SignedInfo.php (2 issues)

1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\XMLSecurity\XML\ds;
6
7
use DOMElement;
8
use SimpleSAML\XML\Constants as C;
9
use SimpleSAML\XML\Exception\InvalidDOMElementException;
10
use SimpleSAML\XML\Exception\MissingElementException;
11
use SimpleSAML\XML\Exception\TooManyElementsException;
12
use SimpleSAML\XML\SchemaValidatableElementInterface;
13
use SimpleSAML\XML\SchemaValidatableElementTrait;
14
use SimpleSAML\XMLSecurity\Assert\Assert;
15
use SimpleSAML\XMLSecurity\Exception\InvalidArgumentException;
16
use SimpleSAML\XMLSecurity\XML\CanonicalizableElementInterface;
17
use SimpleSAML\XMLSecurity\XML\CanonicalizableElementTrait;
18
19
use function array_pop;
20
21
/**
22
 * Class representing a ds:SignedInfo element.
23
 *
24
 * @package simplesamlphp/xml-security
25
 */
26
final class SignedInfo extends AbstractDsElement implements
27
    CanonicalizableElementInterface,
28
    SchemaValidatableElementInterface
29
{
30
    use CanonicalizableElementTrait;
0 ignored issues
show
The trait SimpleSAML\XMLSecurity\X...nicalizableElementTrait requires the property $ownerDocument which is not provided by SimpleSAML\XMLSecurity\XML\ds\SignedInfo.
Loading history...
31
    use SchemaValidatableElementTrait;
0 ignored issues
show
The trait SimpleSAML\XML\SchemaValidatableElementTrait requires some properties which are not provided by SimpleSAML\XMLSecurity\XML\ds\SignedInfo: $message, $line
Loading history...
32
33
    /*
34
     * @var DOMElement
35
     */
36
    protected ?DOMElement $xml = null;
37
38
39
    /**
40
     * Initialize a SignedInfo.
41
     *
42
     * @param \SimpleSAML\XMLSecurity\XML\ds\CanonicalizationMethod $canonicalizationMethod
43
     * @param \SimpleSAML\XMLSecurity\XML\ds\SignatureMethod $signatureMethod
44
     * @param \SimpleSAML\XMLSecurity\XML\ds\Reference[] $references
45
     * @param string|null $Id
46
     */
47
    public function __construct(
48
        protected CanonicalizationMethod $canonicalizationMethod,
49
        protected SignatureMethod $signatureMethod,
50
        protected array $references,
51
        protected ?string $Id = null,
52
    ) {
53
        Assert::maxCount($references, C::UNBOUNDED_LIMIT);
54
        Assert::allIsInstanceOf($references, Reference::class, InvalidArgumentException::class);
55
        Assert::nullOrValidNCName($Id);
56
    }
57
58
59
    /**
60
     * Collect the value of the canonicalizationMethod-property
61
     *
62
     * @return \SimpleSAML\XMLSecurity\XML\ds\CanonicalizationMethod
63
     */
64
    public function getCanonicalizationMethod(): CanonicalizationMethod
65
    {
66
        return $this->canonicalizationMethod;
67
    }
68
69
70
    /**
71
     * Collect the value of the signatureMethod-property
72
     *
73
     * @return \SimpleSAML\XMLSecurity\XML\ds\SignatureMethod
74
     */
75
    public function getSignatureMethod(): SignatureMethod
76
    {
77
        return $this->signatureMethod;
78
    }
79
80
81
    /**
82
     * Collect the value of the references-property
83
     *
84
     * @return \SimpleSAML\XMLSecurity\XML\ds\Reference[]
85
     */
86
    public function getReferences(): array
87
    {
88
        return $this->references;
89
    }
90
91
92
    /**
93
     * Collect the value of the Id-property
94
     *
95
     * @return string|null
96
     */
97
    public function getId(): ?string
98
    {
99
        return $this->Id;
100
    }
101
102
103
    /**
104
     * @inheritDoc
105
     */
106
    protected function getOriginalXML(): DOMElement
107
    {
108
        if ($this->xml !== null) {
109
            return $this->xml;
110
        }
111
112
        return $this->toXML();
113
    }
114
115
116
    /**
117
     * Convert XML into a SignedInfo instance
118
     *
119
     * @param \DOMElement $xml The XML element we should load
120
     * @return static
121
     *
122
     * @throws \SimpleSAML\XML\Exception\InvalidDOMElementException
123
     *   If the qualified name of the supplied element is wrong
124
     */
125
    public static function fromXML(DOMElement $xml): static
126
    {
127
        Assert::same($xml->localName, 'SignedInfo', InvalidDOMElementException::class);
128
        Assert::same($xml->namespaceURI, SignedInfo::NS, InvalidDOMElementException::class);
129
130
        $Id = self::getOptionalAttribute($xml, 'Id', null);
131
132
        $canonicalizationMethod = CanonicalizationMethod::getChildrenOfClass($xml);
133
        Assert::minCount(
134
            $canonicalizationMethod,
135
            1,
136
            'A ds:SignedInfo element must contain exactly one ds:CanonicalizationMethod',
137
            MissingElementException::class,
138
        );
139
        Assert::maxCount(
140
            $canonicalizationMethod,
141
            1,
142
            'A ds:SignedInfo element must contain exactly one ds:CanonicalizationMethod',
143
            TooManyElementsException::class,
144
        );
145
146
        $signatureMethod = SignatureMethod::getChildrenOfClass($xml);
147
        Assert::minCount(
148
            $signatureMethod,
149
            1,
150
            'A ds:SignedInfo element must contain exactly one ds:SignatureMethod',
151
            MissingElementException::class,
152
        );
153
        Assert::maxCount(
154
            $signatureMethod,
155
            1,
156
            'A ds:SignedInfo element must contain exactly one ds:SignatureMethod',
157
            TooManyElementsException::class,
158
        );
159
160
        $references = Reference::getChildrenOfClass($xml);
161
        Assert::minCount(
162
            $references,
163
            1,
164
            'A ds:SignedInfo element must contain at least one ds:Reference',
165
            MissingElementException::class,
166
        );
167
168
        $signedInfo = new static(array_pop($canonicalizationMethod), array_pop($signatureMethod), $references, $Id);
169
        $signedInfo->xml = $xml;
170
        return $signedInfo;
171
    }
172
173
174
    /**
175
     * Convert this SignedInfo element to XML.
176
     *
177
     * @param \DOMElement|null $parent The element we should append this SignedInfo element to.
178
     * @return \DOMElement
179
     */
180
    public function toXML(?DOMElement $parent = null): DOMElement
181
    {
182
        $e = $this->instantiateParentElement($parent);
183
184
        if ($this->getId() !== null) {
185
            $e->setAttribute('Id', $this->getId());
186
        }
187
188
        $this->getCanonicalizationMethod()->toXML($e);
189
        $this->getSignatureMethod()->toXML($e);
190
191
        foreach ($this->getReferences() as $ref) {
192
            $ref->toXML($e);
193
        }
194
195
        return $e;
196
    }
197
}
198