]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/cms/cms_kari.c
Add CMS AuthEnvelopedData with AES-GCM support
[thirdparty/openssl.git] / crypto / cms / cms_kari.c
CommitLineData
0f113f3e 1/*
33388b44 2 * Copyright 2013-2020 The OpenSSL Project Authors. All Rights Reserved.
17c2764d 3 *
08ddd302 4 * Licensed under the Apache License 2.0 (the "License"). You may not use
b1322259
RS
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
17c2764d
DSH
8 */
9
41bbba53
P
10/*
11 * Low level key APIs (DH etc) are deprecated for public use, but still ok for
12 * internal use.
13 */
14#include "internal/deprecated.h"
15
b39fc560 16#include "internal/cryptlib.h"
17c2764d
DSH
17#include <openssl/asn1t.h>
18#include <openssl/pem.h>
19#include <openssl/x509v3.h>
20#include <openssl/err.h>
21#include <openssl/cms.h>
17c2764d 22#include <openssl/aes.h>
706457b7 23#include "cms_local.h"
25f2138b 24#include "crypto/asn1.h"
17c2764d 25
852c2ed2
RS
26DEFINE_STACK_OF(CMS_RecipientEncryptedKey)
27
17c2764d
DSH
28/* Key Agreement Recipient Info (KARI) routines */
29
30int CMS_RecipientInfo_kari_get0_alg(CMS_RecipientInfo *ri,
0f113f3e
MC
31 X509_ALGOR **palg,
32 ASN1_OCTET_STRING **pukm)
33{
34 if (ri->type != CMS_RECIPINFO_AGREE) {
35 CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ALG,
36 CMS_R_NOT_KEY_AGREEMENT);
37 return 0;
38 }
39 if (palg)
40 *palg = ri->d.kari->keyEncryptionAlgorithm;
41 if (pukm)
42 *pukm = ri->d.kari->ukm;
43 return 1;
44}
17c2764d
DSH
45
46/* Retrieve recipient encrypted keys from a kari */
47
0f113f3e
MC
48STACK_OF(CMS_RecipientEncryptedKey)
49*CMS_RecipientInfo_kari_get0_reks(CMS_RecipientInfo *ri)
50{
51 if (ri->type != CMS_RECIPINFO_AGREE) {
52 CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_REKS,
53 CMS_R_NOT_KEY_AGREEMENT);
54 return NULL;
55 }
56 return ri->d.kari->recipientEncryptedKeys;
57}
17c2764d
DSH
58
59int CMS_RecipientInfo_kari_get0_orig_id(CMS_RecipientInfo *ri,
0f113f3e
MC
60 X509_ALGOR **pubalg,
61 ASN1_BIT_STRING **pubkey,
62 ASN1_OCTET_STRING **keyid,
63 X509_NAME **issuer,
64 ASN1_INTEGER **sno)
65{
66 CMS_OriginatorIdentifierOrKey *oik;
c1669f41 67
0f113f3e
MC
68 if (ri->type != CMS_RECIPINFO_AGREE) {
69 CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ORIG_ID,
70 CMS_R_NOT_KEY_AGREEMENT);
71 return 0;
72 }
73 oik = ri->d.kari->originator;
74 if (issuer)
75 *issuer = NULL;
76 if (sno)
77 *sno = NULL;
78 if (keyid)
79 *keyid = NULL;
80 if (pubalg)
81 *pubalg = NULL;
82 if (pubkey)
83 *pubkey = NULL;
84 if (oik->type == CMS_OIK_ISSUER_SERIAL) {
85 if (issuer)
86 *issuer = oik->d.issuerAndSerialNumber->issuer;
87 if (sno)
88 *sno = oik->d.issuerAndSerialNumber->serialNumber;
89 } else if (oik->type == CMS_OIK_KEYIDENTIFIER) {
90 if (keyid)
91 *keyid = oik->d.subjectKeyIdentifier;
92 } else if (oik->type == CMS_OIK_PUBKEY) {
93 if (pubalg)
94 *pubalg = oik->d.originatorKey->algorithm;
95 if (pubkey)
96 *pubkey = oik->d.originatorKey->publicKey;
97 } else
98 return 0;
99 return 1;
100}
17c2764d
DSH
101
102int CMS_RecipientInfo_kari_orig_id_cmp(CMS_RecipientInfo *ri, X509 *cert)
0f113f3e
MC
103{
104 CMS_OriginatorIdentifierOrKey *oik;
c1669f41 105
0f113f3e
MC
106 if (ri->type != CMS_RECIPINFO_AGREE) {
107 CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_ORIG_ID_CMP,
108 CMS_R_NOT_KEY_AGREEMENT);
109 return -2;
110 }
111 oik = ri->d.kari->originator;
112 if (oik->type == CMS_OIK_ISSUER_SERIAL)
113 return cms_ias_cert_cmp(oik->d.issuerAndSerialNumber, cert);
114 else if (oik->type == CMS_OIK_KEYIDENTIFIER)
115 return cms_keyid_cert_cmp(oik->d.subjectKeyIdentifier, cert);
116 return -1;
117}
17c2764d
DSH
118
119int CMS_RecipientEncryptedKey_get0_id(CMS_RecipientEncryptedKey *rek,
0f113f3e
MC
120 ASN1_OCTET_STRING **keyid,
121 ASN1_GENERALIZEDTIME **tm,
122 CMS_OtherKeyAttribute **other,
123 X509_NAME **issuer, ASN1_INTEGER **sno)
124{
125 CMS_KeyAgreeRecipientIdentifier *rid = rek->rid;
c1669f41 126
0f113f3e
MC
127 if (rid->type == CMS_REK_ISSUER_SERIAL) {
128 if (issuer)
129 *issuer = rid->d.issuerAndSerialNumber->issuer;
130 if (sno)
131 *sno = rid->d.issuerAndSerialNumber->serialNumber;
132 if (keyid)
133 *keyid = NULL;
134 if (tm)
135 *tm = NULL;
136 if (other)
137 *other = NULL;
138 } else if (rid->type == CMS_REK_KEYIDENTIFIER) {
139 if (keyid)
140 *keyid = rid->d.rKeyId->subjectKeyIdentifier;
141 if (tm)
142 *tm = rid->d.rKeyId->date;
143 if (other)
144 *other = rid->d.rKeyId->other;
145 if (issuer)
146 *issuer = NULL;
147 if (sno)
148 *sno = NULL;
149 } else
150 return 0;
151 return 1;
152}
17c2764d
DSH
153
154int CMS_RecipientEncryptedKey_cert_cmp(CMS_RecipientEncryptedKey *rek,
0f113f3e
MC
155 X509 *cert)
156{
157 CMS_KeyAgreeRecipientIdentifier *rid = rek->rid;
c1669f41 158
0f113f3e
MC
159 if (rid->type == CMS_REK_ISSUER_SERIAL)
160 return cms_ias_cert_cmp(rid->d.issuerAndSerialNumber, cert);
161 else if (rid->type == CMS_REK_KEYIDENTIFIER)
162 return cms_keyid_cert_cmp(rid->d.rKeyId->subjectKeyIdentifier, cert);
163 else
164 return -1;
165}
17c2764d 166
71434aed 167int CMS_RecipientInfo_kari_set0_pkey_and_peer(CMS_RecipientInfo *ri, EVP_PKEY *pk, X509 *peer)
0f113f3e
MC
168{
169 EVP_PKEY_CTX *pctx;
170 CMS_KeyAgreeRecipientInfo *kari = ri->d.kari;
25aaa98a
RS
171
172 EVP_PKEY_CTX_free(kari->pctx);
173 kari->pctx = NULL;
12a765a5 174 if (pk == NULL)
0f113f3e 175 return 1;
71434aed 176
c1669f41
SL
177 pctx = EVP_PKEY_CTX_new_from_pkey(kari->cms_ctx->libctx, pk,
178 kari->cms_ctx->propq);
12a765a5 179 if (pctx == NULL || EVP_PKEY_derive_init(pctx) <= 0)
0f113f3e 180 goto err;
71434aed
DB
181
182 if (peer != NULL) {
183 EVP_PKEY *pub_pkey = X509_get0_pubkey(peer);
184
185 if (EVP_PKEY_derive_set_peer(pctx, pub_pkey) <= 0)
186 goto err;
187 }
188
0f113f3e
MC
189 kari->pctx = pctx;
190 return 1;
191 err:
c5ba2d99 192 EVP_PKEY_CTX_free(pctx);
0f113f3e
MC
193 return 0;
194}
17c2764d 195
71434aed
DB
196int CMS_RecipientInfo_kari_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pk)
197{
198 return CMS_RecipientInfo_kari_set0_pkey_and_peer(ri, pk, NULL);
199}
200
17c2764d 201EVP_CIPHER_CTX *CMS_RecipientInfo_kari_get0_ctx(CMS_RecipientInfo *ri)
0f113f3e
MC
202{
203 if (ri->type == CMS_RECIPINFO_AGREE)
846ec07d 204 return ri->d.kari->ctx;
0f113f3e
MC
205 return NULL;
206}
207
208/*
209 * Derive KEK and decrypt/encrypt with it to produce either the original CEK
210 * or the encrypted CEK.
17c2764d
DSH
211 */
212
0f113f3e
MC
213static int cms_kek_cipher(unsigned char **pout, size_t *poutlen,
214 const unsigned char *in, size_t inlen,
215 CMS_KeyAgreeRecipientInfo *kari, int enc)
216{
217 /* Key encryption key */
218 unsigned char kek[EVP_MAX_KEY_LENGTH];
219 size_t keklen;
220 int rv = 0;
221 unsigned char *out = NULL;
222 int outlen;
c1669f41 223
846ec07d 224 keklen = EVP_CIPHER_CTX_key_length(kari->ctx);
0f113f3e
MC
225 if (keklen > EVP_MAX_KEY_LENGTH)
226 return 0;
227 /* Derive KEK */
228 if (EVP_PKEY_derive(kari->pctx, kek, &keklen) <= 0)
229 goto err;
230 /* Set KEK in context */
846ec07d 231 if (!EVP_CipherInit_ex(kari->ctx, NULL, NULL, kek, NULL, enc))
0f113f3e
MC
232 goto err;
233 /* obtain output length of ciphered key */
846ec07d 234 if (!EVP_CipherUpdate(kari->ctx, NULL, &outlen, in, inlen))
0f113f3e
MC
235 goto err;
236 out = OPENSSL_malloc(outlen);
90945fa3 237 if (out == NULL)
0f113f3e 238 goto err;
846ec07d 239 if (!EVP_CipherUpdate(kari->ctx, out, &outlen, in, inlen))
0f113f3e
MC
240 goto err;
241 *pout = out;
242 *poutlen = (size_t)outlen;
243 rv = 1;
244
245 err:
246 OPENSSL_cleanse(kek, keklen);
b548a1f1 247 if (!rv)
0f113f3e 248 OPENSSL_free(out);
846ec07d
RL
249 EVP_CIPHER_CTX_reset(kari->ctx);
250 /* FIXME: WHY IS kari->pctx freed here? /RL */
0f113f3e
MC
251 EVP_PKEY_CTX_free(kari->pctx);
252 kari->pctx = NULL;
253 return rv;
254}
255
256int CMS_RecipientInfo_kari_decrypt(CMS_ContentInfo *cms,
257 CMS_RecipientInfo *ri,
258 CMS_RecipientEncryptedKey *rek)
259{
260 int rv = 0;
261 unsigned char *enckey = NULL, *cek = NULL;
262 size_t enckeylen;
263 size_t ceklen;
264 CMS_EncryptedContentInfo *ec;
aec8de1a
RL
265
266 {
267 /*
268 * TODO(3.0) Remove this when we have functionality to deserialize
269 * parameters in EVP_PKEY form from an X509_ALGOR.
270 * This is needed to be able to replace the EC_KEY specific decoding
271 * that happens in ecdh_cms_set_peerkey() (crypto/ec/ec_ameth.c)
272 *
273 * THIS IS TEMPORARY
274 */
275 EVP_PKEY_CTX *pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
276 EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx);
277
278 EVP_PKEY_get0(pkey);
279 if (EVP_PKEY_id(pkey) == EVP_PKEY_NONE) {
280 CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_DECRYPT,
281 CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
282 goto err;
283 }
284 }
285
0f113f3e
MC
286 enckeylen = rek->encryptedKey->length;
287 enckey = rek->encryptedKey->data;
288 /* Setup all parameters to derive KEK */
289 if (!cms_env_asn1_ctrl(ri, 1))
290 goto err;
291 /* Attempt to decrypt CEK */
292 if (!cms_kek_cipher(&cek, &ceklen, enckey, enckeylen, ri->d.kari, 0))
293 goto err;
924663c3 294 ec = cms_get0_env_enc_content(cms);
4b45c6e5 295 OPENSSL_clear_free(ec->key, ec->keylen);
0f113f3e
MC
296 ec->key = cek;
297 ec->keylen = ceklen;
298 cek = NULL;
299 rv = 1;
300 err:
b548a1f1 301 OPENSSL_free(cek);
0f113f3e
MC
302 return rv;
303}
17c2764d
DSH
304
305/* Create ephemeral key and initialise context based on it */
306static int cms_kari_create_ephemeral_key(CMS_KeyAgreeRecipientInfo *kari,
0f113f3e
MC
307 EVP_PKEY *pk)
308{
309 EVP_PKEY_CTX *pctx = NULL;
310 EVP_PKEY *ekey = NULL;
311 int rv = 0;
c1669f41 312 const CMS_CTX *ctx = kari->cms_ctx;
12a765a5 313
c1669f41 314 pctx = EVP_PKEY_CTX_new_from_pkey(ctx->libctx, pk, ctx->propq);
12a765a5 315 if (pctx == NULL)
0f113f3e
MC
316 goto err;
317 if (EVP_PKEY_keygen_init(pctx) <= 0)
318 goto err;
319 if (EVP_PKEY_keygen(pctx, &ekey) <= 0)
320 goto err;
321 EVP_PKEY_CTX_free(pctx);
c1669f41 322 pctx = EVP_PKEY_CTX_new_from_pkey(ctx->libctx, ekey, ctx->propq);
12a765a5 323 if (pctx == NULL)
0f113f3e
MC
324 goto err;
325 if (EVP_PKEY_derive_init(pctx) <= 0)
326 goto err;
327 kari->pctx = pctx;
328 rv = 1;
329 err:
c5ba2d99 330 if (!rv)
0f113f3e 331 EVP_PKEY_CTX_free(pctx);
c5ba2d99 332 EVP_PKEY_free(ekey);
0f113f3e
MC
333 return rv;
334}
17c2764d 335
71434aed 336/* Set originator private key and initialise context based on it */
c1669f41
SL
337static int cms_kari_set_originator_private_key(CMS_KeyAgreeRecipientInfo *kari,
338 EVP_PKEY *originatorPrivKey )
71434aed
DB
339{
340 EVP_PKEY_CTX *pctx = NULL;
341 int rv = 0;
c1669f41 342 const CMS_CTX *ctx = kari->cms_ctx;
71434aed 343
c1669f41 344 pctx = EVP_PKEY_CTX_new_from_pkey(ctx->libctx, originatorPrivKey, ctx->propq);
71434aed
DB
345 if (pctx == NULL)
346 goto err;
347 if (EVP_PKEY_derive_init(pctx) <= 0)
348 goto err;
349
350 kari->pctx = pctx;
351 rv = 1;
352 err:
353 if (rv == 0)
354 EVP_PKEY_CTX_free(pctx);
355 return rv;
356}
357
b754a8a1 358/* Initialise a kari based on passed certificate and key */
17c2764d 359
c1669f41
SL
360int cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip,
361 EVP_PKEY *recipPubKey, X509 *originator,
362 EVP_PKEY *originatorPrivKey, unsigned int flags,
363 const CMS_CTX *ctx)
0f113f3e
MC
364{
365 CMS_KeyAgreeRecipientInfo *kari;
366 CMS_RecipientEncryptedKey *rek = NULL;
367
368 ri->d.kari = M_ASN1_new_of(CMS_KeyAgreeRecipientInfo);
c1669f41 369 if (ri->d.kari == NULL)
0f113f3e
MC
370 return 0;
371 ri->type = CMS_RECIPINFO_AGREE;
372
373 kari = ri->d.kari;
374 kari->version = 3;
c1669f41 375 kari->cms_ctx = ctx;
0f113f3e
MC
376
377 rek = M_ASN1_new_of(CMS_RecipientEncryptedKey);
b754a8a1
DD
378 if (rek == NULL)
379 return 0;
380
0f113f3e
MC
381 if (!sk_CMS_RecipientEncryptedKey_push(kari->recipientEncryptedKeys, rek)) {
382 M_ASN1_free_of(rek, CMS_RecipientEncryptedKey);
383 return 0;
384 }
385
386 if (flags & CMS_USE_KEYID) {
387 rek->rid->type = CMS_REK_KEYIDENTIFIER;
7a317fa0
DSH
388 rek->rid->d.rKeyId = M_ASN1_new_of(CMS_RecipientKeyIdentifier);
389 if (rek->rid->d.rKeyId == NULL)
390 return 0;
0f113f3e
MC
391 if (!cms_set1_keyid(&rek->rid->d.rKeyId->subjectKeyIdentifier, recip))
392 return 0;
393 } else {
394 rek->rid->type = CMS_REK_ISSUER_SERIAL;
395 if (!cms_set1_ias(&rek->rid->d.issuerAndSerialNumber, recip))
396 return 0;
397 }
398
71434aed
DB
399 if (originatorPrivKey == NULL && originator == NULL) {
400 /* Create ephemeral key */
401 if (!cms_kari_create_ephemeral_key(kari, recipPubKey))
402 return 0;
403 } else {
1f74259d
P
404 /* Use originator key */
405 CMS_OriginatorIdentifierOrKey *oik = ri->d.kari->originator;
71434aed 406
1f74259d 407 if (originatorPrivKey == NULL || originator == NULL)
71434aed 408 return 0;
0f113f3e 409
1f74259d
P
410 if (flags & CMS_USE_ORIGINATOR_KEYID) {
411 oik->type = CMS_OIK_KEYIDENTIFIER;
412 oik->d.subjectKeyIdentifier = ASN1_OCTET_STRING_new();
413 if (oik->d.subjectKeyIdentifier == NULL)
414 return 0;
415 if (!cms_set1_keyid(&oik->d.subjectKeyIdentifier, originator))
416 return 0;
417 } else {
418 oik->type = CMS_REK_ISSUER_SERIAL;
419 if (!cms_set1_ias(&oik->d.issuerAndSerialNumber, originator))
420 return 0;
421 }
422
423 if (!cms_kari_set_originator_private_key(kari, originatorPrivKey))
424 return 0;
71434aed
DB
425 }
426
427 EVP_PKEY_up_ref(recipPubKey);
428 rek->pkey = recipPubKey;
0f113f3e
MC
429 return 1;
430}
17c2764d
DSH
431
432static int cms_wrap_init(CMS_KeyAgreeRecipientInfo *kari,
0f113f3e
MC
433 const EVP_CIPHER *cipher)
434{
c1669f41 435 const CMS_CTX *cms_ctx = kari->cms_ctx;
846ec07d 436 EVP_CIPHER_CTX *ctx = kari->ctx;
0f113f3e 437 const EVP_CIPHER *kekcipher;
c1669f41
SL
438 EVP_CIPHER *fetched_kekcipher;
439 const char *kekcipher_name;
3e47e7b4 440 int keylen;
71434aed
DB
441 int ret;
442
0f113f3e
MC
443 /* If a suitable wrap algorithm is already set nothing to do */
444 kekcipher = EVP_CIPHER_CTX_cipher(ctx);
71434aed 445 if (kekcipher != NULL) {
0f113f3e
MC
446 if (EVP_CIPHER_CTX_mode(ctx) != EVP_CIPH_WRAP_MODE)
447 return 0;
448 return 1;
449 }
3e47e7b4
P
450 if (cipher == NULL)
451 return 0;
452 keylen = EVP_CIPHER_key_length(cipher);
453 if ((EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_GET_WRAP_CIPHER) != 0) {
41bbba53 454 /* TODO: make this not get a method we can call directly */
71434aed
DB
455 ret = EVP_CIPHER_meth_get_ctrl(cipher)(NULL, EVP_CTRL_GET_WRAP_CIPHER,
456 0, &kekcipher);
457 if (ret <= 0)
458 return 0;
459
460 if (kekcipher != NULL) {
461 if (EVP_CIPHER_mode(kekcipher) != EVP_CIPH_WRAP_MODE)
462 return 0;
c1669f41
SL
463 kekcipher_name = EVP_CIPHER_name(kekcipher);
464 goto enc;
71434aed
DB
465 }
466 }
467
0f113f3e
MC
468 /*
469 * Pick a cipher based on content encryption cipher. If it is DES3 use
470 * DES3 wrap otherwise use AES wrap similar to key size.
471 */
96bea000 472#ifndef OPENSSL_NO_DES
0f113f3e 473 if (EVP_CIPHER_type(cipher) == NID_des_ede3_cbc)
c1669f41 474 kekcipher_name = SN_id_smime_alg_CMS3DESwrap;
96bea000
MC
475 else
476#endif
477 if (keylen <= 16)
c1669f41 478 kekcipher_name = SN_id_aes128_wrap;
0f113f3e 479 else if (keylen <= 24)
c1669f41 480 kekcipher_name = SN_id_aes192_wrap;
0f113f3e 481 else
c1669f41
SL
482 kekcipher_name = SN_id_aes256_wrap;
483enc:
484 fetched_kekcipher = EVP_CIPHER_fetch(cms_ctx->libctx, kekcipher_name,
485 cms_ctx->propq);
486 if (fetched_kekcipher == NULL)
487 return 0;
488 ret = EVP_EncryptInit_ex(ctx, fetched_kekcipher, NULL, NULL, NULL);
489 EVP_CIPHER_free(fetched_kekcipher);
490 return ret;
0f113f3e 491}
17c2764d
DSH
492
493/* Encrypt content key in key agreement recipient info */
494
9fdcc21f 495int cms_RecipientInfo_kari_encrypt(const CMS_ContentInfo *cms,
0f113f3e
MC
496 CMS_RecipientInfo *ri)
497{
498 CMS_KeyAgreeRecipientInfo *kari;
499 CMS_EncryptedContentInfo *ec;
500 CMS_RecipientEncryptedKey *rek;
501 STACK_OF(CMS_RecipientEncryptedKey) *reks;
502 int i;
503
aec8de1a
RL
504 {
505 /*
506 * TODO(3.0) Remove this when we have figured out all the details
507 * need to set up encryption right. With legacy keys, a *lot* is
508 * happening in the CMS specific EVP_PKEY_ASN1_METHOD functions,
509 * such as automatically setting a default KDF type, KDF digest,
510 * all that kind of stuff.
511 * With EVP_SIGNATURE, setting a default digest is done by getting
512 * the default MD for the key, and then inject that back into the
513 * signature implementation... we could do something similar with
514 * CMS, possibly using CMS specific OSSL_PARAM keys, just like we
515 * have for certain AlgorithmIdentifier retrievals.
516 *
517 * THIS IS TEMPORARY
518 */
519 EVP_PKEY_CTX *pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
520 EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx);
521
522 EVP_PKEY_get0(pkey);
523 if (EVP_PKEY_id(pkey) == EVP_PKEY_NONE) {
524 CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_ENCRYPT,
525 CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
526 return 0;
527 }
528 }
529
0f113f3e
MC
530 if (ri->type != CMS_RECIPINFO_AGREE) {
531 CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_ENCRYPT, CMS_R_NOT_KEY_AGREEMENT);
532 return 0;
533 }
534 kari = ri->d.kari;
535 reks = kari->recipientEncryptedKeys;
924663c3 536 ec = cms_get0_env_enc_content(cms);
0f113f3e
MC
537 /* Initialise wrap algorithm parameters */
538 if (!cms_wrap_init(kari, ec->cipher))
539 return 0;
540 /*
0d4fb843 541 * If no originator key set up initialise for ephemeral key the public key
0f113f3e
MC
542 * ASN1 structure will set the actual public key value.
543 */
544 if (kari->originator->type == -1) {
545 CMS_OriginatorIdentifierOrKey *oik = kari->originator;
546 oik->type = CMS_OIK_PUBKEY;
547 oik->d.originatorKey = M_ASN1_new_of(CMS_OriginatorPublicKey);
548 if (!oik->d.originatorKey)
549 return 0;
550 }
551 /* Initialise KDF algorithm */
552 if (!cms_env_asn1_ctrl(ri, 0))
553 return 0;
554 /* For each rek, derive KEK, encrypt CEK */
555 for (i = 0; i < sk_CMS_RecipientEncryptedKey_num(reks); i++) {
556 unsigned char *enckey;
557 size_t enckeylen;
558 rek = sk_CMS_RecipientEncryptedKey_value(reks, i);
559 if (EVP_PKEY_derive_set_peer(kari->pctx, rek->pkey) <= 0)
560 return 0;
561 if (!cms_kek_cipher(&enckey, &enckeylen, ec->key, ec->keylen,
562 kari, 1))
563 return 0;
564 ASN1_STRING_set0(rek->encryptedKey, enckey, enckeylen);
565 }
566
567 return 1;
0f113f3e 568}