Line data Source code
1 : /* crypto/cms/cms_env.c */
2 : /*
3 : * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
4 : * project.
5 : */
6 : /* ====================================================================
7 : * Copyright (c) 2008 The OpenSSL Project. All rights reserved.
8 : *
9 : * Redistribution and use in source and binary forms, with or without
10 : * modification, are permitted provided that the following conditions
11 : * are met:
12 : *
13 : * 1. Redistributions of source code must retain the above copyright
14 : * notice, this list of conditions and the following disclaimer.
15 : *
16 : * 2. Redistributions in binary form must reproduce the above copyright
17 : * notice, this list of conditions and the following disclaimer in
18 : * the documentation and/or other materials provided with the
19 : * distribution.
20 : *
21 : * 3. All advertising materials mentioning features or use of this
22 : * software must display the following acknowledgment:
23 : * "This product includes software developed by the OpenSSL Project
24 : * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25 : *
26 : * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27 : * endorse or promote products derived from this software without
28 : * prior written permission. For written permission, please contact
29 : * licensing@OpenSSL.org.
30 : *
31 : * 5. Products derived from this software may not be called "OpenSSL"
32 : * nor may "OpenSSL" appear in their names without prior written
33 : * permission of the OpenSSL Project.
34 : *
35 : * 6. Redistributions of any form whatsoever must retain the following
36 : * acknowledgment:
37 : * "This product includes software developed by the OpenSSL Project
38 : * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39 : *
40 : * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41 : * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43 : * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
44 : * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45 : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46 : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47 : * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49 : * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50 : * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51 : * OF THE POSSIBILITY OF SUCH DAMAGE.
52 : * ====================================================================
53 : */
54 :
55 : #include "cryptlib.h"
56 : #include <openssl/asn1t.h>
57 : #include <openssl/pem.h>
58 : #include <openssl/x509v3.h>
59 : #include <openssl/err.h>
60 : #include <openssl/cms.h>
61 : #include <openssl/rand.h>
62 : #include <openssl/aes.h>
63 : #include "cms_lcl.h"
64 : #include "asn1_locl.h"
65 :
66 : /* CMS EnvelopedData Utilities */
67 :
68 : DECLARE_ASN1_ITEM(CMS_EnvelopedData)
69 : DECLARE_ASN1_ITEM(CMS_KeyTransRecipientInfo)
70 : DECLARE_ASN1_ITEM(CMS_KEKRecipientInfo)
71 : DECLARE_ASN1_ITEM(CMS_OtherKeyAttribute)
72 :
73 : DECLARE_STACK_OF(CMS_RecipientInfo)
74 :
75 0 : CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms)
76 : {
77 0 : if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_enveloped) {
78 0 : CMSerr(CMS_F_CMS_GET0_ENVELOPED,
79 : CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA);
80 0 : return NULL;
81 : }
82 0 : return cms->d.envelopedData;
83 : }
84 :
85 0 : static CMS_EnvelopedData *cms_enveloped_data_init(CMS_ContentInfo *cms)
86 : {
87 0 : if (cms->d.other == NULL) {
88 0 : cms->d.envelopedData = M_ASN1_new_of(CMS_EnvelopedData);
89 0 : if (!cms->d.envelopedData) {
90 0 : CMSerr(CMS_F_CMS_ENVELOPED_DATA_INIT, ERR_R_MALLOC_FAILURE);
91 0 : return NULL;
92 : }
93 0 : cms->d.envelopedData->version = 0;
94 0 : cms->d.envelopedData->encryptedContentInfo->contentType =
95 0 : OBJ_nid2obj(NID_pkcs7_data);
96 0 : ASN1_OBJECT_free(cms->contentType);
97 0 : cms->contentType = OBJ_nid2obj(NID_pkcs7_enveloped);
98 0 : return cms->d.envelopedData;
99 : }
100 0 : return cms_get0_enveloped(cms);
101 : }
102 :
103 0 : int cms_env_asn1_ctrl(CMS_RecipientInfo *ri, int cmd)
104 : {
105 : EVP_PKEY *pkey;
106 : int i;
107 0 : if (ri->type == CMS_RECIPINFO_TRANS)
108 0 : pkey = ri->d.ktri->pkey;
109 0 : else if (ri->type == CMS_RECIPINFO_AGREE) {
110 0 : EVP_PKEY_CTX *pctx = ri->d.kari->pctx;
111 0 : if (!pctx)
112 : return 0;
113 0 : pkey = EVP_PKEY_CTX_get0_pkey(pctx);
114 0 : if (!pkey)
115 : return 0;
116 : } else
117 : return 0;
118 0 : if (!pkey->ameth || !pkey->ameth->pkey_ctrl)
119 : return 1;
120 0 : i = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_CMS_ENVELOPE, cmd, ri);
121 0 : if (i == -2) {
122 0 : CMSerr(CMS_F_CMS_ENV_ASN1_CTRL,
123 : CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
124 0 : return 0;
125 : }
126 0 : if (i <= 0) {
127 0 : CMSerr(CMS_F_CMS_ENV_ASN1_CTRL, CMS_R_CTRL_FAILURE);
128 0 : return 0;
129 : }
130 : return 1;
131 : }
132 :
133 0 : STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms)
134 : {
135 : CMS_EnvelopedData *env;
136 0 : env = cms_get0_enveloped(cms);
137 0 : if (!env)
138 : return NULL;
139 0 : return env->recipientInfos;
140 : }
141 :
142 0 : int CMS_RecipientInfo_type(CMS_RecipientInfo *ri)
143 : {
144 0 : return ri->type;
145 : }
146 :
147 0 : EVP_PKEY_CTX *CMS_RecipientInfo_get0_pkey_ctx(CMS_RecipientInfo *ri)
148 : {
149 0 : if (ri->type == CMS_RECIPINFO_TRANS)
150 0 : return ri->d.ktri->pctx;
151 0 : else if (ri->type == CMS_RECIPINFO_AGREE)
152 0 : return ri->d.kari->pctx;
153 : return NULL;
154 : }
155 :
156 0 : CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher)
157 : {
158 : CMS_ContentInfo *cms;
159 : CMS_EnvelopedData *env;
160 0 : cms = CMS_ContentInfo_new();
161 0 : if (!cms)
162 : goto merr;
163 0 : env = cms_enveloped_data_init(cms);
164 0 : if (!env)
165 : goto merr;
166 0 : if (!cms_EncryptedContent_init(env->encryptedContentInfo,
167 : cipher, NULL, 0))
168 : goto merr;
169 : return cms;
170 : merr:
171 0 : if (cms)
172 0 : CMS_ContentInfo_free(cms);
173 0 : CMSerr(CMS_F_CMS_ENVELOPEDDATA_CREATE, ERR_R_MALLOC_FAILURE);
174 0 : return NULL;
175 : }
176 :
177 : /* Key Transport Recipient Info (KTRI) routines */
178 :
179 : /* Initialise a ktri based on passed certificate and key */
180 :
181 0 : static int cms_RecipientInfo_ktri_init(CMS_RecipientInfo *ri, X509 *recip,
182 : EVP_PKEY *pk, unsigned int flags)
183 : {
184 : CMS_KeyTransRecipientInfo *ktri;
185 : int idtype;
186 :
187 0 : ri->d.ktri = M_ASN1_new_of(CMS_KeyTransRecipientInfo);
188 0 : if (!ri->d.ktri)
189 : return 0;
190 0 : ri->type = CMS_RECIPINFO_TRANS;
191 :
192 : ktri = ri->d.ktri;
193 :
194 0 : if (flags & CMS_USE_KEYID) {
195 0 : ktri->version = 2;
196 : idtype = CMS_RECIPINFO_KEYIDENTIFIER;
197 : } else {
198 0 : ktri->version = 0;
199 : idtype = CMS_RECIPINFO_ISSUER_SERIAL;
200 : }
201 :
202 : /*
203 : * Not a typo: RecipientIdentifier and SignerIdentifier are the same
204 : * structure.
205 : */
206 :
207 0 : if (!cms_set1_SignerIdentifier(ktri->rid, recip, idtype))
208 : return 0;
209 :
210 0 : CRYPTO_add(&recip->references, 1, CRYPTO_LOCK_X509);
211 0 : CRYPTO_add(&pk->references, 1, CRYPTO_LOCK_EVP_PKEY);
212 0 : ktri->pkey = pk;
213 0 : ktri->recip = recip;
214 :
215 0 : if (flags & CMS_KEY_PARAM) {
216 0 : ktri->pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL);
217 0 : if (!ktri->pctx)
218 : return 0;
219 0 : if (EVP_PKEY_encrypt_init(ktri->pctx) <= 0)
220 : return 0;
221 0 : } else if (!cms_env_asn1_ctrl(ri, 0))
222 : return 0;
223 : return 1;
224 : }
225 :
226 : /*
227 : * Add a recipient certificate using appropriate type of RecipientInfo
228 : */
229 :
230 0 : CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms,
231 : X509 *recip, unsigned int flags)
232 : {
233 : CMS_RecipientInfo *ri = NULL;
234 : CMS_EnvelopedData *env;
235 : EVP_PKEY *pk = NULL;
236 0 : env = cms_get0_enveloped(cms);
237 0 : if (!env)
238 : goto err;
239 :
240 : /* Initialize recipient info */
241 0 : ri = M_ASN1_new_of(CMS_RecipientInfo);
242 0 : if (!ri)
243 : goto merr;
244 :
245 0 : pk = X509_get_pubkey(recip);
246 0 : if (!pk) {
247 0 : CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, CMS_R_ERROR_GETTING_PUBLIC_KEY);
248 0 : goto err;
249 : }
250 :
251 0 : switch (cms_pkey_get_ri_type(pk)) {
252 :
253 : case CMS_RECIPINFO_TRANS:
254 0 : if (!cms_RecipientInfo_ktri_init(ri, recip, pk, flags))
255 : goto err;
256 : break;
257 :
258 : case CMS_RECIPINFO_AGREE:
259 0 : if (!cms_RecipientInfo_kari_init(ri, recip, pk, flags))
260 : goto err;
261 : break;
262 :
263 : default:
264 0 : CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT,
265 : CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
266 0 : goto err;
267 :
268 : }
269 :
270 0 : if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri))
271 : goto merr;
272 :
273 0 : EVP_PKEY_free(pk);
274 :
275 0 : return ri;
276 :
277 : merr:
278 0 : CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, ERR_R_MALLOC_FAILURE);
279 : err:
280 0 : if (ri)
281 0 : M_ASN1_free_of(ri, CMS_RecipientInfo);
282 0 : if (pk)
283 0 : EVP_PKEY_free(pk);
284 : return NULL;
285 :
286 : }
287 :
288 0 : int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri,
289 : EVP_PKEY **pk, X509 **recip,
290 : X509_ALGOR **palg)
291 : {
292 : CMS_KeyTransRecipientInfo *ktri;
293 0 : if (ri->type != CMS_RECIPINFO_TRANS) {
294 0 : CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS,
295 : CMS_R_NOT_KEY_TRANSPORT);
296 0 : return 0;
297 : }
298 :
299 0 : ktri = ri->d.ktri;
300 :
301 0 : if (pk)
302 0 : *pk = ktri->pkey;
303 0 : if (recip)
304 0 : *recip = ktri->recip;
305 0 : if (palg)
306 0 : *palg = ktri->keyEncryptionAlgorithm;
307 : return 1;
308 : }
309 :
310 0 : int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri,
311 : ASN1_OCTET_STRING **keyid,
312 : X509_NAME **issuer,
313 : ASN1_INTEGER **sno)
314 : {
315 : CMS_KeyTransRecipientInfo *ktri;
316 0 : if (ri->type != CMS_RECIPINFO_TRANS) {
317 0 : CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID,
318 : CMS_R_NOT_KEY_TRANSPORT);
319 0 : return 0;
320 : }
321 0 : ktri = ri->d.ktri;
322 :
323 0 : return cms_SignerIdentifier_get0_signer_id(ktri->rid, keyid, issuer, sno);
324 : }
325 :
326 0 : int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert)
327 : {
328 0 : if (ri->type != CMS_RECIPINFO_TRANS) {
329 0 : CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP,
330 : CMS_R_NOT_KEY_TRANSPORT);
331 0 : return -2;
332 : }
333 0 : return cms_SignerIdentifier_cert_cmp(ri->d.ktri->rid, cert);
334 : }
335 :
336 0 : int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey)
337 : {
338 0 : if (ri->type != CMS_RECIPINFO_TRANS) {
339 0 : CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_PKEY, CMS_R_NOT_KEY_TRANSPORT);
340 0 : return 0;
341 : }
342 0 : ri->d.ktri->pkey = pkey;
343 0 : return 1;
344 : }
345 :
346 : /* Encrypt content key in key transport recipient info */
347 :
348 0 : static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms,
349 : CMS_RecipientInfo *ri)
350 : {
351 : CMS_KeyTransRecipientInfo *ktri;
352 : CMS_EncryptedContentInfo *ec;
353 : EVP_PKEY_CTX *pctx;
354 : unsigned char *ek = NULL;
355 : size_t eklen;
356 :
357 : int ret = 0;
358 :
359 0 : if (ri->type != CMS_RECIPINFO_TRANS) {
360 0 : CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, CMS_R_NOT_KEY_TRANSPORT);
361 : return 0;
362 : }
363 0 : ktri = ri->d.ktri;
364 0 : ec = cms->d.envelopedData->encryptedContentInfo;
365 :
366 0 : pctx = ktri->pctx;
367 :
368 0 : if (pctx) {
369 0 : if (!cms_env_asn1_ctrl(ri, 0))
370 : goto err;
371 : } else {
372 0 : pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL);
373 0 : if (!pctx)
374 : return 0;
375 :
376 0 : if (EVP_PKEY_encrypt_init(pctx) <= 0)
377 : goto err;
378 : }
379 :
380 0 : if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT,
381 : EVP_PKEY_CTRL_CMS_ENCRYPT, 0, ri) <= 0) {
382 0 : CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, CMS_R_CTRL_ERROR);
383 : goto err;
384 : }
385 :
386 0 : if (EVP_PKEY_encrypt(pctx, NULL, &eklen, ec->key, ec->keylen) <= 0)
387 : goto err;
388 :
389 0 : ek = OPENSSL_malloc(eklen);
390 :
391 0 : if (ek == NULL) {
392 0 : CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, ERR_R_MALLOC_FAILURE);
393 : goto err;
394 : }
395 :
396 0 : if (EVP_PKEY_encrypt(pctx, ek, &eklen, ec->key, ec->keylen) <= 0)
397 : goto err;
398 :
399 0 : ASN1_STRING_set0(ktri->encryptedKey, ek, eklen);
400 : ek = NULL;
401 :
402 : ret = 1;
403 :
404 : err:
405 0 : if (pctx) {
406 0 : EVP_PKEY_CTX_free(pctx);
407 0 : ktri->pctx = NULL;
408 : }
409 0 : if (ek)
410 0 : OPENSSL_free(ek);
411 : return ret;
412 :
413 : }
414 :
415 : /* Decrypt content key from KTRI */
416 :
417 0 : static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
418 : CMS_RecipientInfo *ri)
419 : {
420 0 : CMS_KeyTransRecipientInfo *ktri = ri->d.ktri;
421 0 : EVP_PKEY *pkey = ktri->pkey;
422 : unsigned char *ek = NULL;
423 : size_t eklen;
424 : int ret = 0;
425 : CMS_EncryptedContentInfo *ec;
426 0 : ec = cms->d.envelopedData->encryptedContentInfo;
427 :
428 0 : if (ktri->pkey == NULL) {
429 0 : CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_NO_PRIVATE_KEY);
430 : return 0;
431 : }
432 :
433 0 : ktri->pctx = EVP_PKEY_CTX_new(pkey, NULL);
434 0 : if (!ktri->pctx)
435 : return 0;
436 :
437 0 : if (EVP_PKEY_decrypt_init(ktri->pctx) <= 0)
438 : goto err;
439 :
440 0 : if (!cms_env_asn1_ctrl(ri, 1))
441 : goto err;
442 :
443 0 : if (EVP_PKEY_CTX_ctrl(ktri->pctx, -1, EVP_PKEY_OP_DECRYPT,
444 : EVP_PKEY_CTRL_CMS_DECRYPT, 0, ri) <= 0) {
445 0 : CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CTRL_ERROR);
446 : goto err;
447 : }
448 :
449 0 : if (EVP_PKEY_decrypt(ktri->pctx, NULL, &eklen,
450 0 : ktri->encryptedKey->data,
451 0 : ktri->encryptedKey->length) <= 0)
452 : goto err;
453 :
454 0 : ek = OPENSSL_malloc(eklen);
455 :
456 0 : if (ek == NULL) {
457 0 : CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, ERR_R_MALLOC_FAILURE);
458 : goto err;
459 : }
460 :
461 0 : if (EVP_PKEY_decrypt(ktri->pctx, ek, &eklen,
462 0 : ktri->encryptedKey->data,
463 0 : ktri->encryptedKey->length) <= 0) {
464 0 : CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CMS_LIB);
465 : goto err;
466 : }
467 :
468 : ret = 1;
469 :
470 0 : if (ec->key) {
471 0 : OPENSSL_cleanse(ec->key, ec->keylen);
472 0 : OPENSSL_free(ec->key);
473 : }
474 :
475 0 : ec->key = ek;
476 0 : ec->keylen = eklen;
477 :
478 : err:
479 0 : if (ktri->pctx) {
480 0 : EVP_PKEY_CTX_free(ktri->pctx);
481 0 : ktri->pctx = NULL;
482 : }
483 0 : if (!ret && ek)
484 0 : OPENSSL_free(ek);
485 :
486 : return ret;
487 : }
488 :
489 : /* Key Encrypted Key (KEK) RecipientInfo routines */
490 :
491 0 : int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri,
492 : const unsigned char *id, size_t idlen)
493 : {
494 : ASN1_OCTET_STRING tmp_os;
495 : CMS_KEKRecipientInfo *kekri;
496 0 : if (ri->type != CMS_RECIPINFO_KEK) {
497 0 : CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP, CMS_R_NOT_KEK);
498 0 : return -2;
499 : }
500 0 : kekri = ri->d.kekri;
501 0 : tmp_os.type = V_ASN1_OCTET_STRING;
502 0 : tmp_os.flags = 0;
503 0 : tmp_os.data = (unsigned char *)id;
504 0 : tmp_os.length = (int)idlen;
505 0 : return ASN1_OCTET_STRING_cmp(&tmp_os, kekri->kekid->keyIdentifier);
506 : }
507 :
508 : /* For now hard code AES key wrap info */
509 :
510 : static size_t aes_wrap_keylen(int nid)
511 : {
512 0 : switch (nid) {
513 : case NID_id_aes128_wrap:
514 : return 16;
515 :
516 : case NID_id_aes192_wrap:
517 : return 24;
518 :
519 : case NID_id_aes256_wrap:
520 : return 32;
521 :
522 : default:
523 : return 0;
524 : }
525 : }
526 :
527 0 : CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid,
528 : unsigned char *key, size_t keylen,
529 : unsigned char *id, size_t idlen,
530 : ASN1_GENERALIZEDTIME *date,
531 : ASN1_OBJECT *otherTypeId,
532 : ASN1_TYPE *otherType)
533 : {
534 : CMS_RecipientInfo *ri = NULL;
535 : CMS_EnvelopedData *env;
536 : CMS_KEKRecipientInfo *kekri;
537 0 : env = cms_get0_enveloped(cms);
538 0 : if (!env)
539 : goto err;
540 :
541 0 : if (nid == NID_undef) {
542 0 : switch (keylen) {
543 : case 16:
544 : nid = NID_id_aes128_wrap;
545 : break;
546 :
547 : case 24:
548 : nid = NID_id_aes192_wrap;
549 0 : break;
550 :
551 : case 32:
552 : nid = NID_id_aes256_wrap;
553 0 : break;
554 :
555 : default:
556 0 : CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, CMS_R_INVALID_KEY_LENGTH);
557 0 : goto err;
558 : }
559 :
560 : } else {
561 :
562 : size_t exp_keylen = aes_wrap_keylen(nid);
563 :
564 0 : if (!exp_keylen) {
565 0 : CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY,
566 : CMS_R_UNSUPPORTED_KEK_ALGORITHM);
567 0 : goto err;
568 : }
569 :
570 0 : if (keylen != exp_keylen) {
571 0 : CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, CMS_R_INVALID_KEY_LENGTH);
572 0 : goto err;
573 : }
574 :
575 : }
576 :
577 : /* Initialize recipient info */
578 0 : ri = M_ASN1_new_of(CMS_RecipientInfo);
579 0 : if (!ri)
580 : goto merr;
581 :
582 0 : ri->d.kekri = M_ASN1_new_of(CMS_KEKRecipientInfo);
583 0 : if (!ri->d.kekri)
584 : goto merr;
585 0 : ri->type = CMS_RECIPINFO_KEK;
586 :
587 : kekri = ri->d.kekri;
588 :
589 0 : if (otherTypeId) {
590 0 : kekri->kekid->other = M_ASN1_new_of(CMS_OtherKeyAttribute);
591 0 : if (kekri->kekid->other == NULL)
592 : goto merr;
593 : }
594 :
595 0 : if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri))
596 : goto merr;
597 :
598 : /* After this point no calls can fail */
599 :
600 0 : kekri->version = 4;
601 :
602 0 : kekri->key = key;
603 0 : kekri->keylen = keylen;
604 :
605 0 : ASN1_STRING_set0(kekri->kekid->keyIdentifier, id, idlen);
606 :
607 0 : kekri->kekid->date = date;
608 :
609 0 : if (kekri->kekid->other) {
610 0 : kekri->kekid->other->keyAttrId = otherTypeId;
611 0 : kekri->kekid->other->keyAttr = otherType;
612 : }
613 :
614 0 : X509_ALGOR_set0(kekri->keyEncryptionAlgorithm,
615 : OBJ_nid2obj(nid), V_ASN1_UNDEF, NULL);
616 :
617 0 : return ri;
618 :
619 : merr:
620 0 : CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, ERR_R_MALLOC_FAILURE);
621 : err:
622 0 : if (ri)
623 0 : M_ASN1_free_of(ri, CMS_RecipientInfo);
624 : return NULL;
625 :
626 : }
627 :
628 0 : int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri,
629 : X509_ALGOR **palg,
630 : ASN1_OCTET_STRING **pid,
631 : ASN1_GENERALIZEDTIME **pdate,
632 : ASN1_OBJECT **potherid,
633 : ASN1_TYPE **pothertype)
634 : {
635 : CMS_KEKIdentifier *rkid;
636 0 : if (ri->type != CMS_RECIPINFO_KEK) {
637 0 : CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID, CMS_R_NOT_KEK);
638 0 : return 0;
639 : }
640 0 : rkid = ri->d.kekri->kekid;
641 0 : if (palg)
642 0 : *palg = ri->d.kekri->keyEncryptionAlgorithm;
643 0 : if (pid)
644 0 : *pid = rkid->keyIdentifier;
645 0 : if (pdate)
646 0 : *pdate = rkid->date;
647 0 : if (potherid) {
648 0 : if (rkid->other)
649 0 : *potherid = rkid->other->keyAttrId;
650 : else
651 0 : *potherid = NULL;
652 : }
653 0 : if (pothertype) {
654 0 : if (rkid->other)
655 0 : *pothertype = rkid->other->keyAttr;
656 : else
657 0 : *pothertype = NULL;
658 : }
659 : return 1;
660 : }
661 :
662 0 : int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri,
663 : unsigned char *key, size_t keylen)
664 : {
665 : CMS_KEKRecipientInfo *kekri;
666 0 : if (ri->type != CMS_RECIPINFO_KEK) {
667 0 : CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_KEY, CMS_R_NOT_KEK);
668 0 : return 0;
669 : }
670 :
671 0 : kekri = ri->d.kekri;
672 0 : kekri->key = key;
673 0 : kekri->keylen = keylen;
674 0 : return 1;
675 : }
676 :
677 : /* Encrypt content key in KEK recipient info */
678 :
679 0 : static int cms_RecipientInfo_kekri_encrypt(CMS_ContentInfo *cms,
680 : CMS_RecipientInfo *ri)
681 : {
682 : CMS_EncryptedContentInfo *ec;
683 : CMS_KEKRecipientInfo *kekri;
684 : AES_KEY actx;
685 : unsigned char *wkey = NULL;
686 : int wkeylen;
687 : int r = 0;
688 :
689 0 : ec = cms->d.envelopedData->encryptedContentInfo;
690 :
691 0 : kekri = ri->d.kekri;
692 :
693 0 : if (!kekri->key) {
694 0 : CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_NO_KEY);
695 : return 0;
696 : }
697 :
698 0 : if (AES_set_encrypt_key(kekri->key, kekri->keylen << 3, &actx)) {
699 0 : CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT,
700 : CMS_R_ERROR_SETTING_KEY);
701 : goto err;
702 : }
703 :
704 0 : wkey = OPENSSL_malloc(ec->keylen + 8);
705 :
706 0 : if (!wkey) {
707 0 : CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, ERR_R_MALLOC_FAILURE);
708 : goto err;
709 : }
710 :
711 0 : wkeylen = AES_wrap_key(&actx, NULL, wkey, ec->key, ec->keylen);
712 :
713 0 : if (wkeylen <= 0) {
714 0 : CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_WRAP_ERROR);
715 : goto err;
716 : }
717 :
718 0 : ASN1_STRING_set0(kekri->encryptedKey, wkey, wkeylen);
719 :
720 : r = 1;
721 :
722 : err:
723 :
724 0 : if (!r && wkey)
725 0 : OPENSSL_free(wkey);
726 0 : OPENSSL_cleanse(&actx, sizeof(actx));
727 :
728 : return r;
729 :
730 : }
731 :
732 : /* Decrypt content key in KEK recipient info */
733 :
734 0 : static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms,
735 : CMS_RecipientInfo *ri)
736 : {
737 : CMS_EncryptedContentInfo *ec;
738 : CMS_KEKRecipientInfo *kekri;
739 : AES_KEY actx;
740 : unsigned char *ukey = NULL;
741 : int ukeylen;
742 : int r = 0, wrap_nid;
743 :
744 0 : ec = cms->d.envelopedData->encryptedContentInfo;
745 :
746 0 : kekri = ri->d.kekri;
747 :
748 0 : if (!kekri->key) {
749 0 : CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_NO_KEY);
750 : return 0;
751 : }
752 :
753 0 : wrap_nid = OBJ_obj2nid(kekri->keyEncryptionAlgorithm->algorithm);
754 0 : if (aes_wrap_keylen(wrap_nid) != kekri->keylen) {
755 0 : CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
756 : CMS_R_INVALID_KEY_LENGTH);
757 : return 0;
758 : }
759 :
760 : /* If encrypted key length is invalid don't bother */
761 :
762 0 : if (kekri->encryptedKey->length < 16) {
763 0 : CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
764 : CMS_R_INVALID_ENCRYPTED_KEY_LENGTH);
765 : goto err;
766 : }
767 :
768 0 : if (AES_set_decrypt_key(kekri->key, kekri->keylen << 3, &actx)) {
769 0 : CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
770 : CMS_R_ERROR_SETTING_KEY);
771 : goto err;
772 : }
773 :
774 0 : ukey = OPENSSL_malloc(kekri->encryptedKey->length - 8);
775 :
776 0 : if (!ukey) {
777 0 : CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, ERR_R_MALLOC_FAILURE);
778 : goto err;
779 : }
780 :
781 0 : ukeylen = AES_unwrap_key(&actx, NULL, ukey,
782 0 : kekri->encryptedKey->data,
783 0 : kekri->encryptedKey->length);
784 :
785 0 : if (ukeylen <= 0) {
786 0 : CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_UNWRAP_ERROR);
787 : goto err;
788 : }
789 :
790 0 : ec->key = ukey;
791 0 : ec->keylen = ukeylen;
792 :
793 : r = 1;
794 :
795 : err:
796 :
797 0 : if (!r && ukey)
798 0 : OPENSSL_free(ukey);
799 0 : OPENSSL_cleanse(&actx, sizeof(actx));
800 :
801 : return r;
802 :
803 : }
804 :
805 0 : int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri)
806 : {
807 0 : switch (ri->type) {
808 : case CMS_RECIPINFO_TRANS:
809 0 : return cms_RecipientInfo_ktri_decrypt(cms, ri);
810 :
811 : case CMS_RECIPINFO_KEK:
812 0 : return cms_RecipientInfo_kekri_decrypt(cms, ri);
813 :
814 : case CMS_RECIPINFO_PASS:
815 0 : return cms_RecipientInfo_pwri_crypt(cms, ri, 0);
816 :
817 : default:
818 0 : CMSerr(CMS_F_CMS_RECIPIENTINFO_DECRYPT,
819 : CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE);
820 0 : return 0;
821 : }
822 : }
823 :
824 0 : int CMS_RecipientInfo_encrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri)
825 : {
826 0 : switch (ri->type) {
827 : case CMS_RECIPINFO_TRANS:
828 0 : return cms_RecipientInfo_ktri_encrypt(cms, ri);
829 :
830 : case CMS_RECIPINFO_AGREE:
831 0 : return cms_RecipientInfo_kari_encrypt(cms, ri);
832 :
833 : case CMS_RECIPINFO_KEK:
834 0 : return cms_RecipientInfo_kekri_encrypt(cms, ri);
835 : break;
836 :
837 : case CMS_RECIPINFO_PASS:
838 0 : return cms_RecipientInfo_pwri_crypt(cms, ri, 1);
839 : break;
840 :
841 : default:
842 0 : CMSerr(CMS_F_CMS_RECIPIENTINFO_ENCRYPT,
843 : CMS_R_UNSUPPORTED_RECIPIENT_TYPE);
844 0 : return 0;
845 : }
846 : }
847 :
848 : /* Check structures and fixup version numbers (if necessary) */
849 :
850 0 : static void cms_env_set_originfo_version(CMS_EnvelopedData *env)
851 : {
852 0 : CMS_OriginatorInfo *org = env->originatorInfo;
853 : int i;
854 0 : if (org == NULL)
855 : return;
856 0 : for (i = 0; i < sk_CMS_CertificateChoices_num(org->certificates); i++) {
857 : CMS_CertificateChoices *cch;
858 0 : cch = sk_CMS_CertificateChoices_value(org->certificates, i);
859 0 : if (cch->type == CMS_CERTCHOICE_OTHER) {
860 0 : env->version = 4;
861 : return;
862 0 : } else if (cch->type == CMS_CERTCHOICE_V2ACERT) {
863 0 : if (env->version < 3)
864 0 : env->version = 3;
865 : }
866 : }
867 :
868 0 : for (i = 0; i < sk_CMS_RevocationInfoChoice_num(org->crls); i++) {
869 : CMS_RevocationInfoChoice *rch;
870 0 : rch = sk_CMS_RevocationInfoChoice_value(org->crls, i);
871 0 : if (rch->type == CMS_REVCHOICE_OTHER) {
872 0 : env->version = 4;
873 : return;
874 : }
875 : }
876 : }
877 :
878 0 : static void cms_env_set_version(CMS_EnvelopedData *env)
879 : {
880 : int i;
881 : CMS_RecipientInfo *ri;
882 :
883 : /*
884 : * Can't set version higher than 4 so if 4 or more already nothing to do.
885 : */
886 0 : if (env->version >= 4)
887 : return;
888 :
889 0 : cms_env_set_originfo_version(env);
890 :
891 0 : if (env->version >= 3)
892 : return;
893 :
894 0 : for (i = 0; i < sk_CMS_RecipientInfo_num(env->recipientInfos); i++) {
895 0 : ri = sk_CMS_RecipientInfo_value(env->recipientInfos, i);
896 0 : if (ri->type == CMS_RECIPINFO_PASS || ri->type == CMS_RECIPINFO_OTHER) {
897 0 : env->version = 3;
898 0 : return;
899 0 : } else if (ri->type != CMS_RECIPINFO_TRANS
900 0 : || ri->d.ktri->version != 0) {
901 0 : env->version = 2;
902 : }
903 : }
904 0 : if (env->version == 2)
905 : return;
906 0 : if (env->originatorInfo || env->unprotectedAttrs)
907 0 : env->version = 2;
908 0 : env->version = 0;
909 : }
910 :
911 0 : BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms)
912 : {
913 : CMS_EncryptedContentInfo *ec;
914 : STACK_OF(CMS_RecipientInfo) *rinfos;
915 : CMS_RecipientInfo *ri;
916 : int i, ok = 0;
917 : BIO *ret;
918 :
919 : /* Get BIO first to set up key */
920 :
921 0 : ec = cms->d.envelopedData->encryptedContentInfo;
922 0 : ret = cms_EncryptedContent_init_bio(ec);
923 :
924 : /* If error or no cipher end of processing */
925 :
926 0 : if (!ret || !ec->cipher)
927 : return ret;
928 :
929 : /* Now encrypt content key according to each RecipientInfo type */
930 :
931 0 : rinfos = cms->d.envelopedData->recipientInfos;
932 :
933 0 : for (i = 0; i < sk_CMS_RecipientInfo_num(rinfos); i++) {
934 0 : ri = sk_CMS_RecipientInfo_value(rinfos, i);
935 0 : if (CMS_RecipientInfo_encrypt(cms, ri) <= 0) {
936 0 : CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO,
937 : CMS_R_ERROR_SETTING_RECIPIENTINFO);
938 0 : goto err;
939 : }
940 : }
941 0 : cms_env_set_version(cms->d.envelopedData);
942 :
943 : ok = 1;
944 :
945 : err:
946 0 : ec->cipher = NULL;
947 0 : if (ec->key) {
948 0 : OPENSSL_cleanse(ec->key, ec->keylen);
949 0 : OPENSSL_free(ec->key);
950 0 : ec->key = NULL;
951 0 : ec->keylen = 0;
952 : }
953 0 : if (ok)
954 : return ret;
955 0 : BIO_free(ret);
956 0 : return NULL;
957 :
958 : }
959 :
960 : /*
961 : * Get RecipientInfo type (if any) supported by a key (public or private). To
962 : * retain compatibility with previous behaviour if the ctrl value isn't
963 : * supported we assume key transport.
964 : */
965 0 : int cms_pkey_get_ri_type(EVP_PKEY *pk)
966 : {
967 0 : if (pk->ameth && pk->ameth->pkey_ctrl) {
968 : int i, r;
969 0 : i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_RI_TYPE, 0, &r);
970 0 : if (i > 0)
971 0 : return r;
972 : }
973 : return CMS_RECIPINFO_TRANS;
974 : }
|