Issues (81)

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