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