APPS/cmp: improve diagnostics for presence of TLS options
authorDr. David von Oheimb <David.von.Oheimb@siemens.com>
Mon, 6 Dec 2021 13:18:27 +0000 (14:18 +0100)
committerDr. David von Oheimb <dev@ddvo.net>
Thu, 30 Dec 2021 14:04:07 +0000 (15:04 +0100)
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/16747)

apps/cmp.c
doc/man1/openssl-cmp.pod.in

index 9d6d940beb9e96b8fe9fbee770b402ce9dad0c7e..9d0b11399862aa2b4cdec9ecd7a2344c10f94849 100644 (file)
@@ -452,9 +452,9 @@ const OPTIONS cmp_options[] = {
      "Extra certificates to provide to TLS server during TLS handshake"},
     {"tls_trusted", OPT_TLS_TRUSTED, 's',
      "Trusted certificates to use for verifying the TLS server certificate;"},
-    {OPT_MORE_STR, 0, 0, "this implies host name validation"},
+    {OPT_MORE_STR, 0, 0, "this implies hostname validation"},
     {"tls_host", OPT_TLS_HOST, 's',
-     "Address to be checked (rather than -server) during TLS host name validation"},
+     "Address to be checked (rather than -server) during TLS hostname validation"},
 #endif
 
     OPT_SECTION("Client-side debugging"),
@@ -713,12 +713,12 @@ static X509_REQ *load_csr_autofmt(const char *infile, const char *desc)
     return csr;
 }
 
-/* set expected host name/IP addr and clears the email addr in the given ts */
+/* set expected hostname/IP addr and clears the email addr in the given ts */
 static int truststore_set_host_etc(X509_STORE *ts, const char *host)
 {
     X509_VERIFY_PARAM *ts_vpm = X509_STORE_get0_param(ts);
 
-    /* first clear any host names, IP, and email addresses */
+    /* first clear any hostnames, IP, and email addresses */
     if (!X509_VERIFY_PARAM_set1_host(ts_vpm, NULL, 0)
             || !X509_VERIFY_PARAM_set1_ip(ts_vpm, NULL, 0)
             || !X509_VERIFY_PARAM_set1_email(ts_vpm, NULL, 0))
@@ -1239,6 +1239,9 @@ static SSL_CTX *setup_ssl_ctx(OSSL_CMP_CTX *ctx, const char *host,
         if (trust_store == NULL)
             goto err;
         SSL_CTX_set_cert_store(ssl_ctx, trust_store);
+        SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL);
+    } else {
+        CMP_warn("-tls_used given without -tls_trusted; will not authenticate the TLS server");
     }
 
     if (opt_tls_cert != NULL && opt_tls_key != NULL) {
@@ -1347,13 +1350,18 @@ static SSL_CTX *setup_ssl_ctx(OSSL_CMP_CTX *ctx, const char *host,
             goto err;
         }
         EVP_PKEY_free(pkey); /* we do not need the handle any more */
+    } else {
+        CMP_warn("-tls_used given without -tls_key; cannot authenticate to the TLS server");
     }
-    if (opt_tls_trusted != NULL) {
-        /* enable and parameterize server hostname/IP address check */
+    if (trust_store != NULL) {
+        /*
+         * Enable and parameterize server hostname/IP address check.
+         * If we did this before checking our own TLS cert
+         * the expected hostname would mislead the check.
+         */
         if (!truststore_set_host_etc(trust_store,
                                      opt_tls_host != NULL ? opt_tls_host : host))
             goto err;
-        SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL);
     }
     return ssl_ctx;
  err:
@@ -1801,7 +1809,7 @@ static int setup_client_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine)
     int ret = 0;
     char *host = NULL, *port = NULL, *path = NULL, *used_path = opt_path;
 #ifndef OPENSSL_NO_SOCK
-    int portnum, ssl;
+    int portnum, use_ssl;
     static char server_port[32] = { '\0' };
     const char *proxy_host = NULL;
 #endif
@@ -1831,13 +1839,13 @@ static int setup_client_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine)
         }
         goto set_path;
     }
-    if (!OSSL_HTTP_parse_url(opt_server, &ssl, NULL /* user */, &host, &port,
+    if (!OSSL_HTTP_parse_url(opt_server, &use_ssl, NULL /* user */, &host, &port,
                              &portnum, &path, NULL /* q */, NULL /* frag */)) {
         CMP_err1("cannot parse -server URL: %s", opt_server);
         goto err;
     }
-    if (ssl && !opt_tls_used) {
-        CMP_err("missing -tls_used option since -server URL indicates https");
+    if (use_ssl && !opt_tls_used) {
+        CMP_err("missing -tls_used option since -server URL indicates HTTPS");
         goto err;
     }
 
@@ -1855,7 +1863,7 @@ static int setup_client_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine)
                        opt_tls_used ? "s" : "", host, port,
                        *used_path == '/' ? used_path + 1 : used_path);
 
-    proxy_host = OSSL_HTTP_adapt_proxy(opt_proxy, opt_no_proxy, host, ssl);
+    proxy_host = OSSL_HTTP_adapt_proxy(opt_proxy, opt_no_proxy, host, use_ssl);
     if (proxy_host != NULL)
         (void)BIO_snprintf(proxy_buf, sizeof(proxy_buf), " via %s", proxy_host);
 
@@ -2803,11 +2811,13 @@ int cmp_main(int argc, char **argv)
     }
 
 #ifndef OPENSSL_NO_SOCK
-    if ((opt_tls_cert != NULL || opt_tls_key != NULL
-         || opt_tls_keypass != NULL || opt_tls_extra != NULL
-         || opt_tls_trusted != NULL || opt_tls_host != NULL)
-            && !opt_tls_used)
-        CMP_warn("Ingnoring TLS options(s) since -tls_used is not given");
+    if (opt_tls_cert == NULL && opt_tls_key == NULL && opt_tls_keypass == NULL
+            && opt_tls_extra == NULL && opt_tls_trusted == NULL
+            && opt_tls_host == NULL) {
+        if (opt_tls_used)
+            CMP_warn("-tls_used given without any other TLS options");
+    } else if (!opt_tls_used)
+        CMP_warn("ignoring TLS options(s) since -tls_used is not given");
     if (opt_port != NULL) {
         if (opt_tls_used) {
             CMP_err("-tls_used option not supported with -port option");
index c62b2cd962c535bc08b65ffcfaa6751af18731b9..84241a3197de75fb3e828c75e3a45125177d4926 100644 (file)
@@ -445,7 +445,7 @@ The DNS hostname or IP address and optionally port
 of the CMP server to connect to using HTTP(S).
 This excludes I<-port> and I<-use_mock_srv> and is ignored with I<-rspin>.
 
-The scheme C<https> may be given only if the B<-tls_used> option is used.
+The scheme C<https> may be given only if the B<-tls_used> option is provided.
 In this case the default port is 443, else 80.
 The optional userinfo and fragment components are ignored.
 Any given query component is handled as part of the path component.
@@ -457,7 +457,7 @@ The HTTP(S) proxy server to use for reaching the CMP server unless B<-no_proxy>
 applies, see below.
 The proxy port defaults to 80 or 443 if the scheme is C<https>; apart from that
 the optional C<http://> or C<https://> prefix is ignored (note that TLS may be
-selected by B<-tls_used>), as well as any path, userinfo, and query, and fragment
+enabled by B<-tls_used>), as well as any path, userinfo, and query, and fragment
 components.
 Defaults to the environment variable C<http_proxy> if set, else C<HTTP_PROXY>
 in case no TLS is used, otherwise C<https_proxy> if set, else C<HTTPS_PROXY>.
@@ -799,15 +799,17 @@ B<-tls_key>.
 
 =item B<-tls_used>
 
-Enable using TLS (even when other TLS_related options are not set)
-when connecting to CMP server via HTTP.
+Enable using TLS (even when other TLS-related options are not set)
+for message exchange with CMP server via HTTP.
 This option is not supported with the I<-port> option
 and is ignored with the I<-use_mock_srv> and I<-rspin> options
 or if the I<-server> option is not given.
 
+The following TLS-related options are ignored if B<-tls_used> is not given.
+
 =item B<-tls_cert> I<filename>|I<uri>
 
-Client's TLS certificate.
+Client's TLS certificate to use for authenticating to the TLS server.
 If the source includes further certs they are used (along with B<-untrusted>
 certs) for constructing the client cert chain provided to the TLS server.
 
@@ -826,7 +828,7 @@ L<openssl-passphrase-options(1)>.
 
 =item B<-tls_extra> I<filenames>|I<uris>
 
-Extra certificates to provide to TLS server during TLS handshake
+Extra certificates to provide to the TLS server during handshake.
 
 =item B<-tls_trusted> I<filenames>|I<uris>