]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
gnutls-cli will try to verify ocsp responses if --ocsp is given.
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Sat, 28 Jan 2012 18:55:45 +0000 (19:55 +0100)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Sat, 28 Jan 2012 18:55:45 +0000 (19:55 +0100)
src/Makefile.am
src/cli-args.def.in
src/cli.c
src/common.c
src/common.h
src/ocsptool-common.c [new file with mode: 0644]
src/ocsptool-common.h
src/ocsptool.c
src/serv.c

index 136484d3cea96f48ba5f4f5d89d192ac9b9a65d2..f9e77d96c7df8a3f4a146c602055e32dd5271383 100644 (file)
@@ -73,7 +73,7 @@ libcmd_srp_la_SOURCES = srptool-args.def srptool-args.c srptool-args.h
 endif
 
 if ENABLE_OCSP
-ocsptool_SOURCES = ocsptool.c ocsptool-common.h \
+ocsptool_SOURCES = ocsptool.c ocsptool-common.h ocsptool-common.c \
        socket.c socket.h
 ocsptool_LDADD = ../lib/libgnutls.la libcmd-ocsp.la ../gl/libgnu.la $(LIBOPTS_LDADD)
 noinst_LTLIBRARIES += libcmd-ocsp.la
@@ -90,7 +90,7 @@ libcmd_psk_la_SOURCES = psk-args.def psk-args.c psk-args.h
 BENCHMARK_SRCS = benchmark-cipher.c benchmark.c benchmark.h benchmark-tls.c
 
 gnutls_cli_SOURCES = cli.c common.h common.c \
-       socket.c socket.h \
+       socket.c socket.h ocsptool-common.c \
        $(PKCS11_SRCS) $(BENCHMARK_SRCS)
 gnutls_cli_LDADD = ../lib/libgnutls.la
 gnutls_cli_LDADD += libcmd-cli.la ../gl/libgnu.la $(LIBOPTS_LDADD)
index d6979b8cba765417d10e15343cfea14262716216..fc66c12ff7eff6da837e4c0c053fb773b920ea7f 100644 (file)
@@ -44,6 +44,14 @@ flag = {
     doc       = "This option will, in addition to certificate authentication, perform authentication based on stored public keys.";
 };
 
+flag = {
+    name      = ocsp;
+    descrip   = "Enable OCSP certificate verification";
+    disabled;
+    disable   = "no";
+    doc       = "This option will enable verification of the peer's certificate using ocsp";
+};
+
 flag = {
     name      = resume;
     value     = r;
index da4a0a3f3ffc02677b9c8ca32e18667545ec6093..5cb1cd5e003f51b5857623dd14e114e0972e8365 100644 (file)
--- 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;
+}
index 38ea2cffb6ae6891fc5cd771c14e8b604ebb4617..e5ce3c8957a522c12a80c0acfb5f3da54d7a0fbb 100644 (file)
@@ -409,7 +409,8 @@ print_openpgp_info (gnutls_session_t session, int flag)
 
 #endif
 
-/* returns false (0) if not verified, or true (1) otherwise */
+/* returns false (0) if not verified, or true (1) otherwise 
+ */
 int
 cert_verify (gnutls_session_t session, const char* hostname)
 {
@@ -581,13 +582,12 @@ print_ecdh_info (gnutls_session_t session, const char *str)
 }
 
 int
-print_info (gnutls_session_t session, const char *hostname, int insecure)
+print_info (gnutls_session_t session)
 {
     const char *tmp;
     gnutls_credentials_type_t cred;
     gnutls_kx_algorithm_t kx;
     unsigned char session_id[33];
-    int ret;
     size_t session_id_size = sizeof (session_id);
 
     /* print session ID */
@@ -657,13 +657,6 @@ print_info (gnutls_session_t session, const char *hostname, int insecure)
 
           print_cert_info (session, verbose?GNUTLS_CRT_PRINT_FULL:GNUTLS_CRT_PRINT_COMPACT);
 
-          ret = cert_verify (session, hostname);
-          if (insecure == 0 && ret == 0)
-            {
-              fprintf(stderr, "Exiting because verification failed (use --insecure to force connection)\n");
-              exit(1);
-            }
-
           if (kx == GNUTLS_KX_DHE_RSA || kx == GNUTLS_KX_DHE_DSS)
               print_dh_info (session, "Ephemeral ");
           else if (kx == GNUTLS_KX_ECDHE_RSA
index aeeb395e9f32b36d2b337456defcb94a7bd86e96..c2e2dadd95f6b4c537b38570a15a196a775d9d16 100644 (file)
@@ -49,7 +49,7 @@
 
 extern const char str_unknown[];
 
-int print_info (gnutls_session_t state, const char *hostname, int insecure);
+int print_info (gnutls_session_t state);
 void print_cert_info (gnutls_session_t, int flag);
 void print_list (const char* priorities, int verbose);
 int cert_verify (gnutls_session_t session, const char* hostname);
diff --git a/src/ocsptool-common.c b/src/ocsptool-common.c
new file mode 100644 (file)
index 0000000..b52c353
--- /dev/null
@@ -0,0 +1,360 @@
+/*
+ * Copyright (C) 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuTLS.
+ *
+ * GnuTLS is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuTLS is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include <gnutls/gnutls.h>
+#include <gnutls/ocsp.h>
+#include <gnutls/x509.h>
+#include <gnutls/crypto.h>
+
+/* Gnulib portability files. */
+#include <error.h>
+#include <progname.h>
+#include <version-etc.h>
+#include <read-file.h>
+#include <socket.h>
+
+#include <ocsptool-common.h>
+
+#define MAX_BUF 4*1024
+#define HEADER_PATTERN "POST / HTTP/1.1\r\n" \
+  "Host: %s\r\n" \
+  "Accept: */*\r\n" \
+  "Content-Type: application/ocsp-request\r\n" \
+  "Content-Length: %u\r\n" \
+  "Connection: close\r\n\r\n"
+static char buffer[MAX_BUF + 1];
+
+/* returns the host part of a URL */
+static const char* host_from_url(const char* url, unsigned int* port)
+{
+static char hostname[512];
+char * p;
+
+  *port = 0;
+
+  if ((p=strstr(url, "http://")) != NULL)
+    {
+      snprintf(hostname, sizeof(hostname), "%s", p+7);
+      p = strchr(hostname, '/');
+      if (p != NULL) *p = 0;
+
+      p = strchr(hostname, ':');
+      if (p != NULL) {
+        *p = 0;
+        *port = atoi(p+1);
+      }
+      
+      return hostname;
+    }
+  else
+    {
+      return url;
+    }
+}
+
+void
+_generate_request (gnutls_x509_crt_t cert, gnutls_x509_crt_t issuer,
+                   gnutls_datum_t * rdata, int nonce)
+{
+  gnutls_ocsp_req_t req;
+  int ret;
+
+  ret = gnutls_ocsp_req_init (&req);
+  if (ret < 0)
+    error (EXIT_FAILURE, 0, "ocsp_req_init: %s", gnutls_strerror (ret));
+
+  ret = gnutls_ocsp_req_add_cert (req, GNUTLS_DIG_SHA1,
+                                     issuer, cert);
+  if (ret < 0)
+    error (EXIT_FAILURE, 0, "ocsp_req_add_cert: %s", gnutls_strerror (ret));
+    
+  if (nonce)
+    {
+      unsigned char noncebuf[23];
+      gnutls_datum_t nonce = { noncebuf, sizeof (noncebuf) };
+
+      ret = gnutls_rnd (GNUTLS_RND_RANDOM, nonce.data, nonce.size);
+      if (ret < 0)
+       error (EXIT_FAILURE, 0, "gnutls_rnd: %s", gnutls_strerror (ret));
+
+      ret = gnutls_ocsp_req_set_nonce (req, 0, &nonce);
+      if (ret < 0)
+       error (EXIT_FAILURE, 0, "ocsp_req_set_nonce: %s",
+              gnutls_strerror (ret));
+    }
+
+  ret = gnutls_ocsp_req_export (req, rdata);
+  if (ret != 0)
+    error (EXIT_FAILURE, 0, "ocsp_req_export: %s", gnutls_strerror (ret));
+
+  gnutls_ocsp_req_deinit (req);
+  return;
+}
+
+static size_t get_data(void *buffer, size_t size, size_t nmemb, void *userp)
+{
+gnutls_datum_t *ud = userp;
+  
+  size *= nmemb;
+
+  ud->data = realloc(ud->data, size+ud->size);
+  if (ud->data == NULL)
+    {
+      fprintf(stderr, "Not enough memory for the request\n");
+      exit(1);
+    }
+
+  memcpy(&ud->data[ud->size], buffer, size);
+  ud->size += size;
+  
+  return size;
+}
+
+int send_ocsp_request(const char* server,
+                       gnutls_x509_crt_t cert, gnutls_x509_crt_t issuer,
+                       gnutls_datum_t * resp_data, int nonce)
+{
+gnutls_datum_t ud;
+int ret;
+gnutls_datum_t req;
+char* url = (void*)server;
+char headers[1024];
+char service[16];
+unsigned char * p;
+const char *hostname;
+unsigned int headers_size = 0, port;
+socket_st hd;
+
+  sockets_init ();
+
+  if (url == NULL)
+    {
+      /* try to read URL from issuer certificate */
+      gnutls_datum_t data;
+      
+      ret = gnutls_x509_crt_get_authority_info_access(cert, 0, 
+                                  GNUTLS_IA_OCSP_URI, &data, NULL);
+      
+      if (ret < 0)
+        ret = gnutls_x509_crt_get_authority_info_access(issuer, 0, 
+                                    GNUTLS_IA_OCSP_URI, &data, NULL);
+      if (ret < 0)
+        {
+          fprintf(stderr, "Cannot find URL from issuer: %s\n", gnutls_strerror(ret));
+          exit(1);  
+        }
+      
+      url = malloc(data.size+1);
+      memcpy(url, data.data, data.size);
+      url[data.size] = 0;
+      
+      gnutls_free(data.data);
+    }
+    
+  hostname = host_from_url(url, &port);
+  if (port != 0)
+    snprintf(service, sizeof(service), "%u", port);
+  else strcpy(service, "80");
+  
+  fprintf(stderr, "Connecting to OCSP server: %s...\n", hostname);
+
+  memset(&ud, 0, sizeof(ud));
+
+  _generate_request(cert, issuer, &req, nonce);
+
+  snprintf(headers, sizeof(headers), HEADER_PATTERN, hostname, (unsigned int)req.size);
+  headers_size = strlen(headers);
+  
+  socket_open(&hd, hostname, service, 0);
+  socket_connect (&hd);
+  
+  socket_send(&hd, headers, headers_size);
+  socket_send(&hd, req.data, req.size);
+  
+  do {
+    ret = socket_recv(&hd, buffer, sizeof(buffer));
+    if (ret > 0) get_data(buffer, ret, 1, &ud);
+  } while(ret > 0);
+  
+  if (ret < 0 || ud.size == 0)
+    {
+      perror("recv");
+      exit(1);
+    }
+  
+  socket_bye(&hd);
+  
+  p = memmem(ud.data, ud.size, "\r\n\r\n", 4);
+  if (p == NULL)
+    {
+      fprintf(stderr, "Cannot interpret HTTP response\n");
+      exit(1);
+    }
+  
+  p += 4;
+  resp_data->size = ud.size - (p - ud.data);
+  resp_data->data = malloc(resp_data->size);
+  if (resp_data->data == NULL)
+    exit(1);
+  
+  memcpy(resp_data->data, p, resp_data->size);
+
+  free(ud.data);
+  
+  return 0;
+}
+
+void
+print_ocsp_verify_res (unsigned int output)
+{
+  int comma = 0;
+
+  if (output)
+    {
+      printf ("Failure");
+      comma = 1;
+    }
+  else
+    {
+      printf ("Success");
+      comma = 1;
+    }
+
+  if (output & GNUTLS_OCSP_VERIFY_SIGNER_NOT_FOUND)
+    {
+      if (comma)
+        printf (", ");
+      printf ("Signer cert not found");
+      comma = 1;
+    }
+
+  if (output & GNUTLS_OCSP_VERIFY_SIGNER_KEYUSAGE_ERROR)
+    {
+      if (comma)
+        printf (", ");
+      printf ("Signer cert keyusage error");
+      comma = 1;
+    }
+
+  if (output & GNUTLS_OCSP_VERIFY_UNTRUSTED_SIGNER)
+    {
+      if (comma)
+        printf (", ");
+      printf ("Signer cert is not trusted");
+      comma = 1;
+    }
+
+  if (output & GNUTLS_OCSP_VERIFY_INSECURE_ALGORITHM)
+    {
+      if (comma)
+        printf (", ");
+      printf ("Insecure algorithm");
+      comma = 1;
+    }
+
+  if (output & GNUTLS_OCSP_VERIFY_SIGNATURE_FAILURE)
+    {
+      if (comma)
+        printf (", ");
+      printf ("Signature failure");
+      comma = 1;
+    }
+
+  if (output & GNUTLS_OCSP_VERIFY_CERT_NOT_ACTIVATED)
+    {
+      if (comma)
+        printf (", ");
+      printf ("Signer cert not yet activated");
+      comma = 1;
+    }
+
+  if (output & GNUTLS_OCSP_VERIFY_CERT_EXPIRED)
+    {
+      if (comma)
+        printf (", ");
+      printf ("Signer cert expired");
+      comma = 1;
+    }
+}
+
+/* Returns:
+ *  0: certificate is revoked
+ *  1: certificate is ok
+ *  -1: dunno
+ */
+int
+check_ocsp_response (gnutls_certificate_credentials xcred, 
+                      gnutls_datum_t *data)
+{
+  gnutls_ocsp_resp_t resp;
+  int ret;
+  unsigned int status, cert_status;
+  time_t rtime;
+
+  ret = gnutls_ocsp_resp_init (&resp);
+  if (ret < 0)
+    error (EXIT_FAILURE, 0, "ocsp_resp_init: %s", gnutls_strerror (ret));
+
+  ret = gnutls_ocsp_resp_import (resp, data);
+  if (ret < 0)
+    error (EXIT_FAILURE, 0, "importing response: %s", gnutls_strerror (ret));
+
+  ret = gnutls_ocsp_resp_verify_cred (resp, xcred, &status, 0);
+  if (ret < 0)
+    error (EXIT_FAILURE, 0, "gnutls_ocsp_resp_verify: %s",
+              gnutls_strerror (ret));
+
+  printf ("Verifying OCSP Response: ");
+  print_ocsp_verify_res (status);
+  printf (".\n");
+  
+  /* do not print revocation data if response was not verified */
+  if (status != 0)
+    {
+      ret = -1;
+      goto cleanup;
+    }
+
+  ret = gnutls_ocsp_resp_get_single(resp, 0, NULL, NULL, NULL, NULL,
+        &cert_status, NULL, NULL, &rtime, NULL);
+  if (ret < 0)
+    error (EXIT_FAILURE, 0, "reading response: %s", gnutls_strerror (ret));
+  
+  if (cert_status == GNUTLS_OCSP_CERT_REVOKED)
+    {
+      printf("Certificate was revoked at %s\n", ctime(&rtime));
+      ret = 0;
+      goto cleanup;
+    }
+  
+  ret = 1;
+cleanup:
+  gnutls_ocsp_resp_deinit (resp);
+  
+  return ret;
+}
+
index 729d1eb70a9bc69215416ed3fced9492cef85066..ec17cfd3991c84c3ab5b35fa546b2469e1f820a8 100644 (file)
@@ -21,6 +21,8 @@
 #ifndef OCSPTOOL_COMMON_H
 #define OCSPTOOL_COMMON_H
 
+#include <gnutls/ocsp.h>
+
 enum
   {
     ACTION_NONE,
@@ -31,5 +33,17 @@ enum
   };
 
 extern void ocsptool_version (void);
+void
+_generate_request (gnutls_x509_crt_t cert, gnutls_x509_crt_t issuer,
+                   gnutls_datum_t * rdata, int nonce);
+int send_ocsp_request(const char* server,
+                       gnutls_x509_crt_t cert, gnutls_x509_crt_t issuer,
+                       gnutls_datum_t * resp_data, int nonce);
+void
+print_ocsp_verify_res (unsigned int output);
+
+int
+check_ocsp_response (gnutls_certificate_credentials xcred, 
+                      gnutls_datum_t *data);
 
 #endif
index 0e48e44ca0f39115b1b604b5db0b3ca52d2c0a45..93c9c14d9ead12e51303987f19d14913506aa83f 100644 (file)
@@ -192,60 +192,12 @@ load_cert (void)
   return crt;
 }
 
-static void
-_generate_request (gnutls_datum_t * rdata)
-{
-  gnutls_ocsp_req_t req;
-  int ret;
-  gnutls_datum_t dat;
-  gnutls_x509_crt_t issuer, cert;
-
-  ret = gnutls_ocsp_req_init (&req);
-  if (ret < 0)
-    error (EXIT_FAILURE, 0, "ocsp_req_init: %s", gnutls_strerror (ret));
-
-  issuer = load_issuer ();
-  cert = load_cert ();
-  
-  ret = gnutls_ocsp_req_add_cert (req, GNUTLS_DIG_SHA1,
-                                     issuer, cert);
-  if (ret < 0)
-    error (EXIT_FAILURE, 0, "ocsp_req_add_cert: %s", gnutls_strerror (ret));
-    
-  gnutls_x509_crt_deinit (issuer);
-  gnutls_x509_crt_deinit (cert);
-
-  if (ENABLED_OPT(NONCE))
-    {
-      unsigned char noncebuf[23];
-      gnutls_datum_t nonce = { noncebuf, sizeof (noncebuf) };
-
-      ret = gnutls_rnd (GNUTLS_RND_RANDOM, nonce.data, nonce.size);
-      if (ret < 0)
-       error (EXIT_FAILURE, 0, "gnutls_rnd: %s", gnutls_strerror (ret));
-
-      ret = gnutls_ocsp_req_set_nonce (req, 0, &nonce);
-      if (ret < 0)
-       error (EXIT_FAILURE, 0, "ocsp_req_set_nonce: %s",
-              gnutls_strerror (ret));
-    }
-
-  ret = gnutls_ocsp_req_export (req, &dat);
-  if (ret != 0)
-    error (EXIT_FAILURE, 0, "ocsp_req_export: %s", gnutls_strerror (ret));
-
-  gnutls_ocsp_req_deinit (req);
-
-  memcpy(rdata, &dat, sizeof(*rdata));
-  return;
-}
-
 static void
 generate_request (void)
 {
   gnutls_datum_t dat;
   
-  _generate_request(&dat);
+  _generate_request(load_cert(), load_issuer(), &dat, ENABLED_OPT(NONCE));
 
   fwrite (dat.data, 1, dat.size, outfile);
 
@@ -253,79 +205,6 @@ generate_request (void)
 }
 
 
-static void
-print_verify_res (unsigned int output)
-{
-  int comma = 0;
-
-  if (output)
-    {
-      printf ("Failure");
-      comma = 1;
-    }
-  else
-    {
-      printf ("Success");
-      comma = 1;
-    }
-
-  if (output & GNUTLS_OCSP_VERIFY_SIGNER_NOT_FOUND)
-    {
-      if (comma)
-        printf (", ");
-      printf ("Signer cert not found");
-      comma = 1;
-    }
-
-  if (output & GNUTLS_OCSP_VERIFY_SIGNER_KEYUSAGE_ERROR)
-    {
-      if (comma)
-        printf (", ");
-      printf ("Signer cert keyusage error");
-      comma = 1;
-    }
-
-  if (output & GNUTLS_OCSP_VERIFY_UNTRUSTED_SIGNER)
-    {
-      if (comma)
-        printf (", ");
-      printf ("Signer cert is not trusted");
-      comma = 1;
-    }
-
-  if (output & GNUTLS_OCSP_VERIFY_INSECURE_ALGORITHM)
-    {
-      if (comma)
-        printf (", ");
-      printf ("Insecure algorithm");
-      comma = 1;
-    }
-
-  if (output & GNUTLS_OCSP_VERIFY_SIGNATURE_FAILURE)
-    {
-      if (comma)
-        printf (", ");
-      printf ("Signature failure");
-      comma = 1;
-    }
-
-  if (output & GNUTLS_OCSP_VERIFY_CERT_NOT_ACTIVATED)
-    {
-      if (comma)
-        printf (", ");
-      printf ("Signer cert not yet activated");
-      comma = 1;
-    }
-
-  if (output & GNUTLS_OCSP_VERIFY_CERT_EXPIRED)
-    {
-      if (comma)
-        printf (", ");
-      printf ("Signer cert expired");
-      comma = 1;
-    }
-}
-
 static int
 _verify_response (gnutls_datum_t *data)
 {
@@ -437,7 +316,7 @@ _verify_response (gnutls_datum_t *data)
     error (EXIT_FAILURE, 0, "missing --load-trust or --load-signer");
 
   printf ("Verifying OCSP Response: ");
-  print_verify_res (verify);
+  print_ocsp_verify_res (verify);
   printf (".\n");
 
   gnutls_ocsp_resp_deinit (resp);
@@ -462,142 +341,22 @@ verify_response (void)
   _verify_response(&dat);
 }
 
-static size_t get_data(void *buffer, size_t size, size_t nmemb, void *userp)
+static void ask_server(const char* url)
 {
-gnutls_datum_t *ud = userp;
-  
-  size *= nmemb;
-
-  ud->data = realloc(ud->data, size+ud->size);
-  if (ud->data == NULL)
-    {
-      fprintf(stderr, "Not enough memory for the request\n");
-      exit(1);
-    }
-
-  memcpy(&ud->data[ud->size], buffer, size);
-  ud->size += size;
-  
-  return size;
-}
-
-/* returns the host part of a URL */
-static const char* host_from_url(const char* url, unsigned int* port)
-{
-static char hostname[512];
-char * p;
-
-  *port = 0;
-
-  if ((p=strstr(url, "http://")) != NULL)
-    {
-      snprintf(hostname, sizeof(hostname), "%s", p+7);
-      p = strchr(hostname, '/');
-      if (p != NULL) *p = 0;
-
-      p = strchr(hostname, ':');
-      if (p != NULL) {
-        *p = 0;
-        *port = atoi(p+1);
-      }
-      
-      return hostname;
-    }
-  else
-    {
-      return url;
-    }
-}
-
-#define MAX_BUF 4*1024
-#define HEADER_PATTERN "POST / HTTP/1.1\r\n" \
-  "Host: %s\r\n" \
-  "Accept: */*\r\n" \
-  "Content-Type: application/ocsp-request\r\n" \
-  "Content-Length: %u\r\n" \
-  "Connection: close\r\n\r\n"
-static char buffer[MAX_BUF + 1];
-
-static void ask_server(const char* _url)
-{
-gnutls_datum_t ud, resp_data;
+gnutls_datum_t resp_data;
 int ret, v;
-gnutls_datum_t req;
-char* url = (void*)_url;
-char headers[1024];
-char service[16];
-const char *hostname;
-unsigned int headers_size = 0, port;
-socket_st hd;
-
-  sockets_init ();
-
-  if (url == NULL)
-    {
-      /* try to read URL from issuer certificate */
-      gnutls_x509_crt_t issuer = load_issuer();
-      gnutls_datum_t data;
-      
-      ret = gnutls_x509_crt_get_authority_info_access(issuer, 0, 
-                                  GNUTLS_IA_OCSP_URI, &data, NULL);
-      if (ret < 0)
-        {
-          fprintf(stderr, "Cannot find URL from issuer: %s\n", gnutls_strerror(ret));
-          exit(1);  
-        }
-      
-      url = malloc(data.size+1);
-      memcpy(url, data.data, data.size);
-      url[data.size] = 0;
-      
-      gnutls_free(data.data);
-      
-      gnutls_x509_crt_deinit(issuer);
-    }
-    
-  hostname = host_from_url(url, &port);
-  if (port != 0)
-    snprintf(service, sizeof(service), "%u", port);
-  else strcpy(service, "80");
-  
-  fprintf(stderr, "Connecting to %s\n", hostname);
+gnutls_x509_crt_t cert, issuer;
 
-  memset(&ud, 0, sizeof(ud));
-
-  _generate_request(&req);
-
-  snprintf(headers, sizeof(headers), HEADER_PATTERN, hostname, (unsigned int)req.size);
-  headers_size = strlen(headers);
-  
-  socket_open(&hd, hostname, service, 0);
-  socket_connect (&hd);
-  
-  socket_send(&hd, headers, headers_size);
-  socket_send(&hd, req.data, req.size);
-  
-  do {
-    ret = socket_recv(&hd, buffer, sizeof(buffer));
-    if (ret > 0) get_data(buffer, ret, 1, &ud);
-  } while(ret > 0);
-  
-  if (ret < 0 || ud.size == 0)
-    {
-      perror("recv");
-      exit(1);
-    }
+  cert = load_cert();
+  issuer = load_issuer();
   
-  socket_bye(&hd);
-  
-  resp_data.data = memmem(ud.data, ud.size, "\r\n\r\n", 4);
-  if (resp_data.data == NULL)
+  ret = send_ocsp_request(url, cert, issuer, &resp_data, ENABLED_OPT(NONCE));
+  if (ret < 0)
     {
-      fprintf(stderr, "Cannot interpret HTTP response\n");
+      fprintf(stderr, "Cannot send OCSP request\n");
       exit(1);
     }
   
-  resp_data.data += 4;
-  resp_data.size = ud.size - (resp_data.data - ud.data);
-  
   _response_info (&resp_data);
 
   if (HAVE_OPT(LOAD_SIGNER) || HAVE_OPT(LOAD_TRUST))
index 151ee301e3d85134098e2462828f34b1bf8bfde7..88d0be75e28e493c6da9a93f4d84b2960e8e8ca5 100644 (file)
@@ -1309,7 +1309,8 @@ static void tcp_server(const char* name, int port)
                                 human_addr ((struct sockaddr *)
                                             &client_address, calen, topbuf,
                                             sizeof (topbuf)));
-                        print_info (j->tls_session, NULL, 1);
+                        print_info (j->tls_session);
+                        cert_verify(j->tls_session, NULL);
                       }
                     j->handshake_ok = 1;
                   }
@@ -1432,7 +1433,8 @@ static void tcp_server(const char* name, int port)
                                             &client_address, calen, topbuf,
                                             sizeof (topbuf)));
 
-                        print_info (j->tls_session, NULL, 1);
+                        print_info (j->tls_session);
+                        cert_verify(j->tls_session, NULL);
                       }
                     j->handshake_ok = 1;
                   }