Passed
Pull Request — master (#26)
by Jaime Pérez
01:59
created

EncryptedKey::fromKey()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 34
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 16
c 0
b 0
f 0
nc 2
nop 11
dl 0
loc 34
rs 9.7333

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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\XMLSecurity\Alg\Encryption\EncryptionAlgorithmInterface;
11
use SimpleSAML\XMLSecurity\Exception\InvalidArgumentException;
12
use SimpleSAML\XMLSecurity\Key\AbstractKey;
13
use SimpleSAML\XMLSecurity\XML\ds\KeyInfo;
14
15
/**
16
 * Class representing an encrypted key.
17
 *
18
 * @package simplesamlphp/xml-security
19
 */
20
class EncryptedKey extends AbstractEncryptedType
21
{
22
    /** @var \SimpleSAML\XMLSecurity\XML\xenc\CarriedKeyName|null */
23
    protected ?CarriedKeyName $carriedKeyName;
24
25
    /** @var string|null */
26
    protected ?string $recipient;
27
28
    /** @var \SimpleSAML\XMLSecurity\XML\xenc\ReferenceList|null */
29
    protected ?ReferenceList $referenceList;
30
31
32
    /**
33
     * EncryptedKey constructor.
34
     *
35
     * @param \SimpleSAML\XMLSecurity\XML\xenc\CipherData $cipherData The CipherData object of this EncryptedData.
36
     * @param string|null $id The Id attribute of this object. Optional.
37
     * @param string|null $type The Type attribute of this object. Optional.
38
     * @param string|null $mimeType The MimeType attribute of this object. Optional.
39
     * @param string|null $encoding The Encoding attribute of this object. Optional.
40
     * @param string|null $recipient The Recipient attribute of this object. Optional.
41
     * @param \SimpleSAML\XMLSecurity\XML\xenc\CarriedKeyName|null $carriedKeyName
42
     *   The value of the CarriedKeyName element of this EncryptedData.
43
     * @param \SimpleSAML\XMLSecurity\XML\xenc\EncryptionMethod|null $encryptionMethod
44
     *   The EncryptionMethod object of this EncryptedData. Optional.
45
     * @param \SimpleSAML\XMLSecurity\XML\ds\KeyInfo|null $keyInfo The KeyInfo object of this EncryptedData. Optional.
46
     * @param \SimpleSAML\XMLSecurity\XML\xenc\ReferenceList|null $referenceList
47
     *   The ReferenceList object of this EncryptedData. Optional.
48
     */
49
    public function __construct(
50
        CipherData $cipherData,
51
        ?string $id = null,
52
        ?string $type = null,
53
        ?string $mimeType = null,
54
        ?string $encoding = null,
55
        ?string $recipient = null,
56
        ?CarriedKeyName $carriedKeyName = null,
57
        ?EncryptionMethod $encryptionMethod = null,
58
        ?KeyInfo $keyInfo = null,
59
        ?ReferenceList $referenceList = null
60
    ) {
61
        parent::__construct($cipherData, $id, $type, $mimeType, $encoding, $encryptionMethod, $keyInfo);
62
        $this->setRecipient($recipient);
63
        $this->setReferenceList($referenceList);
64
        $this->setCarriedKeyName($carriedKeyName);
65
    }
66
67
68
    /**
69
     * Get the value of the CarriedKeyName property.
70
     *
71
     * @return \SimpleSAML\XMLSecurity\XML\xenc\CarriedKeyName|null
72
     */
73
    public function getCarriedKeyName(): ?CarriedKeyName
74
    {
75
        return $this->carriedKeyName;
76
    }
77
78
79
    /**
80
     * @param \SimpleSAML\XMLSecurity\XML\xenc\CarriedKeyName|null $carriedKeyName
81
     */
82
    protected function setCarriedKeyName(?CarriedKeyName $carriedKeyName): void
83
    {
84
        $this->carriedKeyName = $carriedKeyName;
85
    }
86
87
88
    /**
89
     * Get the value of the Recipient attribute.
90
     *
91
     * @return string|null
92
     */
93
    public function getRecipient(): ?string
94
    {
95
        return $this->recipient;
96
    }
97
98
99
    /**
100
     * @param string|null $recipient
101
     */
102
    protected function setRecipient(?string $recipient): void
103
    {
104
        $this->recipient = $recipient;
105
    }
106
107
108
    /**
109
     * Get the ReferenceList object.
110
     *
111
     * @return \SimpleSAML\XMLSecurity\XML\xenc\ReferenceList|null
112
     */
113
    public function getReferenceList(): ?ReferenceList
114
    {
115
        return $this->referenceList;
116
    }
117
118
119
    /**
120
     * @param \SimpleSAML\XMLSecurity\XML\xenc\ReferenceList|null $referenceList
121
     */
122
    protected function setReferenceList(?ReferenceList $referenceList): void
123
    {
124
        $this->referenceList = $referenceList;
125
    }
126
127
128
    /**
129
     * @param \SimpleSAML\XMLSecurity\Alg\Encryption\EncryptionAlgorithmInterface $decryptor The decryptor to use
130
     * to decrypt the key.
131
     *
132
     * @return string The decrypted key.
133
     */
134
    public function decrypt(EncryptionAlgorithmInterface $decryptor): string
135
    {
136
        if ($this->getCipherData()->getCipherValue() === null) {
137
            throw new InvalidArgumentException('Decrypting keys by reference is not supported.');
138
        }
139
140
        if ($this->getEncryptionMethod()->getAlgorithm() !== $decryptor->getAlgorithmId()) {
141
            throw new InvalidArgumentException('Decryptor algorithm does not match algorithm used.');
142
        }
143
144
        return $decryptor->decrypt(base64_decode($this->getCipherData()->getCipherValue()->getContent()));
145
    }
146
147
148
    /**
149
     * Create an EncryptedKey by encrypting a given key.
150
     *
151
     * @param \SimpleSAML\XMLSecurity\Key\AbstractKey $keyToEncrypt The key to encrypt.
152
     * @param \SimpleSAML\XMLSecurity\Alg\Encryption\EncryptionAlgorithmInterface $encryptor The encryptor to use.
153
     * @param \SimpleSAML\XMLSecurity\XML\xenc\EncryptionMethod|null $encryptionMethod
154
     *   The EncryptionMethod object of this EncryptedData. Optional.
155
     * @param string|null $id The Id attribute of this object. Optional.
156
     * @param string|null $type The Type attribute of this object. Optional.
157
     * @param string|null $mimeType The MimeType attribute of this object. Optional.
158
     * @param string|null $encoding The Encoding attribute of this object. Optional.
159
     * @param string|null $recipient The Recipient attribute of this object. Optional.
160
     * @param \SimpleSAML\XMLSecurity\XML\xenc\CarriedKeyName|null $carriedKeyName
161
     *   The value of the CarriedKeyName element of this EncryptedData.
162
     * @param \SimpleSAML\XMLSecurity\XML\ds\KeyInfo|null $keyInfo The KeyInfo object of this EncryptedData. Optional.
163
     * @param \SimpleSAML\XMLSecurity\XML\xenc\ReferenceList|null $referenceList
164
     *   The ReferenceList object of this EncryptedData. Optional.
165
     *
166
     * @return EncryptedKey The new EncryptedKey object.
167
     */
168
    public static function fromKey(
169
        AbstractKey $keyToEncrypt,
170
        EncryptionAlgorithmInterface $encryptor,
171
        EncryptionMethod $encryptionMethod,
172
        ?string $id = null,
173
        ?string $type = null,
174
        ?string $mimeType = null,
175
        ?string $encoding = null,
176
        ?string $recipient = null,
177
        ?CarriedKeyName $carriedKeyName = null,
178
        ?KeyInfo $keyInfo = null,
179
        ?ReferenceList $referenceList = null
180
    ): EncryptedKey {
181
        if ($encryptor->getAlgorithmId() !== $encryptionMethod->getAlgorithm()) {
182
            throw new InvalidArgumentException('Encryptor algorithm and encryption method do not match.');
183
        }
184
185
        return new self(
186
            new CipherData(
187
                new CipherValue(
188
                    base64_encode(
189
                        $encryptor->encrypt($keyToEncrypt->get())
190
                    )
191
                )
192
            ),
193
            $id,
194
            $type,
195
            $mimeType,
196
            $encoding,
197
            $recipient,
198
            $carriedKeyName,
199
            $encryptionMethod,
200
            $keyInfo,
201
            $referenceList
202
        );
203
    }
204
205
206
    /**
207
     * @inheritDoc
208
     *
209
     * @throws \SimpleSAML\XML\Exception\InvalidDOMElementException
210
     *   If the qualified name of the supplied element is wrong
211
     */
212
    public static function fromXML(DOMElement $xml): object
213
    {
214
        Assert::same($xml->localName, 'EncryptedKey', InvalidDOMElementException::class);
215
        Assert::same($xml->namespaceURI, EncryptedKey::NS, InvalidDOMElementException::class);
216
217
        $cipherData = CipherData::getChildrenOfClass($xml);
218
        Assert::count($cipherData, 1, 'No or more than one CipherData element found in <xenc:EncryptedKey>.');
219
220
        $encryptionMethod = EncryptionMethod::getChildrenOfClass($xml);
221
        Assert::maxCount(
222
            $encryptionMethod,
223
            1,
224
            'No more than one EncryptionMethod element allowed in <xenc:EncryptedKey>.'
225
        );
226
227
        $keyInfo = KeyInfo::getChildrenOfClass($xml);
228
        Assert::maxCount($keyInfo, 1, 'No more than one KeyInfo element allowed in <xenc:EncryptedKey>.');
229
230
        $referenceLists = ReferenceList::getChildrenOfClass($xml);
231
        Assert::maxCount($keyInfo, 1, 'Only one ReferenceList element allowed in <xenc:EncryptedKey>.');
232
233
        $carriedKeyNames = CarriedKeyName::getChildrenOfClass($xml);
234
        Assert::maxCount($carriedKeyNames, 1, 'Only one CarriedKeyName element allowed in <xenc:EncryptedKey>.');
235
236
        return new self(
237
            $cipherData[0],
238
            self::getAttribute($xml, 'Id', null),
239
            self::getAttribute($xml, 'Type', null),
240
            self::getAttribute($xml, 'MimeType', null),
241
            self::getAttribute($xml, 'Encoding', null),
242
            self::getAttribute($xml, 'Recipient', null),
243
            array_pop($carriedKeyNames),
244
            array_pop($encryptionMethod),
245
            array_pop($keyInfo),
246
            array_pop($referenceLists)
247
        );
248
    }
249
250
251
    /**
252
     * @inheritDoc
253
     */
254
    public function toXML(DOMElement $parent = null): DOMElement
255
    {
256
        /** @psalm-var \DOMDocument $e->ownerDocument */
257
        $e = parent::toXML($parent);
258
259
        if ($this->referenceList !== null) {
260
            $this->referenceList->toXML($e);
261
        }
262
263
        if ($this->carriedKeyName !== null) {
264
            $this->carriedKeyName->toXML($e);
265
        }
266
267
        if ($this->recipient !== null) {
268
            $e->setAttribute('Recipient', $this->recipient);
269
        }
270
271
        return $e;
272
    }
273
}
274