Completed
Push — v2.0.x ( 59a3d4...b06cab )
by Florent
03:22
created

JWE::toCompactJSON()   C

Complexity

Conditions 8
Paths 4

Size

Total Lines 23
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 2 Features 0
Metric Value
c 4
b 2
f 0
dl 0
loc 23
rs 6.1403
cc 8
eloc 15
nc 4
nop 1
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\Object;
13
14
use Base64Url\Base64Url;
15
16
/**
17
 * Class JWE.
18
 */
19
final class JWE implements JWEInterface
20
{
21
    use JWT;
22
23
    /**
24
     * @var \Jose\Object\RecipientInterface[]
25
     */
26
    private $recipients = [];
27
28
    /**
29
     * @var string|null
30
     */
31
    private $ciphertext = null;
32
33
    /**
34
     * @var string|null
35
     */
36
    private $iv = null;
37
38
    /**
39
     * @var string|null
40
     */
41
    private $aad = null;
42
43
    /**
44
     * @var string|null
45
     */
46
    private $tag = null;
47
48
    /**
49
     * @var array
50
     */
51
    private $shared_headers = [];
52
53
    /**
54
     * @var array
55
     */
56
    private $shared_protected_headers = [];
57
58
    /**
59
     * @var string|null
60
     */
61
    private $encoded_shared_protected_headers = null;
62
63
    /**
64
     * @var string|null
65
     */
66
    private $content_encryption_key = null;
67
68
    /**
69
     * {@inheritdoc}
70
     */
71
    public function countRecipients()
72
    {
73
        return count($this->recipients);
74
    }
75
76
    /**
77
     * {@inheritdoc}
78
     */
79
    public function addRecipient(RecipientInterface $recipient)
80
    {
81
        $jwe = clone $this;
82
        $jwe->recipients[] = $recipient;
83
84
        return $jwe;
85
    }
86
87
    /**
88
     * {@inheritdoc}
89
     */
90
    public function getRecipients()
91
    {
92
        return $this->recipients;
93
    }
94
95
    /**
96
     * {@inheritdoc}
97
     */
98
    public function getRecipient($id)
99
    {
100
        if (!isset($this->recipients[$id])) {
101
            throw new \InvalidArgumentException('The recipient does not exist.');
102
        }
103
        return $this->recipients[$id];
104
    }
105
106
    /**
107
     * {@inheritdoc}
108
     */
109
    public function getCiphertext()
110
    {
111
        return $this->ciphertext;
112
    }
113
114
    /**
115
     * {@inheritdoc}
116
     */
117
    public function withCiphertext($ciphertext)
118
    {
119
        $jwe = clone $this;
120
        $jwe->ciphertext = $ciphertext;
121
122
        return $jwe;
123
    }
124
125
    /**
126
     * {@inheritdoc}
127
     */
128
    public function getAAD()
129
    {
130
        return $this->aad;
131
    }
132
133
    /**
134
     * {@inheritdoc}
135
     */
136
    public function withAAD($aad)
137
    {
138
        $jwe = clone $this;
139
        $jwe->aad = $aad;
140
141
        return $jwe;
142
    }
143
144
    /**
145
     * {@inheritdoc}
146
     */
147
    public function getIV()
148
    {
149
        return $this->iv;
150
    }
151
152
    /**
153
     * {@inheritdoc}
154
     */
155
    public function withIV($iv)
156
    {
157
        $jwe = clone $this;
158
        $jwe->iv = $iv;
159
160
        return $jwe;
161
    }
162
163
    /**
164
     * {@inheritdoc}
165
     */
166
    public function getTag()
167
    {
168
        return $this->tag;
169
    }
170
171
    /**
172
     * {@inheritdoc}
173
     */
174
    public function withTag($tag)
175
    {
176
        $jwe = clone $this;
177
        $jwe->tag = $tag;
178
179
        return $jwe;
180
    }
181
182
    /**
183
     * {@inheritdoc}
184
     */
185
    public function getEncodedSharedProtectedHeaders()
186
    {
187
        return $this->encoded_shared_protected_headers;
188
    }
189
190
    /**
191
     * {@inheritdoc}
192
     */
193
    public function withEncodedSharedProtectedHeaders($encoded_shared_protected_headers)
194
    {
195
        $jwe = clone $this;
196
        $jwe->encoded_shared_protected_headers = $encoded_shared_protected_headers;
197
198
        return $jwe;
199
    }
200
201
    /**
202
     * {@inheritdoc}
203
     */
204
    public function getSharedProtectedHeaders()
205
    {
206
        return $this->shared_protected_headers;
207
    }
208
209
    /**
210
     * {@inheritdoc}
211
     */
212
    public function withSharedProtectedHeaders(array $shared_protected_headers)
213
    {
214
        $jwe = clone $this;
215
        $jwe->shared_protected_headers = $shared_protected_headers;
216
217
        return $jwe;
218
    }
219
220
    /**
221
     * {@inheritdoc}
222
     */
223
    public function withSharedProtectedHeader($key, $value)
224
    {
225
        $jwe = clone $this;
226
        $jwe->shared_protected_headers[$key] = $value;
227
228
        return $jwe;
229
    }
230
231
    /**
232
     * {@inheritdoc}
233
     */
234
    public function getSharedProtectedHeader($key)
235
    {
236
        if ($this->hasSharedProtectedHeader($key)) {
237
            return $this->shared_protected_headers[$key];
238
        }
239
        throw new \InvalidArgumentException(sprintf('The shared protected header "%s" does not exist', $key));
240
    }
241
242
    /**
243
     * {@inheritdoc}
244
     */
245
    public function hasSharedProtectedHeader($key)
246
    {
247
        return array_key_exists($key, $this->shared_protected_headers);
248
    }
249
250
    /**
251
     * {@inheritdoc}
252
     */
253
    public function withSharedHeaders(array $shared_headers)
254
    {
255
        $jwe = clone $this;
256
        $jwe->shared_headers = $shared_headers;
257
258
        return $jwe;
259
    }
260
261
    /**
262
     * {@inheritdoc}
263
     */
264
    public function withSharedHeader($key, $value)
265
    {
266
        $jwe = clone $this;
267
        $jwe->shared_headers[$key] = $value;
268
269
        return $jwe;
270
    }
271
272
    /**
273
     * {@inheritdoc}
274
     */
275
    public function getSharedHeaders()
276
    {
277
        return $this->shared_headers;
278
    }
279
280
    /**
281
     * {@inheritdoc}
282
     */
283
    public function getSharedHeader($key)
284
    {
285
        if ($this->hasSharedHeader($key)) {
286
            return $this->shared_headers[$key];
287
        }
288
        throw new \InvalidArgumentException(sprintf('The shared header "%s" does not exist', $key));
289
    }
290
291
    /**
292
     * {@inheritdoc}
293
     */
294
    public function hasSharedHeader($key)
295
    {
296
        return array_key_exists($key, $this->shared_headers);
297
    }
298
299
    /**
300
     * {@inheritdoc}
301
     */
302
    public function toCompactJSON($id)
303
    {
304
        $recipient = $this->getRecipient($id);
305
306
        if (empty($this->getSharedProtectedHeaders())) {
307
            throw new \InvalidArgumentException('This JWE does not have shared protected headers and cannot be converted into Compact JSON.');
308
        }
309
        if (!empty($this->getSharedHeaders()) || !empty($this->getRecipient($id)->getHeaders())) {
310
            throw new \InvalidArgumentException('This JWE has shared headers or recipient headers and cannot be converted into Compact JSON.');
311
        }
312
        if (!empty($this->getAAD())) {
313
            throw new \InvalidArgumentException('This JWE has AAD and cannot be converted into Compact JSON.');
314
        }
315
316
        return sprintf(
317
            '%s.%s.%s.%s.%s',
318
            $this->getEncodedSharedProtectedHeaders(),
319
            Base64Url::encode(null === $recipient->getEncryptedKey() ? '' : $recipient->getEncryptedKey()),
320
            Base64Url::encode(null === $this->getIV() ? '' : $this->getIV()),
321
            Base64Url::encode($this->getCiphertext()),
322
            Base64Url::encode(null === $this->getTag() ? '' : $this->getTag())
323
        );
324
    }
325
326
    /**
327
     * {@inheritdoc}
328
     */
329
    public function toFlattenedJSON($id)
330
    {
331
        $recipient = $this->getRecipient($id);
332
333
        $json = [
334
            'ciphertext' => Base64Url::encode($this->getCiphertext()),
335
        ];
336
        if (null !== $this->getIV()) {
337
            $json['iv'] = Base64Url::encode($this->getIV());
338
        }
339
        if (null !== $this->getTag()) {
340
            $json['tag'] = Base64Url::encode($this->getTag());
341
        }
342
        if (null !== $this->getAAD()) {
343
            $json['aad'] = Base64Url::encode($this->getAAD());
344
        }
345
        if (!empty($this->getSharedProtectedHeaders())) {
346
            $json['protected'] = $this->getEncodedSharedProtectedHeaders();
347
        }
348
        if (!empty($this->getSharedHeaders())) {
349
            $json['unprotected'] = $this->getSharedHeaders();
350
        }
351
        if (!empty($recipient->getHeaders())) {
352
            $json['header'] = $recipient->getHeaders();
353
        }
354
        if (!empty($recipient->getEncryptedKey())) {
355
            $json['encrypted_key'] = Base64Url::encode($recipient->getEncryptedKey());
356
        }
357
358
        return json_encode($json);
359
    }
360
361
    /**
362
     * {@inheritdoc}
363
     */
364
    public function toJSON()
365
    {
366
        $json = [
367
            'ciphertext' => Base64Url::encode($this->getCiphertext()),
368
        ];
369
        if (null !== $this->getIV()) {
370
            $json['iv'] = Base64Url::encode($this->getIV());
371
        }
372
        if (null !== $this->getTag()) {
373
            $json['tag'] = Base64Url::encode($this->getTag());
374
        }
375
        if (null !== $this->getAAD()) {
376
            $json['aad'] = Base64Url::encode($this->getAAD());
377
        }
378
        if (!empty($this->getSharedProtectedHeaders())) {
379
            $json['protected'] = $this->getEncodedSharedProtectedHeaders();
380
        }
381
        if (!empty($this->getSharedHeaders())) {
382
            $json['unprotected'] = $this->getSharedHeaders();
383
        }
384
        $json['recipients'] = [];
385
        foreach ($this->getRecipients() as $recipient) {
386
            $temp = [];
387
            if (!empty($recipient->getHeaders())) {
388
                $temp['header'] = $recipient->getHeaders();
389
            }
390
            if (!empty($recipient->getEncryptedKey())) {
391
                $temp['encrypted_key'] = Base64Url::encode($recipient->getEncryptedKey());
392
            }
393
            $json['recipients'][] = $temp;
394
        }
395
396
        return json_encode($json);
397
    }
398
399
    /**
400
     * {@inheritdoc}
401
     */
402
    public function getContentEncryptionKey()
403
    {
404
        return $this->content_encryption_key;
405
    }
406
407
    /**
408
     * {@inheritdoc}
409
     */
410
    public function withContentEncryptionKey($content_encryption_key)
411
    {
412
        $jwe = clone $this;
413
        $jwe->content_encryption_key = $content_encryption_key;
414
415
        return $jwe;
416
    }
417
}
418