add OSSL_STACK_OF_X509_free() for commonly used pattern
[openssl.git] / apps / smime.c
index 07abcbf8c93dc93d0bad9ee5eb90c7e2bc9e3157..9677f056ed229ddf6af33a6a9eae90537e12444d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -33,7 +33,7 @@ static int smime_cb(int ok, X509_STORE_CTX *ctx);
 #define SMIME_RESIGN    (6 | SMIME_IP | SMIME_OP | SMIME_SIGNERS)
 
 typedef enum OPTION_choice {
-    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+    OPT_COMMON,
     OPT_ENCRYPT, OPT_DECRYPT, OPT_SIGN, OPT_RESIGN, OPT_VERIFY,
     OPT_PK7OUT, OPT_TEXT, OPT_NOINTERN, OPT_NOVERIFY, OPT_NOCHAIN,
     OPT_NOCERTS, OPT_NOATTR, OPT_NODETACH, OPT_NOSMIMECAP,
@@ -140,22 +140,22 @@ int smime_main(int argc, char **argv)
     X509 *cert = NULL, *recip = NULL, *signer = NULL;
     X509_STORE *store = NULL;
     X509_VERIFY_PARAM *vpm = NULL;
-    const EVP_CIPHER *cipher = NULL;
-    const EVP_MD *sign_md = NULL;
+    EVP_CIPHER *cipher = NULL;
+    EVP_MD *sign_md = NULL;
     const char *CAfile = NULL, *CApath = NULL, *CAstore = NULL, *prog = NULL;
     char *certfile = NULL, *keyfile = NULL, *contfile = NULL;
     char *infile = NULL, *outfile = NULL, *signerfile = NULL, *recipfile = NULL;
-    char *passinarg = NULL, *passin = NULL, *to = NULL, *from = NULL, *subject = NULL;
+    char *passinarg = NULL, *passin = NULL, *to = NULL, *from = NULL;
+    char *subject = NULL, *digestname = NULL, *ciphername = NULL;
     OPTION_CHOICE o;
     int noCApath = 0, noCAfile = 0, noCAstore = 0;
     int flags = PKCS7_DETACHED, operation = 0, ret = 0, indef = 0;
     int informat = FORMAT_SMIME, outformat = FORMAT_SMIME, keyform =
-        FORMAT_PEM;
+        FORMAT_UNDEF;
     int vpmtouched = 0, rv = 0;
     ENGINE *e = NULL;
     const char *mime_eol = "\n";
     OSSL_LIB_CTX *libctx = app_get0_libctx();
-    const char *propq = app_get0_propq();
 
     if ((vpm = X509_VERIFY_PARAM_new()) == NULL)
         return 1;
@@ -294,12 +294,10 @@ int smime_main(int argc, char **argv)
             recipfile = opt_arg();
             break;
         case OPT_MD:
-            if (!opt_md(opt_arg(), &sign_md))
-                goto opthelp;
+            digestname = opt_arg();
             break;
         case OPT_CIPHER:
-            if (!opt_cipher(opt_unknown(), &cipher))
-                goto opthelp;
+            ciphername = opt_unknown();
             break;
         case OPT_INKEY:
             /* If previous -inkey argument add signer to list */
@@ -361,6 +359,15 @@ int smime_main(int argc, char **argv)
     argc = opt_num_rest();
     argv = opt_rest();
 
+    if (!app_RAND_load())
+        goto end;
+
+    if (digestname != NULL) {
+        if (!opt_md(digestname, &sign_md))
+            goto opthelp;
+    }
+    if (!opt_cipher_any(ciphername, &cipher))
+            goto opthelp;
     if (!(operation & SMIME_SIGNERS) && (skkeys != NULL || sksigners != NULL)) {
         BIO_puts(bio_err, "Multiple signers or keys not allowed\n");
         goto opthelp;
@@ -430,7 +437,7 @@ int smime_main(int argc, char **argv)
     if (operation == SMIME_ENCRYPT) {
         if (cipher == NULL) {
 #ifndef OPENSSL_NO_DES
-            cipher = EVP_des_ede3_cbc();
+            cipher = (EVP_CIPHER *)EVP_des_ede3_cbc();
 #else
             BIO_printf(bio_err, "No cipher selected\n");
             goto end;
@@ -440,7 +447,8 @@ int smime_main(int argc, char **argv)
         if (encerts == NULL)
             goto end;
         while (*argv != NULL) {
-            cert = load_cert(*argv, "recipient certificate file");
+            cert = load_cert(*argv, FORMAT_UNDEF,
+                             "recipient certificate file");
             if (cert == NULL)
                 goto end;
             sk_X509_push(encerts, cert);
@@ -450,14 +458,14 @@ int smime_main(int argc, char **argv)
     }
 
     if (certfile != NULL) {
-        if (!load_certs(certfile, &other, NULL, "certificates")) {
+        if (!load_certs(certfile, 0, &other, NULL, "certificates")) {
             ERR_print_errors(bio_err);
             goto end;
         }
     }
 
     if (recipfile != NULL && (operation == SMIME_DECRYPT)) {
-        if ((recip = load_cert(recipfile,
+        if ((recip = load_cert(recipfile, FORMAT_UNDEF,
                                "recipient certificate file")) == NULL) {
             ERR_print_errors(bio_err);
             goto end;
@@ -487,7 +495,7 @@ int smime_main(int argc, char **argv)
     if (operation & SMIME_IP) {
         PKCS7 *p7_in = NULL;
 
-        p7 = PKCS7_new_ex(libctx, propq);
+        p7 = PKCS7_new_ex(libctx, app_get0_propq());
         if (p7 == NULL) {
             BIO_printf(bio_err, "Error allocating PKCS7 object\n");
             goto end;
@@ -534,7 +542,7 @@ int smime_main(int argc, char **argv)
     if (operation == SMIME_ENCRYPT) {
         if (indef)
             flags |= PKCS7_STREAM;
-        p7 = PKCS7_encrypt_ex(encerts, in, cipher, flags, libctx, propq);
+        p7 = PKCS7_encrypt_ex(encerts, in, cipher, flags, libctx, app_get0_propq());
     } else if (operation & SMIME_SIGNERS) {
         int i;
         /*
@@ -549,7 +557,7 @@ int smime_main(int argc, char **argv)
                 flags |= PKCS7_STREAM;
             }
             flags |= PKCS7_PARTIAL;
-            p7 = PKCS7_sign_ex(NULL, NULL, other, in, flags, libctx, propq);
+            p7 = PKCS7_sign_ex(NULL, NULL, other, in, flags, libctx, app_get0_propq());
             if (p7 == NULL)
                 goto end;
             if (flags & PKCS7_NOCERTS) {
@@ -564,7 +572,7 @@ int smime_main(int argc, char **argv)
         for (i = 0; i < sk_OPENSSL_STRING_num(sksigners); i++) {
             signerfile = sk_OPENSSL_STRING_value(sksigners, i);
             keyfile = sk_OPENSSL_STRING_value(skkeys, i);
-            signer = load_cert(signerfile, "signer certificate");
+            signer = load_cert(signerfile, FORMAT_UNDEF, "signer certificate");
             if (signer == NULL)
                 goto end;
             key = load_key(keyfile, keyform, 0, passin, e, "signing key");
@@ -643,8 +651,8 @@ int smime_main(int argc, char **argv)
  end:
     if (ret)
         ERR_print_errors(bio_err);
-    sk_X509_pop_free(encerts, X509_free);
-    sk_X509_pop_free(other, X509_free);
+    OSSL_STACK_OF_X509_free(encerts);
+    OSSL_STACK_OF_X509_free(other);
     X509_VERIFY_PARAM_free(vpm);
     sk_OPENSSL_STRING_free(sksigners);
     sk_OPENSSL_STRING_free(skkeys);
@@ -653,6 +661,8 @@ int smime_main(int argc, char **argv)
     X509_free(recip);
     X509_free(signer);
     EVP_PKEY_free(key);
+    EVP_MD_free(sign_md);
+    EVP_CIPHER_free(cipher);
     PKCS7_free(p7);
     release_engine(e);
     BIO_free(in);