Coverage Report

Created: 2026-08-31 07:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cjose/src/jwe.c
Line
Count
Source
1
/*!
2
 * Copyrights
3
 *
4
 * Portions created or assigned to Cisco Systems, Inc. are
5
 * Copyright (c) 2014-2016 Cisco Systems, Inc.  All Rights Reserved.
6
 */
7
8
#define OPENSSL_API_COMPAT 0x10000000L
9
10
#include <cjose/base64.h>
11
#include <cjose/header.h>
12
#include <cjose/jwe.h>
13
#include <cjose/util.h>
14
15
#include <stdlib.h>
16
#include <string.h>
17
#include <limits.h>
18
#include <openssl/rand.h>
19
#include <openssl/crypto.h>
20
#include <openssl/rsa.h>
21
#include <openssl/evp.h>
22
#include <openssl/aes.h>
23
#include <openssl/hmac.h>
24
25
#include "include/concatkdf_int.h"
26
#include "include/header_int.h"
27
#include "include/jwk_int.h"
28
#include "include/jwe_int.h"
29
#include "include/util_int.h"
30
31
////////////////////////////////////////////////////////////////////////////////
32
static bool _cjose_jwe_set_cek_aes_gcm(cjose_jwe_t *jwe, const cjose_jwk_t *jwk, bool random, cjose_err *err);
33
34
static bool _cjose_jwe_set_cek_aes_cbc(cjose_jwe_t *jwe, const cjose_jwk_t *jwk, bool random, cjose_err *err);
35
36
static bool _cjose_jwe_encrypt_ek_dir(_jwe_int_recipient_t *recipient, cjose_jwe_t *jwe, const cjose_jwk_t *jwk, cjose_err *err);
37
38
static bool _cjose_jwe_decrypt_ek_dir(_jwe_int_recipient_t *recipient, cjose_jwe_t *jwe, const cjose_jwk_t *jwk, cjose_err *err);
39
40
static bool _cjose_jwe_encrypt_ek_aes_kw(_jwe_int_recipient_t *recipient, cjose_jwe_t *jwe, const cjose_jwk_t *jwk, cjose_err *err);
41
42
static bool _cjose_jwe_decrypt_ek_aes_kw(_jwe_int_recipient_t *recipient, cjose_jwe_t *jwe, const cjose_jwk_t *jwk, cjose_err *err);
43
44
static bool
45
_cjose_jwe_encrypt_ek_rsa_oaep(_jwe_int_recipient_t *recipient, cjose_jwe_t *jwe, const cjose_jwk_t *jwk, cjose_err *err);
46
47
static bool
48
_cjose_jwe_decrypt_ek_rsa_oaep(_jwe_int_recipient_t *recipient, cjose_jwe_t *jwe, const cjose_jwk_t *jwk, cjose_err *err);
49
50
#ifdef HAVE_RSA_PKCS1_PADDING
51
static bool _cjose_jwe_encrypt_ek_rsa1_5(_jwe_int_recipient_t *recipient, cjose_jwe_t *jwe, const cjose_jwk_t *jwk, cjose_err *err);
52
53
static bool _cjose_jwe_decrypt_ek_rsa1_5(_jwe_int_recipient_t *recipient, cjose_jwe_t *jwe, const cjose_jwk_t *jwk, cjose_err *err);
54
#endif // HAVE_RSA_PKCS1_PADDING
55
56
static bool
57
_cjose_jwe_encrypt_ek_ecdh_es(_jwe_int_recipient_t *recipient, cjose_jwe_t *jwe, const cjose_jwk_t *jwk, cjose_err *err);
58
59
static bool
60
_cjose_jwe_decrypt_ek_ecdh_es(_jwe_int_recipient_t *recipient, cjose_jwe_t *jwe, const cjose_jwk_t *jwk, cjose_err *err);
61
62
static bool _cjose_jwe_set_iv_aes_gcm(cjose_jwe_t *jwe, cjose_err *err);
63
64
static bool _cjose_jwe_set_iv_aes_cbc(cjose_jwe_t *jwe, cjose_err *err);
65
66
static bool _cjose_jwe_encrypt_dat_aes_gcm(cjose_jwe_t *jwe, const uint8_t *plaintext, size_t plaintext_len, cjose_err *err);
67
68
static bool _cjose_jwe_encrypt_dat_aes_cbc(cjose_jwe_t *jwe, const uint8_t *plaintext, size_t plaintext_len, cjose_err *err);
69
70
static bool _cjose_jwe_decrypt_dat_aes_gcm(cjose_jwe_t *jwe, cjose_err *err);
71
72
static bool _cjose_jwe_decrypt_dat_aes_cbc(cjose_jwe_t *jwe, cjose_err *err);
73
74
static bool _cjose_jwe_validate_decrypt_key(_jwe_int_recipient_t *recipient,
75
                                            cjose_header_t *protected_header,
76
                                            cjose_header_t *shared_header,
77
                                            const cjose_jwk_t *jwk,
78
                                            cjose_err *err);
79
80
static void _cjose_release_cek(uint8_t **cek, size_t cek_len)
81
119k
{
82
83
119k
    if (NULL == *cek)
84
83.4k
    {
85
83.4k
        return;
86
83.4k
    }
87
88
36.3k
    _cjose_cleanse_dealloc(*cek, cek_len);
89
36.3k
    *cek = 0;
90
36.3k
}
91
92
////////////////////////////////////////////////////////////////////////////////
93
static bool _cjose_empty_json(json_t *arg)
94
32.5k
{
95
96
32.5k
    return (NULL == arg || json_is_null(arg) || (json_is_object(arg) && NULL == json_object_iter_key(arg)));
97
32.5k
}
98
99
////////////////////////////////////////////////////////////////////////////////
100
static void _cjose_dealloc_part(struct _cjose_jwe_part_int *part)
101
335k
{
102
103
335k
    cjose_get_dealloc()(part->raw);
104
335k
    cjose_get_dealloc()(part->b64u);
105
335k
}
106
107
static json_t *_cjose_parse_json_object(const char *str, size_t len, cjose_err *err)
108
22.5k
{
109
110
    // unfortunately, it's not possible to tell whether the error is due
111
    // to syntax, or memory shortage. See https://github.com/akheron/jansson/issues/352
112
113
22.5k
    json_error_t j_err;
114
22.5k
    json_t *json = json_loadb(str, len, 0, &j_err);
115
22.5k
    if (NULL == json || !json_is_object(json))
116
1.75k
    {
117
1.75k
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
118
1.75k
        json_decref(json);
119
1.75k
        return NULL;
120
1.75k
    }
121
122
20.8k
    return json;
123
22.5k
}
124
125
static inline bool _cjose_convert_part(struct _cjose_jwe_part_int *part, cjose_err *err)
126
81.3k
{
127
128
81.3k
    if ((NULL == part->b64u)
129
65.1k
        && (!cjose_base64url_encode((const uint8_t *)part->raw, part->raw_len, &part->b64u, &part->b64u_len, err)))
130
0
    {
131
132
0
        return false;
133
0
    }
134
135
    // dealloc the raw part, we will never need it again
136
81.3k
    cjose_get_dealloc()(part->raw);
137
81.3k
    part->raw = NULL;
138
81.3k
    return true;
139
81.3k
}
140
141
////////////////////////////////////////////////////////////////////////////////
142
static bool _cjose_convert_to_base64(struct _cjose_jwe_int *jwe, cjose_err *err)
143
16.2k
{
144
145
16.2k
    if (!_cjose_convert_part(&jwe->enc_header, err) || !_cjose_convert_part(&jwe->enc_iv, err)
146
16.2k
        || !_cjose_convert_part(&jwe->enc_ct, err) || !_cjose_convert_part(&jwe->enc_auth_tag, err))
147
0
    {
148
149
0
        return false;
150
0
    }
151
152
32.5k
    for (int i = 0; i < jwe->to_count; i++)
153
16.2k
    {
154
16.2k
        if (!_cjose_convert_part(&jwe->to[i].enc_key, err))
155
0
        {
156
0
            return false;
157
0
        }
158
16.2k
    }
159
160
16.2k
    return true;
161
16.2k
}
162
163
////////////////////////////////////////////////////////////////////////////////
164
static size_t _keylen_from_enc(const char *alg)
165
0
{
166
0
    size_t keylen = 0;
167
168
0
    if (0 == strcmp(alg, CJOSE_HDR_ENC_A128GCM))
169
0
    {
170
0
        keylen = 128;
171
0
    }
172
0
    else if (0 == strcmp(alg, CJOSE_HDR_ENC_A192GCM))
173
0
    {
174
0
        keylen = 192;
175
0
    }
176
0
    else if (0 == strcmp(alg, CJOSE_HDR_ENC_A256GCM))
177
0
    {
178
0
        keylen = 256;
179
0
    }
180
0
    else if (0 == strcmp(alg, CJOSE_HDR_ENC_A128CBC_HS256))
181
0
    {
182
0
        keylen = 256;
183
0
    }
184
0
    else if (0 == strcmp(alg, CJOSE_HDR_ENC_A192CBC_HS384))
185
0
    {
186
0
        keylen = 384;
187
0
    }
188
0
    else if (0 == strcmp(alg, CJOSE_HDR_ENC_A256CBC_HS512))
189
0
    {
190
0
        keylen = 512;
191
0
    }
192
193
0
    return keylen;
194
0
}
195
196
////////////////////////////////////////////////////////////////////////////////
197
static bool _cjose_jwe_malloc(size_t bytes, bool random, uint8_t **buffer, cjose_err *err)
198
247k
{
199
247k
    *buffer = (uint8_t *)cjose_get_alloc()(bytes);
200
247k
    if ((NULL == *buffer) && (bytes > 0))
201
0
    {
202
0
        CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY);
203
0
        return false;
204
0
    }
205
247k
    if (random)
206
16.2k
    {
207
16.2k
        if (RAND_bytes((unsigned char *)*buffer, bytes) != 1)
208
0
        {
209
0
            cjose_get_dealloc()(*buffer);
210
0
            CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
211
0
            return false;
212
0
        }
213
16.2k
    }
214
230k
    else if (bytes > 0)
215
230k
    {
216
        // *buffer may be NULL for a zero-byte request (malloc(0)); passing NULL
217
        // to memset is undefined even with a zero length, so skip it
218
230k
        memset(*buffer, 0, bytes);
219
230k
    }
220
247k
    return true;
221
247k
}
222
223
////////////////////////////////////////////////////////////////////////////////
224
static bool _cjose_jwe_build_hdr(cjose_jwe_t *jwe, cjose_err *err)
225
16.2k
{
226
    // serialize the header
227
16.2k
    char *hdr_str = json_dumps(jwe->hdr, JSON_ENCODE_ANY | JSON_PRESERVE_ORDER);
228
16.2k
    if (NULL == hdr_str)
229
0
    {
230
0
        CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY);
231
0
        return false;
232
0
    }
233
234
    // copy the serialized header to JWE (hdr_str is owned by header object)
235
16.2k
    size_t len = strlen(hdr_str);
236
16.2k
    uint8_t *data = (uint8_t *)_cjose_strndup(hdr_str, len, err);
237
16.2k
    if (!data)
238
0
    {
239
0
        cjose_get_dealloc()(hdr_str);
240
0
        return false;
241
0
    }
242
243
16.2k
    jwe->enc_header.raw = data;
244
16.2k
    jwe->enc_header.raw_len = len;
245
16.2k
    cjose_get_dealloc()(hdr_str);
246
247
16.2k
    return true;
248
16.2k
}
249
250
static const char *_cjose_jwe_get_from_headers(cjose_header_t *protected_header,
251
                                               cjose_header_t *unprotected_header,
252
                                               cjose_header_t *personal_header,
253
                                               const char *key)
254
57.3k
{
255
256
    // TODO: https://github.com/cisco/cjose/issues/52
257
57.3k
    cjose_header_t *headers[] = { personal_header, unprotected_header, protected_header };
258
259
172k
    for (int i = 0; i < 3; i++)
260
172k
    {
261
172k
        if (NULL == headers[i])
262
114k
        {
263
114k
            continue;
264
114k
        }
265
57.3k
        json_t *obj = json_object_get((json_t *)headers[i], key);
266
57.3k
        if (NULL == obj)
267
10
        {
268
10
            continue;
269
10
        }
270
57.3k
        const char *value = json_string_value(obj);
271
57.3k
        if (NULL == value)
272
3
        {
273
3
            continue;
274
3
        }
275
57.3k
        return value;
276
57.3k
    }
277
278
13
    return NULL;
279
57.3k
}
280
281
static bool _cjose_jwe_validate_enc(cjose_jwe_t *jwe, cjose_header_t *protected_header, cjose_err *err)
282
36.6k
{
283
284
36.6k
    const char *enc = cjose_header_get(protected_header, CJOSE_HDR_ENC, err);
285
36.6k
    if (NULL == enc)
286
6
    {
287
6
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
288
6
        return false;
289
6
    }
290
291
36.6k
    if ((strcmp(enc, CJOSE_HDR_ENC_A128GCM) == 0) || (strcmp(enc, CJOSE_HDR_ENC_A192GCM) == 0)
292
36.6k
        || (strcmp(enc, CJOSE_HDR_ENC_A256GCM) == 0))
293
36.2k
    {
294
36.2k
        jwe->fns.set_cek = _cjose_jwe_set_cek_aes_gcm;
295
36.2k
        jwe->fns.set_iv = _cjose_jwe_set_iv_aes_gcm;
296
36.2k
        jwe->fns.encrypt_dat = _cjose_jwe_encrypt_dat_aes_gcm;
297
36.2k
        jwe->fns.decrypt_dat = _cjose_jwe_decrypt_dat_aes_gcm;
298
36.2k
    }
299
398
    else if ((strcmp(enc, CJOSE_HDR_ENC_A128CBC_HS256) == 0) || (strcmp(enc, CJOSE_HDR_ENC_A192CBC_HS384) == 0)
300
314
             || (strcmp(enc, CJOSE_HDR_ENC_A256CBC_HS512) == 0))
301
84
    {
302
84
        jwe->fns.set_cek = _cjose_jwe_set_cek_aes_cbc;
303
84
        jwe->fns.set_iv = _cjose_jwe_set_iv_aes_cbc;
304
84
        jwe->fns.encrypt_dat = _cjose_jwe_encrypt_dat_aes_cbc;
305
84
        jwe->fns.decrypt_dat = _cjose_jwe_decrypt_dat_aes_cbc;
306
84
    }
307
308
36.6k
    if (NULL == jwe->fns.set_cek || NULL == jwe->fns.set_iv || NULL == jwe->fns.encrypt_dat || NULL == jwe->fns.decrypt_dat)
309
314
    {
310
314
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
311
314
        return false;
312
314
    }
313
314
36.3k
    return true;
315
36.6k
}
316
317
////////////////////////////////////////////////////////////////////////////////
318
static bool _cjose_jwe_validate_alg(cjose_header_t *protected_header,
319
                                    cjose_header_t *unprotected_header,
320
                                    bool is_multiple,
321
                                    _jwe_int_recipient_t *recipient,
322
                                    cjose_err *err)
323
37.1k
{
324
37.1k
    static const char *const supported_crit_headers[] = { "alg", "enc", "cty", "epk", "apu", "apv" };
325
326
37.1k
    if (!_cjose_header_validate_crit(protected_header, supported_crit_headers,
327
37.1k
                                     sizeof(supported_crit_headers) / sizeof(supported_crit_headers[0]), err)
328
37.1k
        || !_cjose_header_validate_crit(unprotected_header, supported_crit_headers,
329
37.1k
                                        sizeof(supported_crit_headers) / sizeof(supported_crit_headers[0]), err)
330
37.1k
        || !_cjose_header_validate_crit((cjose_header_t *)recipient->unprotected, supported_crit_headers,
331
37.1k
                                        sizeof(supported_crit_headers) / sizeof(supported_crit_headers[0]), err))
332
0
    {
333
0
        return false;
334
0
    }
335
336
37.1k
    const char *alg = _cjose_jwe_get_from_headers(protected_header, unprotected_header, (cjose_header_t *)recipient->unprotected,
337
37.1k
                                                  CJOSE_HDR_ALG);
338
339
37.1k
    if (NULL == alg)
340
13
    {
341
13
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
342
13
        return false;
343
13
    }
344
345
    // set JWE build functions based on header contents
346
37.0k
    if (strcmp(alg, CJOSE_HDR_ALG_RSA_OAEP) == 0)
347
69
    {
348
69
        recipient->fns.encrypt_ek = _cjose_jwe_encrypt_ek_rsa_oaep;
349
69
        recipient->fns.decrypt_ek = _cjose_jwe_decrypt_ek_rsa_oaep;
350
69
    }
351
352
#ifdef HAVE_RSA_PKCS1_PADDING
353
    if (strcmp(alg, CJOSE_HDR_ALG_RSA1_5) == 0)
354
    {
355
        recipient->fns.encrypt_ek = _cjose_jwe_encrypt_ek_rsa1_5;
356
        recipient->fns.decrypt_ek = _cjose_jwe_decrypt_ek_rsa1_5;
357
    }
358
#endif // HAVE_RSA_PKCS1_PADDING
359
37.0k
    if (strcmp(alg, CJOSE_HDR_ALG_ECDH_ES) == 0)
360
5
    {
361
5
        if (is_multiple)
362
0
        {
363
0
            CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
364
0
            return false;
365
0
        }
366
5
        recipient->fns.encrypt_ek = _cjose_jwe_encrypt_ek_ecdh_es;
367
5
        recipient->fns.decrypt_ek = _cjose_jwe_decrypt_ek_ecdh_es;
368
5
    }
369
37.0k
    if (strcmp(alg, CJOSE_HDR_ALG_DIR) == 0)
370
36.2k
    {
371
36.2k
        if (is_multiple)
372
0
        {
373
0
            CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
374
0
            return false;
375
0
        }
376
36.2k
        recipient->fns.encrypt_ek = _cjose_jwe_encrypt_ek_dir;
377
36.2k
        recipient->fns.decrypt_ek = _cjose_jwe_decrypt_ek_dir;
378
36.2k
    }
379
37.0k
    if ((strcmp(alg, CJOSE_HDR_ALG_A128KW) == 0) || (strcmp(alg, CJOSE_HDR_ALG_A192KW) == 0)
380
36.8k
        || (strcmp(alg, CJOSE_HDR_ALG_A256KW) == 0))
381
304
    {
382
304
        recipient->fns.encrypt_ek = _cjose_jwe_encrypt_ek_aes_kw;
383
304
        recipient->fns.decrypt_ek = _cjose_jwe_decrypt_ek_aes_kw;
384
304
    }
385
386
    // ensure required builders have been assigned
387
37.0k
    if (NULL == recipient->fns.encrypt_ek || NULL == recipient->fns.decrypt_ek)
388
414
    {
389
414
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
390
414
        return false;
391
414
    }
392
393
36.6k
    return true;
394
37.0k
}
395
396
////////////////////////////////////////////////////////////////////////////////
397
static bool _cjose_jwe_set_cek_aes_gcm(cjose_jwe_t *jwe, const cjose_jwk_t *jwk, bool random, cjose_err *err)
398
36.2k
{
399
36.2k
    if (NULL != jwe->cek)
400
0
    {
401
0
        return true;
402
0
    }
403
404
    // make sure we have an enc header
405
36.2k
    json_t *enc_obj = json_object_get(jwe->hdr, CJOSE_HDR_ENC);
406
36.2k
    if (NULL == enc_obj)
407
0
    {
408
0
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
409
0
        return false;
410
0
    }
411
36.2k
    const char *enc = json_string_value(enc_obj);
412
413
    // determine the CEK key size based on the encryption algorithm
414
36.2k
    size_t keysize = 0;
415
36.2k
    if (strcmp(enc, CJOSE_HDR_ENC_A128GCM) == 0)
416
1
        keysize = 16;
417
36.2k
    else if (strcmp(enc, CJOSE_HDR_ENC_A192GCM) == 0)
418
1
        keysize = 24;
419
36.2k
    else if (strcmp(enc, CJOSE_HDR_ENC_A256GCM) == 0)
420
36.2k
        keysize = 32;
421
422
    // reject an unrecognized enc rather than proceeding with a zero-length CEK
423
36.2k
    if (0 == keysize)
424
0
    {
425
0
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
426
0
        return false;
427
0
    }
428
429
    // if no JWK is provided, generate a random key
430
36.2k
    if (NULL == jwk)
431
97
    {
432
97
        _cjose_release_cek(&jwe->cek, jwe->cek_len);
433
97
        if (!_cjose_jwe_malloc(keysize, random, &jwe->cek, err))
434
0
        {
435
0
            return false;
436
0
        }
437
97
        jwe->cek_len = keysize;
438
97
    }
439
36.1k
    else
440
36.1k
    {
441
        // if a JWK is provided, it must be a symmetric key of correct size
442
36.1k
        if (CJOSE_JWK_KTY_OCT != cjose_jwk_get_kty(jwk, err) || jwk->keysize != keysize * 8 || NULL == jwk->keydata)
443
2
        {
444
2
            CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
445
2
            return false;
446
2
        }
447
448
        // copy the key material directly from jwk to the jwe->cek
449
36.1k
        _cjose_release_cek(&jwe->cek, jwe->cek_len);
450
36.1k
        if (!_cjose_jwe_malloc(keysize, false, &jwe->cek, err))
451
0
        {
452
0
            return false;
453
0
        }
454
36.1k
        memcpy(jwe->cek, jwk->keydata, keysize);
455
36.1k
        jwe->cek_len = keysize;
456
36.1k
    }
457
458
36.2k
    return true;
459
36.2k
}
460
461
////////////////////////////////////////////////////////////////////////////////
462
static bool _cjose_jwe_set_cek_aes_cbc(cjose_jwe_t *jwe, const cjose_jwk_t *jwk, bool random, cjose_err *err)
463
85
{
464
465
85
    if (NULL != jwe->cek)
466
0
    {
467
0
        return true;
468
0
    }
469
470
    // make sure we have an enc header
471
85
    json_t *enc_obj = json_object_get(jwe->hdr, CJOSE_HDR_ENC);
472
85
    if (NULL == enc_obj)
473
0
    {
474
0
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
475
0
        return false;
476
0
    }
477
85
    const char *enc = json_string_value(enc_obj);
478
479
    // determine the CEK key size based on the encryption algorithm
480
85
    size_t keysize = 0;
481
85
    if (strcmp(enc, CJOSE_HDR_ENC_A128CBC_HS256) == 0)
482
85
        keysize = 32;
483
0
    else if (strcmp(enc, CJOSE_HDR_ENC_A192CBC_HS384) == 0)
484
0
        keysize = 48;
485
0
    else if (strcmp(enc, CJOSE_HDR_ENC_A256CBC_HS512) == 0)
486
0
        keysize = 64;
487
488
    // reject an unrecognized enc rather than proceeding with a zero-length CEK
489
85
    if (0 == keysize)
490
0
    {
491
0
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
492
0
        return false;
493
0
    }
494
495
    // if no JWK is provided, generate a random key
496
85
    if (NULL == jwk)
497
83
    {
498
83
        _cjose_release_cek(&jwe->cek, jwe->cek_len);
499
83
        if (!_cjose_jwe_malloc(keysize, random, &jwe->cek, err))
500
0
        {
501
0
            return false;
502
0
        }
503
83
        jwe->cek_len = keysize;
504
83
    }
505
2
    else
506
2
    {
507
        // if a JWK is provided, it must be a symmetric key of correct size
508
2
        if (CJOSE_JWK_KTY_OCT != cjose_jwk_get_kty(jwk, err) || jwk->keysize != keysize * 8 || NULL == jwk->keydata)
509
2
        {
510
2
            CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
511
2
            return false;
512
2
        }
513
514
        // copy the key material directly from jwk to the jwe->cek
515
0
        _cjose_release_cek(&jwe->cek, jwe->cek_len);
516
0
        if (!_cjose_jwe_malloc(keysize, false, &jwe->cek, err))
517
0
        {
518
0
            return false;
519
0
        }
520
0
        memcpy(jwe->cek, jwk->keydata, keysize);
521
0
        jwe->cek_len = keysize;
522
0
    }
523
83
    return true;
524
85
}
525
526
////////////////////////////////////////////////////////////////////////////////
527
static bool _cjose_jwe_encrypt_ek_dir(_jwe_int_recipient_t *recipient, cjose_jwe_t *jwe, const cjose_jwk_t *jwk, cjose_err *err)
528
16.2k
{
529
    // for direct encryption, JWE sec 5.1, step 6: let CEK be the symmetric key.
530
16.2k
    if (!jwe->fns.set_cek(jwe, jwk, false, err))
531
0
    {
532
0
        return false;
533
0
    }
534
535
    // for direct encryption, JWE sec 5.1, step 5: let EK be empty octet seq.
536
16.2k
    recipient->enc_key.raw = NULL;
537
16.2k
    recipient->enc_key.raw_len = 0;
538
539
16.2k
    return true;
540
16.2k
}
541
542
////////////////////////////////////////////////////////////////////////////////
543
static bool _cjose_jwe_decrypt_ek_dir(_jwe_int_recipient_t *recipient, cjose_jwe_t *jwe, const cjose_jwk_t *jwk, cjose_err *err)
544
19.8k
{
545
    // do not try and decrypt the ek. that's impossible.
546
    // instead... only try to realize the truth.  there is no ek.
547
19.8k
    return jwe->fns.set_cek(jwe, jwk, false, err);
548
19.8k
}
549
550
////////////////////////////////////////////////////////////////////////////////
551
static bool _cjose_jwe_encrypt_ek_aes_kw(_jwe_int_recipient_t *recipient, cjose_jwe_t *jwe, const cjose_jwk_t *jwk, cjose_err *err)
552
0
{
553
0
    if (NULL == jwe || NULL == jwk)
554
0
    {
555
0
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
556
0
        return false;
557
0
    }
558
559
    // jwk must be OCT
560
0
    if (jwk->kty != CJOSE_JWK_KTY_OCT)
561
0
    {
562
0
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
563
0
        return false;
564
0
    }
565
566
    // generate random CEK
567
0
    if (!jwe->fns.set_cek(jwe, NULL, true, err))
568
0
    {
569
0
        return false;
570
0
    }
571
572
    // create the AES encryption key from the shared key
573
0
    AES_KEY akey;
574
0
    if (AES_set_encrypt_key(jwk->keydata, jwk->keysize, &akey) < 0)
575
0
    {
576
0
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
577
0
        return false;
578
0
    }
579
580
    // allocate buffer for encrypted CEK (=cek_len + 8)
581
0
    if (!_cjose_jwe_malloc(jwe->cek_len + 8, false, &recipient->enc_key.raw, err))
582
0
    {
583
0
        return false;
584
0
    }
585
586
    // AES wrap the CEK
587
0
    int len = AES_wrap_key(&akey, NULL, recipient->enc_key.raw, jwe->cek, jwe->cek_len);
588
0
    if (len <= 0)
589
0
    {
590
0
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
591
0
        return false;
592
0
    }
593
0
    recipient->enc_key.raw_len = len;
594
595
0
    return true;
596
0
}
597
598
////////////////////////////////////////////////////////////////////////////////
599
static bool _cjose_jwe_decrypt_ek_aes_kw(_jwe_int_recipient_t *recipient, cjose_jwe_t *jwe, const cjose_jwk_t *jwk, cjose_err *err)
600
229
{
601
229
    if (NULL == jwe || NULL == jwk)
602
0
    {
603
0
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
604
0
        return false;
605
0
    }
606
607
    // jwk must be OCT
608
229
    if (jwk->kty != CJOSE_JWK_KTY_OCT)
609
0
    {
610
0
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
611
0
        return false;
612
0
    }
613
614
    // create the AES decryption key from the shared key
615
229
    AES_KEY akey;
616
229
    if (AES_set_decrypt_key(jwk->keydata, jwk->keysize, &akey) < 0)
617
115
    {
618
115
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
619
115
        return false;
620
115
    }
621
622
114
    if (!jwe->fns.set_cek(jwe, NULL, false, err))
623
0
    {
624
0
        return false;
625
0
    }
626
627
    // the wrapped key (RFC 3394) is always the plaintext CEK length plus 8 bytes;
628
    // enforce this before calling AES_unwrap_key, which would otherwise copy the
629
    // attacker-controlled encrypted_key into the fixed-size jwe->cek buffer
630
114
    if (recipient->enc_key.raw_len != jwe->cek_len + 8)
631
40
    {
632
40
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
633
40
        return false;
634
40
    }
635
636
    // AES unwrap the CEK in to jwe->cek
637
74
    int len = AES_unwrap_key(&akey, (const unsigned char *)NULL, jwe->cek, (const unsigned char *)recipient->enc_key.raw,
638
74
                             recipient->enc_key.raw_len);
639
74
    if (len <= 0)
640
2
    {
641
2
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
642
2
        return false;
643
2
    }
644
72
    jwe->cek_len = len;
645
646
72
    return true;
647
74
}
648
649
////////////////////////////////////////////////////////////////////////////////
650
static bool _cjose_jwe_encrypt_ek_rsa_padding(
651
    _jwe_int_recipient_t *recipient, cjose_jwe_t *jwe, const cjose_jwk_t *jwk, int padding, cjose_err *err)
652
0
{
653
    // jwk must be RSA
654
0
    if (jwk->kty != CJOSE_JWK_KTY_RSA || NULL == jwk->keydata)
655
0
    {
656
0
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
657
0
        return false;
658
0
    }
659
660
    // jwk must have the necessary public parts set
661
0
    BIGNUM *rsa_n = NULL, *rsa_e = NULL, *rsa_d = NULL;
662
0
    _cjose_jwk_rsa_get((RSA *)jwk->keydata, &rsa_n, &rsa_e, &rsa_d);
663
0
    if (NULL == rsa_e || NULL == rsa_n)
664
0
    {
665
0
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
666
0
        return false;
667
0
    }
668
669
    // generate random cek
670
0
    if (!jwe->fns.set_cek(jwe, NULL, true, err))
671
0
    {
672
0
        return false;
673
0
    }
674
675
    // the size of the ek will match the size of the RSA key
676
0
    recipient->enc_key.raw_len = RSA_size((RSA *)jwk->keydata);
677
678
    // for OAEP padding - the RSA size - 41 must be greater than input
679
0
    if (jwe->cek_len >= recipient->enc_key.raw_len - 41)
680
0
    {
681
0
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
682
0
        return false;
683
0
    }
684
685
    // allocate memory for RSA encryption
686
0
    cjose_get_dealloc()(recipient->enc_key.raw);
687
0
    if (!_cjose_jwe_malloc(recipient->enc_key.raw_len, false, &recipient->enc_key.raw, err))
688
0
    {
689
0
        return false;
690
0
    }
691
692
0
#ifndef HAVE_RSA_PKCS1_PADDING
693
    // prohibite RSA_PKCS1_PADDING because it is not safe
694
0
    if (padding == RSA_PKCS1_PADDING)
695
0
    {
696
0
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
697
0
        return false;
698
0
    }
699
0
#endif // HAVE_RSA_PKCS1_PADDING
700
701
    // encrypt the CEK using RSA v1.5 or OAEP padding
702
0
    if (RSA_public_encrypt(jwe->cek_len, jwe->cek, recipient->enc_key.raw, (RSA *)jwk->keydata, padding)
703
0
        != recipient->enc_key.raw_len)
704
0
    {
705
0
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
706
0
        return false;
707
0
    }
708
709
0
    return true;
710
0
}
711
712
////////////////////////////////////////////////////////////////////////////////
713
static bool _cjose_jwe_decrypt_ek_rsa_padding(
714
    _jwe_int_recipient_t *recipient, cjose_jwe_t *jwe, const cjose_jwk_t *jwk, int padding, cjose_err *err)
715
131
{
716
131
    if (NULL == jwe || NULL == jwk)
717
0
    {
718
0
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
719
0
        return false;
720
0
    }
721
722
    // jwk must be RSA
723
131
    if (jwk->kty != CJOSE_JWK_KTY_RSA)
724
0
    {
725
0
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
726
0
        return false;
727
0
    }
728
729
    // jwk must have the necessary private parts set
730
131
    BIGNUM *rsa_n = NULL, *rsa_e = NULL, *rsa_d = NULL;
731
131
    _cjose_jwk_rsa_get((RSA *)jwk->keydata, &rsa_n, &rsa_e, &rsa_d);
732
131
    if (NULL == rsa_e || NULL == rsa_n || NULL == rsa_d)
733
65
    {
734
65
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
735
65
        return false;
736
65
    }
737
738
    // pin the expected CEK length from the enc header; like the other
739
    // decrypt_ek paths the RSA-decrypted key must match it exactly
740
66
    _cjose_release_cek(&jwe->cek, jwe->cek_len);
741
66
    if (!jwe->fns.set_cek(jwe, NULL, false, err))
742
0
    {
743
0
        return false;
744
0
    }
745
746
    // a valid RSA encrypted key segment is exactly the size of the modulus;
747
    // reject other lengths before they reach RSA_private_decrypt
748
66
    size_t buflen = RSA_size((RSA *)jwk->keydata);
749
66
    if (recipient->enc_key.raw_len != buflen)
750
29
    {
751
29
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
752
29
        return false;
753
29
    }
754
755
37
#ifndef HAVE_RSA_PKCS1_PADDING
756
    // prohibite RSA_PKCS1_PADDING because implementation are often vulnerable
757
    // See marvin attack
758
37
    if (padding == RSA_PKCS1_PADDING)
759
0
    {
760
0
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
761
0
        return false;
762
0
    }
763
37
#endif // HAVE_RSA_PKCS1_PADDING
764
765
    // decrypt into a scratch buffer; the recovered plaintext can be up to
766
    // RSA_size bytes, larger than the pinned CEK buffer
767
37
    uint8_t *buf = NULL;
768
37
    if (!_cjose_jwe_malloc(buflen, false, &buf, err))
769
0
    {
770
0
        return false;
771
0
    }
772
773
    // decrypt the CEK using RSA v1.5 or OAEP padding and require that its
774
    // length matches the CEK size dictated by the enc header (RFC 7518 sec 4.2/4.3)
775
37
    int len = RSA_private_decrypt(recipient->enc_key.raw_len, recipient->enc_key.raw, buf, (RSA *)jwk->keydata, padding);
776
37
    if (-1 == len || (size_t)len != jwe->cek_len)
777
1
    {
778
1
        _cjose_cleanse_dealloc(buf, buflen);
779
1
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
780
1
        return false;
781
1
    }
782
783
36
    memcpy(jwe->cek, buf, jwe->cek_len);
784
36
    _cjose_cleanse_dealloc(buf, buflen);
785
786
36
    return true;
787
37
}
788
789
////////////////////////////////////////////////////////////////////////////////
790
static bool
791
_cjose_jwe_encrypt_ek_rsa_oaep(_jwe_int_recipient_t *recipient, cjose_jwe_t *jwe, const cjose_jwk_t *jwk, cjose_err *err)
792
0
{
793
0
    return _cjose_jwe_encrypt_ek_rsa_padding(recipient, jwe, jwk, RSA_PKCS1_OAEP_PADDING, err);
794
0
}
795
796
////////////////////////////////////////////////////////////////////////////////
797
static bool
798
_cjose_jwe_decrypt_ek_rsa_oaep(_jwe_int_recipient_t *recipient, cjose_jwe_t *jwe, const cjose_jwk_t *jwk, cjose_err *err)
799
131
{
800
131
    return _cjose_jwe_decrypt_ek_rsa_padding(recipient, jwe, jwk, RSA_PKCS1_OAEP_PADDING, err);
801
131
}
802
803
#ifdef HAVE_RSA_PKCS1_PADDING
804
////////////////////////////////////////////////////////////////////////////////
805
static bool _cjose_jwe_encrypt_ek_rsa1_5(_jwe_int_recipient_t *recipient, cjose_jwe_t *jwe, const cjose_jwk_t *jwk, cjose_err *err)
806
{
807
    return _cjose_jwe_encrypt_ek_rsa_padding(recipient, jwe, jwk, RSA_PKCS1_PADDING, err);
808
}
809
810
////////////////////////////////////////////////////////////////////////////////
811
static bool _cjose_jwe_decrypt_ek_rsa1_5(_jwe_int_recipient_t *recipient, cjose_jwe_t *jwe, const cjose_jwk_t *jwk, cjose_err *err)
812
{
813
    return _cjose_jwe_decrypt_ek_rsa_padding(recipient, jwe, jwk, RSA_PKCS1_PADDING, err);
814
}
815
#endif // HAVE_RSA_PKCS1_PADDING
816
817
////////////////////////////////////////////////////////////////////////////////
818
static bool _cjose_jwe_encrypt_ek_ecdh_es(_jwe_int_recipient_t *recipient, cjose_jwe_t *jwe, const cjose_jwk_t *jwk, cjose_err *err)
819
0
{
820
0
    cjose_jwk_t *epk_jwk = NULL;
821
0
    char *epk_json = NULL;
822
0
    uint8_t *secret = NULL;
823
0
    size_t secret_len = 0;
824
0
    uint8_t *otherinfo = NULL;
825
0
    size_t otherinfo_len = 0;
826
0
    uint8_t *derived = NULL;
827
0
    bool result = false;
828
829
    // generate and export random EPK
830
0
    epk_jwk = cjose_jwk_create_EC_random(cjose_jwk_EC_get_curve(jwk, err), err);
831
0
    if (NULL == epk_jwk)
832
0
    {
833
        // error details already set
834
0
        goto cjose_encrypt_ek_ecdh_es_finish;
835
0
    }
836
0
    epk_json = cjose_jwk_to_json(epk_jwk, false, err);
837
0
    if (NULL == epk_json)
838
0
    {
839
0
        goto cjose_encrypt_ek_ecdh_es_finish;
840
0
    }
841
0
    if (!cjose_header_set_raw(jwe->hdr, CJOSE_HDR_EPK, epk_json, err))
842
0
    {
843
0
        goto cjose_encrypt_ek_ecdh_es_finish;
844
0
    }
845
846
    // perform ECDH (private=epk_jwk, public=jwk)
847
0
    if (!cjose_jwk_derive_ecdh_bits(epk_jwk, jwk, &secret, &secret_len, err))
848
0
    {
849
0
        goto cjose_encrypt_ek_ecdh_es_finish;
850
0
    }
851
852
    // perform label, ConcatKDF
853
    // - assemble otherInfo from:
854
    //   * alg (== {enc})
855
    //   * apu (default = "")
856
    //   * apv (default = "")
857
    //   * keylen (determined from {enc})
858
0
    cjose_header_t *hdr = jwe->hdr;
859
0
    const char *algId = cjose_header_get(hdr, CJOSE_HDR_ENC, err);
860
0
    const size_t keylen = _keylen_from_enc(algId) / 8;
861
862
0
    if (!cjose_concatkdf_create_otherinfo(algId, keylen * 8, hdr, &otherinfo, &otherinfo_len, err))
863
0
    {
864
0
        goto cjose_encrypt_ek_ecdh_es_finish;
865
0
    }
866
867
0
    derived = cjose_concatkdf_derive(keylen, secret, secret_len, otherinfo, otherinfo_len, err);
868
0
    if (NULL == derived)
869
0
    {
870
0
        goto cjose_encrypt_ek_ecdh_es_finish;
871
0
    }
872
873
0
    jwe->cek = derived;
874
0
    jwe->cek_len = keylen;
875
876
    // empty string may have been allocated upon import
877
0
    if (recipient->enc_key.raw != NULL)
878
0
    {
879
0
        cjose_get_dealloc()(recipient->enc_key.raw);
880
0
    }
881
882
0
    recipient->enc_key.raw = NULL;
883
0
    recipient->enc_key.raw_len = 0;
884
0
    result = true;
885
886
0
cjose_encrypt_ek_ecdh_es_finish:
887
888
0
    cjose_jwk_release(epk_jwk);
889
0
    cjose_get_dealloc()(epk_json);
890
0
    _cjose_cleanse_dealloc(secret, secret_len);
891
0
    cjose_get_dealloc()(otherinfo);
892
893
0
    return result;
894
0
}
895
896
////////////////////////////////////////////////////////////////////////////////
897
static bool _cjose_jwe_decrypt_ek_ecdh_es(_jwe_int_recipient_t *recipient, cjose_jwe_t *jwe, const cjose_jwk_t *jwk, cjose_err *err)
898
0
{
899
0
    cjose_jwk_t *epk_jwk = NULL;
900
0
    uint8_t *secret = NULL;
901
0
    size_t secret_len = 0;
902
0
    uint8_t *otherinfo = NULL;
903
0
    size_t otherinfo_len = 0;
904
0
    uint8_t *derived = NULL;
905
0
    bool result = false;
906
907
    // err is optional in the public API, but the logic below inspects
908
    // err->code to distinguish an absent EPK header from a real failure;
909
    // fall back to a local error object when the caller did not supply one
910
0
    cjose_err local_err;
911
0
    if (NULL == err)
912
0
    {
913
0
        err = &local_err;
914
0
    }
915
0
    memset(err, 0, sizeof(cjose_err));
916
0
    char *epk_json = cjose_header_get_raw(jwe->hdr, CJOSE_HDR_EPK, err);
917
0
    if (NULL != epk_json)
918
0
    {
919
0
        epk_jwk = cjose_jwk_import(epk_json, strlen(epk_json), err);
920
0
    }
921
0
    else if (CJOSE_ERR_NONE == err->code)
922
0
    {
923
0
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
924
0
        goto cjose_decrypt_ek_ecdh_es_finish;
925
0
    }
926
927
0
    if (NULL == epk_jwk)
928
0
    {
929
        // error details already set
930
0
        goto cjose_decrypt_ek_ecdh_es_finish;
931
0
    }
932
933
0
    if (cjose_jwk_EC_get_curve(jwk, err) != cjose_jwk_EC_get_curve(epk_jwk, err))
934
0
    {
935
0
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
936
0
        goto cjose_decrypt_ek_ecdh_es_finish;
937
0
    }
938
939
    // perform ECDH (private=jwk, public=epk_jwk)
940
0
    if (!cjose_jwk_derive_ecdh_bits(jwk, epk_jwk, &secret, &secret_len, err))
941
0
    {
942
0
        goto cjose_decrypt_ek_ecdh_es_finish;
943
0
    }
944
945
    // perform label, ConcatKDF
946
    // - assemble otherInfo from:
947
    //   * alg (== {enc})
948
    //   * apu (default = "")
949
    //   * apv (default = "")
950
    //   * keylen (determined from {enc})
951
0
    cjose_header_t *hdr = jwe->hdr;
952
0
    const char *algId = cjose_header_get(hdr, CJOSE_HDR_ENC, err);
953
0
    const size_t keylen = _keylen_from_enc(algId) / 8;
954
955
0
    if (!cjose_concatkdf_create_otherinfo(algId, keylen * 8, hdr, &otherinfo, &otherinfo_len, err))
956
0
    {
957
0
        goto cjose_decrypt_ek_ecdh_es_finish;
958
0
    }
959
960
0
    derived = cjose_concatkdf_derive(keylen, secret, secret_len, otherinfo, otherinfo_len, err);
961
0
    if (NULL == derived)
962
0
    {
963
0
        goto cjose_decrypt_ek_ecdh_es_finish;
964
0
    }
965
966
0
    jwe->cek = derived;
967
0
    jwe->cek_len = keylen;
968
969
    // empty string may have been allocated upon import
970
0
    if (recipient->enc_key.raw != NULL)
971
0
    {
972
0
        cjose_get_dealloc()(recipient->enc_key.raw);
973
0
    }
974
975
0
    recipient->enc_key.raw = NULL;
976
0
    recipient->enc_key.raw_len = 0;
977
0
    result = true;
978
979
0
cjose_decrypt_ek_ecdh_es_finish:
980
981
0
    cjose_jwk_release(epk_jwk);
982
0
    cjose_get_dealloc()(epk_json);
983
0
    _cjose_cleanse_dealloc(secret, secret_len);
984
0
    cjose_get_dealloc()(otherinfo);
985
986
0
    return result;
987
0
}
988
989
////////////////////////////////////////////////////////////////////////////////
990
static bool _cjose_jwe_set_iv_aes_gcm(cjose_jwe_t *jwe, cjose_err *err)
991
16.2k
{
992
    // generate IV as random 96 bit value
993
16.2k
    cjose_get_dealloc()(jwe->enc_iv.raw);
994
16.2k
    jwe->enc_iv.raw_len = 12;
995
16.2k
    if (!_cjose_jwe_malloc(jwe->enc_iv.raw_len, true, &jwe->enc_iv.raw, err))
996
0
    {
997
0
        return false;
998
0
    }
999
1000
16.2k
    return true;
1001
16.2k
}
1002
1003
////////////////////////////////////////////////////////////////////////////////
1004
static bool _cjose_jwe_set_iv_aes_cbc(cjose_jwe_t *jwe, cjose_err *err)
1005
0
{
1006
    // make sure we have an enc header
1007
0
    json_t *enc_obj = json_object_get(jwe->hdr, CJOSE_HDR_ENC);
1008
0
    if (NULL == enc_obj)
1009
0
    {
1010
0
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
1011
0
        return false;
1012
0
    }
1013
0
    cjose_get_dealloc()(jwe->enc_iv.raw);
1014
1015
    // RFC 7516 (https://tools.ietf.org/html/rfc7516) is unclear about
1016
    // the size of the IV for AES-CBC. In section 5.1
1017
    // (https://tools.ietf.org/html/rfc7516#section-5.1), they state in no. 9.:
1018
    // "Generate a random JWE Initialization Vector of the correct size
1019
    // for the content encryption algorithm"
1020
    // And in the example in A.2.4 (https://tools.ietf.org/html/rfc7516#appendix-A.2.4)
1021
    // they provide an example for AES128-CBC, which results (naturally) in the IV size of 128Bit.
1022
    //
1023
    // The CISCO implementation chose for the size of the IV the key size of the
1024
    // cipher algorithm, which seems to be wrong.
1025
    //
1026
    // According to RFC 3602 section 3 (https://tools.ietf.org/html/rfc3602#section-3):
1027
    // "The IV field MUST be the same size as the block size of the cipher algorithm being used."
1028
    // And because the block size for AES cipher is always 16 Byte, the IV must be 16 Byte long.
1029
    //
1030
    // IV size for AES CBC is always 16 Byte
1031
0
    jwe->enc_iv.raw_len = 16;
1032
1033
    // generate IV as random iv_size * 8 bit value
1034
0
    if (!_cjose_jwe_malloc(jwe->enc_iv.raw_len, true, &jwe->enc_iv.raw, err))
1035
0
    {
1036
0
        return false;
1037
0
    }
1038
1039
0
    return true;
1040
0
}
1041
1042
#if defined(CJOSE_OPENSSL_11X)
1043
16.2k
#define CJOSE_EVP_CTRL_GCM_GET_TAG EVP_CTRL_AEAD_GET_TAG
1044
11.3k
#define CJOSE_EVP_CTRL_GCM_SET_TAG EVP_CTRL_AEAD_SET_TAG
1045
#else
1046
#define CJOSE_EVP_CTRL_GCM_GET_TAG EVP_CTRL_GCM_GET_TAG
1047
#define CJOSE_EVP_CTRL_GCM_SET_TAG EVP_CTRL_GCM_SET_TAG
1048
#endif
1049
1050
////////////////////////////////////////////////////////////////////////////////
1051
static bool _cjose_jwe_encrypt_dat_aes_gcm(cjose_jwe_t *jwe, const uint8_t *plaintext, size_t plaintext_len, cjose_err *err)
1052
16.2k
{
1053
16.2k
    EVP_CIPHER_CTX *ctx = NULL;
1054
1055
    // make sure we have an enc header
1056
16.2k
    json_t *enc_obj = json_object_get(jwe->hdr, CJOSE_HDR_ENC);
1057
16.2k
    if (NULL == enc_obj)
1058
0
    {
1059
0
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
1060
0
        return false;
1061
0
    }
1062
16.2k
    const char *enc = json_string_value(enc_obj);
1063
1064
16.2k
    if (NULL == plaintext)
1065
0
    {
1066
0
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
1067
0
        goto _cjose_jwe_encrypt_dat_fail;
1068
0
    }
1069
1070
    // get AES GCM cipher
1071
16.2k
    const EVP_CIPHER *cipher = NULL;
1072
1073
16.2k
    if (strcmp(enc, CJOSE_HDR_ENC_A128GCM) == 0)
1074
0
        cipher = EVP_aes_128_gcm();
1075
16.2k
    if (strcmp(enc, CJOSE_HDR_ENC_A192GCM) == 0)
1076
0
        cipher = EVP_aes_192_gcm();
1077
16.2k
    if (strcmp(enc, CJOSE_HDR_ENC_A256GCM) == 0)
1078
16.2k
        cipher = EVP_aes_256_gcm();
1079
1080
16.2k
    if (NULL == cipher)
1081
0
    {
1082
0
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
1083
0
        goto _cjose_jwe_encrypt_dat_fail;
1084
0
    }
1085
1086
    // instantiate and initialize a new openssl cipher context
1087
16.2k
    ctx = EVP_CIPHER_CTX_new();
1088
16.2k
    if (NULL == ctx)
1089
0
    {
1090
0
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
1091
0
        goto _cjose_jwe_encrypt_dat_fail;
1092
0
    }
1093
16.2k
    EVP_CIPHER_CTX_init(ctx);
1094
1095
    // AES GCM requires a 96-bit IV; enforce this before EVP_EncryptInit_ex,
1096
    // which reads a fixed 12 bytes from a possibly shorter caller-supplied IV
1097
    // (mirrors the corresponding check on the decrypt path)
1098
16.2k
    if (jwe->enc_iv.raw_len != 12)
1099
0
    {
1100
0
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
1101
0
        goto _cjose_jwe_encrypt_dat_fail;
1102
0
    }
1103
1104
    // initialize context for encryption using AES GCM cipher and CEK and IV
1105
16.2k
    if (EVP_EncryptInit_ex(ctx, cipher, NULL, jwe->cek, jwe->enc_iv.raw) != 1)
1106
0
    {
1107
0
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
1108
0
        goto _cjose_jwe_encrypt_dat_fail;
1109
0
    }
1110
1111
    // we need the header in base64url encoding as input for encryption
1112
16.2k
    if ((NULL == jwe->enc_header.b64u)
1113
16.2k
        && (!cjose_base64url_encode((const uint8_t *)jwe->enc_header.raw, jwe->enc_header.raw_len, &jwe->enc_header.b64u,
1114
16.2k
                                    &jwe->enc_header.b64u_len, err)))
1115
0
    {
1116
0
        goto _cjose_jwe_encrypt_dat_fail;
1117
0
    }
1118
1119
    // set GCM mode AAD data (hdr_b64u) by setting "out" to NULL
1120
16.2k
    int bytes_encrypted = 0;
1121
16.2k
    if (EVP_EncryptUpdate(ctx, NULL, &bytes_encrypted, (unsigned char *)jwe->enc_header.b64u, jwe->enc_header.b64u_len) != 1
1122
16.2k
        || bytes_encrypted != jwe->enc_header.b64u_len)
1123
0
    {
1124
0
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
1125
0
        goto _cjose_jwe_encrypt_dat_fail;
1126
0
    }
1127
1128
    // allocate buffer for the ciphertext
1129
16.2k
    cjose_get_dealloc()(jwe->enc_ct.raw);
1130
16.2k
    jwe->enc_ct.raw_len = plaintext_len;
1131
16.2k
    if (!_cjose_jwe_malloc(jwe->enc_ct.raw_len, false, &jwe->enc_ct.raw, err))
1132
0
    {
1133
0
        goto _cjose_jwe_encrypt_dat_fail;
1134
0
    }
1135
1136
    // encrypt entire plaintext to ciphertext buffer
1137
16.2k
    if (EVP_EncryptUpdate(ctx, jwe->enc_ct.raw, &bytes_encrypted, plaintext, plaintext_len) != 1)
1138
0
    {
1139
0
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
1140
0
        goto _cjose_jwe_encrypt_dat_fail;
1141
0
    }
1142
16.2k
    jwe->enc_ct.raw_len = bytes_encrypted;
1143
1144
    // finalize the encryption and set the ciphertext length to correct value
1145
16.2k
    if (EVP_EncryptFinal_ex(ctx, NULL, &bytes_encrypted) != 1)
1146
0
    {
1147
0
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
1148
0
        goto _cjose_jwe_encrypt_dat_fail;
1149
0
    }
1150
1151
    // allocate buffer for the authentication tag
1152
16.2k
    cjose_get_dealloc()(jwe->enc_auth_tag.raw);
1153
16.2k
    jwe->enc_auth_tag.raw_len = 16;
1154
16.2k
    if (!_cjose_jwe_malloc(jwe->enc_auth_tag.raw_len, false, &jwe->enc_auth_tag.raw, err))
1155
0
    {
1156
0
        goto _cjose_jwe_encrypt_dat_fail;
1157
0
    }
1158
1159
    // get the GCM-mode authentication tag
1160
16.2k
    if (EVP_CIPHER_CTX_ctrl(ctx, CJOSE_EVP_CTRL_GCM_GET_TAG, jwe->enc_auth_tag.raw_len, jwe->enc_auth_tag.raw) != 1)
1161
0
    {
1162
0
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
1163
0
        goto _cjose_jwe_encrypt_dat_fail;
1164
0
    }
1165
1166
16.2k
    EVP_CIPHER_CTX_free(ctx);
1167
16.2k
    return true;
1168
1169
0
_cjose_jwe_encrypt_dat_fail:
1170
0
    if (NULL != ctx)
1171
0
    {
1172
0
        EVP_CIPHER_CTX_free(ctx);
1173
0
    }
1174
0
    return false;
1175
16.2k
}
1176
1177
////////////////////////////////////////////////////////////////////////////////
1178
static bool _cjose_jwe_calc_auth_tag(const char *enc, cjose_jwe_t *jwe, uint8_t *md, unsigned int *md_len, cjose_err *err)
1179
54
{
1180
54
    bool retval = false;
1181
54
    const EVP_MD *hash = NULL;
1182
1183
54
    if (strcmp(enc, CJOSE_HDR_ENC_A128CBC_HS256) == 0)
1184
54
    {
1185
54
        hash = EVP_sha256();
1186
54
    }
1187
0
    else if (strcmp(enc, CJOSE_HDR_ENC_A192CBC_HS384) == 0)
1188
0
    {
1189
0
        hash = EVP_sha384();
1190
0
    }
1191
0
    else if (strcmp(enc, CJOSE_HDR_ENC_A256CBC_HS512) == 0)
1192
0
    {
1193
0
        hash = EVP_sha512();
1194
0
    }
1195
1196
54
    if (NULL == hash)
1197
0
    {
1198
0
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
1199
0
        return false;
1200
0
    }
1201
1202
54
    uint8_t *msg = NULL;
1203
1204
    // calculate the Authentication Tag value over AAD + IV + ciphertext + AAD length
1205
1206
    // 0 = header
1207
    // 1 = cek
1208
    // 2 = iv
1209
    // 3 = ciphertext
1210
    // 4 = authentication tag
1211
1212
    // Additional Authentication Data length (base64encoded header) in # of bits in 64 bit length field
1213
54
    uint64_t al = jwe->enc_header.b64u_len * 8;
1214
1215
    // concatenate AAD + IV + ciphertext + AAD length field
1216
54
    size_t msg_len = jwe->enc_header.b64u_len;
1217
54
    if (msg_len > SIZE_MAX - jwe->enc_iv.raw_len || msg_len + jwe->enc_iv.raw_len > SIZE_MAX - jwe->enc_ct.raw_len
1218
54
        || msg_len + jwe->enc_iv.raw_len + jwe->enc_ct.raw_len > SIZE_MAX - sizeof(uint64_t))
1219
0
    {
1220
0
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
1221
0
        goto _cjose_jwe_calc_auth_tag_end;
1222
0
    }
1223
54
    msg_len += jwe->enc_iv.raw_len;
1224
54
    msg_len += jwe->enc_ct.raw_len;
1225
54
    msg_len += sizeof(uint64_t);
1226
54
    if (!_cjose_jwe_malloc(msg_len, false, &msg, err))
1227
0
    {
1228
0
        goto _cjose_jwe_calc_auth_tag_end;
1229
0
    }
1230
1231
    // construct AAD + IV + ciphertext + AAD input
1232
54
    uint8_t *p = msg;
1233
54
    memcpy(p, jwe->enc_header.b64u, jwe->enc_header.b64u_len);
1234
54
    p += jwe->enc_header.b64u_len;
1235
54
    memcpy(p, jwe->enc_iv.raw, jwe->enc_iv.raw_len);
1236
54
    p += jwe->enc_iv.raw_len;
1237
54
    memcpy(p, jwe->enc_ct.raw, jwe->enc_ct.raw_len);
1238
54
    p += jwe->enc_ct.raw_len;
1239
1240
    // check if we are on a big endian or little endian machine
1241
54
    int c = 1;
1242
54
    if (*(char *)&c == 1)
1243
54
    {
1244
        // little endian machine: reverse AAD length for big endian representation
1245
54
        al = (al & 0x00000000FFFFFFFF) << 32 | (al & 0xFFFFFFFF00000000) >> 32;
1246
54
        al = (al & 0x0000FFFF0000FFFF) << 16 | (al & 0xFFFF0000FFFF0000) >> 16;
1247
54
        al = (al & 0x00FF00FF00FF00FF) << 8 | (al & 0xFF00FF00FF00FF00) >> 8;
1248
54
    }
1249
54
    memcpy(p, &al, sizeof(uint64_t));
1250
1251
    // HMAC the input
1252
54
    if (!HMAC(hash, jwe->cek, jwe->cek_len / 2, msg, msg_len, md, md_len))
1253
0
    {
1254
0
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
1255
0
        goto _cjose_jwe_calc_auth_tag_end;
1256
0
    }
1257
1258
    // use only the first half of the bits
1259
54
    *md_len = *md_len / 2;
1260
54
    retval = true;
1261
1262
54
_cjose_jwe_calc_auth_tag_end:
1263
54
    if (msg)
1264
54
    {
1265
54
        cjose_get_dealloc()(msg);
1266
54
    }
1267
54
    return retval;
1268
54
}
1269
1270
////////////////////////////////////////////////////////////////////////////////
1271
static bool _cjose_jwe_encrypt_dat_aes_cbc(cjose_jwe_t *jwe, const uint8_t *plaintext, size_t plaintext_len, cjose_err *err)
1272
0
{
1273
    // make sure we have an enc header
1274
0
    json_t *enc_obj = json_object_get(jwe->hdr, CJOSE_HDR_ENC);
1275
0
    if (NULL == enc_obj)
1276
0
    {
1277
0
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
1278
0
        return false;
1279
0
    }
1280
0
    const char *enc = json_string_value(enc_obj);
1281
1282
    // get the AES cipher
1283
0
    EVP_CIPHER_CTX *ctx = NULL;
1284
0
    const EVP_CIPHER *cipher = NULL;
1285
1286
0
    if (strcmp(enc, CJOSE_HDR_ENC_A128CBC_HS256) == 0)
1287
0
        cipher = EVP_aes_128_cbc();
1288
0
    if (strcmp(enc, CJOSE_HDR_ENC_A192CBC_HS384) == 0)
1289
0
        cipher = EVP_aes_192_cbc();
1290
0
    if (strcmp(enc, CJOSE_HDR_ENC_A256CBC_HS512) == 0)
1291
0
        cipher = EVP_aes_256_cbc();
1292
1293
0
    if (NULL == cipher)
1294
0
    {
1295
0
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
1296
0
        goto _cjose_jwe_encrypt_dat_aes_cbc_fail;
1297
0
    }
1298
1299
    // instantiate and initialize a new openssl cipher context
1300
0
    ctx = EVP_CIPHER_CTX_new();
1301
0
    if (NULL == ctx)
1302
0
    {
1303
0
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
1304
0
        goto _cjose_jwe_encrypt_dat_aes_cbc_fail;
1305
0
    }
1306
0
    EVP_CIPHER_CTX_init(ctx);
1307
1308
    // AES CBC requires a block-sized IV; enforce this before EVP_EncryptInit_ex,
1309
    // which reads a fixed 16 bytes from a possibly shorter caller-supplied IV
1310
    // (mirrors the corresponding check on the decrypt path)
1311
0
    if (jwe->enc_iv.raw_len != AES_BLOCK_SIZE)
1312
0
    {
1313
0
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
1314
0
        goto _cjose_jwe_encrypt_dat_aes_cbc_fail;
1315
0
    }
1316
1317
    // initialize context for decryption using the cipher, the 2nd half of the CEK and the IV
1318
0
    if (EVP_EncryptInit_ex(ctx, cipher, NULL, jwe->cek + jwe->cek_len / 2, jwe->enc_iv.raw) != 1)
1319
0
    {
1320
0
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
1321
0
        goto _cjose_jwe_encrypt_dat_aes_cbc_fail;
1322
0
    }
1323
1324
    // we need the header in base64url encoding as input for encryption
1325
0
    if ((NULL == jwe->enc_header.b64u)
1326
0
        && (!cjose_base64url_encode((const uint8_t *)jwe->enc_header.raw, jwe->enc_header.raw_len, &jwe->enc_header.b64u,
1327
0
                                    &jwe->enc_header.b64u_len, err)))
1328
0
    {
1329
0
        goto _cjose_jwe_encrypt_dat_aes_cbc_fail;
1330
0
    }
1331
    // allocate buffer for the ciphertext (plaintext + block size)
1332
0
    cjose_get_dealloc()(jwe->enc_ct.raw);
1333
0
    jwe->enc_ct.raw_len = plaintext_len + EVP_CIPHER_block_size(cipher);
1334
0
    if (!_cjose_jwe_malloc(jwe->enc_ct.raw_len, false, &jwe->enc_ct.raw, err))
1335
0
    {
1336
0
        goto _cjose_jwe_encrypt_dat_aes_cbc_fail;
1337
0
    }
1338
1339
    // encrypt entire plaintext to ciphertext buffer
1340
0
    int bytes_encrypted = 0;
1341
0
    if (EVP_EncryptUpdate(ctx, jwe->enc_ct.raw, &bytes_encrypted, plaintext, plaintext_len) != 1)
1342
0
    {
1343
0
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
1344
0
        goto _cjose_jwe_encrypt_dat_aes_cbc_fail;
1345
0
    }
1346
0
    jwe->enc_ct.raw_len = bytes_encrypted;
1347
1348
    // finalize the encryption and set the ciphertext length to correct value
1349
0
    if (EVP_EncryptFinal_ex(ctx, jwe->enc_ct.raw + bytes_encrypted, &bytes_encrypted) != 1)
1350
0
    {
1351
0
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
1352
0
        goto _cjose_jwe_encrypt_dat_aes_cbc_fail;
1353
0
    }
1354
0
    jwe->enc_ct.raw_len += bytes_encrypted;
1355
1356
    // calculate Authentication Tag
1357
0
    unsigned int tag_len = 0;
1358
0
    uint8_t tag[EVP_MAX_MD_SIZE];
1359
0
    if (_cjose_jwe_calc_auth_tag(enc, jwe, (unsigned char *)&tag, &tag_len, err) == false)
1360
0
    {
1361
0
        goto _cjose_jwe_encrypt_dat_aes_cbc_fail;
1362
0
    }
1363
1364
    // allocate buffer for the authentication tag
1365
0
    cjose_get_dealloc()(jwe->enc_auth_tag.raw);
1366
0
    jwe->enc_auth_tag.raw_len = tag_len;
1367
0
    if (!_cjose_jwe_malloc(jwe->enc_auth_tag.raw_len, false, &jwe->enc_auth_tag.raw, err))
1368
0
    {
1369
0
        goto _cjose_jwe_encrypt_dat_aes_cbc_fail;
1370
0
    }
1371
1372
0
    memcpy(jwe->enc_auth_tag.raw, tag, tag_len);
1373
1374
0
    EVP_CIPHER_CTX_free(ctx);
1375
1376
0
    return true;
1377
1378
0
_cjose_jwe_encrypt_dat_aes_cbc_fail:
1379
0
    if (NULL != ctx)
1380
0
    {
1381
0
        EVP_CIPHER_CTX_free(ctx);
1382
0
    }
1383
0
    return false;
1384
0
}
1385
1386
////////////////////////////////////////////////////////////////////////////////
1387
static bool _cjose_jwe_decrypt_dat_aes_gcm(cjose_jwe_t *jwe, cjose_err *err)
1388
19.9k
{
1389
19.9k
    EVP_CIPHER_CTX *ctx = NULL;
1390
1391
    // make sure we have an enc header
1392
19.9k
    json_t *enc_obj = json_object_get(jwe->hdr, CJOSE_HDR_ENC);
1393
19.9k
    if (NULL == enc_obj)
1394
0
    {
1395
0
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
1396
0
        return false;
1397
0
    }
1398
19.9k
    const char *enc = json_string_value(enc_obj);
1399
1400
    // get AES GCM cipher
1401
19.9k
    const EVP_CIPHER *cipher = NULL;
1402
1403
19.9k
    if (strcmp(enc, CJOSE_HDR_ENC_A128GCM) == 0)
1404
0
        cipher = EVP_aes_128_gcm();
1405
19.9k
    if (strcmp(enc, CJOSE_HDR_ENC_A192GCM) == 0)
1406
0
        cipher = EVP_aes_192_gcm();
1407
19.9k
    if (strcmp(enc, CJOSE_HDR_ENC_A256GCM) == 0)
1408
19.9k
        cipher = EVP_aes_256_gcm();
1409
1410
19.9k
    if (NULL == cipher)
1411
0
    {
1412
0
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
1413
0
        goto _cjose_jwe_decrypt_dat_aes_gcm_fail;
1414
0
    }
1415
1416
    // instantiate and initialize a new openssl cipher context
1417
19.9k
    ctx = EVP_CIPHER_CTX_new();
1418
19.9k
    if (NULL == ctx)
1419
0
    {
1420
0
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
1421
0
        goto _cjose_jwe_decrypt_dat_aes_gcm_fail;
1422
0
    }
1423
19.9k
    EVP_CIPHER_CTX_init(ctx);
1424
1425
19.9k
    if (jwe->enc_iv.raw_len != 12)
1426
7.15k
    {
1427
7.15k
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
1428
7.15k
        goto _cjose_jwe_decrypt_dat_aes_gcm_fail;
1429
7.15k
    }
1430
1431
    // initialize context for decryption using AES GCM cipher and CEK and IV
1432
12.7k
    if (EVP_DecryptInit_ex(ctx, cipher, NULL, jwe->cek, jwe->enc_iv.raw) != 1)
1433
0
    {
1434
0
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
1435
0
        goto _cjose_jwe_decrypt_dat_aes_gcm_fail;
1436
0
    }
1437
1438
12.7k
    if (jwe->enc_auth_tag.raw_len != 16)
1439
1.40k
    {
1440
1.40k
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
1441
1.40k
        goto _cjose_jwe_decrypt_dat_aes_gcm_fail;
1442
1.40k
    }
1443
1444
    // set the expected GCM-mode authentication tag
1445
11.3k
    if (EVP_CIPHER_CTX_ctrl(ctx, CJOSE_EVP_CTRL_GCM_SET_TAG, jwe->enc_auth_tag.raw_len, jwe->enc_auth_tag.raw) != 1)
1446
0
    {
1447
0
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
1448
0
        goto _cjose_jwe_decrypt_dat_aes_gcm_fail;
1449
0
    }
1450
1451
    // set GCM mode AAD data (hdr_b64u) by setting "out" to NULL
1452
11.3k
    int bytes_decrypted = 0;
1453
11.3k
    if (EVP_DecryptUpdate(ctx, NULL, &bytes_decrypted, (unsigned char *)jwe->enc_header.b64u, jwe->enc_header.b64u_len) != 1
1454
11.3k
        || bytes_decrypted != jwe->enc_header.b64u_len)
1455
0
    {
1456
0
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
1457
0
        goto _cjose_jwe_decrypt_dat_aes_gcm_fail;
1458
0
    }
1459
1460
    // allocate buffer for the plaintext, wiping any previously decrypted data
1461
11.3k
    _cjose_cleanse_dealloc(jwe->dat, jwe->dat_len);
1462
11.3k
    jwe->dat_len = jwe->enc_ct.raw_len;
1463
11.3k
    if (!_cjose_jwe_malloc(jwe->dat_len, false, &jwe->dat, err))
1464
0
    {
1465
0
        goto _cjose_jwe_decrypt_dat_aes_gcm_fail;
1466
0
    }
1467
1468
    // decrypt ciphertext to plaintext buffer
1469
11.3k
    if (EVP_DecryptUpdate(ctx, jwe->dat, &bytes_decrypted, jwe->enc_ct.raw, jwe->enc_ct.raw_len) != 1)
1470
0
    {
1471
0
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
1472
0
        goto _cjose_jwe_decrypt_dat_aes_gcm_fail;
1473
0
    }
1474
11.3k
    jwe->dat_len = bytes_decrypted;
1475
1476
    // finalize the decryption
1477
11.3k
    if (EVP_DecryptFinal_ex(ctx, NULL, &bytes_decrypted) != 1)
1478
2.08k
    {
1479
2.08k
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
1480
2.08k
        goto _cjose_jwe_decrypt_dat_aes_gcm_fail;
1481
2.08k
    }
1482
1483
9.27k
    EVP_CIPHER_CTX_free(ctx);
1484
9.27k
    return true;
1485
1486
10.6k
_cjose_jwe_decrypt_dat_aes_gcm_fail:
1487
10.6k
    if (NULL != ctx)
1488
10.6k
    {
1489
10.6k
        EVP_CIPHER_CTX_free(ctx);
1490
10.6k
    }
1491
10.6k
    return false;
1492
11.3k
}
1493
1494
////////////////////////////////////////////////////////////////////////////////
1495
static bool _cjose_jwe_decrypt_dat_aes_cbc(cjose_jwe_t *jwe, cjose_err *err)
1496
72
{
1497
    // make sure we have an enc header
1498
72
    json_t *enc_obj = json_object_get(jwe->hdr, CJOSE_HDR_ENC);
1499
72
    if (NULL == enc_obj)
1500
0
    {
1501
0
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
1502
0
        return false;
1503
0
    }
1504
72
    const char *enc = json_string_value(enc_obj);
1505
1506
72
    if (jwe->enc_iv.raw_len != AES_BLOCK_SIZE)
1507
18
    {
1508
18
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
1509
18
        return false;
1510
18
    }
1511
1512
    // calculate Authentication Tag
1513
54
    unsigned int tag_len = 0;
1514
54
    uint8_t tag[EVP_MAX_MD_SIZE];
1515
54
    if (_cjose_jwe_calc_auth_tag(enc, jwe, (unsigned char *)&tag, &tag_len, err) == false)
1516
0
    {
1517
0
        return false;
1518
0
    }
1519
1520
    // compare the provided Authentication Tag against our calculation
1521
54
    if ((tag_len != jwe->enc_auth_tag.raw_len) || (cjose_const_memcmp(tag, jwe->enc_auth_tag.raw, tag_len) != 0))
1522
53
    {
1523
53
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
1524
53
        return false;
1525
53
    }
1526
1527
    // get the AES cipher
1528
1
    EVP_CIPHER_CTX *ctx = NULL;
1529
1
    const EVP_CIPHER *cipher = NULL;
1530
1531
1
    if (strcmp(enc, CJOSE_HDR_ENC_A128CBC_HS256) == 0)
1532
1
    {
1533
1
        cipher = EVP_aes_128_cbc();
1534
1
    }
1535
0
    else if (strcmp(enc, CJOSE_HDR_ENC_A192CBC_HS384) == 0)
1536
0
    {
1537
0
        cipher = EVP_aes_192_cbc();
1538
0
    }
1539
0
    else if (strcmp(enc, CJOSE_HDR_ENC_A256CBC_HS512) == 0)
1540
0
    {
1541
0
        cipher = EVP_aes_256_cbc();
1542
0
    }
1543
1544
1
    if (NULL == cipher)
1545
0
    {
1546
0
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
1547
0
        goto _cjose_jwe_decrypt_dat_aes_cbc_fail;
1548
0
    }
1549
1550
    // instantiate and initialize a new openssl cipher context
1551
1
    ctx = EVP_CIPHER_CTX_new();
1552
1
    if (NULL == ctx)
1553
0
    {
1554
0
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
1555
0
        goto _cjose_jwe_decrypt_dat_aes_cbc_fail;
1556
0
    }
1557
1
    EVP_CIPHER_CTX_init(ctx);
1558
1559
    // initialize context for decryption using the cipher, the 2nd half of the CEK and the IV
1560
1
    if (EVP_DecryptInit_ex(ctx, cipher, NULL, jwe->cek + jwe->cek_len / 2, jwe->enc_iv.raw) != 1)
1561
0
    {
1562
0
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
1563
0
        goto _cjose_jwe_decrypt_dat_aes_cbc_fail;
1564
0
    }
1565
1566
    // allocate buffer for the plaintext + one block padding
1567
1
    if (jwe->enc_ct.raw_len > INT_MAX || jwe->enc_ct.raw_len > SIZE_MAX - AES_BLOCK_SIZE)
1568
0
    {
1569
0
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
1570
0
        goto _cjose_jwe_decrypt_dat_aes_cbc_fail;
1571
0
    }
1572
1573
1
    int p_len = (int)jwe->enc_ct.raw_len, f_len = 0;
1574
1
    _cjose_cleanse_dealloc(jwe->dat, jwe->dat_len);
1575
    // size the buffer in size_t; p_len + AES_BLOCK_SIZE would overflow int when
1576
    // raw_len is near INT_MAX (raw_len is already bounded above)
1577
1
    jwe->dat_len = jwe->enc_ct.raw_len + AES_BLOCK_SIZE;
1578
1
    if (!_cjose_jwe_malloc(jwe->dat_len, false, &jwe->dat, err))
1579
0
    {
1580
0
        goto _cjose_jwe_decrypt_dat_aes_cbc_fail;
1581
0
    }
1582
1583
    // decrypt ciphertext to plaintext buffer
1584
1
    if (EVP_DecryptUpdate(ctx, jwe->dat, &p_len, jwe->enc_ct.raw, jwe->enc_ct.raw_len) != 1)
1585
0
    {
1586
0
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
1587
0
        goto _cjose_jwe_decrypt_dat_aes_cbc_fail;
1588
0
    }
1589
1590
    // finalize the decryption
1591
1
    if (EVP_DecryptFinal_ex(ctx, jwe->dat + p_len, &f_len) != 1)
1592
0
    {
1593
0
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
1594
0
        goto _cjose_jwe_decrypt_dat_aes_cbc_fail;
1595
0
    }
1596
1
    jwe->dat_len = p_len + f_len;
1597
1598
1
    EVP_CIPHER_CTX_free(ctx);
1599
1600
1
    return true;
1601
1602
0
_cjose_jwe_decrypt_dat_aes_cbc_fail:
1603
0
    if (NULL != ctx)
1604
0
    {
1605
0
        EVP_CIPHER_CTX_free(ctx);
1606
0
    }
1607
0
    return false;
1608
1
}
1609
1610
////////////////////////////////////////////////////////////////////////////////
1611
static bool _cjose_jwe_validate_decrypt_key(_jwe_int_recipient_t *recipient,
1612
                                            cjose_header_t *protected_header,
1613
                                            cjose_header_t *shared_header,
1614
                                            const cjose_jwk_t *jwk,
1615
                                            cjose_err *err)
1616
20.2k
{
1617
20.2k
    const char *alg
1618
20.2k
        = _cjose_jwe_get_from_headers(protected_header, shared_header, (cjose_header_t *)recipient->unprotected, CJOSE_HDR_ALG);
1619
20.2k
    if (NULL == alg)
1620
0
    {
1621
0
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
1622
0
        return false;
1623
0
    }
1624
1625
20.2k
    if (((0 == strcmp(alg, CJOSE_HDR_ALG_RSA_OAEP)) || (0 == strcmp(alg, CJOSE_HDR_ALG_RSA1_5))) && jwk->kty != CJOSE_JWK_KTY_RSA)
1626
0
    {
1627
0
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
1628
0
        return false;
1629
0
    }
1630
1631
20.2k
    if (((0 == strcmp(alg, CJOSE_HDR_ALG_A128KW)) || (0 == strcmp(alg, CJOSE_HDR_ALG_A192KW))
1632
20.0k
         || (0 == strcmp(alg, CJOSE_HDR_ALG_A256KW)) || (0 == strcmp(alg, CJOSE_HDR_ALG_DIR)))
1633
20.1k
        && jwk->kty != CJOSE_JWK_KTY_OCT)
1634
0
    {
1635
0
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
1636
0
        return false;
1637
0
    }
1638
1639
20.2k
    if ((0 == strcmp(alg, CJOSE_HDR_ALG_ECDH_ES)) && jwk->kty != CJOSE_JWK_KTY_EC)
1640
0
    {
1641
0
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
1642
0
        return false;
1643
0
    }
1644
1645
20.2k
    return true;
1646
20.2k
}
1647
1648
////////////////////////////////////////////////////////////////////////////////
1649
cjose_jwe_t *cjose_jwe_encrypt_iv(const cjose_jwk_t *jwk,
1650
                                  cjose_header_t *protected_header,
1651
                                  const uint8_t *iv,
1652
                                  size_t iv_len,
1653
                                  const uint8_t *plaintext,
1654
                                  size_t plaintext_len,
1655
                                  cjose_err *err)
1656
16.2k
{
1657
1658
16.2k
    cjose_jwe_recipient_t rec = { .jwk = jwk, .unprotected_header = NULL };
1659
1660
16.2k
    return cjose_jwe_encrypt_multi_iv(&rec, 1, protected_header, NULL, iv, iv_len, plaintext, plaintext_len, err);
1661
16.2k
}
1662
1663
////////////////////////////////////////////////////////////////////////////////
1664
cjose_jwe_t *cjose_jwe_encrypt(
1665
    const cjose_jwk_t *jwk, cjose_header_t *protected_header, const uint8_t *plaintext, size_t plaintext_len, cjose_err *err)
1666
16.2k
{
1667
16.2k
    return cjose_jwe_encrypt_iv(jwk, protected_header, NULL, 0, plaintext, plaintext_len, err);
1668
16.2k
}
1669
1670
////////////////////////////////////////////////////////////////////////////////
1671
cjose_jwe_t *cjose_jwe_encrypt_multi_iv(const cjose_jwe_recipient_t *recipients,
1672
                                        size_t recipient_count,
1673
                                        cjose_header_t *protected_header,
1674
                                        cjose_header_t *shared_unprotected_header,
1675
                                        const uint8_t *iv,
1676
                                        size_t iv_len,
1677
                                        const uint8_t *plaintext,
1678
                                        size_t plaintext_len,
1679
                                        cjose_err *err)
1680
16.2k
{
1681
16.2k
    cjose_jwe_t *jwe = NULL;
1682
1683
16.2k
    if (NULL == recipients || NULL == protected_header || recipient_count < 1)
1684
0
    {
1685
0
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
1686
0
        return NULL;
1687
0
    }
1688
1689
    // allocate and initialize a new JWE object
1690
16.2k
    if (!_cjose_jwe_malloc(sizeof(cjose_jwe_t), false, (uint8_t **)&jwe, err))
1691
0
    {
1692
0
        return NULL;
1693
0
    }
1694
1695
16.2k
    jwe->to_count = recipient_count;
1696
16.2k
    if (!_cjose_jwe_malloc(sizeof(_jwe_int_recipient_t) * recipient_count, false, (uint8_t **)&jwe->to, err))
1697
0
    {
1698
0
        cjose_jwe_release(jwe);
1699
0
        return NULL;
1700
0
    }
1701
1702
16.2k
    if (!_cjose_jwe_validate_enc(jwe, protected_header, err))
1703
0
    {
1704
0
        cjose_jwe_release(jwe);
1705
0
        return NULL;
1706
0
    }
1707
1708
    // validate JWE header
1709
32.5k
    for (size_t i = 0; i < recipient_count; i++)
1710
16.2k
    {
1711
1712
16.2k
        if (NULL == recipients[i].jwk)
1713
0
        {
1714
0
            CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
1715
0
            cjose_jwe_release(jwe);
1716
0
            return NULL;
1717
0
        }
1718
1719
16.2k
        jwe->to[i].unprotected = json_incref(recipients[i].unprotected_header);
1720
1721
        // make sure we have an alg header
1722
16.2k
        if (!_cjose_jwe_validate_alg(protected_header, jwe->to[i].unprotected, recipient_count > 1, jwe->to + i, err))
1723
0
        {
1724
0
            cjose_jwe_release(jwe);
1725
0
            return NULL;
1726
0
        }
1727
16.2k
    }
1728
1729
    // prepare JWE headers
1730
16.2k
    jwe->hdr = json_deep_copy(protected_header);
1731
16.2k
    if (jwe->hdr == NULL)
1732
0
    {
1733
0
        cjose_jwe_release(jwe);
1734
0
        return NULL;
1735
0
    }
1736
16.2k
    jwe->shared_hdr = json_incref(shared_unprotected_header);
1737
1738
32.5k
    for (size_t i = 0; i < recipient_count; i++)
1739
16.2k
    {
1740
1741
        // build JWE content-encryption key and encrypted key
1742
16.2k
        if (!jwe->to[i].fns.encrypt_ek(jwe->to + i, jwe, recipients[i].jwk, err))
1743
0
        {
1744
0
            cjose_jwe_release(jwe);
1745
0
            return NULL;
1746
0
        }
1747
16.2k
    }
1748
1749
    // build JWE header
1750
16.2k
    if (!_cjose_jwe_build_hdr(jwe, err))
1751
0
    {
1752
0
        cjose_jwe_release(jwe);
1753
0
        return NULL;
1754
0
    }
1755
1756
    // build JWE initialization vector
1757
16.2k
    if (iv == NULL)
1758
16.2k
    {
1759
16.2k
        if (!jwe->fns.set_iv(jwe, err))
1760
0
        {
1761
0
            cjose_jwe_release(jwe);
1762
0
            return NULL;
1763
0
        }
1764
16.2k
    }
1765
0
    else
1766
0
    {
1767
0
        cjose_get_dealloc()(jwe->enc_iv.raw);
1768
0
        jwe->enc_iv.raw_len = iv_len;
1769
0
        if (!_cjose_jwe_malloc(jwe->enc_iv.raw_len, false, &jwe->enc_iv.raw, err))
1770
0
        {
1771
0
            cjose_jwe_release(jwe);
1772
0
            return NULL;
1773
0
        }
1774
0
        memcpy(jwe->enc_iv.raw, iv, iv_len);
1775
0
    }
1776
1777
    // build JWE encrypted data and authentication tag
1778
16.2k
    if (!jwe->fns.encrypt_dat(jwe, plaintext, plaintext_len, err))
1779
0
    {
1780
0
        cjose_jwe_release(jwe);
1781
0
        return NULL;
1782
0
    }
1783
1784
16.2k
    _cjose_release_cek(&jwe->cek, jwe->cek_len);
1785
1786
16.2k
    return jwe;
1787
16.2k
}
1788
1789
////////////////////////////////////////////////////////////////////////////////
1790
cjose_jwe_t *cjose_jwe_encrypt_multi(const cjose_jwe_recipient_t *recipients,
1791
                                     size_t recipient_count,
1792
                                     cjose_header_t *protected_header,
1793
                                     cjose_header_t *shared_unprotected_header,
1794
                                     const uint8_t *plaintext,
1795
                                     size_t plaintext_len,
1796
                                     cjose_err *err)
1797
0
{
1798
0
    return cjose_jwe_encrypt_multi_iv(recipients, recipient_count, protected_header, shared_unprotected_header, NULL, 0, plaintext,
1799
0
                                      plaintext_len, err);
1800
0
}
1801
1802
////////////////////////////////////////////////////////////////////////////////
1803
void cjose_jwe_release(cjose_jwe_t *jwe)
1804
67.1k
{
1805
67.1k
    if (NULL == jwe)
1806
0
    {
1807
0
        return;
1808
0
    }
1809
1810
67.1k
    json_decref(jwe->hdr);
1811
67.1k
    json_decref(jwe->shared_hdr);
1812
1813
67.1k
    _cjose_dealloc_part(&jwe->enc_header);
1814
67.1k
    _cjose_dealloc_part(&jwe->enc_iv);
1815
67.1k
    _cjose_dealloc_part(&jwe->enc_ct);
1816
67.1k
    _cjose_dealloc_part(&jwe->enc_auth_tag);
1817
1818
134k
    for (int i = 0; i < jwe->to_count; ++i)
1819
67.1k
    {
1820
67.1k
        json_decref(jwe->to[i].unprotected);
1821
67.1k
        _cjose_dealloc_part(&jwe->to[i].enc_key);
1822
67.1k
    }
1823
1824
67.1k
    cjose_get_dealloc()(jwe->to);
1825
1826
67.1k
    _cjose_release_cek(&jwe->cek, jwe->cek_len);
1827
1828
    // jwe->dat holds decrypted plaintext when the caller has not taken
1829
    // ownership of it (e.g. after a failed decrypt); wipe it before release
1830
67.1k
    _cjose_cleanse_dealloc(jwe->dat, jwe->dat_len);
1831
67.1k
    cjose_get_dealloc()(jwe);
1832
67.1k
}
1833
1834
////////////////////////////////////////////////////////////////////////////////
1835
char *cjose_jwe_export(cjose_jwe_t *jwe, cjose_err *err)
1836
16.2k
{
1837
16.2k
    char *cser = NULL;
1838
16.2k
    size_t cser_len = 0;
1839
1840
16.2k
    if (NULL == jwe || jwe->to_count > 1 || !_cjose_empty_json(jwe->shared_hdr) || !_cjose_empty_json(jwe->to[0].unprotected))
1841
0
    {
1842
0
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
1843
0
        return NULL;
1844
0
    }
1845
1846
16.2k
    if (!_cjose_convert_to_base64(jwe, err))
1847
0
    {
1848
0
        return NULL;
1849
0
    }
1850
1851
    // make sure all parts are b64u encoded
1852
16.2k
    cser_len = jwe->enc_header.b64u_len + jwe->to[0].enc_key.b64u_len + jwe->enc_iv.b64u_len + jwe->enc_ct.b64u_len
1853
16.2k
               + jwe->enc_auth_tag.b64u_len + 5;
1854
1855
    // allocate buffer for compact serialization
1856
16.2k
    if (!_cjose_jwe_malloc(cser_len, false, (uint8_t **)&cser, err))
1857
0
    {
1858
0
        return NULL;
1859
0
    }
1860
1861
    // build the compact serialization
1862
16.2k
    snprintf(cser, cser_len, "%s.%s.%s.%s.%s", jwe->enc_header.b64u, jwe->to[0].enc_key.b64u, jwe->enc_iv.b64u, jwe->enc_ct.b64u,
1863
16.2k
             jwe->enc_auth_tag.b64u);
1864
1865
16.2k
    return cser;
1866
16.2k
}
1867
1868
////////////////////////////////////////////////////////////////////////////////
1869
static inline bool _cjose_add_json_part(json_t *obj, const char *key, struct _cjose_jwe_part_int *part, cjose_err *err)
1870
0
{
1871
0
    json_t *str = json_stringn(part->b64u, part->b64u_len);
1872
0
    if (NULL == str)
1873
0
    {
1874
0
        CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY);
1875
0
        return false;
1876
0
    }
1877
0
    json_object_set_new(obj, key, str);
1878
0
    return true;
1879
0
}
1880
1881
////////////////////////////////////////////////////////////////////////////////
1882
char *cjose_jwe_export_json(cjose_jwe_t *jwe, cjose_err *err)
1883
0
{
1884
1885
0
    if (!_cjose_convert_to_base64(jwe, err))
1886
0
    {
1887
0
        return NULL;
1888
0
    }
1889
1890
0
    json_t *form = json_object();
1891
0
    if (NULL == form)
1892
0
    {
1893
0
        CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY);
1894
0
        return NULL;
1895
0
    }
1896
1897
0
    if (!_cjose_add_json_part(form, "protected", &jwe->enc_header, err) || !_cjose_add_json_part(form, "iv", &jwe->enc_iv, err)
1898
0
        || !_cjose_add_json_part(form, "ciphertext", &jwe->enc_ct, err)
1899
0
        || !_cjose_add_json_part(form, "tag", &jwe->enc_auth_tag, err))
1900
0
    {
1901
0
        json_delete(form);
1902
0
        return NULL;
1903
0
    }
1904
1905
0
    json_object_set(form, "unprotected", jwe->shared_hdr);
1906
1907
0
    if (jwe->to_count == 1)
1908
0
    {
1909
0
        json_object_set(form, "header", jwe->to[0].unprotected);
1910
0
        if (!_cjose_add_json_part(form, "encrypted_key", &jwe->to[0].enc_key, err))
1911
0
        {
1912
0
            json_delete(form);
1913
0
            return NULL;
1914
0
        }
1915
0
    }
1916
0
    else
1917
0
    {
1918
1919
0
        json_t *recipients = json_array();
1920
0
        if (NULL == recipients)
1921
0
        {
1922
0
            CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY);
1923
0
            json_delete(form);
1924
0
            return NULL;
1925
0
        }
1926
1927
0
        json_object_set_new(form, "recipients", recipients);
1928
1929
0
        for (int i = 0; i < jwe->to_count; i++)
1930
0
        {
1931
1932
0
            json_t *recipient = json_object();
1933
0
            if (NULL == recipient)
1934
0
            {
1935
0
                CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY);
1936
0
                json_delete(form);
1937
0
                return NULL;
1938
0
            }
1939
1940
0
            json_array_append_new(recipients, recipient);
1941
1942
0
            json_object_set(recipient, "header", jwe->to[i].unprotected);
1943
0
            if (!_cjose_add_json_part(recipient, "encrypted_key", &jwe->to[i].enc_key, err))
1944
0
            {
1945
0
                json_delete(form);
1946
0
                return NULL;
1947
0
            }
1948
0
        }
1949
0
    }
1950
1951
0
    char *json_str = json_dumps(form, JSON_PRESERVE_ORDER);
1952
0
    if (NULL == json_str)
1953
0
    {
1954
0
        CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY);
1955
0
        json_delete(form);
1956
0
        return NULL;
1957
0
    }
1958
1959
0
    json_delete(form);
1960
0
    return json_str;
1961
0
}
1962
1963
////////////////////////////////////////////////////////////////////////////////
1964
static bool
1965
_cjose_jwe_import_part(struct _cjose_jwe_part_int *part, bool empty_ok, const char *b64u, size_t b64u_len, cjose_err *err)
1966
195k
{
1967
    // only the ek and the data parts may be of zero length
1968
195k
    if (b64u_len == 0 && !empty_ok)
1969
5.41k
    {
1970
5.41k
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
1971
5.41k
        return false;
1972
5.41k
    }
1973
1974
    // copy the b64u part to the jwe
1975
189k
    part->b64u = _cjose_strndup(b64u, b64u_len, err);
1976
189k
    part->b64u_len = b64u_len;
1977
1978
    // b64u decode the part
1979
189k
    if (!cjose_base64url_decode(part->b64u, part->b64u_len, (uint8_t **)&part->raw, &part->raw_len, err) || NULL == part->raw)
1980
7.57k
    {
1981
7.57k
        return false;
1982
7.57k
    }
1983
1984
182k
    return true;
1985
189k
}
1986
1987
static bool _cjose_jwe_import_json_part(struct _cjose_jwe_part_int *part, bool empty_ok, json_t *json, cjose_err *err)
1988
0
{
1989
1990
0
    if (NULL == json || !json_is_string(json))
1991
0
    {
1992
0
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
1993
0
        return false;
1994
0
    }
1995
1996
0
    const char *str = json_string_value(json);
1997
    // TODO: if json_is_string() was true, are we guaranteed that str is !NULL?
1998
1999
0
    return _cjose_jwe_import_part(part, empty_ok, str, strlen(str), err);
2000
0
}
2001
2002
////////////////////////////////////////////////////////////////////////////////
2003
cjose_jwe_t *cjose_jwe_import(const char *cser, size_t cser_len, cjose_err *err)
2004
50.8k
{
2005
50.8k
    cjose_jwe_t *jwe = NULL;
2006
2007
50.8k
    if (NULL == cser)
2008
0
    {
2009
0
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
2010
0
        return NULL;
2011
0
    }
2012
2013
    // allocate and initialize a new JWE object
2014
50.8k
    if (!_cjose_jwe_malloc(sizeof(cjose_jwe_t), false, (uint8_t **)&jwe, err))
2015
0
    {
2016
0
        return NULL;
2017
0
    }
2018
2019
50.8k
    jwe->to_count = 1;
2020
50.8k
    if (!_cjose_jwe_malloc(sizeof(_jwe_int_recipient_t), false, (uint8_t **)&jwe->to, err))
2021
0
    {
2022
0
        cjose_jwe_release(jwe);
2023
0
        return NULL;
2024
0
    }
2025
2026
50.8k
    struct _cjose_jwe_part_int *parts[] = {
2027
50.8k
        &jwe->enc_header, &jwe->to[0].enc_key, &jwe->enc_iv, &jwe->enc_ct, &jwe->enc_auth_tag,
2028
50.8k
    };
2029
2030
    // import each part of the compact serialization
2031
50.8k
    int part = 0;
2032
50.8k
    size_t idx = 0;
2033
50.8k
    size_t start_idx = 0;
2034
243M
    while (idx <= cser_len && part < 5)
2035
243M
    {
2036
243M
        if ((idx == cser_len) || (cser[idx] == '.'))
2037
195k
        {
2038
195k
            if (!_cjose_jwe_import_part(parts[part], 1 == part || 3 == part, cser + start_idx, idx - start_idx, err))
2039
12.9k
            {
2040
12.9k
                cjose_jwe_release(jwe);
2041
12.9k
                return NULL;
2042
12.9k
            }
2043
182k
            part++;
2044
182k
            start_idx = idx + 1;
2045
182k
        }
2046
243M
        if (part < 5)
2047
243M
            ++idx;
2048
243M
    }
2049
2050
    // fail if we didn't find enough parts
2051
37.8k
    if (part != 5)
2052
14.2k
    {
2053
14.2k
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
2054
14.2k
        cjose_jwe_release(jwe);
2055
14.2k
        return NULL;
2056
14.2k
    }
2057
2058
    // fail if we finished early (e.g. more than 5 parts)
2059
23.5k
    if (idx != cser_len)
2060
999
    {
2061
999
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
2062
999
        cjose_jwe_release(jwe);
2063
999
        return NULL;
2064
999
    }
2065
2066
    // deserialize JSON header
2067
22.5k
    jwe->hdr = _cjose_parse_json_object((const char *)jwe->enc_header.raw, jwe->enc_header.raw_len, err);
2068
22.5k
    if (NULL == jwe->hdr)
2069
1.75k
    {
2070
1.75k
        cjose_jwe_release(jwe);
2071
1.75k
        return NULL;
2072
1.75k
    }
2073
2074
    // validate the JSON header. No unprotected headers can exist.
2075
20.8k
    if (!_cjose_jwe_validate_alg((cjose_header_t *)jwe->hdr, NULL, false, jwe->to, err)
2076
20.4k
        || !_cjose_jwe_validate_enc(jwe, (cjose_header_t *)jwe->hdr, err))
2077
747
    {
2078
747
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
2079
747
        cjose_jwe_release(jwe);
2080
747
        return NULL;
2081
747
    }
2082
2083
20.0k
    return jwe;
2084
20.8k
}
2085
2086
static inline bool _cjose_read_json_recipient(cjose_jwe_t *jwe,
2087
                                              cjose_header_t *protected_header,
2088
                                              bool is_multiple,
2089
                                              _jwe_int_recipient_t *recipient,
2090
                                              json_t *obj,
2091
                                              cjose_err *err)
2092
0
{
2093
2094
0
    if (!json_is_object(obj))
2095
0
    {
2096
0
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
2097
0
        return false;
2098
0
    }
2099
2100
0
    if (!_cjose_jwe_import_json_part(&recipient->enc_key, true, json_object_get(obj, "encrypted_key"), err))
2101
0
    {
2102
0
        return false;
2103
0
    };
2104
2105
0
    recipient->unprotected = json_incref(json_object_get(obj, "header"));
2106
2107
    // it's OK to have empty/null unprotected header
2108
0
    if (recipient->unprotected && !json_is_object(recipient->unprotected))
2109
0
    {
2110
0
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
2111
0
        return false;
2112
0
    }
2113
2114
0
    return _cjose_jwe_validate_alg(protected_header, jwe->shared_hdr, is_multiple, recipient, err);
2115
0
}
2116
2117
////////////////////////////////////////////////////////////////////////////////
2118
cjose_jwe_t *cjose_jwe_import_json(const char *cser, size_t cser_len, cjose_err *err)
2119
0
{
2120
0
    cjose_jwe_t *jwe = NULL;
2121
0
    json_t *form = NULL;
2122
0
    json_t *protected_header = NULL;
2123
2124
0
    if (NULL == cser)
2125
0
    {
2126
0
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
2127
0
        return NULL;
2128
0
    }
2129
2130
    // allocate and initialize a new JWE object
2131
0
    if (!_cjose_jwe_malloc(sizeof(cjose_jwe_t), false, (uint8_t **)&jwe, err))
2132
0
    {
2133
0
        return NULL;
2134
0
    }
2135
2136
0
    form = _cjose_parse_json_object(cser, cser_len, err);
2137
0
    if (NULL == form)
2138
0
    {
2139
0
        goto _cjose_jwe_import_json_fail;
2140
0
    }
2141
2142
0
    json_t *recipients = json_object_get(form, "recipients");
2143
0
    if (NULL != recipients)
2144
0
    {
2145
0
        if (!json_is_array(recipients))
2146
0
        {
2147
0
            CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
2148
0
            goto _cjose_jwe_import_json_fail;
2149
0
        }
2150
0
        jwe->to_count = json_array_size(recipients);
2151
0
        if (jwe->to_count < 1)
2152
0
        {
2153
            // TODO: is empty recipients array allowed?
2154
0
            CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
2155
0
            goto _cjose_jwe_import_json_fail;
2156
0
        }
2157
0
    }
2158
0
    else
2159
0
    {
2160
0
        jwe->to_count = 1;
2161
0
    }
2162
2163
0
    if (!_cjose_jwe_malloc(sizeof(_jwe_int_recipient_t) * jwe->to_count, false, (uint8_t **)&jwe->to, err))
2164
0
    {
2165
0
        goto _cjose_jwe_import_json_fail;
2166
0
    }
2167
2168
0
    if (!_cjose_jwe_import_json_part(&jwe->enc_header, false, json_object_get(form, "protected"), err))
2169
0
    {
2170
0
        goto _cjose_jwe_import_json_fail;
2171
0
    }
2172
2173
0
    protected_header = _cjose_parse_json_object((const char *)jwe->enc_header.raw, jwe->enc_header.raw_len, err);
2174
0
    if (NULL == protected_header)
2175
0
    {
2176
0
        goto _cjose_jwe_import_json_fail;
2177
0
    }
2178
2179
    // the shared unprotected header, if present, must be a JSON object; retain
2180
    // it so the per-recipient effective-header lookups (and cjose_jwe_export_json)
2181
    // see it, mirroring the "unprotected" member written on export
2182
0
    json_t *shared_unprotected = json_object_get(form, "unprotected");
2183
0
    if (NULL != shared_unprotected)
2184
0
    {
2185
0
        if (!json_is_object(shared_unprotected))
2186
0
        {
2187
0
            CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
2188
0
            goto _cjose_jwe_import_json_fail;
2189
0
        }
2190
0
        jwe->shared_hdr = json_incref(shared_unprotected);
2191
0
    }
2192
2193
0
    if (NULL == recipients)
2194
0
    {
2195
2196
0
        if (!_cjose_read_json_recipient(jwe, protected_header, false, jwe->to, form, err))
2197
0
        {
2198
0
            goto _cjose_jwe_import_json_fail;
2199
0
        }
2200
0
    }
2201
0
    else
2202
0
    {
2203
2204
0
        for (size_t i = 0; i < jwe->to_count; i++)
2205
0
        {
2206
2207
0
            if (!_cjose_read_json_recipient(jwe, protected_header, jwe->to_count > 1, jwe->to + i, json_array_get(recipients, i),
2208
0
                                            err))
2209
0
            {
2210
0
                goto _cjose_jwe_import_json_fail;
2211
0
            }
2212
0
        }
2213
0
    }
2214
2215
0
    if (!_cjose_jwe_validate_enc(jwe, protected_header, err))
2216
0
    {
2217
0
        goto _cjose_jwe_import_json_fail;
2218
0
    }
2219
2220
0
    if (!_cjose_jwe_import_json_part(&jwe->enc_iv, false, json_object_get(form, "iv"), err)
2221
0
        || !_cjose_jwe_import_json_part(&jwe->enc_ct, false, json_object_get(form, "ciphertext"), err)
2222
0
        || !_cjose_jwe_import_json_part(&jwe->enc_auth_tag, false, json_object_get(form, "tag"), err))
2223
0
    {
2224
2225
0
        goto _cjose_jwe_import_json_fail;
2226
0
    }
2227
2228
0
    jwe->hdr = json_incref(protected_header);
2229
2230
0
    json_decref(form);
2231
0
    json_decref(protected_header);
2232
2233
0
    return jwe;
2234
2235
0
_cjose_jwe_import_json_fail:
2236
0
    json_decref(form);
2237
0
    json_decref(protected_header);
2238
0
    cjose_jwe_release(jwe);
2239
0
    return NULL;
2240
0
}
2241
2242
uint8_t *cjose_jwe_decrypt_multi(cjose_jwe_t *jwe, cjose_key_locator key_locator, void *data, size_t *content_len, cjose_err *err)
2243
0
{
2244
2245
0
    uint8_t *cek = 0;
2246
0
    size_t cek_len = 0;
2247
0
    uint8_t *content = NULL;
2248
2249
0
    if (NULL == jwe || NULL == key_locator || NULL == content_len)
2250
0
    {
2251
0
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
2252
0
        return NULL;
2253
0
    }
2254
2255
0
    for (size_t i = 0; i < jwe->to_count; i++)
2256
0
    {
2257
2258
0
        const cjose_jwk_t *key = key_locator(jwe, (cjose_header_t *)jwe->to[i].unprotected, data);
2259
0
        if (NULL == key)
2260
0
        {
2261
0
            continue;
2262
0
        }
2263
2264
0
        if (!_cjose_jwe_validate_decrypt_key(jwe->to + i, (cjose_header_t *)jwe->hdr, (cjose_header_t *)jwe->shared_hdr, key, err))
2265
0
        {
2266
0
            goto _cjose_jwe_decrypt_multi_fail;
2267
0
        }
2268
2269
        // decrypt JWE content-encryption key from encrypted key
2270
0
        if (!jwe->to[i].fns.decrypt_ek(jwe->to + i, jwe, key, err))
2271
0
        {
2272
            // if one key failed to decrypt, fail everything.
2273
0
            goto _cjose_jwe_decrypt_multi_fail;
2274
0
        }
2275
2276
0
        if (NULL == cek)
2277
0
        {
2278
0
            cek_len = jwe->cek_len;
2279
0
            cek = cjose_get_alloc()(cek_len);
2280
0
            if (!cek)
2281
0
            {
2282
0
                CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY);
2283
0
                return NULL;
2284
0
            }
2285
0
            memcpy(cek, jwe->cek, cek_len);
2286
0
        }
2287
0
        else
2288
0
        {
2289
            // constant-time compare: both operands are secret CEKs
2290
0
            if (cek_len != jwe->cek_len || cjose_const_memcmp(jwe->cek, cek, cek_len) != 0)
2291
0
            {
2292
0
                CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
2293
0
                goto _cjose_jwe_decrypt_multi_fail;
2294
0
            }
2295
0
        }
2296
0
    }
2297
2298
0
    if (NULL == jwe->cek)
2299
0
    {
2300
0
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
2301
0
        goto _cjose_jwe_decrypt_multi_fail;
2302
0
    }
2303
2304
    // decrypt JWE encrypted data
2305
0
    if (!jwe->fns.decrypt_dat(jwe, err))
2306
0
    {
2307
0
        goto _cjose_jwe_decrypt_multi_fail;
2308
0
    }
2309
2310
    // take the plaintext data from the jwe object
2311
0
    content = jwe->dat;
2312
0
    *content_len = jwe->dat_len;
2313
2314
0
    jwe->dat = NULL;
2315
0
    jwe->dat_len = 0;
2316
2317
0
_cjose_jwe_decrypt_multi_fail:
2318
2319
0
    _cjose_release_cek(&cek, cek_len);
2320
2321
0
    return content;
2322
0
}
2323
2324
////////////////////////////////////////////////////////////////////////////////
2325
uint8_t *cjose_jwe_decrypt(cjose_jwe_t *jwe, const cjose_jwk_t *jwk, size_t *content_len, cjose_err *err)
2326
20.2k
{
2327
20.2k
    if (NULL == jwe || NULL == jwk || NULL == content_len || jwe->to_count > 1)
2328
0
    {
2329
0
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
2330
0
        return NULL;
2331
0
    }
2332
2333
20.2k
    if (!_cjose_jwe_validate_decrypt_key(jwe->to, (cjose_header_t *)jwe->hdr, (cjose_header_t *)jwe->shared_hdr, jwk, err))
2334
0
    {
2335
0
        return NULL;
2336
0
    }
2337
2338
    // decrypt JWE content-encryption key from encrypted key
2339
20.2k
    if (!jwe->to[0].fns.decrypt_ek(jwe->to, jwe, jwk, err))
2340
256
    {
2341
256
        return NULL;
2342
256
    }
2343
2344
    // decrypt JWE encrypted data
2345
20.0k
    if (!jwe->fns.decrypt_dat(jwe, err))
2346
10.7k
    {
2347
10.7k
        return NULL;
2348
10.7k
    }
2349
2350
    // take the plaintext data from the jwe object
2351
9.27k
    uint8_t *content = jwe->dat;
2352
9.27k
    *content_len = jwe->dat_len;
2353
9.27k
    jwe->dat = NULL;
2354
9.27k
    jwe->dat_len = 0;
2355
2356
9.27k
    return content;
2357
20.0k
}
2358
2359
////////////////////////////////////////////////////////////////////////////////
2360
cjose_header_t *cjose_jwe_get_protected(cjose_jwe_t *jwe)
2361
20.0k
{
2362
20.0k
    if (NULL == jwe)
2363
0
    {
2364
0
        return NULL;
2365
0
    }
2366
20.0k
    return (cjose_header_t *)jwe->hdr;
2367
20.0k
}