Completed
Push — master ( 2c8a8a...5f56ba )
by Florent
10:35 queued 08:00
created

JWE   A

Complexity

Total Complexity 24

Size/Duplication

Total Lines 313
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 0

Importance

Changes 0
Metric Value
wmc 24
lcom 2
cbo 0
dl 0
loc 313
rs 10
c 0
b 0
f 0

20 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 11 1
A create() 0 4 1
A getPayload() 0 4 1
A withPayload() 0 7 1
A countRecipients() 0 4 1
A isEncrypted() 0 4 1
A getRecipients() 0 4 1
A getRecipient() 0 8 2
A getCiphertext() 0 4 1
A getAAD() 0 4 1
A getIV() 0 4 1
A getTag() 0 4 1
A getEncodedSharedProtectedHeader() 0 4 1
A getSharedProtectedHeader() 0 4 1
A getSharedProtectedHeaderParameter() 0 8 2
A hasSharedProtectedHeaderParameter() 0 4 1
A getSharedHeader() 0 4 1
A getSharedHeaderParameter() 0 8 2
A hasSharedHeaderParameter() 0 4 1
A split() 0 18 2
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * The MIT License (MIT)
7
 *
8
 * Copyright (c) 2014-2018 Spomky-Labs
9
 *
10
 * This software may be modified and distributed under the terms
11
 * of the MIT license.  See the LICENSE file for details.
12
 */
13
14
namespace Jose\Component\Encryption;
15
16
use Jose\Component\Core\JWT;
17
18
class JWE implements JWT
19
{
20
    /**
21
     * @var Recipient[]
22
     */
23
    private $recipients = [];
24
25
    /**
26
     * @var string|null
27
     */
28
    private $ciphertext = null;
29
30
    /**
31
     * @var string
32
     */
33
    private $iv;
34
35
    /**
36
     * @var string|null
37
     */
38
    private $aad = null;
39
40
    /**
41
     * @var string
42
     */
43
    private $tag;
44
45
    /**
46
     * @var array
47
     */
48
    private $sharedHeader = [];
49
50
    /**
51
     * @var array
52
     */
53
    private $sharedProtectedHeader = [];
54
55
    /**
56
     * @var string|null
57
     */
58
    private $encodedSharedProtectedHeader = null;
59
60
    /**
61
     * @var string|null
62
     */
63
    private $payload = null;
64
65
    /**
66
     * JWE constructor.
67
     *
68
     * @param string      $ciphertext
69
     * @param string      $iv
70
     * @param string      $tag
71
     * @param null|string $aad
72
     * @param array       $sharedHeader
73
     * @param array       $sharedProtectedHeader
74
     * @param null|string $encodedSharedProtectedHeader
75
     * @param array       $recipients
76
     */
77
    private function __construct(string $ciphertext, string $iv, string $tag, ?string $aad = null, array $sharedHeader = [], array $sharedProtectedHeader = [], ?string $encodedSharedProtectedHeader = null, array $recipients = [])
78
    {
79
        $this->ciphertext = $ciphertext;
80
        $this->iv = $iv;
81
        $this->aad = $aad;
82
        $this->tag = $tag;
83
        $this->sharedHeader = $sharedHeader;
84
        $this->sharedProtectedHeader = $sharedProtectedHeader;
85
        $this->encodedSharedProtectedHeader = $encodedSharedProtectedHeader;
86
        $this->recipients = $recipients;
87
    }
88
89
    /**
90
     * Creates a new JWE object.
91
     *
92
     * @param string      $ciphertext
93
     * @param string      $iv
94
     * @param string      $tag
95
     * @param null|string $aad
96
     * @param array       $sharedHeader
97
     * @param array       $sharedProtectedHeader
98
     * @param null|string $encodedSharedProtectedHeader
99
     * @param array       $recipients
100
     *
101
     * @return JWE
102
     */
103
    public static function create(string $ciphertext, string $iv, string $tag, ?string $aad = null, array $sharedHeader = [], array $sharedProtectedHeader = [], ?string $encodedSharedProtectedHeader = null, array $recipients = []): self
104
    {
105
        return new self($ciphertext, $iv, $tag, $aad, $sharedHeader, $sharedProtectedHeader, $encodedSharedProtectedHeader, $recipients);
106
    }
107
108
    /**
109
     * {@inheritdoc}
110
     */
111
    public function getPayload(): ?string
112
    {
113
        return $this->payload;
114
    }
115
116
    /**
117
     * Set the payload.
118
     * This method is immutable and a new object will be returned.
119
     *
120
     * @param string $payload
121
     *
122
     * @return JWE
123
     */
124
    public function withPayload(string $payload): self
125
    {
126
        $clone = clone $this;
127
        $clone->payload = $payload;
128
129
        return $clone;
130
    }
131
132
    /**
133
     * Returns the number of recipients associated with the JWS.
134
     *
135
     * @return int
136
     */
137
    public function countRecipients(): int
138
    {
139
        return count($this->recipients);
140
    }
141
142
    /**
143
     * Returns true is the JWE has already been encrypted.
144
     *
145
     * @return bool
146
     */
147
    public function isEncrypted(): bool
148
    {
149
        return null !== $this->getCiphertext();
150
    }
151
152
    /**
153
     * Returns the recipients associated with the JWS.
154
     *
155
     * @return Recipient[]
156
     */
157
    public function getRecipients(): array
158
    {
159
        return $this->recipients;
160
    }
161
162
    /**
163
     * Returns the recipient object at the given index.
164
     *
165
     * @param int $id
166
     *
167
     * @return Recipient
168
     */
169
    public function getRecipient(int $id): Recipient
170
    {
171
        if (!array_key_exists($id, $this->recipients)) {
172
            throw new \InvalidArgumentException('The recipient does not exist.');
173
        }
174
175
        return $this->recipients[$id];
176
    }
177
178
    /**
179
     * Returns the ciphertext. This method will return null is the JWE has not yet been encrypted.
180
     *
181
     * @return string|null The cyphertext
182
     */
183
    public function getCiphertext(): ?string
184
    {
185
        return $this->ciphertext;
186
    }
187
188
    /**
189
     * Returns the Additional Authentication Data if available.
190
     *
191
     * @return string|null
192
     */
193
    public function getAAD(): ?string
194
    {
195
        return $this->aad;
196
    }
197
198
    /**
199
     * Returns the Initialization Vector if available.
200
     *
201
     * @return string|null
202
     */
203
    public function getIV(): ?string
204
    {
205
        return $this->iv;
206
    }
207
208
    /**
209
     * Returns the tag if available.
210
     *
211
     * @return string|null
212
     */
213
    public function getTag(): ?string
214
    {
215
        return $this->tag;
216
    }
217
218
    /**
219
     * Returns the encoded shared protected header.
220
     *
221
     * @return string
222
     */
223
    public function getEncodedSharedProtectedHeader(): string
224
    {
225
        return $this->encodedSharedProtectedHeader ?? '';
226
    }
227
228
    /**
229
     * Returns the shared protected header.
230
     *
231
     * @return array
232
     */
233
    public function getSharedProtectedHeader(): array
234
    {
235
        return $this->sharedProtectedHeader;
236
    }
237
238
    /**
239
     * Returns the shared protected header parameter identified by the given key.
240
     * Throws an exception is the the parameter is not available.
241
     *
242
     * @param string $key The key
243
     *
244
     * @return mixed|null
245
     */
246
    public function getSharedProtectedHeaderParameter(string $key)
247
    {
248
        if ($this->hasSharedProtectedHeaderParameter($key)) {
249
            return $this->sharedProtectedHeader[$key];
250
        }
251
252
        throw new \InvalidArgumentException(sprintf('The shared protected header "%s" does not exist.', $key));
253
    }
254
255
    /**
256
     * Returns true if the shared protected header has the parameter identified by the given key.
257
     *
258
     * @param string $key The key
259
     *
260
     * @return bool
261
     */
262
    public function hasSharedProtectedHeaderParameter(string $key): bool
263
    {
264
        return array_key_exists($key, $this->sharedProtectedHeader);
265
    }
266
267
    /**
268
     * Returns the shared header.
269
     *
270
     * @return array
271
     */
272
    public function getSharedHeader(): array
273
    {
274
        return $this->sharedHeader;
275
    }
276
277
    /**
278
     * Returns the shared header parameter identified by the given key.
279
     * Throws an exception is the the parameter is not available.
280
     *
281
     * @param string $key The key
282
     *
283
     * @return mixed|null
284
     */
285
    public function getSharedHeaderParameter(string $key)
286
    {
287
        if ($this->hasSharedHeaderParameter($key)) {
288
            return $this->sharedHeader[$key];
289
        }
290
291
        throw new \InvalidArgumentException(sprintf('The shared header "%s" does not exist.', $key));
292
    }
293
294
    /**
295
     * Returns true if the shared header has the parameter identified by the given key.
296
     *
297
     * @param string $key The key
298
     *
299
     * @return bool
300
     */
301
    public function hasSharedHeaderParameter(string $key): bool
302
    {
303
        return array_key_exists($key, $this->sharedHeader);
304
    }
305
306
    /**
307
     * This method splits the JWE into a list of JWEs.
308
     * It is only useful when the JWE contains more than one recipient (JSON General Serialization).
309
     *
310
     * @return JWE[]
311
     */
312
    public function split(): array
313
    {
314
        $result = [];
315
        foreach ($this->recipients as $recipient) {
316
            $result[] = self::create(
317
                $this->ciphertext,
318
                $this->iv,
319
                $this->tag,
320
                $this->aad,
321
                $this->sharedHeader,
322
                $this->sharedProtectedHeader,
323
                $this->encodedSharedProtectedHeader,
324
                [$recipient]
325
            );
326
        }
327
328
        return $result;
329
    }
330
}
331