Preliminary support for enveloped data content type creation.
Fix signed data creation so versions are only corrected if structure is being created.
This commit is contained in:
parent
1e26a8baed
commit
761ffa729f
7 changed files with 221 additions and 31 deletions
|
@ -169,6 +169,9 @@ int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pkey, X509 *cert,
|
|||
|
||||
STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms);
|
||||
int CMS_RecipientInfo_type(CMS_RecipientInfo *ri);
|
||||
CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher);
|
||||
CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms,
|
||||
X509 *recip, unsigned int flags);
|
||||
int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert);
|
||||
int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri,
|
||||
EVP_PKEY **pk, X509 **recip,
|
||||
|
@ -290,6 +293,7 @@ void ERR_load_CMS_strings(void);
|
|||
#define CMS_F_CMS_DIGESTALGORITHM_INIT_BIO 111
|
||||
#define CMS_F_CMS_DIGESTEDDATA_DO_FINAL 112
|
||||
#define CMS_F_CMS_DIGEST_VERIFY 113
|
||||
#define CMS_F_CMS_ENCRYPT 154
|
||||
#define CMS_F_CMS_ENCRYPTEDCONTENT_DECRYPT_BIO 146
|
||||
#define CMS_F_CMS_ENCRYPTEDCONTENT_ENCRYPT_BIO 144
|
||||
#define CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO 148
|
||||
|
@ -299,6 +303,8 @@ void ERR_load_CMS_strings(void);
|
|||
#define CMS_F_CMS_ENCRYPTEDDATA_INIT_BIO 147
|
||||
#define CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY 141
|
||||
#define CMS_F_CMS_ENCRYPTED_DATA_DECRYPT 139
|
||||
#define CMS_F_CMS_ENVELOPEDDATA_CREATE 153
|
||||
#define CMS_F_CMS_ENVELOPEDDATA_INIT_BIO 156
|
||||
#define CMS_F_CMS_ENVELOPED_DATA_INIT 114
|
||||
#define CMS_F_CMS_FINAL 115
|
||||
#define CMS_F_CMS_GET0_CERTIFICATE_CHOICES 116
|
||||
|
@ -309,6 +315,7 @@ void ERR_load_CMS_strings(void);
|
|||
#define CMS_F_CMS_GET0_SIGNED 121
|
||||
#define CMS_F_CMS_RECIPIENTINFO_DECRYPT 150
|
||||
#define CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP 122
|
||||
#define CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT 155
|
||||
#define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS 123
|
||||
#define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID 124
|
||||
#define CMS_F_CMS_SET1_SIGNERIDENTIFIER 125
|
||||
|
@ -340,6 +347,7 @@ void ERR_load_CMS_strings(void);
|
|||
#define CMS_R_CTRL_FAILURE 108
|
||||
#define CMS_R_ERROR_GETTING_PUBLIC_KEY 109
|
||||
#define CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE 110
|
||||
#define CMS_R_ERROR_SETTING_RECIPIENTINFO 150
|
||||
#define CMS_R_INVALID_KEY_LENGTH 140
|
||||
#define CMS_R_MD_BIO_INIT_ERROR 111
|
||||
#define CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH 112
|
||||
|
@ -358,6 +366,7 @@ void ERR_load_CMS_strings(void);
|
|||
#define CMS_R_NO_PUBLIC_KEY 121
|
||||
#define CMS_R_NO_SIGNERS 122
|
||||
#define CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 123
|
||||
#define CMS_R_RECIPIENT_ERROR 149
|
||||
#define CMS_R_SIGNER_CERTIFICATE_NOT_FOUND 124
|
||||
#define CMS_R_SIGNFINAL_ERROR 125
|
||||
#define CMS_R_SMIME_TEXT_ERROR 126
|
||||
|
@ -373,6 +382,7 @@ void ERR_load_CMS_strings(void);
|
|||
#define CMS_R_UNKNOWN_ID 133
|
||||
#define CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM 134
|
||||
#define CMS_R_UNSUPPORTED_CONTENT_TYPE 135
|
||||
#define CMS_R_UNSUPPORTED_RECIPIENT_TYPE 151
|
||||
#define CMS_R_UNSUPPORTED_TYPE 136
|
||||
#define CMS_R_VERIFICATION_FAILURE 137
|
||||
|
||||
|
|
|
@ -92,7 +92,14 @@ BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec)
|
|||
BIO_get_cipher_ctx(b, &ctx);
|
||||
|
||||
if (enc)
|
||||
{
|
||||
ciph = ec->cipher;
|
||||
/* If not keeping key set cipher to NULL so subsequent calls
|
||||
* decrypt.
|
||||
*/
|
||||
if (ec->key)
|
||||
ec->cipher = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
ciph = EVP_get_cipherbyobj(calg->algorithm);
|
||||
|
@ -112,12 +119,10 @@ BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec)
|
|||
goto err;
|
||||
}
|
||||
|
||||
if (enc)
|
||||
calg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(ctx));
|
||||
|
||||
if (enc)
|
||||
{
|
||||
int ivlen;
|
||||
calg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(ctx));
|
||||
/* Generate a random IV if we need one */
|
||||
ivlen = EVP_CIPHER_CTX_iv_length(ctx);
|
||||
if (ivlen > 0)
|
||||
|
@ -128,11 +133,11 @@ BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec)
|
|||
}
|
||||
}
|
||||
else if (EVP_CIPHER_asn1_to_param(ctx, calg->parameter) <= 0)
|
||||
{
|
||||
CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
|
||||
{
|
||||
CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
|
||||
CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
|
||||
goto err;
|
||||
}
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
||||
if (enc && !ec->key)
|
||||
|
@ -200,7 +205,7 @@ BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec,
|
||||
int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec,
|
||||
const EVP_CIPHER *cipher,
|
||||
const unsigned char *key, size_t keylen)
|
||||
{
|
||||
|
@ -252,7 +257,7 @@ int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph,
|
|||
BIO *cms_EncryptedData_init_bio(CMS_ContentInfo *cms)
|
||||
{
|
||||
CMS_EncryptedData *enc = cms->d.encryptedData;
|
||||
if (enc->unprotectedAttrs)
|
||||
if (enc->encryptedContentInfo->cipher && enc->unprotectedAttrs)
|
||||
enc->version = 2;
|
||||
return cms_EncryptedContent_init_bio(enc->encryptedContentInfo);
|
||||
}
|
||||
|
|
|
@ -104,7 +104,7 @@ static CMS_EnvelopedData *cms_enveloped_data_init(CMS_ContentInfo *cms)
|
|||
STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms)
|
||||
{
|
||||
CMS_EnvelopedData *env;
|
||||
env = cms_enveloped_data_init(cms);
|
||||
env = cms_get0_enveloped(cms);
|
||||
if (!env)
|
||||
return NULL;
|
||||
return env->recipientInfos;
|
||||
|
@ -115,10 +115,30 @@ int CMS_RecipientInfo_type(CMS_RecipientInfo *ri)
|
|||
return ri->type;
|
||||
}
|
||||
|
||||
CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher)
|
||||
{
|
||||
CMS_ContentInfo *cms;
|
||||
CMS_EnvelopedData *env;
|
||||
cms = CMS_ContentInfo_new();
|
||||
if (!cms)
|
||||
goto merr;
|
||||
env = cms_enveloped_data_init(cms);
|
||||
if (!env)
|
||||
goto merr;
|
||||
if (!cms_EncryptedContent_init(env->encryptedContentInfo,
|
||||
cipher, NULL, 0))
|
||||
goto merr;
|
||||
return cms;
|
||||
merr:
|
||||
if (cms)
|
||||
CMS_ContentInfo_free(cms);
|
||||
CMSerr(CMS_F_CMS_ENVELOPEDDATA_CREATE, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Add a recipient certificate. For now only handle key transport.
|
||||
* If we ever handle key agreement will need updating.
|
||||
*/
|
||||
#if 0 /* currently unused/undeclared */
|
||||
CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms,
|
||||
X509 *recip, unsigned int flags)
|
||||
{
|
||||
|
@ -127,17 +147,16 @@ CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms,
|
|||
CMS_EnvelopedData *env;
|
||||
EVP_PKEY *pk = NULL;
|
||||
int i, type;
|
||||
/* Init enveloped data */
|
||||
env = cms_enveloped_data_init(cms);
|
||||
env = cms_get0_enveloped(cms);
|
||||
if (!env)
|
||||
goto err;
|
||||
|
||||
/* Initialized recipient info */
|
||||
/* Initialize recipient info */
|
||||
ri = M_ASN1_new_of(CMS_RecipientInfo);
|
||||
if (!ri)
|
||||
goto merr;
|
||||
|
||||
/* Initialize and add key transrport recipient info */
|
||||
/* Initialize and add key transport recipient info */
|
||||
|
||||
ri->d.ktri = M_ASN1_new_of(CMS_KeyTransRecipientInfo);
|
||||
if (!ri->d.ktri)
|
||||
|
@ -155,7 +174,6 @@ CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms,
|
|||
goto err;
|
||||
}
|
||||
CRYPTO_add(&recip->references, 1, CRYPTO_LOCK_X509);
|
||||
CRYPTO_add(&pk->references, 1, CRYPTO_LOCK_EVP_PKEY);
|
||||
ktri->pkey = pk;
|
||||
ktri->recip = recip;
|
||||
|
||||
|
@ -208,7 +226,6 @@ CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms,
|
|||
return NULL;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri,
|
||||
EVP_PKEY **pk, X509 **recip,
|
||||
|
@ -262,6 +279,71 @@ int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert)
|
|||
return cms_SignerIdentifier_cert_cmp(ri->d.ktri->rid, cert);
|
||||
}
|
||||
|
||||
/* Encrypt content key in key transport recipient info */
|
||||
|
||||
static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms,
|
||||
CMS_RecipientInfo *ri)
|
||||
{
|
||||
CMS_KeyTransRecipientInfo *ktri;
|
||||
CMS_EncryptedContentInfo *ec;
|
||||
EVP_PKEY_CTX *pctx = NULL;
|
||||
unsigned char *ek = NULL;
|
||||
size_t eklen;
|
||||
|
||||
int ret = 0;
|
||||
|
||||
if (ri->type != CMS_RECIPINFO_TRANS)
|
||||
{
|
||||
CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT,
|
||||
CMS_R_NOT_KEY_TRANSPORT);
|
||||
return 0;
|
||||
}
|
||||
ktri = ri->d.ktri;
|
||||
ec = cms->d.envelopedData->encryptedContentInfo;
|
||||
|
||||
pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL);
|
||||
if (!pctx)
|
||||
return 0;
|
||||
|
||||
if (EVP_PKEY_encrypt_init(pctx) <= 0)
|
||||
goto err;
|
||||
|
||||
if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT,
|
||||
EVP_PKEY_CTRL_CMS_ENCRYPT, 0, ri) <= 0)
|
||||
{
|
||||
CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, CMS_R_CTRL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (EVP_PKEY_encrypt(pctx, NULL, &eklen, ec->key, ec->keylen) <= 0)
|
||||
goto err;
|
||||
|
||||
ek = OPENSSL_malloc(eklen);
|
||||
|
||||
if (ek == NULL)
|
||||
{
|
||||
CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT,
|
||||
ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (EVP_PKEY_encrypt(pctx, ek, &eklen, ec->key, ec->keylen) <= 0)
|
||||
goto err;
|
||||
|
||||
ASN1_STRING_set0(ktri->encryptedKey, ek, eklen);
|
||||
ek = NULL;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
if (pctx)
|
||||
EVP_PKEY_CTX_free(pctx);
|
||||
if (ek)
|
||||
OPENSSL_free(ek);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
|
||||
EVP_PKEY *pkey)
|
||||
{
|
||||
|
@ -332,6 +414,57 @@ int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
|
|||
BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms)
|
||||
{
|
||||
CMS_EncryptedContentInfo *ec;
|
||||
STACK_OF(CMS_RecipientInfo) *rinfos;
|
||||
CMS_RecipientInfo *ri;
|
||||
int i, r, ok = 0;
|
||||
BIO *ret;
|
||||
|
||||
/* Get BIO first to set up key */
|
||||
|
||||
ec = cms->d.envelopedData->encryptedContentInfo;
|
||||
return cms_EncryptedContent_init_bio(ec);
|
||||
ret = cms_EncryptedContent_init_bio(ec);
|
||||
|
||||
/* If error or no cipher end of processing */
|
||||
|
||||
if (!ret || !ec->cipher)
|
||||
return ret;
|
||||
|
||||
|
||||
rinfos = cms->d.envelopedData->recipientInfos;
|
||||
|
||||
for (i = 0; i < sk_CMS_RecipientInfo_num(rinfos); i++)
|
||||
{
|
||||
ri = sk_CMS_RecipientInfo_value(rinfos, i);
|
||||
if (ri->type == CMS_RECIPINFO_TRANS)
|
||||
r = cms_RecipientInfo_ktri_encrypt(cms, ri);
|
||||
else
|
||||
{
|
||||
CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO,
|
||||
CMS_R_UNSUPPORTED_RECIPIENT_TYPE);
|
||||
goto err;
|
||||
}
|
||||
if (r <= 0)
|
||||
{
|
||||
CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO,
|
||||
CMS_R_ERROR_SETTING_RECIPIENTINFO);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
ok = 1;
|
||||
|
||||
err:
|
||||
ec->cipher = NULL;
|
||||
if (ec->key)
|
||||
{
|
||||
OPENSSL_cleanse(ec->key, ec->keylen);
|
||||
OPENSSL_free(ec->key);
|
||||
ec->key = NULL;
|
||||
ec->keylen = 0;
|
||||
}
|
||||
if (ok)
|
||||
return ret;
|
||||
BIO_free(ret);
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@
|
|||
static ERR_STRING_DATA CMS_str_functs[]=
|
||||
{
|
||||
{ERR_FUNC(CMS_F_CHECK_CONTENT), "CHECK_CONTENT"},
|
||||
{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_SIGNINGTIME), "CMS_ADD1_SIGNINGTIME"},
|
||||
{ERR_FUNC(CMS_F_CMS_BIO_TO_ENCRYPTEDCONTENT), "CMS_BIO_TO_ENCRYPTEDCONTENT"},
|
||||
|
@ -91,6 +91,7 @@ static ERR_STRING_DATA CMS_str_functs[]=
|
|||
{ERR_FUNC(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO), "CMS_DIGESTALGORITHM_INIT_BIO"},
|
||||
{ERR_FUNC(CMS_F_CMS_DIGESTEDDATA_DO_FINAL), "CMS_DIGESTEDDATA_DO_FINAL"},
|
||||
{ERR_FUNC(CMS_F_CMS_DIGEST_VERIFY), "CMS_digest_verify"},
|
||||
{ERR_FUNC(CMS_F_CMS_ENCRYPT), "CMS_encrypt"},
|
||||
{ERR_FUNC(CMS_F_CMS_ENCRYPTEDCONTENT_DECRYPT_BIO), "CMS_ENCRYPTEDCONTENT_DECRYPT_BIO"},
|
||||
{ERR_FUNC(CMS_F_CMS_ENCRYPTEDCONTENT_ENCRYPT_BIO), "CMS_ENCRYPTEDCONTENT_ENCRYPT_BIO"},
|
||||
{ERR_FUNC(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO), "CMS_ENCRYPTEDCONTENT_INIT_BIO"},
|
||||
|
@ -100,6 +101,8 @@ static ERR_STRING_DATA CMS_str_functs[]=
|
|||
{ERR_FUNC(CMS_F_CMS_ENCRYPTEDDATA_INIT_BIO), "CMS_ENCRYPTEDDATA_INIT_BIO"},
|
||||
{ERR_FUNC(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY), "CMS_EncryptedData_set1_key"},
|
||||
{ERR_FUNC(CMS_F_CMS_ENCRYPTED_DATA_DECRYPT), "CMS_ENCRYPTED_DATA_DECRYPT"},
|
||||
{ERR_FUNC(CMS_F_CMS_ENVELOPEDDATA_CREATE), "CMS_EnvelopedData_create"},
|
||||
{ERR_FUNC(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO), "CMS_ENVELOPEDDATA_INIT_BIO"},
|
||||
{ERR_FUNC(CMS_F_CMS_ENVELOPED_DATA_INIT), "CMS_ENVELOPED_DATA_INIT"},
|
||||
{ERR_FUNC(CMS_F_CMS_FINAL), "CMS_final"},
|
||||
{ERR_FUNC(CMS_F_CMS_GET0_CERTIFICATE_CHOICES), "CMS_GET0_CERTIFICATE_CHOICES"},
|
||||
|
@ -110,6 +113,7 @@ static ERR_STRING_DATA CMS_str_functs[]=
|
|||
{ERR_FUNC(CMS_F_CMS_GET0_SIGNED), "CMS_GET0_SIGNED"},
|
||||
{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_DECRYPT), "CMS_RecipientInfo_decrypt"},
|
||||
{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP), "CMS_RecipientInfo_ktri_cert_cmp"},
|
||||
{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_SET1_SIGNERIDENTIFIER), "CMS_SET1_SIGNERIDENTIFIER"},
|
||||
|
@ -144,6 +148,7 @@ static ERR_STRING_DATA CMS_str_reasons[]=
|
|||
{ERR_REASON(CMS_R_CTRL_FAILURE) ,"ctrl failure"},
|
||||
{ERR_REASON(CMS_R_ERROR_GETTING_PUBLIC_KEY),"error getting public key"},
|
||||
{ERR_REASON(CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE),"error reading messagedigest attribute"},
|
||||
{ERR_REASON(CMS_R_ERROR_SETTING_RECIPIENTINFO),"error setting recipientinfo"},
|
||||
{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"},
|
||||
|
@ -162,6 +167,7 @@ static ERR_STRING_DATA CMS_str_reasons[]=
|
|||
{ERR_REASON(CMS_R_NO_PUBLIC_KEY) ,"no public key"},
|
||||
{ERR_REASON(CMS_R_NO_SIGNERS) ,"no signers"},
|
||||
{ERR_REASON(CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE),"private key does not match certificate"},
|
||||
{ERR_REASON(CMS_R_RECIPIENT_ERROR) ,"recipient error"},
|
||||
{ERR_REASON(CMS_R_SIGNER_CERTIFICATE_NOT_FOUND),"signer certificate not found"},
|
||||
{ERR_REASON(CMS_R_SIGNFINAL_ERROR) ,"signfinal error"},
|
||||
{ERR_REASON(CMS_R_SMIME_TEXT_ERROR) ,"smime text error"},
|
||||
|
@ -177,6 +183,7 @@ static ERR_STRING_DATA CMS_str_reasons[]=
|
|||
{ERR_REASON(CMS_R_UNKNOWN_ID) ,"unknown id"},
|
||||
{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_RECIPIENT_TYPE),"unsupported recipient type"},
|
||||
{ERR_REASON(CMS_R_UNSUPPORTED_TYPE) ,"unsupported type"},
|
||||
{ERR_REASON(CMS_R_VERIFICATION_FAILURE) ,"verification failure"},
|
||||
{0,NULL}
|
||||
|
|
|
@ -123,6 +123,8 @@ struct CMS_EncapsulatedContentInfo_st
|
|||
{
|
||||
ASN1_OBJECT *eContentType;
|
||||
ASN1_OCTET_STRING *eContent;
|
||||
/* Set to 1 if incomplete structure only part set up */
|
||||
int partial;
|
||||
};
|
||||
|
||||
struct CMS_SignerInfo_st
|
||||
|
@ -411,6 +413,9 @@ int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain,
|
|||
|
||||
BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec);
|
||||
BIO *cms_EncryptedData_init_bio(CMS_ContentInfo *cms);
|
||||
int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec,
|
||||
const EVP_CIPHER *cipher,
|
||||
const unsigned char *key, size_t keylen);
|
||||
|
||||
BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms);
|
||||
|
||||
|
|
|
@ -87,6 +87,7 @@ static CMS_SignedData *cms_signed_data_init(CMS_ContentInfo *cms)
|
|||
cms->d.signedData->version = 1;
|
||||
cms->d.signedData->encapContentInfo->eContentType =
|
||||
OBJ_nid2obj(NID_pkcs7_data);
|
||||
cms->d.signedData->encapContentInfo->partial = 1;
|
||||
ASN1_OBJECT_free(cms->contentType);
|
||||
cms->contentType = OBJ_nid2obj(NID_pkcs7_signed);
|
||||
return cms->d.signedData;
|
||||
|
@ -679,6 +680,7 @@ int cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain)
|
|||
if (!cms_SignerInfo_content_sign(si, chain))
|
||||
return 0;
|
||||
}
|
||||
cms->d.signedData->encapContentInfo->partial = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -800,7 +802,8 @@ BIO *cms_SignedData_init_bio(CMS_ContentInfo *cms)
|
|||
sd = cms_get0_signed(cms);
|
||||
if (!sd)
|
||||
return NULL;
|
||||
cms_sd_set_version(sd);
|
||||
if (cms->d.signedData->encapContentInfo->partial)
|
||||
cms_sd_set_version(sd);
|
||||
for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++)
|
||||
{
|
||||
X509_ALGOR *digestAlgorithm;
|
||||
|
|
|
@ -459,11 +459,38 @@ CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Placeholder for now... */
|
||||
|
||||
CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *in,
|
||||
CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *data,
|
||||
const EVP_CIPHER *cipher, unsigned int flags)
|
||||
{
|
||||
CMS_ContentInfo *cms;
|
||||
int i;
|
||||
X509 *recip;
|
||||
cms = CMS_EnvelopedData_create(cipher);
|
||||
if (!cms)
|
||||
goto merr;
|
||||
for (i = 0; i < sk_X509_num(certs); i++)
|
||||
{
|
||||
recip = sk_X509_value(certs, i);
|
||||
if (!CMS_add1_recipient_cert(cms, recip, flags))
|
||||
{
|
||||
CMSerr(CMS_F_CMS_ENCRYPT, CMS_R_RECIPIENT_ERROR);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if(!(flags & CMS_DETACHED))
|
||||
CMS_set_detached(cms, 0);
|
||||
|
||||
if ((flags & (CMS_STREAM|CMS_PARTIAL)) || CMS_final(cms, data, flags))
|
||||
return cms;
|
||||
|
||||
return cms;
|
||||
|
||||
merr:
|
||||
CMSerr(CMS_F_CMS_ENCRYPT, ERR_R_MALLOC_FAILURE);
|
||||
err:
|
||||
if (cms)
|
||||
CMS_ContentInfo_free(cms);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -488,15 +515,15 @@ int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert,
|
|||
ri = sk_CMS_RecipientInfo_value(ris, i);
|
||||
if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_TRANS)
|
||||
continue;
|
||||
if (cert)
|
||||
/* If we have a cert try matching RecipientInfo otherwise
|
||||
* try them all.
|
||||
*/
|
||||
if (!cert || (CMS_RecipientInfo_ktri_cert_cmp(ri, cert) == 0))
|
||||
{
|
||||
if (CMS_RecipientInfo_ktri_cert_cmp(ri, cert) == 0)
|
||||
{
|
||||
if (CMS_RecipientInfo_decrypt(cms, ri, pk) <=0)
|
||||
return 0;
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (CMS_RecipientInfo_decrypt(cms, ri, pk) > 0)
|
||||
break;
|
||||
else if (cert)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue