mirror of https://github.com/openssl/openssl.git
				
				
				
			Experimental CMS password based recipient Info support.
This commit is contained in:
		
							parent
							
								
									480af99ef4
								
							
						
					
					
						commit
						d2a53c2238
					
				
							
								
								
									
										4
									
								
								CHANGES
								
								
								
								
							
							
						
						
									
										4
									
								
								CHANGES
								
								
								
								
							|  | @ -4,6 +4,10 @@ | ||||||
| 
 | 
 | ||||||
|  Changes between 1.0.0 and 1.1.0  [xx XXX xxxx] |  Changes between 1.0.0 and 1.1.0  [xx XXX xxxx] | ||||||
| 
 | 
 | ||||||
|  |   *) Experiemental password based recipient info support for CMS library: | ||||||
|  |      implementing RFC3211. | ||||||
|  |      [Steve Henson] | ||||||
|  | 
 | ||||||
|   *) Split password based encryption into PBES2 and PBKDF2 functions. This |   *) Split password based encryption into PBES2 and PBKDF2 functions. This | ||||||
|      neatly separates the code into cipher and PBE sections and is required |      neatly separates the code into cipher and PBE sections and is required | ||||||
|      for some algorithms that split PBES2 into separate pieces (such as |      for some algorithms that split PBES2 into separate pieces (such as | ||||||
|  |  | ||||||
							
								
								
									
										35
									
								
								apps/cms.c
								
								
								
								
							
							
						
						
									
										35
									
								
								apps/cms.c
								
								
								
								
							|  | @ -136,6 +136,7 @@ int MAIN(int argc, char **argv) | ||||||
| 	char *engine=NULL; | 	char *engine=NULL; | ||||||
| #endif | #endif | ||||||
| 	unsigned char *secret_key = NULL, *secret_keyid = NULL; | 	unsigned char *secret_key = NULL, *secret_keyid = NULL; | ||||||
|  | 	unsigned char *pwri_pass = NULL, *pwri_tmp = NULL; | ||||||
| 	size_t secret_keylen = 0, secret_keyidlen = 0; | 	size_t secret_keylen = 0, secret_keyidlen = 0; | ||||||
| 
 | 
 | ||||||
| 	ASN1_OBJECT *econtent_type = NULL; | 	ASN1_OBJECT *econtent_type = NULL; | ||||||
|  | @ -326,6 +327,13 @@ int MAIN(int argc, char **argv) | ||||||
| 				} | 				} | ||||||
| 			secret_keyidlen = (size_t)ltmp; | 			secret_keyidlen = (size_t)ltmp; | ||||||
| 			} | 			} | ||||||
|  | 		else if (!strcmp(*args,"-pwri_password")) | ||||||
|  | 			{ | ||||||
|  | 			if (!args[1]) | ||||||
|  | 				goto argerr; | ||||||
|  | 			args++; | ||||||
|  | 			pwri_pass = (unsigned char *)*args; | ||||||
|  | 			} | ||||||
| 		else if (!strcmp(*args,"-econtent_type")) | 		else if (!strcmp(*args,"-econtent_type")) | ||||||
| 			{ | 			{ | ||||||
| 			if (!args[1]) | 			if (!args[1]) | ||||||
|  | @ -559,7 +567,7 @@ int MAIN(int argc, char **argv) | ||||||
| 
 | 
 | ||||||
| 	else if (operation == SMIME_DECRYPT) | 	else if (operation == SMIME_DECRYPT) | ||||||
| 		{ | 		{ | ||||||
| 		if (!recipfile && !keyfile && !secret_key) | 		if (!recipfile && !keyfile && !secret_key && !pwri_pass) | ||||||
| 			{ | 			{ | ||||||
| 			BIO_printf(bio_err, "No recipient certificate or key specified\n"); | 			BIO_printf(bio_err, "No recipient certificate or key specified\n"); | ||||||
| 			badarg = 1; | 			badarg = 1; | ||||||
|  | @ -567,7 +575,7 @@ int MAIN(int argc, char **argv) | ||||||
| 		} | 		} | ||||||
| 	else if (operation == SMIME_ENCRYPT) | 	else if (operation == SMIME_ENCRYPT) | ||||||
| 		{ | 		{ | ||||||
| 		if (!*args && !secret_key) | 		if (!*args && !secret_key && !pwri_pass) | ||||||
| 			{ | 			{ | ||||||
| 			BIO_printf(bio_err, "No recipient(s) certificate(s) specified\n"); | 			BIO_printf(bio_err, "No recipient(s) certificate(s) specified\n"); | ||||||
| 			badarg = 1; | 			badarg = 1; | ||||||
|  | @ -917,6 +925,17 @@ int MAIN(int argc, char **argv) | ||||||
| 			secret_key = NULL; | 			secret_key = NULL; | ||||||
| 			secret_keyid = NULL; | 			secret_keyid = NULL; | ||||||
| 			} | 			} | ||||||
|  | 		if (pwri_pass) | ||||||
|  | 			{ | ||||||
|  | 			pwri_tmp = (unsigned char *)BUF_strdup((char *)pwri_pass); | ||||||
|  | 			if (!pwri_tmp) | ||||||
|  | 				goto end; | ||||||
|  | 			if (!CMS_add0_recipient_password(cms, | ||||||
|  | 						-1, NID_undef, NID_undef, | ||||||
|  | 						 pwri_tmp, -1, NULL)) | ||||||
|  | 				goto end; | ||||||
|  | 			pwri_tmp = NULL; | ||||||
|  | 			} | ||||||
| 		if (!(flags & CMS_STREAM)) | 		if (!(flags & CMS_STREAM)) | ||||||
| 			{ | 			{ | ||||||
| 			if (!CMS_final(cms, in, NULL, flags)) | 			if (!CMS_final(cms, in, NULL, flags)) | ||||||
|  | @ -1043,6 +1062,16 @@ int MAIN(int argc, char **argv) | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
|  | 		if (pwri_pass) | ||||||
|  | 			{ | ||||||
|  | 			if (!CMS_decrypt_set1_password(cms, pwri_pass, -1)) | ||||||
|  | 				{ | ||||||
|  | 				BIO_puts(bio_err, | ||||||
|  | 					"Error decrypting CMS using password\n"); | ||||||
|  | 				goto end; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
| 		if (!CMS_decrypt(cms, NULL, NULL, indata, out, flags)) | 		if (!CMS_decrypt(cms, NULL, NULL, indata, out, flags)) | ||||||
| 			{ | 			{ | ||||||
| 			BIO_printf(bio_err, "Error decrypting CMS structure\n"); | 			BIO_printf(bio_err, "Error decrypting CMS structure\n"); | ||||||
|  | @ -1167,6 +1196,8 @@ end: | ||||||
| 		OPENSSL_free(secret_key); | 		OPENSSL_free(secret_key); | ||||||
| 	if (secret_keyid) | 	if (secret_keyid) | ||||||
| 		OPENSSL_free(secret_keyid); | 		OPENSSL_free(secret_keyid); | ||||||
|  | 	if (pwri_tmp) | ||||||
|  | 		OPENSSL_free(pwri_tmp); | ||||||
| 	if (econtent_type) | 	if (econtent_type) | ||||||
| 		ASN1_OBJECT_free(econtent_type); | 		ASN1_OBJECT_free(econtent_type); | ||||||
| 	if (rr) | 	if (rr) | ||||||
|  |  | ||||||
|  | @ -18,9 +18,11 @@ APPS= | ||||||
| 
 | 
 | ||||||
| LIB=$(TOP)/libcrypto.a | LIB=$(TOP)/libcrypto.a | ||||||
| LIBSRC= cms_lib.c cms_asn1.c cms_att.c cms_io.c cms_smime.c cms_err.c \
 | LIBSRC= cms_lib.c cms_asn1.c cms_att.c cms_io.c cms_smime.c cms_err.c \
 | ||||||
| 	cms_sd.c cms_dd.c cms_cd.c cms_env.c cms_enc.c cms_ess.c | 	cms_sd.c cms_dd.c cms_cd.c cms_env.c cms_enc.c cms_ess.c \
 | ||||||
|  | 	cms_pwri.c | ||||||
| LIBOBJ= cms_lib.o cms_asn1.o cms_att.o cms_io.o cms_smime.o cms_err.o \
 | LIBOBJ= cms_lib.o cms_asn1.o cms_att.o cms_io.o cms_smime.o cms_err.o \
 | ||||||
| 	cms_sd.o cms_dd.o cms_cd.o cms_env.o cms_enc.o cms_ess.o | 	cms_sd.o cms_dd.o cms_cd.o cms_env.o cms_enc.o cms_ess.o \
 | ||||||
|  | 	cms_pwri.o | ||||||
| 
 | 
 | ||||||
| SRC= $(LIBSRC) | SRC= $(LIBSRC) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -184,6 +184,8 @@ int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert); | ||||||
| int CMS_decrypt_set1_key(CMS_ContentInfo *cms,  | int CMS_decrypt_set1_key(CMS_ContentInfo *cms,  | ||||||
| 				unsigned char *key, size_t keylen, | 				unsigned char *key, size_t keylen, | ||||||
| 				unsigned char *id, size_t idlen); | 				unsigned char *id, size_t idlen); | ||||||
|  | int CMS_decrypt_set1_password(CMS_ContentInfo *cms,  | ||||||
|  | 				unsigned char *pass, ssize_t passlen); | ||||||
| 
 | 
 | ||||||
| STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms); | STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms); | ||||||
| int CMS_RecipientInfo_type(CMS_RecipientInfo *ri); | int CMS_RecipientInfo_type(CMS_RecipientInfo *ri); | ||||||
|  | @ -219,6 +221,14 @@ int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri, | ||||||
| int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri,  | int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri,  | ||||||
| 					const unsigned char *id, size_t idlen); | 					const unsigned char *id, size_t idlen); | ||||||
| 
 | 
 | ||||||
|  | int CMS_RecipientInfo_set0_password(CMS_RecipientInfo *ri,  | ||||||
|  | 					unsigned char *pass, ssize_t passlen); | ||||||
|  | 
 | ||||||
|  | CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms, | ||||||
|  | 					int iter, int wrap_nid, int pbe_nid, | ||||||
|  | 					unsigned char *pass, ssize_t passlen, | ||||||
|  | 					const EVP_CIPHER *kekciph); | ||||||
|  | 
 | ||||||
| int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri); | int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri); | ||||||
| 	 | 	 | ||||||
| int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out, | int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out, | ||||||
|  | @ -330,6 +340,7 @@ void ERR_load_CMS_strings(void); | ||||||
| #define CMS_F_CHECK_CONTENT				 99 | #define CMS_F_CHECK_CONTENT				 99 | ||||||
| #define CMS_F_CMS_ADD0_CERT				 164 | #define CMS_F_CMS_ADD0_CERT				 164 | ||||||
| #define CMS_F_CMS_ADD0_RECIPIENT_KEY			 100 | #define CMS_F_CMS_ADD0_RECIPIENT_KEY			 100 | ||||||
|  | #define CMS_F_CMS_ADD0_RECIPIENT_PASSWORD		 165 | ||||||
| #define CMS_F_CMS_ADD1_RECEIPTREQUEST			 158 | #define CMS_F_CMS_ADD1_RECEIPTREQUEST			 158 | ||||||
| #define CMS_F_CMS_ADD1_RECIPIENT_CERT			 101 | #define CMS_F_CMS_ADD1_RECIPIENT_CERT			 101 | ||||||
| #define CMS_F_CMS_ADD1_SIGNER				 102 | #define CMS_F_CMS_ADD1_SIGNER				 102 | ||||||
|  | @ -344,6 +355,7 @@ void ERR_load_CMS_strings(void); | ||||||
| #define CMS_F_CMS_DATAINIT				 111 | #define CMS_F_CMS_DATAINIT				 111 | ||||||
| #define CMS_F_CMS_DECRYPT				 112 | #define CMS_F_CMS_DECRYPT				 112 | ||||||
| #define CMS_F_CMS_DECRYPT_SET1_KEY			 113 | #define CMS_F_CMS_DECRYPT_SET1_KEY			 113 | ||||||
|  | #define CMS_F_CMS_DECRYPT_SET1_PASSWORD			 166 | ||||||
| #define CMS_F_CMS_DECRYPT_SET1_PKEY			 114 | #define CMS_F_CMS_DECRYPT_SET1_PKEY			 114 | ||||||
| #define CMS_F_CMS_DIGESTALGORITHM_FIND_CTX		 115 | #define CMS_F_CMS_DIGESTALGORITHM_FIND_CTX		 115 | ||||||
| #define CMS_F_CMS_DIGESTALGORITHM_INIT_BIO		 116 | #define CMS_F_CMS_DIGESTALGORITHM_INIT_BIO		 116 | ||||||
|  | @ -378,7 +390,9 @@ void ERR_load_CMS_strings(void); | ||||||
| #define CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT		 141 | #define CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT		 141 | ||||||
| #define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS		 142 | #define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS		 142 | ||||||
| #define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID	 143 | #define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID	 143 | ||||||
|  | #define CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT		 167 | ||||||
| #define CMS_F_CMS_RECIPIENTINFO_SET0_KEY		 144 | #define CMS_F_CMS_RECIPIENTINFO_SET0_KEY		 144 | ||||||
|  | #define CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD		 168 | ||||||
| #define CMS_F_CMS_RECIPIENTINFO_SET0_PKEY		 145 | #define CMS_F_CMS_RECIPIENTINFO_SET0_PKEY		 145 | ||||||
| #define CMS_F_CMS_SET1_SIGNERIDENTIFIER			 146 | #define CMS_F_CMS_SET1_SIGNERIDENTIFIER			 146 | ||||||
| #define CMS_F_CMS_SET_DETACHED				 147 | #define CMS_F_CMS_SET_DETACHED				 147 | ||||||
|  | @ -419,6 +433,7 @@ void ERR_load_CMS_strings(void); | ||||||
| #define CMS_R_ERROR_SETTING_KEY				 115 | #define CMS_R_ERROR_SETTING_KEY				 115 | ||||||
| #define CMS_R_ERROR_SETTING_RECIPIENTINFO		 116 | #define CMS_R_ERROR_SETTING_RECIPIENTINFO		 116 | ||||||
| #define CMS_R_INVALID_ENCRYPTED_KEY_LENGTH		 117 | #define CMS_R_INVALID_ENCRYPTED_KEY_LENGTH		 117 | ||||||
|  | #define CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER		 176 | ||||||
| #define CMS_R_INVALID_KEY_LENGTH			 118 | #define CMS_R_INVALID_KEY_LENGTH			 118 | ||||||
| #define CMS_R_MD_BIO_INIT_ERROR				 119 | #define CMS_R_MD_BIO_INIT_ERROR				 119 | ||||||
| #define CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH	 120 | #define CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH	 120 | ||||||
|  | @ -431,6 +446,7 @@ void ERR_load_CMS_strings(void); | ||||||
| #define CMS_R_NOT_ENCRYPTED_DATA			 122 | #define CMS_R_NOT_ENCRYPTED_DATA			 122 | ||||||
| #define CMS_R_NOT_KEK					 123 | #define CMS_R_NOT_KEK					 123 | ||||||
| #define CMS_R_NOT_KEY_TRANSPORT				 124 | #define CMS_R_NOT_KEY_TRANSPORT				 124 | ||||||
|  | #define CMS_R_NOT_PWRI					 177 | ||||||
| #define CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE		 125 | #define CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE		 125 | ||||||
| #define CMS_R_NO_CIPHER					 126 | #define CMS_R_NO_CIPHER					 126 | ||||||
| #define CMS_R_NO_CONTENT				 127 | #define CMS_R_NO_CONTENT				 127 | ||||||
|  | @ -443,6 +459,7 @@ void ERR_load_CMS_strings(void); | ||||||
| #define CMS_R_NO_MATCHING_RECIPIENT			 132 | #define CMS_R_NO_MATCHING_RECIPIENT			 132 | ||||||
| #define CMS_R_NO_MATCHING_SIGNATURE			 166 | #define CMS_R_NO_MATCHING_SIGNATURE			 166 | ||||||
| #define CMS_R_NO_MSGSIGDIGEST				 167 | #define CMS_R_NO_MSGSIGDIGEST				 167 | ||||||
|  | #define CMS_R_NO_PASSWORD				 178 | ||||||
| #define CMS_R_NO_PRIVATE_KEY				 133 | #define CMS_R_NO_PRIVATE_KEY				 133 | ||||||
| #define CMS_R_NO_PUBLIC_KEY				 134 | #define CMS_R_NO_PUBLIC_KEY				 134 | ||||||
| #define CMS_R_NO_RECEIPT_REQUEST			 168 | #define CMS_R_NO_RECEIPT_REQUEST			 168 | ||||||
|  | @ -466,10 +483,12 @@ void ERR_load_CMS_strings(void); | ||||||
| #define CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM		 151 | #define CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM		 151 | ||||||
| #define CMS_R_UNSUPPORTED_CONTENT_TYPE			 152 | #define CMS_R_UNSUPPORTED_CONTENT_TYPE			 152 | ||||||
| #define CMS_R_UNSUPPORTED_KEK_ALGORITHM			 153 | #define CMS_R_UNSUPPORTED_KEK_ALGORITHM			 153 | ||||||
|  | #define CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM	 179 | ||||||
| #define CMS_R_UNSUPPORTED_RECIPIENT_TYPE		 154 | #define CMS_R_UNSUPPORTED_RECIPIENT_TYPE		 154 | ||||||
| #define CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE		 155 | #define CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE		 155 | ||||||
| #define CMS_R_UNSUPPORTED_TYPE				 156 | #define CMS_R_UNSUPPORTED_TYPE				 156 | ||||||
| #define CMS_R_UNWRAP_ERROR				 157 | #define CMS_R_UNWRAP_ERROR				 157 | ||||||
|  | #define CMS_R_UNWRAP_FAILURE				 180 | ||||||
| #define CMS_R_VERIFICATION_FAILURE			 158 | #define CMS_R_VERIFICATION_FAILURE			 158 | ||||||
| #define CMS_R_WRAP_ERROR				 159 | #define CMS_R_WRAP_ERROR				 159 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -237,6 +237,15 @@ static int cms_ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, | ||||||
| 				OPENSSL_free(kekri->key); | 				OPENSSL_free(kekri->key); | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
|  | 		else if (ri->type == CMS_RECIPINFO_PASS) | ||||||
|  | 			{ | ||||||
|  | 			CMS_PasswordRecipientInfo *pwri = ri->d.pwri; | ||||||
|  | 			if (pwri->pass) | ||||||
|  | 				{ | ||||||
|  | 				OPENSSL_cleanse(pwri->pass, pwri->passlen); | ||||||
|  | 				OPENSSL_free(pwri->pass); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 	return 1; | 	return 1; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -65,14 +65,13 @@ | ||||||
| /* CMS EnvelopedData Utilities */ | /* CMS EnvelopedData Utilities */ | ||||||
| 
 | 
 | ||||||
| DECLARE_ASN1_ITEM(CMS_EnvelopedData) | DECLARE_ASN1_ITEM(CMS_EnvelopedData) | ||||||
| DECLARE_ASN1_ITEM(CMS_RecipientInfo) |  | ||||||
| DECLARE_ASN1_ITEM(CMS_KeyTransRecipientInfo) | DECLARE_ASN1_ITEM(CMS_KeyTransRecipientInfo) | ||||||
| DECLARE_ASN1_ITEM(CMS_KEKRecipientInfo) | DECLARE_ASN1_ITEM(CMS_KEKRecipientInfo) | ||||||
| DECLARE_ASN1_ITEM(CMS_OtherKeyAttribute) | DECLARE_ASN1_ITEM(CMS_OtherKeyAttribute) | ||||||
| 
 | 
 | ||||||
| DECLARE_STACK_OF(CMS_RecipientInfo) | DECLARE_STACK_OF(CMS_RecipientInfo) | ||||||
| 
 | 
 | ||||||
| static CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms) | CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms) | ||||||
| 	{ | 	{ | ||||||
| 	if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_enveloped) | 	if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_enveloped) | ||||||
| 		{ | 		{ | ||||||
|  | @ -786,6 +785,9 @@ int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri) | ||||||
| 		case CMS_RECIPINFO_KEK: | 		case CMS_RECIPINFO_KEK: | ||||||
| 		return cms_RecipientInfo_kekri_decrypt(cms, ri); | 		return cms_RecipientInfo_kekri_decrypt(cms, ri); | ||||||
| 
 | 
 | ||||||
|  | 		case CMS_RECIPINFO_PASS: | ||||||
|  | 		return cms_RecipientInfo_pwri_crypt(cms, ri, 0); | ||||||
|  | 
 | ||||||
| 		default: | 		default: | ||||||
| 		CMSerr(CMS_F_CMS_RECIPIENTINFO_DECRYPT, | 		CMSerr(CMS_F_CMS_RECIPIENTINFO_DECRYPT, | ||||||
| 			CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE); | 			CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE); | ||||||
|  | @ -829,6 +831,10 @@ BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms) | ||||||
| 			r = cms_RecipientInfo_kekri_encrypt(cms, ri); | 			r = cms_RecipientInfo_kekri_encrypt(cms, ri); | ||||||
| 			break; | 			break; | ||||||
| 
 | 
 | ||||||
|  | 			case CMS_RECIPINFO_PASS: | ||||||
|  | 			r = cms_RecipientInfo_pwri_crypt(cms, ri, 1); | ||||||
|  | 			break; | ||||||
|  | 
 | ||||||
| 			default: | 			default: | ||||||
| 			CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO, | 			CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO, | ||||||
| 				CMS_R_UNSUPPORTED_RECIPIENT_TYPE); | 				CMS_R_UNSUPPORTED_RECIPIENT_TYPE); | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| /* crypto/cms/cms_err.c */ | /* crypto/cms/cms_err.c */ | ||||||
| /* ====================================================================
 | /* ====================================================================
 | ||||||
|  * Copyright (c) 1999-2007 The OpenSSL Project.  All rights reserved. |  * Copyright (c) 1999-2009 The OpenSSL Project.  All rights reserved. | ||||||
|  * |  * | ||||||
|  * Redistribution and use in source and binary forms, with or without |  * Redistribution and use in source and binary forms, with or without | ||||||
|  * modification, are permitted provided that the following conditions |  * modification, are permitted provided that the following conditions | ||||||
|  | @ -73,6 +73,7 @@ static ERR_STRING_DATA CMS_str_functs[]= | ||||||
| {ERR_FUNC(CMS_F_CHECK_CONTENT),	"CHECK_CONTENT"}, | {ERR_FUNC(CMS_F_CHECK_CONTENT),	"CHECK_CONTENT"}, | ||||||
| {ERR_FUNC(CMS_F_CMS_ADD0_CERT),	"CMS_add0_cert"}, | {ERR_FUNC(CMS_F_CMS_ADD0_CERT),	"CMS_add0_cert"}, | ||||||
| {ERR_FUNC(CMS_F_CMS_ADD0_RECIPIENT_KEY),	"CMS_add0_recipient_key"}, | {ERR_FUNC(CMS_F_CMS_ADD0_RECIPIENT_KEY),	"CMS_add0_recipient_key"}, | ||||||
|  | {ERR_FUNC(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD),	"CMS_add0_recipient_password"}, | ||||||
| {ERR_FUNC(CMS_F_CMS_ADD1_RECEIPTREQUEST),	"CMS_add1_ReceiptRequest"}, | {ERR_FUNC(CMS_F_CMS_ADD1_RECEIPTREQUEST),	"CMS_add1_ReceiptRequest"}, | ||||||
| {ERR_FUNC(CMS_F_CMS_ADD1_RECIPIENT_CERT),	"CMS_add1_recipient_cert"}, | {ERR_FUNC(CMS_F_CMS_ADD1_RECIPIENT_CERT),	"CMS_add1_recipient_cert"}, | ||||||
| {ERR_FUNC(CMS_F_CMS_ADD1_SIGNER),	"CMS_add1_signer"}, | {ERR_FUNC(CMS_F_CMS_ADD1_SIGNER),	"CMS_add1_signer"}, | ||||||
|  | @ -87,6 +88,7 @@ static ERR_STRING_DATA CMS_str_functs[]= | ||||||
| {ERR_FUNC(CMS_F_CMS_DATAINIT),	"CMS_dataInit"}, | {ERR_FUNC(CMS_F_CMS_DATAINIT),	"CMS_dataInit"}, | ||||||
| {ERR_FUNC(CMS_F_CMS_DECRYPT),	"CMS_decrypt"}, | {ERR_FUNC(CMS_F_CMS_DECRYPT),	"CMS_decrypt"}, | ||||||
| {ERR_FUNC(CMS_F_CMS_DECRYPT_SET1_KEY),	"CMS_decrypt_set1_key"}, | {ERR_FUNC(CMS_F_CMS_DECRYPT_SET1_KEY),	"CMS_decrypt_set1_key"}, | ||||||
|  | {ERR_FUNC(CMS_F_CMS_DECRYPT_SET1_PASSWORD),	"CMS_decrypt_set1_password"}, | ||||||
| {ERR_FUNC(CMS_F_CMS_DECRYPT_SET1_PKEY),	"CMS_decrypt_set1_pkey"}, | {ERR_FUNC(CMS_F_CMS_DECRYPT_SET1_PKEY),	"CMS_decrypt_set1_pkey"}, | ||||||
| {ERR_FUNC(CMS_F_CMS_DIGESTALGORITHM_FIND_CTX),	"cms_DigestAlgorithm_find_ctx"}, | {ERR_FUNC(CMS_F_CMS_DIGESTALGORITHM_FIND_CTX),	"cms_DigestAlgorithm_find_ctx"}, | ||||||
| {ERR_FUNC(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO),	"cms_DigestAlgorithm_init_bio"}, | {ERR_FUNC(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO),	"cms_DigestAlgorithm_init_bio"}, | ||||||
|  | @ -105,7 +107,7 @@ static ERR_STRING_DATA CMS_str_functs[]= | ||||||
| {ERR_FUNC(CMS_F_CMS_GET0_CERTIFICATE_CHOICES),	"CMS_GET0_CERTIFICATE_CHOICES"}, | {ERR_FUNC(CMS_F_CMS_GET0_CERTIFICATE_CHOICES),	"CMS_GET0_CERTIFICATE_CHOICES"}, | ||||||
| {ERR_FUNC(CMS_F_CMS_GET0_CONTENT),	"CMS_get0_content"}, | {ERR_FUNC(CMS_F_CMS_GET0_CONTENT),	"CMS_get0_content"}, | ||||||
| {ERR_FUNC(CMS_F_CMS_GET0_ECONTENT_TYPE),	"CMS_GET0_ECONTENT_TYPE"}, | {ERR_FUNC(CMS_F_CMS_GET0_ECONTENT_TYPE),	"CMS_GET0_ECONTENT_TYPE"}, | ||||||
| {ERR_FUNC(CMS_F_CMS_GET0_ENVELOPED),	"CMS_GET0_ENVELOPED"}, | {ERR_FUNC(CMS_F_CMS_GET0_ENVELOPED),	"cms_get0_enveloped"}, | ||||||
| {ERR_FUNC(CMS_F_CMS_GET0_REVOCATION_CHOICES),	"CMS_GET0_REVOCATION_CHOICES"}, | {ERR_FUNC(CMS_F_CMS_GET0_REVOCATION_CHOICES),	"CMS_GET0_REVOCATION_CHOICES"}, | ||||||
| {ERR_FUNC(CMS_F_CMS_GET0_SIGNED),	"CMS_GET0_SIGNED"}, | {ERR_FUNC(CMS_F_CMS_GET0_SIGNED),	"CMS_GET0_SIGNED"}, | ||||||
| {ERR_FUNC(CMS_F_CMS_MSGSIGDIGEST_ADD1),	"cms_msgSigDigest_add1"}, | {ERR_FUNC(CMS_F_CMS_MSGSIGDIGEST_ADD1),	"cms_msgSigDigest_add1"}, | ||||||
|  | @ -121,7 +123,9 @@ static ERR_STRING_DATA CMS_str_functs[]= | ||||||
| {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT),	"CMS_RECIPIENTINFO_KTRI_ENCRYPT"}, | {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT),	"CMS_RECIPIENTINFO_KTRI_ENCRYPT"}, | ||||||
| {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS),	"CMS_RecipientInfo_ktri_get0_algs"}, | {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS),	"CMS_RecipientInfo_ktri_get0_algs"}, | ||||||
| {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID),	"CMS_RecipientInfo_ktri_get0_signer_id"}, | {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID),	"CMS_RecipientInfo_ktri_get0_signer_id"}, | ||||||
|  | {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT),	"cms_RecipientInfo_pwri_crypt"}, | ||||||
| {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_SET0_KEY),	"CMS_RecipientInfo_set0_key"}, | {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_SET0_KEY),	"CMS_RecipientInfo_set0_key"}, | ||||||
|  | {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD),	"CMS_RecipientInfo_set0_password"}, | ||||||
| {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_SET0_PKEY),	"CMS_RecipientInfo_set0_pkey"}, | {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_SET0_PKEY),	"CMS_RecipientInfo_set0_pkey"}, | ||||||
| {ERR_FUNC(CMS_F_CMS_SET1_SIGNERIDENTIFIER),	"cms_set1_SignerIdentifier"}, | {ERR_FUNC(CMS_F_CMS_SET1_SIGNERIDENTIFIER),	"cms_set1_SignerIdentifier"}, | ||||||
| {ERR_FUNC(CMS_F_CMS_SET_DETACHED),	"CMS_set_detached"}, | {ERR_FUNC(CMS_F_CMS_SET_DETACHED),	"CMS_set_detached"}, | ||||||
|  | @ -165,6 +169,7 @@ static ERR_STRING_DATA CMS_str_reasons[]= | ||||||
| {ERR_REASON(CMS_R_ERROR_SETTING_KEY)     ,"error setting key"}, | {ERR_REASON(CMS_R_ERROR_SETTING_KEY)     ,"error setting key"}, | ||||||
| {ERR_REASON(CMS_R_ERROR_SETTING_RECIPIENTINFO),"error setting recipientinfo"}, | {ERR_REASON(CMS_R_ERROR_SETTING_RECIPIENTINFO),"error setting recipientinfo"}, | ||||||
| {ERR_REASON(CMS_R_INVALID_ENCRYPTED_KEY_LENGTH),"invalid encrypted key length"}, | {ERR_REASON(CMS_R_INVALID_ENCRYPTED_KEY_LENGTH),"invalid encrypted key length"}, | ||||||
|  | {ERR_REASON(CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER),"invalid key encryption parameter"}, | ||||||
| {ERR_REASON(CMS_R_INVALID_KEY_LENGTH)    ,"invalid key length"}, | {ERR_REASON(CMS_R_INVALID_KEY_LENGTH)    ,"invalid key length"}, | ||||||
| {ERR_REASON(CMS_R_MD_BIO_INIT_ERROR)     ,"md bio init error"}, | {ERR_REASON(CMS_R_MD_BIO_INIT_ERROR)     ,"md bio init error"}, | ||||||
| {ERR_REASON(CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH),"messagedigest attribute wrong length"}, | {ERR_REASON(CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH),"messagedigest attribute wrong length"}, | ||||||
|  | @ -177,6 +182,7 @@ static ERR_STRING_DATA CMS_str_reasons[]= | ||||||
| {ERR_REASON(CMS_R_NOT_ENCRYPTED_DATA)    ,"not encrypted data"}, | {ERR_REASON(CMS_R_NOT_ENCRYPTED_DATA)    ,"not encrypted data"}, | ||||||
| {ERR_REASON(CMS_R_NOT_KEK)               ,"not kek"}, | {ERR_REASON(CMS_R_NOT_KEK)               ,"not kek"}, | ||||||
| {ERR_REASON(CMS_R_NOT_KEY_TRANSPORT)     ,"not key transport"}, | {ERR_REASON(CMS_R_NOT_KEY_TRANSPORT)     ,"not key transport"}, | ||||||
|  | {ERR_REASON(CMS_R_NOT_PWRI)              ,"not pwri"}, | ||||||
| {ERR_REASON(CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE),"not supported for this key type"}, | {ERR_REASON(CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE),"not supported for this key type"}, | ||||||
| {ERR_REASON(CMS_R_NO_CIPHER)             ,"no cipher"}, | {ERR_REASON(CMS_R_NO_CIPHER)             ,"no cipher"}, | ||||||
| {ERR_REASON(CMS_R_NO_CONTENT)            ,"no content"}, | {ERR_REASON(CMS_R_NO_CONTENT)            ,"no content"}, | ||||||
|  | @ -189,6 +195,7 @@ static ERR_STRING_DATA CMS_str_reasons[]= | ||||||
| {ERR_REASON(CMS_R_NO_MATCHING_RECIPIENT) ,"no matching recipient"}, | {ERR_REASON(CMS_R_NO_MATCHING_RECIPIENT) ,"no matching recipient"}, | ||||||
| {ERR_REASON(CMS_R_NO_MATCHING_SIGNATURE) ,"no matching signature"}, | {ERR_REASON(CMS_R_NO_MATCHING_SIGNATURE) ,"no matching signature"}, | ||||||
| {ERR_REASON(CMS_R_NO_MSGSIGDIGEST)       ,"no msgsigdigest"}, | {ERR_REASON(CMS_R_NO_MSGSIGDIGEST)       ,"no msgsigdigest"}, | ||||||
|  | {ERR_REASON(CMS_R_NO_PASSWORD)           ,"no password"}, | ||||||
| {ERR_REASON(CMS_R_NO_PRIVATE_KEY)        ,"no private key"}, | {ERR_REASON(CMS_R_NO_PRIVATE_KEY)        ,"no private key"}, | ||||||
| {ERR_REASON(CMS_R_NO_PUBLIC_KEY)         ,"no public key"}, | {ERR_REASON(CMS_R_NO_PUBLIC_KEY)         ,"no public key"}, | ||||||
| {ERR_REASON(CMS_R_NO_RECEIPT_REQUEST)    ,"no receipt request"}, | {ERR_REASON(CMS_R_NO_RECEIPT_REQUEST)    ,"no receipt request"}, | ||||||
|  | @ -212,10 +219,12 @@ static ERR_STRING_DATA CMS_str_reasons[]= | ||||||
| {ERR_REASON(CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM),"unsupported compression algorithm"}, | {ERR_REASON(CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM),"unsupported compression algorithm"}, | ||||||
| {ERR_REASON(CMS_R_UNSUPPORTED_CONTENT_TYPE),"unsupported content type"}, | {ERR_REASON(CMS_R_UNSUPPORTED_CONTENT_TYPE),"unsupported content type"}, | ||||||
| {ERR_REASON(CMS_R_UNSUPPORTED_KEK_ALGORITHM),"unsupported kek algorithm"}, | {ERR_REASON(CMS_R_UNSUPPORTED_KEK_ALGORITHM),"unsupported kek algorithm"}, | ||||||
|  | {ERR_REASON(CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM),"unsupported key encryption algorithm"}, | ||||||
| {ERR_REASON(CMS_R_UNSUPPORTED_RECIPIENT_TYPE),"unsupported recipient type"}, | {ERR_REASON(CMS_R_UNSUPPORTED_RECIPIENT_TYPE),"unsupported recipient type"}, | ||||||
| {ERR_REASON(CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE),"unsupported recpientinfo type"}, | {ERR_REASON(CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE),"unsupported recpientinfo type"}, | ||||||
| {ERR_REASON(CMS_R_UNSUPPORTED_TYPE)      ,"unsupported type"}, | {ERR_REASON(CMS_R_UNSUPPORTED_TYPE)      ,"unsupported type"}, | ||||||
| {ERR_REASON(CMS_R_UNWRAP_ERROR)          ,"unwrap error"}, | {ERR_REASON(CMS_R_UNWRAP_ERROR)          ,"unwrap error"}, | ||||||
|  | {ERR_REASON(CMS_R_UNWRAP_FAILURE)        ,"unwrap failure"}, | ||||||
| {ERR_REASON(CMS_R_VERIFICATION_FAILURE)  ,"verification failure"}, | {ERR_REASON(CMS_R_VERIFICATION_FAILURE)  ,"verification failure"}, | ||||||
| {ERR_REASON(CMS_R_WRAP_ERROR)            ,"wrap error"}, | {ERR_REASON(CMS_R_WRAP_ERROR)            ,"wrap error"}, | ||||||
| {0,NULL} | {0,NULL} | ||||||
|  |  | ||||||
|  | @ -273,6 +273,9 @@ struct CMS_PasswordRecipientInfo_st | ||||||
|  	X509_ALGOR *keyDerivationAlgorithm; |  	X509_ALGOR *keyDerivationAlgorithm; | ||||||
|  	X509_ALGOR *keyEncryptionAlgorithm; |  	X509_ALGOR *keyEncryptionAlgorithm; | ||||||
|  	ASN1_OCTET_STRING *encryptedKey; |  	ASN1_OCTET_STRING *encryptedKey; | ||||||
|  | 	/* Extra info: password to use */ | ||||||
|  | 	unsigned char *pass; | ||||||
|  | 	size_t passlen; | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| struct CMS_OtherRecipientInfo_st | struct CMS_OtherRecipientInfo_st | ||||||
|  | @ -411,6 +414,8 @@ DECLARE_ASN1_ITEM(CMS_SignerInfo) | ||||||
| DECLARE_ASN1_ITEM(CMS_IssuerAndSerialNumber) | DECLARE_ASN1_ITEM(CMS_IssuerAndSerialNumber) | ||||||
| DECLARE_ASN1_ITEM(CMS_Attributes_Sign) | DECLARE_ASN1_ITEM(CMS_Attributes_Sign) | ||||||
| DECLARE_ASN1_ITEM(CMS_Attributes_Verify) | DECLARE_ASN1_ITEM(CMS_Attributes_Verify) | ||||||
|  | DECLARE_ASN1_ITEM(CMS_RecipientInfo) | ||||||
|  | DECLARE_ASN1_ITEM(CMS_PasswordRecipientInfo) | ||||||
| DECLARE_ASN1_ALLOC_FUNCTIONS(CMS_IssuerAndSerialNumber) | DECLARE_ASN1_ALLOC_FUNCTIONS(CMS_IssuerAndSerialNumber) | ||||||
| 
 | 
 | ||||||
| #define CMS_SIGNERINFO_ISSUER_SERIAL	0 | #define CMS_SIGNERINFO_ISSUER_SERIAL	0 | ||||||
|  | @ -454,6 +459,11 @@ int cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src); | ||||||
| ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si); | ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si); | ||||||
| 
 | 
 | ||||||
| BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms); | BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms); | ||||||
|  | CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms); | ||||||
|  | 
 | ||||||
|  | /* PWRI routines */ | ||||||
|  | int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri, | ||||||
|  | 							int en_de); | ||||||
| 	 | 	 | ||||||
| #ifdef  __cplusplus | #ifdef  __cplusplus | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -0,0 +1,453 @@ | ||||||
|  | /* crypto/cms/cms_pwri.c */ | ||||||
|  | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
 | ||||||
|  |  * project. | ||||||
|  |  */ | ||||||
|  | /* ====================================================================
 | ||||||
|  |  * Copyright (c) 2009 The OpenSSL Project.  All rights reserved. | ||||||
|  |  * | ||||||
|  |  * Redistribution and use in source and binary forms, with or without | ||||||
|  |  * modification, are permitted provided that the following conditions | ||||||
|  |  * are met: | ||||||
|  |  * | ||||||
|  |  * 1. Redistributions of source code must retain the above copyright | ||||||
|  |  *    notice, this list of conditions and the following disclaimer.  | ||||||
|  |  * | ||||||
|  |  * 2. Redistributions in binary form must reproduce the above copyright | ||||||
|  |  *    notice, this list of conditions and the following disclaimer in | ||||||
|  |  *    the documentation and/or other materials provided with the | ||||||
|  |  *    distribution. | ||||||
|  |  * | ||||||
|  |  * 3. All advertising materials mentioning features or use of this | ||||||
|  |  *    software must display the following acknowledgment: | ||||||
|  |  *    "This product includes software developed by the OpenSSL Project | ||||||
|  |  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 | ||||||
|  |  * | ||||||
|  |  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||||||
|  |  *    endorse or promote products derived from this software without | ||||||
|  |  *    prior written permission. For written permission, please contact | ||||||
|  |  *    licensing@OpenSSL.org. | ||||||
|  |  * | ||||||
|  |  * 5. Products derived from this software may not be called "OpenSSL" | ||||||
|  |  *    nor may "OpenSSL" appear in their names without prior written | ||||||
|  |  *    permission of the OpenSSL Project. | ||||||
|  |  * | ||||||
|  |  * 6. Redistributions of any form whatsoever must retain the following | ||||||
|  |  *    acknowledgment: | ||||||
|  |  *    "This product includes software developed by the OpenSSL Project | ||||||
|  |  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 | ||||||
|  |  * | ||||||
|  |  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||||||
|  |  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||||||
|  |  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||||||
|  |  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||||||
|  |  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||||||
|  |  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||||||
|  |  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||||||
|  |  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||||||
|  |  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||||||
|  |  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||||||
|  |  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||||||
|  |  * OF THE POSSIBILITY OF SUCH DAMAGE. | ||||||
|  |  * ==================================================================== | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include "cryptlib.h" | ||||||
|  | #include <openssl/asn1t.h> | ||||||
|  | #include <openssl/pem.h> | ||||||
|  | #include <openssl/x509v3.h> | ||||||
|  | #include <openssl/err.h> | ||||||
|  | #include <openssl/cms.h> | ||||||
|  | #include <openssl/rand.h> | ||||||
|  | #include <openssl/aes.h> | ||||||
|  | #include "cms_lcl.h" | ||||||
|  | #include "asn1_locl.h" | ||||||
|  | 
 | ||||||
|  | int CMS_RecipientInfo_set0_password(CMS_RecipientInfo *ri,  | ||||||
|  | 				unsigned char *pass, ssize_t passlen) | ||||||
|  | 	{ | ||||||
|  | 	CMS_PasswordRecipientInfo *pwri; | ||||||
|  | 	if (ri->type != CMS_RECIPINFO_PASS) | ||||||
|  | 		{ | ||||||
|  | 		CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD, CMS_R_NOT_PWRI); | ||||||
|  | 		return 0; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 	pwri = ri->d.pwri; | ||||||
|  | 	pwri->pass = pass; | ||||||
|  | 	if (pass && passlen < 0) | ||||||
|  | 		passlen = strlen((char *)pass); | ||||||
|  | 	pwri->passlen = passlen; | ||||||
|  | 	return 1; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms, | ||||||
|  | 					int iter, int wrap_nid, int pbe_nid, | ||||||
|  | 					unsigned char *pass, ssize_t passlen, | ||||||
|  | 					const EVP_CIPHER *kekciph) | ||||||
|  | 	{ | ||||||
|  | 	CMS_RecipientInfo *ri = NULL; | ||||||
|  | 	CMS_EnvelopedData *env; | ||||||
|  | 	CMS_PasswordRecipientInfo *pwri; | ||||||
|  | 	EVP_CIPHER_CTX ctx; | ||||||
|  | 	X509_ALGOR *encalg = NULL; | ||||||
|  | 	unsigned char iv[EVP_MAX_IV_LENGTH]; | ||||||
|  | 	int ivlen; | ||||||
|  | 	env = cms_get0_enveloped(cms); | ||||||
|  | 	if (!env) | ||||||
|  | 		goto err; | ||||||
|  | 
 | ||||||
|  | 	if (wrap_nid <= 0) | ||||||
|  | 		wrap_nid = NID_id_alg_PWRI_KEK; | ||||||
|  | 
 | ||||||
|  | 	if (pbe_nid <= 0) | ||||||
|  | 		pbe_nid = NID_id_pbkdf2; | ||||||
|  | 
 | ||||||
|  | 	/* Get from enveloped data */ | ||||||
|  | 	if (kekciph == NULL) | ||||||
|  | 		kekciph = env->encryptedContentInfo->cipher; | ||||||
|  | 
 | ||||||
|  | 	if (kekciph == NULL) | ||||||
|  | 		{ | ||||||
|  | 		CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, CMS_R_NO_CIPHER); | ||||||
|  | 		return NULL; | ||||||
|  | 		} | ||||||
|  | 	if (wrap_nid != NID_id_alg_PWRI_KEK) | ||||||
|  | 		{ | ||||||
|  | 		CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, | ||||||
|  | 				CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM); | ||||||
|  | 		return NULL; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 	/* Setup algorithm identifier for cipher */ | ||||||
|  | 	encalg = X509_ALGOR_new(); | ||||||
|  | 	EVP_CIPHER_CTX_init(&ctx); | ||||||
|  | 
 | ||||||
|  | 	if (EVP_EncryptInit_ex(&ctx, kekciph, NULL, NULL, NULL) <= 0) | ||||||
|  | 		{ | ||||||
|  | 		CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_EVP_LIB); | ||||||
|  | 		goto err; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 	ivlen = EVP_CIPHER_CTX_iv_length(&ctx); | ||||||
|  | 
 | ||||||
|  | 	if (ivlen > 0) | ||||||
|  | 		{ | ||||||
|  | 		if (RAND_pseudo_bytes(iv, ivlen) <= 0) | ||||||
|  | 			goto err; | ||||||
|  | 		if (EVP_EncryptInit_ex(&ctx, NULL, NULL, NULL, iv) <= 0) | ||||||
|  | 			{ | ||||||
|  | 			CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, | ||||||
|  | 							ERR_R_EVP_LIB); | ||||||
|  | 			goto err; | ||||||
|  | 			} | ||||||
|  | 		encalg->parameter = ASN1_TYPE_new(); | ||||||
|  | 		if (!encalg->parameter) | ||||||
|  | 			{ | ||||||
|  | 			CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, | ||||||
|  | 							ERR_R_MALLOC_FAILURE); | ||||||
|  | 			goto err; | ||||||
|  | 			} | ||||||
|  | 		if (EVP_CIPHER_param_to_asn1(&ctx, encalg->parameter) <= 0) | ||||||
|  | 			{ | ||||||
|  | 			CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, | ||||||
|  | 				CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); | ||||||
|  | 			goto err; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 	encalg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(&ctx)); | ||||||
|  | 
 | ||||||
|  | 	EVP_CIPHER_CTX_cleanup(&ctx); | ||||||
|  | 
 | ||||||
|  | 	/* Initialize recipient info */ | ||||||
|  | 	ri = M_ASN1_new_of(CMS_RecipientInfo); | ||||||
|  | 	if (!ri) | ||||||
|  | 		goto merr; | ||||||
|  | 
 | ||||||
|  | 	ri->d.pwri = M_ASN1_new_of(CMS_PasswordRecipientInfo); | ||||||
|  | 	if (!ri->d.pwri) | ||||||
|  | 		goto merr; | ||||||
|  | 	ri->type = CMS_RECIPINFO_PASS; | ||||||
|  | 
 | ||||||
|  | 	pwri = ri->d.pwri; | ||||||
|  | 	/* Since this is overwritten, free up empty structure already there */ | ||||||
|  | 	X509_ALGOR_free(pwri->keyEncryptionAlgorithm); | ||||||
|  | 	pwri->keyEncryptionAlgorithm = X509_ALGOR_new(); | ||||||
|  | 	if (!pwri->keyEncryptionAlgorithm) | ||||||
|  | 		goto merr; | ||||||
|  | 	pwri->keyEncryptionAlgorithm->algorithm = OBJ_nid2obj(wrap_nid); | ||||||
|  | 	pwri->keyEncryptionAlgorithm->parameter = ASN1_TYPE_new(); | ||||||
|  | 	if (!pwri->keyEncryptionAlgorithm->parameter) | ||||||
|  | 		goto merr; | ||||||
|  | 
 | ||||||
|  |         if(!ASN1_item_pack(encalg, ASN1_ITEM_rptr(X509_ALGOR), | ||||||
|  | 	    &pwri->keyEncryptionAlgorithm->parameter->value.sequence)) | ||||||
|  | 		goto merr; | ||||||
|  |         pwri->keyEncryptionAlgorithm->parameter->type = V_ASN1_SEQUENCE; | ||||||
|  | 
 | ||||||
|  | 	X509_ALGOR_free(encalg); | ||||||
|  | 	encalg = NULL; | ||||||
|  | 
 | ||||||
|  | 	/* Setup PBE algorithm */ | ||||||
|  | 
 | ||||||
|  | 	pwri->keyDerivationAlgorithm = PKCS5_pbkdf2_set(iter, NULL, 0, -1, -1); | ||||||
|  | 
 | ||||||
|  | 	if (!pwri->keyDerivationAlgorithm) | ||||||
|  | 		goto err; | ||||||
|  | 
 | ||||||
|  | 	CMS_RecipientInfo_set0_password(ri, pass, passlen); | ||||||
|  | 	pwri->version = 0; | ||||||
|  | 
 | ||||||
|  | 	if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri)) | ||||||
|  | 		goto merr; | ||||||
|  | 
 | ||||||
|  | 	return ri; | ||||||
|  | 
 | ||||||
|  | 	merr: | ||||||
|  | 	CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_MALLOC_FAILURE); | ||||||
|  | 	err: | ||||||
|  | 	EVP_CIPHER_CTX_cleanup(&ctx); | ||||||
|  | 	if (ri) | ||||||
|  | 		M_ASN1_free_of(ri, CMS_RecipientInfo); | ||||||
|  | 	if (encalg) | ||||||
|  | 		X509_ALGOR_free(encalg); | ||||||
|  | 	return NULL; | ||||||
|  | 
 | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | /* This is an implementation of the key wrapping mechanism in RFC3211,
 | ||||||
|  |  * at some point this should go into EVP. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | static int kek_unwrap_key(unsigned char *out, size_t *outlen, | ||||||
|  | 		const unsigned char *in, size_t inlen, EVP_CIPHER_CTX *ctx) | ||||||
|  | 	{ | ||||||
|  | 	size_t blocklen = EVP_CIPHER_CTX_block_size(ctx); | ||||||
|  | 	unsigned char *tmp; | ||||||
|  | 	int outl, rv = 0; | ||||||
|  | 	if (inlen < 2 * blocklen) | ||||||
|  | 		{ | ||||||
|  | 		/* too small */ | ||||||
|  | 		return 0; | ||||||
|  | 		} | ||||||
|  | 	if (inlen % blocklen) | ||||||
|  | 		{ | ||||||
|  | 		/* Invalid size */ | ||||||
|  | 		return 0; | ||||||
|  | 		} | ||||||
|  | 	tmp = OPENSSL_malloc(inlen); | ||||||
|  | 	/* setup IV by decrypting last two blocks */ | ||||||
|  | 	EVP_DecryptUpdate(ctx, tmp + inlen - 2 * blocklen, &outl, | ||||||
|  | 				in  + inlen - 2 * blocklen, blocklen * 2); | ||||||
|  | 	/* Do a decrypt of last decrypted block to set IV to correct value
 | ||||||
|  | 	 * output it to start of buffer so we don't corrupt decrypted block | ||||||
|  | 	 * this works because buffer is at least two block lengths long. | ||||||
|  | 	 */ | ||||||
|  | 	EVP_DecryptUpdate(ctx, tmp, &outl, | ||||||
|  | 				tmp  + inlen - blocklen, blocklen); | ||||||
|  | 	/* Can now decrypt first n - 1 blocks */ | ||||||
|  | 	EVP_DecryptUpdate(ctx, tmp, &outl, in, inlen - blocklen); | ||||||
|  | 
 | ||||||
|  | 	/* Reset IV to original value */ | ||||||
|  | 	EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, NULL); | ||||||
|  | 	/* Decrypt again */ | ||||||
|  | 	EVP_DecryptUpdate(ctx, tmp, &outl, tmp, inlen); | ||||||
|  | 	/* Check check bytes */ | ||||||
|  | 	if (((tmp[1] ^ tmp[4]) & (tmp[2] ^ tmp[5]) & (tmp[3] ^ tmp[6])) != 0xff) | ||||||
|  | 		{ | ||||||
|  | 		/* Check byte failure */ | ||||||
|  | 		goto err; | ||||||
|  | 		} | ||||||
|  | 	if (inlen < (size_t)(tmp[0] - 4 )) | ||||||
|  | 		{ | ||||||
|  | 		/* Invalid length value */ | ||||||
|  | 		goto err; | ||||||
|  | 		} | ||||||
|  | 	*outlen = (size_t)tmp[0]; | ||||||
|  | 	memcpy(out, tmp + 4, *outlen); | ||||||
|  | 	rv = 1; | ||||||
|  | 	err: | ||||||
|  | 	OPENSSL_cleanse(tmp, inlen); | ||||||
|  | 	OPENSSL_free(tmp); | ||||||
|  | 	return rv; | ||||||
|  | 
 | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | static int kek_wrap_key(unsigned char *out, size_t *outlen, | ||||||
|  | 		const unsigned char *in, size_t inlen, EVP_CIPHER_CTX *ctx) | ||||||
|  | 	{ | ||||||
|  | 	size_t blocklen = EVP_CIPHER_CTX_block_size(ctx); | ||||||
|  | 	size_t olen; | ||||||
|  | 	int dummy; | ||||||
|  | 	/* First decide length of output buffer: need header and round up to
 | ||||||
|  | 	 * multiple of block length. | ||||||
|  | 	 */ | ||||||
|  | 	olen = (inlen + 4 + blocklen - 1)/blocklen; | ||||||
|  | 	olen *= blocklen; | ||||||
|  | 	if (olen < 2 * blocklen) | ||||||
|  | 		{ | ||||||
|  | 		/* Key too small */ | ||||||
|  | 		return 0; | ||||||
|  | 		} | ||||||
|  | 	if (inlen > 0xFF) | ||||||
|  | 		{ | ||||||
|  | 		/* Key too large */ | ||||||
|  | 		return 0; | ||||||
|  | 		} | ||||||
|  | 	if (out) | ||||||
|  | 		{ | ||||||
|  | 		/* Set header */ | ||||||
|  | 		out[0] = (unsigned char)inlen; | ||||||
|  | 		out[1] = in[0] ^ 0xFF; | ||||||
|  | 		out[2] = in[1] ^ 0xFF; | ||||||
|  | 		out[3] = in[2] ^ 0xFF; | ||||||
|  | 		memcpy(out + 4, in, inlen); | ||||||
|  | 		/* Add random padding to end */ | ||||||
|  | 		if (olen > inlen + 4) | ||||||
|  | 			RAND_pseudo_bytes(out + 4 + inlen, olen - 4 - inlen); | ||||||
|  | 		/* Encrypt twice */ | ||||||
|  | 		EVP_EncryptUpdate(ctx, out, &dummy, out, olen); | ||||||
|  | 		EVP_EncryptUpdate(ctx, out, &dummy, out, olen); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 	*outlen = olen; | ||||||
|  | 
 | ||||||
|  | 	return 1; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | /* Encrypt/Decrypt content key in PWRI recipient info */ | ||||||
|  | 
 | ||||||
|  | int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri, | ||||||
|  | 							int en_de) | ||||||
|  | 	{ | ||||||
|  | 	CMS_EncryptedContentInfo *ec; | ||||||
|  | 	CMS_PasswordRecipientInfo *pwri; | ||||||
|  | 	const unsigned char *p = NULL; | ||||||
|  | 	int plen; | ||||||
|  | 	int r = 0; | ||||||
|  | 	X509_ALGOR *algtmp, *kekalg = NULL; | ||||||
|  | 	EVP_CIPHER_CTX kekctx; | ||||||
|  | 	const EVP_CIPHER *kekcipher; | ||||||
|  | 	unsigned char *key = NULL; | ||||||
|  | 	size_t keylen; | ||||||
|  | 
 | ||||||
|  | 	ec = cms->d.envelopedData->encryptedContentInfo; | ||||||
|  | 
 | ||||||
|  | 	pwri = ri->d.pwri; | ||||||
|  | 	EVP_CIPHER_CTX_init(&kekctx); | ||||||
|  | 
 | ||||||
|  | 	if (!pwri->pass) | ||||||
|  | 		{ | ||||||
|  | 		CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_NO_PASSWORD); | ||||||
|  | 		return 0; | ||||||
|  | 		} | ||||||
|  | 	algtmp = pwri->keyEncryptionAlgorithm; | ||||||
|  | 
 | ||||||
|  | 	if (!algtmp || OBJ_obj2nid(algtmp->algorithm) != NID_id_alg_PWRI_KEK) | ||||||
|  | 		{ | ||||||
|  | 		CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, | ||||||
|  | 				CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM); | ||||||
|  | 		return 0; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 	if (algtmp->parameter->type == V_ASN1_SEQUENCE) | ||||||
|  | 		{ | ||||||
|  | 		p = algtmp->parameter->value.sequence->data; | ||||||
|  | 		plen = algtmp->parameter->value.sequence->length; | ||||||
|  | 		kekalg = d2i_X509_ALGOR(NULL, &p, plen); | ||||||
|  | 		} | ||||||
|  | 	if (kekalg == NULL) | ||||||
|  | 		{ | ||||||
|  | 		CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, | ||||||
|  | 				CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER); | ||||||
|  | 		return 0; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 	kekcipher = EVP_get_cipherbyobj(kekalg->algorithm); | ||||||
|  | 		 | ||||||
|  | 	if(!kekcipher) | ||||||
|  | 		{ | ||||||
|  | 		CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, | ||||||
|  | 				CMS_R_UNKNOWN_CIPHER); | ||||||
|  | 		goto err; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 	/* Fixup cipher based on AlgorithmIdentifier to set IV etc */ | ||||||
|  | 	if (!EVP_CipherInit_ex(&kekctx, kekcipher, NULL, NULL, NULL, en_de)) | ||||||
|  | 		goto err; | ||||||
|  | 	EVP_CIPHER_CTX_set_padding(&kekctx, 0); | ||||||
|  | 	if(EVP_CIPHER_asn1_to_param(&kekctx, kekalg->parameter) < 0) | ||||||
|  | 		{ | ||||||
|  | 		CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, | ||||||
|  | 				CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); | ||||||
|  | 		goto err; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 	algtmp = pwri->keyDerivationAlgorithm; | ||||||
|  | 
 | ||||||
|  | 	/* Finish password based key derivation to setup key in "ctx" */ | ||||||
|  | 
 | ||||||
|  | 	if (EVP_PBE_CipherInit(algtmp->algorithm, | ||||||
|  | 				(char *)pwri->pass, pwri->passlen, | ||||||
|  | 				algtmp->parameter, &kekctx, en_de) < 0) | ||||||
|  | 		{ | ||||||
|  | 		CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_EVP_LIB); | ||||||
|  | 		goto err; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 	/* Finally wrap/unwrap the key */ | ||||||
|  | 
 | ||||||
|  | 	if (en_de) | ||||||
|  | 		{ | ||||||
|  | 
 | ||||||
|  | 		if (!kek_wrap_key(NULL, &keylen, ec->key, ec->keylen, &kekctx)) | ||||||
|  | 			goto err; | ||||||
|  | 
 | ||||||
|  | 		key = OPENSSL_malloc(keylen); | ||||||
|  | 
 | ||||||
|  | 		if (!key) | ||||||
|  | 			goto err; | ||||||
|  | 
 | ||||||
|  | 		if (!kek_wrap_key(key, &keylen, ec->key, ec->keylen, &kekctx)) | ||||||
|  | 			goto err; | ||||||
|  | 		pwri->encryptedKey->data = key; | ||||||
|  | 		pwri->encryptedKey->length = keylen; | ||||||
|  | 		} | ||||||
|  | 	else | ||||||
|  | 		{ | ||||||
|  | 		key = OPENSSL_malloc(pwri->encryptedKey->length); | ||||||
|  | 
 | ||||||
|  | 		if (!key) | ||||||
|  | 			{ | ||||||
|  | 			CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, | ||||||
|  | 							ERR_R_MALLOC_FAILURE); | ||||||
|  | 			goto err; | ||||||
|  | 			} | ||||||
|  | 		if (!kek_unwrap_key(key, &keylen, | ||||||
|  | 					pwri->encryptedKey->data, | ||||||
|  | 					pwri->encryptedKey->length, &kekctx)) | ||||||
|  | 			{ | ||||||
|  | 			CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, | ||||||
|  | 							CMS_R_UNWRAP_FAILURE); | ||||||
|  | 			goto err; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 		ec->key = key; | ||||||
|  | 		ec->keylen = keylen; | ||||||
|  | 
 | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 	r = 1; | ||||||
|  | 
 | ||||||
|  | 	err: | ||||||
|  | 
 | ||||||
|  | 	EVP_CIPHER_CTX_cleanup(&kekctx); | ||||||
|  | 
 | ||||||
|  | 	if (!r && key) | ||||||
|  | 		OPENSSL_free(key); | ||||||
|  | 	X509_ALGOR_free(kekalg); | ||||||
|  | 
 | ||||||
|  | 	return r; | ||||||
|  | 
 | ||||||
|  | 	} | ||||||
|  | @ -681,6 +681,30 @@ int CMS_decrypt_set1_key(CMS_ContentInfo *cms, | ||||||
| 
 | 
 | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | int CMS_decrypt_set1_password(CMS_ContentInfo *cms,  | ||||||
|  | 				unsigned char *pass, ssize_t passlen) | ||||||
|  | 	{ | ||||||
|  | 	STACK_OF(CMS_RecipientInfo) *ris; | ||||||
|  | 	CMS_RecipientInfo *ri; | ||||||
|  | 	int i, r; | ||||||
|  | 	ris = CMS_get0_RecipientInfos(cms); | ||||||
|  | 	for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) | ||||||
|  | 		{ | ||||||
|  | 		ri = sk_CMS_RecipientInfo_value(ris, i); | ||||||
|  | 		if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_PASS) | ||||||
|  | 				continue; | ||||||
|  | 		CMS_RecipientInfo_set0_password(ri, pass, passlen); | ||||||
|  | 		r = CMS_RecipientInfo_decrypt(cms, ri); | ||||||
|  | 		CMS_RecipientInfo_set0_password(ri, NULL, 0); | ||||||
|  | 		if (r > 0) | ||||||
|  | 			return 1; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 	CMSerr(CMS_F_CMS_DECRYPT_SET1_PASSWORD, CMS_R_NO_MATCHING_RECIPIENT); | ||||||
|  | 	return 0; | ||||||
|  | 
 | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
| int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert, | int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert, | ||||||
| 				BIO *dcont, BIO *out, | 				BIO *dcont, BIO *out, | ||||||
| 				unsigned int flags) | 				unsigned int flags) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue