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

EncryptedKey::getRecipient()   A

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\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