EncryptedKey::fromKey()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 37
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 19
c 1
b 0
f 0
nc 1
nop 11
dl 0
loc 37
rs 9.6333

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