Coverage Report

Created: 2026-09-27 07:07

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