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