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]
|
||||
|
||||
*) Experiemental password based recipient info support for CMS library:
|
||||
implementing RFC3211.
|
||||
[Steve Henson]
|
||||
|
||||
*) Split password based encryption into PBES2 and PBKDF2 functions. This
|
||||
neatly separates the code into cipher and PBE sections and is required
|
||||
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;
|
||||
#endif
|
||||
unsigned char *secret_key = NULL, *secret_keyid = NULL;
|
||||
unsigned char *pwri_pass = NULL, *pwri_tmp = NULL;
|
||||
size_t secret_keylen = 0, secret_keyidlen = 0;
|
||||
|
||||
ASN1_OBJECT *econtent_type = NULL;
|
||||
@ -326,6 +327,13 @@ int MAIN(int argc, char **argv)
|
||||
}
|
||||
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"))
|
||||
{
|
||||
if (!args[1])
|
||||
@ -559,7 +567,7 @@ int MAIN(int argc, char **argv)
|
||||
|
||||
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");
|
||||
badarg = 1;
|
||||
@ -567,7 +575,7 @@ int MAIN(int argc, char **argv)
|
||||
}
|
||||
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");
|
||||
badarg = 1;
|
||||
@ -917,6 +925,17 @@ int MAIN(int argc, char **argv)
|
||||
secret_key = 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 (!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))
|
||||
{
|
||||
BIO_printf(bio_err, "Error decrypting CMS structure\n");
|
||||
@ -1167,6 +1196,8 @@ end:
|
||||
OPENSSL_free(secret_key);
|
||||
if (secret_keyid)
|
||||
OPENSSL_free(secret_keyid);
|
||||
if (pwri_tmp)
|
||||
OPENSSL_free(pwri_tmp);
|
||||
if (econtent_type)
|
||||
ASN1_OBJECT_free(econtent_type);
|
||||
if (rr)
|
||||
|
@ -18,9 +18,11 @@ APPS=
|
||||
|
||||
LIB=$(TOP)/libcrypto.a
|
||||
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 \
|
||||
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)
|
||||
|
||||
|
@ -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,
|
||||
unsigned char *key, size_t keylen,
|
||||
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);
|
||||
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,
|
||||
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_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_CMS_ADD0_CERT 164
|
||||
#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_RECIPIENT_CERT 101
|
||||
#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_DECRYPT 112
|
||||
#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_DIGESTALGORITHM_FIND_CTX 115
|
||||
#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_GET0_ALGS 142
|
||||
#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_PASSWORD 168
|
||||
#define CMS_F_CMS_RECIPIENTINFO_SET0_PKEY 145
|
||||
#define CMS_F_CMS_SET1_SIGNERIDENTIFIER 146
|
||||
#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_RECIPIENTINFO 116
|
||||
#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_MD_BIO_INIT_ERROR 119
|
||||
#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_KEK 123
|
||||
#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_NO_CIPHER 126
|
||||
#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_SIGNATURE 166
|
||||
#define CMS_R_NO_MSGSIGDIGEST 167
|
||||
#define CMS_R_NO_PASSWORD 178
|
||||
#define CMS_R_NO_PRIVATE_KEY 133
|
||||
#define CMS_R_NO_PUBLIC_KEY 134
|
||||
#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_CONTENT_TYPE 152
|
||||
#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_RECPIENTINFO_TYPE 155
|
||||
#define CMS_R_UNSUPPORTED_TYPE 156
|
||||
#define CMS_R_UNWRAP_ERROR 157
|
||||
#define CMS_R_UNWRAP_FAILURE 180
|
||||
#define CMS_R_VERIFICATION_FAILURE 158
|
||||
#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);
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
@ -65,14 +65,13 @@
|
||||
/* CMS EnvelopedData Utilities */
|
||||
|
||||
DECLARE_ASN1_ITEM(CMS_EnvelopedData)
|
||||
DECLARE_ASN1_ITEM(CMS_RecipientInfo)
|
||||
DECLARE_ASN1_ITEM(CMS_KeyTransRecipientInfo)
|
||||
DECLARE_ASN1_ITEM(CMS_KEKRecipientInfo)
|
||||
DECLARE_ASN1_ITEM(CMS_OtherKeyAttribute)
|
||||
|
||||
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)
|
||||
{
|
||||
@ -786,6 +785,9 @@ int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri)
|
||||
case CMS_RECIPINFO_KEK:
|
||||
return cms_RecipientInfo_kekri_decrypt(cms, ri);
|
||||
|
||||
case CMS_RECIPINFO_PASS:
|
||||
return cms_RecipientInfo_pwri_crypt(cms, ri, 0);
|
||||
|
||||
default:
|
||||
CMSerr(CMS_F_CMS_RECIPIENTINFO_DECRYPT,
|
||||
CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE);
|
||||
@ -829,6 +831,10 @@ BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms)
|
||||
r = cms_RecipientInfo_kekri_encrypt(cms, ri);
|
||||
break;
|
||||
|
||||
case CMS_RECIPINFO_PASS:
|
||||
r = cms_RecipientInfo_pwri_crypt(cms, ri, 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO,
|
||||
CMS_R_UNSUPPORTED_RECIPIENT_TYPE);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* 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
|
||||
* 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_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_PASSWORD), "CMS_add0_recipient_password"},
|
||||
{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_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_DECRYPT), "CMS_decrypt"},
|
||||
{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_DIGESTALGORITHM_FIND_CTX), "cms_DigestAlgorithm_find_ctx"},
|
||||
{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_CONTENT), "CMS_get0_content"},
|
||||
{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_SIGNED), "CMS_GET0_SIGNED"},
|
||||
{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_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_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_PASSWORD), "CMS_RecipientInfo_set0_password"},
|
||||
{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_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_RECIPIENTINFO),"error setting recipientinfo"},
|
||||
{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_MD_BIO_INIT_ERROR) ,"md bio init error"},
|
||||
{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_KEK) ,"not kek"},
|
||||
{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_NO_CIPHER) ,"no cipher"},
|
||||
{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_SIGNATURE) ,"no matching signature"},
|
||||
{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_PUBLIC_KEY) ,"no public key"},
|
||||
{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_CONTENT_TYPE),"unsupported content type"},
|
||||
{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_RECPIENTINFO_TYPE),"unsupported recpientinfo type"},
|
||||
{ERR_REASON(CMS_R_UNSUPPORTED_TYPE) ,"unsupported type"},
|
||||
{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_WRAP_ERROR) ,"wrap error"},
|
||||
{0,NULL}
|
||||
|
@ -273,6 +273,9 @@ struct CMS_PasswordRecipientInfo_st
|
||||
X509_ALGOR *keyDerivationAlgorithm;
|
||||
X509_ALGOR *keyEncryptionAlgorithm;
|
||||
ASN1_OCTET_STRING *encryptedKey;
|
||||
/* Extra info: password to use */
|
||||
unsigned char *pass;
|
||||
size_t passlen;
|
||||
};
|
||||
|
||||
struct CMS_OtherRecipientInfo_st
|
||||
@ -411,6 +414,8 @@ DECLARE_ASN1_ITEM(CMS_SignerInfo)
|
||||
DECLARE_ASN1_ITEM(CMS_IssuerAndSerialNumber)
|
||||
DECLARE_ASN1_ITEM(CMS_Attributes_Sign)
|
||||
DECLARE_ASN1_ITEM(CMS_Attributes_Verify)
|
||||
DECLARE_ASN1_ITEM(CMS_RecipientInfo)
|
||||
DECLARE_ASN1_ITEM(CMS_PasswordRecipientInfo)
|
||||
DECLARE_ASN1_ALLOC_FUNCTIONS(CMS_IssuerAndSerialNumber)
|
||||
|
||||
#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);
|
||||
|
||||
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
|
||||
}
|
||||
|
453
crypto/cms/cms_pwri.c
Normal file
453
crypto/cms/cms_pwri.c
Normal file
@ -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,
|
||||
BIO *dcont, BIO *out,
|
||||
unsigned int flags)
|
||||
|
Loading…
Reference in New Issue
Block a user