Passed
Push — master ( 6db269...70aff8 )
by Jaime Pérez
02:49
created

EncryptionMethod::fromXML()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 31
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

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