Completed
Push — v2.0.x ( 7a58b6 )
by Florent
24:58
created

JWE::toCompactJSON()   B

Complexity

Conditions 6
Paths 3

Size

Total Lines 19
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

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