Passed
Pull Request — master (#60)
by Tim
02:12
created

EncryptedKeyTest::testMarshallingElementOrdering()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 52
Code Lines 36

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 36
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 52
rs 9.344

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\XMLSecurity\Test\XML\xenc;
6
7
use PHPUnit\Framework\Attributes\{CoversClass, Group};
8
use PHPUnit\Framework\TestCase;
9
use SimpleSAML\XML\DOMDocumentFactory;
10
use SimpleSAML\XML\TestUtils\{SchemaValidationTestTrait, SerializableElementTestTrait};
11
use SimpleSAML\XML\Type\{AnyURIValue, Base64BinaryValue, IDValue, StringValue};
12
use SimpleSAML\XMLSecurity\Alg\KeyTransport\KeyTransportAlgorithmFactory;
13
use SimpleSAML\XMLSecurity\Constants as C;
14
use SimpleSAML\XMLSecurity\Key\{PrivateKey, PublicKey, SymmetricKey};
15
use SimpleSAML\XMLSecurity\TestUtils\PEMCertificatesMock;
16
use SimpleSAML\XMLSecurity\Utils\XPath;
17
use SimpleSAML\XMLSecurity\XML\ds\KeyInfo;
18
use SimpleSAML\XMLSecurity\XML\xenc\{
19
    AbstractEncryptedType,
20
    AbstractXencElement,
21
    CarriedKeyName,
22
    CipherData,
23
    CipherValue,
24
    DataReference,
25
    EncryptedKey,
26
    EncryptionMethod,
27
    ReferenceList,
28
};
29
30
use function bin2hex;
31
use function dirname;
32
use function strval;
33
34
/**
35
 * Class \SimpleSAML\XMLSecurity\Test\XML\xenc\EncryptedKeyTest
36
 *
37
 * @covers \SimpleSAML\XMLSecurity\XML\xenc\AbstractXencElement
38
 * @covers \SimpleSAML\XMLSecurity\XML\xenc\AbstractEncryptedType
39
 * @covers \SimpleSAML\XMLSecurity\XML\xenc\EncryptedKey
40
 *
41
 * @package simplesamlphp/xml-security
42
 */
43
#[Group('xenc')]
44
#[CoversClass(AbstractXencElement::class)]
45
#[CoversClass(AbstractEncryptedType::class)]
46
#[CoversClass(EncryptedKey::class)]
47
final class EncryptedKeyTest extends TestCase
48
{
49
    use SchemaValidationTestTrait;
50
    use SerializableElementTestTrait;
51
52
    /** @var \SimpleSAML\XMLSecurity\Key\PrivateKey */
53
    protected static PrivateKey $privKey;
54
55
    /** @var \SimpleSAML\XMLSecurity\Key\PublicKey */
56
    protected static PublicKey $pubKey;
57
58
    /**
59
     */
60
    public static function setUpBeforeClass(): void
61
    {
62
        self::$testedClass = EncryptedKey::class;
63
64
        self::$xmlRepresentation = DOMDocumentFactory::fromFile(
65
            dirname(__FILE__, 3) . '/resources/xml/xenc_EncryptedKey.xml',
66
        );
67
68
        self::$privKey = PEMCertificatesMock::getPrivateKey(PEMCertificatesMock::PRIVATE_KEY);
69
        self::$pubKey = PEMCertificatesMock::getPublicKey(PEMCertificatesMock::PUBLIC_KEY);
70
    }
71
72
73
    // marshalling
74
75
76
    /**
77
     */
78
    public function testMarshalling(): void
79
    {
80
        $encryptedKey = new EncryptedKey(
81
            new CipherData(
82
                new CipherValue(
83
                    Base64BinaryValue::fromString(
84
                        '3W3C4UoWshi02yrqsLC2z8Qr1FjdTz7LV9CvpunilOX4teGKsjKqNbS92DKcXLwS8s' .
85
                        '4eHBdHejiL1bySDQT5diN/TVo8zz0AmPwX3/eHPQE91NWzceB+yaoEDauMPvi7twUd' .
86
                        'oipbLZa7cyT4QR+RO9w5P5wf4wDoTPUoQV6dF9YSJqehuRFCqVJprIDZNfrKnm7Wfw' .
87
                        'MiaMLvaLVdLWgXjuVdiH0lT/F4KJrhJwAnjp57KGn9mhAcwkFe+qDIMSi8Ond6I0FO' .
88
                        'V3SOx8NxpSTHYfZ4qE1Xn/dvUUXqgRnEFPHAw4JFmJPjgTSCPU6BdwBLzqVjh1pCLo' .
89
                        'Cn66P/Zt7I9Q==',
90
                    ),
91
                ),
92
            ),
93
            IDValue::fromString('Encrypted_KEY_ID'),
94
            AnyURIValue::fromString(C::XMLENC_ELEMENT),
95
            StringValue::fromString('text/plain'),
96
            AnyURIValue::fromString('urn:x-simplesamlphp:encoding'),
97
            StringValue::fromString('some_ENTITY_ID'),
98
            new CarriedKeyName(
99
                StringValue::fromString('Name of the key'),
100
            ),
101
            new EncryptionMethod(
102
                AnyURIValue::fromString(C::KEY_TRANSPORT_RSA_1_5),
103
            ),
104
            new KeyInfo(
105
                [
106
                    new EncryptedKey(
107
                        new CipherData(
108
                            new CipherValue(
109
                                Base64BinaryValue::fromString('/CTj03d1DB5e2t7CTo9BEzCf5S9NRzwnBgZRlm32REI='),
110
                            ),
111
                        ),
112
                        null,
113
                        null,
114
                        null,
115
                        null,
116
                        null,
117
                        null,
118
                        new EncryptionMethod(
119
                            AnyURIValue::fromString(C::SIG_RSA_SHA256),
120
                        ),
121
                    ),
122
                ],
123
            ),
124
            new ReferenceList([
125
                new DataReference(
126
                    AnyURIValue::fromString('#Encrypted_DATA_ID'),
127
                ),
128
            ]),
129
        );
130
131
        $this->assertEquals(
132
            self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement),
133
            strval($encryptedKey),
134
        );
135
    }
136
137
138
    /**
139
     */
140
    public function testMarshallingElementOrdering(): void
141
    {
142
        $encryptedKey = new EncryptedKey(
143
            new CipherData(
144
                new CipherValue(
145
                    Base64BinaryValue::fromString(
146
                        '3W3C4UoWshi02yrqsLC2z8Qr1FjdTz7LV9CvpunilOX4teGKsjKqNbS92DKcXLwS8s' .
147
                        '4eHBdHejiL1bySDQT5diN/TVo8zz0AmPwX3/eHPQE91NWzceB+yaoEDauMPvi7twUd' .
148
                        'oipbLZa7cyT4QR+RO9w5P5wf4wDoTPUoQV6dF9YSJqehuRFCqVJprIDZNfrKnm7Wfw' .
149
                        'MiaMLvaLVdLWgXjuVdiH0lT/F4KJrhJwAnjp57KGn9mhAcwkFe+qDIMSi8Ond6I0FO' .
150
                        'V3SOx8NxpSTHYfZ4qE1Xn/dvUUXqgRnEFPHAw4JFmJPjgTSCPU6BdwBLzqVjh1pCLo' .
151
                        'Cn66P/Zt7I9Q==',
152
                    ),
153
                ),
154
            ),
155
            IDValue::fromString('Encrypted_KEY_ID'),
156
            AnyURIValue::fromString(C::XMLENC_ELEMENT),
157
            StringValue::fromString('text/plain'),
158
            AnyURIValue::fromString('urn:x-simplesamlphp:encoding'),
159
            StringValue::fromString('some_ENTITY_ID'),
160
            new CarriedKeyName(
161
                StringValue::fromString('Name of the key'),
162
            ),
163
            new EncryptionMethod(
164
                AnyURIValue::fromString(C::KEY_TRANSPORT_RSA_1_5),
165
            ),
166
            new KeyInfo(
167
                [
168
                    new EncryptedKey(
169
                        new CipherData(
170
                            new CipherValue(
171
                                Base64BinaryValue::fromString('/CTj03d1DB5e2t7CTo9BEzCf5S9NRzwnBgZRlm32REI='),
172
                            ),
173
                        ),
174
                        null,
175
                        null,
176
                        null,
177
                        null,
178
                        null,
179
                        null,
180
                        new EncryptionMethod(
181
                            AnyURIValue::fromString(C::SIG_RSA_SHA256),
182
                        ),
183
                    ),
184
                ],
185
            ),
186
            new ReferenceList([
187
                new DataReference(
188
                    AnyURIValue::fromString('#Encrypted_DATA_ID'),
189
                ),
190
            ]),
191
        );
192
193
        // Marshall it to a \DOMElement
194
        $encryptedKeyElement = $encryptedKey->toXML();
195
196
        $xpCache = XPath::getXPath($encryptedKeyElement);
197
        // Test for a ReferenceList
198
        $encryptedKeyElements = XPath::xpQuery(
199
            $encryptedKeyElement,
200
            './xenc:ReferenceList',
201
            $xpCache,
202
        );
203
        $this->assertCount(1, $encryptedKeyElements);
204
205
        // Test ordering of EncryptedKey contents
206
        /** @var \DOMElement[] $encryptedKeyElements */
207
        $encryptedKeyElements = XPath::xpQuery(
208
            $encryptedKeyElement,
209
            './xenc:ReferenceList/following-sibling::*',
210
            $xpCache,
211
        );
212
        $this->assertCount(1, $encryptedKeyElements);
213
        $this->assertEquals('xenc:CarriedKeyName', $encryptedKeyElements[0]->tagName);
214
    }
215
216
217
    /**
218
     * Test encryption and decryption with PKCS1 RSA 1.5.
219
     */
220
    public function testPKCS1Encryption(): void
221
    {
222
        $factory = new KeyTransportAlgorithmFactory([]);
223
        /** @var \SimpleSAML\XMLSecurity\Alg\Encryption\EncryptionAlgorithmInterface $encryptor */
224
        $encryptor = $factory->getAlgorithm(C::KEY_TRANSPORT_RSA_1_5, self::$pubKey);
225
        $symmetricKey = SymmetricKey::generate(8);
226
        $encryptedKey = EncryptedKey::fromKey(
227
            $symmetricKey,
228
            $encryptor,
229
            new EncryptionMethod(
230
                AnyURIValue::fromString(C::KEY_TRANSPORT_RSA_1_5),
231
            ),
232
        );
233
234
        $decryptor = $factory->getAlgorithm(C::KEY_TRANSPORT_RSA_1_5, self::$privKey);
235
        $decryptedKey = $encryptedKey->decrypt($decryptor);
236
237
        $this->assertEquals(bin2hex($symmetricKey->getMaterial()), bin2hex($decryptedKey));
238
    }
239
240
241
    /**
242
     * Test encryption and decryption with RSA OAEP
243
     */
244
    public function testOAEPEncryption(): void
245
    {
246
        $factory = new KeyTransportAlgorithmFactory([]);
247
        $encryptor = $factory->getAlgorithm(C::KEY_TRANSPORT_OAEP, self::$pubKey);
248
        $symmetricKey = SymmetricKey::generate(16);
249
        $encryptedKey = EncryptedKey::fromKey(
250
            $symmetricKey,
251
            $encryptor,
252
            new EncryptionMethod(
253
                AnyURIValue::fromString(C::KEY_TRANSPORT_OAEP),
254
            ),
255
        );
256
257
        $decryptor = $factory->getAlgorithm(C::KEY_TRANSPORT_OAEP, self::$privKey);
258
        $decryptedKey = $encryptedKey->decrypt($decryptor);
259
260
        $this->assertEquals(bin2hex($symmetricKey->getMaterial()), bin2hex($decryptedKey));
261
    }
262
263
264
    /**
265
     * Test encryption and decryption with RSA OAEP-MGF1P
266
     */
267
    public function testOAEMGF1PPEncryption(): void
268
    {
269
        $factory = new KeyTransportAlgorithmFactory([]);
270
        $encryptor = $factory->getAlgorithm(C::KEY_TRANSPORT_OAEP_MGF1P, self::$pubKey);
271
        $symmetricKey = SymmetricKey::generate(16);
272
        $encryptedKey = EncryptedKey::fromKey(
273
            $symmetricKey,
274
            $encryptor,
275
            new EncryptionMethod(
276
                AnyURIValue::fromString(C::KEY_TRANSPORT_OAEP_MGF1P),
277
            ),
278
        );
279
280
        $decryptor = $factory->getAlgorithm(C::KEY_TRANSPORT_OAEP_MGF1P, self::$privKey);
281
        $decryptedKey = $encryptedKey->decrypt($decryptor);
282
283
        $this->assertEquals(bin2hex($symmetricKey->getMaterial()), bin2hex($decryptedKey));
284
    }
285
}
286