1 /*
2 * Copyright 2013-2025 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
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
8 */
9
10 #include "internal/cryptlib.h"
11 #include <openssl/asn1t.h>
12 #include <openssl/pem.h>
13 #include <openssl/x509v3.h>
14 #include <openssl/err.h>
15 #include <openssl/cms.h>
16 #include <openssl/aes.h>
17 #include "cms_local.h"
18 #include "crypto/asn1.h"
19
20 /* Key Agreement Recipient Info (KARI) routines */
21
CMS_RecipientInfo_kari_get0_alg(CMS_RecipientInfo * ri,X509_ALGOR ** palg,ASN1_OCTET_STRING ** pukm)22 int CMS_RecipientInfo_kari_get0_alg(CMS_RecipientInfo *ri,
23 X509_ALGOR **palg,
24 ASN1_OCTET_STRING **pukm)
25 {
26 if (ri->type != CMS_RECIPINFO_AGREE) {
27 ERR_raise(ERR_LIB_CMS, CMS_R_NOT_KEY_AGREEMENT);
28 return 0;
29 }
30 if (palg)
31 *palg = ri->d.kari->keyEncryptionAlgorithm;
32 if (pukm)
33 *pukm = ri->d.kari->ukm;
34 return 1;
35 }
36
37 /* Retrieve recipient encrypted keys from a kari */
38
STACK_OF(CMS_RecipientEncryptedKey)39 STACK_OF(CMS_RecipientEncryptedKey)
40 *CMS_RecipientInfo_kari_get0_reks(CMS_RecipientInfo *ri)
41 {
42 if (ri->type != CMS_RECIPINFO_AGREE) {
43 ERR_raise(ERR_LIB_CMS, CMS_R_NOT_KEY_AGREEMENT);
44 return NULL;
45 }
46 return ri->d.kari->recipientEncryptedKeys;
47 }
48
CMS_RecipientInfo_kari_get0_orig_id(CMS_RecipientInfo * ri,X509_ALGOR ** pubalg,ASN1_BIT_STRING ** pubkey,ASN1_OCTET_STRING ** keyid,X509_NAME ** issuer,ASN1_INTEGER ** sno)49 int CMS_RecipientInfo_kari_get0_orig_id(CMS_RecipientInfo *ri,
50 X509_ALGOR **pubalg,
51 ASN1_BIT_STRING **pubkey,
52 ASN1_OCTET_STRING **keyid,
53 X509_NAME **issuer,
54 ASN1_INTEGER **sno)
55 {
56 CMS_OriginatorIdentifierOrKey *oik;
57
58 if (ri->type != CMS_RECIPINFO_AGREE) {
59 ERR_raise(ERR_LIB_CMS, CMS_R_NOT_KEY_AGREEMENT);
60 return 0;
61 }
62 oik = ri->d.kari->originator;
63 if (issuer)
64 *issuer = NULL;
65 if (sno)
66 *sno = NULL;
67 if (keyid)
68 *keyid = NULL;
69 if (pubalg)
70 *pubalg = NULL;
71 if (pubkey)
72 *pubkey = NULL;
73 if (oik->type == CMS_OIK_ISSUER_SERIAL) {
74 if (issuer)
75 *issuer = oik->d.issuerAndSerialNumber->issuer;
76 if (sno)
77 *sno = oik->d.issuerAndSerialNumber->serialNumber;
78 } else if (oik->type == CMS_OIK_KEYIDENTIFIER) {
79 if (keyid)
80 *keyid = oik->d.subjectKeyIdentifier;
81 } else if (oik->type == CMS_OIK_PUBKEY) {
82 if (pubalg)
83 *pubalg = oik->d.originatorKey->algorithm;
84 if (pubkey)
85 *pubkey = oik->d.originatorKey->publicKey;
86 } else
87 return 0;
88 return 1;
89 }
90
CMS_RecipientInfo_kari_orig_id_cmp(CMS_RecipientInfo * ri,X509 * cert)91 int CMS_RecipientInfo_kari_orig_id_cmp(CMS_RecipientInfo *ri, X509 *cert)
92 {
93 CMS_OriginatorIdentifierOrKey *oik;
94
95 if (ri->type != CMS_RECIPINFO_AGREE) {
96 ERR_raise(ERR_LIB_CMS, CMS_R_NOT_KEY_AGREEMENT);
97 return -2;
98 }
99 oik = ri->d.kari->originator;
100 if (oik->type == CMS_OIK_ISSUER_SERIAL)
101 return ossl_cms_ias_cert_cmp(oik->d.issuerAndSerialNumber, cert);
102 else if (oik->type == CMS_OIK_KEYIDENTIFIER)
103 return ossl_cms_keyid_cert_cmp(oik->d.subjectKeyIdentifier, cert);
104 return -1;
105 }
106
CMS_RecipientEncryptedKey_get0_id(CMS_RecipientEncryptedKey * rek,ASN1_OCTET_STRING ** keyid,ASN1_GENERALIZEDTIME ** tm,CMS_OtherKeyAttribute ** other,X509_NAME ** issuer,ASN1_INTEGER ** sno)107 int CMS_RecipientEncryptedKey_get0_id(CMS_RecipientEncryptedKey *rek,
108 ASN1_OCTET_STRING **keyid,
109 ASN1_GENERALIZEDTIME **tm,
110 CMS_OtherKeyAttribute **other,
111 X509_NAME **issuer, ASN1_INTEGER **sno)
112 {
113 CMS_KeyAgreeRecipientIdentifier *rid = rek->rid;
114
115 if (rid->type == CMS_REK_ISSUER_SERIAL) {
116 if (issuer)
117 *issuer = rid->d.issuerAndSerialNumber->issuer;
118 if (sno)
119 *sno = rid->d.issuerAndSerialNumber->serialNumber;
120 if (keyid)
121 *keyid = NULL;
122 if (tm)
123 *tm = NULL;
124 if (other)
125 *other = NULL;
126 } else if (rid->type == CMS_REK_KEYIDENTIFIER) {
127 if (keyid)
128 *keyid = rid->d.rKeyId->subjectKeyIdentifier;
129 if (tm)
130 *tm = rid->d.rKeyId->date;
131 if (other)
132 *other = rid->d.rKeyId->other;
133 if (issuer)
134 *issuer = NULL;
135 if (sno)
136 *sno = NULL;
137 } else
138 return 0;
139 return 1;
140 }
141
CMS_RecipientEncryptedKey_cert_cmp(CMS_RecipientEncryptedKey * rek,X509 * cert)142 int CMS_RecipientEncryptedKey_cert_cmp(CMS_RecipientEncryptedKey *rek,
143 X509 *cert)
144 {
145 CMS_KeyAgreeRecipientIdentifier *rid = rek->rid;
146
147 if (rid->type == CMS_REK_ISSUER_SERIAL)
148 return ossl_cms_ias_cert_cmp(rid->d.issuerAndSerialNumber, cert);
149 else if (rid->type == CMS_REK_KEYIDENTIFIER)
150 return ossl_cms_keyid_cert_cmp(rid->d.rKeyId->subjectKeyIdentifier,
151 cert);
152 else
153 return -1;
154 }
155
CMS_RecipientInfo_kari_set0_pkey_and_peer(CMS_RecipientInfo * ri,EVP_PKEY * pk,X509 * peer)156 int CMS_RecipientInfo_kari_set0_pkey_and_peer(CMS_RecipientInfo *ri,
157 EVP_PKEY *pk, X509 *peer)
158 {
159 EVP_PKEY_CTX *pctx;
160 CMS_KeyAgreeRecipientInfo *kari = ri->d.kari;
161
162 EVP_PKEY_CTX_free(kari->pctx);
163 kari->pctx = NULL;
164 if (pk == NULL)
165 return 1;
166
167 pctx = EVP_PKEY_CTX_new_from_pkey(ossl_cms_ctx_get0_libctx(kari->cms_ctx),
168 pk,
169 ossl_cms_ctx_get0_propq(kari->cms_ctx));
170 if (pctx == NULL || EVP_PKEY_derive_init(pctx) <= 0)
171 goto err;
172
173 if (peer != NULL) {
174 EVP_PKEY *pub_pkey = X509_get0_pubkey(peer);
175
176 if (EVP_PKEY_derive_set_peer(pctx, pub_pkey) <= 0)
177 goto err;
178 }
179
180 kari->pctx = pctx;
181 return 1;
182 err:
183 EVP_PKEY_CTX_free(pctx);
184 return 0;
185 }
186
CMS_RecipientInfo_kari_set0_pkey(CMS_RecipientInfo * ri,EVP_PKEY * pk)187 int CMS_RecipientInfo_kari_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pk)
188 {
189 return CMS_RecipientInfo_kari_set0_pkey_and_peer(ri, pk, NULL);
190 }
191
CMS_RecipientInfo_kari_get0_ctx(CMS_RecipientInfo * ri)192 EVP_CIPHER_CTX *CMS_RecipientInfo_kari_get0_ctx(CMS_RecipientInfo *ri)
193 {
194 if (ri->type == CMS_RECIPINFO_AGREE)
195 return ri->d.kari->ctx;
196 return NULL;
197 }
198
199 /*
200 * Derive KEK and decrypt/encrypt with it to produce either the original CEK
201 * or the encrypted CEK.
202 */
203
cms_kek_cipher(unsigned char ** pout,size_t * poutlen,const unsigned char * in,size_t inlen,CMS_KeyAgreeRecipientInfo * kari,int enc)204 static int cms_kek_cipher(unsigned char **pout, size_t *poutlen,
205 const unsigned char *in, size_t inlen,
206 CMS_KeyAgreeRecipientInfo *kari, int enc)
207 {
208 /* Key encryption key */
209 unsigned char kek[EVP_MAX_KEY_LENGTH];
210 size_t keklen;
211 int rv = 0;
212 unsigned char *out = NULL;
213 int outlen;
214
215 keklen = EVP_CIPHER_CTX_get_key_length(kari->ctx);
216 if (keklen > EVP_MAX_KEY_LENGTH || inlen > INT_MAX)
217 return 0;
218 /* Derive KEK */
219 if (EVP_PKEY_derive(kari->pctx, kek, &keklen) <= 0)
220 goto err;
221 /* Set KEK in context */
222 if (!EVP_CipherInit_ex(kari->ctx, NULL, NULL, kek, NULL, enc))
223 goto err;
224 /* obtain output length of ciphered key */
225 if (!EVP_CipherUpdate(kari->ctx, NULL, &outlen, in, (int)inlen))
226 goto err;
227 out = OPENSSL_malloc(outlen);
228 if (out == NULL)
229 goto err;
230 if (!EVP_CipherUpdate(kari->ctx, out, &outlen, in, (int)inlen))
231 goto err;
232 *pout = out;
233 *poutlen = (size_t)outlen;
234 rv = 1;
235
236 err:
237 OPENSSL_cleanse(kek, keklen);
238 if (!rv)
239 OPENSSL_free(out);
240 EVP_CIPHER_CTX_reset(kari->ctx);
241 /* FIXME: WHY IS kari->pctx freed here? /RL */
242 EVP_PKEY_CTX_free(kari->pctx);
243 kari->pctx = NULL;
244 return rv;
245 }
246
CMS_RecipientInfo_kari_decrypt(CMS_ContentInfo * cms,CMS_RecipientInfo * ri,CMS_RecipientEncryptedKey * rek)247 int CMS_RecipientInfo_kari_decrypt(CMS_ContentInfo *cms,
248 CMS_RecipientInfo *ri,
249 CMS_RecipientEncryptedKey *rek)
250 {
251 int rv = 0;
252 unsigned char *enckey = NULL, *cek = NULL;
253 size_t enckeylen;
254 size_t ceklen;
255 CMS_EncryptedContentInfo *ec;
256
257 enckeylen = rek->encryptedKey->length;
258 enckey = rek->encryptedKey->data;
259 /* Setup all parameters to derive KEK */
260 if (!ossl_cms_env_asn1_ctrl(ri, 1))
261 goto err;
262 /* Attempt to decrypt CEK */
263 if (!cms_kek_cipher(&cek, &ceklen, enckey, enckeylen, ri->d.kari, 0))
264 goto err;
265 ec = ossl_cms_get0_env_enc_content(cms);
266 OPENSSL_clear_free(ec->key, ec->keylen);
267 ec->key = cek;
268 ec->keylen = ceklen;
269 cek = NULL;
270 rv = 1;
271 err:
272 OPENSSL_free(cek);
273 return rv;
274 }
275
276 /* Create ephemeral key and initialise context based on it */
cms_kari_create_ephemeral_key(CMS_KeyAgreeRecipientInfo * kari,EVP_PKEY * pk)277 static int cms_kari_create_ephemeral_key(CMS_KeyAgreeRecipientInfo *kari,
278 EVP_PKEY *pk)
279 {
280 EVP_PKEY_CTX *pctx = NULL;
281 EVP_PKEY *ekey = NULL;
282 int rv = 0;
283 const CMS_CTX *ctx = kari->cms_ctx;
284 OSSL_LIB_CTX *libctx = ossl_cms_ctx_get0_libctx(ctx);
285 const char *propq = ossl_cms_ctx_get0_propq(ctx);
286
287 pctx = EVP_PKEY_CTX_new_from_pkey(libctx, pk, propq);
288 if (pctx == NULL)
289 goto err;
290 if (EVP_PKEY_keygen_init(pctx) <= 0)
291 goto err;
292 if (EVP_PKEY_keygen(pctx, &ekey) <= 0)
293 goto err;
294 EVP_PKEY_CTX_free(pctx);
295 pctx = EVP_PKEY_CTX_new_from_pkey(libctx, ekey, propq);
296 if (pctx == NULL)
297 goto err;
298 if (EVP_PKEY_derive_init(pctx) <= 0)
299 goto err;
300 kari->pctx = pctx;
301 rv = 1;
302 err:
303 if (!rv)
304 EVP_PKEY_CTX_free(pctx);
305 EVP_PKEY_free(ekey);
306 return rv;
307 }
308
309 /* Set originator private key and initialise context based on it */
cms_kari_set_originator_private_key(CMS_KeyAgreeRecipientInfo * kari,EVP_PKEY * originatorPrivKey)310 static int cms_kari_set_originator_private_key(CMS_KeyAgreeRecipientInfo *kari,
311 EVP_PKEY *originatorPrivKey )
312 {
313 EVP_PKEY_CTX *pctx = NULL;
314 int rv = 0;
315 const CMS_CTX *ctx = kari->cms_ctx;
316
317 pctx = EVP_PKEY_CTX_new_from_pkey(ossl_cms_ctx_get0_libctx(ctx),
318 originatorPrivKey,
319 ossl_cms_ctx_get0_propq(ctx));
320 if (pctx == NULL)
321 goto err;
322 if (EVP_PKEY_derive_init(pctx) <= 0)
323 goto err;
324
325 kari->pctx = pctx;
326 rv = 1;
327 err:
328 if (rv == 0)
329 EVP_PKEY_CTX_free(pctx);
330 return rv;
331 }
332
333 /* Initialise a kari based on passed certificate and key */
334
ossl_cms_RecipientInfo_kari_init(CMS_RecipientInfo * ri,X509 * recip,EVP_PKEY * recipPubKey,X509 * originator,EVP_PKEY * originatorPrivKey,unsigned int flags,const CMS_CTX * ctx)335 int ossl_cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip,
336 EVP_PKEY *recipPubKey, X509 *originator,
337 EVP_PKEY *originatorPrivKey,
338 unsigned int flags, const CMS_CTX *ctx)
339 {
340 CMS_KeyAgreeRecipientInfo *kari;
341 CMS_RecipientEncryptedKey *rek = NULL;
342
343 ri->d.kari = M_ASN1_new_of(CMS_KeyAgreeRecipientInfo);
344 if (ri->d.kari == NULL)
345 return 0;
346 ri->encoded_type = ri->type = CMS_RECIPINFO_AGREE;
347
348 kari = ri->d.kari;
349 kari->version = 3;
350 kari->cms_ctx = ctx;
351
352 rek = M_ASN1_new_of(CMS_RecipientEncryptedKey);
353 if (rek == NULL)
354 return 0;
355
356 if (!sk_CMS_RecipientEncryptedKey_push(kari->recipientEncryptedKeys, rek)) {
357 M_ASN1_free_of(rek, CMS_RecipientEncryptedKey);
358 return 0;
359 }
360
361 if (flags & CMS_USE_KEYID) {
362 rek->rid->type = CMS_REK_KEYIDENTIFIER;
363 rek->rid->d.rKeyId = M_ASN1_new_of(CMS_RecipientKeyIdentifier);
364 if (rek->rid->d.rKeyId == NULL)
365 return 0;
366 if (!ossl_cms_set1_keyid(&rek->rid->d.rKeyId->subjectKeyIdentifier, recip))
367 return 0;
368 } else {
369 rek->rid->type = CMS_REK_ISSUER_SERIAL;
370 if (!ossl_cms_set1_ias(&rek->rid->d.issuerAndSerialNumber, recip))
371 return 0;
372 }
373
374 if (originatorPrivKey == NULL && originator == NULL) {
375 /* Create ephemeral key */
376 if (!cms_kari_create_ephemeral_key(kari, recipPubKey))
377 return 0;
378 } else {
379 /* Use originator key */
380 CMS_OriginatorIdentifierOrKey *oik = ri->d.kari->originator;
381
382 if (originatorPrivKey == NULL || originator == NULL)
383 return 0;
384
385 if (flags & CMS_USE_ORIGINATOR_KEYID) {
386 oik->type = CMS_OIK_KEYIDENTIFIER;
387 oik->d.subjectKeyIdentifier = ASN1_OCTET_STRING_new();
388 if (oik->d.subjectKeyIdentifier == NULL)
389 return 0;
390 if (!ossl_cms_set1_keyid(&oik->d.subjectKeyIdentifier, originator))
391 return 0;
392 } else {
393 oik->type = CMS_REK_ISSUER_SERIAL;
394 if (!ossl_cms_set1_ias(&oik->d.issuerAndSerialNumber, originator))
395 return 0;
396 }
397
398 if (!cms_kari_set_originator_private_key(kari, originatorPrivKey))
399 return 0;
400 }
401
402 if (!EVP_PKEY_up_ref(recipPubKey))
403 return 0;
404
405 rek->pkey = recipPubKey;
406 return 1;
407 }
408
409 /* Encrypt content key in key agreement recipient info */
410
ossl_cms_RecipientInfo_kari_encrypt(const CMS_ContentInfo * cms,CMS_RecipientInfo * ri)411 int ossl_cms_RecipientInfo_kari_encrypt(const CMS_ContentInfo *cms,
412 CMS_RecipientInfo *ri)
413 {
414 CMS_KeyAgreeRecipientInfo *kari;
415 CMS_EncryptedContentInfo *ec;
416 CMS_RecipientEncryptedKey *rek;
417 STACK_OF(CMS_RecipientEncryptedKey) *reks;
418 int i;
419
420 if (ri->type != CMS_RECIPINFO_AGREE) {
421 ERR_raise(ERR_LIB_CMS, CMS_R_NOT_KEY_AGREEMENT);
422 return 0;
423 }
424 kari = ri->d.kari;
425 reks = kari->recipientEncryptedKeys;
426 ec = ossl_cms_get0_env_enc_content(cms);
427 /* Initialise wrap algorithm parameters */
428 if (!ossl_cms_RecipientInfo_wrap_init(ri, ec->cipher))
429 return 0;
430 /*
431 * If no originator key set up initialise for ephemeral key the public key
432 * ASN1 structure will set the actual public key value.
433 */
434 if (kari->originator->type == -1) {
435 CMS_OriginatorIdentifierOrKey *oik = kari->originator;
436 oik->type = CMS_OIK_PUBKEY;
437 oik->d.originatorKey = M_ASN1_new_of(CMS_OriginatorPublicKey);
438 if (!oik->d.originatorKey)
439 return 0;
440 } else {
441 /*
442 * Currently it is not possible to get public key as it is not stored
443 * during kari initialization.
444 */
445 ERR_raise(ERR_LIB_CMS, CMS_R_ERROR_UNSUPPORTED_STATIC_KEY_AGREEMENT);
446 return 0;
447 }
448 /* Initialise KDF algorithm */
449 if (!ossl_cms_env_asn1_ctrl(ri, 0))
450 return 0;
451 /* For each rek, derive KEK, encrypt CEK */
452 for (i = 0; i < sk_CMS_RecipientEncryptedKey_num(reks); i++) {
453 unsigned char *enckey;
454 size_t enckeylen;
455 rek = sk_CMS_RecipientEncryptedKey_value(reks, i);
456 if (EVP_PKEY_derive_set_peer(kari->pctx, rek->pkey) <= 0)
457 return 0;
458 if (!cms_kek_cipher(&enckey, &enckeylen, ec->key, ec->keylen,
459 kari, 1))
460 return 0;
461 ASN1_STRING_set0(rek->encryptedKey, enckey, (int)enckeylen);
462 }
463
464 return 1;
465 }
466