[BACK]Return to smime.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / openssl

Diff for /src/usr.bin/openssl/smime.c between version 1.10 and 1.11

version 1.10, 2018/02/07 05:47:55 version 1.11, 2022/01/11 14:23:05
Line 82 
Line 82 
 #define SMIME_PK7OUT    (5 | SMIME_IP | SMIME_OP)  #define SMIME_PK7OUT    (5 | SMIME_IP | SMIME_OP)
 #define SMIME_RESIGN    (6 | SMIME_IP | SMIME_OP | SMIME_SIGNERS)  #define SMIME_RESIGN    (6 | SMIME_IP | SMIME_OP | SMIME_SIGNERS)
   
   static struct {
           char *CAfile;
           char *CApath;
           char *certfile;
           const EVP_CIPHER *cipher;
           char *contfile;
           int flags;
           char *from;
           int indef;
           char *infile;
           int informat;
           char *keyfile;
           int keyform;
           int operation;
           char *outfile;
           int outformat;
           char *passargin;
           char *recipfile;
           const EVP_MD *sign_md;
           char *signerfile;
           STACK_OF(OPENSSL_STRING) *skkeys;
           STACK_OF(OPENSSL_STRING) *sksigners;
           char *subject;
           char *to;
           X509_VERIFY_PARAM *vpm;
   } smime_config;
   
   static const EVP_CIPHER *
   get_cipher_by_name(char *name)
   {
           if (name == NULL || strcmp(name, "") == 0)
                   return (NULL);
   #ifndef OPENSSL_NO_AES
           else if (strcmp(name, "aes128") == 0)
                   return EVP_aes_128_cbc();
           else if (strcmp(name, "aes192") == 0)
                   return EVP_aes_192_cbc();
           else if (strcmp(name, "aes256") == 0)
                   return EVP_aes_256_cbc();
   #endif
   #ifndef OPENSSL_NO_CAMELLIA
           else if (strcmp(name, "camellia128") == 0)
                   return EVP_camellia_128_cbc();
           else if (strcmp(name, "camellia192") == 0)
                   return EVP_camellia_192_cbc();
           else if (strcmp(name, "camellia256") == 0)
                   return EVP_camellia_256_cbc();
   #endif
   #ifndef OPENSSL_NO_DES
           else if (strcmp(name, "des") == 0)
                   return EVP_des_cbc();
           else if (strcmp(name, "des3") == 0)
                   return EVP_des_ede3_cbc();
   #endif
   #ifndef OPENSSL_NO_RC2
           else if (!strcmp(name, "rc2-40"))
                   return EVP_rc2_40_cbc();
           else if (!strcmp(name, "rc2-64"))
                   return EVP_rc2_64_cbc();
           else if (!strcmp(name, "rc2-128"))
                   return EVP_rc2_cbc();
   #endif
   }
   
   static int
   smime_opt_cipher(int argc, char **argv, int *argsused)
   {
           char *name = argv[0];
   
           if (*name++ != '-')
                   return (1);
   
           if ((smime_config.cipher = get_cipher_by_name(name)) == NULL)
                   if ((smime_config.cipher = EVP_get_cipherbyname(name)) == NULL)
                           return (1);
   
           *argsused = 1;
           return (0);
   }
   
   static int
   smime_opt_inkey(char *arg)
   {
           if (smime_config.keyfile == NULL) {
                   smime_config.keyfile = arg;
                   return (0);
           }
   
           if (smime_config.signerfile == NULL) {
                   BIO_puts(bio_err, "Illegal -inkey without -signer\n");
                   return (1);
           }
   
           if (smime_config.sksigners == NULL) {
                   if ((smime_config.sksigners = sk_OPENSSL_STRING_new_null()) == NULL)
                           return (1);
           }
           if (!sk_OPENSSL_STRING_push(smime_config.sksigners,
               smime_config.signerfile))
                   return (1);
   
           smime_config.signerfile = NULL;
   
           if (smime_config.skkeys == NULL) {
                   if ((smime_config.skkeys = sk_OPENSSL_STRING_new_null()) == NULL)
                           return (1);
           }
           if (!sk_OPENSSL_STRING_push(smime_config.skkeys, smime_config.keyfile))
                   return (1);
   
           smime_config.keyfile = arg;
           return (0);
   }
   
   static int
   smime_opt_md(char *arg)
   {
           if ((smime_config.sign_md = EVP_get_digestbyname(arg)) == NULL) {
                   BIO_printf(bio_err, "Unknown digest %s\n", arg);
                   return (1);
           }
           return (0);
   }
   
   static int
   smime_opt_signer(char *arg)
   {
           if (smime_config.signerfile == NULL) {
                   smime_config.signerfile = arg;
                   return (0);
           }
   
           if (smime_config.sksigners == NULL) {
                   if ((smime_config.sksigners = sk_OPENSSL_STRING_new_null()) == NULL)
                           return (1);
           }
           if (!sk_OPENSSL_STRING_push(smime_config.sksigners,
               smime_config.signerfile))
                   return (1);
   
           if (smime_config.keyfile == NULL)
                   smime_config.keyfile = smime_config.signerfile;
   
           if (smime_config.skkeys == NULL) {
                   if ((smime_config.skkeys = sk_OPENSSL_STRING_new_null()) == NULL)
                           return (1);
           }
           if (!sk_OPENSSL_STRING_push(smime_config.skkeys, smime_config.keyfile))
                   return (1);
   
           smime_config.keyfile = NULL;
   
           smime_config.signerfile = arg;
           return (0);
   }
   
   static int
   smime_opt_verify_param(int argc, char **argv, int *argsused)
   {
           int oargc = argc;
           int badarg = 0;
   
           if (!args_verify(&argv, &argc, &badarg, bio_err, &smime_config.vpm))
                   return (1);
           if (badarg)
                   return (1);
   
           *argsused = oargc - argc;
   
           return (0);
   }
   
   static const struct option smime_options[] = {
   #ifndef OPENSSL_NO_AES
           {
                   .name = "aes128",
                   .desc = "Encrypt PEM output with CBC AES",
                   .type = OPTION_ARGV_FUNC,
                   .opt.argvfunc = smime_opt_cipher,
           },
           {
                   .name = "aes192",
                   .desc = "Encrypt PEM output with CBC AES",
                   .type = OPTION_ARGV_FUNC,
                   .opt.argvfunc = smime_opt_cipher,
           },
           {
                   .name = "aes256",
                   .desc = "Encrypt PEM output with CBC AES",
                   .type = OPTION_ARGV_FUNC,
                   .opt.argvfunc = smime_opt_cipher,
           },
   #endif
   #ifndef OPENSSL_NO_CAMELLIA
           {
                   .name = "camellia128",
                   .desc = "Encrypt PEM output with CBC Camellia",
                   .type = OPTION_ARGV_FUNC,
                   .opt.argvfunc = smime_opt_cipher,
           },
           {
                   .name = "camellia192",
                   .desc = "Encrypt PEM output with CBC Camellia",
                   .type = OPTION_ARGV_FUNC,
                   .opt.argvfunc = smime_opt_cipher,
           },
           {
                   .name = "camellia256",
                   .desc = "Encrypt PEM output with CBC Camellia",
                   .type = OPTION_ARGV_FUNC,
                   .opt.argvfunc = smime_opt_cipher,
           },
   #endif
   #ifndef OPENSSL_NO_DES
           {
                   .name = "des",
                   .desc = "Encrypt with DES",
                   .type = OPTION_ARGV_FUNC,
                   .opt.argvfunc = smime_opt_cipher,
           },
           {
                   .name = "des3",
                   .desc = "Encrypt with triple DES",
                   .type = OPTION_ARGV_FUNC,
                   .opt.argvfunc = smime_opt_cipher,
           },
   #endif
   #ifndef OPENSSL_NO_RC2
           {
                   .name = "rc2-40",
                   .desc = "Encrypt with RC2-40 (default)",
                   .type = OPTION_ARGV_FUNC,
                   .opt.argvfunc = smime_opt_cipher,
           },
           {
                   .name = "rc2-64",
                   .desc = "Encrypt with RC2-64",
                   .type = OPTION_ARGV_FUNC,
                   .opt.argvfunc = smime_opt_cipher,
           },
           {
                   .name = "rc2-128",
                   .desc = "Encrypt with RC2-128",
                   .type = OPTION_ARGV_FUNC,
                   .opt.argvfunc = smime_opt_cipher,
           },
   #endif
           {
                   .name = "CAfile",
                   .argname = "file",
                   .desc = "Certificate Authority file",
                   .type = OPTION_ARG,
                   .opt.arg = &smime_config.CAfile,
           },
           {
                   .name = "CApath",
                   .argname = "path",
                   .desc = "Certificate Authority path",
                   .type = OPTION_ARG,
                   .opt.arg = &smime_config.CApath,
           },
           {
                   .name = "binary",
                   .desc = "Do not translate message to text",
                   .type = OPTION_VALUE_OR,
                   .opt.value = &smime_config.flags,
                   .value = PKCS7_BINARY,
           },
           {
                   .name = "certfile",
                   .argname = "file",
                   .desc = "Other certificates file",
                   .type = OPTION_ARG,
                   .opt.arg = &smime_config.certfile,
           },
           {
                   .name = "content",
                   .argname = "file",
                   .desc = "Supply or override content for detached signature",
                   .type = OPTION_ARG,
                   .opt.arg = &smime_config.contfile,
           },
           {
                   .name = "crlfeol",
                   .desc = "Use CRLF as EOL termination instead of CR only",
                   .type = OPTION_VALUE_OR,
                   .opt.value = &smime_config.flags,
                   .value = PKCS7_CRLFEOL,
           },
           {
                   .name = "decrypt",
                   .desc = "Decrypt encrypted message",
                   .type = OPTION_VALUE,
                   .opt.value = &smime_config.operation,
                   .value = SMIME_DECRYPT,
           },
           {
                   .name = "encrypt",
                   .desc = "Encrypt message",
                   .type = OPTION_VALUE,
                   .opt.value = &smime_config.operation,
                   .value = SMIME_ENCRYPT,
           },
           {
                   .name = "from",
                   .argname = "addr",
                   .desc = "From address",
                   .type = OPTION_ARG,
                   .opt.arg = &smime_config.from,
           },
           {
                   .name = "in",
                   .argname = "file",
                   .desc = "Input file",
                   .type = OPTION_ARG,
                   .opt.arg = &smime_config.infile,
           },
           {
                   .name = "indef",
                   .desc = "Same as -stream",
                   .type = OPTION_VALUE,
                   .opt.value = &smime_config.indef,
                   .value = 1,
           },
           {
                   .name = "inform",
                   .argname = "fmt",
                   .desc = "Input format (DER, PEM or SMIME (default))",
                   .type = OPTION_ARG_FORMAT,
                   .opt.value = &smime_config.informat,
           },
           {
                   .name = "inkey",
                   .argname = "file",
                   .desc = "Input key file",
                   .type = OPTION_ARG_FUNC,
                   .opt.argfunc = smime_opt_inkey,
           },
           {
                   .name = "keyform",
                   .argname = "fmt",
                   .desc = "Input key format (DER or PEM (default))",
                   .type = OPTION_ARG_FORMAT,
                   .opt.value = &smime_config.keyform,
           },
           {
                   .name = "md",
                   .argname = "digest",
                   .desc = "Digest to use when signing or resigning",
                   .type = OPTION_ARG_FUNC,
                   .opt.argfunc = smime_opt_md,
           },
           {
                   .name = "noattr",
                   .desc = "Do not include any signed attributes",
                   .type = OPTION_VALUE_OR,
                   .opt.value = &smime_config.flags,
                   .value = PKCS7_NOATTR,
           },
           {
                   .name = "nocerts",
                   .desc = "Do not include signer's certificate when signing",
                   .type = OPTION_VALUE_OR,
                   .opt.value = &smime_config.flags,
                   .value = PKCS7_NOCERTS,
           },
           {
                   .name = "nochain",
                   .desc = "Do not chain verification of signer's certificates",
                   .type = OPTION_VALUE_OR,
                   .opt.value = &smime_config.flags,
                   .value = PKCS7_NOCHAIN,
           },
           {
                   .name = "nodetach",
                   .desc = "Use opaque signing",
                   .type = OPTION_VALUE_AND,
                   .opt.value = &smime_config.flags,
                   .value = ~PKCS7_DETACHED,
           },
           {
                   .name = "noindef",
                   .desc = "Disable streaming I/O",
                   .type = OPTION_VALUE,
                   .opt.value = &smime_config.indef,
                   .value = 0,
           },
           {
                   .name = "nointern",
                   .desc = "Do not search certificates in message for signer",
                   .type = OPTION_VALUE_OR,
                   .opt.value = &smime_config.flags,
                   .value = PKCS7_NOINTERN,
           },
           {
                   .name = "nooldmime",
                   .desc = "Output old S/MIME content type",
                   .type = OPTION_VALUE_OR,
                   .opt.value = &smime_config.flags,
                   .value = PKCS7_NOOLDMIMETYPE,
           },
           {
                   .name = "nosigs",
                   .desc = "Do not verify message signature",
                   .type = OPTION_VALUE_OR,
                   .opt.value = &smime_config.flags,
                   .value = PKCS7_NOSIGS,
           },
           {
                   .name = "nosmimecap",
                   .desc = "Omit the SMIMECapabilities attribute",
                   .type = OPTION_VALUE_OR,
                   .opt.value = &smime_config.flags,
                   .value = PKCS7_NOSMIMECAP,
           },
           {
                   .name = "noverify",
                   .desc = "Do not verify signer's certificate",
                   .type = OPTION_VALUE_OR,
                   .opt.value = &smime_config.flags,
                   .value = PKCS7_NOVERIFY,
           },
           {
                   .name = "out",
                   .argname = "file",
                   .desc = "Output file",
                   .type = OPTION_ARG,
                   .opt.arg = &smime_config.outfile,
           },
           {
                   .name = "outform",
                   .argname = "fmt",
                   .desc = "Output format (DER, PEM or SMIME (default))",
                   .type = OPTION_ARG_FORMAT,
                   .opt.value = &smime_config.outformat,
           },
           {
                   .name = "passin",
                   .argname = "src",
                   .desc = "Private key password source",
                   .type = OPTION_ARG,
                   .opt.arg = &smime_config.passargin,
           },
           {
                   .name = "pk7out",
                   .desc = "Output PKCS#7 structure",
                   .type = OPTION_VALUE,
                   .opt.value = &smime_config.operation,
                   .value = SMIME_PK7OUT,
           },
           {
                   .name = "recip",
                   .argname = "file",
                   .desc = "Recipient certificate file for decryption",
                   .type = OPTION_ARG,
                   .opt.arg = &smime_config.recipfile,
           },
           {
                   .name = "resign",
                   .desc = "Resign a signed message",
                   .type = OPTION_VALUE,
                   .opt.value = &smime_config.operation,
                   .value = SMIME_RESIGN,
           },
           {
                   .name = "sign",
                   .desc = "Sign message",
                   .type = OPTION_VALUE,
                   .opt.value = &smime_config.operation,
                   .value = SMIME_SIGN,
           },
           {
                   .name = "signer",
                   .argname = "file",
                   .desc = "Signer certificate file",
                   .type = OPTION_ARG_FUNC,
                   .opt.argfunc = smime_opt_signer,
           },
           {
                   .name = "stream",
                   .desc = "Enable streaming I/O",
                   .type = OPTION_VALUE,
                   .opt.value = &smime_config.indef,
                   .value = 1,
           },
           {
                   .name = "subject",
                   .argname = "s",
                   .desc = "Subject",
                   .type = OPTION_ARG,
                   .opt.arg = &smime_config.subject,
           },
           {
                   .name = "text",
                   .desc = "Include or delete text MIME headers",
                   .type = OPTION_VALUE_OR,
                   .opt.value = &smime_config.flags,
                   .value = PKCS7_TEXT,
           },
           {
                   .name = "to",
                   .argname = "addr",
                   .desc = "To address",
                   .type = OPTION_ARG,
                   .opt.arg = &smime_config.to,
           },
           {
                   .name = "verify",
                   .desc = "Verify signed message",
                   .type = OPTION_VALUE,
                   .opt.value = &smime_config.operation,
                   .value = SMIME_VERIFY,
           },
           {
                   .name = "check_ss_sig",
                   .type = OPTION_ARGV_FUNC,
                   .opt.argvfunc = smime_opt_verify_param,
           },
           {
                   .name = "crl_check",
                   .type = OPTION_ARGV_FUNC,
                   .opt.argvfunc = smime_opt_verify_param,
           },
           {
                   .name = "crl_check_all",
                   .type = OPTION_ARGV_FUNC,
                   .opt.argvfunc = smime_opt_verify_param,
           },
           {
                   .name = "extended_crl",
                   .type = OPTION_ARGV_FUNC,
                   .opt.argvfunc = smime_opt_verify_param,
           },
           {
                   .name = "ignore_critical",
                   .type = OPTION_ARGV_FUNC,
                   .opt.argvfunc = smime_opt_verify_param,
           },
           {
                   .name = "issuer_checks",
                   .type = OPTION_ARGV_FUNC,
                   .opt.argvfunc = smime_opt_verify_param,
           },
           {
                   .name = "policy_check",
                   .type = OPTION_ARGV_FUNC,
                   .opt.argvfunc = smime_opt_verify_param,
           },
           {
                   .name = "x509_strict",
                   .type = OPTION_ARGV_FUNC,
                   .opt.argvfunc = smime_opt_verify_param,
           },
           {
                   .name = NULL,
                   .type = OPTION_ARGV_FUNC,
                   .opt.argvfunc = smime_opt_cipher,
           },
           { NULL },
   };
   
   static const struct option verify_shared_options[] = {
           {
                   .name = "check_ss_sig",
                   .desc = "Check the root CA self-signed certificate signature",
           },
           {
                   .name = "crl_check",
                   .desc = "Enable CRL checking for the leaf certificate",
           },
           {
                   .name = "crl_check_all",
                   .desc = "Enable CRL checking for the entire certificate chain",
           },
           {
                   .name = "extended_crl",
                   .desc = "Enable extended CRL support",
           },
           {
                   .name = "ignore_critical",
                   .desc = "Disable critical extension checking",
           },
           {
                   .name = "issuer_checks",
                   .desc = "Enable debugging of certificate issuer checks",
           },
           {
                   .name = "policy_check",
                   .desc = "Enable certificate policy checking",
           },
           {
                   .name = "x509_strict",
                   .desc = "Use strict X.509 rules (disables workarounds)",
           },
           { NULL },
   };
   
   static void
   smime_usage(void)
   {
           fprintf(stderr, "usage: smime "
               "[-aes128 | -aes192 | -aes256 | -des |\n"
               "    -des3 | -rc2-40 | -rc2-64 | -rc2-128] [-binary]\n"
               "    [-CAfile file] [-CApath directory] [-certfile file]\n"
               "    [-content file]\n"
               "    [-decrypt] [-encrypt]\n"
               "    [-from addr] [-in file] [-indef]\n"
               "    [-inform der | pem | smime] [-inkey file]\n"
               "    [-keyform der | pem] [-md digest] [-noattr] [-nocerts]\n"
               "    [-nochain] [-nodetach] [-noindef] [-nointern] [-nosigs]\n"
               "    [-nosmimecap] [-noverify] [-out file]\n"
               "    [-outform der | pem | smime] [-passin arg] [-pk7out]\n"
               "    [-recip file] [-resign] [-sign]\n"
               "    [-signer file] [-stream] [-subject s] [-text] [-to addr]\n"
               "    [-verify] [cert.pem ...]\n\n");
   
           options_usage(smime_options);
   
           fprintf(stderr, "\nVerification options:\n\n");
           options_usage(verify_shared_options);
   }
   
 int  int
 smime_main(int argc, char **argv)  smime_main(int argc, char **argv)
 {  {
         int operation = 0;  
         int ret = 0;          int ret = 0;
         char **args;          char **args;
           int argsused = 0;
         const char *inmode = "r", *outmode = "w";          const char *inmode = "r", *outmode = "w";
         char *infile = NULL, *outfile = NULL;  
         char *signerfile = NULL, *recipfile = NULL;  
         STACK_OF(OPENSSL_STRING) * sksigners = NULL, *skkeys = NULL;  
         char *certfile = NULL, *keyfile = NULL, *contfile = NULL;  
         const EVP_CIPHER *cipher = NULL;  
         PKCS7 *p7 = NULL;          PKCS7 *p7 = NULL;
         X509_STORE *store = NULL;          X509_STORE *store = NULL;
         X509 *cert = NULL, *recip = NULL, *signer = NULL;          X509 *cert = NULL, *recip = NULL, *signer = NULL;
Line 101 
Line 718 
         STACK_OF(X509) * encerts = NULL, *other = NULL;          STACK_OF(X509) * encerts = NULL, *other = NULL;
         BIO *in = NULL, *out = NULL, *indata = NULL;          BIO *in = NULL, *out = NULL, *indata = NULL;
         int badarg = 0;          int badarg = 0;
         int flags = PKCS7_DETACHED;          char *passin = NULL;
         char *to = NULL, *from = NULL, *subject = NULL;  
         char *CAfile = NULL, *CApath = NULL;  
         char *passargin = NULL, *passin = NULL;  
         int indef = 0;  
         const EVP_MD *sign_md = NULL;  
         int informat = FORMAT_SMIME, outformat = FORMAT_SMIME;  
         int keyform = FORMAT_PEM;  
   
         X509_VERIFY_PARAM *vpm = NULL;  
   
         if (single_execution) {          if (single_execution) {
                 if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {                  if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
                         perror("pledge");                          perror("pledge");
Line 119 
Line 727 
                 }                  }
         }          }
   
         args = argv + 1;          memset(&smime_config, 0, sizeof(smime_config));
           smime_config.flags = PKCS7_DETACHED;
           smime_config.informat = FORMAT_SMIME;
           smime_config.outformat = FORMAT_SMIME;
           smime_config.keyform = FORMAT_PEM;
           if (options_parse(argc, argv, smime_options, NULL, &argsused) != 0) {
                   goto argerr;
           }
           args = argv + argsused;
         ret = 1;          ret = 1;
   
         while (!badarg && *args && *args[0] == '-') {          if (!(smime_config.operation & SMIME_SIGNERS) && (smime_config.skkeys || smime_config.sksigners)) {
                 if (!strcmp(*args, "-encrypt"))  
                         operation = SMIME_ENCRYPT;  
                 else if (!strcmp(*args, "-decrypt"))  
                         operation = SMIME_DECRYPT;  
                 else if (!strcmp(*args, "-sign"))  
                         operation = SMIME_SIGN;  
                 else if (!strcmp(*args, "-resign"))  
                         operation = SMIME_RESIGN;  
                 else if (!strcmp(*args, "-verify"))  
                         operation = SMIME_VERIFY;  
                 else if (!strcmp(*args, "-pk7out"))  
                         operation = SMIME_PK7OUT;  
 #ifndef OPENSSL_NO_DES  
                 else if (!strcmp(*args, "-des3"))  
                         cipher = EVP_des_ede3_cbc();  
                 else if (!strcmp(*args, "-des"))  
                         cipher = EVP_des_cbc();  
 #endif  
 #ifndef OPENSSL_NO_RC2  
                 else if (!strcmp(*args, "-rc2-40"))  
                         cipher = EVP_rc2_40_cbc();  
                 else if (!strcmp(*args, "-rc2-128"))  
                         cipher = EVP_rc2_cbc();  
                 else if (!strcmp(*args, "-rc2-64"))  
                         cipher = EVP_rc2_64_cbc();  
 #endif  
 #ifndef OPENSSL_NO_AES  
                 else if (!strcmp(*args, "-aes128"))  
                         cipher = EVP_aes_128_cbc();  
                 else if (!strcmp(*args, "-aes192"))  
                         cipher = EVP_aes_192_cbc();  
                 else if (!strcmp(*args, "-aes256"))  
                         cipher = EVP_aes_256_cbc();  
 #endif  
 #ifndef OPENSSL_NO_CAMELLIA  
                 else if (!strcmp(*args, "-camellia128"))  
                         cipher = EVP_camellia_128_cbc();  
                 else if (!strcmp(*args, "-camellia192"))  
                         cipher = EVP_camellia_192_cbc();  
                 else if (!strcmp(*args, "-camellia256"))  
                         cipher = EVP_camellia_256_cbc();  
 #endif  
                 else if (!strcmp(*args, "-text"))  
                         flags |= PKCS7_TEXT;  
                 else if (!strcmp(*args, "-nointern"))  
                         flags |= PKCS7_NOINTERN;  
                 else if (!strcmp(*args, "-noverify"))  
                         flags |= PKCS7_NOVERIFY;  
                 else if (!strcmp(*args, "-nochain"))  
                         flags |= PKCS7_NOCHAIN;  
                 else if (!strcmp(*args, "-nocerts"))  
                         flags |= PKCS7_NOCERTS;  
                 else if (!strcmp(*args, "-noattr"))  
                         flags |= PKCS7_NOATTR;  
                 else if (!strcmp(*args, "-nodetach"))  
                         flags &= ~PKCS7_DETACHED;  
                 else if (!strcmp(*args, "-nosmimecap"))  
                         flags |= PKCS7_NOSMIMECAP;  
                 else if (!strcmp(*args, "-binary"))  
                         flags |= PKCS7_BINARY;  
                 else if (!strcmp(*args, "-nosigs"))  
                         flags |= PKCS7_NOSIGS;  
                 else if (!strcmp(*args, "-stream"))  
                         indef = 1;  
                 else if (!strcmp(*args, "-indef"))  
                         indef = 1;  
                 else if (!strcmp(*args, "-noindef"))  
                         indef = 0;  
                 else if (!strcmp(*args, "-nooldmime"))  
                         flags |= PKCS7_NOOLDMIMETYPE;  
                 else if (!strcmp(*args, "-crlfeol"))  
                         flags |= PKCS7_CRLFEOL;  
                 else if (!strcmp(*args, "-passin")) {  
                         if (!args[1])  
                                 goto argerr;  
                         passargin = *++args;  
                 } else if (!strcmp(*args, "-to")) {  
                         if (!args[1])  
                                 goto argerr;  
                         to = *++args;  
                 } else if (!strcmp(*args, "-from")) {  
                         if (!args[1])  
                                 goto argerr;  
                         from = *++args;  
                 } else if (!strcmp(*args, "-subject")) {  
                         if (!args[1])  
                                 goto argerr;  
                         subject = *++args;  
                 } else if (!strcmp(*args, "-signer")) {  
                         if (!args[1])  
                                 goto argerr;  
                         /* If previous -signer argument add signer to list */  
   
                         if (signerfile) {  
                                 if (!sksigners)  
                                         sksigners = sk_OPENSSL_STRING_new_null();  
                                 sk_OPENSSL_STRING_push(sksigners, signerfile);  
                                 if (!keyfile)  
                                         keyfile = signerfile;  
                                 if (!skkeys)  
                                         skkeys = sk_OPENSSL_STRING_new_null();  
                                 sk_OPENSSL_STRING_push(skkeys, keyfile);  
                                 keyfile = NULL;  
                         }  
                         signerfile = *++args;  
                 } else if (!strcmp(*args, "-recip")) {  
                         if (!args[1])  
                                 goto argerr;  
                         recipfile = *++args;  
                 } else if (!strcmp(*args, "-md")) {  
                         if (!args[1])  
                                 goto argerr;  
                         sign_md = EVP_get_digestbyname(*++args);  
                         if (sign_md == NULL) {  
                                 BIO_printf(bio_err, "Unknown digest %s\n",  
                                     *args);  
                                 goto argerr;  
                         }  
                 } else if (!strcmp(*args, "-inkey")) {  
                         if (!args[1])  
                                 goto argerr;  
                         /* If previous -inkey arument add signer to list */  
                         if (keyfile) {  
                                 if (!signerfile) {  
                                         BIO_puts(bio_err, "Illegal -inkey without -signer\n");  
                                         goto argerr;  
                                 }  
                                 if (!sksigners)  
                                         sksigners = sk_OPENSSL_STRING_new_null();  
                                 sk_OPENSSL_STRING_push(sksigners, signerfile);  
                                 signerfile = NULL;  
                                 if (!skkeys)  
                                         skkeys = sk_OPENSSL_STRING_new_null();  
                                 sk_OPENSSL_STRING_push(skkeys, keyfile);  
                         }  
                         keyfile = *++args;  
                 } else if (!strcmp(*args, "-keyform")) {  
                         if (!args[1])  
                                 goto argerr;  
                         keyform = str2fmt(*++args);  
                 } else if (!strcmp(*args, "-certfile")) {  
                         if (!args[1])  
                                 goto argerr;  
                         certfile = *++args;  
                 } else if (!strcmp(*args, "-CAfile")) {  
                         if (!args[1])  
                                 goto argerr;  
                         CAfile = *++args;  
                 } else if (!strcmp(*args, "-CApath")) {  
                         if (!args[1])  
                                 goto argerr;  
                         CApath = *++args;  
                 } else if (!strcmp(*args, "-in")) {  
                         if (!args[1])  
                                 goto argerr;  
                         infile = *++args;  
                 } else if (!strcmp(*args, "-inform")) {  
                         if (!args[1])  
                                 goto argerr;  
                         informat = str2fmt(*++args);  
                 } else if (!strcmp(*args, "-outform")) {  
                         if (!args[1])  
                                 goto argerr;  
                         outformat = str2fmt(*++args);  
                 } else if (!strcmp(*args, "-out")) {  
                         if (!args[1])  
                                 goto argerr;  
                         outfile = *++args;  
                 } else if (!strcmp(*args, "-content")) {  
                         if (!args[1])  
                                 goto argerr;  
                         contfile = *++args;  
                 } else if (args_verify(&args, NULL, &badarg, bio_err, &vpm))  
                         continue;  
                 else if ((cipher = EVP_get_cipherbyname(*args + 1)) == NULL)  
                         badarg = 1;  
                 args++;  
         }  
   
         if (!(operation & SMIME_SIGNERS) && (skkeys || sksigners)) {  
                 BIO_puts(bio_err, "Multiple signers or keys not allowed\n");                  BIO_puts(bio_err, "Multiple signers or keys not allowed\n");
                 goto argerr;                  goto argerr;
         }          }
         if (operation & SMIME_SIGNERS) {          if (smime_config.operation & SMIME_SIGNERS) {
                 /* Check to see if any final signer needs to be appended */                  /* Check to see if any final signer needs to be appended */
                 if (keyfile && !signerfile) {                  if (smime_config.keyfile && !smime_config.signerfile) {
                         BIO_puts(bio_err, "Illegal -inkey without -signer\n");                          BIO_puts(bio_err, "Illegal -inkey without -signer\n");
                         goto argerr;                          goto argerr;
                 }                  }
                 if (signerfile) {                  if (smime_config.signerfile) {
                         if (!sksigners)                          if (!smime_config.sksigners)
                                 sksigners = sk_OPENSSL_STRING_new_null();                                  smime_config.sksigners = sk_OPENSSL_STRING_new_null();
                         sk_OPENSSL_STRING_push(sksigners, signerfile);                          sk_OPENSSL_STRING_push(smime_config.sksigners, smime_config.signerfile);
                         if (!skkeys)                          if (!smime_config.skkeys)
                                 skkeys = sk_OPENSSL_STRING_new_null();                                  smime_config.skkeys = sk_OPENSSL_STRING_new_null();
                         if (!keyfile)                          if (!smime_config.keyfile)
                                 keyfile = signerfile;                                  smime_config.keyfile = smime_config.signerfile;
                         sk_OPENSSL_STRING_push(skkeys, keyfile);                          sk_OPENSSL_STRING_push(smime_config.skkeys, smime_config.keyfile);
                 }                  }
                 if (!sksigners) {                  if (!smime_config.sksigners) {
                         BIO_printf(bio_err, "No signer certificate specified\n");                          BIO_printf(bio_err, "No signer certificate specified\n");
                         badarg = 1;                          badarg = 1;
                 }                  }
                 signerfile = NULL;                  smime_config.signerfile = NULL;
                 keyfile = NULL;                  smime_config.keyfile = NULL;
         } else if (operation == SMIME_DECRYPT) {          } else if (smime_config.operation == SMIME_DECRYPT) {
                 if (!recipfile && !keyfile) {                  if (!smime_config.recipfile && !smime_config.keyfile) {
                         BIO_printf(bio_err, "No recipient certificate or key specified\n");                          BIO_printf(bio_err, "No recipient certificate or key specified\n");
                         badarg = 1;                          badarg = 1;
                 }                  }
         } else if (operation == SMIME_ENCRYPT) {          } else if (smime_config.operation == SMIME_ENCRYPT) {
                 if (!*args) {                  if (!*args) {
                         BIO_printf(bio_err, "No recipient(s) certificate(s) specified\n");                          BIO_printf(bio_err, "No recipient(s) certificate(s) specified\n");
                         badarg = 1;                          badarg = 1;
                 }                  }
         } else if (!operation)          } else if (!smime_config.operation)
                 badarg = 1;                  badarg = 1;
   
         if (badarg) {          if (badarg) {
  argerr:   argerr:
                 BIO_printf(bio_err, "Usage smime [options] cert.pem ...\n");                  smime_usage();
                 BIO_printf(bio_err, "where options are\n");  
                 BIO_printf(bio_err, "-encrypt       encrypt message\n");  
                 BIO_printf(bio_err, "-decrypt       decrypt encrypted message\n");  
                 BIO_printf(bio_err, "-sign          sign message\n");  
                 BIO_printf(bio_err, "-verify        verify signed message\n");  
                 BIO_printf(bio_err, "-pk7out        output PKCS#7 structure\n");  
 #ifndef OPENSSL_NO_DES  
                 BIO_printf(bio_err, "-des3          encrypt with triple DES\n");  
                 BIO_printf(bio_err, "-des           encrypt with DES\n");  
 #endif  
 #ifndef OPENSSL_NO_RC2  
                 BIO_printf(bio_err, "-rc2-40        encrypt with RC2-40 (default)\n");  
                 BIO_printf(bio_err, "-rc2-64        encrypt with RC2-64\n");  
                 BIO_printf(bio_err, "-rc2-128       encrypt with RC2-128\n");  
 #endif  
 #ifndef OPENSSL_NO_AES  
                 BIO_printf(bio_err, "-aes128, -aes192, -aes256\n");  
                 BIO_printf(bio_err, "               encrypt PEM output with cbc aes\n");  
 #endif  
 #ifndef OPENSSL_NO_CAMELLIA  
                 BIO_printf(bio_err, "-camellia128, -camellia192, -camellia256\n");  
                 BIO_printf(bio_err, "               encrypt PEM output with cbc camellia\n");  
 #endif  
                 BIO_printf(bio_err, "-nointern      don't search certificates in message for signer\n");  
                 BIO_printf(bio_err, "-nosigs        don't verify message signature\n");  
                 BIO_printf(bio_err, "-noverify      don't verify signers certificate\n");  
                 BIO_printf(bio_err, "-nocerts       don't include signers certificate when signing\n");  
                 BIO_printf(bio_err, "-nodetach      use opaque signing\n");  
                 BIO_printf(bio_err, "-noattr        don't include any signed attributes\n");  
                 BIO_printf(bio_err, "-binary        don't translate message to text\n");  
                 BIO_printf(bio_err, "-certfile file other certificates file\n");  
                 BIO_printf(bio_err, "-signer file   signer certificate file\n");  
                 BIO_printf(bio_err, "-recip  file   recipient certificate file for decryption\n");  
                 BIO_printf(bio_err, "-in file       input file\n");  
                 BIO_printf(bio_err, "-inform arg    input format SMIME (default), PEM or DER\n");  
                 BIO_printf(bio_err, "-inkey file    input private key (if not signer or recipient)\n");  
                 BIO_printf(bio_err, "-keyform arg   input private key format (PEM)\n");  
                 BIO_printf(bio_err, "-out file      output file\n");  
                 BIO_printf(bio_err, "-outform arg   output format SMIME (default), PEM or DER\n");  
                 BIO_printf(bio_err, "-content file  supply or override content for detached signature\n");  
                 BIO_printf(bio_err, "-to addr       to address\n");  
                 BIO_printf(bio_err, "-from ad       from address\n");  
                 BIO_printf(bio_err, "-subject s     subject\n");  
                 BIO_printf(bio_err, "-text          include or delete text MIME headers\n");  
                 BIO_printf(bio_err, "-CApath dir    trusted certificates directory\n");  
                 BIO_printf(bio_err, "-CAfile file   trusted certificates file\n");  
                 BIO_printf(bio_err, "-crl_check     check revocation status of signer's certificate using CRLs\n");  
                 BIO_printf(bio_err, "-crl_check_all check revocation status of signer's certificate chain using CRLs\n");  
                 BIO_printf(bio_err, "-passin arg    input file pass phrase source\n");  
                 BIO_printf(bio_err, "cert.pem       recipient certificate(s) for encryption\n");  
                 goto end;                  goto end;
         }          }
   
         if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) {          if (!app_passwd(bio_err, smime_config.passargin, NULL, &passin, NULL)) {
                 BIO_printf(bio_err, "Error getting password\n");                  BIO_printf(bio_err, "Error getting password\n");
                 goto end;                  goto end;
         }          }
         ret = 2;          ret = 2;
   
         if (!(operation & SMIME_SIGNERS))          if (!(smime_config.operation & SMIME_SIGNERS))
                 flags &= ~PKCS7_DETACHED;                  smime_config.flags &= ~PKCS7_DETACHED;
   
         if (operation & SMIME_OP) {          if (smime_config.operation & SMIME_OP) {
                 if (outformat == FORMAT_ASN1)                  if (smime_config.outformat == FORMAT_ASN1)
                         outmode = "wb";                          outmode = "wb";
         } else {          } else {
                 if (flags & PKCS7_BINARY)                  if (smime_config.flags & PKCS7_BINARY)
                         outmode = "wb";                          outmode = "wb";
         }          }
   
         if (operation & SMIME_IP) {          if (smime_config.operation & SMIME_IP) {
                 if (informat == FORMAT_ASN1)                  if (smime_config.informat == FORMAT_ASN1)
                         inmode = "rb";                          inmode = "rb";
         } else {          } else {
                 if (flags & PKCS7_BINARY)                  if (smime_config.flags & PKCS7_BINARY)
                         inmode = "rb";                          inmode = "rb";
         }          }
   
         if (operation == SMIME_ENCRYPT) {          if (smime_config.operation == SMIME_ENCRYPT) {
                 if (!cipher) {                  if (!smime_config.cipher) {
 #ifndef OPENSSL_NO_RC2  #ifndef OPENSSL_NO_RC2
                         cipher = EVP_rc2_40_cbc();                          smime_config.cipher = EVP_rc2_40_cbc();
 #else  #else
                         BIO_printf(bio_err, "No cipher selected\n");                          BIO_printf(bio_err, "No cipher selected\n");
                         goto end;                          goto end;
Line 442 
Line 828 
                         args++;                          args++;
                 }                  }
         }          }
         if (certfile) {          if (smime_config.certfile) {
                 if (!(other = load_certs(bio_err, certfile, FORMAT_PEM, NULL,                  if (!(other = load_certs(bio_err, smime_config.certfile, FORMAT_PEM, NULL,
                     "certificate file"))) {                      "certificate file"))) {
                         ERR_print_errors(bio_err);                          ERR_print_errors(bio_err);
                         goto end;                          goto end;
                 }                  }
         }          }
         if (recipfile && (operation == SMIME_DECRYPT)) {          if (smime_config.recipfile && (smime_config.operation == SMIME_DECRYPT)) {
                 if (!(recip = load_cert(bio_err, recipfile, FORMAT_PEM, NULL,                  if (!(recip = load_cert(bio_err, smime_config.recipfile, FORMAT_PEM, NULL,
                     "recipient certificate file"))) {                      "recipient certificate file"))) {
                         ERR_print_errors(bio_err);                          ERR_print_errors(bio_err);
                         goto end;                          goto end;
                 }                  }
         }          }
         if (operation == SMIME_DECRYPT) {          if (smime_config.operation == SMIME_DECRYPT) {
                 if (!keyfile)                  if (!smime_config.keyfile)
                         keyfile = recipfile;                          smime_config.keyfile = smime_config.recipfile;
         } else if (operation == SMIME_SIGN) {          } else if (smime_config.operation == SMIME_SIGN) {
                 if (!keyfile)                  if (!smime_config.keyfile)
                         keyfile = signerfile;                          smime_config.keyfile = smime_config.signerfile;
         } else          } else
                 keyfile = NULL;                  smime_config.keyfile = NULL;
   
         if (keyfile) {          if (smime_config.keyfile) {
                 key = load_key(bio_err, keyfile, keyform, 0, passin,                  key = load_key(bio_err, smime_config.keyfile, smime_config.keyform, 0, passin,
                     "signing key file");                      "signing key file");
                 if (!key)                  if (!key)
                         goto end;                          goto end;
         }          }
         if (infile) {          if (smime_config.infile) {
                 if (!(in = BIO_new_file(infile, inmode))) {                  if (!(in = BIO_new_file(smime_config.infile, inmode))) {
                         BIO_printf(bio_err,                          BIO_printf(bio_err,
                             "Can't open input file %s\n", infile);                              "Can't open input file %s\n", smime_config.infile);
                         goto end;                          goto end;
                 }                  }
         } else          } else
                 in = BIO_new_fp(stdin, BIO_NOCLOSE);                  in = BIO_new_fp(stdin, BIO_NOCLOSE);
   
         if (operation & SMIME_IP) {          if (smime_config.operation & SMIME_IP) {
                 if (informat == FORMAT_SMIME)                  if (smime_config.informat == FORMAT_SMIME)
                         p7 = SMIME_read_PKCS7(in, &indata);                          p7 = SMIME_read_PKCS7(in, &indata);
                 else if (informat == FORMAT_PEM)                  else if (smime_config.informat == FORMAT_PEM)
                         p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL);                          p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL);
                 else if (informat == FORMAT_ASN1)                  else if (smime_config.informat == FORMAT_ASN1)
                         p7 = d2i_PKCS7_bio(in, NULL);                          p7 = d2i_PKCS7_bio(in, NULL);
                 else {                  else {
                         BIO_printf(bio_err, "Bad input format for PKCS#7 file\n");                          BIO_printf(bio_err, "Bad input format for PKCS#7 file\n");
Line 496 
Line 882 
                         BIO_printf(bio_err, "Error reading S/MIME message\n");                          BIO_printf(bio_err, "Error reading S/MIME message\n");
                         goto end;                          goto end;
                 }                  }
                 if (contfile) {                  if (smime_config.contfile) {
                         BIO_free(indata);                          BIO_free(indata);
                         if (!(indata = BIO_new_file(contfile, "rb"))) {                          if (!(indata = BIO_new_file(smime_config.contfile, "rb"))) {
                                 BIO_printf(bio_err, "Can't read content file %s\n", contfile);                                  BIO_printf(bio_err, "Can't read content file %s\n", smime_config.contfile);
                                 goto end;                                  goto end;
                         }                          }
                 }                  }
         }          }
         if (outfile) {          if (smime_config.outfile) {
                 if (!(out = BIO_new_file(outfile, outmode))) {                  if (!(out = BIO_new_file(smime_config.outfile, outmode))) {
                         BIO_printf(bio_err,                          BIO_printf(bio_err,
                             "Can't open output file %s\n", outfile);                              "Can't open output file %s\n", smime_config.outfile);
                         goto end;                          goto end;
                 }                  }
         } else {          } else {
                 out = BIO_new_fp(stdout, BIO_NOCLOSE);                  out = BIO_new_fp(stdout, BIO_NOCLOSE);
         }          }
   
         if (operation == SMIME_VERIFY) {          if (smime_config.operation == SMIME_VERIFY) {
                 if (!(store = setup_verify(bio_err, CAfile, CApath)))                  if (!(store = setup_verify(bio_err, smime_config.CAfile, smime_config.CApath)))
                         goto end;                          goto end;
                 X509_STORE_set_verify_cb(store, smime_cb);                  X509_STORE_set_verify_cb(store, smime_cb);
                 if (vpm)                  if (smime_config.vpm)
                         X509_STORE_set1_param(store, vpm);                          X509_STORE_set1_param(store, smime_config.vpm);
         }          }
         ret = 3;          ret = 3;
   
         if (operation == SMIME_ENCRYPT) {          if (smime_config.operation == SMIME_ENCRYPT) {
                 if (indef)                  if (smime_config.indef)
                         flags |= PKCS7_STREAM;                          smime_config.flags |= PKCS7_STREAM;
                 p7 = PKCS7_encrypt(encerts, in, cipher, flags);                  p7 = PKCS7_encrypt(encerts, in, smime_config.cipher, smime_config.flags);
         } else if (operation & SMIME_SIGNERS) {          } else if (smime_config.operation & SMIME_SIGNERS) {
                 int i;                  int i;
                 /*                  /*
                  * If detached data content we only enable streaming if                   * If detached data content we only enable streaming if
                  * S/MIME output format.                   * S/MIME output format.
                  */                   */
                 if (operation == SMIME_SIGN) {                  if (smime_config.operation == SMIME_SIGN) {
                         if (flags & PKCS7_DETACHED) {                          if (smime_config.flags & PKCS7_DETACHED) {
                                 if (outformat == FORMAT_SMIME)                                  if (smime_config.outformat == FORMAT_SMIME)
                                         flags |= PKCS7_STREAM;                                          smime_config.flags |= PKCS7_STREAM;
                         } else if (indef)                          } else if (smime_config.indef)
                                 flags |= PKCS7_STREAM;                                  smime_config.flags |= PKCS7_STREAM;
                         flags |= PKCS7_PARTIAL;                          smime_config.flags |= PKCS7_PARTIAL;
                         p7 = PKCS7_sign(NULL, NULL, other, in, flags);                          p7 = PKCS7_sign(NULL, NULL, other, in, smime_config.flags);
                         if (!p7)                          if (!p7)
                                 goto end;                                  goto end;
                 } else                  } else
                         flags |= PKCS7_REUSE_DIGEST;                          smime_config.flags |= PKCS7_REUSE_DIGEST;
                 for (i = 0; i < sk_OPENSSL_STRING_num(sksigners); i++) {                  for (i = 0; i < sk_OPENSSL_STRING_num(smime_config.sksigners); i++) {
                         signerfile = sk_OPENSSL_STRING_value(sksigners, i);                          smime_config.signerfile = sk_OPENSSL_STRING_value(smime_config.sksigners, i);
                         keyfile = sk_OPENSSL_STRING_value(skkeys, i);                          smime_config.keyfile = sk_OPENSSL_STRING_value(smime_config.skkeys, i);
                         signer = load_cert(bio_err, signerfile, FORMAT_PEM, NULL,                          signer = load_cert(bio_err, smime_config.signerfile, FORMAT_PEM, NULL,
                             "signer certificate");                              "signer certificate");
                         if (!signer)                          if (!signer)
                                 goto end;                                  goto end;
                         key = load_key(bio_err, keyfile, keyform, 0, passin,                          key = load_key(bio_err, smime_config.keyfile, smime_config.keyform, 0, passin,
                             "signing key file");                              "signing key file");
                         if (!key)                          if (!key)
                                 goto end;                                  goto end;
                         if (!PKCS7_sign_add_signer(p7, signer, key,                          if (!PKCS7_sign_add_signer(p7, signer, key,
                                 sign_md, flags))                                  smime_config.sign_md, smime_config.flags))
                                 goto end;                                  goto end;
                         X509_free(signer);                          X509_free(signer);
                         signer = NULL;                          signer = NULL;
Line 565 
Line 951 
                         key = NULL;                          key = NULL;
                 }                  }
                 /* If not streaming or resigning finalize structure */                  /* If not streaming or resigning finalize structure */
                 if ((operation == SMIME_SIGN) && !(flags & PKCS7_STREAM)) {                  if ((smime_config.operation == SMIME_SIGN) && !(smime_config.flags & PKCS7_STREAM)) {
                         if (!PKCS7_final(p7, in, flags))                          if (!PKCS7_final(p7, in, smime_config.flags))
                                 goto end;                                  goto end;
                 }                  }
         }          }
Line 575 
Line 961 
                 goto end;                  goto end;
         }          }
         ret = 4;          ret = 4;
         if (operation == SMIME_DECRYPT) {          if (smime_config.operation == SMIME_DECRYPT) {
                 if (!PKCS7_decrypt(p7, key, recip, out, flags)) {                  if (!PKCS7_decrypt(p7, key, recip, out, smime_config.flags)) {
                         BIO_printf(bio_err, "Error decrypting PKCS#7 structure\n");                          BIO_printf(bio_err, "Error decrypting PKCS#7 structure\n");
                         goto end;                          goto end;
                 }                  }
         } else if (operation == SMIME_VERIFY) {          } else if (smime_config.operation == SMIME_VERIFY) {
                 STACK_OF(X509) * signers;                  STACK_OF(X509) * signers;
                 if (PKCS7_verify(p7, other, store, indata, out, flags))                  if (PKCS7_verify(p7, other, store, indata, out, smime_config.flags))
                         BIO_printf(bio_err, "Verification successful\n");                          BIO_printf(bio_err, "Verification successful\n");
                 else {                  else {
                         BIO_printf(bio_err, "Verification failure\n");                          BIO_printf(bio_err, "Verification failure\n");
                         goto end;                          goto end;
                 }                  }
                 signers = PKCS7_get0_signers(p7, other, flags);                  signers = PKCS7_get0_signers(p7, other, smime_config.flags);
                 if (!save_certs(signerfile, signers)) {                  if (!save_certs(smime_config.signerfile, signers)) {
                         BIO_printf(bio_err, "Error writing signers to %s\n",                          BIO_printf(bio_err, "Error writing signers to %s\n",
                             signerfile);                              smime_config.signerfile);
                         ret = 5;                          ret = 5;
                         goto end;                          goto end;
                 }                  }
                 sk_X509_free(signers);                  sk_X509_free(signers);
         } else if (operation == SMIME_PK7OUT)          } else if (smime_config.operation == SMIME_PK7OUT)
                 PEM_write_bio_PKCS7(out, p7);                  PEM_write_bio_PKCS7(out, p7);
         else {          else {
                 if (to)                  if (smime_config.to)
                         BIO_printf(out, "To: %s\n", to);                          BIO_printf(out, "To: %s\n", smime_config.to);
                 if (from)                  if (smime_config.from)
                         BIO_printf(out, "From: %s\n", from);                          BIO_printf(out, "From: %s\n", smime_config.from);
                 if (subject)                  if (smime_config.subject)
                         BIO_printf(out, "Subject: %s\n", subject);                          BIO_printf(out, "Subject: %s\n", smime_config.subject);
                 if (outformat == FORMAT_SMIME) {                  if (smime_config.outformat == FORMAT_SMIME) {
                         if (operation == SMIME_RESIGN)                          if (smime_config.operation == SMIME_RESIGN)
                                 SMIME_write_PKCS7(out, p7, indata, flags);                                  SMIME_write_PKCS7(out, p7, indata, smime_config.flags);
                         else                          else
                                 SMIME_write_PKCS7(out, p7, in, flags);                                  SMIME_write_PKCS7(out, p7, in, smime_config.flags);
                 } else if (outformat == FORMAT_PEM)                  } else if (smime_config.outformat == FORMAT_PEM)
                         PEM_write_bio_PKCS7_stream(out, p7, in, flags);                          PEM_write_bio_PKCS7_stream(out, p7, in, smime_config.flags);
                 else if (outformat == FORMAT_ASN1)                  else if (smime_config.outformat == FORMAT_ASN1)
                         i2d_PKCS7_bio_stream(out, p7, in, flags);                          i2d_PKCS7_bio_stream(out, p7, in, smime_config.flags);
                 else {                  else {
                         BIO_printf(bio_err, "Bad output format for PKCS#7 file\n");                          BIO_printf(bio_err, "Bad output format for PKCS#7 file\n");
                         goto end;                          goto end;
Line 625 
Line 1011 
                 ERR_print_errors(bio_err);                  ERR_print_errors(bio_err);
         sk_X509_pop_free(encerts, X509_free);          sk_X509_pop_free(encerts, X509_free);
         sk_X509_pop_free(other, X509_free);          sk_X509_pop_free(other, X509_free);
         X509_VERIFY_PARAM_free(vpm);          X509_VERIFY_PARAM_free(smime_config.vpm);
         sk_OPENSSL_STRING_free(sksigners);          sk_OPENSSL_STRING_free(smime_config.sksigners);
         sk_OPENSSL_STRING_free(skkeys);          sk_OPENSSL_STRING_free(smime_config.skkeys);
         X509_STORE_free(store);          X509_STORE_free(store);
         X509_free(cert);          X509_free(cert);
         X509_free(recip);          X509_free(recip);
Line 677 
Line 1063 
         return ok;          return ok;
   
 }  }
   

Legend:
Removed from v.1.10  
changed lines
  Added in v.1.11