]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
apps/openssl: add -propquery command line option
authorPetr Gotthard <petr.gotthard@centrum.cz>
Sat, 26 Dec 2020 20:32:14 +0000 (21:32 +0100)
committerPauli <ppzgs1@gmail.com>
Fri, 5 Feb 2021 00:24:04 +0000 (10:24 +1000)
Fixes #13656. Right now all openssl commands use a NULL propq. This
patch adds a possibility to specify a custom propq.

The implementation follows the example of set_nameopt/get_nameopt.

Various tools had to be modified to call app_get0_propq after it has
been populated. Otherwise the -propquery has no effect.

The tests then verify the -propquery affects the tool behaviour by
requesting a non-existing property.

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/13707)

15 files changed:
apps/cms.c
apps/genpkey.c
apps/include/apps.h
apps/include/opt.h
apps/lib/app_provider.c
apps/lib/apps.c
apps/mac.c
apps/pkcs7.c
apps/pkeyutl.c
apps/smime.c
apps/storeutl.c
doc/man1/openssl.pod
doc/perlvars.pm
test/recipes/15-test_genrsa.t
test/recipes/20-test_mac.t

index e8254cb85c3f5a330beffd61104c67094c0297bc..36fb88e15cf0dacdece7dc9baec6d96c2d250263 100644 (file)
@@ -28,7 +28,7 @@ static int cms_cb(int ok, X509_STORE_CTX *ctx);
 static void receipt_request_print(CMS_ContentInfo *cms);
 static CMS_ReceiptRequest *make_receipt_request(
     STACK_OF(OPENSSL_STRING) *rr_to, int rr_allorfirst,
-    STACK_OF(OPENSSL_STRING) *rr_from, OSSL_LIB_CTX *libctx, const char *propq);
+    STACK_OF(OPENSSL_STRING) *rr_from, OSSL_LIB_CTX *libctx);
 static int cms_set_pkey_param(EVP_PKEY_CTX *pctx,
                               STACK_OF(OPENSSL_STRING) *param);
 
@@ -303,7 +303,6 @@ int cms_main(int argc, char **argv)
     const char *mime_eol = "\n";
     OPTION_CHOICE o;
     OSSL_LIB_CTX *libctx = app_get0_libctx();
-    const char *propq = app_get0_propq();
 
     if ((vpm = X509_VERIFY_PARAM_new()) == NULL)
         return 1;
@@ -457,7 +456,7 @@ int cms_main(int argc, char **argv)
                     goto opthelp;
             } else {
                 rcms = load_content_info(rctformat, rctin, NULL, "recipient",
-                                         libctx, propq);
+                                         libctx, app_get0_propq());
             }
             break;
         case OPT_CERTFILE:
@@ -870,7 +869,7 @@ int cms_main(int argc, char **argv)
         goto end;
 
     if (operation & SMIME_IP) {
-        cms = load_content_info(informat, in, &indata, "SMIME", libctx, propq);
+        cms = load_content_info(informat, in, &indata, "SMIME", libctx, app_get0_propq());
         if (cms == NULL)
             goto end;
         if (contfile != NULL) {
@@ -901,7 +900,7 @@ int cms_main(int argc, char **argv)
         }
 
         rcms = load_content_info(rctformat, rctin, NULL, "recipient", libctx,
-                                 propq);
+                                 app_get0_propq());
         if (rcms == NULL)
             goto end;
     }
@@ -922,15 +921,15 @@ int cms_main(int argc, char **argv)
     ret = 3;
 
     if (operation == SMIME_DATA_CREATE) {
-        cms = CMS_data_create_ex(in, flags, libctx, propq);
+        cms = CMS_data_create_ex(in, flags, libctx, app_get0_propq());
     } else if (operation == SMIME_DIGEST_CREATE) {
-        cms = CMS_digest_create_ex(in, sign_md, flags, libctx, propq);
+        cms = CMS_digest_create_ex(in, sign_md, flags, libctx, app_get0_propq());
     } else if (operation == SMIME_COMPRESS) {
         cms = CMS_compress(in, -1, flags);
     } else if (operation == SMIME_ENCRYPT) {
         int i;
         flags |= CMS_PARTIAL;
-        cms = CMS_encrypt_ex(NULL, in, cipher, flags, libctx, propq);
+        cms = CMS_encrypt_ex(NULL, in, cipher, flags, libctx, app_get0_propq());
         if (cms == NULL)
             goto end;
         for (i = 0; i < sk_X509_num(encerts); i++) {
@@ -996,7 +995,7 @@ int cms_main(int argc, char **argv)
         }
     } else if (operation == SMIME_ENCRYPTED_ENCRYPT) {
         cms = CMS_EncryptedData_encrypt_ex(in, cipher, secret_key,
-                                           secret_keylen, flags, libctx, propq);
+                                           secret_keylen, flags, libctx, app_get0_propq());
 
     } else if (operation == SMIME_SIGN_RECEIPT) {
         CMS_ContentInfo *srcms = NULL;
@@ -1024,15 +1023,14 @@ int cms_main(int argc, char **argv)
                     flags |= CMS_STREAM;
             }
             flags |= CMS_PARTIAL;
-            cms = CMS_sign_ex(NULL, NULL, other, in, flags, libctx, propq);
+            cms = CMS_sign_ex(NULL, NULL, other, in, flags, libctx, app_get0_propq());
             if (cms == NULL)
                 goto end;
             if (econtent_type != NULL)
                 CMS_set1_eContentType(cms, econtent_type);
 
             if (rr_to != NULL) {
-                rr = make_receipt_request(rr_to, rr_allorfirst, rr_from, libctx,
-                                          propq);
+                rr = make_receipt_request(rr_to, rr_allorfirst, rr_from, libctx);
                 if (rr == NULL) {
                     BIO_puts(bio_err,
                              "Signed Receipt Request Creation Error\n");
@@ -1389,7 +1387,7 @@ static STACK_OF(GENERAL_NAMES) *make_names_stack(STACK_OF(OPENSSL_STRING) *ns)
 static CMS_ReceiptRequest *make_receipt_request(
    STACK_OF(OPENSSL_STRING) *rr_to, int rr_allorfirst,
    STACK_OF(OPENSSL_STRING) *rr_from,
-   OSSL_LIB_CTX *libctx, const char *propq)
+   OSSL_LIB_CTX *libctx)
 {
     STACK_OF(GENERAL_NAMES) *rct_to = NULL, *rct_from = NULL;
     CMS_ReceiptRequest *rr;
@@ -1404,7 +1402,7 @@ static CMS_ReceiptRequest *make_receipt_request(
         rct_from = NULL;
     }
     rr = CMS_ReceiptRequest_create0_ex(NULL, -1, rr_allorfirst, rct_from,
-                                       rct_to, libctx, propq);
+                                       rct_to, libctx, app_get0_propq());
     return rr;
  err:
     sk_GENERAL_NAMES_pop_free(rct_to, GENERAL_NAMES_free);
index 83af5ec88fb6a53e4ce2239c2d8c1c2933655ed4..bdd8b43e4716dcea90895dda0d38540776b3b9d1 100644 (file)
@@ -68,7 +68,6 @@ int genpkey_main(int argc, char **argv)
     int outformat = FORMAT_PEM, text = 0, ret = 1, rv, do_param = 0;
     int private = 0;
     OSSL_LIB_CTX *libctx = app_get0_libctx();
-    const char *propq = app_get0_propq();
 
     prog = opt_init(argc, argv, genpkey_options);
     while ((o = opt_next()) != OPT_EOF) {
@@ -98,11 +97,11 @@ int genpkey_main(int argc, char **argv)
         case OPT_PARAMFILE:
             if (do_param == 1)
                 goto opthelp;
-            if (!init_keygen_file(&ctx, opt_arg(), e, libctx, propq))
+            if (!init_keygen_file(&ctx, opt_arg(), e, libctx, app_get0_propq()))
                 goto end;
             break;
         case OPT_ALGORITHM:
-            if (!init_gen_str(&ctx, opt_arg(), e, do_param, libctx, propq))
+            if (!init_gen_str(&ctx, opt_arg(), e, do_param, libctx, app_get0_propq()))
                 goto end;
             break;
         case OPT_PKEYOPT:
index c0e351b3b9950b0d0b9379d18ea1e10f35ffee6c..d4241fa61e3d565de2af1f372b2df4e0a0d65e1c 100644 (file)
@@ -323,6 +323,7 @@ int app_provider_load(OSSL_LIB_CTX *libctx, const char *provider_name);
 void app_providers_cleanup(void);
 
 OSSL_LIB_CTX *app_get0_libctx(void);
+int app_set_propq(const char *arg);
 const char *app_get0_propq(void);
 
 #endif
index 5f3efe5105e3d8da576b51629dc3d0951825e2ff..d23bf262fc6bbe57079f3c22e6f40e94f96b8f72 100644 (file)
  */
 # define OPT_PROV_ENUM \
         OPT_PROV__FIRST=1600, \
-        OPT_PROV_PROVIDER, OPT_PROV_PROVIDER_PATH, \
+        OPT_PROV_PROVIDER, OPT_PROV_PROVIDER_PATH, OPT_PROV_PROPQUERY, \
         OPT_PROV__LAST
 
 # define OPT_CONFIG_OPTION \
 # define OPT_PROV_OPTIONS \
         OPT_SECTION("Provider"), \
         { "provider-path", OPT_PROV_PROVIDER_PATH, 's', "Provider load path (must be before 'provider' argument if required)" }, \
-        { "provider", OPT_PROV_PROVIDER, 's', "Provider to load (can be specified multiple times)" }
+        { "provider", OPT_PROV_PROVIDER, 's', "Provider to load (can be specified multiple times)" }, \
+        { "propquery", OPT_PROV_PROPQUERY, 's', "Property query used when fetching algorithms" }
 
 # define OPT_PROV_CASES \
         OPT_PROV__FIRST: case OPT_PROV__LAST: break; \
         case OPT_PROV_PROVIDER: \
-        case OPT_PROV_PROVIDER_PATH
+        case OPT_PROV_PROVIDER_PATH: \
+        case OPT_PROV_PROPQUERY
 
 /*
  * Option parsing.
index 490960521c63c03e2fdb801463c114e2ed0369c2..1a1757a5bd350d13144fb558ea91b30a8f6c9a1d 100644 (file)
@@ -70,6 +70,8 @@ int opt_provider(int opt)
         return app_provider_load(app_get0_libctx(), opt_arg());
     case OPT_PROV_PROVIDER_PATH:
         return opt_provider_path(opt_arg());
+    case OPT_PROV_PROPQUERY:
+        return app_set_propq(opt_arg());
     }
     return 0;
 }
index 51c7c82eae9e7fb336cb40663d890c54492f30e3..f53f1b20030b17699a6192445b2f709986bc120a 100644 (file)
@@ -331,10 +331,17 @@ OSSL_LIB_CTX *app_get0_libctx(void)
     return app_libctx;
 }
 
-/* TODO(3.0): Make this an environment variable if required */
+static const char *app_propq = NULL;
+
+int app_set_propq(const char *arg)
+{
+    app_propq = arg;
+    return 1;
+}
+
 const char *app_get0_propq(void)
 {
-    return NULL;
+    return app_propq;
 }
 
 OSSL_LIB_CTX *app_create_libctx(void)
index ea75b33623b6f7c69b6c7b889f79c64dab33670b..ce00ff92e01d7339f2be8847a322aefdafd1cced 100644 (file)
@@ -105,7 +105,7 @@ opthelp:
     if (argc != 1)
         goto opthelp;
 
-    mac = EVP_MAC_fetch(NULL, argv[0], NULL);
+    mac = EVP_MAC_fetch(app_get0_libctx(), argv[0], app_get0_propq());
     if (mac == NULL) {
         BIO_printf(bio_err, "Invalid MAC name %s\n", argv[0]);
         goto opthelp;
index efc58b10c94c81aeeda9b91aa704c062b26c6a26..d970feb30ed759ffc4675e5dba1dd656f7a053b3 100644 (file)
@@ -61,7 +61,6 @@ int pkcs7_main(int argc, char **argv)
     int i, print_certs = 0, text = 0, noout = 0, p7_print = 0, ret = 1;
     OPTION_CHOICE o;
     OSSL_LIB_CTX *libctx = app_get0_libctx();
-    const char *propq = app_get0_propq();
 
     prog = opt_init(argc, argv, pkcs7_options);
     while ((o = opt_next()) != OPT_EOF) {
@@ -120,7 +119,7 @@ int pkcs7_main(int argc, char **argv)
     if (in == NULL)
         goto end;
 
-    p7 = PKCS7_new_ex(libctx, propq);
+    p7 = PKCS7_new_ex(libctx, app_get0_propq());
     if (p7 == NULL) {
         BIO_printf(bio_err, "unable to allocate PKCS7 object\n");
         ERR_print_errors(bio_err);
index a88a6ca7a3504613c6dd0564afdaec340baa4dd1..4eb15c30f434252d160e47e7d05a50d93fea8dcc 100644 (file)
@@ -24,7 +24,7 @@ static EVP_PKEY_CTX *init_ctx(const char *kdfalg, int *pkeysize,
                               const char *keyfile, int keyform, int key_type,
                               char *passinarg, int pkey_op, ENGINE *e,
                               const int impl, int rawin, EVP_PKEY **ppkey,
-                              OSSL_LIB_CTX *libctx, const char *propq);
+                              OSSL_LIB_CTX *libctx);
 
 static int setup_peer(EVP_PKEY_CTX *ctx, int peerform, const char *file,
                       ENGINE *e);
@@ -125,7 +125,6 @@ int pkeyutl_main(int argc, char **argv)
     const EVP_MD *md = NULL;
     int filesize = -1;
     OSSL_LIB_CTX *libctx = app_get0_libctx();
-    const char *propq = NULL;
 
     prog = opt_init(argc, argv, pkeyutl_options);
     while ((o = opt_next()) != OPT_EOF) {
@@ -293,7 +292,7 @@ int pkeyutl_main(int argc, char **argv)
     }
     ctx = init_ctx(kdfalg, &keysize, inkey, keyform, key_type,
                    passinarg, pkey_op, e, engine_impl, rawin, &pkey,
-                   libctx, propq);
+                   libctx);
     if (ctx == NULL) {
         BIO_printf(bio_err, "%s: Error initializing context\n", prog);
         ERR_print_errors(bio_err);
@@ -514,7 +513,7 @@ static EVP_PKEY_CTX *init_ctx(const char *kdfalg, int *pkeysize,
                               char *passinarg, int pkey_op, ENGINE *e,
                               const int engine_impl, int rawin,
                               EVP_PKEY **ppkey,
-                              OSSL_LIB_CTX *libctx, const char *propq)
+                              OSSL_LIB_CTX *libctx)
 {
     EVP_PKEY *pkey = NULL;
     EVP_PKEY_CTX *ctx = NULL;
@@ -522,6 +521,7 @@ static EVP_PKEY_CTX *init_ctx(const char *kdfalg, int *pkeysize,
     char *passin = NULL;
     int rv = -1;
     X509 *x;
+
     if (((pkey_op == EVP_PKEY_OP_SIGN) || (pkey_op == EVP_PKEY_OP_DECRYPT)
          || (pkey_op == EVP_PKEY_OP_DERIVE))
         && (key_type != KEY_PRIVKEY && kdfalg == NULL)) {
@@ -573,7 +573,7 @@ static EVP_PKEY_CTX *init_ctx(const char *kdfalg, int *pkeysize,
         if (impl != NULL)
             ctx = EVP_PKEY_CTX_new_id(kdfnid, impl);
         else
-            ctx = EVP_PKEY_CTX_new_from_name(libctx, kdfalg, propq);
+            ctx = EVP_PKEY_CTX_new_from_name(libctx, kdfalg, app_get0_propq());
     } else {
         if (pkey == NULL)
             goto end;
@@ -582,7 +582,7 @@ static EVP_PKEY_CTX *init_ctx(const char *kdfalg, int *pkeysize,
         if (impl != NULL)
             ctx = EVP_PKEY_CTX_new(pkey, impl);
         else
-            ctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, propq);
+            ctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, app_get0_propq());
         if (ppkey != NULL)
             *ppkey = pkey;
         EVP_PKEY_free(pkey);
index 2e3500970971ac03b33d09cb7b8e0d84dbddb4dc..2a9ee27a34082bc125e1102ec570a1e402e28be3 100644 (file)
@@ -155,7 +155,6 @@ int smime_main(int argc, char **argv)
     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;
@@ -487,7 +486,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 +533,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 +548,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) {
index 0ec65ab047bcffd11a78aad0bd3239e04d93b6ec..9333c478f287bcd2337be5090170766da582d9f2 100644 (file)
@@ -19,7 +19,7 @@
 static int process(const char *uri, const UI_METHOD *uimeth, PW_CB_DATA *uidata,
                    int expected, int criterion, OSSL_STORE_SEARCH *search,
                    int text, int noout, int recursive, int indent, BIO *out,
-                   const char *prog, OSSL_LIB_CTX *libctx, const char *propq);
+                   const char *prog, OSSL_LIB_CTX *libctx);
 
 typedef enum OPTION_choice {
     OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, OPT_ENGINE, OPT_OUT, OPT_PASSIN,
@@ -85,7 +85,6 @@ int storeutl_main(int argc, char *argv[])
     OSSL_STORE_SEARCH *search = NULL;
     const EVP_MD *digest = NULL;
     OSSL_LIB_CTX *libctx = app_get0_libctx();
-    const char *propq = app_get0_propq();
 
     while ((o = opt_next()) != OPT_EOF) {
         switch (o) {
@@ -315,7 +314,7 @@ int storeutl_main(int argc, char *argv[])
 
     ret = process(argv[0], get_ui_method(), &pw_cb_data,
                   expected, criterion, search,
-                  text, noout, recursive, 0, out, prog, libctx, propq);
+                  text, noout, recursive, 0, out, prog, libctx);
 
  end:
     OPENSSL_free(fingerprint);
@@ -346,12 +345,12 @@ static int indent_printf(int indent, BIO *bio, const char *format, ...)
 static int process(const char *uri, const UI_METHOD *uimeth, PW_CB_DATA *uidata,
                    int expected, int criterion, OSSL_STORE_SEARCH *search,
                    int text, int noout, int recursive, int indent, BIO *out,
-                   const char *prog, OSSL_LIB_CTX *libctx, const char *propq)
+                   const char *prog, OSSL_LIB_CTX *libctx)
 {
     OSSL_STORE_CTX *store_ctx = NULL;
     int ret = 1, items = 0;
 
-    if ((store_ctx = OSSL_STORE_open_ex(uri, libctx, propq, uimeth, uidata,
+    if ((store_ctx = OSSL_STORE_open_ex(uri, libctx, app_get0_propq(), uimeth, uidata,
                                         NULL, NULL))
         == NULL) {
         BIO_printf(bio_err, "Couldn't open file or uri %s\n", uri);
@@ -436,7 +435,7 @@ static int process(const char *uri, const UI_METHOD *uimeth, PW_CB_DATA *uidata,
                 ret += process(suburi, uimeth, uidata,
                                expected, criterion, search,
                                text, noout, recursive, indent + 2, out, prog,
-                               libctx, propq);
+                               libctx);
             }
             break;
         case OSSL_STORE_INFO_PARAMS:
index 3176c19eee92528a7caa593636f50bdf67a3cbf7..8e30f81fe9f6750e815f44ae71f9cba343cc2bc4 100644 (file)
@@ -645,6 +645,26 @@ the PKCS#11 URI as defined in RFC 7512 should be possible to use directly:
 
     -key pkcs11:object=some-private-key;pin-value=1234
 
+=head2 Provider Options
+
+=over 4
+
+=item B<-provider> I<name>
+
+Load and initialize the provider identified by I<name>.
+
+=item B<-provider-path> I<path>
+
+Specifies the search path that is to be used for looking for providers.
+
+=item B<-propquery> I<propq>
+
+Specifies the I<property query clause> to be used when fetching algorithms
+from the loaded providers.
+See L<property(7)> for a more detailed description.
+
+=back
+
 =head1 ENVIRONMENT
 
 The OpenSSL library can be take some configuration parameters from the
index d4fbba9a64fd719b1660ae611b2e90302c37bf6c..47f813d51e77dd5a019f4bd16889d45b51e24dc8 100644 (file)
@@ -93,12 +93,15 @@ $OpenSSL::safe::opt_r_item = ""
 # Provider options
 $OpenSSL::safe::opt_provider_synopsis = ""
 . "[B<-provider> I<name>]\n"
-. "[B<-provider-path> I<path>]";
+. "[B<-provider-path> I<path>]\n"
+. "[B<-propquery> I<propq>]";
 $OpenSSL::safe::opt_provider_item = ""
 . "=item B<-provider> I<name>\n"
 . "\n"
 . "=item B<-provider-path> I<path>\n"
 . "\n"
+. "=item B<-propquery> I<propq>\n"
+. "\n"
 . "See L<openssl(1)/Provider Options>.";
 
 # Configuration option
index ffa334f15eb051574e4ad94509abb1e39a066407..16bad16d652c7ac730cf0a9fd28bc605e579a30c 100644 (file)
@@ -26,7 +26,7 @@ my $no_fips = disabled('fips') || ($ENV{NO_FIPS} // 0);
 
 plan tests =>
     ($no_fips ? 0 : 2)          # FIPS install test + fips related test
-    + 12;
+    + 13;
 
 # We want to know that an absurdly small number of bits isn't support
 if (disabled("deprecated-3.0")) {
@@ -101,6 +101,9 @@ ok(!run(app([ 'openssl', 'genpkey', '-algorithm', 'RSA',
              '-pkeyopt', 'e:65538',
              '-out', 'genrsatest.pem' ])),
    "genpkey with a even public exponent should fail");
+ok(!run(app([ 'openssl', 'genpkey', '-propquery', 'unknown',
+             '-algorithm', 'RSA' ])),
+   "genpkey requesting unknown=yes property should fail");
 
 
  SKIP: {
index e34381c0256bcad4f9f3d6854e070546d2425446..61f6161b0ccc61a229a92612515cb94ac4f2e4df 100644 (file)
@@ -78,6 +78,11 @@ my @mac_fail_tests = (
       input => '00',
       err => 'EVP_MAC_Init',
       desc => 'KMAC128 Fail no key' },
+    { cmd => [qw{openssl mac -propquery unknown -macopt hexkey:404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F}],
+      type => 'KMAC128',
+      input => '00',
+      err => 'Invalid MAC name KMAC128',
+      desc => 'KMAC128 Fail unknown property' },
 );
 
 my @siphash_fail_tests = (