else
tmpout = out;
- /* Read all content through chain to determine content digests */
+ /* Read all content through chain to process digest, decrypt etc */
for (;;)
{
i=BIO_read(in,buf,sizeof(buf));
if (i <= 0)
+ {
+ if (BIO_method_type(in) == BIO_TYPE_CIPHER)
+ {
+ if (!BIO_get_cipher_status(in))
+ goto err;
+ }
break;
+ }
+
if (tmpout)
BIO_write(tmpout, buf, i);
}
}
+static int check_content(CMS_ContentInfo *cms)
+ {
+ ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
+ if (!pos || !*pos)
+ {
+ CMSerr(CMS_F_CHECK_CONTENT, CMS_R_NO_CONTENT);
+ return 0;
+ }
+ return 1;
+ }
+
int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags)
{
BIO *cont;
return 0;
}
- if (!dcont)
- {
- ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
- if (!pos || !*pos)
- {
- CMSerr(CMS_F_CMS_DIGEST_VERIFY, CMS_R_NO_CONTENT);
- return 0;
- }
- }
+ if (!dcont && !check_content(cms))
+ return 0;
cont = CMS_dataInit(cms, dcont);
if (!cont)
return 0;
}
- if (!dcont)
- {
- ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
- if (!pos || !*pos)
- {
- CMSerr(CMS_F_CMS_ENCRYPTEDDATA_DECRYPT,
- CMS_R_NO_CONTENT);
- return 0;
- }
- }
+ if (!dcont && !check_content(cms))
+ return 0;
if (CMS_EncryptedData_set1_key(cms, NULL, key, keylen) <= 0)
return 0;
int i, scount = 0, ret = 0;
BIO *cmsbio = NULL, *tmpin = NULL;
- if (!dcont)
- {
- ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
- if (!pos || !*pos)
- {
- CMSerr(CMS_F_CMS_VERIFY, CMS_R_NO_CONTENT);
- return 0;
- }
- }
+ if (!dcont && !check_content(cms))
+ return 0;
/* Attempt to find all signer certificates */
if ((flags & (CMS_STREAM|CMS_PARTIAL)) || CMS_final(cms, data, flags))
return cms;
-
- return cms;
+ else
+ goto err;
merr:
CMSerr(CMS_F_CMS_SIGN, ERR_R_MALLOC_FAILURE);
return NULL;
}
-/* Placeholders 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;
+ else
+ goto err;
+
+ merr:
+ CMSerr(CMS_F_CMS_ENCRYPT, ERR_R_MALLOC_FAILURE);
+ err:
+ if (cms)
+ CMS_ContentInfo_free(cms);
return NULL;
}
-int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pkey, X509 *cert, BIO *data,
+int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert,
+ BIO *dcont, BIO *out,
unsigned int flags)
{
- return 0;
+ int i, r;
+ BIO *cont;
+ if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_enveloped)
+ {
+ CMSerr(CMS_F_CMS_DECRYPT, CMS_R_TYPE_NOT_ENVELOPED_DATA);
+ return 0;
+ }
+ if (!dcont && !check_content(cms))
+ return 0;
+ if (pk)
+ {
+ STACK_OF(CMS_RecipientInfo) *ris;
+ CMS_RecipientInfo *ri;
+ 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_TRANS)
+ continue;
+ /* If we have a cert try matching RecipientInfo
+ * otherwise try them all.
+ */
+ if (!cert ||
+ (CMS_RecipientInfo_ktri_cert_cmp(ri, cert) == 0))
+ {
+ CMS_RecipientInfo_set0_pkey(ri, pk);
+ r = CMS_RecipientInfo_decrypt(cms, ri);
+ CMS_RecipientInfo_set0_pkey(ri, NULL);
+ if (r > 0)
+ break;
+ if (cert)
+ return 0;
+ ERR_clear_error();
+ }
+ }
+
+ if (i == sk_CMS_RecipientInfo_num(ris))
+ {
+ CMSerr(CMS_F_CMS_DECRYPT, CMS_R_NO_MATCHING_RECIPIENT);
+ return 0;
+ }
+ }
+ cont = CMS_dataInit(cms, dcont);
+ if (!cont)
+ return 0;
+ r = cms_copy_content(out, cont, flags);
+ BIO_free_all(cont);
+ return r;
}
int CMS_final(CMS_ContentInfo *cms, BIO *data, int flags)
return 0;
}
- if (!dcont)
- {
- ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
- if (!pos || !*pos)
- {
- CMSerr(CMS_F_CMS_UNCOMPRESS, CMS_R_NO_CONTENT);
- return 0;
- }
- }
+ if (!dcont && !check_content(cms))
+ return 0;
cont = CMS_dataInit(cms, dcont);
if (!cont)