Various tidies/fixes:
[openssl.git] / crypto / cms / cms_smime.c
index 7a2498d..c9be5a0 100644 (file)
@@ -447,8 +447,8 @@ CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
 
        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);
@@ -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;
+       else
+               goto err;
+
+       merr:
+       CMSerr(CMS_F_CMS_ENCRYPT, ERR_R_MALLOC_FAILURE);
+       err:
+       if (cms)
+               CMS_ContentInfo_free(cms);
        return NULL;
        }
        
@@ -471,8 +498,6 @@ int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert,
                                BIO *dcont, BIO *out,
                                unsigned int flags)
        {
-       STACK_OF(CMS_RecipientInfo) *ris;
-       CMS_RecipientInfo *ri;
        int i, r;
        BIO *cont;
        if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_enveloped)
@@ -482,28 +507,38 @@ int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert,
                }
        if (!dcont && !check_content(cms))
                return 0;
-       ris = CMS_get0_RecipientInfos(cms);
-       for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++)
+       if (pk)
                {
-               ri = sk_CMS_RecipientInfo_value(ris, i);
-               if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_TRANS)
-                       continue;
-               if (cert)
+               STACK_OF(CMS_RecipientInfo) *ris;
+               CMS_RecipientInfo *ri;
+               ris = CMS_get0_RecipientInfos(cms);
+               for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++)
                        {
-                       if (CMS_RecipientInfo_ktri_cert_cmp(ri, cert) == 0)
+                       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))
                                {
-                               if (CMS_RecipientInfo_decrypt(cms, ri, pk) <=0)
-                                       return 0;
-                               else
+                               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;
+               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)