| 
									
										
										
										
											2008-03-13 05:14:28 +08:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2025-03-12 21:35:59 +08:00
										 |  |  |  * Copyright 2008-2025 The OpenSSL Project Authors. All Rights Reserved. | 
					
						
							| 
									
										
										
										
											2008-03-13 05:14:28 +08:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2018-12-06 20:32:50 +08:00
										 |  |  |  * Licensed under the Apache License 2.0 (the "License").  You may not use | 
					
						
							| 
									
										
										
										
											2016-05-18 02:52:22 +08:00
										 |  |  |  * this file except in compliance with the License.  You can obtain a copy | 
					
						
							|  |  |  |  * in the file LICENSE in the source distribution or at | 
					
						
							|  |  |  |  * https://www.openssl.org/source/license.html
 | 
					
						
							| 
									
										
										
										
											2008-03-13 05:14:28 +08:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-03 18:19:43 +08:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Low level key APIs (DH etc) are deprecated for public use, but still ok for | 
					
						
							|  |  |  |  * internal use. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | #include "internal/deprecated.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-14 22:56:48 +08:00
										 |  |  | #include "internal/cryptlib.h"
 | 
					
						
							| 
									
										
										
										
											2008-03-13 05:14:28 +08:00
										 |  |  | #include <openssl/asn1t.h>
 | 
					
						
							|  |  |  | #include <openssl/pem.h>
 | 
					
						
							|  |  |  | #include <openssl/x509v3.h>
 | 
					
						
							|  |  |  | #include <openssl/err.h>
 | 
					
						
							|  |  |  | #include <openssl/cms.h>
 | 
					
						
							| 
									
										
										
										
											2019-12-06 02:01:44 +08:00
										 |  |  | #include <openssl/evp.h>
 | 
					
						
							| 
									
										
										
										
											2025-04-03 18:19:43 +08:00
										 |  |  | #include <openssl/core_names.h>
 | 
					
						
							| 
									
										
										
										
											2021-03-10 19:58:53 +08:00
										 |  |  | #include "internal/sizes.h"
 | 
					
						
							| 
									
										
										
										
											2019-09-28 06:45:33 +08:00
										 |  |  | #include "crypto/asn1.h"
 | 
					
						
							|  |  |  | #include "crypto/evp.h"
 | 
					
						
							| 
									
										
										
										
											2020-07-25 16:04:55 +08:00
										 |  |  | #include "crypto/x509.h"
 | 
					
						
							|  |  |  | #include "cms_local.h"
 | 
					
						
							| 
									
										
										
										
											2008-03-13 05:14:28 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* CMS EnvelopedData Utilities */ | 
					
						
							| 
									
										
										
										
											2020-01-20 23:17:44 +08:00
										 |  |  | static void cms_env_set_version(CMS_EnvelopedData *env); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-07 02:11:34 +08:00
										 |  |  | #define CMS_ENVELOPED_STANDARD 1
 | 
					
						
							|  |  |  | #define CMS_ENVELOPED_AUTH     2
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-07 20:51:53 +08:00
										 |  |  | static int cms_get_enveloped_type_simple(const CMS_ContentInfo *cms) | 
					
						
							| 
									
										
										
										
											2020-09-07 02:11:34 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     int nid = OBJ_obj2nid(cms->contentType); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     switch (nid) { | 
					
						
							|  |  |  |     case NID_pkcs7_enveloped: | 
					
						
							|  |  |  |         return CMS_ENVELOPED_STANDARD; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case NID_id_smime_ct_authEnvelopedData: | 
					
						
							|  |  |  |         return CMS_ENVELOPED_AUTH; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-07 20:51:53 +08:00
										 |  |  | static int cms_get_enveloped_type(const CMS_ContentInfo *cms) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int ret = cms_get_enveloped_type_simple(cms); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (ret == 0) | 
					
						
							|  |  |  |         ERR_raise(ERR_LIB_CMS, CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA); | 
					
						
							|  |  |  |     return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-18 12:03:25 +08:00
										 |  |  | CMS_EnvelopedData *ossl_cms_get0_enveloped(CMS_ContentInfo *cms) | 
					
						
							| 
									
										
										
										
											2008-03-13 05:14:28 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_enveloped) { | 
					
						
							| 
									
										
										
										
											2020-11-04 19:23:19 +08:00
										 |  |  |         ERR_raise(ERR_LIB_CMS, CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA); | 
					
						
							| 
									
										
										
										
											2008-03-13 05:14:28 +08:00
										 |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return cms->d.envelopedData; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-18 12:03:25 +08:00
										 |  |  | CMS_AuthEnvelopedData *ossl_cms_get0_auth_enveloped(CMS_ContentInfo *cms) | 
					
						
							| 
									
										
										
										
											2020-09-07 02:11:34 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     if (OBJ_obj2nid(cms->contentType) != NID_id_smime_ct_authEnvelopedData) { | 
					
						
							| 
									
										
										
										
											2020-11-04 19:23:19 +08:00
										 |  |  |         ERR_raise(ERR_LIB_CMS, CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA); | 
					
						
							| 
									
										
										
										
											2020-09-07 02:11:34 +08:00
										 |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return cms->d.authEnvelopedData; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-13 05:14:28 +08:00
										 |  |  | static CMS_EnvelopedData *cms_enveloped_data_init(CMS_ContentInfo *cms) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (cms->d.other == NULL) { | 
					
						
							|  |  |  |         cms->d.envelopedData = M_ASN1_new_of(CMS_EnvelopedData); | 
					
						
							| 
									
										
										
										
											2020-09-07 02:11:34 +08:00
										 |  |  |         if (cms->d.envelopedData == NULL) { | 
					
						
							| 
									
										
										
										
											2022-09-29 19:57:34 +08:00
										 |  |  |             ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB); | 
					
						
							| 
									
										
										
										
											2008-03-13 05:14:28 +08:00
										 |  |  |             return NULL; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         cms->d.envelopedData->version = 0; | 
					
						
							|  |  |  |         cms->d.envelopedData->encryptedContentInfo->contentType = | 
					
						
							|  |  |  |             OBJ_nid2obj(NID_pkcs7_data); | 
					
						
							|  |  |  |         ASN1_OBJECT_free(cms->contentType); | 
					
						
							|  |  |  |         cms->contentType = OBJ_nid2obj(NID_pkcs7_enveloped); | 
					
						
							|  |  |  |         return cms->d.envelopedData; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-02-18 12:03:25 +08:00
										 |  |  |     return ossl_cms_get0_enveloped(cms); | 
					
						
							| 
									
										
										
										
											2008-03-13 05:14:28 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-07 02:11:34 +08:00
										 |  |  | static CMS_AuthEnvelopedData * | 
					
						
							|  |  |  | cms_auth_enveloped_data_init(CMS_ContentInfo *cms) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (cms->d.other == NULL) { | 
					
						
							|  |  |  |         cms->d.authEnvelopedData = M_ASN1_new_of(CMS_AuthEnvelopedData); | 
					
						
							|  |  |  |         if (cms->d.authEnvelopedData == NULL) { | 
					
						
							| 
									
										
										
										
											2022-09-29 19:57:34 +08:00
										 |  |  |             ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB); | 
					
						
							| 
									
										
										
										
											2020-09-07 02:11:34 +08:00
										 |  |  |             return NULL; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         /* Defined in RFC 5083 - Section 2.1. "AuthEnvelopedData Type" */ | 
					
						
							|  |  |  |         cms->d.authEnvelopedData->version = 0; | 
					
						
							|  |  |  |         cms->d.authEnvelopedData->authEncryptedContentInfo->contentType = | 
					
						
							|  |  |  |             OBJ_nid2obj(NID_pkcs7_data); | 
					
						
							|  |  |  |         ASN1_OBJECT_free(cms->contentType); | 
					
						
							|  |  |  |         cms->contentType = OBJ_nid2obj(NID_id_smime_ct_authEnvelopedData); | 
					
						
							|  |  |  |         return cms->d.authEnvelopedData; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-02-18 12:03:25 +08:00
										 |  |  |     return ossl_cms_get0_auth_enveloped(cms); | 
					
						
							| 
									
										
										
										
											2020-09-07 02:11:34 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-18 12:03:25 +08:00
										 |  |  | int ossl_cms_env_asn1_ctrl(CMS_RecipientInfo *ri, int cmd) | 
					
						
							| 
									
										
										
										
											2013-06-20 01:17:14 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-07-17 21:36:39 +08:00
										 |  |  |     EVP_PKEY *pkey; | 
					
						
							| 
									
										
										
										
											2013-06-20 01:17:14 +08:00
										 |  |  |     int i; | 
					
						
							| 
									
										
										
										
											2025-04-03 18:19:43 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     switch (ri->type) { | 
					
						
							|  |  |  |     case CMS_RECIPINFO_TRANS: | 
					
						
							| 
									
										
										
										
											2013-07-17 21:36:39 +08:00
										 |  |  |         pkey = ri->d.ktri->pkey; | 
					
						
							| 
									
										
										
										
											2025-04-03 18:19:43 +08:00
										 |  |  |         break; | 
					
						
							|  |  |  |     case CMS_RECIPINFO_AGREE: { | 
					
						
							| 
									
										
										
										
											2013-07-17 21:36:39 +08:00
										 |  |  |         EVP_PKEY_CTX *pctx = ri->d.kari->pctx; | 
					
						
							| 
									
										
										
										
											2019-09-17 03:28:57 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (pctx == NULL) | 
					
						
							| 
									
										
										
										
											2013-07-17 21:36:39 +08:00
										 |  |  |             return 0; | 
					
						
							|  |  |  |         pkey = EVP_PKEY_CTX_get0_pkey(pctx); | 
					
						
							| 
									
										
										
										
											2019-09-17 03:28:57 +08:00
										 |  |  |         if (pkey == NULL) | 
					
						
							| 
									
										
										
										
											2013-07-17 21:36:39 +08:00
										 |  |  |             return 0; | 
					
						
							| 
									
										
										
										
											2025-04-03 18:19:43 +08:00
										 |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     case CMS_RECIPINFO_KEM: | 
					
						
							|  |  |  |         return ossl_cms_kem_envelope(ri, cmd); | 
					
						
							|  |  |  |     default: | 
					
						
							| 
									
										
										
										
											2013-07-17 21:36:39 +08:00
										 |  |  |         return 0; | 
					
						
							| 
									
										
										
										
											2025-04-03 18:19:43 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-10-06 23:02:43 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-14 21:43:11 +08:00
										 |  |  |     if (EVP_PKEY_is_a(pkey, "DHX") || EVP_PKEY_is_a(pkey, "DH")) | 
					
						
							| 
									
										
										
										
											2021-02-18 12:03:25 +08:00
										 |  |  |         return ossl_cms_dh_envelope(ri, cmd); | 
					
						
							| 
									
										
										
										
											2020-12-03 01:27:03 +08:00
										 |  |  |     else if (EVP_PKEY_is_a(pkey, "EC")) | 
					
						
							| 
									
										
										
										
											2021-02-18 12:03:25 +08:00
										 |  |  |         return ossl_cms_ecdh_envelope(ri, cmd); | 
					
						
							| 
									
										
										
										
											2020-12-03 01:27:03 +08:00
										 |  |  |     else if (EVP_PKEY_is_a(pkey, "RSA")) | 
					
						
							| 
									
										
										
										
											2021-02-18 12:03:25 +08:00
										 |  |  |         return ossl_cms_rsa_envelope(ri, cmd); | 
					
						
							| 
									
										
										
										
											2020-10-06 23:02:43 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* Something else? We'll give engines etc a chance to handle this */ | 
					
						
							| 
									
										
										
										
											2019-09-17 03:28:57 +08:00
										 |  |  |     if (pkey->ameth == NULL || pkey->ameth->pkey_ctrl == NULL) | 
					
						
							| 
									
										
										
										
											2013-06-20 01:17:14 +08:00
										 |  |  |         return 1; | 
					
						
							|  |  |  |     i = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_CMS_ENVELOPE, cmd, ri); | 
					
						
							|  |  |  |     if (i == -2) { | 
					
						
							| 
									
										
										
										
											2020-11-04 19:23:19 +08:00
										 |  |  |         ERR_raise(ERR_LIB_CMS, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); | 
					
						
							| 
									
										
										
										
											2013-06-20 01:17:14 +08:00
										 |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (i <= 0) { | 
					
						
							| 
									
										
										
										
											2020-11-04 19:23:19 +08:00
										 |  |  |         ERR_raise(ERR_LIB_CMS, CMS_R_CTRL_FAILURE); | 
					
						
							| 
									
										
										
										
											2013-06-20 01:17:14 +08:00
										 |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-15 17:51:30 +08:00
										 |  |  | CMS_EncryptedContentInfo *ossl_cms_get0_env_enc_content(const CMS_ContentInfo *cms) | 
					
						
							| 
									
										
										
										
											2020-09-07 02:11:34 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     switch (cms_get_enveloped_type(cms)) { | 
					
						
							|  |  |  |     case CMS_ENVELOPED_STANDARD: | 
					
						
							| 
									
										
										
										
											2023-05-25 23:46:48 +08:00
										 |  |  |         return cms->d.envelopedData == NULL ? NULL | 
					
						
							|  |  |  |             : cms->d.envelopedData->encryptedContentInfo; | 
					
						
							| 
									
										
										
										
											2020-09-07 02:11:34 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     case CMS_ENVELOPED_AUTH: | 
					
						
							| 
									
										
										
										
											2023-05-25 23:46:48 +08:00
										 |  |  |         return cms->d.authEnvelopedData == NULL ? NULL | 
					
						
							|  |  |  |             : cms->d.authEnvelopedData->authEncryptedContentInfo; | 
					
						
							| 
									
										
										
										
											2020-09-07 02:11:34 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-16 07:21:33 +08:00
										 |  |  | STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-09-07 02:11:34 +08:00
										 |  |  |     switch (cms_get_enveloped_type(cms)) { | 
					
						
							|  |  |  |     case CMS_ENVELOPED_STANDARD: | 
					
						
							|  |  |  |         return cms->d.envelopedData->recipientInfos; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case CMS_ENVELOPED_AUTH: | 
					
						
							|  |  |  |         return cms->d.authEnvelopedData->recipientInfos; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     default: | 
					
						
							| 
									
										
										
										
											2008-03-16 07:21:33 +08:00
										 |  |  |         return NULL; | 
					
						
							| 
									
										
										
										
											2020-09-07 02:11:34 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-03-16 07:21:33 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-18 12:03:25 +08:00
										 |  |  | void ossl_cms_RecipientInfos_set_cmsctx(CMS_ContentInfo *cms) | 
					
						
							| 
									
										
										
										
											2020-07-25 16:04:55 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     int i; | 
					
						
							|  |  |  |     CMS_RecipientInfo *ri; | 
					
						
							| 
									
										
										
										
											2021-02-18 12:03:25 +08:00
										 |  |  |     const CMS_CTX *ctx = ossl_cms_get0_cmsctx(cms); | 
					
						
							| 
									
										
										
										
											2020-07-25 16:04:55 +08:00
										 |  |  |     STACK_OF(CMS_RecipientInfo) *rinfos = CMS_get0_RecipientInfos(cms); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (i = 0; i < sk_CMS_RecipientInfo_num(rinfos); i++) { | 
					
						
							|  |  |  |         ri = sk_CMS_RecipientInfo_value(rinfos, i); | 
					
						
							|  |  |  |         if (ri != NULL) { | 
					
						
							|  |  |  |             switch (ri->type) { | 
					
						
							|  |  |  |             case CMS_RECIPINFO_AGREE: | 
					
						
							|  |  |  |                 ri->d.kari->cms_ctx = ctx; | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             case CMS_RECIPINFO_TRANS: | 
					
						
							|  |  |  |                 ri->d.ktri->cms_ctx = ctx; | 
					
						
							| 
									
										
										
										
											2021-03-09 12:18:03 +08:00
										 |  |  |                 ossl_x509_set0_libctx(ri->d.ktri->recip, | 
					
						
							|  |  |  |                                       ossl_cms_ctx_get0_libctx(ctx), | 
					
						
							|  |  |  |                                       ossl_cms_ctx_get0_propq(ctx)); | 
					
						
							| 
									
										
										
										
											2020-07-25 16:04:55 +08:00
										 |  |  |                 break; | 
					
						
							|  |  |  |             case CMS_RECIPINFO_KEK: | 
					
						
							|  |  |  |                 ri->d.kekri->cms_ctx = ctx; | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             case CMS_RECIPINFO_PASS: | 
					
						
							|  |  |  |                 ri->d.pwri->cms_ctx = ctx; | 
					
						
							|  |  |  |                 break; | 
					
						
							| 
									
										
										
										
											2025-04-03 18:19:43 +08:00
										 |  |  |             case CMS_RECIPINFO_KEM: | 
					
						
							|  |  |  |                 ri->d.ori->d.kemri->cms_ctx = ctx; | 
					
						
							|  |  |  |                 break; | 
					
						
							| 
									
										
										
										
											2020-07-25 16:04:55 +08:00
										 |  |  |             default: | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-16 07:21:33 +08:00
										 |  |  | int CMS_RecipientInfo_type(CMS_RecipientInfo *ri) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return ri->type; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-20 01:17:14 +08:00
										 |  |  | EVP_PKEY_CTX *CMS_RecipientInfo_get0_pkey_ctx(CMS_RecipientInfo *ri) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (ri->type == CMS_RECIPINFO_TRANS) | 
					
						
							|  |  |  |         return ri->d.ktri->pctx; | 
					
						
							| 
									
										
										
										
											2013-07-17 21:36:39 +08:00
										 |  |  |     else if (ri->type == CMS_RECIPINFO_AGREE) | 
					
						
							|  |  |  |         return ri->d.kari->pctx; | 
					
						
							| 
									
										
										
										
											2025-04-03 18:19:43 +08:00
										 |  |  |     else if (ri->type == CMS_RECIPINFO_KEM) | 
					
						
							|  |  |  |         return ri->d.ori->d.kemri->pctx; | 
					
						
							| 
									
										
										
										
											2013-06-20 01:17:14 +08:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-24 17:42:23 +08:00
										 |  |  | CMS_ContentInfo *CMS_EnvelopedData_create_ex(const EVP_CIPHER *cipher, | 
					
						
							| 
									
										
										
										
											2020-10-15 17:55:50 +08:00
										 |  |  |                                              OSSL_LIB_CTX *libctx, | 
					
						
							| 
									
										
										
										
											2020-09-24 17:42:23 +08:00
										 |  |  |                                              const char *propq) | 
					
						
							| 
									
										
										
										
											2008-03-17 21:38:51 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     CMS_ContentInfo *cms; | 
					
						
							|  |  |  |     CMS_EnvelopedData *env; | 
					
						
							| 
									
										
										
										
											2020-07-25 16:04:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-24 17:42:23 +08:00
										 |  |  |     cms = CMS_ContentInfo_new_ex(libctx, propq); | 
					
						
							| 
									
										
										
										
											2015-10-30 19:12:26 +08:00
										 |  |  |     if (cms == NULL) | 
					
						
							| 
									
										
										
										
											2022-09-29 19:57:34 +08:00
										 |  |  |         goto err; | 
					
						
							| 
									
										
										
										
											2008-03-17 21:38:51 +08:00
										 |  |  |     env = cms_enveloped_data_init(cms); | 
					
						
							| 
									
										
										
										
											2015-10-30 19:12:26 +08:00
										 |  |  |     if (env == NULL) | 
					
						
							| 
									
										
										
										
											2022-09-29 19:57:34 +08:00
										 |  |  |         goto err; | 
					
						
							| 
									
										
										
										
											2020-07-25 16:04:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-18 12:03:25 +08:00
										 |  |  |     if (!ossl_cms_EncryptedContent_init(env->encryptedContentInfo, cipher, NULL, | 
					
						
							|  |  |  |                                         0, ossl_cms_get0_cmsctx(cms))) | 
					
						
							| 
									
										
										
										
											2022-09-29 19:57:34 +08:00
										 |  |  |         goto err; | 
					
						
							| 
									
										
										
										
											2008-03-17 21:38:51 +08:00
										 |  |  |     return cms; | 
					
						
							| 
									
										
										
										
											2022-09-29 19:57:34 +08:00
										 |  |  |  err: | 
					
						
							| 
									
										
										
										
											2015-05-02 02:37:16 +08:00
										 |  |  |     CMS_ContentInfo_free(cms); | 
					
						
							| 
									
										
										
										
											2022-09-29 19:57:34 +08:00
										 |  |  |     ERR_raise(ERR_LIB_CMS, ERR_R_CMS_LIB); | 
					
						
							| 
									
										
										
										
											2008-03-17 21:38:51 +08:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-25 16:04:55 +08:00
										 |  |  | CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-09-24 17:42:23 +08:00
										 |  |  |     return CMS_EnvelopedData_create_ex(cipher, NULL, NULL); | 
					
						
							| 
									
										
										
										
											2020-07-25 16:04:55 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-10 03:00:03 +08:00
										 |  |  | BIO *CMS_EnvelopedData_decrypt(CMS_EnvelopedData *env, BIO *detached_data, | 
					
						
							|  |  |  |                                EVP_PKEY *pkey, X509 *cert, | 
					
						
							|  |  |  |                                ASN1_OCTET_STRING *secret, unsigned int flags, | 
					
						
							|  |  |  |                                OSSL_LIB_CTX *libctx, const char *propq) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     CMS_ContentInfo *ci; | 
					
						
							|  |  |  |     BIO *bio = NULL; | 
					
						
							|  |  |  |     int res = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (env == NULL) { | 
					
						
							|  |  |  |         ERR_raise(ERR_LIB_CMS, ERR_R_PASSED_NULL_PARAMETER); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((ci = CMS_ContentInfo_new_ex(libctx, propq)) == NULL | 
					
						
							|  |  |  |             || (bio = BIO_new(BIO_s_mem())) == NULL) | 
					
						
							|  |  |  |         goto end; | 
					
						
							|  |  |  |     ci->contentType = OBJ_nid2obj(NID_pkcs7_enveloped); | 
					
						
							|  |  |  |     ci->d.envelopedData = env; | 
					
						
							|  |  |  |     if (secret != NULL | 
					
						
							|  |  |  |         && CMS_decrypt_set1_password(ci, (unsigned char *) | 
					
						
							|  |  |  |                                      ASN1_STRING_get0_data(secret), | 
					
						
							|  |  |  |                                      ASN1_STRING_length(secret)) != 1) | 
					
						
							|  |  |  |         goto end; | 
					
						
							| 
									
										
										
										
											2022-09-15 17:51:30 +08:00
										 |  |  |     res = CMS_decrypt(ci, secret == NULL ? pkey : NULL, | 
					
						
							|  |  |  |                       secret == NULL ? cert : NULL, detached_data, bio, flags); | 
					
						
							| 
									
										
										
										
											2022-05-10 03:00:03 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |  end: | 
					
						
							| 
									
										
										
										
											2023-09-08 00:05:44 +08:00
										 |  |  |     if (ci != NULL) { | 
					
						
							| 
									
										
										
										
											2022-06-27 23:05:21 +08:00
										 |  |  |         ci->d.envelopedData = NULL; /* do not indirectly free |env| */ | 
					
						
							| 
									
										
										
										
											2023-09-08 00:05:44 +08:00
										 |  |  |         ci->contentType = NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-05-10 03:00:03 +08:00
										 |  |  |     CMS_ContentInfo_free(ci); | 
					
						
							|  |  |  |     if (!res) { | 
					
						
							|  |  |  |         BIO_free(bio); | 
					
						
							|  |  |  |         bio = NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return bio; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-07 02:11:34 +08:00
										 |  |  | CMS_ContentInfo * | 
					
						
							| 
									
										
										
										
											2020-10-15 17:55:50 +08:00
										 |  |  | CMS_AuthEnvelopedData_create_ex(const EVP_CIPHER *cipher, OSSL_LIB_CTX *libctx, | 
					
						
							| 
									
										
										
										
											2020-09-24 17:42:23 +08:00
										 |  |  |                                 const char *propq) | 
					
						
							| 
									
										
										
										
											2020-01-20 23:17:44 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-09-07 02:11:34 +08:00
										 |  |  |     CMS_ContentInfo *cms; | 
					
						
							|  |  |  |     CMS_AuthEnvelopedData *aenv; | 
					
						
							| 
									
										
										
										
											2020-01-20 23:17:44 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-24 17:42:23 +08:00
										 |  |  |     cms = CMS_ContentInfo_new_ex(libctx, propq); | 
					
						
							| 
									
										
										
										
											2020-09-07 02:11:34 +08:00
										 |  |  |     if (cms == NULL) | 
					
						
							|  |  |  |         goto merr; | 
					
						
							|  |  |  |     aenv = cms_auth_enveloped_data_init(cms); | 
					
						
							|  |  |  |     if (aenv == NULL) | 
					
						
							|  |  |  |         goto merr; | 
					
						
							| 
									
										
										
										
											2021-02-18 12:03:25 +08:00
										 |  |  |     if (!ossl_cms_EncryptedContent_init(aenv->authEncryptedContentInfo, | 
					
						
							|  |  |  |                                         cipher, NULL, 0, | 
					
						
							|  |  |  |                                         ossl_cms_get0_cmsctx(cms))) | 
					
						
							| 
									
										
										
										
											2020-09-07 02:11:34 +08:00
										 |  |  |         goto merr; | 
					
						
							|  |  |  |     return cms; | 
					
						
							|  |  |  |  merr: | 
					
						
							|  |  |  |     CMS_ContentInfo_free(cms); | 
					
						
							| 
									
										
										
										
											2022-09-29 19:57:34 +08:00
										 |  |  |     ERR_raise(ERR_LIB_CMS, ERR_R_CMS_LIB); | 
					
						
							| 
									
										
										
										
											2020-09-07 02:11:34 +08:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-01-20 23:17:44 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-07 02:11:34 +08:00
										 |  |  | CMS_ContentInfo *CMS_AuthEnvelopedData_create(const EVP_CIPHER *cipher) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-09-24 17:42:23 +08:00
										 |  |  |     return CMS_AuthEnvelopedData_create_ex(cipher, NULL, NULL); | 
					
						
							| 
									
										
										
										
											2020-01-20 23:17:44 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-19 21:53:52 +08:00
										 |  |  | /* Key Transport Recipient Info (KTRI) routines */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-17 21:36:39 +08:00
										 |  |  | /* Initialise a ktri based on passed certificate and key */ | 
					
						
							| 
									
										
										
										
											2008-03-19 21:53:52 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-17 21:36:39 +08:00
										 |  |  | static int cms_RecipientInfo_ktri_init(CMS_RecipientInfo *ri, X509 *recip, | 
					
						
							| 
									
										
										
										
											2020-07-25 16:04:55 +08:00
										 |  |  |                                        EVP_PKEY *pk, unsigned int flags, | 
					
						
							|  |  |  |                                        const CMS_CTX *ctx) | 
					
						
							| 
									
										
										
										
											2008-03-13 05:14:28 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     CMS_KeyTransRecipientInfo *ktri; | 
					
						
							| 
									
										
										
										
											2013-07-17 21:36:39 +08:00
										 |  |  |     int idtype; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-13 05:14:28 +08:00
										 |  |  |     ri->d.ktri = M_ASN1_new_of(CMS_KeyTransRecipientInfo); | 
					
						
							|  |  |  |     if (!ri->d.ktri) | 
					
						
							| 
									
										
										
										
											2013-07-17 21:36:39 +08:00
										 |  |  |         return 0; | 
					
						
							| 
									
										
										
										
											2025-04-03 18:19:43 +08:00
										 |  |  |     ri->encoded_type = ri->type = CMS_RECIPINFO_TRANS; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-13 05:14:28 +08:00
										 |  |  |     ktri = ri->d.ktri; | 
					
						
							| 
									
										
										
										
											2020-07-25 16:04:55 +08:00
										 |  |  |     ktri->cms_ctx = ctx; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-13 05:14:28 +08:00
										 |  |  |     if (flags & CMS_USE_KEYID) { | 
					
						
							|  |  |  |         ktri->version = 2; | 
					
						
							| 
									
										
										
										
											2013-07-17 21:36:39 +08:00
										 |  |  |         idtype = CMS_RECIPINFO_KEYIDENTIFIER; | 
					
						
							| 
									
										
										
										
											2008-03-13 05:14:28 +08:00
										 |  |  |     } else { | 
					
						
							|  |  |  |         ktri->version = 0; | 
					
						
							| 
									
										
										
										
											2013-07-17 21:36:39 +08:00
										 |  |  |         idtype = CMS_RECIPINFO_ISSUER_SERIAL; | 
					
						
							| 
									
										
										
										
											2008-03-13 05:14:28 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-13 05:14:28 +08:00
										 |  |  |     /*
 | 
					
						
							|  |  |  |      * Not a typo: RecipientIdentifier and SignerIdentifier are the same | 
					
						
							|  |  |  |      * structure. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-18 12:03:25 +08:00
										 |  |  |     if (!ossl_cms_set1_SignerIdentifier(ktri->rid, recip, idtype, ctx)) | 
					
						
							| 
									
										
										
										
											2013-07-17 21:36:39 +08:00
										 |  |  |         return 0; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-28 17:13:48 +08:00
										 |  |  |     if (!X509_up_ref(recip)) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     if (!EVP_PKEY_up_ref(pk)) { | 
					
						
							|  |  |  |         X509_free(recip); | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-02-26 20:21:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-17 21:36:39 +08:00
										 |  |  |     ktri->pkey = pk; | 
					
						
							|  |  |  |     ktri->recip = recip; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-20 01:17:14 +08:00
										 |  |  |     if (flags & CMS_KEY_PARAM) { | 
					
						
							| 
									
										
										
										
											2021-02-18 12:03:25 +08:00
										 |  |  |         ktri->pctx = EVP_PKEY_CTX_new_from_pkey(ossl_cms_ctx_get0_libctx(ctx), | 
					
						
							| 
									
										
										
										
											2020-12-11 17:19:37 +08:00
										 |  |  |                                                 ktri->pkey, | 
					
						
							| 
									
										
										
										
											2021-02-18 12:03:25 +08:00
										 |  |  |                                                 ossl_cms_ctx_get0_propq(ctx)); | 
					
						
							| 
									
										
										
										
											2015-10-30 19:12:26 +08:00
										 |  |  |         if (ktri->pctx == NULL) | 
					
						
							| 
									
										
										
										
											2013-06-20 01:17:14 +08:00
										 |  |  |             return 0; | 
					
						
							|  |  |  |         if (EVP_PKEY_encrypt_init(ktri->pctx) <= 0) | 
					
						
							| 
									
										
										
										
											2013-07-17 21:36:39 +08:00
										 |  |  |             return 0; | 
					
						
							| 
									
										
										
										
											2021-02-18 12:03:25 +08:00
										 |  |  |     } else if (!ossl_cms_env_asn1_ctrl(ri, 0)) | 
					
						
							| 
									
										
										
										
											2013-07-17 21:36:39 +08:00
										 |  |  |         return 0; | 
					
						
							|  |  |  |     return 1; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-17 21:36:39 +08:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Add a recipient certificate using appropriate type of RecipientInfo | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-20 23:17:44 +08:00
										 |  |  | CMS_RecipientInfo *CMS_add1_recipient(CMS_ContentInfo *cms, X509 *recip, | 
					
						
							|  |  |  |                                       EVP_PKEY *originatorPrivKey, | 
					
						
							|  |  |  |                                       X509 *originator, unsigned int flags) | 
					
						
							| 
									
										
										
										
											2013-07-17 21:36:39 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     CMS_RecipientInfo *ri = NULL; | 
					
						
							| 
									
										
										
										
											2020-09-07 02:11:34 +08:00
										 |  |  |     STACK_OF(CMS_RecipientInfo) *ris; | 
					
						
							| 
									
										
										
										
											2013-07-17 21:36:39 +08:00
										 |  |  |     EVP_PKEY *pk = NULL; | 
					
						
							| 
									
										
										
										
											2021-02-18 12:03:25 +08:00
										 |  |  |     const CMS_CTX *ctx = ossl_cms_get0_cmsctx(cms); | 
					
						
							| 
									
										
										
										
											2020-07-25 16:04:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-07 02:11:34 +08:00
										 |  |  |     ris = CMS_get0_RecipientInfos(cms); | 
					
						
							|  |  |  |     if (ris == NULL) | 
					
						
							| 
									
										
										
										
											2013-07-17 21:36:39 +08:00
										 |  |  |         goto err; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-17 21:36:39 +08:00
										 |  |  |     /* Initialize recipient info */ | 
					
						
							|  |  |  |     ri = M_ASN1_new_of(CMS_RecipientInfo); | 
					
						
							| 
									
										
										
										
											2022-09-29 19:57:34 +08:00
										 |  |  |     if (ri == NULL) { | 
					
						
							|  |  |  |         ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB); | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-20 08:32:36 +08:00
										 |  |  |     pk = X509_get0_pubkey(recip); | 
					
						
							| 
									
										
										
										
											2019-09-17 03:28:57 +08:00
										 |  |  |     if (pk == NULL) { | 
					
						
							| 
									
										
										
										
											2020-11-04 19:23:19 +08:00
										 |  |  |         ERR_raise(ERR_LIB_CMS, CMS_R_ERROR_GETTING_PUBLIC_KEY); | 
					
						
							| 
									
										
										
										
											2013-06-20 01:17:14 +08:00
										 |  |  |         goto err; | 
					
						
							| 
									
										
										
										
											2013-07-17 21:36:39 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-18 12:03:25 +08:00
										 |  |  |     switch (ossl_cms_pkey_get_ri_type(pk)) { | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-17 21:36:39 +08:00
										 |  |  |     case CMS_RECIPINFO_TRANS: | 
					
						
							| 
									
										
										
										
											2020-07-25 16:04:55 +08:00
										 |  |  |         if (!cms_RecipientInfo_ktri_init(ri, recip, pk, flags, ctx)) | 
					
						
							| 
									
										
										
										
											2013-07-17 21:36:39 +08:00
										 |  |  |             goto err; | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-17 21:36:39 +08:00
										 |  |  |     case CMS_RECIPINFO_AGREE: | 
					
						
							| 
									
										
										
										
											2021-02-18 12:03:25 +08:00
										 |  |  |         if (!ossl_cms_RecipientInfo_kari_init(ri, recip, pk, originator, | 
					
						
							|  |  |  |                                               originatorPrivKey, flags, ctx)) | 
					
						
							| 
									
										
										
										
											2013-07-17 21:36:39 +08:00
										 |  |  |             goto err; | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-03 18:19:43 +08:00
										 |  |  |     case CMS_RECIPINFO_KEM: | 
					
						
							|  |  |  |         if (!ossl_cms_RecipientInfo_kemri_init(ri, recip, pk, flags, ctx)) | 
					
						
							|  |  |  |             goto err; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-17 21:36:39 +08:00
										 |  |  |     default: | 
					
						
							| 
									
										
										
										
											2020-11-04 19:23:19 +08:00
										 |  |  |         ERR_raise(ERR_LIB_CMS, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); | 
					
						
							| 
									
										
										
										
											2013-07-17 21:36:39 +08:00
										 |  |  |         goto err; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-17 21:36:39 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-29 19:57:34 +08:00
										 |  |  |     if (!sk_CMS_RecipientInfo_push(ris, ri)) { | 
					
						
							|  |  |  |         ERR_raise(ERR_LIB_CMS, ERR_R_CRYPTO_LIB); | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-13 05:14:28 +08:00
										 |  |  |     return ri; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-13 05:14:28 +08:00
										 |  |  |  err: | 
					
						
							| 
									
										
										
										
											2015-04-30 23:30:03 +08:00
										 |  |  |     M_ASN1_free_of(ri, CMS_RecipientInfo); | 
					
						
							| 
									
										
										
										
											2008-03-13 05:14:28 +08:00
										 |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-13 05:14:28 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-07 02:11:34 +08:00
										 |  |  | CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms, X509 *recip, | 
					
						
							|  |  |  |                                            unsigned int flags) | 
					
						
							| 
									
										
										
										
											2020-01-20 23:17:44 +08:00
										 |  |  | { | 
					
						
							|  |  |  |      return CMS_add1_recipient(cms, recip, NULL, NULL, flags); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-13 05:14:28 +08:00
										 |  |  | int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri, | 
					
						
							|  |  |  |                                      EVP_PKEY **pk, X509 **recip, | 
					
						
							|  |  |  |                                      X509_ALGOR **palg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     CMS_KeyTransRecipientInfo *ktri; | 
					
						
							|  |  |  |     if (ri->type != CMS_RECIPINFO_TRANS) { | 
					
						
							| 
									
										
										
										
											2020-11-04 19:23:19 +08:00
										 |  |  |         ERR_raise(ERR_LIB_CMS, CMS_R_NOT_KEY_TRANSPORT); | 
					
						
							| 
									
										
										
										
											2008-03-13 05:14:28 +08:00
										 |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-13 05:14:28 +08:00
										 |  |  |     ktri = ri->d.ktri; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-13 05:14:28 +08:00
										 |  |  |     if (pk) | 
					
						
							|  |  |  |         *pk = ktri->pkey; | 
					
						
							|  |  |  |     if (recip) | 
					
						
							|  |  |  |         *recip = ktri->recip; | 
					
						
							|  |  |  |     if (palg) | 
					
						
							|  |  |  |         *palg = ktri->keyEncryptionAlgorithm; | 
					
						
							|  |  |  |     return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri, | 
					
						
							|  |  |  |                                           ASN1_OCTET_STRING **keyid, | 
					
						
							|  |  |  |                                           X509_NAME **issuer, | 
					
						
							|  |  |  |                                           ASN1_INTEGER **sno) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     CMS_KeyTransRecipientInfo *ktri; | 
					
						
							|  |  |  |     if (ri->type != CMS_RECIPINFO_TRANS) { | 
					
						
							| 
									
										
										
										
											2020-11-04 19:23:19 +08:00
										 |  |  |         ERR_raise(ERR_LIB_CMS, CMS_R_NOT_KEY_TRANSPORT); | 
					
						
							| 
									
										
										
										
											2008-03-13 05:14:28 +08:00
										 |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-03-16 07:21:33 +08:00
										 |  |  |     ktri = ri->d.ktri; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-18 12:03:25 +08:00
										 |  |  |     return ossl_cms_SignerIdentifier_get0_signer_id(ktri->rid, keyid, issuer, | 
					
						
							|  |  |  |                                                     sno); | 
					
						
							| 
									
										
										
										
											2008-03-13 05:14:28 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (ri->type != CMS_RECIPINFO_TRANS) { | 
					
						
							| 
									
										
										
										
											2020-11-04 19:23:19 +08:00
										 |  |  |         ERR_raise(ERR_LIB_CMS, CMS_R_NOT_KEY_TRANSPORT); | 
					
						
							| 
									
										
										
										
											2008-03-16 07:21:33 +08:00
										 |  |  |         return -2; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-02-18 12:03:25 +08:00
										 |  |  |     return ossl_cms_SignerIdentifier_cert_cmp(ri->d.ktri->rid, cert); | 
					
						
							| 
									
										
										
										
											2008-03-16 07:21:33 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-18 09:00:38 +08:00
										 |  |  | int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (ri->type != CMS_RECIPINFO_TRANS) { | 
					
						
							| 
									
										
										
										
											2020-11-04 19:23:19 +08:00
										 |  |  |         ERR_raise(ERR_LIB_CMS, CMS_R_NOT_KEY_TRANSPORT); | 
					
						
							| 
									
										
										
										
											2008-03-18 09:00:38 +08:00
										 |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-05-01 16:29:17 +08:00
										 |  |  |     EVP_PKEY_free(ri->d.ktri->pkey); | 
					
						
							| 
									
										
										
										
											2008-03-18 09:00:38 +08:00
										 |  |  |     ri->d.ktri->pkey = pkey; | 
					
						
							|  |  |  |     return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-17 21:38:51 +08:00
										 |  |  | /* Encrypt content key in key transport recipient info */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-16 04:51:25 +08:00
										 |  |  | static int cms_RecipientInfo_ktri_encrypt(const CMS_ContentInfo *cms, | 
					
						
							| 
									
										
										
										
											2008-03-17 21:38:51 +08:00
										 |  |  |                                           CMS_RecipientInfo *ri) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     CMS_KeyTransRecipientInfo *ktri; | 
					
						
							|  |  |  |     CMS_EncryptedContentInfo *ec; | 
					
						
							| 
									
										
										
										
											2013-06-20 01:17:14 +08:00
										 |  |  |     EVP_PKEY_CTX *pctx; | 
					
						
							| 
									
										
										
										
											2008-03-17 21:38:51 +08:00
										 |  |  |     unsigned char *ek = NULL; | 
					
						
							|  |  |  |     size_t eklen; | 
					
						
							| 
									
										
										
										
											2021-02-18 12:03:25 +08:00
										 |  |  |     const CMS_CTX *ctx = ossl_cms_get0_cmsctx(cms); | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-17 21:38:51 +08:00
										 |  |  |     int ret = 0; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-17 21:38:51 +08:00
										 |  |  |     if (ri->type != CMS_RECIPINFO_TRANS) { | 
					
						
							| 
									
										
										
										
											2020-11-04 19:23:19 +08:00
										 |  |  |         ERR_raise(ERR_LIB_CMS, CMS_R_NOT_KEY_TRANSPORT); | 
					
						
							| 
									
										
										
										
											2008-03-17 21:38:51 +08:00
										 |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ktri = ri->d.ktri; | 
					
						
							| 
									
										
										
										
											2021-02-18 12:03:25 +08:00
										 |  |  |     ec = ossl_cms_get0_env_enc_content(cms); | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-20 01:17:14 +08:00
										 |  |  |     pctx = ktri->pctx; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-20 01:17:14 +08:00
										 |  |  |     if (pctx) { | 
					
						
							| 
									
										
										
										
											2021-02-18 12:03:25 +08:00
										 |  |  |         if (!ossl_cms_env_asn1_ctrl(ri, 0)) | 
					
						
							| 
									
										
										
										
											2013-06-20 01:17:14 +08:00
										 |  |  |             goto err; | 
					
						
							|  |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2021-02-18 12:03:25 +08:00
										 |  |  |         pctx = EVP_PKEY_CTX_new_from_pkey(ossl_cms_ctx_get0_libctx(ctx), | 
					
						
							|  |  |  |                                           ktri->pkey, | 
					
						
							|  |  |  |                                           ossl_cms_ctx_get0_propq(ctx)); | 
					
						
							| 
									
										
										
										
											2015-10-30 19:12:26 +08:00
										 |  |  |         if (pctx == NULL) | 
					
						
							| 
									
										
										
										
											2013-06-20 01:17:14 +08:00
										 |  |  |             return 0; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-20 01:17:14 +08:00
										 |  |  |         if (EVP_PKEY_encrypt_init(pctx) <= 0) | 
					
						
							|  |  |  |             goto err; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-17 21:38:51 +08:00
										 |  |  |     if (EVP_PKEY_encrypt(pctx, NULL, &eklen, ec->key, ec->keylen) <= 0) | 
					
						
							|  |  |  |         goto err; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-17 21:38:51 +08:00
										 |  |  |     ek = OPENSSL_malloc(eklen); | 
					
						
							| 
									
										
										
										
											2022-09-29 19:57:34 +08:00
										 |  |  |     if (ek == NULL) | 
					
						
							| 
									
										
										
										
											2008-03-17 21:38:51 +08:00
										 |  |  |         goto err; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-17 21:38:51 +08:00
										 |  |  |     if (EVP_PKEY_encrypt(pctx, ek, &eklen, ec->key, ec->keylen) <= 0) | 
					
						
							|  |  |  |         goto err; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-11 16:48:01 +08:00
										 |  |  |     ASN1_STRING_set0(ktri->encryptedKey, ek, (int)eklen); | 
					
						
							| 
									
										
										
										
											2008-03-17 21:38:51 +08:00
										 |  |  |     ek = NULL; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-17 21:38:51 +08:00
										 |  |  |     ret = 1; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-17 21:38:51 +08:00
										 |  |  |  err: | 
					
						
							| 
									
										
										
										
											2015-05-02 02:37:16 +08:00
										 |  |  |     EVP_PKEY_CTX_free(pctx); | 
					
						
							|  |  |  |     ktri->pctx = NULL; | 
					
						
							| 
									
										
										
										
											2015-05-01 22:02:07 +08:00
										 |  |  |     OPENSSL_free(ek); | 
					
						
							| 
									
										
										
										
											2008-03-17 21:38:51 +08:00
										 |  |  |     return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-19 21:53:52 +08:00
										 |  |  | /* Decrypt content key from KTRI */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-18 09:00:38 +08:00
										 |  |  | static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms, | 
					
						
							|  |  |  |                                           CMS_RecipientInfo *ri) | 
					
						
							| 
									
										
										
										
											2008-03-16 07:21:33 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-03-18 09:00:38 +08:00
										 |  |  |     CMS_KeyTransRecipientInfo *ktri = ri->d.ktri; | 
					
						
							| 
									
										
										
										
											2013-06-20 01:17:14 +08:00
										 |  |  |     EVP_PKEY *pkey = ktri->pkey; | 
					
						
							| 
									
										
										
										
											2008-03-16 07:21:33 +08:00
										 |  |  |     unsigned char *ek = NULL; | 
					
						
							|  |  |  |     size_t eklen; | 
					
						
							| 
									
										
										
										
											2008-03-19 02:18:25 +08:00
										 |  |  |     int ret = 0; | 
					
						
							| 
									
										
										
										
											2019-09-01 06:16:28 +08:00
										 |  |  |     size_t fixlen = 0; | 
					
						
							| 
									
										
										
										
											2020-08-20 11:28:11 +08:00
										 |  |  |     const EVP_CIPHER *cipher = NULL; | 
					
						
							|  |  |  |     EVP_CIPHER *fetched_cipher = NULL; | 
					
						
							| 
									
										
										
										
											2012-03-13 00:31:39 +08:00
										 |  |  |     CMS_EncryptedContentInfo *ec; | 
					
						
							| 
									
										
										
										
											2021-02-18 12:03:25 +08:00
										 |  |  |     const CMS_CTX *ctx = ossl_cms_get0_cmsctx(cms); | 
					
						
							|  |  |  |     OSSL_LIB_CTX *libctx = ossl_cms_ctx_get0_libctx(ctx); | 
					
						
							|  |  |  |     const char *propq = ossl_cms_ctx_get0_propq(ctx); | 
					
						
							| 
									
										
										
										
											2020-07-25 16:04:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-18 12:03:25 +08:00
										 |  |  |     ec = ossl_cms_get0_env_enc_content(cms); | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-18 09:00:38 +08:00
										 |  |  |     if (ktri->pkey == NULL) { | 
					
						
							| 
									
										
										
										
											2020-11-04 19:23:19 +08:00
										 |  |  |         ERR_raise(ERR_LIB_CMS, CMS_R_NO_PRIVATE_KEY); | 
					
						
							| 
									
										
										
										
											2008-03-16 07:21:33 +08:00
										 |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-01 06:16:28 +08:00
										 |  |  |     if (cms->d.envelopedData->encryptedContentInfo->havenocert | 
					
						
							|  |  |  |             && !cms->d.envelopedData->encryptedContentInfo->debug) { | 
					
						
							|  |  |  |         X509_ALGOR *calg = ec->contentEncryptionAlgorithm; | 
					
						
							| 
									
										
										
										
											2021-03-10 19:58:53 +08:00
										 |  |  |         char name[OSSL_MAX_NAME_SIZE]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         OBJ_obj2txt(name, sizeof(name), calg->algorithm, 0); | 
					
						
							| 
									
										
										
										
											2019-09-01 06:16:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-20 11:28:11 +08:00
										 |  |  |         (void)ERR_set_mark(); | 
					
						
							| 
									
										
										
										
											2020-12-11 17:19:37 +08:00
										 |  |  |         fetched_cipher = EVP_CIPHER_fetch(libctx, name, propq); | 
					
						
							| 
									
										
										
										
											2020-08-20 11:28:11 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (fetched_cipher != NULL) | 
					
						
							|  |  |  |             cipher = fetched_cipher; | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             cipher = EVP_get_cipherbyobj(calg->algorithm); | 
					
						
							|  |  |  |         if (cipher == NULL) { | 
					
						
							|  |  |  |             (void)ERR_clear_last_mark(); | 
					
						
							| 
									
										
										
										
											2020-11-04 19:23:19 +08:00
										 |  |  |             ERR_raise(ERR_LIB_CMS, CMS_R_UNKNOWN_CIPHER); | 
					
						
							| 
									
										
										
										
											2019-09-01 06:16:28 +08:00
										 |  |  |             return 0; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-08-20 11:28:11 +08:00
										 |  |  |         (void)ERR_pop_to_mark(); | 
					
						
							| 
									
										
										
										
											2019-09-01 06:16:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
											
												Rename all getters to use get/get0 in name
For functions that exist in 1.1.1 provide a simple aliases via #define.
Fixes #15236
Functions with OSSL_DECODER_, OSSL_ENCODER_, OSSL_STORE_LOADER_,
EVP_KEYEXCH_, EVP_KEM_, EVP_ASYM_CIPHER_, EVP_SIGNATURE_,
EVP_KEYMGMT_, EVP_RAND_, EVP_MAC_, EVP_KDF_, EVP_PKEY_,
EVP_MD_, and EVP_CIPHER_ prefixes are renamed.
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15405)
											
										 
											2021-05-21 22:58:08 +08:00
										 |  |  |         fixlen = EVP_CIPHER_get_key_length(cipher); | 
					
						
							| 
									
										
										
										
											2020-08-20 11:28:11 +08:00
										 |  |  |         EVP_CIPHER_free(fetched_cipher); | 
					
						
							| 
									
										
										
										
											2019-09-01 06:16:28 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-11 17:19:37 +08:00
										 |  |  |     ktri->pctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, propq); | 
					
						
							| 
									
										
										
										
											2015-10-30 19:12:26 +08:00
										 |  |  |     if (ktri->pctx == NULL) | 
					
						
							| 
									
										
										
										
											2020-07-25 16:04:55 +08:00
										 |  |  |         goto err; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-20 01:17:14 +08:00
										 |  |  |     if (EVP_PKEY_decrypt_init(ktri->pctx) <= 0) | 
					
						
							|  |  |  |         goto err; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-18 12:03:25 +08:00
										 |  |  |     if (!ossl_cms_env_asn1_ctrl(ri, 1)) | 
					
						
							| 
									
										
										
										
											2008-03-16 07:21:33 +08:00
										 |  |  |         goto err; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-28 01:16:58 +08:00
										 |  |  |     if (EVP_PKEY_is_a(pkey, "RSA")) | 
					
						
							|  |  |  |         /* upper layer CMS code incorrectly assumes that a successful RSA
 | 
					
						
							|  |  |  |          * decryption means that the key matches ciphertext (which never | 
					
						
							|  |  |  |          * was the case, implicit rejection or not), so to make it work | 
					
						
							|  |  |  |          * disable implicit rejection for RSA keys */ | 
					
						
							|  |  |  |         EVP_PKEY_CTX_ctrl_str(ktri->pctx, "rsa_pkcs1_implicit_rejection", "0"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-25 20:38:23 +08:00
										 |  |  |     if (evp_pkey_decrypt_alloc(ktri->pctx, &ek, &eklen, fixlen, | 
					
						
							|  |  |  |                                ktri->encryptedKey->data, | 
					
						
							|  |  |  |                                ktri->encryptedKey->length) <= 0) | 
					
						
							| 
									
										
										
										
											2008-03-16 07:21:33 +08:00
										 |  |  |         goto err; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-16 07:21:33 +08:00
										 |  |  |     ret = 1; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-01 05:57:32 +08:00
										 |  |  |     OPENSSL_clear_free(ec->key, ec->keylen); | 
					
						
							| 
									
										
										
										
											2012-03-13 00:31:39 +08:00
										 |  |  |     ec->key = ek; | 
					
						
							|  |  |  |     ec->keylen = eklen; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-16 07:21:33 +08:00
										 |  |  |  err: | 
					
						
							| 
									
										
										
										
											2015-03-28 22:54:15 +08:00
										 |  |  |     EVP_PKEY_CTX_free(ktri->pctx); | 
					
						
							|  |  |  |     ktri->pctx = NULL; | 
					
						
							| 
									
										
										
										
											2015-05-01 22:02:07 +08:00
										 |  |  |     if (!ret) | 
					
						
							| 
									
										
										
										
											2008-03-16 07:21:33 +08:00
										 |  |  |         OPENSSL_free(ek); | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-16 07:21:33 +08:00
										 |  |  |     return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-19 21:53:52 +08:00
										 |  |  | /* Key Encrypted Key (KEK) RecipientInfo routines */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-20 02:39:51 +08:00
										 |  |  | int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri, | 
					
						
							|  |  |  |                                    const unsigned char *id, size_t idlen) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     ASN1_OCTET_STRING tmp_os; | 
					
						
							|  |  |  |     CMS_KEKRecipientInfo *kekri; | 
					
						
							|  |  |  |     if (ri->type != CMS_RECIPINFO_KEK) { | 
					
						
							| 
									
										
										
										
											2020-11-04 19:23:19 +08:00
										 |  |  |         ERR_raise(ERR_LIB_CMS, CMS_R_NOT_KEK); | 
					
						
							| 
									
										
										
										
											2008-03-20 02:39:51 +08:00
										 |  |  |         return -2; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     kekri = ri->d.kekri; | 
					
						
							|  |  |  |     tmp_os.type = V_ASN1_OCTET_STRING; | 
					
						
							|  |  |  |     tmp_os.flags = 0; | 
					
						
							|  |  |  |     tmp_os.data = (unsigned char *)id; | 
					
						
							|  |  |  |     tmp_os.length = (int)idlen; | 
					
						
							|  |  |  |     return ASN1_OCTET_STRING_cmp(&tmp_os, kekri->kekid->keyIdentifier); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-19 21:53:52 +08:00
										 |  |  | /* For now hard code AES key wrap info */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static size_t aes_wrap_keylen(int nid) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     switch (nid) { | 
					
						
							|  |  |  |     case NID_id_aes128_wrap: | 
					
						
							|  |  |  |         return 16; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case NID_id_aes192_wrap: | 
					
						
							|  |  |  |         return 24; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case NID_id_aes256_wrap: | 
					
						
							|  |  |  |         return 32; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid, | 
					
						
							|  |  |  |                                           unsigned char *key, size_t keylen, | 
					
						
							|  |  |  |                                           unsigned char *id, size_t idlen, | 
					
						
							|  |  |  |                                           ASN1_GENERALIZEDTIME *date, | 
					
						
							|  |  |  |                                           ASN1_OBJECT *otherTypeId, | 
					
						
							|  |  |  |                                           ASN1_TYPE *otherType) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     CMS_RecipientInfo *ri = NULL; | 
					
						
							|  |  |  |     CMS_KEKRecipientInfo *kekri; | 
					
						
							| 
									
										
										
										
											2020-09-07 02:11:34 +08:00
										 |  |  |     STACK_OF(CMS_RecipientInfo) *ris = CMS_get0_RecipientInfos(cms); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-11 16:48:01 +08:00
										 |  |  |     if (ris == NULL || idlen > INT_MAX) | 
					
						
							| 
									
										
										
										
											2008-03-19 21:53:52 +08:00
										 |  |  |         goto err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (nid == NID_undef) { | 
					
						
							|  |  |  |         switch (keylen) { | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |         case 16: | 
					
						
							| 
									
										
										
										
											2008-03-19 21:53:52 +08:00
										 |  |  |             nid = NID_id_aes128_wrap; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |             break; | 
					
						
							| 
									
										
										
										
											2008-03-19 21:53:52 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         case 24: | 
					
						
							|  |  |  |             nid = NID_id_aes192_wrap; | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-19 21:53:52 +08:00
										 |  |  |         case 32: | 
					
						
							|  |  |  |             nid = NID_id_aes256_wrap; | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         default: | 
					
						
							| 
									
										
										
										
											2020-11-04 19:23:19 +08:00
										 |  |  |             ERR_raise(ERR_LIB_CMS, CMS_R_INVALID_KEY_LENGTH); | 
					
						
							| 
									
										
										
										
											2008-03-19 21:53:52 +08:00
										 |  |  |             goto err; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-19 21:53:52 +08:00
										 |  |  |         size_t exp_keylen = aes_wrap_keylen(nid); | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-19 21:53:52 +08:00
										 |  |  |         if (!exp_keylen) { | 
					
						
							| 
									
										
										
										
											2020-11-04 19:23:19 +08:00
										 |  |  |             ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_KEK_ALGORITHM); | 
					
						
							| 
									
										
										
										
											2008-03-19 21:53:52 +08:00
										 |  |  |             goto err; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-19 21:53:52 +08:00
										 |  |  |         if (keylen != exp_keylen) { | 
					
						
							| 
									
										
										
										
											2020-11-04 19:23:19 +08:00
										 |  |  |             ERR_raise(ERR_LIB_CMS, CMS_R_INVALID_KEY_LENGTH); | 
					
						
							| 
									
										
										
										
											2008-03-19 21:53:52 +08:00
										 |  |  |             goto err; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-19 21:53:52 +08:00
										 |  |  |     /* Initialize recipient info */ | 
					
						
							|  |  |  |     ri = M_ASN1_new_of(CMS_RecipientInfo); | 
					
						
							| 
									
										
										
										
											2022-09-29 19:57:34 +08:00
										 |  |  |     if (!ri) { | 
					
						
							|  |  |  |         ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB); | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-19 21:53:52 +08:00
										 |  |  |     ri->d.kekri = M_ASN1_new_of(CMS_KEKRecipientInfo); | 
					
						
							| 
									
										
										
										
											2022-09-29 19:57:34 +08:00
										 |  |  |     if (!ri->d.kekri) { | 
					
						
							|  |  |  |         ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB); | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2025-04-03 18:19:43 +08:00
										 |  |  |     ri->encoded_type = ri->type = CMS_RECIPINFO_KEK; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-19 21:53:52 +08:00
										 |  |  |     kekri = ri->d.kekri; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-19 21:53:52 +08:00
										 |  |  |     if (otherTypeId) { | 
					
						
							|  |  |  |         kekri->kekid->other = M_ASN1_new_of(CMS_OtherKeyAttribute); | 
					
						
							| 
									
										
										
										
											2022-09-29 19:57:34 +08:00
										 |  |  |         if (kekri->kekid->other == NULL) { | 
					
						
							|  |  |  |             ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB); | 
					
						
							|  |  |  |             goto err; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2008-03-19 21:53:52 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-29 19:57:34 +08:00
										 |  |  |     if (!sk_CMS_RecipientInfo_push(ris, ri)) { | 
					
						
							|  |  |  |         ERR_raise(ERR_LIB_CMS, ERR_R_CRYPTO_LIB); | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-19 21:53:52 +08:00
										 |  |  |     /* After this point no calls can fail */ | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-19 21:53:52 +08:00
										 |  |  |     kekri->version = 4; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-19 21:53:52 +08:00
										 |  |  |     kekri->key = key; | 
					
						
							|  |  |  |     kekri->keylen = keylen; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-11 16:48:01 +08:00
										 |  |  |     ASN1_STRING_set0(kekri->kekid->keyIdentifier, id, (int)idlen); | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-19 21:53:52 +08:00
										 |  |  |     kekri->kekid->date = date; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-19 21:53:52 +08:00
										 |  |  |     if (kekri->kekid->other) { | 
					
						
							|  |  |  |         kekri->kekid->other->keyAttrId = otherTypeId; | 
					
						
							|  |  |  |         kekri->kekid->other->keyAttr = otherType; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-06 18:11:13 +08:00
										 |  |  |     (void)X509_ALGOR_set0(kekri->keyEncryptionAlgorithm, OBJ_nid2obj(nid), | 
					
						
							|  |  |  |                           V_ASN1_UNDEF, NULL); /* cannot fail */ | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-19 21:53:52 +08:00
										 |  |  |     return ri; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |  err: | 
					
						
							| 
									
										
										
										
											2015-04-30 23:30:03 +08:00
										 |  |  |     M_ASN1_free_of(ri, CMS_RecipientInfo); | 
					
						
							| 
									
										
										
										
											2008-03-19 21:53:52 +08:00
										 |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-13 05:14:28 +08:00
										 |  |  | int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri, | 
					
						
							| 
									
										
										
										
											2008-03-19 21:53:52 +08:00
										 |  |  |                                     X509_ALGOR **palg, | 
					
						
							|  |  |  |                                     ASN1_OCTET_STRING **pid, | 
					
						
							|  |  |  |                                     ASN1_GENERALIZEDTIME **pdate, | 
					
						
							|  |  |  |                                     ASN1_OBJECT **potherid, | 
					
						
							|  |  |  |                                     ASN1_TYPE **pothertype) | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-03-19 21:53:52 +08:00
										 |  |  |     CMS_KEKIdentifier *rkid; | 
					
						
							|  |  |  |     if (ri->type != CMS_RECIPINFO_KEK) { | 
					
						
							| 
									
										
										
										
											2020-11-04 19:23:19 +08:00
										 |  |  |         ERR_raise(ERR_LIB_CMS, CMS_R_NOT_KEK); | 
					
						
							| 
									
										
										
										
											2008-03-19 21:53:52 +08:00
										 |  |  |         return 0; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-03-19 21:53:52 +08:00
										 |  |  |     rkid = ri->d.kekri->kekid; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |     if (palg) | 
					
						
							| 
									
										
										
										
											2008-03-20 02:39:51 +08:00
										 |  |  |         *palg = ri->d.kekri->keyEncryptionAlgorithm; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |     if (pid) | 
					
						
							| 
									
										
										
										
											2008-03-19 21:53:52 +08:00
										 |  |  |         *pid = rkid->keyIdentifier; | 
					
						
							|  |  |  |     if (pdate) | 
					
						
							|  |  |  |         *pdate = rkid->date; | 
					
						
							|  |  |  |     if (potherid) { | 
					
						
							|  |  |  |         if (rkid->other) | 
					
						
							|  |  |  |             *potherid = rkid->other->keyAttrId; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |         else | 
					
						
							| 
									
										
										
										
											2008-03-19 21:53:52 +08:00
										 |  |  |             *potherid = NULL; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-03-19 21:53:52 +08:00
										 |  |  |     if (pothertype) { | 
					
						
							|  |  |  |         if (rkid->other) | 
					
						
							|  |  |  |             *pothertype = rkid->other->keyAttr; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |         else | 
					
						
							| 
									
										
										
										
											2008-03-19 21:53:52 +08:00
										 |  |  |             *pothertype = NULL; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-03-19 21:53:52 +08:00
										 |  |  |     return 1; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-18 09:00:38 +08:00
										 |  |  | int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri, | 
					
						
							| 
									
										
										
										
											2008-03-19 21:53:52 +08:00
										 |  |  |                                unsigned char *key, size_t keylen) | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-03-18 09:00:38 +08:00
										 |  |  |     CMS_KEKRecipientInfo *kekri; | 
					
						
							| 
									
										
										
										
											2008-03-19 21:53:52 +08:00
										 |  |  |     if (ri->type != CMS_RECIPINFO_KEK) { | 
					
						
							| 
									
										
										
										
											2020-11-04 19:23:19 +08:00
										 |  |  |         ERR_raise(ERR_LIB_CMS, CMS_R_NOT_KEK); | 
					
						
							| 
									
										
										
										
											2008-03-19 21:53:52 +08:00
										 |  |  |         return 0; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-19 21:53:52 +08:00
										 |  |  |     kekri = ri->d.kekri; | 
					
						
							|  |  |  |     kekri->key = key; | 
					
						
							|  |  |  |     kekri->keylen = keylen; | 
					
						
							|  |  |  |     return 1; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2008-03-18 09:00:38 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-25 16:04:55 +08:00
										 |  |  | static EVP_CIPHER *cms_get_key_wrap_cipher(size_t keylen, const CMS_CTX *ctx) | 
					
						
							| 
									
										
										
										
											2019-12-06 02:01:44 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-25 16:04:55 +08:00
										 |  |  |     const char *alg = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-26 15:16:18 +08:00
										 |  |  |     switch (keylen) { | 
					
						
							| 
									
										
										
										
											2019-12-06 02:01:44 +08:00
										 |  |  |     case 16: | 
					
						
							| 
									
										
										
										
											2020-07-25 16:04:55 +08:00
										 |  |  |         alg = "AES-128-WRAP"; | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2019-12-06 02:01:44 +08:00
										 |  |  |     case 24: | 
					
						
							| 
									
										
										
										
											2020-07-25 16:04:55 +08:00
										 |  |  |         alg = "AES-192-WRAP"; | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2019-12-06 02:01:44 +08:00
										 |  |  |     case 32: | 
					
						
							| 
									
										
										
										
											2020-07-25 16:04:55 +08:00
										 |  |  |         alg = "AES-256-WRAP"; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         return NULL; | 
					
						
							| 
									
										
										
										
											2019-12-06 02:01:44 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-02-18 12:03:25 +08:00
										 |  |  |     return EVP_CIPHER_fetch(ossl_cms_ctx_get0_libctx(ctx), alg, | 
					
						
							|  |  |  |                             ossl_cms_ctx_get0_propq(ctx)); | 
					
						
							| 
									
										
										
										
											2019-12-06 02:01:44 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-18 09:00:38 +08:00
										 |  |  | /* Encrypt content key in KEK recipient info */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-16 04:51:25 +08:00
										 |  |  | static int cms_RecipientInfo_kekri_encrypt(const CMS_ContentInfo *cms, | 
					
						
							| 
									
										
										
										
											2008-03-18 09:00:38 +08:00
										 |  |  |                                            CMS_RecipientInfo *ri) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     CMS_EncryptedContentInfo *ec; | 
					
						
							|  |  |  |     CMS_KEKRecipientInfo *kekri; | 
					
						
							|  |  |  |     unsigned char *wkey = NULL; | 
					
						
							|  |  |  |     int wkeylen; | 
					
						
							|  |  |  |     int r = 0; | 
					
						
							| 
									
										
										
										
											2020-07-25 16:04:55 +08:00
										 |  |  |     EVP_CIPHER *cipher = NULL; | 
					
						
							| 
									
										
										
										
											2019-12-06 02:01:44 +08:00
										 |  |  |     int outlen = 0; | 
					
						
							|  |  |  |     EVP_CIPHER_CTX *ctx = NULL; | 
					
						
							| 
									
										
										
										
											2021-02-18 12:03:25 +08:00
										 |  |  |     const CMS_CTX *cms_ctx = ossl_cms_get0_cmsctx(cms); | 
					
						
							| 
									
										
										
										
											2008-03-18 09:00:38 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-18 12:03:25 +08:00
										 |  |  |     ec = ossl_cms_get0_env_enc_content(cms); | 
					
						
							| 
									
										
										
										
											2020-09-07 02:11:34 +08:00
										 |  |  |     if (ec == NULL) | 
					
						
							|  |  |  |         return 0; | 
					
						
							| 
									
										
										
										
											2008-03-18 09:00:38 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     kekri = ri->d.kekri; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-06 02:01:44 +08:00
										 |  |  |     if (kekri->key == NULL) { | 
					
						
							| 
									
										
										
										
											2020-11-04 19:23:19 +08:00
										 |  |  |         ERR_raise(ERR_LIB_CMS, CMS_R_NO_KEY); | 
					
						
							| 
									
										
										
										
											2008-03-18 09:00:38 +08:00
										 |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-25 16:04:55 +08:00
										 |  |  |     cipher = cms_get_key_wrap_cipher(kekri->keylen, cms_ctx); | 
					
						
							| 
									
										
										
										
											2019-12-06 02:01:44 +08:00
										 |  |  |     if (cipher == NULL) { | 
					
						
							| 
									
										
										
										
											2020-11-04 19:23:19 +08:00
										 |  |  |         ERR_raise(ERR_LIB_CMS, CMS_R_INVALID_KEY_LENGTH); | 
					
						
							| 
									
										
										
										
											2008-03-18 09:00:38 +08:00
										 |  |  |         goto err; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-06 02:01:44 +08:00
										 |  |  |     /* 8 byte prefix for AES wrap ciphers */ | 
					
						
							| 
									
										
										
										
											2008-03-18 09:00:38 +08:00
										 |  |  |     wkey = OPENSSL_malloc(ec->keylen + 8); | 
					
						
							| 
									
										
										
										
											2022-09-29 19:57:34 +08:00
										 |  |  |     if (wkey == NULL) | 
					
						
							| 
									
										
										
										
											2008-03-18 09:00:38 +08:00
										 |  |  |         goto err; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-06 02:01:44 +08:00
										 |  |  |     ctx = EVP_CIPHER_CTX_new(); | 
					
						
							|  |  |  |     if (ctx == NULL) { | 
					
						
							| 
									
										
										
										
											2022-09-29 19:57:34 +08:00
										 |  |  |         ERR_raise(ERR_LIB_CMS, ERR_R_EVP_LIB); | 
					
						
							| 
									
										
										
										
											2019-12-06 02:01:44 +08:00
										 |  |  |         goto err; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-03-18 09:00:38 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-06 02:01:44 +08:00
										 |  |  |     EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW); | 
					
						
							|  |  |  |     if (!EVP_EncryptInit_ex(ctx, cipher, NULL, kekri->key, NULL) | 
					
						
							| 
									
										
										
										
											2025-06-11 16:48:01 +08:00
										 |  |  |             || !EVP_EncryptUpdate(ctx, wkey, &wkeylen, ec->key, (int)ec->keylen) | 
					
						
							| 
									
										
										
										
											2019-12-06 02:01:44 +08:00
										 |  |  |             || !EVP_EncryptFinal_ex(ctx, wkey + wkeylen, &outlen)) { | 
					
						
							| 
									
										
										
										
											2020-11-04 19:23:19 +08:00
										 |  |  |         ERR_raise(ERR_LIB_CMS, CMS_R_WRAP_ERROR); | 
					
						
							| 
									
										
										
										
											2019-12-06 02:01:44 +08:00
										 |  |  |         goto err; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     wkeylen += outlen; | 
					
						
							|  |  |  |     if (!ossl_assert((size_t)wkeylen == ec->keylen + 8)) { | 
					
						
							| 
									
										
										
										
											2020-11-04 19:23:19 +08:00
										 |  |  |         ERR_raise(ERR_LIB_CMS, CMS_R_WRAP_ERROR); | 
					
						
							| 
									
										
										
										
											2008-03-18 09:00:38 +08:00
										 |  |  |         goto err; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ASN1_STRING_set0(kekri->encryptedKey, wkey, wkeylen); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     r = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  err: | 
					
						
							| 
									
										
										
										
											2020-07-25 16:04:55 +08:00
										 |  |  |     EVP_CIPHER_free(cipher); | 
					
						
							| 
									
										
										
										
											2015-05-01 22:02:07 +08:00
										 |  |  |     if (!r) | 
					
						
							| 
									
										
										
										
											2008-03-18 09:00:38 +08:00
										 |  |  |         OPENSSL_free(wkey); | 
					
						
							| 
									
										
										
										
											2019-12-06 02:01:44 +08:00
										 |  |  |     EVP_CIPHER_CTX_free(ctx); | 
					
						
							| 
									
										
										
										
											2008-03-18 09:00:38 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return r; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-19 21:53:52 +08:00
										 |  |  | /* Decrypt content key in KEK recipient info */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-18 09:00:38 +08:00
										 |  |  | static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms, | 
					
						
							|  |  |  |                                            CMS_RecipientInfo *ri) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     CMS_EncryptedContentInfo *ec; | 
					
						
							|  |  |  |     CMS_KEKRecipientInfo *kekri; | 
					
						
							|  |  |  |     unsigned char *ukey = NULL; | 
					
						
							|  |  |  |     int ukeylen; | 
					
						
							| 
									
										
										
										
											2008-03-20 02:39:51 +08:00
										 |  |  |     int r = 0, wrap_nid; | 
					
						
							| 
									
										
										
										
											2020-07-25 16:04:55 +08:00
										 |  |  |     EVP_CIPHER *cipher = NULL; | 
					
						
							| 
									
										
										
										
											2019-12-06 02:01:44 +08:00
										 |  |  |     int outlen = 0; | 
					
						
							|  |  |  |     EVP_CIPHER_CTX *ctx = NULL; | 
					
						
							| 
									
										
										
										
											2021-02-18 12:03:25 +08:00
										 |  |  |     const CMS_CTX *cms_ctx = ossl_cms_get0_cmsctx(cms); | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-18 12:03:25 +08:00
										 |  |  |     ec = ossl_cms_get0_env_enc_content(cms); | 
					
						
							| 
									
										
										
										
											2020-09-07 02:11:34 +08:00
										 |  |  |     if (ec == NULL) | 
					
						
							|  |  |  |         return 0; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-18 09:00:38 +08:00
										 |  |  |     kekri = ri->d.kekri; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-18 09:00:38 +08:00
										 |  |  |     if (!kekri->key) { | 
					
						
							| 
									
										
										
										
											2020-11-04 19:23:19 +08:00
										 |  |  |         ERR_raise(ERR_LIB_CMS, CMS_R_NO_KEY); | 
					
						
							| 
									
										
										
										
											2008-03-18 09:00:38 +08:00
										 |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-20 02:39:51 +08:00
										 |  |  |     wrap_nid = OBJ_obj2nid(kekri->keyEncryptionAlgorithm->algorithm); | 
					
						
							|  |  |  |     if (aes_wrap_keylen(wrap_nid) != kekri->keylen) { | 
					
						
							| 
									
										
										
										
											2020-11-04 19:23:19 +08:00
										 |  |  |         ERR_raise(ERR_LIB_CMS, CMS_R_INVALID_KEY_LENGTH); | 
					
						
							| 
									
										
										
										
											2008-03-20 02:39:51 +08:00
										 |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-18 09:00:38 +08:00
										 |  |  |     /* If encrypted key length is invalid don't bother */ | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-18 09:00:38 +08:00
										 |  |  |     if (kekri->encryptedKey->length < 16) { | 
					
						
							| 
									
										
										
										
											2020-11-04 19:23:19 +08:00
										 |  |  |         ERR_raise(ERR_LIB_CMS, CMS_R_INVALID_ENCRYPTED_KEY_LENGTH); | 
					
						
							| 
									
										
										
										
											2008-03-18 09:00:38 +08:00
										 |  |  |         goto err; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-25 16:04:55 +08:00
										 |  |  |     cipher = cms_get_key_wrap_cipher(kekri->keylen, cms_ctx); | 
					
						
							| 
									
										
										
										
											2019-12-06 02:01:44 +08:00
										 |  |  |     if (cipher == NULL) { | 
					
						
							| 
									
										
										
										
											2020-11-04 19:23:19 +08:00
										 |  |  |         ERR_raise(ERR_LIB_CMS, CMS_R_INVALID_KEY_LENGTH); | 
					
						
							| 
									
										
										
										
											2008-03-18 09:00:38 +08:00
										 |  |  |         goto err; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-18 09:00:38 +08:00
										 |  |  |     ukey = OPENSSL_malloc(kekri->encryptedKey->length - 8); | 
					
						
							| 
									
										
										
										
											2022-09-29 19:57:34 +08:00
										 |  |  |     if (ukey == NULL) | 
					
						
							| 
									
										
										
										
											2008-03-18 09:00:38 +08:00
										 |  |  |         goto err; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-06 02:01:44 +08:00
										 |  |  |     ctx = EVP_CIPHER_CTX_new(); | 
					
						
							|  |  |  |     if (ctx == NULL) { | 
					
						
							| 
									
										
										
										
											2022-09-29 19:57:34 +08:00
										 |  |  |         ERR_raise(ERR_LIB_CMS, ERR_R_EVP_LIB); | 
					
						
							| 
									
										
										
										
											2019-12-06 02:01:44 +08:00
										 |  |  |         goto err; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-06 02:01:44 +08:00
										 |  |  |     if (!EVP_DecryptInit_ex(ctx, cipher, NULL, kekri->key, NULL) | 
					
						
							|  |  |  |             || !EVP_DecryptUpdate(ctx, ukey, &ukeylen, | 
					
						
							|  |  |  |                                   kekri->encryptedKey->data, | 
					
						
							|  |  |  |                                   kekri->encryptedKey->length) | 
					
						
							|  |  |  |             || !EVP_DecryptFinal_ex(ctx, ukey + ukeylen, &outlen)) { | 
					
						
							| 
									
										
										
										
											2020-11-04 19:23:19 +08:00
										 |  |  |         ERR_raise(ERR_LIB_CMS, CMS_R_UNWRAP_ERROR); | 
					
						
							| 
									
										
										
										
											2008-03-18 09:00:38 +08:00
										 |  |  |         goto err; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-12-06 02:01:44 +08:00
										 |  |  |     ukeylen += outlen; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-24 22:43:18 +08:00
										 |  |  |     OPENSSL_clear_free(ec->key, ec->keylen); | 
					
						
							| 
									
										
										
										
											2008-03-18 09:00:38 +08:00
										 |  |  |     ec->key = ukey; | 
					
						
							|  |  |  |     ec->keylen = ukeylen; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-18 09:00:38 +08:00
										 |  |  |     r = 1; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-18 09:00:38 +08:00
										 |  |  |  err: | 
					
						
							| 
									
										
										
										
											2020-07-25 16:04:55 +08:00
										 |  |  |     EVP_CIPHER_free(cipher); | 
					
						
							| 
									
										
										
										
											2015-05-01 22:02:07 +08:00
										 |  |  |     if (!r) | 
					
						
							| 
									
										
										
										
											2008-03-18 09:00:38 +08:00
										 |  |  |         OPENSSL_free(ukey); | 
					
						
							| 
									
										
										
										
											2019-12-06 02:01:44 +08:00
										 |  |  |     EVP_CIPHER_CTX_free(ctx); | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-18 09:00:38 +08:00
										 |  |  |     return r; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     switch (ri->type) { | 
					
						
							|  |  |  |     case CMS_RECIPINFO_TRANS: | 
					
						
							|  |  |  |         return cms_RecipientInfo_ktri_decrypt(cms, ri); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case CMS_RECIPINFO_KEK: | 
					
						
							|  |  |  |         return cms_RecipientInfo_kekri_decrypt(cms, ri); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-27 02:57:39 +08:00
										 |  |  |     case CMS_RECIPINFO_PASS: | 
					
						
							| 
									
										
										
										
											2021-02-18 12:03:25 +08:00
										 |  |  |         return ossl_cms_RecipientInfo_pwri_crypt(cms, ri, 0); | 
					
						
							| 
									
										
										
										
											2009-11-27 02:57:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-03 18:19:43 +08:00
										 |  |  |     case CMS_RECIPINFO_KEM: | 
					
						
							|  |  |  |         return ossl_cms_RecipientInfo_kemri_decrypt(cms, ri); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-18 09:00:38 +08:00
										 |  |  |     default: | 
					
						
							| 
									
										
										
										
											2020-11-04 19:23:19 +08:00
										 |  |  |         ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_RECIPIENTINFO_TYPE); | 
					
						
							| 
									
										
										
										
											2008-03-18 09:00:38 +08:00
										 |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-16 04:51:25 +08:00
										 |  |  | int CMS_RecipientInfo_encrypt(const CMS_ContentInfo *cms, CMS_RecipientInfo *ri) | 
					
						
							| 
									
										
										
										
											2013-02-27 00:48:49 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     switch (ri->type) { | 
					
						
							|  |  |  |     case CMS_RECIPINFO_TRANS: | 
					
						
							|  |  |  |         return cms_RecipientInfo_ktri_encrypt(cms, ri); | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-17 21:36:39 +08:00
										 |  |  |     case CMS_RECIPINFO_AGREE: | 
					
						
							| 
									
										
										
										
											2021-02-18 12:03:25 +08:00
										 |  |  |         return ossl_cms_RecipientInfo_kari_encrypt(cms, ri); | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-27 00:48:49 +08:00
										 |  |  |     case CMS_RECIPINFO_KEK: | 
					
						
							|  |  |  |         return cms_RecipientInfo_kekri_encrypt(cms, ri); | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-27 00:48:49 +08:00
										 |  |  |     case CMS_RECIPINFO_PASS: | 
					
						
							| 
									
										
										
										
											2021-02-18 12:03:25 +08:00
										 |  |  |         return ossl_cms_RecipientInfo_pwri_crypt(cms, ri, 1); | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-03 18:19:43 +08:00
										 |  |  |     case CMS_RECIPINFO_KEM: | 
					
						
							|  |  |  |         return ossl_cms_RecipientInfo_kemri_encrypt(cms, ri); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-27 00:48:49 +08:00
										 |  |  |     default: | 
					
						
							| 
									
										
										
										
											2020-11-04 19:23:19 +08:00
										 |  |  |         ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_RECIPIENT_TYPE); | 
					
						
							| 
									
										
										
										
											2013-02-27 00:48:49 +08:00
										 |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-11 01:36:37 +08:00
										 |  |  | /* Check structures and fixup version numbers (if necessary) */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void cms_env_set_originfo_version(CMS_EnvelopedData *env) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     CMS_OriginatorInfo *org = env->originatorInfo; | 
					
						
							|  |  |  |     int i; | 
					
						
							|  |  |  |     if (org == NULL) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     for (i = 0; i < sk_CMS_CertificateChoices_num(org->certificates); i++) { | 
					
						
							|  |  |  |         CMS_CertificateChoices *cch; | 
					
						
							|  |  |  |         cch = sk_CMS_CertificateChoices_value(org->certificates, i); | 
					
						
							|  |  |  |         if (cch->type == CMS_CERTCHOICE_OTHER) { | 
					
						
							|  |  |  |             env->version = 4; | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         } else if (cch->type == CMS_CERTCHOICE_V2ACERT) { | 
					
						
							|  |  |  |             if (env->version < 3) | 
					
						
							|  |  |  |                 env->version = 3; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-11 01:36:37 +08:00
										 |  |  |     for (i = 0; i < sk_CMS_RevocationInfoChoice_num(org->crls); i++) { | 
					
						
							|  |  |  |         CMS_RevocationInfoChoice *rch; | 
					
						
							|  |  |  |         rch = sk_CMS_RevocationInfoChoice_value(org->crls, i); | 
					
						
							|  |  |  |         if (rch->type == CMS_REVCHOICE_OTHER) { | 
					
						
							|  |  |  |             env->version = 4; | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void cms_env_set_version(CMS_EnvelopedData *env) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int i; | 
					
						
							|  |  |  |     CMS_RecipientInfo *ri; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-11 01:36:37 +08:00
										 |  |  |     /*
 | 
					
						
							|  |  |  |      * Can't set version higher than 4 so if 4 or more already nothing to do. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     if (env->version >= 4) | 
					
						
							|  |  |  |         return; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-11 01:36:37 +08:00
										 |  |  |     cms_env_set_originfo_version(env); | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-11 01:36:37 +08:00
										 |  |  |     if (env->version >= 3) | 
					
						
							|  |  |  |         return; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-11 01:36:37 +08:00
										 |  |  |     for (i = 0; i < sk_CMS_RecipientInfo_num(env->recipientInfos); i++) { | 
					
						
							|  |  |  |         ri = sk_CMS_RecipientInfo_value(env->recipientInfos, i); | 
					
						
							| 
									
										
										
										
											2025-04-03 18:19:43 +08:00
										 |  |  |         if (ri->type == CMS_RECIPINFO_PASS || ri->type == CMS_RECIPINFO_OTHER | 
					
						
							|  |  |  |             || ri->type == CMS_RECIPINFO_KEM) { | 
					
						
							| 
									
										
										
										
											2013-07-11 01:36:37 +08:00
										 |  |  |             env->version = 3; | 
					
						
							|  |  |  |             return; | 
					
						
							| 
									
										
										
										
											2014-05-06 06:56:43 +08:00
										 |  |  |         } else if (ri->type != CMS_RECIPINFO_TRANS | 
					
						
							|  |  |  |                    || ri->d.ktri->version != 0) { | 
					
						
							| 
									
										
										
										
											2013-07-11 01:36:37 +08:00
										 |  |  |             env->version = 2; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2013-07-11 01:36:37 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |     if (env->originatorInfo || env->unprotectedAttrs) | 
					
						
							|  |  |  |         env->version = 2; | 
					
						
							| 
									
										
										
										
											2016-06-13 21:51:12 +08:00
										 |  |  |     if (env->version == 2) | 
					
						
							|  |  |  |         return; | 
					
						
							| 
									
										
										
										
											2013-07-11 01:36:37 +08:00
										 |  |  |     env->version = 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-07 02:11:34 +08:00
										 |  |  | static int cms_env_encrypt_content_key(const CMS_ContentInfo *cms, | 
					
						
							|  |  |  |                                        STACK_OF(CMS_RecipientInfo) *ris) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int i; | 
					
						
							|  |  |  |     CMS_RecipientInfo *ri; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) { | 
					
						
							|  |  |  |         ri = sk_CMS_RecipientInfo_value(ris, i); | 
					
						
							|  |  |  |         if (CMS_RecipientInfo_encrypt(cms, ri) <= 0) | 
					
						
							|  |  |  |             return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void cms_env_clear_ec(CMS_EncryptedContentInfo *ec) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     ec->cipher = NULL; | 
					
						
							|  |  |  |     OPENSSL_clear_free(ec->key, ec->keylen); | 
					
						
							|  |  |  |     ec->key = NULL; | 
					
						
							|  |  |  |     ec->keylen = 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-20 23:17:44 +08:00
										 |  |  | static BIO *cms_EnvelopedData_Decryption_init_bio(CMS_ContentInfo *cms) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     CMS_EncryptedContentInfo *ec = cms->d.envelopedData->encryptedContentInfo; | 
					
						
							| 
									
										
										
										
											2021-02-18 12:03:25 +08:00
										 |  |  |     BIO *contentBio = ossl_cms_EncryptedContent_init_bio(ec, | 
					
						
							|  |  |  |                                                          ossl_cms_get0_cmsctx(cms)); | 
					
						
							| 
									
										
										
										
											2020-01-20 23:17:44 +08:00
										 |  |  |     EVP_CIPHER_CTX *ctx = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (contentBio == NULL) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     BIO_get_cipher_ctx(contentBio, &ctx); | 
					
						
							|  |  |  |     if (ctx == NULL) { | 
					
						
							|  |  |  |         BIO_free(contentBio); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-09-07 02:11:34 +08:00
										 |  |  |     /*
 | 
					
						
							|  |  |  |      * If the selected cipher supports unprotected attributes, | 
					
						
							|  |  |  |      * deal with it using special ctrl function | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
											
												Rename all getters to use get/get0 in name
For functions that exist in 1.1.1 provide a simple aliases via #define.
Fixes #15236
Functions with OSSL_DECODER_, OSSL_ENCODER_, OSSL_STORE_LOADER_,
EVP_KEYEXCH_, EVP_KEM_, EVP_ASYM_CIPHER_, EVP_SIGNATURE_,
EVP_KEYMGMT_, EVP_RAND_, EVP_MAC_, EVP_KDF_, EVP_PKEY_,
EVP_MD_, and EVP_CIPHER_ prefixes are renamed.
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15405)
											
										 
											2021-05-21 22:58:08 +08:00
										 |  |  |     if ((EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(ctx)) | 
					
						
							| 
									
										
											  
											
												Add "origin" field to EVP_CIPHER, EVP_MD
Add a "where did this EVP_{CIPHER,MD} come from" flag: global, via fetch,
or via EVP_{CIPHER,MD}_meth_new.  Update EVP_{CIPHER,MD}_free to handle all
three origins. The flag is deliberately right before some function pointers,
so that compile-time failures (int/pointer) will occur, as opposed to
taking a bit in the existing "flags" field.  The "global variable" flag
is non-zero, so the default case of using OPENSSL_zalloc (for provider
ciphers), will do the right thing. Ref-counting is a no-op for
Make up_ref no-op for global MD and CIPHER objects
Deprecate EVP_MD_CTX_md().  Added EVP_MD_CTX_get0_md() (same semantics as
the deprecated function) and EVP_MD_CTX_get1_md().  Likewise, deprecate
EVP_CIPHER_CTX_cipher() in favor of EVP_CIPHER_CTX_get0_cipher(), and add
EVP_CIPHER_CTX_get1_CIPHER().
Refactor EVP_MD_free() and EVP_MD_meth_free() to call new common
evp_md_free_int() function.
Refactor EVP_CIPHER_free() and EVP_CIPHER_meth_free() to call new common
evp_cipher_free_int() function.
Also change some flags tests to explicit test == or != zero. E.g.,
        if (flags & x) --> if ((flags & x) != 0)
        if (!(flags & x)) --> if ((flags & x) == 0)
Only done for those lines where "get0_cipher" calls were made.
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14193)
											
										 
											2021-02-17 06:51:56 +08:00
										 |  |  |                 & EVP_CIPH_FLAG_CIPHER_WITH_MAC) != 0 | 
					
						
							| 
									
										
										
										
											2020-01-20 23:17:44 +08:00
										 |  |  |          && EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_PROCESS_UNPROTECTED, 0, | 
					
						
							|  |  |  |                                 cms->d.envelopedData->unprotectedAttrs) <= 0) { | 
					
						
							|  |  |  |         BIO_free(contentBio); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return contentBio; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static BIO *cms_EnvelopedData_Encryption_init_bio(CMS_ContentInfo *cms) | 
					
						
							| 
									
										
										
										
											2008-03-16 07:21:33 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     CMS_EncryptedContentInfo *ec; | 
					
						
							| 
									
										
										
										
											2008-03-17 21:38:51 +08:00
										 |  |  |     STACK_OF(CMS_RecipientInfo) *rinfos; | 
					
						
							| 
									
										
										
										
											2020-09-07 02:11:34 +08:00
										 |  |  |     int ok = 0; | 
					
						
							| 
									
										
										
										
											2008-03-17 21:38:51 +08:00
										 |  |  |     BIO *ret; | 
					
						
							| 
									
										
										
										
											2020-09-07 02:11:34 +08:00
										 |  |  |     CMS_EnvelopedData *env = cms->d.envelopedData; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-17 21:38:51 +08:00
										 |  |  |     /* Get BIO first to set up key */ | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-07 02:11:34 +08:00
										 |  |  |     ec = env->encryptedContentInfo; | 
					
						
							| 
									
										
										
										
											2021-02-18 12:03:25 +08:00
										 |  |  |     ret = ossl_cms_EncryptedContent_init_bio(ec, ossl_cms_get0_cmsctx(cms)); | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-20 23:17:44 +08:00
										 |  |  |     /* If error end of processing */ | 
					
						
							|  |  |  |     if (!ret) | 
					
						
							| 
									
										
										
										
											2008-03-17 21:38:51 +08:00
										 |  |  |         return ret; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-19 21:53:52 +08:00
										 |  |  |     /* Now encrypt content key according to each RecipientInfo type */ | 
					
						
							| 
									
										
										
										
											2020-09-07 02:11:34 +08:00
										 |  |  |     rinfos = env->recipientInfos; | 
					
						
							|  |  |  |     if (cms_env_encrypt_content_key(cms, rinfos) < 0) { | 
					
						
							| 
									
										
										
										
											2020-11-04 19:23:19 +08:00
										 |  |  |         ERR_raise(ERR_LIB_CMS, CMS_R_ERROR_SETTING_RECIPIENTINFO); | 
					
						
							| 
									
										
										
										
											2020-09-07 02:11:34 +08:00
										 |  |  |         goto err; | 
					
						
							| 
									
										
										
										
											2008-03-17 21:38:51 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-09-07 02:11:34 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* And finally set the version */ | 
					
						
							|  |  |  |     cms_env_set_version(env); | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-17 21:38:51 +08:00
										 |  |  |     ok = 1; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-17 21:38:51 +08:00
										 |  |  |  err: | 
					
						
							| 
									
										
										
										
											2020-09-07 02:11:34 +08:00
										 |  |  |     cms_env_clear_ec(ec); | 
					
						
							| 
									
										
										
										
											2008-03-17 21:38:51 +08:00
										 |  |  |     if (ok) | 
					
						
							|  |  |  |         return ret; | 
					
						
							|  |  |  |     BIO_free(ret); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2020-01-20 23:17:44 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-18 12:03:25 +08:00
										 |  |  | BIO *ossl_cms_EnvelopedData_init_bio(CMS_ContentInfo *cms) | 
					
						
							| 
									
										
										
										
											2020-01-20 23:17:44 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     if (cms->d.envelopedData->encryptedContentInfo->cipher != NULL) { | 
					
						
							|  |  |  |          /* If cipher is set it's encryption */ | 
					
						
							|  |  |  |          return cms_EnvelopedData_Encryption_init_bio(cms); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-20 23:17:44 +08:00
										 |  |  |     /* If cipher is not set it's decryption */ | 
					
						
							|  |  |  |     return cms_EnvelopedData_Decryption_init_bio(cms); | 
					
						
							| 
									
										
										
										
											2008-03-13 05:14:28 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-18 12:03:25 +08:00
										 |  |  | BIO *ossl_cms_AuthEnvelopedData_init_bio(CMS_ContentInfo *cms) | 
					
						
							| 
									
										
										
										
											2020-09-07 02:11:34 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     CMS_EncryptedContentInfo *ec; | 
					
						
							|  |  |  |     STACK_OF(CMS_RecipientInfo) *rinfos; | 
					
						
							|  |  |  |     int ok = 0; | 
					
						
							|  |  |  |     BIO *ret; | 
					
						
							|  |  |  |     CMS_AuthEnvelopedData *aenv = cms->d.authEnvelopedData; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Get BIO first to set up key */ | 
					
						
							|  |  |  |     ec = aenv->authEncryptedContentInfo; | 
					
						
							|  |  |  |     /* Set tag for decryption */ | 
					
						
							|  |  |  |     if (ec->cipher == NULL) { | 
					
						
							|  |  |  |         ec->tag = aenv->mac->data; | 
					
						
							|  |  |  |         ec->taglen = aenv->mac->length; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-02-18 12:03:25 +08:00
										 |  |  |     ret = ossl_cms_EncryptedContent_init_bio(ec, ossl_cms_get0_cmsctx(cms)); | 
					
						
							| 
									
										
										
										
											2020-09-07 02:11:34 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* If error or no cipher end of processing */ | 
					
						
							|  |  |  |     if (ret == NULL || ec->cipher == NULL) | 
					
						
							|  |  |  |         return ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Now encrypt content key according to each RecipientInfo type */ | 
					
						
							|  |  |  |     rinfos = aenv->recipientInfos; | 
					
						
							|  |  |  |     if (cms_env_encrypt_content_key(cms, rinfos) < 0) { | 
					
						
							| 
									
										
										
										
											2020-11-04 19:23:19 +08:00
										 |  |  |         ERR_raise(ERR_LIB_CMS, CMS_R_ERROR_SETTING_RECIPIENTINFO); | 
					
						
							| 
									
										
										
										
											2020-09-07 02:11:34 +08:00
										 |  |  |         goto err; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* And finally set the version */ | 
					
						
							|  |  |  |     aenv->version = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ok = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  err: | 
					
						
							|  |  |  |     cms_env_clear_ec(ec); | 
					
						
							|  |  |  |     if (ok) | 
					
						
							|  |  |  |         return ret; | 
					
						
							|  |  |  |     BIO_free(ret); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-18 12:03:25 +08:00
										 |  |  | int ossl_cms_EnvelopedData_final(CMS_ContentInfo *cms, BIO *chain) | 
					
						
							| 
									
										
										
										
											2020-09-07 02:11:34 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     CMS_EnvelopedData *env = NULL; | 
					
						
							|  |  |  |     EVP_CIPHER_CTX *ctx = NULL; | 
					
						
							|  |  |  |     BIO *mbio = BIO_find_type(chain, BIO_TYPE_CIPHER); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-18 12:03:25 +08:00
										 |  |  |     env = ossl_cms_get0_enveloped(cms); | 
					
						
							| 
									
										
										
										
											2020-09-07 02:11:34 +08:00
										 |  |  |     if (env == NULL) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (mbio == NULL) { | 
					
						
							| 
									
										
										
										
											2020-11-04 19:23:19 +08:00
										 |  |  |         ERR_raise(ERR_LIB_CMS, CMS_R_CONTENT_NOT_FOUND); | 
					
						
							| 
									
										
										
										
											2020-09-07 02:11:34 +08:00
										 |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     BIO_get_cipher_ctx(mbio, &ctx); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /*
 | 
					
						
							|  |  |  |      * If the selected cipher supports unprotected attributes, | 
					
						
							|  |  |  |      * deal with it using special ctrl function | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
											
												Rename all getters to use get/get0 in name
For functions that exist in 1.1.1 provide a simple aliases via #define.
Fixes #15236
Functions with OSSL_DECODER_, OSSL_ENCODER_, OSSL_STORE_LOADER_,
EVP_KEYEXCH_, EVP_KEM_, EVP_ASYM_CIPHER_, EVP_SIGNATURE_,
EVP_KEYMGMT_, EVP_RAND_, EVP_MAC_, EVP_KDF_, EVP_PKEY_,
EVP_MD_, and EVP_CIPHER_ prefixes are renamed.
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15405)
											
										 
											2021-05-21 22:58:08 +08:00
										 |  |  |     if ((EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(ctx)) | 
					
						
							| 
									
										
											  
											
												Add "origin" field to EVP_CIPHER, EVP_MD
Add a "where did this EVP_{CIPHER,MD} come from" flag: global, via fetch,
or via EVP_{CIPHER,MD}_meth_new.  Update EVP_{CIPHER,MD}_free to handle all
three origins. The flag is deliberately right before some function pointers,
so that compile-time failures (int/pointer) will occur, as opposed to
taking a bit in the existing "flags" field.  The "global variable" flag
is non-zero, so the default case of using OPENSSL_zalloc (for provider
ciphers), will do the right thing. Ref-counting is a no-op for
Make up_ref no-op for global MD and CIPHER objects
Deprecate EVP_MD_CTX_md().  Added EVP_MD_CTX_get0_md() (same semantics as
the deprecated function) and EVP_MD_CTX_get1_md().  Likewise, deprecate
EVP_CIPHER_CTX_cipher() in favor of EVP_CIPHER_CTX_get0_cipher(), and add
EVP_CIPHER_CTX_get1_CIPHER().
Refactor EVP_MD_free() and EVP_MD_meth_free() to call new common
evp_md_free_int() function.
Refactor EVP_CIPHER_free() and EVP_CIPHER_meth_free() to call new common
evp_cipher_free_int() function.
Also change some flags tests to explicit test == or != zero. E.g.,
        if (flags & x) --> if ((flags & x) != 0)
        if (!(flags & x)) --> if ((flags & x) == 0)
Only done for those lines where "get0_cipher" calls were made.
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14193)
											
										 
											2021-02-17 06:51:56 +08:00
										 |  |  |             & EVP_CIPH_FLAG_CIPHER_WITH_MAC) != 0) { | 
					
						
							| 
									
										
										
										
											2020-09-07 02:11:34 +08:00
										 |  |  |         if (env->unprotectedAttrs == NULL) | 
					
						
							|  |  |  |             env->unprotectedAttrs = sk_X509_ATTRIBUTE_new_null(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (env->unprotectedAttrs == NULL) { | 
					
						
							| 
									
										
										
										
											2022-09-29 19:57:34 +08:00
										 |  |  |             ERR_raise(ERR_LIB_CMS, ERR_R_CRYPTO_LIB); | 
					
						
							| 
									
										
										
										
											2020-09-07 02:11:34 +08:00
										 |  |  |             return 0; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_PROCESS_UNPROTECTED, | 
					
						
							|  |  |  |                                 1, env->unprotectedAttrs) <= 0) { | 
					
						
							| 
									
										
										
										
											2020-11-04 19:23:19 +08:00
										 |  |  |             ERR_raise(ERR_LIB_CMS, CMS_R_CTRL_FAILURE); | 
					
						
							| 
									
										
										
										
											2020-09-07 02:11:34 +08:00
										 |  |  |             return 0; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     cms_env_set_version(cms->d.envelopedData); | 
					
						
							|  |  |  |     return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-18 12:03:25 +08:00
										 |  |  | int ossl_cms_AuthEnvelopedData_final(CMS_ContentInfo *cms, BIO *cmsbio) | 
					
						
							| 
									
										
										
										
											2020-09-07 02:11:34 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     EVP_CIPHER_CTX *ctx; | 
					
						
							|  |  |  |     unsigned char *tag = NULL; | 
					
						
							|  |  |  |     int taglen, ok = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     BIO_get_cipher_ctx(cmsbio, &ctx); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-14 01:53:39 +08:00
										 |  |  |     /*
 | 
					
						
							| 
									
										
										
										
											2020-09-07 02:11:34 +08:00
										 |  |  |      * The tag is set only for encryption. There is nothing to do for | 
					
						
							|  |  |  |      * decryption. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
											
												Rename all getters to use get/get0 in name
For functions that exist in 1.1.1 provide a simple aliases via #define.
Fixes #15236
Functions with OSSL_DECODER_, OSSL_ENCODER_, OSSL_STORE_LOADER_,
EVP_KEYEXCH_, EVP_KEM_, EVP_ASYM_CIPHER_, EVP_SIGNATURE_,
EVP_KEYMGMT_, EVP_RAND_, EVP_MAC_, EVP_KDF_, EVP_PKEY_,
EVP_MD_, and EVP_CIPHER_ prefixes are renamed.
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15405)
											
										 
											2021-05-21 22:58:08 +08:00
										 |  |  |     if (!EVP_CIPHER_CTX_is_encrypting(ctx)) | 
					
						
							| 
									
										
										
										
											2020-09-07 02:11:34 +08:00
										 |  |  |         return 1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												Rename all getters to use get/get0 in name
For functions that exist in 1.1.1 provide a simple aliases via #define.
Fixes #15236
Functions with OSSL_DECODER_, OSSL_ENCODER_, OSSL_STORE_LOADER_,
EVP_KEYEXCH_, EVP_KEM_, EVP_ASYM_CIPHER_, EVP_SIGNATURE_,
EVP_KEYMGMT_, EVP_RAND_, EVP_MAC_, EVP_KDF_, EVP_PKEY_,
EVP_MD_, and EVP_CIPHER_ prefixes are renamed.
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15405)
											
										 
											2021-05-21 22:58:08 +08:00
										 |  |  |     taglen = EVP_CIPHER_CTX_get_tag_length(ctx); | 
					
						
							| 
									
										
										
										
											2020-09-07 02:11:34 +08:00
										 |  |  |     if (taglen <= 0 | 
					
						
							|  |  |  |             || (tag = OPENSSL_malloc(taglen)) == NULL | 
					
						
							|  |  |  |             || EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, taglen, | 
					
						
							|  |  |  |                                    tag) <= 0) { | 
					
						
							| 
									
										
										
										
											2020-11-04 19:23:19 +08:00
										 |  |  |         ERR_raise(ERR_LIB_CMS, CMS_R_CIPHER_GET_TAG); | 
					
						
							| 
									
										
										
										
											2020-09-07 02:11:34 +08:00
										 |  |  |         goto err; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!ASN1_OCTET_STRING_set(cms->d.authEnvelopedData->mac, tag, taglen)) | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ok = 1; | 
					
						
							|  |  |  | err: | 
					
						
							|  |  |  |     OPENSSL_free(tag); | 
					
						
							|  |  |  |     return ok; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-17 21:36:39 +08:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Get RecipientInfo type (if any) supported by a key (public or private). To | 
					
						
							|  |  |  |  * retain compatibility with previous behaviour if the ctrl value isn't | 
					
						
							|  |  |  |  * supported we assume key transport. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2021-02-18 12:03:25 +08:00
										 |  |  | int ossl_cms_pkey_get_ri_type(EVP_PKEY *pk) | 
					
						
							| 
									
										
										
										
											2013-07-17 21:36:39 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2025-04-03 18:19:43 +08:00
										 |  |  |     int ri_type; | 
					
						
							|  |  |  |     EVP_PKEY_CTX *ctx = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /*
 | 
					
						
							|  |  |  |      * First check the provider for RecipientInfo support since a key may support | 
					
						
							|  |  |  |      * multiple types, e.g. an RSA key and provider may support RSA key transport | 
					
						
							|  |  |  |      * and/or RSA-KEM. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     if (evp_pkey_is_provided(pk) | 
					
						
							|  |  |  |         && EVP_PKEY_get_int_param(pk, OSSL_PKEY_PARAM_CMS_RI_TYPE, &ri_type)) | 
					
						
							|  |  |  |         return ri_type; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-07 22:59:28 +08:00
										 |  |  |     /* Check types that we know about */ | 
					
						
							|  |  |  |     if (EVP_PKEY_is_a(pk, "DH")) | 
					
						
							|  |  |  |         return CMS_RECIPINFO_AGREE; | 
					
						
							| 
									
										
										
										
											2021-01-14 21:43:11 +08:00
										 |  |  |     else if (EVP_PKEY_is_a(pk, "DHX")) | 
					
						
							|  |  |  |         return CMS_RECIPINFO_AGREE; | 
					
						
							| 
									
										
										
										
											2020-10-07 22:59:28 +08:00
										 |  |  |     else if (EVP_PKEY_is_a(pk, "DSA")) | 
					
						
							|  |  |  |         return CMS_RECIPINFO_NONE; | 
					
						
							|  |  |  |     else if (EVP_PKEY_is_a(pk, "EC")) | 
					
						
							|  |  |  |         return CMS_RECIPINFO_AGREE; | 
					
						
							|  |  |  |     else if (EVP_PKEY_is_a(pk, "RSA")) | 
					
						
							|  |  |  |         return CMS_RECIPINFO_TRANS; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /*
 | 
					
						
							| 
									
										
										
										
											2025-04-03 18:19:43 +08:00
										 |  |  |      * Otherwise this might be an engine implementation, so see if we can get | 
					
						
							| 
									
										
										
										
											2020-10-07 22:59:28 +08:00
										 |  |  |      * the type from the ameth. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2013-07-17 21:36:39 +08:00
										 |  |  |     if (pk->ameth && pk->ameth->pkey_ctrl) { | 
					
						
							|  |  |  |         int i, r; | 
					
						
							|  |  |  |         i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_RI_TYPE, 0, &r); | 
					
						
							|  |  |  |         if (i > 0) | 
					
						
							|  |  |  |             return r; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2025-04-03 18:19:43 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /*
 | 
					
						
							|  |  |  |      * Otherwise try very hard to figure out what RecipientInfo the key supports. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     ri_type = CMS_RECIPINFO_TRANS; | 
					
						
							|  |  |  |     ctx = EVP_PKEY_CTX_new(pk, NULL); | 
					
						
							|  |  |  |     if (ctx != NULL) { | 
					
						
							|  |  |  |         ERR_set_mark(); | 
					
						
							|  |  |  |         if (EVP_PKEY_encrypt_init(ctx) > 0) | 
					
						
							|  |  |  |             ri_type = CMS_RECIPINFO_TRANS; | 
					
						
							|  |  |  |         else if (EVP_PKEY_derive_init(ctx) > 0) | 
					
						
							|  |  |  |             ri_type = CMS_RECIPINFO_AGREE; | 
					
						
							|  |  |  |         else if (EVP_PKEY_encapsulate_init(ctx, NULL) > 0) | 
					
						
							|  |  |  |             ri_type = CMS_RECIPINFO_KEM; | 
					
						
							|  |  |  |         ERR_pop_to_mark(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     EVP_PKEY_CTX_free(ctx); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return ri_type; | 
					
						
							| 
									
										
										
										
											2013-07-17 21:36:39 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2020-01-20 23:17:44 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-18 12:03:25 +08:00
										 |  |  | int ossl_cms_pkey_is_ri_type_supported(EVP_PKEY *pk, int ri_type) | 
					
						
							| 
									
										
										
										
											2020-01-20 23:17:44 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     int supportedRiType; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (pk->ameth != NULL && pk->ameth->pkey_ctrl != NULL) { | 
					
						
							|  |  |  |         int i, r; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-25 16:04:55 +08:00
										 |  |  |         i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_IS_RI_TYPE_SUPPORTED, | 
					
						
							|  |  |  |                                  ri_type, &r); | 
					
						
							| 
									
										
										
										
											2020-01-20 23:17:44 +08:00
										 |  |  |         if (i > 0) | 
					
						
							|  |  |  |             return r; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-18 12:03:25 +08:00
										 |  |  |     supportedRiType = ossl_cms_pkey_get_ri_type(pk); | 
					
						
							| 
									
										
										
										
											2020-01-20 23:17:44 +08:00
										 |  |  |     if (supportedRiType < 0) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return (supportedRiType == ri_type); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2025-04-03 18:19:43 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | int ossl_cms_RecipientInfo_wrap_init(CMS_RecipientInfo *ri, | 
					
						
							|  |  |  |                                      const EVP_CIPHER *cipher) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const CMS_CTX *cms_ctx; | 
					
						
							|  |  |  |     EVP_CIPHER_CTX *ctx; | 
					
						
							|  |  |  |     const EVP_CIPHER *kekcipher; | 
					
						
							|  |  |  |     EVP_CIPHER *fetched_kekcipher; | 
					
						
							|  |  |  |     const char *kekcipher_name; | 
					
						
							|  |  |  |     int keylen; | 
					
						
							|  |  |  |     int ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (ri->type == CMS_RECIPINFO_AGREE) { | 
					
						
							|  |  |  |         cms_ctx = ri->d.kari->cms_ctx; | 
					
						
							|  |  |  |         ctx = ri->d.kari->ctx; | 
					
						
							|  |  |  |     } else if (ri->type == CMS_RECIPINFO_KEM) { | 
					
						
							|  |  |  |         cms_ctx = ri->d.ori->d.kemri->cms_ctx; | 
					
						
							|  |  |  |         ctx = ri->d.ori->d.kemri->ctx; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_RECIPIENTINFO_TYPE); | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* If a suitable wrap algorithm is already set nothing to do */ | 
					
						
							|  |  |  |     kekcipher = EVP_CIPHER_CTX_get0_cipher(ctx); | 
					
						
							|  |  |  |     if (kekcipher != NULL) { | 
					
						
							|  |  |  |         if (EVP_CIPHER_CTX_get_mode(ctx) != EVP_CIPH_WRAP_MODE) | 
					
						
							|  |  |  |             return 0; | 
					
						
							|  |  |  |         return 1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (cipher == NULL) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     keylen = EVP_CIPHER_get_key_length(cipher); | 
					
						
							|  |  |  |     if (keylen <= 0) { | 
					
						
							|  |  |  |         ERR_raise(ERR_LIB_CMS, CMS_R_INVALID_KEY_LENGTH); | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if ((EVP_CIPHER_get_flags(cipher) & EVP_CIPH_FLAG_GET_WRAP_CIPHER) != 0) { | 
					
						
							|  |  |  |         ret = EVP_CIPHER_meth_get_ctrl(cipher)(NULL, EVP_CTRL_GET_WRAP_CIPHER, | 
					
						
							|  |  |  |                                                0, &kekcipher); | 
					
						
							|  |  |  |         if (ret <= 0) | 
					
						
							|  |  |  |             return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (kekcipher != NULL) { | 
					
						
							|  |  |  |             if (EVP_CIPHER_get_mode(kekcipher) != EVP_CIPH_WRAP_MODE) | 
					
						
							|  |  |  |                 return 0; | 
					
						
							|  |  |  |             kekcipher_name = EVP_CIPHER_get0_name(kekcipher); | 
					
						
							|  |  |  |             goto enc; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /*
 | 
					
						
							|  |  |  |      * Pick a cipher based on content encryption cipher. If it is DES3 use | 
					
						
							|  |  |  |      * DES3 wrap otherwise use AES wrap similar to key size. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  | #ifndef OPENSSL_NO_DES
 | 
					
						
							|  |  |  |     if (EVP_CIPHER_get_type(cipher) == NID_des_ede3_cbc) | 
					
						
							|  |  |  |         kekcipher_name = SN_id_smime_alg_CMS3DESwrap; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     if (keylen <= 16) | 
					
						
							|  |  |  |         kekcipher_name = SN_id_aes128_wrap; | 
					
						
							|  |  |  |     else if (keylen <= 24) | 
					
						
							|  |  |  |         kekcipher_name = SN_id_aes192_wrap; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         kekcipher_name = SN_id_aes256_wrap; | 
					
						
							|  |  |  | enc: | 
					
						
							|  |  |  |     fetched_kekcipher = EVP_CIPHER_fetch(ossl_cms_ctx_get0_libctx(cms_ctx), | 
					
						
							|  |  |  |                                          kekcipher_name, | 
					
						
							|  |  |  |                                          ossl_cms_ctx_get0_propq(cms_ctx)); | 
					
						
							|  |  |  |     if (fetched_kekcipher == NULL) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     ret = EVP_EncryptInit_ex(ctx, fetched_kekcipher, NULL, NULL, NULL); | 
					
						
							|  |  |  |     EVP_CIPHER_free(fetched_kekcipher); | 
					
						
							|  |  |  |     return ret; | 
					
						
							|  |  |  | } |