Completed
Push — develop ( b5844e...e46df6 )
by Florent
02:33
created

HMACSignatureTest   A

Complexity

Total Complexity 4

Size/Duplication

Total Lines 237
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 10

Importance

Changes 8
Bugs 2 Features 2
Metric Value
wmc 4
c 8
b 2
f 2
lcom 1
cbo 10
dl 0
loc 237
rs 10
1
<?php
2
3
/*
4
 * The MIT License (MIT)
5
 *
6
 * Copyright (c) 2014-2016 Spomky-Labs
7
 *
8
 * This software may be modified and distributed under the terms
9
 * of the MIT license.  See the LICENSE file for details.
10
 */
11
12
namespace Jose\Test\RFC7520;
13
14
use Jose\Factory\JWSFactory;
15
use Jose\Factory\SignerFactory;
16
use Jose\Factory\VerifierFactory;
17
use Jose\Loader;
18
use Jose\Object\JWK;
19
20
/**
21
 * @see https://tools.ietf.org/html/rfc7520#section-4.4
22
 * @see https://tools.ietf.org/html/rfc7520#section-4.5
23
 * @see https://tools.ietf.org/html/rfc7520#section-4.6
24
 * @see https://tools.ietf.org/html/rfc7520#section-4.7
25
 *
26
 * @group HMAC
27
 * @group RFC7520
28
 */
29
class HMACSignatureTest extends \PHPUnit_Framework_TestCase
30
{
31
    /**
32
     * @see https://tools.ietf.org/html/rfc7520#section-4.4
33
     */
34
    public function testHS256()
35
    {
36
        /*
37
         * Payload
38
         * Symmetric Key
39
         * @see https://tools.ietf.org/html/rfc7520#section-3.5
40
         * @see https://tools.ietf.org/html/rfc7520#section-4.4.1
41
         */
42
        $payload = "It\xe2\x80\x99s a dangerous business, Frodo, going out your door. You step onto the road, and if you don't keep your feet, there\xe2\x80\x99s no knowing where you might be swept off to.";
43
        $key = new JWK([
44
            'kty' => 'oct',
45
            'kid' => '018c0ae5-4d9b-471b-bfd6-eef314bc7037',
46
            'use' => 'sig',
47
            'alg' => 'HS256',
48
            'k'   => 'hJtXIZ2uSN5kbQfbtTNWbpdmhkV8FJG-Onbc6mxCcYg',
49
        ]);
50
51
        /*
52
         * Header
53
         * @see https://tools.ietf.org/html/rfc7520#section-4.4.2
54
         */
55
        $headers = [
56
            'alg' => 'HS256',
57
            'kid' => '018c0ae5-4d9b-471b-bfd6-eef314bc7037',
58
        ];
59
60
        $jws = JWSFactory::createJWS($payload);
61
        $jws = $jws->addSignature($key, $headers);
62
63
        $signer = SignerFactory::createSigner(['HS256']);
64
        $signer->sign($jws);
65
66
        $verifer = VerifierFactory::createVerifier(['HS256']);
67
68
        /*
69
         * Header
70
         * @see https://tools.ietf.org/html/rfc7520#section-4.4.3
71
         */
72
        $expected_compact_json = 'eyJhbGciOiJIUzI1NiIsImtpZCI6IjAxOGMwYWU1LTRkOWItNDcxYi1iZmQ2LWVlZjMxNGJjNzAzNyJ9.SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4.s0h6KThzkfBBBkLspW1h84VsJZFTsPPqMDA7g1Md7p0';
73
        $expected_flattened_json = '{"payload":"SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4","protected":"eyJhbGciOiJIUzI1NiIsImtpZCI6IjAxOGMwYWU1LTRkOWItNDcxYi1iZmQ2LWVlZjMxNGJjNzAzNyJ9","signature":"s0h6KThzkfBBBkLspW1h84VsJZFTsPPqMDA7g1Md7p0"}';
74
        $expected_json = '{"payload":"SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4","signatures":[{"protected":"eyJhbGciOiJIUzI1NiIsImtpZCI6IjAxOGMwYWU1LTRkOWItNDcxYi1iZmQ2LWVlZjMxNGJjNzAzNyJ9","signature":"s0h6KThzkfBBBkLspW1h84VsJZFTsPPqMDA7g1Md7p0"}]}';
75
76
        $this->assertEquals($expected_compact_json, $jws->toCompactJSON(0));
77
78
        // We decode the json to compare the 2 arrays otherwise the test may fail as the order may be different
79
        $this->assertEquals(json_decode($expected_flattened_json, true), json_decode($jws->toFlattenedJSON(0), true));
80
        $this->assertEquals(json_decode($expected_json, true), json_decode($jws->toJSON(), true));
81
82
        $loaded_compact_json = Loader::load($expected_compact_json);
83
        $verifer->verifyWithKey($loaded_compact_json, $key);
84
85
        $loaded_flattened_json = Loader::load($expected_flattened_json);
86
        $verifer->verifyWithKey($loaded_flattened_json, $key);
87
88
        $loaded_json = Loader::load($expected_json);
89
        $verifer->verifyWithKey($loaded_json, $key);
90
    }
91
92
    /**
93
     * @see https://tools.ietf.org/html/rfc7520#section-4.5
94
     */
95
    public function testHS256WithDetachedPayload()
96
    {
97
        /*
98
         * Payload
99
         * Symmetric Key
100
         * @see https://tools.ietf.org/html/rfc7520#section-3.5
101
         * @see https://tools.ietf.org/html/rfc7520#section-4.5.1
102
         */
103
        $payload = "It\xe2\x80\x99s a dangerous business, Frodo, going out your door. You step onto the road, and if you don't keep your feet, there\xe2\x80\x99s no knowing where you might be swept off to.";
104
        $key = new JWK([
105
            'kty' => 'oct',
106
            'kid' => '018c0ae5-4d9b-471b-bfd6-eef314bc7037',
107
            'use' => 'sig',
108
            'alg' => 'HS256',
109
            'k'   => 'hJtXIZ2uSN5kbQfbtTNWbpdmhkV8FJG-Onbc6mxCcYg',
110
        ]);
111
112
        /*
113
         * Header
114
         * @see https://tools.ietf.org/html/rfc7520#section-4.5.2
115
         */
116
        $headers = [
117
            'alg' => 'HS256',
118
            'kid' => '018c0ae5-4d9b-471b-bfd6-eef314bc7037',
119
        ];
120
121
        $jws = JWSFactory::createJWSWithDetachedPayload($payload, $encoded_payload);
122
        $jws = $jws->addSignature($key, $headers);
123
124
        $signer = SignerFactory::createSigner(['HS256']);
125
        $signer->signWithDetachedPayload($jws, $encoded_payload);
126
127
        $verifer = VerifierFactory::createVerifier(['HS256']);
128
129
        /*
130
         * Header
131
         * @see https://tools.ietf.org/html/rfc7520#section-4.5.3
132
         */
133
        $expected_compact_json = 'eyJhbGciOiJIUzI1NiIsImtpZCI6IjAxOGMwYWU1LTRkOWItNDcxYi1iZmQ2LWVlZjMxNGJjNzAzNyJ9..s0h6KThzkfBBBkLspW1h84VsJZFTsPPqMDA7g1Md7p0';
134
        $expected_flattened_json = '{"protected":"eyJhbGciOiJIUzI1NiIsImtpZCI6IjAxOGMwYWU1LTRkOWItNDcxYi1iZmQ2LWVlZjMxNGJjNzAzNyJ9","signature":"s0h6KThzkfBBBkLspW1h84VsJZFTsPPqMDA7g1Md7p0"}';
135
        $expected_json = '{"signatures":[{"protected":"eyJhbGciOiJIUzI1NiIsImtpZCI6IjAxOGMwYWU1LTRkOWItNDcxYi1iZmQ2LWVlZjMxNGJjNzAzNyJ9","signature":"s0h6KThzkfBBBkLspW1h84VsJZFTsPPqMDA7g1Md7p0"}]}';
136
137
        $this->assertEquals($expected_compact_json, $jws->toCompactJSON(0));
138
139
        // We decode the json to compare the 2 arrays otherwise the test may fail as the order may be different
140
        $this->assertEquals(json_decode($expected_flattened_json, true), json_decode($jws->toFlattenedJSON(0), true));
141
142
        $this->assertEquals(json_decode($expected_json, true), json_decode($jws->toJSON(), true));
143
144
        $loaded_compact_json = Loader::load($expected_compact_json);
145
        $verifer->verifyWithKey($loaded_compact_json, $key, $encoded_payload);
146
147
        $loaded_flattened_json = Loader::load($expected_flattened_json);
148
        $verifer->verifyWithKey($loaded_flattened_json, $key, $encoded_payload);
149
150
        $loaded_json = Loader::load($expected_json);
151
        $verifer->verifyWithKey($loaded_json, $key, $encoded_payload);
152
    }
153
154
    /**
155
     * @see https://tools.ietf.org/html/rfc7520#section-4.6
156
     */
157
    public function testHS256WithUnprotectedHeaders()
158
    {
159
        /*
160
         * Payload
161
         * Symmetric Key
162
         * @see https://tools.ietf.org/html/rfc7520#section-3.5
163
         * @see https://tools.ietf.org/html/rfc7520#section-4.6.1
164
         */
165
        $payload = "It\xe2\x80\x99s a dangerous business, Frodo, going out your door. You step onto the road, and if you don't keep your feet, there\xe2\x80\x99s no knowing where you might be swept off to.";
166
        $key = new JWK([
167
            'kty' => 'oct',
168
            'kid' => '018c0ae5-4d9b-471b-bfd6-eef314bc7037',
169
            'use' => 'sig',
170
            'alg' => 'HS256',
171
            'k'   => 'hJtXIZ2uSN5kbQfbtTNWbpdmhkV8FJG-Onbc6mxCcYg',
172
        ]);
173
174
        /*
175
         * Header
176
         * @see https://tools.ietf.org/html/rfc7520#section-4.6.2
177
         */
178
        $protected_headers = [
179
            'alg' => 'HS256',
180
        ];
181
        $unprotected_headers = [
182
            'kid' => '018c0ae5-4d9b-471b-bfd6-eef314bc7037',
183
        ];
184
185
        $jws = JWSFactory::createJWS($payload);
186
        $jws = $jws->addSignature($key, $protected_headers, $unprotected_headers);
187
188
        $signer = SignerFactory::createSigner(['HS256']);
189
        $signer->sign($jws);
190
191
        $verifer = VerifierFactory::createVerifier(['HS256']);
192
193
        /*
194
         * Header
195
         * @see https://tools.ietf.org/html/rfc7520#section-4.6.3
196
         */
197
        $expected_flattened_json = '{"payload": "SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4","protected": "eyJhbGciOiJIUzI1NiJ9","header": {"kid": "018c0ae5-4d9b-471b-bfd6-eef314bc7037"},"signature": "bWUSVaxorn7bEF1djytBd0kHv70Ly5pvbomzMWSOr20"}';
198
        $expected_json = '{"payload":"SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4","signatures":[{"protected":"eyJhbGciOiJIUzI1NiJ9","header":{"kid":"018c0ae5-4d9b-471b-bfd6-eef314bc7037"},"signature":"bWUSVaxorn7bEF1djytBd0kHv70Ly5pvbomzMWSOr20"}]}';
199
200
        // We decode the json to compare the 2 arrays otherwise the test may fail as the order may be different
201
        $this->assertEquals(json_decode($expected_flattened_json, true), json_decode($jws->toFlattenedJSON(0), true));
202
        $this->assertEquals(json_decode($expected_json, true), json_decode($jws->toJSON(), true));
203
204
        $loaded_flattened_json = Loader::load($expected_flattened_json);
205
        $verifer->verifyWithKey($loaded_flattened_json, $key);
206
207
        $loaded_json = Loader::load($expected_json);
208
        $verifer->verifyWithKey($loaded_json, $key);
209
    }
210
211
    /**
212
     * @see https://tools.ietf.org/html/rfc7520#section-4.7
213
     */
214
    public function testHS256WithoutProtectedHeaders()
215
    {
216
        /*
217
         * Payload
218
         * Symmetric Key
219
         * @see https://tools.ietf.org/html/rfc7520#section-3.5
220
         * @see https://tools.ietf.org/html/rfc7520#section-4.7.1
221
         */
222
        $payload = "It\xe2\x80\x99s a dangerous business, Frodo, going out your door. You step onto the road, and if you don't keep your feet, there\xe2\x80\x99s no knowing where you might be swept off to.";
223
        $key = new JWK([
224
            'kty' => 'oct',
225
            'kid' => '018c0ae5-4d9b-471b-bfd6-eef314bc7037',
226
            'use' => 'sig',
227
            'alg' => 'HS256',
228
            'k'   => 'hJtXIZ2uSN5kbQfbtTNWbpdmhkV8FJG-Onbc6mxCcYg',
229
        ]);
230
231
        /*
232
         * Header
233
         * @see https://tools.ietf.org/html/rfc7520#section-4.7.2
234
         */
235
        $unprotected_headers = [
236
            'alg' => 'HS256',
237
            'kid' => '018c0ae5-4d9b-471b-bfd6-eef314bc7037',
238
        ];
239
240
        $jws = JWSFactory::createJWS($payload);
241
        $jws = $jws->addSignature($key, [], $unprotected_headers);
242
243
        $signer = SignerFactory::createSigner(['HS256']);
244
        $signer->sign($jws);
245
246
        $verifer = VerifierFactory::createVerifier(['HS256']);
247
248
        /*
249
         * Header
250
         * @see https://tools.ietf.org/html/rfc7520#section-4.7.3
251
         */
252
        $expected_flattened_json = '{"payload":"SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4","header":{"alg":"HS256","kid":"018c0ae5-4d9b-471b-bfd6-eef314bc7037"},"signature":"xuLifqLGiblpv9zBpuZczWhNj1gARaLV3UxvxhJxZuk"}';
253
        $expected_json = '{"payload":"SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4","signatures":[{"header":{"alg":"HS256","kid":"018c0ae5-4d9b-471b-bfd6-eef314bc7037"},"signature":"xuLifqLGiblpv9zBpuZczWhNj1gARaLV3UxvxhJxZuk"}]}';
254
255
        // We decode the json to compare the 2 arrays otherwise the test may fail as the order may be different
256
        $this->assertEquals(json_decode($expected_flattened_json, true), json_decode($jws->toFlattenedJSON(0), true));
257
        $this->assertEquals(json_decode($expected_json, true), json_decode($jws->toJSON(), true));
258
259
        $loaded_flattened_json = Loader::load($expected_flattened_json);
260
        $verifer->verifyWithKey($loaded_flattened_json, $key);
261
262
        $loaded_json = Loader::load($expected_json);
263
        $verifer->verifyWithKey($loaded_json, $key);
264
    }
265
}
266