]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
ex-rfc2818 is now a functional program demonstrating the verification procedure.
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Thu, 8 Jul 2010 15:55:54 +0000 (17:55 +0200)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Thu, 8 Jul 2010 15:55:54 +0000 (17:55 +0200)
doc/cha-gtls-app.texi
doc/examples/Makefile.am
doc/examples/ex-rfc2818.c

index a15c4d9ebb0d87322420939312359dc55508736a..5e08aa32920eda54b839c117f73f6f3fb945ab9b 100644 (file)
@@ -233,8 +233,8 @@ treat the connection as being a secure one.
 
 @verbatiminclude examples/ex-rfc2818.c
 
-An other example is listed below which provides a more detailed
-verification output.
+Another example is listed below which provides more detailed
+verification output, for applications that need it.
 
 @verbatiminclude examples/ex-verify.c
 
index bbdec1fcd7883162f6ff37cfdddedfce3d1148aa..9a19409c7f5f88fe553b80d3111c32322d5a2cc6 100644 (file)
@@ -42,7 +42,7 @@ CXX_LDADD = $(LDADD) \
        ../../lib/libgnutlsxx.la
 
 noinst_PROGRAMS = ex-client2 ex-client-resume
-noinst_PROGRAMS += ex-cert-select
+noinst_PROGRAMS += ex-cert-select ex-rfc2818
 
 if ENABLE_PKI
 noinst_PROGRAMS += ex-crq ex-serv1
@@ -77,5 +77,5 @@ endif
 noinst_LTLIBRARIES = libexamples.la
 
 libexamples_la_SOURCES = examples.h ex-alert.c ex-pkcs12.c             \
-       ex-rfc2818.c ex-session-info.c ex-x509-info.c ex-verify.c       \
+       ex-session-info.c ex-x509-info.c ex-verify.c    \
        tcp.c ex-cert-select-pkcs11.c
index 1df60a88e8b065e94223022119fd24e2224a1e6d..693e5f5e3c43971d95afe693f5aff21195c77767 100644 (file)
@@ -5,33 +5,46 @@
 #endif
 
 #include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 #include <gnutls/gnutls.h>
 #include <gnutls/x509.h>
-
 #include "examples.h"
 
+/* A very basic TLS client, with X.509 authentication and server certificate
+ * verification.
+ */
+
+#define MAX_BUF 1024
+#define CAFILE "ca.pem"
+#define MSG "GET / HTTP/1.0\r\n\r\n"
+
+extern int tcp_connect (void);
+extern void tcp_close (int sd);
+
 /* This function will try to verify the peer's certificate, and
  * also check if the hostname matches, and the activation, expiration dates.
  */
-void
-verify_certificate (gnutls_session_t session, const char *hostname)
+static int verify_certificate_callback (gnutls_session_t session)
 {
   unsigned int status;
   const gnutls_datum_t *cert_list;
   unsigned int cert_list_size;
   int ret;
   gnutls_x509_crt_t cert;
+  const char *hostname;
 
+  /* read hostname */
+  hostname = gnutls_session_get_ptr(session);
 
   /* This verification function uses the trusted CAs in the credentials
    * structure. So you must have installed one or more CA certificates.
    */
   ret = gnutls_certificate_verify_peers2 (session, &status);
-
   if (ret < 0)
     {
       printf ("Error\n");
-      return;
+      return GNUTLS_E_CERTIFICATE_ERROR;
     }
 
   if (status & GNUTLS_CERT_INVALID)
@@ -54,19 +67,19 @@ verify_certificate (gnutls_session_t session, const char *hostname)
    * be easily extended to work with openpgp keys as well.
    */
   if (gnutls_certificate_type_get (session) != GNUTLS_CRT_X509)
-    return;
+    return GNUTLS_E_CERTIFICATE_ERROR;
 
   if (gnutls_x509_crt_init (&cert) < 0)
     {
       printf ("error in initialization\n");
-      return;
+      return GNUTLS_E_CERTIFICATE_ERROR;
     }
 
   cert_list = gnutls_certificate_get_peers (session, &cert_list_size);
   if (cert_list == NULL)
     {
       printf ("No certificate was found!\n");
-      return;
+      return GNUTLS_E_CERTIFICATE_ERROR;
     }
 
   /* This is not a real world example, since we only check the first 
@@ -75,7 +88,7 @@ verify_certificate (gnutls_session_t session, const char *hostname)
   if (gnutls_x509_crt_import (cert, &cert_list[0], GNUTLS_X509_FMT_DER) < 0)
     {
       printf ("error parsing certificate\n");
-      return;
+      return GNUTLS_E_CERTIFICATE_ERROR;
     }
 
 
@@ -83,10 +96,110 @@ verify_certificate (gnutls_session_t session, const char *hostname)
     {
       printf ("The certificate's owner does not match hostname '%s'\n",
              hostname);
-      return;
+      return GNUTLS_E_CERTIFICATE_ERROR;
     }
 
   gnutls_x509_crt_deinit (cert);
 
-  return;
+  /* notify gnutls to continue handshake normally */
+  return 0;
+}
+
+
+int
+main (void)
+{
+  int ret, sd, ii;
+  gnutls_session_t session;
+  char buffer[MAX_BUF + 1];
+  const char *err;
+  gnutls_certificate_credentials_t xcred;
+
+  gnutls_global_init ();
+
+  /* X509 stuff */
+  gnutls_certificate_allocate_credentials (&xcred);
+
+  /* sets the trusted cas file
+   */
+  gnutls_certificate_set_x509_trust_file (xcred, CAFILE, GNUTLS_X509_FMT_PEM);
+  gnutls_certificate_set_verify_function (xcred, verify_certificate_callback);
+  gnutls_certificate_set_verify_flags(xcred, GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT);
+
+  /* Initialize TLS session 
+   */
+  gnutls_init (&session, GNUTLS_CLIENT);
+
+  gnutls_session_set_ptr(session, (void*)"my_host_name");
+
+  /* Use default priorities */
+  ret = gnutls_priority_set_direct (session, "PERFORMANCE", &err);
+  if (ret < 0)
+    {
+      if (ret == GNUTLS_E_INVALID_REQUEST)
+       {
+         fprintf (stderr, "Syntax error at: %s\n", err);
+       }
+      exit (1);
+    }
+
+  /* put the x509 credentials to the current session
+   */
+  gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
+
+  /* connect to the peer
+   */
+  sd = tcp_connect ();
+
+  gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) sd);
+
+  /* Perform the TLS handshake
+   */
+  ret = gnutls_handshake (session);
+
+  if (ret < 0)
+    {
+      fprintf (stderr, "*** Handshake failed\n");
+      gnutls_perror (ret);
+      goto end;
+    }
+  else
+    {
+      printf ("- Handshake was completed\n");
+    }
+
+  gnutls_record_send (session, MSG, strlen (MSG));
+
+  ret = gnutls_record_recv (session, buffer, MAX_BUF);
+  if (ret == 0)
+    {
+      printf ("- Peer has closed the TLS connection\n");
+      goto end;
+    }
+  else if (ret < 0)
+    {
+      fprintf (stderr, "*** Error: %s\n", gnutls_strerror (ret));
+      goto end;
+    }
+
+  printf ("- Received %d bytes: ", ret);
+  for (ii = 0; ii < ret; ii++)
+    {
+      fputc (buffer[ii], stdout);
+    }
+  fputs ("\n", stdout);
+
+  gnutls_bye (session, GNUTLS_SHUT_RDWR);
+
+end:
+
+  tcp_close (sd);
+
+  gnutls_deinit (session);
+
+  gnutls_certificate_free_credentials (xcred);
+
+  gnutls_global_deinit ();
+
+  return 0;
 }