+ if (!PKCS7_content_new(p7, NID_pkcs7_data))
+ goto err;
+
+ if (pkey && !PKCS7_sign_add_signer(p7, signcert, pkey, NULL, flags))
+ {
+ PKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PKCS7_ADD_SIGNER_ERROR);
+ goto err;
+ }
+
+ if(!(flags & PKCS7_NOCERTS))
+ {
+ for(i = 0; i < sk_X509_num(certs); i++)
+ {
+ if (!PKCS7_add_certificate(p7, sk_X509_value(certs, i)))
+ goto err;
+ }
+ }
+
+ if (flags & (PKCS7_STREAM|PKCS7_PARTIAL))
+ return p7;
+
+ if (PKCS7_final(p7, data, flags))
+ return p7;
+
+ err:
+ PKCS7_free(p7);
+ return NULL;
+}
+
+int PKCS7_final(PKCS7 *p7, BIO *data, int flags)
+ {
+ BIO *p7bio;
+ int ret;
+ if (!(p7bio = PKCS7_dataInit(p7, NULL)))
+ {
+ PKCS7err(PKCS7_F_PKCS7_FINAL,ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+
+ SMIME_crlf_copy(data, p7bio, flags);
+
+ if(PKCS7_type_is_signed(p7) && (flags & PKCS7_DETACHED))
+ PKCS7_set_detached(p7, 1);
+
+ if (!PKCS7_dataFinal(p7,p7bio))
+ {
+ PKCS7err(PKCS7_F_PKCS7_FINAL,PKCS7_R_PKCS7_DATASIGN);
+ goto err;
+ }
+
+ ret = 1;
+
+ err:
+ BIO_free_all(p7bio);
+
+ return ret;