EncryptedKey::getCarriedKeyName()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
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