1f579bf8eSKris Kennaway /* smime.c */ 26f9291ceSJung-uk Kim /* 36f9291ceSJung-uk Kim * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 43b4e3dcbSSimon L. B. Nielsen * project. 5f579bf8eSKris Kennaway */ 6f579bf8eSKris Kennaway /* ==================================================================== 73b4e3dcbSSimon L. B. Nielsen * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved. 8f579bf8eSKris Kennaway * 9f579bf8eSKris Kennaway * Redistribution and use in source and binary forms, with or without 10f579bf8eSKris Kennaway * modification, are permitted provided that the following conditions 11f579bf8eSKris Kennaway * are met: 12f579bf8eSKris Kennaway * 13f579bf8eSKris Kennaway * 1. Redistributions of source code must retain the above copyright 14f579bf8eSKris Kennaway * notice, this list of conditions and the following disclaimer. 15f579bf8eSKris Kennaway * 16f579bf8eSKris Kennaway * 2. Redistributions in binary form must reproduce the above copyright 17f579bf8eSKris Kennaway * notice, this list of conditions and the following disclaimer in 18f579bf8eSKris Kennaway * the documentation and/or other materials provided with the 19f579bf8eSKris Kennaway * distribution. 20f579bf8eSKris Kennaway * 21f579bf8eSKris Kennaway * 3. All advertising materials mentioning features or use of this 22f579bf8eSKris Kennaway * software must display the following acknowledgment: 23f579bf8eSKris Kennaway * "This product includes software developed by the OpenSSL Project 24f579bf8eSKris Kennaway * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 25f579bf8eSKris Kennaway * 26f579bf8eSKris Kennaway * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 27f579bf8eSKris Kennaway * endorse or promote products derived from this software without 28f579bf8eSKris Kennaway * prior written permission. For written permission, please contact 29f579bf8eSKris Kennaway * licensing@OpenSSL.org. 30f579bf8eSKris Kennaway * 31f579bf8eSKris Kennaway * 5. Products derived from this software may not be called "OpenSSL" 32f579bf8eSKris Kennaway * nor may "OpenSSL" appear in their names without prior written 33f579bf8eSKris Kennaway * permission of the OpenSSL Project. 34f579bf8eSKris Kennaway * 35f579bf8eSKris Kennaway * 6. Redistributions of any form whatsoever must retain the following 36f579bf8eSKris Kennaway * acknowledgment: 37f579bf8eSKris Kennaway * "This product includes software developed by the OpenSSL Project 38f579bf8eSKris Kennaway * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 39f579bf8eSKris Kennaway * 40f579bf8eSKris Kennaway * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 41f579bf8eSKris Kennaway * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42f579bf8eSKris Kennaway * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 43f579bf8eSKris Kennaway * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 44f579bf8eSKris Kennaway * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45f579bf8eSKris Kennaway * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 46f579bf8eSKris Kennaway * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 47f579bf8eSKris Kennaway * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48f579bf8eSKris Kennaway * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 49f579bf8eSKris Kennaway * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50f579bf8eSKris Kennaway * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 51f579bf8eSKris Kennaway * OF THE POSSIBILITY OF SUCH DAMAGE. 52f579bf8eSKris Kennaway * ==================================================================== 53f579bf8eSKris Kennaway * 54f579bf8eSKris Kennaway * This product includes cryptographic software written by Eric Young 55f579bf8eSKris Kennaway * (eay@cryptsoft.com). This product includes software written by Tim 56f579bf8eSKris Kennaway * Hudson (tjh@cryptsoft.com). 57f579bf8eSKris Kennaway * 58f579bf8eSKris Kennaway */ 59f579bf8eSKris Kennaway 60f579bf8eSKris Kennaway /* S/MIME utility function */ 61f579bf8eSKris Kennaway 62f579bf8eSKris Kennaway #include <stdio.h> 63f579bf8eSKris Kennaway #include <string.h> 64f579bf8eSKris Kennaway #include "apps.h" 65f579bf8eSKris Kennaway #include <openssl/crypto.h> 66f579bf8eSKris Kennaway #include <openssl/pem.h> 67f579bf8eSKris Kennaway #include <openssl/err.h> 683b4e3dcbSSimon L. B. Nielsen #include <openssl/x509_vfy.h> 693b4e3dcbSSimon L. B. Nielsen #include <openssl/x509v3.h> 70f579bf8eSKris Kennaway 71f579bf8eSKris Kennaway #undef PROG 72f579bf8eSKris Kennaway #define PROG smime_main 73f579bf8eSKris Kennaway static int save_certs(char *signerfile, STACK_OF(X509) *signers); 743b4e3dcbSSimon L. B. Nielsen static int smime_cb(int ok, X509_STORE_CTX *ctx); 75f579bf8eSKris Kennaway 76f579bf8eSKris Kennaway #define SMIME_OP 0x10 771f13597dSJung-uk Kim #define SMIME_IP 0x20 781f13597dSJung-uk Kim #define SMIME_SIGNERS 0x40 79f579bf8eSKris Kennaway #define SMIME_ENCRYPT (1 | SMIME_OP) 801f13597dSJung-uk Kim #define SMIME_DECRYPT (2 | SMIME_IP) 811f13597dSJung-uk Kim #define SMIME_SIGN (3 | SMIME_OP | SMIME_SIGNERS) 821f13597dSJung-uk Kim #define SMIME_VERIFY (4 | SMIME_IP) 831f13597dSJung-uk Kim #define SMIME_PK7OUT (5 | SMIME_IP | SMIME_OP) 841f13597dSJung-uk Kim #define SMIME_RESIGN (6 | SMIME_IP | SMIME_OP | SMIME_SIGNERS) 85f579bf8eSKris Kennaway 86f579bf8eSKris Kennaway int MAIN(int, char **); 87f579bf8eSKris Kennaway 88f579bf8eSKris Kennaway int MAIN(int argc, char **argv) 89f579bf8eSKris Kennaway { 905c87c606SMark Murray ENGINE *e = NULL; 91f579bf8eSKris Kennaway int operation = 0; 92f579bf8eSKris Kennaway int ret = 0; 93f579bf8eSKris Kennaway char **args; 943b4e3dcbSSimon L. B. Nielsen const char *inmode = "r", *outmode = "w"; 95f579bf8eSKris Kennaway char *infile = NULL, *outfile = NULL; 96f579bf8eSKris Kennaway char *signerfile = NULL, *recipfile = NULL; 971f13597dSJung-uk Kim STACK_OF(OPENSSL_STRING) *sksigners = NULL, *skkeys = NULL; 98ddd58736SKris Kennaway char *certfile = NULL, *keyfile = NULL, *contfile = NULL; 995c87c606SMark Murray const EVP_CIPHER *cipher = NULL; 100f579bf8eSKris Kennaway PKCS7 *p7 = NULL; 101f579bf8eSKris Kennaway X509_STORE *store = NULL; 102f579bf8eSKris Kennaway X509 *cert = NULL, *recip = NULL, *signer = NULL; 103f579bf8eSKris Kennaway EVP_PKEY *key = NULL; 104f579bf8eSKris Kennaway STACK_OF(X509) *encerts = NULL, *other = NULL; 105f579bf8eSKris Kennaway BIO *in = NULL, *out = NULL, *indata = NULL; 106f579bf8eSKris Kennaway int badarg = 0; 1073b4e3dcbSSimon L. B. Nielsen int flags = PKCS7_DETACHED; 108f579bf8eSKris Kennaway char *to = NULL, *from = NULL, *subject = NULL; 109f579bf8eSKris Kennaway char *CAfile = NULL, *CApath = NULL; 110f579bf8eSKris Kennaway char *passargin = NULL, *passin = NULL; 111f579bf8eSKris Kennaway char *inrand = NULL; 112f579bf8eSKris Kennaway int need_rand = 0; 1131f13597dSJung-uk Kim int indef = 0; 1141f13597dSJung-uk Kim const EVP_MD *sign_md = NULL; 115ddd58736SKris Kennaway int informat = FORMAT_SMIME, outformat = FORMAT_SMIME; 1165c87c606SMark Murray int keyform = FORMAT_PEM; 1175c87c606SMark Murray char *engine = NULL; 118f579bf8eSKris Kennaway 1193b4e3dcbSSimon L. B. Nielsen X509_VERIFY_PARAM *vpm = NULL; 1203b4e3dcbSSimon L. B. Nielsen 1215c87c606SMark Murray args = argv + 1; 122f579bf8eSKris Kennaway ret = 1; 123f579bf8eSKris Kennaway 1245c87c606SMark Murray apps_startup(); 1255c87c606SMark Murray 1266f9291ceSJung-uk Kim if (bio_err == NULL) { 1275c87c606SMark Murray if ((bio_err = BIO_new(BIO_s_file())) != NULL) 1285c87c606SMark Murray BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); 1293b4e3dcbSSimon L. B. Nielsen } 1305c87c606SMark Murray 1315c87c606SMark Murray if (!load_config(bio_err, NULL)) 1325c87c606SMark Murray goto end; 1335c87c606SMark Murray 1346f9291ceSJung-uk Kim while (!badarg && *args && *args[0] == '-') { 1353b4e3dcbSSimon L. B. Nielsen if (!strcmp(*args, "-encrypt")) 1363b4e3dcbSSimon L. B. Nielsen operation = SMIME_ENCRYPT; 1373b4e3dcbSSimon L. B. Nielsen else if (!strcmp(*args, "-decrypt")) 1383b4e3dcbSSimon L. B. Nielsen operation = SMIME_DECRYPT; 1393b4e3dcbSSimon L. B. Nielsen else if (!strcmp(*args, "-sign")) 1403b4e3dcbSSimon L. B. Nielsen operation = SMIME_SIGN; 1411f13597dSJung-uk Kim else if (!strcmp(*args, "-resign")) 1421f13597dSJung-uk Kim operation = SMIME_RESIGN; 1433b4e3dcbSSimon L. B. Nielsen else if (!strcmp(*args, "-verify")) 1443b4e3dcbSSimon L. B. Nielsen operation = SMIME_VERIFY; 1453b4e3dcbSSimon L. B. Nielsen else if (!strcmp(*args, "-pk7out")) 1463b4e3dcbSSimon L. B. Nielsen operation = SMIME_PK7OUT; 1475c87c606SMark Murray #ifndef OPENSSL_NO_DES 148f579bf8eSKris Kennaway else if (!strcmp(*args, "-des3")) 149f579bf8eSKris Kennaway cipher = EVP_des_ede3_cbc(); 150f579bf8eSKris Kennaway else if (!strcmp(*args, "-des")) 151f579bf8eSKris Kennaway cipher = EVP_des_cbc(); 152f579bf8eSKris Kennaway #endif 153db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_SEED 154db522d3aSSimon L. B. Nielsen else if (!strcmp(*args, "-seed")) 155db522d3aSSimon L. B. Nielsen cipher = EVP_seed_cbc(); 156db522d3aSSimon L. B. Nielsen #endif 1575c87c606SMark Murray #ifndef OPENSSL_NO_RC2 158f579bf8eSKris Kennaway else if (!strcmp(*args, "-rc2-40")) 159f579bf8eSKris Kennaway cipher = EVP_rc2_40_cbc(); 160f579bf8eSKris Kennaway else if (!strcmp(*args, "-rc2-128")) 161f579bf8eSKris Kennaway cipher = EVP_rc2_cbc(); 162f579bf8eSKris Kennaway else if (!strcmp(*args, "-rc2-64")) 163f579bf8eSKris Kennaway cipher = EVP_rc2_64_cbc(); 164f579bf8eSKris Kennaway #endif 1655c87c606SMark Murray #ifndef OPENSSL_NO_AES 1665c87c606SMark Murray else if (!strcmp(*args, "-aes128")) 1675c87c606SMark Murray cipher = EVP_aes_128_cbc(); 1685c87c606SMark Murray else if (!strcmp(*args, "-aes192")) 1695c87c606SMark Murray cipher = EVP_aes_192_cbc(); 1705c87c606SMark Murray else if (!strcmp(*args, "-aes256")) 1715c87c606SMark Murray cipher = EVP_aes_256_cbc(); 1725c87c606SMark Murray #endif 173ed5d4f9aSSimon L. B. Nielsen #ifndef OPENSSL_NO_CAMELLIA 174ed5d4f9aSSimon L. B. Nielsen else if (!strcmp(*args, "-camellia128")) 175ed5d4f9aSSimon L. B. Nielsen cipher = EVP_camellia_128_cbc(); 176ed5d4f9aSSimon L. B. Nielsen else if (!strcmp(*args, "-camellia192")) 177ed5d4f9aSSimon L. B. Nielsen cipher = EVP_camellia_192_cbc(); 178ed5d4f9aSSimon L. B. Nielsen else if (!strcmp(*args, "-camellia256")) 179ed5d4f9aSSimon L. B. Nielsen cipher = EVP_camellia_256_cbc(); 180ed5d4f9aSSimon L. B. Nielsen #endif 181f579bf8eSKris Kennaway else if (!strcmp(*args, "-text")) 182f579bf8eSKris Kennaway flags |= PKCS7_TEXT; 183f579bf8eSKris Kennaway else if (!strcmp(*args, "-nointern")) 184f579bf8eSKris Kennaway flags |= PKCS7_NOINTERN; 185f579bf8eSKris Kennaway else if (!strcmp(*args, "-noverify")) 186f579bf8eSKris Kennaway flags |= PKCS7_NOVERIFY; 187f579bf8eSKris Kennaway else if (!strcmp(*args, "-nochain")) 188f579bf8eSKris Kennaway flags |= PKCS7_NOCHAIN; 189f579bf8eSKris Kennaway else if (!strcmp(*args, "-nocerts")) 190f579bf8eSKris Kennaway flags |= PKCS7_NOCERTS; 191f579bf8eSKris Kennaway else if (!strcmp(*args, "-noattr")) 192f579bf8eSKris Kennaway flags |= PKCS7_NOATTR; 193f579bf8eSKris Kennaway else if (!strcmp(*args, "-nodetach")) 194f579bf8eSKris Kennaway flags &= ~PKCS7_DETACHED; 195ddd58736SKris Kennaway else if (!strcmp(*args, "-nosmimecap")) 196ddd58736SKris Kennaway flags |= PKCS7_NOSMIMECAP; 197f579bf8eSKris Kennaway else if (!strcmp(*args, "-binary")) 198f579bf8eSKris Kennaway flags |= PKCS7_BINARY; 199f579bf8eSKris Kennaway else if (!strcmp(*args, "-nosigs")) 200f579bf8eSKris Kennaway flags |= PKCS7_NOSIGS; 2011f13597dSJung-uk Kim else if (!strcmp(*args, "-stream")) 2021f13597dSJung-uk Kim indef = 1; 2031f13597dSJung-uk Kim else if (!strcmp(*args, "-indef")) 2041f13597dSJung-uk Kim indef = 1; 2051f13597dSJung-uk Kim else if (!strcmp(*args, "-noindef")) 2061f13597dSJung-uk Kim indef = 0; 20750ef0093SJacques Vidrine else if (!strcmp(*args, "-nooldmime")) 20850ef0093SJacques Vidrine flags |= PKCS7_NOOLDMIMETYPE; 20950ef0093SJacques Vidrine else if (!strcmp(*args, "-crlfeol")) 21050ef0093SJacques Vidrine flags |= PKCS7_CRLFEOL; 2116f9291ceSJung-uk Kim else if (!strcmp(*args, "-rand")) { 2121f13597dSJung-uk Kim if (!args[1]) 2131f13597dSJung-uk Kim goto argerr; 214f579bf8eSKris Kennaway args++; 215f579bf8eSKris Kennaway inrand = *args; 216f579bf8eSKris Kennaway need_rand = 1; 2173b4e3dcbSSimon L. B. Nielsen } 218fceca8a3SJacques Vidrine #ifndef OPENSSL_NO_ENGINE 2196f9291ceSJung-uk Kim else if (!strcmp(*args, "-engine")) { 2201f13597dSJung-uk Kim if (!args[1]) 2211f13597dSJung-uk Kim goto argerr; 2221f13597dSJung-uk Kim engine = *++args; 2233b4e3dcbSSimon L. B. Nielsen } 224fceca8a3SJacques Vidrine #endif 2256f9291ceSJung-uk Kim else if (!strcmp(*args, "-passin")) { 2261f13597dSJung-uk Kim if (!args[1]) 2271f13597dSJung-uk Kim goto argerr; 2281f13597dSJung-uk Kim passargin = *++args; 2296f9291ceSJung-uk Kim } else if (!strcmp(*args, "-to")) { 2301f13597dSJung-uk Kim if (!args[1]) 2311f13597dSJung-uk Kim goto argerr; 2321f13597dSJung-uk Kim to = *++args; 2336f9291ceSJung-uk Kim } else if (!strcmp(*args, "-from")) { 2341f13597dSJung-uk Kim if (!args[1]) 2351f13597dSJung-uk Kim goto argerr; 2361f13597dSJung-uk Kim from = *++args; 2376f9291ceSJung-uk Kim } else if (!strcmp(*args, "-subject")) { 2381f13597dSJung-uk Kim if (!args[1]) 2391f13597dSJung-uk Kim goto argerr; 2401f13597dSJung-uk Kim subject = *++args; 2416f9291ceSJung-uk Kim } else if (!strcmp(*args, "-signer")) { 2421f13597dSJung-uk Kim if (!args[1]) 2431f13597dSJung-uk Kim goto argerr; 2441f13597dSJung-uk Kim /* If previous -signer argument add signer to list */ 2451f13597dSJung-uk Kim 2466f9291ceSJung-uk Kim if (signerfile) { 2471f13597dSJung-uk Kim if (!sksigners) 2481f13597dSJung-uk Kim sksigners = sk_OPENSSL_STRING_new_null(); 2491f13597dSJung-uk Kim sk_OPENSSL_STRING_push(sksigners, signerfile); 2501f13597dSJung-uk Kim if (!keyfile) 2511f13597dSJung-uk Kim keyfile = signerfile; 2521f13597dSJung-uk Kim if (!skkeys) 2531f13597dSJung-uk Kim skkeys = sk_OPENSSL_STRING_new_null(); 2541f13597dSJung-uk Kim sk_OPENSSL_STRING_push(skkeys, keyfile); 2551f13597dSJung-uk Kim keyfile = NULL; 2563b4e3dcbSSimon L. B. Nielsen } 2571f13597dSJung-uk Kim signerfile = *++args; 2586f9291ceSJung-uk Kim } else if (!strcmp(*args, "-recip")) { 2591f13597dSJung-uk Kim if (!args[1]) 2601f13597dSJung-uk Kim goto argerr; 2611f13597dSJung-uk Kim recipfile = *++args; 2626f9291ceSJung-uk Kim } else if (!strcmp(*args, "-md")) { 2631f13597dSJung-uk Kim if (!args[1]) 2641f13597dSJung-uk Kim goto argerr; 2651f13597dSJung-uk Kim sign_md = EVP_get_digestbyname(*++args); 2666f9291ceSJung-uk Kim if (sign_md == NULL) { 2676f9291ceSJung-uk Kim BIO_printf(bio_err, "Unknown digest %s\n", *args); 2681f13597dSJung-uk Kim goto argerr; 2691f13597dSJung-uk Kim } 2706f9291ceSJung-uk Kim } else if (!strcmp(*args, "-inkey")) { 2711f13597dSJung-uk Kim if (!args[1]) 2721f13597dSJung-uk Kim goto argerr; 2731f13597dSJung-uk Kim /* If previous -inkey arument add signer to list */ 2746f9291ceSJung-uk Kim if (keyfile) { 2756f9291ceSJung-uk Kim if (!signerfile) { 2761f13597dSJung-uk Kim BIO_puts(bio_err, "Illegal -inkey without -signer\n"); 2771f13597dSJung-uk Kim goto argerr; 2783b4e3dcbSSimon L. B. Nielsen } 2791f13597dSJung-uk Kim if (!sksigners) 2801f13597dSJung-uk Kim sksigners = sk_OPENSSL_STRING_new_null(); 2811f13597dSJung-uk Kim sk_OPENSSL_STRING_push(sksigners, signerfile); 2821f13597dSJung-uk Kim signerfile = NULL; 2831f13597dSJung-uk Kim if (!skkeys) 2841f13597dSJung-uk Kim skkeys = sk_OPENSSL_STRING_new_null(); 2851f13597dSJung-uk Kim sk_OPENSSL_STRING_push(skkeys, keyfile); 2861f13597dSJung-uk Kim } 2871f13597dSJung-uk Kim keyfile = *++args; 2886f9291ceSJung-uk Kim } else if (!strcmp(*args, "-keyform")) { 2891f13597dSJung-uk Kim if (!args[1]) 2901f13597dSJung-uk Kim goto argerr; 2911f13597dSJung-uk Kim keyform = str2fmt(*++args); 2926f9291ceSJung-uk Kim } else if (!strcmp(*args, "-certfile")) { 2931f13597dSJung-uk Kim if (!args[1]) 2941f13597dSJung-uk Kim goto argerr; 2951f13597dSJung-uk Kim certfile = *++args; 2966f9291ceSJung-uk Kim } else if (!strcmp(*args, "-CAfile")) { 2971f13597dSJung-uk Kim if (!args[1]) 2981f13597dSJung-uk Kim goto argerr; 2991f13597dSJung-uk Kim CAfile = *++args; 3006f9291ceSJung-uk Kim } else if (!strcmp(*args, "-CApath")) { 3011f13597dSJung-uk Kim if (!args[1]) 3021f13597dSJung-uk Kim goto argerr; 3031f13597dSJung-uk Kim CApath = *++args; 3046f9291ceSJung-uk Kim } else if (!strcmp(*args, "-in")) { 3051f13597dSJung-uk Kim if (!args[1]) 3061f13597dSJung-uk Kim goto argerr; 3071f13597dSJung-uk Kim infile = *++args; 3086f9291ceSJung-uk Kim } else if (!strcmp(*args, "-inform")) { 3091f13597dSJung-uk Kim if (!args[1]) 3101f13597dSJung-uk Kim goto argerr; 3111f13597dSJung-uk Kim informat = str2fmt(*++args); 3126f9291ceSJung-uk Kim } else if (!strcmp(*args, "-outform")) { 3131f13597dSJung-uk Kim if (!args[1]) 3141f13597dSJung-uk Kim goto argerr; 3151f13597dSJung-uk Kim outformat = str2fmt(*++args); 3166f9291ceSJung-uk Kim } else if (!strcmp(*args, "-out")) { 3171f13597dSJung-uk Kim if (!args[1]) 3181f13597dSJung-uk Kim goto argerr; 3191f13597dSJung-uk Kim outfile = *++args; 3206f9291ceSJung-uk Kim } else if (!strcmp(*args, "-content")) { 3211f13597dSJung-uk Kim if (!args[1]) 3221f13597dSJung-uk Kim goto argerr; 3231f13597dSJung-uk Kim contfile = *++args; 3246f9291ceSJung-uk Kim } else if (args_verify(&args, NULL, &badarg, bio_err, &vpm)) 3253b4e3dcbSSimon L. B. Nielsen continue; 3261f13597dSJung-uk Kim else if ((cipher = EVP_get_cipherbyname(*args + 1)) == NULL) 3273b4e3dcbSSimon L. B. Nielsen badarg = 1; 328f579bf8eSKris Kennaway args++; 329f579bf8eSKris Kennaway } 330f579bf8eSKris Kennaway 3316f9291ceSJung-uk Kim if (!(operation & SMIME_SIGNERS) && (skkeys || sksigners)) { 3321f13597dSJung-uk Kim BIO_puts(bio_err, "Multiple signers or keys not allowed\n"); 3331f13597dSJung-uk Kim goto argerr; 3341f13597dSJung-uk Kim } 3351f13597dSJung-uk Kim 3366f9291ceSJung-uk Kim if (operation & SMIME_SIGNERS) { 3371f13597dSJung-uk Kim /* Check to see if any final signer needs to be appended */ 3386f9291ceSJung-uk Kim if (keyfile && !signerfile) { 3391f13597dSJung-uk Kim BIO_puts(bio_err, "Illegal -inkey without -signer\n"); 3401f13597dSJung-uk Kim goto argerr; 3411f13597dSJung-uk Kim } 3426f9291ceSJung-uk Kim if (signerfile) { 3431f13597dSJung-uk Kim if (!sksigners) 3441f13597dSJung-uk Kim sksigners = sk_OPENSSL_STRING_new_null(); 3451f13597dSJung-uk Kim sk_OPENSSL_STRING_push(sksigners, signerfile); 3461f13597dSJung-uk Kim if (!skkeys) 3471f13597dSJung-uk Kim skkeys = sk_OPENSSL_STRING_new_null(); 3481f13597dSJung-uk Kim if (!keyfile) 3491f13597dSJung-uk Kim keyfile = signerfile; 3501f13597dSJung-uk Kim sk_OPENSSL_STRING_push(skkeys, keyfile); 3511f13597dSJung-uk Kim } 3526f9291ceSJung-uk Kim if (!sksigners) { 353f579bf8eSKris Kennaway BIO_printf(bio_err, "No signer certificate specified\n"); 354f579bf8eSKris Kennaway badarg = 1; 355f579bf8eSKris Kennaway } 3561f13597dSJung-uk Kim signerfile = NULL; 3571f13597dSJung-uk Kim keyfile = NULL; 358f579bf8eSKris Kennaway need_rand = 1; 3596f9291ceSJung-uk Kim } else if (operation == SMIME_DECRYPT) { 3606f9291ceSJung-uk Kim if (!recipfile && !keyfile) { 3616f9291ceSJung-uk Kim BIO_printf(bio_err, 3626f9291ceSJung-uk Kim "No recipient certificate or key specified\n"); 363f579bf8eSKris Kennaway badarg = 1; 364f579bf8eSKris Kennaway } 3656f9291ceSJung-uk Kim } else if (operation == SMIME_ENCRYPT) { 3666f9291ceSJung-uk Kim if (!*args) { 367f579bf8eSKris Kennaway BIO_printf(bio_err, "No recipient(s) certificate(s) specified\n"); 368f579bf8eSKris Kennaway badarg = 1; 369f579bf8eSKris Kennaway } 370f579bf8eSKris Kennaway need_rand = 1; 3716f9291ceSJung-uk Kim } else if (!operation) 3723b4e3dcbSSimon L. B. Nielsen badarg = 1; 373f579bf8eSKris Kennaway 3746f9291ceSJung-uk Kim if (badarg) { 3751f13597dSJung-uk Kim argerr: 376f579bf8eSKris Kennaway BIO_printf(bio_err, "Usage smime [options] cert.pem ...\n"); 377f579bf8eSKris Kennaway BIO_printf(bio_err, "where options are\n"); 378f579bf8eSKris Kennaway BIO_printf(bio_err, "-encrypt encrypt message\n"); 379f579bf8eSKris Kennaway BIO_printf(bio_err, "-decrypt decrypt encrypted message\n"); 380f579bf8eSKris Kennaway BIO_printf(bio_err, "-sign sign message\n"); 381f579bf8eSKris Kennaway BIO_printf(bio_err, "-verify verify signed message\n"); 382f579bf8eSKris Kennaway BIO_printf(bio_err, "-pk7out output PKCS#7 structure\n"); 3835c87c606SMark Murray #ifndef OPENSSL_NO_DES 384f579bf8eSKris Kennaway BIO_printf(bio_err, "-des3 encrypt with triple DES\n"); 385f579bf8eSKris Kennaway BIO_printf(bio_err, "-des encrypt with DES\n"); 386f579bf8eSKris Kennaway #endif 387db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_SEED 388db522d3aSSimon L. B. Nielsen BIO_printf(bio_err, "-seed encrypt with SEED\n"); 389db522d3aSSimon L. B. Nielsen #endif 3905c87c606SMark Murray #ifndef OPENSSL_NO_RC2 391f579bf8eSKris Kennaway BIO_printf(bio_err, "-rc2-40 encrypt with RC2-40 (default)\n"); 392f579bf8eSKris Kennaway BIO_printf(bio_err, "-rc2-64 encrypt with RC2-64\n"); 393f579bf8eSKris Kennaway BIO_printf(bio_err, "-rc2-128 encrypt with RC2-128\n"); 394f579bf8eSKris Kennaway #endif 3955c87c606SMark Murray #ifndef OPENSSL_NO_AES 3965c87c606SMark Murray BIO_printf(bio_err, "-aes128, -aes192, -aes256\n"); 3976f9291ceSJung-uk Kim BIO_printf(bio_err, 3986f9291ceSJung-uk Kim " encrypt PEM output with cbc aes\n"); 3995c87c606SMark Murray #endif 400ed5d4f9aSSimon L. B. Nielsen #ifndef OPENSSL_NO_CAMELLIA 401ed5d4f9aSSimon L. B. Nielsen BIO_printf(bio_err, "-camellia128, -camellia192, -camellia256\n"); 4026f9291ceSJung-uk Kim BIO_printf(bio_err, 4036f9291ceSJung-uk Kim " encrypt PEM output with cbc camellia\n"); 404ed5d4f9aSSimon L. B. Nielsen #endif 4056f9291ceSJung-uk Kim BIO_printf(bio_err, 4066f9291ceSJung-uk Kim "-nointern don't search certificates in message for signer\n"); 4076f9291ceSJung-uk Kim BIO_printf(bio_err, 4086f9291ceSJung-uk Kim "-nosigs don't verify message signature\n"); 4096f9291ceSJung-uk Kim BIO_printf(bio_err, 4106f9291ceSJung-uk Kim "-noverify don't verify signers certificate\n"); 4116f9291ceSJung-uk Kim BIO_printf(bio_err, 4126f9291ceSJung-uk Kim "-nocerts don't include signers certificate when signing\n"); 413f579bf8eSKris Kennaway BIO_printf(bio_err, "-nodetach use opaque signing\n"); 4146f9291ceSJung-uk Kim BIO_printf(bio_err, 4156f9291ceSJung-uk Kim "-noattr don't include any signed attributes\n"); 4166f9291ceSJung-uk Kim BIO_printf(bio_err, 4176f9291ceSJung-uk Kim "-binary don't translate message to text\n"); 418f579bf8eSKris Kennaway BIO_printf(bio_err, "-certfile file other certificates file\n"); 419f579bf8eSKris Kennaway BIO_printf(bio_err, "-signer file signer certificate file\n"); 4206f9291ceSJung-uk Kim BIO_printf(bio_err, 4216f9291ceSJung-uk Kim "-recip file recipient certificate file for decryption\n"); 422f579bf8eSKris Kennaway BIO_printf(bio_err, "-in file input file\n"); 4236f9291ceSJung-uk Kim BIO_printf(bio_err, 4246f9291ceSJung-uk Kim "-inform arg input format SMIME (default), PEM or DER\n"); 4256f9291ceSJung-uk Kim BIO_printf(bio_err, 4266f9291ceSJung-uk Kim "-inkey file input private key (if not signer or recipient)\n"); 4276f9291ceSJung-uk Kim BIO_printf(bio_err, 4286f9291ceSJung-uk Kim "-keyform arg input private key format (PEM or ENGINE)\n"); 429f579bf8eSKris Kennaway BIO_printf(bio_err, "-out file output file\n"); 4306f9291ceSJung-uk Kim BIO_printf(bio_err, 4316f9291ceSJung-uk Kim "-outform arg output format SMIME (default), PEM or DER\n"); 4326f9291ceSJung-uk Kim BIO_printf(bio_err, 4336f9291ceSJung-uk Kim "-content file supply or override content for detached signature\n"); 434f579bf8eSKris Kennaway BIO_printf(bio_err, "-to addr to address\n"); 435f579bf8eSKris Kennaway BIO_printf(bio_err, "-from ad from address\n"); 436f579bf8eSKris Kennaway BIO_printf(bio_err, "-subject s subject\n"); 4376f9291ceSJung-uk Kim BIO_printf(bio_err, 4386f9291ceSJung-uk Kim "-text include or delete text MIME headers\n"); 4396f9291ceSJung-uk Kim BIO_printf(bio_err, 4406f9291ceSJung-uk Kim "-CApath dir trusted certificates directory\n"); 441f579bf8eSKris Kennaway BIO_printf(bio_err, "-CAfile file trusted certificates file\n"); 4426f9291ceSJung-uk Kim BIO_printf(bio_err, 443ed6b93beSJung-uk Kim "-no_alt_chains only ever use the first certificate chain found\n"); 444ed6b93beSJung-uk Kim BIO_printf(bio_err, 4456f9291ceSJung-uk Kim "-crl_check check revocation status of signer's certificate using CRLs\n"); 4466f9291ceSJung-uk Kim BIO_printf(bio_err, 4476f9291ceSJung-uk Kim "-crl_check_all check revocation status of signer's certificate chain using CRLs\n"); 448fceca8a3SJacques Vidrine #ifndef OPENSSL_NO_ENGINE 4496f9291ceSJung-uk Kim BIO_printf(bio_err, 4506f9291ceSJung-uk Kim "-engine e use engine e, possibly a hardware device.\n"); 451fceca8a3SJacques Vidrine #endif 45226d191b4SKris Kennaway BIO_printf(bio_err, "-passin arg input file pass phrase source\n"); 4536f9291ceSJung-uk Kim BIO_printf(bio_err, "-rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, 4546f9291ceSJung-uk Kim LIST_SEPARATOR_CHAR); 4556f9291ceSJung-uk Kim BIO_printf(bio_err, 4566f9291ceSJung-uk Kim " load the file (or the files in the directory) into\n"); 457f579bf8eSKris Kennaway BIO_printf(bio_err, " the random number generator\n"); 4586f9291ceSJung-uk Kim BIO_printf(bio_err, 4596f9291ceSJung-uk Kim "cert.pem recipient certificate(s) for encryption\n"); 460f579bf8eSKris Kennaway goto end; 461f579bf8eSKris Kennaway } 4625c87c606SMark Murray e = setup_engine(bio_err, engine, 0); 4635c87c606SMark Murray 4646f9291ceSJung-uk Kim if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) { 465f579bf8eSKris Kennaway BIO_printf(bio_err, "Error getting password\n"); 466f579bf8eSKris Kennaway goto end; 467f579bf8eSKris Kennaway } 468f579bf8eSKris Kennaway 4696f9291ceSJung-uk Kim if (need_rand) { 470f579bf8eSKris Kennaway app_RAND_load_file(NULL, bio_err, (inrand != NULL)); 471f579bf8eSKris Kennaway if (inrand != NULL) 472f579bf8eSKris Kennaway BIO_printf(bio_err, "%ld semi-random bytes loaded\n", 473f579bf8eSKris Kennaway app_RAND_load_files(inrand)); 474f579bf8eSKris Kennaway } 475f579bf8eSKris Kennaway 476f579bf8eSKris Kennaway ret = 2; 477f579bf8eSKris Kennaway 4781f13597dSJung-uk Kim if (!(operation & SMIME_SIGNERS)) 4793b4e3dcbSSimon L. B. Nielsen flags &= ~PKCS7_DETACHED; 480f579bf8eSKris Kennaway 4816f9291ceSJung-uk Kim if (operation & SMIME_OP) { 4823b4e3dcbSSimon L. B. Nielsen if (outformat == FORMAT_ASN1) 4833b4e3dcbSSimon L. B. Nielsen outmode = "wb"; 4846f9291ceSJung-uk Kim } else { 4853b4e3dcbSSimon L. B. Nielsen if (flags & PKCS7_BINARY) 4863b4e3dcbSSimon L. B. Nielsen outmode = "wb"; 4871f13597dSJung-uk Kim } 4881f13597dSJung-uk Kim 4896f9291ceSJung-uk Kim if (operation & SMIME_IP) { 4903b4e3dcbSSimon L. B. Nielsen if (informat == FORMAT_ASN1) 4913b4e3dcbSSimon L. B. Nielsen inmode = "rb"; 4926f9291ceSJung-uk Kim } else { 4931f13597dSJung-uk Kim if (flags & PKCS7_BINARY) 4941f13597dSJung-uk Kim inmode = "rb"; 4951f13597dSJung-uk Kim } 496f579bf8eSKris Kennaway 4976f9291ceSJung-uk Kim if (operation == SMIME_ENCRYPT) { 4986f9291ceSJung-uk Kim if (!cipher) { 49994ad176cSJung-uk Kim #ifndef OPENSSL_NO_DES 50094ad176cSJung-uk Kim cipher = EVP_des_ede3_cbc(); 501f579bf8eSKris Kennaway #else 502f579bf8eSKris Kennaway BIO_printf(bio_err, "No cipher selected\n"); 503f579bf8eSKris Kennaway goto end; 504f579bf8eSKris Kennaway #endif 505f579bf8eSKris Kennaway } 506f579bf8eSKris Kennaway encerts = sk_X509_new_null(); 5076f9291ceSJung-uk Kim while (*args) { 5085c87c606SMark Murray if (!(cert = load_cert(bio_err, *args, FORMAT_PEM, 5096f9291ceSJung-uk Kim NULL, e, "recipient certificate file"))) { 5105c87c606SMark Murray #if 0 /* An appropriate message is already printed */ 5116f9291ceSJung-uk Kim BIO_printf(bio_err, 5126f9291ceSJung-uk Kim "Can't read recipient certificate file %s\n", 5136f9291ceSJung-uk Kim *args); 5145c87c606SMark Murray #endif 515f579bf8eSKris Kennaway goto end; 516f579bf8eSKris Kennaway } 517f579bf8eSKris Kennaway sk_X509_push(encerts, cert); 518f579bf8eSKris Kennaway cert = NULL; 519f579bf8eSKris Kennaway args++; 520f579bf8eSKris Kennaway } 521f579bf8eSKris Kennaway } 522f579bf8eSKris Kennaway 5236f9291ceSJung-uk Kim if (certfile) { 5245c87c606SMark Murray if (!(other = load_certs(bio_err, certfile, FORMAT_PEM, NULL, 5256f9291ceSJung-uk Kim e, "certificate file"))) { 526f579bf8eSKris Kennaway ERR_print_errors(bio_err); 527f579bf8eSKris Kennaway goto end; 528f579bf8eSKris Kennaway } 529f579bf8eSKris Kennaway } 530f579bf8eSKris Kennaway 5316f9291ceSJung-uk Kim if (recipfile && (operation == SMIME_DECRYPT)) { 5325c87c606SMark Murray if (!(recip = load_cert(bio_err, recipfile, FORMAT_PEM, NULL, 5336f9291ceSJung-uk Kim e, "recipient certificate file"))) { 534f579bf8eSKris Kennaway ERR_print_errors(bio_err); 535f579bf8eSKris Kennaway goto end; 536f579bf8eSKris Kennaway } 537f579bf8eSKris Kennaway } 538f579bf8eSKris Kennaway 5396f9291ceSJung-uk Kim if (operation == SMIME_DECRYPT) { 5403b4e3dcbSSimon L. B. Nielsen if (!keyfile) 5413b4e3dcbSSimon L. B. Nielsen keyfile = recipfile; 5426f9291ceSJung-uk Kim } else if (operation == SMIME_SIGN) { 5433b4e3dcbSSimon L. B. Nielsen if (!keyfile) 5443b4e3dcbSSimon L. B. Nielsen keyfile = signerfile; 5456f9291ceSJung-uk Kim } else 5466f9291ceSJung-uk Kim keyfile = NULL; 547f579bf8eSKris Kennaway 5486f9291ceSJung-uk Kim if (keyfile) { 5495c87c606SMark Murray key = load_key(bio_err, keyfile, keyform, 0, passin, e, 5505c87c606SMark Murray "signing key file"); 5513b4e3dcbSSimon L. B. Nielsen if (!key) 552f579bf8eSKris Kennaway goto end; 553f579bf8eSKris Kennaway } 554f579bf8eSKris Kennaway 5556f9291ceSJung-uk Kim if (infile) { 5566f9291ceSJung-uk Kim if (!(in = BIO_new_file(infile, inmode))) { 5576f9291ceSJung-uk Kim BIO_printf(bio_err, "Can't open input file %s\n", infile); 558f579bf8eSKris Kennaway goto end; 559f579bf8eSKris Kennaway } 5606f9291ceSJung-uk Kim } else 5613b4e3dcbSSimon L. B. Nielsen in = BIO_new_fp(stdin, BIO_NOCLOSE); 562f579bf8eSKris Kennaway 5636f9291ceSJung-uk Kim if (operation & SMIME_IP) { 564ddd58736SKris Kennaway if (informat == FORMAT_SMIME) 565ddd58736SKris Kennaway p7 = SMIME_read_PKCS7(in, &indata); 566ddd58736SKris Kennaway else if (informat == FORMAT_PEM) 567ddd58736SKris Kennaway p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL); 568ddd58736SKris Kennaway else if (informat == FORMAT_ASN1) 569ddd58736SKris Kennaway p7 = d2i_PKCS7_bio(in, NULL); 5706f9291ceSJung-uk Kim else { 571ddd58736SKris Kennaway BIO_printf(bio_err, "Bad input format for PKCS#7 file\n"); 572ddd58736SKris Kennaway goto end; 573ddd58736SKris Kennaway } 574ddd58736SKris Kennaway 5756f9291ceSJung-uk Kim if (!p7) { 576f579bf8eSKris Kennaway BIO_printf(bio_err, "Error reading S/MIME message\n"); 577f579bf8eSKris Kennaway goto end; 578f579bf8eSKris Kennaway } 5796f9291ceSJung-uk Kim if (contfile) { 580ddd58736SKris Kennaway BIO_free(indata); 5816f9291ceSJung-uk Kim if (!(indata = BIO_new_file(contfile, "rb"))) { 582ddd58736SKris Kennaway BIO_printf(bio_err, "Can't read content file %s\n", contfile); 583ddd58736SKris Kennaway goto end; 584ddd58736SKris Kennaway } 585ddd58736SKris Kennaway } 586f579bf8eSKris Kennaway } 587f579bf8eSKris Kennaway 5886f9291ceSJung-uk Kim if (outfile) { 5896f9291ceSJung-uk Kim if (!(out = BIO_new_file(outfile, outmode))) { 5906f9291ceSJung-uk Kim BIO_printf(bio_err, "Can't open output file %s\n", outfile); 5911f13597dSJung-uk Kim goto end; 5921f13597dSJung-uk Kim } 5936f9291ceSJung-uk Kim } else { 5941f13597dSJung-uk Kim out = BIO_new_fp(stdout, BIO_NOCLOSE); 5951f13597dSJung-uk Kim #ifdef OPENSSL_SYS_VMS 5961f13597dSJung-uk Kim { 5971f13597dSJung-uk Kim BIO *tmpbio = BIO_new(BIO_f_linebuffer()); 5981f13597dSJung-uk Kim out = BIO_push(tmpbio, out); 5991f13597dSJung-uk Kim } 6001f13597dSJung-uk Kim #endif 6011f13597dSJung-uk Kim } 6021f13597dSJung-uk Kim 6036f9291ceSJung-uk Kim if (operation == SMIME_VERIFY) { 6041f13597dSJung-uk Kim if (!(store = setup_verify(bio_err, CAfile, CApath))) 6051f13597dSJung-uk Kim goto end; 6061f13597dSJung-uk Kim X509_STORE_set_verify_cb(store, smime_cb); 6071f13597dSJung-uk Kim if (vpm) 6081f13597dSJung-uk Kim X509_STORE_set1_param(store, vpm); 6091f13597dSJung-uk Kim } 6101f13597dSJung-uk Kim 6111f13597dSJung-uk Kim ret = 3; 6121f13597dSJung-uk Kim 6136f9291ceSJung-uk Kim if (operation == SMIME_ENCRYPT) { 6141f13597dSJung-uk Kim if (indef) 6151f13597dSJung-uk Kim flags |= PKCS7_STREAM; 6161f13597dSJung-uk Kim p7 = PKCS7_encrypt(encerts, in, cipher, flags); 6176f9291ceSJung-uk Kim } else if (operation & SMIME_SIGNERS) { 6181f13597dSJung-uk Kim int i; 6196f9291ceSJung-uk Kim /* 6206f9291ceSJung-uk Kim * If detached data content we only enable streaming if S/MIME output 6216f9291ceSJung-uk Kim * format. 6221f13597dSJung-uk Kim */ 6236f9291ceSJung-uk Kim if (operation == SMIME_SIGN) { 6246f9291ceSJung-uk Kim if (flags & PKCS7_DETACHED) { 6251f13597dSJung-uk Kim if (outformat == FORMAT_SMIME) 6261f13597dSJung-uk Kim flags |= PKCS7_STREAM; 6276f9291ceSJung-uk Kim } else if (indef) 6281f13597dSJung-uk Kim flags |= PKCS7_STREAM; 6291f13597dSJung-uk Kim flags |= PKCS7_PARTIAL; 6301f13597dSJung-uk Kim p7 = PKCS7_sign(NULL, NULL, other, in, flags); 6311f13597dSJung-uk Kim if (!p7) 6321f13597dSJung-uk Kim goto end; 6337bded2dbSJung-uk Kim if (flags & PKCS7_NOCERTS) { 6347bded2dbSJung-uk Kim for (i = 0; i < sk_X509_num(other); i++) { 6357bded2dbSJung-uk Kim X509 *x = sk_X509_value(other, i); 6367bded2dbSJung-uk Kim PKCS7_add_certificate(p7, x); 6377bded2dbSJung-uk Kim } 6387bded2dbSJung-uk Kim } 6396f9291ceSJung-uk Kim } else 6401f13597dSJung-uk Kim flags |= PKCS7_REUSE_DIGEST; 6416f9291ceSJung-uk Kim for (i = 0; i < sk_OPENSSL_STRING_num(sksigners); i++) { 6421f13597dSJung-uk Kim signerfile = sk_OPENSSL_STRING_value(sksigners, i); 6431f13597dSJung-uk Kim keyfile = sk_OPENSSL_STRING_value(skkeys, i); 6441f13597dSJung-uk Kim signer = load_cert(bio_err, signerfile, FORMAT_PEM, NULL, 6451f13597dSJung-uk Kim e, "signer certificate"); 6461f13597dSJung-uk Kim if (!signer) 6471f13597dSJung-uk Kim goto end; 6481f13597dSJung-uk Kim key = load_key(bio_err, keyfile, keyform, 0, passin, e, 6491f13597dSJung-uk Kim "signing key file"); 6501f13597dSJung-uk Kim if (!key) 6511f13597dSJung-uk Kim goto end; 6526f9291ceSJung-uk Kim if (!PKCS7_sign_add_signer(p7, signer, key, sign_md, flags)) 6531f13597dSJung-uk Kim goto end; 6541f13597dSJung-uk Kim X509_free(signer); 6551f13597dSJung-uk Kim signer = NULL; 6561f13597dSJung-uk Kim EVP_PKEY_free(key); 6571f13597dSJung-uk Kim key = NULL; 6581f13597dSJung-uk Kim } 6591f13597dSJung-uk Kim /* If not streaming or resigning finalize structure */ 6606f9291ceSJung-uk Kim if ((operation == SMIME_SIGN) && !(flags & PKCS7_STREAM)) { 6611f13597dSJung-uk Kim if (!PKCS7_final(p7, in, flags)) 6621f13597dSJung-uk Kim goto end; 6631f13597dSJung-uk Kim } 6641f13597dSJung-uk Kim } 6651f13597dSJung-uk Kim 6666f9291ceSJung-uk Kim if (!p7) { 667f579bf8eSKris Kennaway BIO_printf(bio_err, "Error creating PKCS#7 structure\n"); 668f579bf8eSKris Kennaway goto end; 669f579bf8eSKris Kennaway } 670f579bf8eSKris Kennaway 671f579bf8eSKris Kennaway ret = 4; 6726f9291ceSJung-uk Kim if (operation == SMIME_DECRYPT) { 6736f9291ceSJung-uk Kim if (!PKCS7_decrypt(p7, key, recip, out, flags)) { 674f579bf8eSKris Kennaway BIO_printf(bio_err, "Error decrypting PKCS#7 structure\n"); 675f579bf8eSKris Kennaway goto end; 676f579bf8eSKris Kennaway } 6776f9291ceSJung-uk Kim } else if (operation == SMIME_VERIFY) { 678f579bf8eSKris Kennaway STACK_OF(X509) *signers; 6793b4e3dcbSSimon L. B. Nielsen if (PKCS7_verify(p7, other, store, indata, out, flags)) 680c1803d78SJacques Vidrine BIO_printf(bio_err, "Verification successful\n"); 6816f9291ceSJung-uk Kim else { 682c1803d78SJacques Vidrine BIO_printf(bio_err, "Verification failure\n"); 683f579bf8eSKris Kennaway goto end; 684f579bf8eSKris Kennaway } 685f579bf8eSKris Kennaway signers = PKCS7_get0_signers(p7, other, flags); 6866f9291ceSJung-uk Kim if (!save_certs(signerfile, signers)) { 6876f9291ceSJung-uk Kim BIO_printf(bio_err, "Error writing signers to %s\n", signerfile); 688f579bf8eSKris Kennaway ret = 5; 689f579bf8eSKris Kennaway goto end; 690f579bf8eSKris Kennaway } 691f579bf8eSKris Kennaway sk_X509_free(signers); 6926f9291ceSJung-uk Kim } else if (operation == SMIME_PK7OUT) 693f579bf8eSKris Kennaway PEM_write_bio_PKCS7(out, p7); 6946f9291ceSJung-uk Kim else { 6953b4e3dcbSSimon L. B. Nielsen if (to) 6963b4e3dcbSSimon L. B. Nielsen BIO_printf(out, "To: %s\n", to); 6973b4e3dcbSSimon L. B. Nielsen if (from) 6983b4e3dcbSSimon L. B. Nielsen BIO_printf(out, "From: %s\n", from); 6993b4e3dcbSSimon L. B. Nielsen if (subject) 7003b4e3dcbSSimon L. B. Nielsen BIO_printf(out, "Subject: %s\n", subject); 7016f9291ceSJung-uk Kim if (outformat == FORMAT_SMIME) { 7021f13597dSJung-uk Kim if (operation == SMIME_RESIGN) 7031f13597dSJung-uk Kim SMIME_write_PKCS7(out, p7, indata, flags); 7041f13597dSJung-uk Kim else 705f579bf8eSKris Kennaway SMIME_write_PKCS7(out, p7, in, flags); 7066f9291ceSJung-uk Kim } else if (outformat == FORMAT_PEM) 7071f13597dSJung-uk Kim PEM_write_bio_PKCS7_stream(out, p7, in, flags); 708ddd58736SKris Kennaway else if (outformat == FORMAT_ASN1) 7091f13597dSJung-uk Kim i2d_PKCS7_bio_stream(out, p7, in, flags); 7106f9291ceSJung-uk Kim else { 711ddd58736SKris Kennaway BIO_printf(bio_err, "Bad output format for PKCS#7 file\n"); 712ddd58736SKris Kennaway goto end; 713ddd58736SKris Kennaway } 714f579bf8eSKris Kennaway } 715f579bf8eSKris Kennaway ret = 0; 716f579bf8eSKris Kennaway end: 717f579bf8eSKris Kennaway if (need_rand) 718f579bf8eSKris Kennaway app_RAND_write_file(NULL, bio_err); 7196f9291ceSJung-uk Kim if (ret) 7206f9291ceSJung-uk Kim ERR_print_errors(bio_err); 721f579bf8eSKris Kennaway sk_X509_pop_free(encerts, X509_free); 722f579bf8eSKris Kennaway sk_X509_pop_free(other, X509_free); 7233b4e3dcbSSimon L. B. Nielsen if (vpm) 7243b4e3dcbSSimon L. B. Nielsen X509_VERIFY_PARAM_free(vpm); 7251f13597dSJung-uk Kim if (sksigners) 7261f13597dSJung-uk Kim sk_OPENSSL_STRING_free(sksigners); 7271f13597dSJung-uk Kim if (skkeys) 7281f13597dSJung-uk Kim sk_OPENSSL_STRING_free(skkeys); 729f579bf8eSKris Kennaway X509_STORE_free(store); 730f579bf8eSKris Kennaway X509_free(cert); 731f579bf8eSKris Kennaway X509_free(recip); 732f579bf8eSKris Kennaway X509_free(signer); 733f579bf8eSKris Kennaway EVP_PKEY_free(key); 734f579bf8eSKris Kennaway PKCS7_free(p7); 735*6cf8931aSJung-uk Kim release_engine(e); 736f579bf8eSKris Kennaway BIO_free(in); 737f579bf8eSKris Kennaway BIO_free(indata); 738ddd58736SKris Kennaway BIO_free_all(out); 7396f9291ceSJung-uk Kim if (passin) 7406f9291ceSJung-uk Kim OPENSSL_free(passin); 741f579bf8eSKris Kennaway return (ret); 742f579bf8eSKris Kennaway } 743f579bf8eSKris Kennaway 744f579bf8eSKris Kennaway static int save_certs(char *signerfile, STACK_OF(X509) *signers) 745f579bf8eSKris Kennaway { 746f579bf8eSKris Kennaway int i; 747f579bf8eSKris Kennaway BIO *tmp; 7483b4e3dcbSSimon L. B. Nielsen if (!signerfile) 7493b4e3dcbSSimon L. B. Nielsen return 1; 750f579bf8eSKris Kennaway tmp = BIO_new_file(signerfile, "w"); 7516f9291ceSJung-uk Kim if (!tmp) 7526f9291ceSJung-uk Kim return 0; 753f579bf8eSKris Kennaway for (i = 0; i < sk_X509_num(signers); i++) 754f579bf8eSKris Kennaway PEM_write_bio_X509(tmp, sk_X509_value(signers, i)); 755f579bf8eSKris Kennaway BIO_free(tmp); 756f579bf8eSKris Kennaway return 1; 757f579bf8eSKris Kennaway } 758f579bf8eSKris Kennaway 7593b4e3dcbSSimon L. B. Nielsen /* Minimal callback just to output policy info (if any) */ 7603b4e3dcbSSimon L. B. Nielsen 7613b4e3dcbSSimon L. B. Nielsen static int smime_cb(int ok, X509_STORE_CTX *ctx) 7623b4e3dcbSSimon L. B. Nielsen { 7633b4e3dcbSSimon L. B. Nielsen int error; 7643b4e3dcbSSimon L. B. Nielsen 7653b4e3dcbSSimon L. B. Nielsen error = X509_STORE_CTX_get_error(ctx); 7663b4e3dcbSSimon L. B. Nielsen 7673b4e3dcbSSimon L. B. Nielsen if ((error != X509_V_ERR_NO_EXPLICIT_POLICY) 7683b4e3dcbSSimon L. B. Nielsen && ((error != X509_V_OK) || (ok != 2))) 7693b4e3dcbSSimon L. B. Nielsen return ok; 7703b4e3dcbSSimon L. B. Nielsen 7713b4e3dcbSSimon L. B. Nielsen policies_print(NULL, ctx); 7723b4e3dcbSSimon L. B. Nielsen 7733b4e3dcbSSimon L. B. Nielsen return ok; 7743b4e3dcbSSimon L. B. Nielsen 7753b4e3dcbSSimon L. B. Nielsen } 776