]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
APPS: Add check for multiple 'unknown' options
authorDr. David von Oheimb <David.von.Oheimb@siemens.com>
Tue, 24 Aug 2021 10:03:12 +0000 (12:03 +0200)
committerDr. David von Oheimb <dev@ddvo.net>
Tue, 11 Jan 2022 11:45:33 +0000 (12:45 +0100)
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
(Merged from https://github.com/openssl/openssl/pull/16416)

21 files changed:
apps/cms.c
apps/crl.c
apps/dgst.c
apps/dsa.c
apps/ec.c
apps/enc.c
apps/gendsa.c
apps/genpkey.c
apps/genrsa.c
apps/include/opt.h
apps/lib/opt.c
apps/ocsp.c
apps/pkcs12.c
apps/pkey.c
apps/req.c
apps/rsa.c
apps/smime.c
apps/storeutl.c
apps/ts.c
apps/x509.c
doc/man1/openssl-ocsp.pod.in

index b49d1e3a68894acc0cd2ce0a48979312f4b8ba81..575f8b36251e7347772673a44d595f0b1d1ff7e0 100644 (file)
@@ -314,6 +314,7 @@ int cms_main(int argc, char **argv)
     if (encerts == NULL || vpm == NULL)
         goto end;
 
+    opt_set_unknown_name("cipher");
     prog = opt_init(argc, argv, cms_options);
     while ((o = opt_next()) != OPT_EOF) {
         switch (o) {
index 8d353ff2af6599ddc39ddaea31e982d549f01ee5..c8f0981ee79905b8c436f5feed963484faecaf6c 100644 (file)
@@ -98,6 +98,7 @@ int crl_main(int argc, char **argv)
     int hash_old = 0;
 #endif
 
+    opt_set_unknown_name("digest");
     prog = opt_init(argc, argv, crl_options);
     while ((o = opt_next()) != OPT_EOF) {
         switch (o) {
index e75dd725211b2dac86a4417fe2710a8362947c4e..18ba3d41c5f1adc0eb11f490c78de669a26e395f 100644 (file)
@@ -115,6 +115,7 @@ int dgst_main(int argc, char **argv)
     buf = app_malloc(BUFSIZE, "I/O buffer");
     md = (EVP_MD *)EVP_get_digestbyname(argv[0]);
 
+    opt_set_unknown_name("digest");
     prog = opt_init(argc, argv, dgst_options);
     while ((o = opt_next()) != OPT_EOF) {
         switch (o) {
index 9605ed81e7c319b3c226df49b0f613fcab00a459..fae277b8a252d5c8d4db6631177ec7d42158a1d9 100644 (file)
@@ -92,6 +92,7 @@ int dsa_main(int argc, char **argv)
     int selection = 0;
     OSSL_ENCODER_CTX *ectx = NULL;
 
+    opt_set_unknown_name("cipher");
     prog = opt_init(argc, argv, dsa_options);
     while ((o = opt_next()) != OPT_EOF) {
         switch (o) {
index 4573300a5e7eb3e54de49e78cea527a397198093..2c350ff0b4a0bc8dd69ab722008c7926d6198f4c 100644 (file)
--- a/apps/ec.c
+++ b/apps/ec.c
@@ -80,6 +80,7 @@ int ec_main(int argc, char **argv)
     char *point_format = NULL;
     int no_public = 0;
 
+    opt_set_unknown_name("cipher");
     prog = opt_init(argc, argv, ec_options);
     while ((o = opt_next()) != OPT_EOF) {
         switch (o) {
index e71453c3c4adcb81b5bfb34ae0d08c301d0405f8..b14129d9b0fe461c6c5a10cc5026eae49d8a4be1 100644 (file)
@@ -143,6 +143,7 @@ int enc_main(int argc, char **argv)
     else if (strcmp(argv[0], "enc") != 0)
         ciphername = argv[0];
 
+    opt_set_unknown_name("cipher");
     prog = opt_init(argc, argv, enc_options);
     while ((o = opt_next()) != OPT_EOF) {
         switch (o) {
index b9bc2f502b33f538e165511394aea7e05cd9622e..c4070c9e1a71f333a111a7e6f0e125b8c74b6181 100644 (file)
@@ -62,6 +62,7 @@ int gendsa_main(int argc, char **argv)
     OPTION_CHOICE o;
     int ret = 1, private = 0, verbose = 0, nbits;
 
+    opt_set_unknown_name("cipher");
     prog = opt_init(argc, argv, gendsa_options);
     while ((o = opt_next()) != OPT_EOF) {
         switch (o) {
index 7f70a6baa28f3e19076cb7c3dbc7092fc38f0d8d..f4c8f92c34b92c712dc57a0aa7e9562bc7907cff 100644 (file)
@@ -74,6 +74,7 @@ int genpkey_main(int argc, char **argv)
     OSSL_LIB_CTX *libctx = app_get0_libctx();
     STACK_OF(OPENSSL_STRING) *keyopt = NULL;
 
+    opt_set_unknown_name("cipher");
     prog = opt_init(argc, argv, genpkey_options);
     keyopt = sk_OPENSSL_STRING_new_null();
     if (keyopt == NULL)
index 1a6c67380f7ed13d66a3e89e0828563a0196f424..9d0fea76460142145cbbc9465f32809d174dc06c 100644 (file)
@@ -93,6 +93,7 @@ int genrsa_main(int argc, char **argv)
     if (bn == NULL || cb == NULL)
         goto end;
 
+    opt_set_unknown_name("cipher");
     prog = opt_init(argc, argv, genrsa_options);
     while ((o = opt_next()) != OPT_EOF) {
         switch (o) {
index 9493901c44d377fe2b6730b655ff5b06d195a627..365eae5bc845259142728d55404e5659726c3cda 100644 (file)
@@ -365,6 +365,7 @@ int opt_next(void);
 char *opt_flag(void);
 char *opt_arg(void);
 char *opt_unknown(void);
+void reset_unknown(void);
 int opt_cipher(const char *name, EVP_CIPHER **cipherp);
 int opt_cipher_any(const char *name, EVP_CIPHER **cipherp);
 int opt_cipher_silent(const char *name, EVP_CIPHER **cipherp);
@@ -373,6 +374,7 @@ int opt_md(const char *name, EVP_MD **mdp);
 int opt_md_silent(const char *name, EVP_MD **mdp);
 
 int opt_int(const char *arg, int *result);
+void opt_set_unknown_name(const char *name);
 int opt_int_arg(void);
 int opt_long(const char *arg, long *result);
 int opt_ulong(const char *arg, unsigned long *result);
index 7967fa795631b92017794ce97a9fc0bec95891ea..2865a1eefbfdae476b82e56f313685ac6c810f2a 100644 (file)
@@ -41,6 +41,7 @@ static int opt_index;
 static char *arg;
 static char *flag;
 static char *dunno;
+static const char *unknown_name;
 static const OPTIONS *unknown;
 static const OPTIONS *opts;
 static char prog[40];
@@ -166,7 +167,6 @@ char *opt_init(int ac, char **av, const OPTIONS *o)
     opt_begin();
     opts = o;
     unknown = NULL;
-
     /* Make sure prog name is set for usage output */
     (void)opt_progname(argv[0]);
 
@@ -215,6 +215,7 @@ char *opt_init(int ac, char **av, const OPTIONS *o)
         }
 #endif
         if (o->name[0] == '\0') {
+            OPENSSL_assert(unknown_name != NULL);
             OPENSSL_assert(unknown == NULL);
             unknown = o;
             OPENSSL_assert(unknown->valtype == 0 || unknown->valtype == '-');
@@ -236,6 +237,11 @@ static OPT_PAIR formats[] = {
     {NULL}
 };
 
+void opt_set_unknown_name(const char *name)
+{
+    unknown_name = name;
+}
+
 /* Print an error message about a failed format parse. */
 static int opt_format_error(const char *s, unsigned long flags)
 {
@@ -985,6 +991,11 @@ int opt_next(void)
         return o->retval;
     }
     if (unknown != NULL) {
+        if (dunno != NULL) {
+            opt_printf_stderr("%s: Multiple %s or unknown options: -%s and -%s\n",
+                              prog, unknown_name, dunno, p);
+            return -1;
+        }
         dunno = p;
         return unknown->retval;
     }
@@ -1010,6 +1021,12 @@ char *opt_unknown(void)
     return dunno;
 }
 
+/* Reset the unknown option; needed by ocsp to allow multiple digest options. */
+void reset_unknown(void)
+{
+    dunno = NULL;
+}
+
 /* Return the rest of the arguments after parsing flags. */
 char **opt_rest(void)
 {
index d8e45ccd4388ba5510f8738cc37841782ec6c694..18e7c441916137a6443266393dd6ce698c7322b0 100644 (file)
@@ -196,8 +196,10 @@ const OPTIONS ocsp_options[] = {
     {"VAfile", OPT_VAFILE, '<', "Validator certificates file"},
     {"verify_other", OPT_VERIFY_OTHER, '<',
      "Additional certificates to search for signer"},
-    {"cert", OPT_CERT, '<', "Certificate to check"},
-    {"serial", OPT_SERIAL, 's', "Serial number to check"},
+    {"cert", OPT_CERT, '<',
+     "Certificate to check; may be given multiple times"},
+    {"serial", OPT_SERIAL, 's',
+     "Serial number to check; may be given multiple times"},
     {"validity_period", OPT_VALIDITY_PERIOD, 'u',
      "Maximum validity discrepancy in seconds"},
     {"signkey", OPT_SIGNKEY, 's', "Private key to sign OCSP request with"},
@@ -261,6 +263,7 @@ int ocsp_main(int argc, char **argv)
             || (vpm = X509_VERIFY_PARAM_new()) == NULL)
         goto end;
 
+    opt_set_unknown_name("digest");
     prog = opt_init(argc, argv, ocsp_options);
     while ((o = opt_next()) != OPT_EOF) {
         switch (o) {
@@ -436,6 +439,7 @@ int ocsp_main(int argc, char **argv)
                 goto end;
             break;
         case OPT_CERT:
+            reset_unknown();
             X509_free(cert);
             cert = load_cert(opt_arg(), FORMAT_UNDEF, "certificate");
             if (cert == NULL)
@@ -449,6 +453,7 @@ int ocsp_main(int argc, char **argv)
             trailing_md = 0;
             break;
         case OPT_SERIAL:
+            reset_unknown();
             if (cert_id_md == NULL)
                 cert_id_md = (EVP_MD *)EVP_sha1();
             if (!add_ocsp_serial(&req, opt_arg(), cert_id_md, issuer, ids))
index 08af7bf3d2a8dab9154056fae37597e26cbbf80c..754994e6a9a9a31d74f548b8bdb7355e8e9a4dfb 100644 (file)
@@ -182,6 +182,7 @@ int pkcs12_main(int argc, char **argv)
     EVP_CIPHER *enc = (EVP_CIPHER *)default_enc;
     OPTION_CHOICE o;
 
+    opt_set_unknown_name("cipher");
     prog = opt_init(argc, argv, pkcs12_options);
     while ((o = opt_next()) != OPT_EOF) {
         switch (o) {
index 41a4c29897a611aa72b5ecdb3d33f2ce7089a962..cfef85ec0e4ea69efeb2bfbe3ffd36402016b80e 100644 (file)
@@ -83,6 +83,7 @@ int pkey_main(int argc, char **argv)
     char *point_format = NULL;
 #endif
 
+    opt_set_unknown_name("cipher");
     prog = opt_init(argc, argv, pkey_options);
     while ((o = opt_next()) != OPT_EOF) {
         switch (o) {
index 36ac4938078b3c5ab97c6f59075dd176221bbea0..eaff69faa4846a94bee3f945a5aed681c97f7b8d 100644 (file)
@@ -266,6 +266,7 @@ int req_main(int argc, char **argv)
     cipher = (EVP_CIPHER *)EVP_des_ede3_cbc();
 #endif
 
+    opt_set_unknown_name("digest");
     prog = opt_init(argc, argv, req_options);
     while ((o = opt_next()) != OPT_EOF) {
         switch (o) {
index fb73173428cdb6eedd2ba687b6256b8e90827ab7..08527f63478008ef6a78a0414843f86c74052948 100644 (file)
@@ -139,6 +139,7 @@ int rsa_main(int argc, char **argv)
     int selection = 0;
     OSSL_ENCODER_CTX *ectx = NULL;
 
+    opt_set_unknown_name("cipher");
     prog = opt_init(argc, argv, rsa_options);
     while ((o = opt_next()) != OPT_EOF) {
         switch (o) {
index 9677f056ed229ddf6af33a6a9eae90537e12444d..6001d444ff393f70410413bf2ce4bce710861087 100644 (file)
@@ -160,6 +160,7 @@ int smime_main(int argc, char **argv)
     if ((vpm = X509_VERIFY_PARAM_new()) == NULL)
         return 1;
 
+    opt_set_unknown_name("cipher");
     prog = opt_init(argc, argv, smime_options);
     while ((o = opt_next()) != OPT_EOF) {
         switch (o) {
index 8d1ce3cea338393bcf9f5a203b18df7f054f8f9e..65444fc53eada2397a8b3901bc796031a3e514e9 100644 (file)
@@ -74,7 +74,7 @@ int storeutl_main(int argc, char *argv[])
     BIO *out = NULL;
     ENGINE *e = NULL;
     OPTION_CHOICE o;
-    char *prog = opt_init(argc, argv, storeutl_options);
+    char *prog;
     PW_CB_DATA pw_cb_data;
     int expected = 0;
     int criterion = 0;
@@ -87,6 +87,8 @@ int storeutl_main(int argc, char *argv[])
     EVP_MD *digest = NULL;
     OSSL_LIB_CTX *libctx = app_get0_libctx();
 
+    opt_set_unknown_name("digest");
+    prog = opt_init(argc, argv, storeutl_options);
     while ((o = opt_next()) != OPT_EOF) {
         switch (o) {
         case OPT_EOF:
index 8e58ef00b4d66500228d9a6676770c9d62bb88cc..2497c3b32a7c222d2059da382a441edf54d9068b 100644 (file)
--- a/apps/ts.c
+++ b/apps/ts.c
@@ -181,6 +181,7 @@ int ts_main(int argc, char **argv)
     if ((vpm = X509_VERIFY_PARAM_new()) == NULL)
         goto end;
 
+    opt_set_unknown_name("digest");
     prog = opt_init(argc, argv, ts_options);
     while ((o = opt_next()) != OPT_EOF) {
         switch (o) {
index 188bc17a09ff87333f2737166afb2fa399ad09b9..29dc74ca9e9648c5fcdb7496c2a53330ae96b4cc 100644 (file)
@@ -302,6 +302,7 @@ int x509_main(int argc, char **argv)
         goto err;
     X509_STORE_set_verify_cb(ctx, callb);
 
+    opt_set_unknown_name("digest");
     prog = opt_init(argc, argv, x509_options);
     while ((o = opt_next()) != OPT_EOF) {
         switch (o) {
@@ -592,7 +593,6 @@ int x509_main(int argc, char **argv)
             break;
         }
     }
-
     /* No extra arguments. */
     if (!opt_check_rest_arg(NULL))
         goto opthelp;
index fbad5079af67569ed6fd7ac111c0aec54c03857e..37c7aeb915da56ad91822c5940fd24baa287be5d 100644 (file)
@@ -102,15 +102,16 @@ specify output filename, default is standard output.
 
 =item B<-issuer> I<filename>
 
-This specifies the current issuer certificate. This option can be used
-multiple times.
+This specifies the current issuer certificate.
+This option can be used multiple times.
 This option B<MUST> come before any B<-cert> options.
 
 =item B<-cert> I<filename>
 
-Add the certificate I<filename> to the request. The issuer certificate
-is taken from the previous B<-issuer> option, or an error occurs if no
-issuer certificate is specified.
+Add the certificate I<filename> to the request.
+This option can be used multiple times.
+The issuer certificate is taken from the previous B<-issuer> option,
+or an error occurs if no issuer certificate is specified.
 
 =item B<-no_certs>