Kaynağa Gözat

APPS: Adapt load_key() and load_pubkey() for the engine: loader

These two functions react when the FORMAT_ENGINE format is given, and
use the passed ENGINE |e| and the passed key argument to form a URI
suitable for the engine: loader.

Co-authored-by: David von Oheimb <david.von.oheimb@siemens.com>

Reviewed-by: David von Oheimb <david.von.oheimb@siemens.com>
(Merged from https://github.com/openssl/openssl/pull/13570)
Richard Levitte 4 yıl önce
ebeveyn
işleme
f91d003a0e

+ 1 - 5
apps/cmp.c

@@ -409,11 +409,7 @@ const OPTIONS cmp_options[] = {
     {"engine", OPT_ENGINE, 's',
      "Use crypto engine with given identifier, possibly a hardware device."},
     {OPT_MORE_STR, 0, 0,
-     "Engines may be defined in OpenSSL config file engine section."},
-    {OPT_MORE_STR, 0, 0,
-     "Options like -key specifying keys held in the engine can give key IDs"},
-    {OPT_MORE_STR, 0, 0,
-     "prefixed by 'engine:', e.g. '-key engine:pkcs11:object=mykey;pin-value=1234'"},
+     "Engines may also be defined in OpenSSL config file engine section."},
 #endif
     OPT_PROV_OPTIONS,
 

+ 1 - 4
apps/include/apps.h

@@ -156,10 +156,7 @@ ENGINE *setup_engine_methods(const char *id, unsigned int methods, int debug);
 void release_engine(ENGINE *e);
 int init_engine(ENGINE *e);
 int finish_engine(ENGINE *e);
-EVP_PKEY *load_engine_private_key(ENGINE *e, const char *keyid,
-                                  const char *pass, const char *desc);
-EVP_PKEY *load_engine_public_key(ENGINE *e, const char *keyid,
-                                 const char *pass, const char *desc);
+char *make_engine_uri(ENGINE *e, const char *key_id, const char *desc);
 
 int get_legacy_pkey_id(OSSL_LIB_CTX *libctx, const char *algname, ENGINE *e);
 

+ 39 - 28
apps/lib/apps.c

@@ -560,25 +560,18 @@ EVP_PKEY *load_key(const char *uri, int format, int may_stdin,
                    const char *pass, ENGINE *e, const char *desc)
 {
     EVP_PKEY *pkey = NULL;
+    char *allocated_uri = NULL;
 
     if (desc == NULL)
         desc = "private key";
 
     if (format == FORMAT_ENGINE) {
-        if (e == NULL) {
-            BIO_printf(bio_err, "No engine specified for loading %s\n", desc);
-        } else {
-            pkey = load_engine_private_key(e, uri, pass, desc);
-            if (pkey == NULL) {
-                BIO_printf(bio_err, "Cannot load %s from engine\n", desc);
-                ERR_print_errors(bio_err);
-            }
-        }
-    } else {
-        (void)load_key_certs_crls(uri, may_stdin, pass, desc,
-                                  &pkey, NULL, NULL, NULL, NULL, NULL, NULL);
+        uri = allocated_uri = make_engine_uri(e, uri, desc);
     }
+    (void)load_key_certs_crls(uri, may_stdin, pass, desc,
+                              &pkey, NULL, NULL, NULL, NULL, NULL, NULL);
 
+    OPENSSL_free(allocated_uri);
     return pkey;
 }
 
@@ -586,25 +579,18 @@ EVP_PKEY *load_pubkey(const char *uri, int format, int maybe_stdin,
                       const char *pass, ENGINE *e, const char *desc)
 {
     EVP_PKEY *pkey = NULL;
+    char *allocated_uri = NULL;
 
     if (desc == NULL)
         desc = "public key";
 
     if (format == FORMAT_ENGINE) {
-        if (e == NULL) {
-            BIO_printf(bio_err, "No engine specified for loading %s\n", desc);
-        } else {
-            pkey = load_engine_public_key(e, uri, pass, desc);
-            if (pkey == NULL) {
-                BIO_printf(bio_err, "Cannot load %s from engine\n", desc);
-                ERR_print_errors(bio_err);
-            }
-        }
-    } else {
-        (void)load_key_certs_crls(uri, maybe_stdin, pass, desc,
-                                  NULL, &pkey, NULL, NULL, NULL, NULL, NULL);
+        uri = allocated_uri = make_engine_uri(e, uri, desc);
     }
+    (void)load_key_certs_crls(uri, maybe_stdin, pass, desc,
+                              NULL, &pkey, NULL, NULL, NULL, NULL, NULL);
 
+    OPENSSL_free(allocated_uri);
     return pkey;
 }
 
@@ -717,14 +703,25 @@ int load_key_certs_crls(const char *uri, int maybe_stdin,
         pparams != NULL ? "params" : pcert != NULL ? "cert" :
         pcrl != NULL ? "CRL" : pcerts != NULL ? "certs" :
         pcrls != NULL ? "CRLs" : NULL;
+    int cnt_expectations = 0;
+    int expect = 0;
     /* TODO make use of the engine reference 'eng' when loading pkeys */
 
-    if (ppkey != NULL)
+    if (ppkey != NULL) {
         *ppkey = NULL;
-    if (ppubkey != NULL)
+        cnt_expectations++;
+        expect = OSSL_STORE_INFO_PKEY;
+    }
+    if (ppubkey != NULL) {
         *ppubkey = NULL;
-    if (pcert != NULL)
+        cnt_expectations++;
+        expect = OSSL_STORE_INFO_PUBKEY;
+    }
+    if (pcert != NULL) {
         *pcert = NULL;
+        cnt_expectations++;
+        expect = OSSL_STORE_INFO_CERT;
+    }
     if (failed == NULL) {
         BIO_printf(bio_err, "Internal error: nothing to load into from %s\n",
                    uri != NULL ? uri : "<stdin>");
@@ -735,13 +732,22 @@ int load_key_certs_crls(const char *uri, int maybe_stdin,
             && (*pcerts = sk_X509_new_null()) == NULL) {
         BIO_printf(bio_err, "Out of memory loading");
         goto end;
+    } else {
+        cnt_expectations++;
+        expect = OSSL_STORE_INFO_CERT;
     }
-    if (pcrl != NULL)
+    if (pcrl != NULL) {
         *pcrl = NULL;
+        cnt_expectations++;
+        expect = OSSL_STORE_INFO_CRL;
+    }
     if (pcrls != NULL && *pcrls == NULL
             && (*pcrls = sk_X509_CRL_new_null()) == NULL) {
         BIO_printf(bio_err, "Out of memory loading");
         goto end;
+    } else {
+        cnt_expectations++;
+        expect = OSSL_STORE_INFO_CRL;
     }
 
     uidata.password = pass;
@@ -769,6 +775,11 @@ int load_key_certs_crls(const char *uri, int maybe_stdin,
         goto end;
     }
 
+    if (cnt_expectations != 1)
+        expect = 0;
+    if (!OSSL_STORE_expect(ctx, expect))
+        goto end;
+
     failed = NULL;
     while (!OSSL_STORE_eof(ctx)) {
         OSSL_STORE_INFO *info = OSSL_STORE_load(ctx);

+ 24 - 35
apps/lib/engine.c

@@ -102,48 +102,37 @@ int finish_engine(ENGINE *e)
     return rv;
 }
 
-EVP_PKEY *load_engine_private_key(ENGINE *e, const char *keyid,
-                                  const char *pass, const char *desc)
+char *make_engine_uri(ENGINE *e, const char *key_id, const char *desc)
 {
-    EVP_PKEY *rv = NULL;
+    char *new_uri = NULL;
 
 #ifndef OPENSSL_NO_ENGINE
-    if (init_engine(e)) {
-        PW_CB_DATA cb_data;
-
-        cb_data.password = pass;
-        cb_data.prompt_info = keyid;
-
-        rv = ENGINE_load_private_key(e, keyid,
-                                     (UI_METHOD *)get_ui_method(), &cb_data);
-        finish_engine(e);
-    }
-#else
-    BIO_printf(bio_err, "Engines not supported for loading %s\n", desc);
-#endif
-    return rv;
-}
-
-EVP_PKEY *load_engine_public_key(ENGINE *e, const char *keyid,
-                                 const char *pass, const char *desc)
-{
-    EVP_PKEY *rv = NULL;
-
-#ifndef OPENSSL_NO_ENGINE
-    if (init_engine(e)) {
-        PW_CB_DATA cb_data;
-
-        cb_data.password = pass;
-        cb_data.prompt_info = keyid;
-
-        rv = ENGINE_load_public_key(e, keyid,
-                                    (UI_METHOD *)get_ui_method(), &cb_data);
-        finish_engine(e);
+    if (e == NULL) {
+        BIO_printf(bio_err, "No engine specified for loading %s\n", desc);
+    } else if (key_id == NULL) {
+        BIO_printf(bio_err, "No engine key id specified for loading %s\n", desc);
+    } else {
+        const char *engineid = ENGINE_get_id(e);
+        size_t uri_sz =
+            sizeof(ENGINE_SCHEME_COLON) - 1
+            + strlen(engineid)
+            + 1 /* : */
+            + strlen(key_id)
+            + 1 /* \0 */
+            ;
+
+        new_uri = OPENSSL_malloc(uri_sz);
+        if (new_uri != NULL) {
+            OPENSSL_strlcpy(new_uri, ENGINE_SCHEME_COLON, uri_sz);
+            OPENSSL_strlcat(new_uri, engineid, uri_sz);
+            OPENSSL_strlcat(new_uri, ":", uri_sz);
+            OPENSSL_strlcat(new_uri, key_id, uri_sz);
+        }
     }
 #else
     BIO_printf(bio_err, "Engines not supported for loading %s\n", desc);
 #endif
-    return rv;
+    return new_uri;
 }
 
 int get_legacy_pkey_id(OSSL_LIB_CTX *libctx, const char *algname, ENGINE *e)

+ 2 - 2
doc/man1/openssl-ca.pod.in

@@ -33,7 +33,7 @@ B<openssl> B<ca>
 [B<-days> I<arg>]
 [B<-md> I<arg>]
 [B<-policy> I<arg>]
-[B<-keyfile> I<arg>]
+[B<-keyfile> I<filename>|I<uri>]
 [B<-keyform> B<DER>|B<PEM>|B<P12>|B<ENGINE>]
 [B<-key> I<arg>]
 [B<-passin> I<arg>]
@@ -148,7 +148,7 @@ The CA certificate, which must match with B<-keyfile>.
 The format of the data in certificate input files.
 This option has no effect and is retained for backward compatibility only.
 
-=item B<-keyfile> I<filename>
+=item B<-keyfile> I<filename>|I<uri>
 
 The CA private key to sign requests with. This must match with B<-cert>.
 

+ 26 - 20
doc/man1/openssl-cmp.pod.in

@@ -21,7 +21,7 @@ Generic message options:
 
 Certificate enrollment options:
 
-[B<-newkey> I<filename>]
+[B<-newkey> I<filename>|I<uri>]
 [B<-newkeypass> I<arg>]
 [B<-subject> I<name>]
 [B<-issuer> I<name>]
@@ -90,7 +90,7 @@ TLS connection options:
 
 [B<-tls_used>]
 [B<-tls_cert> I<filename>]
-[B<-tls_key> I<filename>]
+[B<-tls_key> I<filename>|I<uri>]
 [B<-tls_keypass> I<arg>]
 [B<-tls_extra> I<filenames>]
 [B<-tls_trusted> I<filenames>]
@@ -139,6 +139,8 @@ Certificate verification options, for both CMP and TLS:
 
 {- $OpenSSL::safe::opt_v_synopsis -}
 
+=for openssl ifdef engine
+
 =head1 DESCRIPTION
 
 The B<cmp> command is a client implementation for the Certificate
@@ -241,9 +243,9 @@ e.g., C<1.2.3.4:int:56789>.
 
 =over 4
 
-=item B<-newkey> I<filename>
+=item B<-newkey> I<filename>|I<uri>
 
-The file containing the private or public key for the certificate requested
+The source of the private or public key for the certificate requested
 in Initialization Request (IR), Certification Request(CR), or
 Key Update Request (KUR).
 Default is the public key in the PKCS#10 CSR given with the B<-csr> option,
@@ -701,6 +703,7 @@ Default value is PEM.
 
 The format of the key input.
 The only value with effect is B<ENGINE>.
+See L<openssl(1)/Format Options> for details.
 
 =item B<-otherpass> I<arg>
 
@@ -712,27 +715,24 @@ If not given here, the password will be prompted for if needed.
 
 For more information about the format of B<arg> see the
 B<PASS PHRASE ARGUMENTS> section in L<openssl(1)>.
+
+{- $OpenSSL::safe::opt_engine_item -}
+
+=back
+
 {- output_off() if $disabled{"deprecated-3.0"}; "" -}
+As an alternative to using this combination:
 
-=item B<-engine> I<id>
+    -engine {engineid} -key {keyid} -keyform ENGINE
 
-Specifying a crypto engine B<id> will lead to obtaining a functional
-reference to the specified engine, initializing it if needed.
-The engine will be used for all algorithms supported for keys
-prefixed by C<engine:>.
-Engines may be defined in the OpenSSL config file as usual in an engine section.
+... it's also possible to just give the key ID in URI form to B<-key>,
+like this:
 
-Options specifying keys, like B<-key>, B<-newkey>, B<-tls_key> can prefix
-C<engine:> to engine-specific identifiers for security tokens objects held by
-the engine.
- The following example utilizes the RFC 7512 PKCS #11 URI scheme
-as supported, e.g., by libp11:
-C<-key engine:pkcs11:object=my-private-key;type=private;pin-value=1234>
+    -key org.openssl.engine:{engineid}:{keyid}
 
+This applies to all options specifying keys: B<-key>, B<-newkey>, and
+B<-tls_key>.
 {- output_on() if $disabled{"deprecated-3.0"}; "" -}
-{- $OpenSSL::safe::opt_provider_item -}
-
-=back
 
 =head2 TLS connection options
 
@@ -749,7 +749,7 @@ Client's TLS certificate.
 If the file includes further certs they are used (along with B<-untrusted>
 certs) for constructing the client cert chain provided to the TLS server.
 
-=item B<-tls_key> I<filename>
+=item B<-tls_key> I<filename>|I<uri>
 
 Private key for the client's TLS certificate.
 
@@ -1162,6 +1162,12 @@ and the above genm call reduces to
 L<openssl-genrsa(1)>, L<openssl-ecparam(1)>, L<openssl-list(1)>,
 L<openssl-req(1)>, L<openssl-x509(1)>, L<x509v3_config(5)>
 
+=head1 HISTORY
+
+The B<cmp> application was added in OpenSSL 3.0.
+
+The B<-engine option> was deprecated in OpenSSL 3.0.
+
 =head1 COPYRIGHT
 
 Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved.

+ 2 - 2
doc/man1/openssl-cms.pod.in

@@ -72,7 +72,7 @@ B<openssl> B<cms>
 [B<-secretkey> I<key>]
 [B<-secretkeyid> I<id>]
 [B<-econtent_type> I<type>]
-[B<-inkey> I<file>]
+[B<-inkey> I<filename>|I<uri>]
 [B<-keyopt> I<name>:I<parameter>]
 [B<-passin> I<arg>]
 [B<-to> I<addr>]
@@ -466,7 +466,7 @@ Set the encapsulated content type to I<type> if not supplied the B<Data> type
 is used. The I<type> argument can be any valid OID name in either text or
 numerical format.
 
-=item B<-inkey> I<file>
+=item B<-inkey> I<filename>|I<uri>
 
 The private key to use when signing or decrypting. This must match the
 corresponding certificate. If this option is not specified then the

+ 3 - 3
doc/man1/openssl-dgst.pod.in

@@ -19,7 +19,7 @@ B<openssl> B<dgst>|I<digest>
 [B<-xoflen> I<length>]
 [B<-r>]
 [B<-out> I<filename>]
-[B<-sign> I<filename>]
+[B<-sign> I<filename>|I<uri>]
 [B<-keyform> B<DER>|B<PEM>|B<P12>|B<ENGINE>]
 [B<-passin> I<arg>]
 [B<-verify> I<filename>]
@@ -100,9 +100,9 @@ Used by programs like L<sha1sum(1)>.
 
 Filename to output to, or standard output by default.
 
-=item B<-sign> I<filename>
+=item B<-sign> I<filename>|I<uri>
 
-Digitally sign the digest using the private key in "filename". Note this option
+Digitally sign the digest using the given private key. Note this option
 does not support Ed25519 or Ed448 private keys. Use the L<openssl-pkeyutl(1)>
 command instead for this.
 

+ 3 - 3
doc/man1/openssl-ec.pod.in

@@ -15,7 +15,7 @@ B<openssl> B<ec>
 [B<-help>]
 [B<-inform> B<DER>|B<PEM>|B<P12>|B<ENGINE>]
 [B<-outform> B<DER>|B<PEM>]
-[B<-in> I<filename>]
+[B<-in> I<filename>|I<uri>]
 [B<-passin> I<arg>]
 [B<-out> I<filename>]
 [B<-passout> I<arg>]
@@ -65,9 +65,9 @@ See L<openssl(1)/Format Options> for details.
 Private keys are an SEC1 private key or PKCS#8 format.
 Public keys are a B<SubjectPublicKeyInfo> as specified in IETF RFC 3280.
 
-=item B<-in> I<filename>
+=item B<-in> I<filename>|I<uri>
 
-This specifies the input filename to read a key from or standard input if this
+This specifies the input to read a key from or standard input if this
 option is not specified. If the key is encrypted a pass phrase will be
 prompted for.
 

+ 0 - 1
doc/man1/openssl-list.pod.in

@@ -158,7 +158,6 @@ This option is deprecated.
 
 Display a list of loaded engines.
 
-{- output_on() if $disabled{"deprecated-3.0"}; "" -}
 =item B<-disabled>
 
 Display a list of disabled features, those that were compiled out

+ 11 - 9
doc/man1/openssl-pkcs12.pod.in

@@ -12,12 +12,12 @@ B<openssl> B<pkcs12>
 [B<-export>]
 [B<-chain>]
 [B<-untrusted> I<filename>]
-[B<-inkey> I<file_or_id>]
+[B<-inkey> I<filename>|I<uri>]
 [B<-certfile> I<filename>]
 [B<-passcerts> I<arg>]
 [B<-name> I<name>]
 [B<-caname> I<name>]
-[B<-in> I<filename>]
+[B<-in> I<filename>|I<uri>]
 [B<-out> I<filename>]
 [B<-noout>]
 [B<-nomacver>]
@@ -86,12 +86,13 @@ The default encryption algorithm is AES-256-CBC with PBKDF2 for key derivation.
 
 Print out a usage message.
 
-=item B<-in> I<filename>
+=item B<-in> I<filename>|I<uri>
 
 This specifies the input filename or URI.
 Standard input is used by default.
 Without the B<-export> option this is a PKCS#12 file to be parsed.
-With the B<-export> option this is a file with certificates and possibly a key.
+With the B<-export> option this is a file with certificates and possibly a key,
+or a URI that refers to a key accessed via an engine.
 
 =item B<-out> I<filename>
 
@@ -206,12 +207,13 @@ The order doesn't matter but one private key and
 its corresponding certificate should be present. If additional
 certificates are present they will also be included in the PKCS#12 file.
 
-=item B<-inkey> I<file_or_id>
+=item B<-inkey> I<filename>|I<uri>
 
-File to read private key from for PKCS12 output.
-If not present then the input file (B<-in> argument) must contain a private key.
-If no engine is used, the argument is taken as a file; if an engine is
-specified, the argument is given to the engine as a key identifier.
+The private key input for PKCS12 output. If this option is not specified then
+the input file (B<-in> argument) must contain a private key.
+If no engine is used, the argument is taken as a file;
+if the B<-engine> option is used or the URI has prefix C<org.openssl.engine:>
+then the rest of the URI is taken as key identifier for the given engine.
 
 =item B<-name> I<friendlyname>
 

+ 3 - 3
doc/man1/openssl-pkey.pod.in

@@ -15,7 +15,7 @@ B<openssl> B<pkey>
 [B<-help>]
 [B<-inform> B<DER>|B<PEM>|B<P12>|B<ENGINE>]
 [B<-outform> B<DER>|B<PEM>]
-[B<-in> I<filename>]
+[B<-in> I<filename>|I<uri>]
 [B<-passin> I<arg>]
 [B<-out> I<filename>]
 [B<-passout> I<arg>]
@@ -58,9 +58,9 @@ See L<openssl(1)/Format Options> for details.
 The key output formats; the default is B<PEM>.
 See L<openssl(1)/Format Options> for details.
 
-=item B<-in> I<filename>
+=item B<-in> I<filename>|I<uri>
 
-This specifies the input filename to read a key from or standard input if this
+This specifies the input to read a key from or standard input if this
 option is not specified. If the key is encrypted a pass phrase will be
 prompted for.
 

+ 5 - 3
doc/man1/openssl-pkeyutl.pod.in

@@ -14,7 +14,7 @@ B<openssl> B<pkeyutl>
 [B<-digest> I<algorithm>]
 [B<-out> I<file>]
 [B<-sigfile> I<file>]
-[B<-inkey> I<file>]
+[B<-inkey> I<filename>|I<uri>]
 [B<-keyform> B<DER>|B<PEM>|B<P12>|B<ENGINE>]
 [B<-passin> I<arg>]
 [B<-peerkey> I<file>]
@@ -85,9 +85,9 @@ default.
 
 Signature file, required for B<-verify> operations only
 
-=item B<-inkey> I<file>
+=item B<-inkey> I<filename>|I<uri>
 
-The input key file, by default it should be a private key.
+The input key, by default it should be a private key.
 
 =item B<-keyform> B<DER>|B<PEM>|B<P12>|B<ENGINE>
 
@@ -184,10 +184,12 @@ B<-verifyrecover> option when an ASN1 structure is signed.
 
 {- $OpenSSL::safe::opt_engine_item -}
 
+{- output_off() if $disabled{"deprecated-3.0"}; "" -}
 =item B<-engine_impl>
 
 When used with the B<-engine> option, it specifies to also use
 engine I<id> for crypto operations.
+{- output_on() if $disabled{"deprecated-3.0"}; "" -}
 
 {- $OpenSSL::safe::opt_r_item -}
 

+ 3 - 3
doc/man1/openssl-req.pod.in

@@ -25,7 +25,7 @@ B<openssl> B<req>
 [B<-pkeyopt> I<opt>:I<value>]
 [B<-noenc>]
 [B<-nodes>]
-[B<-key> I<filename>]
+[B<-key> I<filename>|I<uri>]
 [B<-keyform> B<DER>|B<PEM>|B<P12>|B<ENGINE>]
 [B<-keyout> I<filename>]
 [B<-keygen_engine> I<id>]
@@ -181,9 +181,9 @@ options supported depends on the public key algorithm used and its
 implementation.
 See L<openssl-genpkey(1)/KEY GENERATION OPTIONS> for more details.
 
-=item B<-key> I<filename>
+=item B<-key> I<filename>|I<uri>
 
-This specifies the file to read the private key from. It also
+This specifies the private key to use. It also
 accepts PKCS#8 format private keys for PEM format files.
 
 =item B<-keyform> B<DER>|B<PEM>|B<P12>|B<ENGINE>

+ 3 - 3
doc/man1/openssl-rsa.pod.in

@@ -15,7 +15,7 @@ B<openssl> B<rsa>
 [B<-help>]
 [B<-inform> B<DER>|B<PEM>|B<P12>|B<ENGINE>]
 [B<-outform> B<DER>|B<PEM>]
-[B<-in> I<filename>]
+[B<-in> I<filename>|I<uri>]
 [B<-passin> I<arg>]
 [B<-out> I<filename>]
 [B<-passout> I<arg>]
@@ -74,9 +74,9 @@ See L<openssl(1)/Format Options> for details.
 When writing a private key, use the traditional PKCS#1 format
 instead of the PKCS#8 format.
 
-=item B<-in> I<filename>
+=item B<-in> I<filename>|I<uri>
 
-This specifies the input filename to read a key from or standard input if this
+This specifies the input to read a key from or standard input if this
 option is not specified. If the key is encrypted a pass phrase will be
 prompted for.
 

+ 3 - 3
doc/man1/openssl-rsautl.pod.in

@@ -13,7 +13,7 @@ B<openssl> B<rsautl>
 [B<-passin> I<arg>]
 [B<-rev>]
 [B<-out> I<file>]
-[B<-inkey> I<file>]
+[B<-inkey> I<filename>|I<uri>]
 [B<-keyform> B<DER>|B<PEM>|B<P12>|B<ENGINE>]
 [B<-pubin>]
 [B<-certin>]
@@ -71,9 +71,9 @@ Reverse the order of the input.
 Specifies the output filename to write to or standard output by
 default.
 
-=item B<-inkey> I<file>
+=item B<-inkey> I<filename>|I<uri>
 
-The input key file, by default it should be an RSA private key.
+The input key, by default it should be an RSA private key.
 
 =item B<-keyform> B<DER>|B<PEM>|B<P12>|B<ENGINE>
 

+ 5 - 3
doc/man1/openssl-s_client.pod.in

@@ -35,7 +35,7 @@ B<openssl> B<s_client>
 [B<-CRL> I<filename>]
 [B<-CRLform> B<DER>|B<PEM>]
 [B<-crl_download>]
-[B<-key> I<filename>]
+[B<-key> I<filename>|I<uri>]
 [B<-keyform> B<DER>|B<PEM>|B<P12>|B<ENGINE>]
 [B<-pass> I<arg>]
 [B<-chainCAfile> I<filename>]
@@ -269,9 +269,9 @@ See L<openssl(1)/Format Options> for details.
 
 Download CRL from distribution points in the certificate.
 
-=item B<-key> I<keyfile>
+=item B<-key> I<filename>|I<uri>
 
-The client private key file to use.
+The client private key to use.
 If not specified then the certificate file will be used to read also the key.
 
 =item B<-keyform> B<DER>|B<PEM>|B<P12>|B<ENGINE>
@@ -786,9 +786,11 @@ Set the minimal acceptable length, in bits, for B<N>.
 
 {- $OpenSSL::safe::opt_engine_item -}
 
+{- output_off() if $disabled{"deprecated-3.0"}; "" -}
 =item B<-ssl_client_engine> I<id>
 
 Specify engine to be used for client certificate operations.
+{- output_on() if $disabled{"deprecated-3.0"}; "" -}
 
 {- $OpenSSL::safe::opt_v_item -}
 

+ 13 - 5
doc/man1/openssl-s_server.pod.in

@@ -24,14 +24,14 @@ B<openssl> B<s_server>
 [B<-cert_chain> I<infile>]
 [B<-build_chain>]
 [B<-serverinfo> I<val>]
-[B<-key> I<infile>]
-[B<-key2> I<infile>]
+[B<-key> I<filename>|I<uri>]
+[B<-key2> I<filename>|I<uri>]
 [B<-keyform> B<DER>|B<PEM>|B<P12>|B<ENGINE>]
 [B<-pass> I<val>]
 [B<-dcert> I<infile>]
 [B<-dcertform> B<DER>|B<PEM>|B<P12>]
 [B<-dcert_chain> I<infile>]
-[B<-dkey> I<infile>]
+[B<-dkey> I<filename>|I<uri>]
 [B<-dkeyform> B<DER>|B<PEM>|B<P12>|B<ENGINE>]
 [B<-dpass> I<val>]
 [B<-nbio_test>]
@@ -220,6 +220,10 @@ certificate and some require a certificate with a certain public key type:
 for example the DSS cipher suites require a certificate containing a DSS
 (DSA) key. If not specified then the filename F<server.pem> will be used.
 
+=item B<-cert2> I<infile>
+
+The certificate file to use for servername; default is C<server2.pem>.
+
 =item B<-certform> B<DER>|B<PEM>|B<P12>
 
 The server certificate file format.
@@ -244,11 +248,15 @@ followed by "length" bytes of extension data).  If the client sends
 an empty TLS ClientHello extension matching the type, the corresponding
 ServerHello extension will be returned.
 
-=item B<-key> I<infile>
+=item B<-key> I<filename>|I<uri>
 
 The private key to use. If not specified then the certificate file will
 be used.
 
+=item B<-key2> I<filename>|I<uri>
+
+The private Key file to use for servername if not given via B<-cert2>.
+
 =item B<-keyform> B<DER>|B<PEM>|B<P12>|B<ENGINE>
 
 The key format; the default is B<PEM>.
@@ -261,7 +269,7 @@ The private key and certificate file password source.
 For more information about the format of I<val>,
 see L<openssl(1)/Pass Phrase Options>.
 
-=item B<-dcert> I<infile>, B<-dkey> I<infile>
+=item B<-dcert> I<infile>, B<-dkey> I<filename>|I<uri>
 
 Specify an additional certificate and private key, these behave in the
 same manner as the B<-cert> and B<-key> options except there is no default

+ 2 - 4
doc/man1/openssl-smime.pod.in

@@ -34,7 +34,7 @@ B<openssl> B<smime>
 [B<-outform> B<DER>|B<PEM>|B<SMIME>]
 [B<-keyform> B<DER>|B<PEM>|B<P12>|B<ENGINE>]
 [B<-passin> I<arg>]
-[B<-inkey> I<file_or_id>]
+[B<-inkey> I<filename>|I<uri>]
 [B<-out> I<file>]
 [B<-content> I<file>]
 [B<-to> I<addr>]
@@ -259,15 +259,13 @@ Don't include any signed attributes when signing.
 The recipients certificate when decrypting a message. This certificate
 must match one of the recipients of the message or an error occurs.
 
-=item B<-inkey> I<file_or_id>
+=item B<-inkey> I<filename>|I<uri>
 
 The private key to use when signing or decrypting. This must match the
 corresponding certificate. If this option is not specified then the
 private key must be included in the certificate file specified with
 the B<-recip> or B<-signer> file. When signing this option can be used
 multiple times to specify successive keys.
-If no engine is used, the argument is taken as a file; if an engine is
-specified, the argument is given to the engine as a key identifier.
 
 =item B<-passin> I<arg>
 

+ 4 - 4
doc/man1/openssl-spkac.pod.in

@@ -15,7 +15,7 @@ B<openssl> B<spkac>
 [B<-help>]
 [B<-in> I<filename>]
 [B<-out> I<filename>]
-[B<-key> I<keyfile>]
+[B<-key> I<filename>|I<uri>]
 [B<-keyform> B<DER>|B<PEM>|B<P12>|B<ENGINE>]
 [B<-passin> I<arg>]
 [B<-challenge> I<string>]
@@ -52,10 +52,10 @@ option is not specified. Ignored if the B<-key> option is used.
 Specifies the output filename to write to or standard output by
 default.
 
-=item B<-key> I<keyfile>
+=item B<-key> I<filename>|I<uri>
 
-Create an SPKAC file using the private key in I<keyfile>. The
-B<-in>, B<-noout>, B<-spksect> and B<-verify> options are ignored if
+Create an SPKAC file using the private key specified by I<filename> or I<uri>.
+The B<-in>, B<-noout>, B<-spksect> and B<-verify> options are ignored if
 present.
 
 =item B<-keyform> B<DER>|B<PEM>|B<P12>|B<ENGINE>

+ 2 - 4
doc/man1/openssl-ts.pod.in

@@ -32,7 +32,7 @@ B<-reply>
 [B<-queryfile> I<request.tsq>]
 [B<-passin> I<password_src>]
 [B<-signer> I<tsa_cert.pem>]
-[B<-inkey> I<file_or_id>]
+[B<-inkey> I<filename>|I<uri>]
 [B<-I<digest>>]
 [B<-chain> I<certs_file.pem>]
 [B<-tspolicy> I<object_id>]
@@ -225,12 +225,10 @@ timeStamping. The extended key usage must also be critical, otherwise
 the certificate is going to be refused. Overrides the B<signer_cert>
 variable of the config file. (Optional)
 
-=item B<-inkey> I<file_or_id>
+=item B<-inkey> I<filename>|I<uri>
 
 The signer private key of the TSA in PEM format. Overrides the
 B<signer_key> config file option. (Optional)
-If no engine is used, the argument is taken as a file; if an engine is
-specified, the argument is given to the engine as a key identifier.
 
 =item B<-I<digest>>
 

+ 2 - 0
doc/man1/openssl-verify.pod.in

@@ -79,9 +79,11 @@ Names and values of these options are algorithm-specific.
 {- $OpenSSL::safe::opt_name_item -}
 
 {- $OpenSSL::safe::opt_engine_item -}
+{- output_off() if $disabled{"deprecated-3.0"}; "" -}
 To load certificates or CRLs that require engine support, specify the
 B<-engine> option before any of the
 B<-trusted>, B<-untrusted> or B<-CRLfile> options.
+{- output_on() if $disabled{"deprecated-3.0"}; "" -}
 
 {- $OpenSSL::safe::opt_trust_item -}
 

+ 5 - 5
doc/man1/openssl-x509.pod.in

@@ -45,13 +45,13 @@ B<openssl> B<x509>
 [B<-setalias> I<arg>]
 [B<-days> I<arg>]
 [B<-set_serial> I<n>]
-[B<-signkey> I<arg>]
+[B<-signkey> I<filename>|I<uri>]
 [B<-badsig>]
 [B<-passin> I<arg>]
 [B<-x509toreq>]
 [B<-req>]
 [B<-CA> I<filename>]
-[B<-CAkey> I<filename>]
+[B<-CAkey> I<filename>|I<uri>]
 [B<-CAcreateserial>]
 [B<-CAserial> I<filename>]
 [B<-new>]
@@ -351,10 +351,10 @@ can thus behave like a "mini CA".
 
 =over 4
 
-=item B<-signkey> I<arg>
+=item B<-signkey> I<filename>|I<uri>
 
 This option causes the input file to be self signed using the supplied
-private key or engine.
+private key.
 
 It sets the issuer name to the subject name (i.e., makes it self-issued)
 and changes the public key to the supplied value (unless overridden by
@@ -442,7 +442,7 @@ of the CA and it is digitally signed using the CAs private key.
 This option is normally combined with the B<-req> option. Without the
 B<-req> option the input is a certificate which must be self signed.
 
-=item B<-CAkey> I<filename>
+=item B<-CAkey> I<filename>|I<uri>
 
 Sets the CA private key to sign a certificate with. If this option is
 not specified then it is assumed that the CA private key is present in

+ 34 - 7
doc/man1/openssl.pod

@@ -527,6 +527,10 @@ of formats.
 Since OpenSSL 3.0 keys, single certificates, and CRLs can be read from
 files in any of the B<DER>, B<PEM> or B<P12> formats,
 while specifying their input format is no more needed.
+In order to access a key via an engine the input format B<ENGINE> may be used;
+alternatively the key identifier in the <uri> argument of the respective key
+option may be preceded by C<org.openssl.engine:>.
+See L<openssl(1)/Engine Options> for an example usage of the latter.
 
 The list of acceptable formats, and the default, is
 described in each command documentation.  The list of formats is
@@ -543,9 +547,7 @@ A binary format, encoded or parsed according to Distinguished Encoding Rules
 
 Used to specify that the cryptographic material is in an OpenSSL B<engine>.
 An engine must be configured or specified using the B<-engine> option.
-In addition, the B<-input> flag can be used to name a specific object in
-the engine.
-A password, such as the B<-passin> flag often must be specified as well.
+A password or PIN may be supplied to the engine using the B<-passin> option.
 
 =item B<P12>
 
@@ -1300,13 +1302,38 @@ respectively.
 
 =item B<-engine> I<id>
 
-Use the engine identified by I<id> and use all the methods it
-implements (algorithms, key storage, etc.), unless specified otherwise in
-the command-specific documentation or it is configured to do so, as described
-in L<config(5)/Engine Configuration Module>.
+Load the engine identified by I<id> and use all the methods it implements
+(algorithms, key storage, etc.), unless specified otherwise in the
+command-specific documentation or it is configured to do so, as described in
+L<config(5)/Engine Configuration>.
+
+The engine will be used for key ids specified with B<-key> and similar
+options when an option like B<-keyform engine> is given.
 
 =back
 
+Options specifying keys, like B<-key> and similar, can use the generic
+OpenSSL engine key loading URI scheme C<org.openssl.engine:> to retrieve
+private keys and public keys.  The URI syntax is as follows, in simplified
+form:
+
+    org.openssl.engine:{engineid}:{keyid}
+
+Where C<{engineid}> is the identity/name of the engine, and C<{keyid}> is a
+key identifier that's acceptable by that engine.  For example, when using an
+engine that interfaces against a PKCS#11 implementation, the generic key URI
+would be something like this (this happens to be an example for the PKCS#11
+engine that's part of OpenSC):
+
+    -key org.openssl.engine:pkcs11:label_some-private-key
+
+As a third possibility, for engines and providers that have implemented
+their own L<OSSL_STORE_LOADER(3)>, C<org.openssl.engine:> should not be
+necessary.  For a PKCS#11 implementation that has implemented such a loader,
+the PKCS#11 URI as defined in RFC 7512 should be possible to use directly:
+
+    -key pkcs11:object=some-private-key;pin-value=1234
+
 =head1 ENVIRONMENT
 
 The OpenSSL library can be take some configuration parameters from the