From afaffc51369a31cf32cacf58cc61d65957746f01 Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos Date: Mon, 23 Apr 2018 13:58:22 +0200 Subject: gnutls-cli: added option to specify the verification hostname This enables testing various scenarios, by allowing to specify the hostname to be used for certificate validation when connecting to a remote host (e.g., localhost but with a certificate for example.com). Resolves #344 Signed-off-by: Nikos Mavrogiannopoulos --- src/cli-args.def | 7 +++++++ src/cli.c | 22 ++++++++++++++-------- 2 files changed, 21 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/cli-args.def b/src/cli-args.def index 8ad9a98ed3..2dfad14502 100644 --- a/src/cli-args.def +++ b/src/cli-args.def @@ -88,6 +88,13 @@ flag = { doc = "Set explicitly the server name used in the TLS server name indication extension. That is useful when testing with servers setup on different DNS name than the intended. If not specified, the provided hostname is used."; }; +flag = { + name = verify-hostname; + descrip = "Server's hostname to use for validation"; + arg-type = string; + doc = "Set explicitly the server name to be used when validating the server's certificate."; +}; + flag = { name = starttls; value = s; diff --git a/src/cli.c b/src/cli.c index e1d9c7aa67..27db30d7c1 100644 --- a/src/cli.c +++ b/src/cli.c @@ -325,6 +325,7 @@ static int cert_verify_callback(gnutls_session_t session) int ca_verify = ENABLED_OPT(CA_VERIFICATION); const char *txt_service; gnutls_datum_t oresp; + const char *host; /* On an session with TOFU the PKI/DANE verification * become advisory. @@ -334,6 +335,11 @@ static int cert_verify_callback(gnutls_session_t session) ssh = strictssh; } + if (HAVE_OPT(VERIFY_HOSTNAME)) + host = OPT_ARG(VERIFY_HOSTNAME); + else + host = hostname; + /* Save certificate and OCSP response */ if (HAVE_OPT(SAVE_CERT)) { try_save_cert(session); @@ -357,7 +363,7 @@ static int cert_verify_callback(gnutls_session_t session) print_cert_info(session, verbose, print_cert); if (ca_verify) { - rc = cert_verify(session, hostname, GNUTLS_KP_TLS_WWW_SERVER); + rc = cert_verify(session, host, GNUTLS_KP_TLS_WWW_SERVER); if (rc == 0) { printf ("*** PKI verification of server certificate failed...\n"); @@ -391,7 +397,7 @@ static int cert_verify_callback(gnutls_session_t session) vflags |= DANE_VFLAG_ONLY_CHECK_EE_USAGE; port = service_to_port(service, udp?"udp":"tcp"); - rc = dane_verify_session_crt(NULL, session, hostname, + rc = dane_verify_session_crt(NULL, session, host, udp ? "udp" : "tcp", port, sflags, vflags, &status); if (rc < 0) { @@ -436,17 +442,17 @@ static int cert_verify_callback(gnutls_session_t session) txt_service = port_to_service(service, udp?"udp":"tcp"); - rc = gnutls_verify_stored_pubkey(NULL, NULL, hostname, + rc = gnutls_verify_stored_pubkey(NULL, NULL, host, txt_service, GNUTLS_CRT_X509, cert, 0); if (rc == GNUTLS_E_NO_CERTIFICATE_FOUND) { fprintf(stderr, "Host %s (%s) has never been contacted before.\n", - hostname, txt_service); + host, txt_service); if (status == 0) fprintf(stderr, "Its certificate is valid for %s.\n", - hostname); + host); if (strictssh) return -1; @@ -458,13 +464,13 @@ static int cert_verify_callback(gnutls_session_t session) } else if (rc == GNUTLS_E_CERTIFICATE_KEY_MISMATCH) { fprintf(stderr, "Warning: host %s is known and it is associated with a different key.\n", - hostname); + host); fprintf(stderr, "It might be that the server has multiple keys, or an attacker replaced the key to eavesdrop this connection .\n"); if (status == 0) fprintf(stderr, "Its certificate is valid for %s.\n", - hostname); + host); if (strictssh) return -1; @@ -481,7 +487,7 @@ static int cert_verify_callback(gnutls_session_t session) } if (rc != 0) { - rc = gnutls_store_pubkey(NULL, NULL, hostname, + rc = gnutls_store_pubkey(NULL, NULL, host, txt_service, GNUTLS_CRT_X509, cert, 0, 0); -- cgit v1.2.1