- }
-
- if(operation == SMIME_VERIFY) {
- if(!(store = setup_verify(bio_err, CAfile, CApath))) goto end;
- X509_STORE_set_flags(store, store_flags);
- }
-
-
- ret = 3;
-
- if(operation == SMIME_ENCRYPT) {
- p7 = PKCS7_encrypt(encerts, in, cipher, flags);
- } else if(operation == SMIME_SIGN) {
- /* If detached data and SMIME output enable partial
- * signing.
- */
- if ((flags & PKCS7_DETACHED) && (outformat == FORMAT_SMIME))
- flags |= PKCS7_STREAM;
- p7 = PKCS7_sign(signer, key, other, in, flags);
- /* Don't need to rewind for partial signing */
- if (!(flags & PKCS7_STREAM) && (BIO_reset(in) != 0)) {
- BIO_printf(bio_err, "Can't rewind input file\n");
- goto end;
- }
- } else {
- if(informat == FORMAT_SMIME)
- p7 = SMIME_read_PKCS7(in, &indata);
- else if(informat == FORMAT_PEM)
- p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL);
- else if(informat == FORMAT_ASN1)
- p7 = d2i_PKCS7_bio(in, NULL);
- else {
- BIO_printf(bio_err, "Bad input format for PKCS#7 file\n");
- goto end;
- }
-
- if(!p7) {
- BIO_printf(bio_err, "Error reading S/MIME message\n");
- goto end;
- }
- if(contfile) {
- BIO_free(indata);
- if(!(indata = BIO_new_file(contfile, "rb"))) {
- BIO_printf(bio_err, "Can't read content file %s\n", contfile);
- goto end;
- }
- }
- }
-
- if(!p7) {
- BIO_printf(bio_err, "Error creating PKCS#7 structure\n");
- goto end;
- }
-
- ret = 4;
- if(operation == SMIME_DECRYPT) {
- if(!PKCS7_decrypt(p7, key, recip, out, flags)) {
- BIO_printf(bio_err, "Error decrypting PKCS#7 structure\n");
- goto end;
- }
- } else if(operation == SMIME_VERIFY) {
- STACK_OF(X509) *signers;
- if(PKCS7_verify(p7, other, store, indata, out, flags)) {
- BIO_printf(bio_err, "Verification successful\n");
- } else {
- BIO_printf(bio_err, "Verification failure\n");
- goto end;
- }
- signers = PKCS7_get0_signers(p7, other, flags);
- if(!save_certs(signerfile, signers)) {
- BIO_printf(bio_err, "Error writing signers to %s\n",
- signerfile);
- ret = 5;
- goto end;
- }
- sk_X509_free(signers);
- } else if(operation == SMIME_PK7OUT) {
- PEM_write_bio_PKCS7(out, p7);
- } else {
- if(to) BIO_printf(out, "To: %s\n", to);
- if(from) BIO_printf(out, "From: %s\n", from);
- if(subject) BIO_printf(out, "Subject: %s\n", subject);
- if(outformat == FORMAT_SMIME)
- SMIME_write_PKCS7(out, p7, in, flags);
- else if(outformat == FORMAT_PEM)
- PEM_write_bio_PKCS7(out,p7);
- else if(outformat == FORMAT_ASN1)
- i2d_PKCS7_bio(out,p7);
- else {
- BIO_printf(bio_err, "Bad output format for PKCS#7 file\n");
- goto end;
- }
- }
- ret = 0;
-end:
- if (need_rand)
- app_RAND_write_file(NULL, bio_err);
- if(ret) ERR_print_errors(bio_err);
- sk_X509_pop_free(encerts, X509_free);
- sk_X509_pop_free(other, X509_free);
- X509_STORE_free(store);
- X509_free(cert);
- X509_free(recip);
- X509_free(signer);
- EVP_PKEY_free(key);
- PKCS7_free(p7);
- BIO_free(in);
- BIO_free(indata);
- BIO_free_all(out);
- if(passin) OPENSSL_free(passin);
- return (ret);
+ }
+
+ if (operation == SMIME_VERIFY) {
+ if (!(store = setup_verify(bio_err, CAfile, CApath)))
+ goto end;
+ X509_STORE_set_verify_cb(store, smime_cb);
+ if (vpm)
+ X509_STORE_set1_param(store, vpm);
+ }
+
+ ret = 3;
+
+ if (operation == SMIME_ENCRYPT) {
+ if (indef)
+ flags |= PKCS7_STREAM;
+ p7 = PKCS7_encrypt(encerts, in, cipher, flags);
+ } else if (operation & SMIME_SIGNERS) {
+ int i;
+ /*
+ * If detached data content we only enable streaming if S/MIME output
+ * format.
+ */
+ if (operation == SMIME_SIGN) {
+ if (flags & PKCS7_DETACHED) {
+ if (outformat == FORMAT_SMIME)
+ flags |= PKCS7_STREAM;
+ } else if (indef)
+ flags |= PKCS7_STREAM;
+ flags |= PKCS7_PARTIAL;
+ p7 = PKCS7_sign(NULL, NULL, other, in, flags);
+ if (!p7)
+ goto end;
+ if (flags & PKCS7_NOCERTS) {
+ for (i = 0; i < sk_X509_num(other); i++) {
+ X509 *x = sk_X509_value(other, i);
+ PKCS7_add_certificate(p7, x);
+ }
+ }
+ } else
+ flags |= PKCS7_REUSE_DIGEST;
+ for (i = 0; i < sk_OPENSSL_STRING_num(sksigners); i++) {
+ signerfile = sk_OPENSSL_STRING_value(sksigners, i);
+ keyfile = sk_OPENSSL_STRING_value(skkeys, i);
+ signer = load_cert(bio_err, signerfile, FORMAT_PEM, NULL,
+ e, "signer certificate");
+ if (!signer)
+ goto end;
+ key = load_key(bio_err, keyfile, keyform, 0, passin, e,
+ "signing key file");
+ if (!key)
+ goto end;
+ if (!PKCS7_sign_add_signer(p7, signer, key, sign_md, flags))
+ goto end;
+ X509_free(signer);
+ signer = NULL;
+ EVP_PKEY_free(key);
+ key = NULL;
+ }
+ /* If not streaming or resigning finalize structure */
+ if ((operation == SMIME_SIGN) && !(flags & PKCS7_STREAM)) {
+ if (!PKCS7_final(p7, in, flags))
+ goto end;
+ }
+ }
+
+ if (!p7) {
+ BIO_printf(bio_err, "Error creating PKCS#7 structure\n");
+ goto end;
+ }
+
+ ret = 4;
+ if (operation == SMIME_DECRYPT) {
+ if (!PKCS7_decrypt(p7, key, recip, out, flags)) {
+ BIO_printf(bio_err, "Error decrypting PKCS#7 structure\n");
+ goto end;
+ }
+ } else if (operation == SMIME_VERIFY) {
+ STACK_OF(X509) *signers;
+ if (PKCS7_verify(p7, other, store, indata, out, flags))
+ BIO_printf(bio_err, "Verification successful\n");
+ else {
+ BIO_printf(bio_err, "Verification failure\n");
+ goto end;
+ }
+ signers = PKCS7_get0_signers(p7, other, flags);
+ if (!save_certs(signerfile, signers)) {
+ BIO_printf(bio_err, "Error writing signers to %s\n", signerfile);
+ ret = 5;
+ goto end;
+ }
+ sk_X509_free(signers);
+ } else if (operation == SMIME_PK7OUT)
+ PEM_write_bio_PKCS7(out, p7);
+ else {
+ if (to)
+ BIO_printf(out, "To: %s\n", to);
+ if (from)
+ BIO_printf(out, "From: %s\n", from);
+ if (subject)
+ BIO_printf(out, "Subject: %s\n", subject);
+ if (outformat == FORMAT_SMIME) {
+ if (operation == SMIME_RESIGN)
+ SMIME_write_PKCS7(out, p7, indata, flags);
+ else
+ SMIME_write_PKCS7(out, p7, in, flags);
+ } else if (outformat == FORMAT_PEM)
+ PEM_write_bio_PKCS7_stream(out, p7, in, flags);
+ else if (outformat == FORMAT_ASN1)
+ i2d_PKCS7_bio_stream(out, p7, in, flags);
+ else {
+ BIO_printf(bio_err, "Bad output format for PKCS#7 file\n");
+ goto end;
+ }
+ }
+ ret = 0;
+ end:
+ if (need_rand)
+ app_RAND_write_file(NULL, bio_err);
+ if (ret)
+ ERR_print_errors(bio_err);
+ sk_X509_pop_free(encerts, X509_free);
+ sk_X509_pop_free(other, X509_free);
+ if (vpm)
+ X509_VERIFY_PARAM_free(vpm);
+ if (sksigners)
+ sk_OPENSSL_STRING_free(sksigners);
+ if (skkeys)
+ sk_OPENSSL_STRING_free(skkeys);
+ X509_STORE_free(store);
+ X509_free(cert);
+ X509_free(recip);
+ X509_free(signer);
+ EVP_PKEY_free(key);
+ PKCS7_free(p7);
+ BIO_free(in);
+ BIO_free(indata);
+ BIO_free_all(out);
+ if (passin)
+ OPENSSL_free(passin);
+ return (ret);