Passed
Push — master ( 25fd26...1cb796 )
by Jaime Pérez
02:17
created

EncryptionMethod::fromXML()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 34
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 21
c 1
b 0
f 0
nc 6
nop 1
dl 0
loc 34
rs 8.9617
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SAML2\XML\xenc;
6
7
use DOMElement;
8
use SAML2\Constants;
9
use SAML2\XML\Chunk;
10
use Webmozart\Assert\Assert;
11
12
/**
13
 * A class implementing the xenc:EncryptionMethod element.
14
 *
15
 * @package simplesamlphp/saml2
16
 */
17
class EncryptionMethod extends AbstractXencElement
18
{
19
    /** @var string */
20
    protected $algorithm;
21
22
    /** @var int|null */
23
    protected $keySize = null;
24
25
    /** @var string|null */
26
    protected $oaepParams = null;
27
28
    /** @var \SAML2\XML\Chunk[] */
29
    protected $children = [];
30
31
32
    /**
33
     * EncryptionMethod constructor.
34
     *
35
     * @param string $algorithm
36
     * @param int|null $keySize
37
     * @param string|null $oaepParams
38
     * @param \SAML2\XML\Chunk[] $children
39
     */
40
    public function __construct(
41
        string $algorithm,
42
        ?int $keySize = null,
43
        ?string $oaepParams = null,
44
        array $children = []
45
    ) {
46
        $this->setAlgorithm($algorithm);
47
        $this->setKeySize($keySize);
48
        $this->setOAEPParams($oaepParams);
49
        $this->setChildren($children);
50
    }
51
52
53
    /**
54
     * Initialize an EncryptionMethod object from an existing XML.
55
     *
56
     * @param \DOMElement $xml
57
     * @return \SAML2\XML\md\EncryptionMethod
58
     * @throws \InvalidArgumentException if the qualified name of the supplied element is wrong
59
     */
60
    public static function fromXML(DOMElement $xml): object
61
    {
62
        Assert::same($xml->localName, 'EncryptionMethod');
63
        Assert::same($xml->namespaceURI, static::NS);
64
65
        /** @var string $algorithm */
66
        $algorithm = self::getAttribute($xml, 'Algorithm');
67
68
        $keySize = null;
69
        $oaepParams = null;
70
        $children = [];
71
        foreach ($xml->childNodes as $node) {
72
            if (!$node instanceof DOMElement) {
73
                continue;
74
            } elseif ($node->namespaceURI === Constants::NS_XENC) {
75
                if ($node->localName === 'KeySize') {
76
                    Assert::null($keySize, $node->tagName . ' cannot be set more than once.');
77
                    Assert::numeric($node->textContent, $node->tagName . ' must be numerical.');
78
                    $keySize = intval($node->textContent);
79
                    continue;
80
                }
81
82
                if ($node->localName === 'OAEPParams') {
83
                    Assert::null($oaepParams, $node->tagName . ' cannot be set more than once.');
84
                    $oaepParams = trim($node->textContent);
85
                    continue;
86
                }
87
            }
88
89
            /** @var \DOMElement $node */
90
            $children[] = Chunk::fromXML($node);
91
        }
92
93
        return new static($algorithm, $keySize, $oaepParams, $children);
94
    }
95
96
97
    /**
98
     * Get the URI identifying the algorithm used by this encryption method.
99
     *
100
     * @return string
101
     */
102
    public function getAlgorithm(): string
103
    {
104
        return $this->algorithm;
105
    }
106
107
108
    /**
109
     * Set the URI identifying the algorithm used by this encryption method.
110
     *
111
     * @param string $algorithm
112
     * @return void
113
     * @throws \InvalidArgumentException
114
     */
115
    protected function setAlgorithm(string $algorithm): void
116
    {
117
        Assert::notEmpty($algorithm, 'Cannot set an empty algorithm in ' . static::NS_PREFIX . ':EncryptionMethod.');
118
        $this->algorithm = $algorithm;
119
    }
120
121
122
    /**
123
     * Get the size of the key used by this encryption method.
124
     *
125
     * @return int|null
126
     */
127
    public function getKeySize(): ?int
128
    {
129
        return $this->keySize;
130
    }
131
132
133
    /**
134
     * Set the size of the key used by this encryption method.
135
     *
136
     * @param int|null $keySize
137
     * @return void
138
     */
139
    protected function setKeySize(?int $keySize): void
140
    {
141
        $this->keySize = $keySize;
142
    }
143
144
145
    /**
146
     * Get the base64-encoded OAEP parameters.
147
     *
148
     * @return string
149
     */
150
    public function getOAEPParams(): ?string
151
    {
152
        return $this->oaepParams;
153
    }
154
155
156
    /**
157
     * Set the OAEP parameters.
158
     *
159
     * @param string|null $oaepParams The OAEP parameters, base64-encoded.
160
     * @return void
161
     * @throws \InvalidArgumentException
162
     */
163
    protected function setOAEPParams(?string $oaepParams): void
164
    {
165
        if ($oaepParams === null) {
166
            return;
167
        }
168
        Assert::Eq(
169
            $oaepParams,
170
            base64_encode(base64_decode($oaepParams, true)),
171
            'OAEPParams must be base64-encoded.'
172
        );
173
        $this->oaepParams = $oaepParams;
174
    }
175
176
177
    /**
178
     * Get the children elements of this encryption method as chunks.
179
     *
180
     * @return \SAML2\XML\Chunk[]
181
     */
182
    public function getChildren(): array
183
    {
184
        return $this->children;
185
    }
186
187
188
    /**
189
     * Set an array of chunks as children of this encryption method.
190
     *
191
     * @param \SAML2\XML\Chunk[] $children
192
     * @return void
193
     * @throws \InvalidArgumentException
194
     */
195
    protected function setChildren(array $children): void
196
    {
197
        Assert::allIsInstanceOf(
198
            $children,
199
            Chunk::class,
200
            'All children elements of ' . static::NS_PREFIX . ':EncryptionMethod must be of type \SAML2\XML\Chunk.'
201
        );
202
        $this->children = $children;
203
    }
204
205
206
    /**
207
     * Convert this EncryptionMethod object to XML.
208
     *
209
     * @param \DOMElement|null $parent The element we should append this EncryptionMethod to.
210
     * @return \DOMElement
211
     */
212
    public function toXML(DOMElement $parent = null): DOMElement
213
    {
214
        $e = $this->instantiateParentElement($parent);
215
        $e->setAttribute('Algorithm', $this->algorithm);
216
217
        if ($this->keySize !== null) {
218
            $keySize = $e->ownerDocument->createElementNS(Constants::NS_XENC, 'xenc:KeySize', strval($this->keySize));
219
            $e->appendChild($keySize);
220
        }
221
222
        if ($this->oaepParams !== null) {
223
            $oaepParams = $e->ownerDocument->createElementNS(Constants::NS_XENC, 'xenc:OAEPParams', $this->oaepParams);
224
            $e->appendChild($oaepParams);
225
        }
226
227
        foreach ($this->children as $child) {
228
            $child->toXML($e);
229
        }
230
231
        return $e;
232
    }
233
}
234