Passed
Push — master ( 95262c...c6f342 )
by Tim
02:08
created

AbstractEncryptionMethod::setKeySize()   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\xenc;
6
7
use DOMElement;
8
use SimpleSAML\Assert\Assert;
9
use SimpleSAML\XML\Exception\InvalidDOMElementException;
10
use SimpleSAML\XML\Exception\SchemaViolationException;
11
use SimpleSAML\XML\Exception\TooManyElementsException;
12
use SimpleSAML\XML\Chunk;
13
use SimpleSAML\XMLSecurity\Constants as C;
14
use SimpleSAML\XMLSecurity\Exception\InvalidArgumentException;
15
16
use function array_pop;
17
use function sprintf;
18
19
/**
20
 * A class implementing the xenc:AbstractEncryptionMethod element.
21
 *
22
 * @package simplesamlphp/xml-security
23
 */
24
abstract class AbstractEncryptionMethod extends AbstractXencElement
25
{
26
    /** @var string */
27
    protected string $algorithm;
28
29
    /** @var \SimpleSAML\XMLSecurity\XML\xenc\KeySize|null */
30
    protected ?KeySize $keySize = null;
31
32
    /** @var \SimpleSAML\XMLSecurity\XML\xenc\OAEPparams|null */
33
    protected ?OAEPparams $oaepParams = null;
34
35
    /** @var \SimpleSAML\XML\Chunk[] */
36
    protected array $children = [];
37
38
39
    /**
40
     * EncryptionMethod constructor.
41
     *
42
     * @param string $algorithm
43
     * @param \SimpleSAML\XMLSecurity\XML\xenc\KeySize|null $keySize
44
     * @param \SimpleSAML\XMLSecurity\XML\xenc\OAEPparams|null $oaepParams
45
     * @param \SimpleSAML\XML\Chunk[] $children
46
     */
47
    final public function __construct(
48
        string $algorithm,
49
        ?KeySize $keySize = null,
50
        ?OAEPparams $oaepParams = null,
51
        array $children = [],
52
    ) {
53
        $this->setAlgorithm($algorithm);
54
        $this->setKeySize($keySize);
55
        $this->setOAEPParams($oaepParams);
56
        $this->setChildren($children);
57
    }
58
59
60
    /**
61
     * Get the URI identifying the algorithm used by this encryption method.
62
     *
63
     * @return string
64
     */
65
    public function getAlgorithm(): string
66
    {
67
        return $this->algorithm;
68
    }
69
70
71
    /**
72
     * Set the URI identifying the algorithm used by this encryption method.
73
     *
74
     * @param string $algorithm
75
     * @throws \SimpleSAML\Assert\AssertionFailedException
76
     */
77
    protected function setAlgorithm(string $algorithm): void
78
    {
79
        Assert::validURI($algorithm, SchemaViolationException::class); // Covers the empty string
80
        $this->algorithm = $algorithm;
81
    }
82
83
84
    /**
85
     * Get the size of the key used by this encryption method.
86
     *
87
     * @return \SimpleSAML\XMLSecurity\XML\xenc\KeySize|null
88
     */
89
    public function getKeySize(): ?KeySize
90
    {
91
        return $this->keySize;
92
    }
93
94
95
    /**
96
     * Set the size of the key used by this encryption method.
97
     *
98
     * @param \SimpleSAML\XMLSecurity\XML\xenc\KeySize|null $keySize
99
     */
100
    protected function setKeySize(?KeySize $keySize): void
101
    {
102
        $this->keySize = $keySize;
103
    }
104
105
106
    /**
107
     * Get the OAEP parameters.
108
     *
109
     * @return \SimpleSAML\XMLSecurity\XML\xenc\OAEPparams|null
110
     */
111
    public function getOAEPParams(): ?OAEPparams
112
    {
113
        return $this->oaepParams;
114
    }
115
116
117
    /**
118
     * Set the OAEP parameters.
119
     *
120
     * @param \SimpleSAML\XMLSecurity\XML\xenc\OAEPparams|null $oaepParams The OAEP parameters.
121
     * @throws \SimpleSAML\Assert\AssertionFailedException
122
     */
123
    protected function setOAEPParams(?OAEPparams $oaepParams): void
124
    {
125
        $this->oaepParams = $oaepParams;
126
    }
127
128
129
    /**
130
     * Get the children elements of this encryption method as chunks.
131
     *
132
     * @return \SimpleSAML\XML\Chunk[]
133
     */
134
    public function getChildren(): array
135
    {
136
        return $this->children;
137
    }
138
139
140
    /**
141
     * Set an array of chunks as children of this encryption method.
142
     *
143
     * @param \SimpleSAML\XML\Chunk[] $children
144
     * @throws \SimpleSAML\Assert\AssertionFailedException
145
     */
146
    protected function setChildren(array $children): void
147
    {
148
        Assert::allIsInstanceOf(
149
            $children,
150
            Chunk::class,
151
            sprintf(
152
                'All children elements of %s:EncryptionMethod must be of type \SimpleSAML\XML\Chunk.',
153
                static::NS_PREFIX
154
            ),
155
            InvalidArgumentException::class,
156
        );
157
158
        $this->children = $children;
159
    }
160
161
162
    /**
163
     * Initialize an EncryptionMethod object from an existing XML.
164
     *
165
     * @param \DOMElement $xml
166
     * @return static
167
     *
168
     * @throws \SimpleSAML\XML\Exception\InvalidDOMElementException
169
     *   if the qualified name of the supplied element is wrong
170
     * @throws \SimpleSAML\XML\Exception\MissingAttributeException
171
     *   if the supplied element is missing one of the mandatory attributes
172
     * @throws \SimpleSAML\XML\Exception\TooManyElementsException
173
     *   if too many child-elements of a type are specified
174
     */
175
    public static function fromXML(DOMElement $xml): static
176
    {
177
        Assert::same($xml->localName, 'EncryptionMethod', InvalidDOMElementException::class);
178
        Assert::same($xml->namespaceURI, static::NS, InvalidDOMElementException::class);
179
180
        /** @psalm-var string $algorithm */
181
        $algorithm = self::getAttribute($xml, 'Algorithm');
182
183
        $keySize = KeySize::getChildrenOfClass($xml);
184
        Assert::maxCount($keySize, 1, TooManyElementsException::class);
185
186
        $oaepParams = OAEPparams::getChildrenOfClass($xml);
187
        Assert::maxCount($oaepParams, 1, TooManyElementsException::class);
188
189
        $children = [];
190
        foreach ($xml->childNodes as $node) {
191
            if (!$node instanceof DOMElement) {
192
                continue;
193
            } elseif ($node->namespaceURI === C::NS_XENC) {
194
                if ($node->localName === 'KeySize') {
195
                    continue;
196
                } elseif ($node->localName === 'OAEPparams') {
197
                    continue;
198
                }
199
            }
200
201
            $children[] = Chunk::fromXML($node);
202
        }
203
204
        return new static($algorithm, array_pop($keySize), array_pop($oaepParams), $children);
205
    }
206
207
208
    /**
209
     * Convert this EncryptionMethod object to XML.
210
     *
211
     * @param \DOMElement|null $parent The element we should append this EncryptionMethod to.
212
     * @return \DOMElement
213
     */
214
    public function toXML(DOMElement $parent = null): DOMElement
215
    {
216
        /** @psalm-var \DOMDocument $e->ownerDocument */
217
        $e = $this->instantiateParentElement($parent);
218
        $e->setAttribute('Algorithm', $this->getAlgorithm());
219
220
        $this->getKeySize()?->toXML($e);
221
        $this->getOAEPparams()?->toXML($e);
222
223
        foreach ($this->getChildren() as $child) {
224
            $child->toXML($e);
225
        }
226
227
        return $e;
228
    }
229
}
230