summaryrefslogtreecommitdiff
path: root/src/cli.c
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2012-01-28 19:55:45 +0100
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2012-01-28 19:55:45 +0100
commit0fcf4c8bd71df103f56bd532b64cbb5466381546 (patch)
tree06eae70e46ae072990c0d814eb8218f2bb18dbab /src/cli.c
parentefaa2ee176568fcd009ff2ca9daa1b7fdac4c491 (diff)
downloadgnutls-0fcf4c8bd71df103f56bd532b64cbb5466381546.tar.gz
gnutls-cli will try to verify ocsp responses if --ocsp is given.
Diffstat (limited to 'src/cli.c')
-rw-r--r--src/cli.c86
1 files changed, 85 insertions, 1 deletions
diff --git a/src/cli.c b/src/cli.c
index da4a0a3f3f..5cb1cd5e00 100644
--- a/src/cli.c
+++ b/src/cli.c
@@ -57,6 +57,7 @@
#include <gettext.h>
#include <cli-args.h>
+#include <ocsptool-common.h>
#define MAX_BUF 4096
@@ -100,6 +101,7 @@ static gnutls_certificate_credentials_t xcred;
static void check_rehandshake (socket_st * socket, int ret);
static int do_handshake (socket_st * socket);
static void init_global_tls_stuff (void);
+static int cert_verify_ocsp (gnutls_session_t session);
/* Helper functions to load a certificate and key
* files into memory.
@@ -461,6 +463,18 @@ cert_verify_callback (gnutls_session_t session)
if (!insecure && !ssh)
return -1;
}
+ else if (ENABLED_OPT(OCSP))
+ { /* off-line verification succeeded. Try OCSP */
+ rc = cert_verify_ocsp(session);
+ if (rc == 0)
+ {
+ printf ("*** Verifying (with OCSP) server certificate failed...\n");
+ if (!insecure && !ssh)
+ return -1;
+ }
+ else if (rc == -1)
+ printf("*** OCSP response ignored\n");
+ }
if (ssh) /* try ssh auth */
{
@@ -1229,7 +1243,7 @@ do_handshake (socket_st * socket)
if (ret == 0)
{
/* print some information */
- print_info (socket->session, socket->hostname, HAVE_OPT(INSECURE));
+ print_info (socket->session);
socket->secure = 1;
}
else
@@ -1441,4 +1455,74 @@ init_global_tls_stuff (void)
}
+/* Returns:
+ * 0: certificate is revoked
+ * 1: certificate is ok
+ * -1: dunno
+ */
+static int
+cert_verify_ocsp (gnutls_session_t session)
+{
+ gnutls_x509_crt_t crt, issuer;
+ const gnutls_datum_t *cert_list;
+ unsigned int cert_list_size = 0;
+ int deinit_issuer = 0;
+ gnutls_datum_t resp;
+ int ret;
+
+ cert_list = gnutls_certificate_get_peers (session, &cert_list_size);
+ if (cert_list_size == 0)
+ {
+ fprintf (stderr, "No certificates found!\n");
+ return -1;
+ }
+ gnutls_x509_crt_init (&crt);
+ ret =
+ gnutls_x509_crt_import (crt, &cert_list[0],
+ GNUTLS_X509_FMT_DER);
+ if (ret < 0)
+ {
+ fprintf (stderr, "Decoding error: %s\n",
+ gnutls_strerror (ret));
+ return -1;
+ }
+
+ ret = gnutls_certificate_get_issuer(xcred, crt, &issuer, 0);
+ if (ret < 0 && cert_list_size > 1)
+ {
+ gnutls_x509_crt_init(&issuer);
+ ret = gnutls_x509_crt_import(issuer, &cert_list[1], GNUTLS_X509_FMT_DER);
+ if (ret < 0)
+ {
+ fprintf (stderr, "Decoding error: %s\n",
+ gnutls_strerror (ret));
+ return -1;
+ }
+ deinit_issuer = 1;
+ }
+ else if (ret < 0)
+ {
+ fprintf(stderr, "Cannot find issuer\n");
+ ret = -1;
+ goto cleanup;
+ }
+
+ ret = send_ocsp_request(NULL, crt, issuer, &resp, 1);
+ if (ret < 0)
+ {
+ fprintf(stderr, "Cannot contact OCSP server\n");
+ ret = -1;
+ goto cleanup;
+ }
+
+ /* verify and check the response for revoked cert */
+ ret = check_ocsp_response(xcred, &resp);
+
+cleanup:
+ if (deinit_issuer)
+ gnutls_x509_crt_deinit (issuer);
+ gnutls_x509_crt_deinit (crt);
+
+ return ret;
+}