]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Include only a single example with X.509 client. This example includes certificate...
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Fri, 4 Nov 2011 21:03:25 +0000 (22:03 +0100)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Fri, 4 Nov 2011 21:03:25 +0000 (22:03 +0100)
doc/Makefile.am
doc/cha-gtls-app.texi
doc/examples/Makefile.am
doc/examples/ex-client-udp.c
doc/examples/ex-client2.c [deleted file]
doc/examples/ex-rfc2818.c
doc/examples/examples.h
doc/examples/verify.c [new file with mode: 0644]

index 2619eb87fb435c8f14b1ef935c9bcfb015d0c9aa..b99224b42c5831dc76bb797cd010d28398eaca7d 100644 (file)
@@ -38,7 +38,7 @@ gnutls_TEXINFOS = gnutls.texi fdl-1.3.texi lgpl-2.1.texi gpl-3.0.texi \
        sec-tls-app.texi cha-errors.texi cha-support.texi
 
 # Examples.
-gnutls_TEXINFOS += examples/ex-client1.c examples/ex-client2.c         \
+gnutls_TEXINFOS += examples/ex-client1.c               \
        examples/ex-session-info.c examples/ex-verify.c                 \
        examples/ex-cert-select.c examples/ex-client-resume.c           \
        examples/ex-client-srp.c examples/ex-rfc2818.c                  \
index 1e20f02fcedd902bd0f34ae287d676e1f39cf393..72aab12e6d5641ea9ae3243ea54bc44f24af3eea 100644 (file)
@@ -480,7 +480,6 @@ implemented by another example.
 * Simple client example with X.509 certificate support::
 * Simple Datagram TLS client example::
 * Obtaining session information::
-* Verifying peer's certificate::
 * Using a callback to select the certificate to use::
 * Verifying a certificate::
 * Client using a PKCS 11 token with TLS::
@@ -503,16 +502,17 @@ However, the data is integrity and privacy protected.
 
 @node Simple client example with X.509 certificate support
 @subsection Simple client example with @acronym{X.509} certificate support
+@anchor{ex:verify}
 
 Let's assume now that we want to create a TCP client which
 communicates with servers that use @acronym{X.509} or
 @acronym{OpenPGP} certificate authentication. The following client is
-a very simple @acronym{TLS} client, it does not support session
-resuming, not even certificate verification. The TCP functions defined
-in this example are used in most of the other examples below, without
-redefining them.
+a very simple @acronym{TLS} client, which uses the high level verification
+functions for certificates, but does not support session
+resumption. The TCP functions defined in this example are used 
+in most of the other examples below, without redefining them.
 
-@verbatiminclude examples/ex-client2.c
+@verbatiminclude examples/ex-rfc2818.c
 
 @node Simple Datagram TLS client example
 @subsection Simple datagram @acronym{TLS} client example
@@ -534,19 +534,6 @@ if called after a successful @funcref{gnutls_handshake}.
 
 @verbatiminclude examples/ex-session-info.c
 
-@node Verifying peer's certificate
-@subsection Verifying peer's certificate
-@anchor{ex:verify}
-
-A @acronym{TLS} session is not secure just after the handshake
-procedure has finished.  It must be considered secure, only after the
-peer's certificate and identity have been verified. That is, you have
-to verify the signature in peer's certificate, the hostname in the
-certificate, and expiration dates.  Just after this step you should
-treat the connection as being a secure one.
-
-@verbatiminclude examples/ex-rfc2818.c
-
 @node Using a callback to select the certificate to use
 @subsection Using a callback to select the certificate to use
 
index 76afe837ab99aeb0e189b6f3ab3bf3971f224de1..0ed1eae2db4d9789e5162c206266536f69dac3a2 100644 (file)
@@ -41,7 +41,7 @@ LDADD = libexamples.la                                \
 CXX_LDADD = $(LDADD) \
        ../../lib/libgnutlsxx.la
 
-noinst_PROGRAMS = ex-client2 ex-client-resume ex-client-udp
+noinst_PROGRAMS = ex-client-resume ex-client-udp
 noinst_PROGRAMS += ex-cert-select ex-rfc2818
 
 if ENABLE_PKI
@@ -81,4 +81,4 @@ noinst_LTLIBRARIES = libexamples.la
 
 libexamples_la_SOURCES = examples.h ex-alert.c ex-pkcs12.c             \
        ex-session-info.c ex-x509-info.c ex-verify.c    \
-       tcp.c udp.c ex-pkcs11-list.c
+       tcp.c udp.c ex-pkcs11-list.c verify.c
index a2e6cccad6be6c382cc6695700708d1d0243772d..7a0721a8562afe25e05e71be55c4c9e196c70fda 100644 (file)
@@ -23,6 +23,7 @@
 
 extern int udp_connect (void);
 extern void udp_close (int sd);
+extern int verify_certificate_callback (gnutls_session_t session);
 
 int
 main (void)
@@ -40,6 +41,7 @@ main (void)
 
   /* 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);
 
   /* Initialize TLS session */
   gnutls_init (&session, GNUTLS_CLIENT | GNUTLS_DATAGRAM);
diff --git a/doc/examples/ex-client2.c b/doc/examples/ex-client2.c
deleted file mode 100644 (file)
index e58c910..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-/* This example code is placed in the public domain. */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-#include <unistd.h>
-#include <gnutls/gnutls.h>
-
-/* A very basic TLS client, with X.509 authentication.
- */
-
-#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);
-
-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);
-
-  /* Initialize TLS session 
-   */
-  gnutls_init (&session, GNUTLS_CLIENT);
-
-  /* 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;
-}
index 04114f41ba51a20856d06fbe528f2389209fd381..f7aa08d0682dd96de4751f8311304ea4690bf827 100644 (file)
 
 extern int tcp_connect (void);
 extern void tcp_close (int sd);
+static int _verify_certificate_callback (gnutls_session_t session);
 
-/* This function will try to verify the peer's certificate, and
- * also check if the hostname matches, and the activation, expiration dates.
- */
-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 GNUTLS_E_CERTIFICATE_ERROR;
-    }
-
-  if (status & GNUTLS_CERT_INVALID)
-    printf ("The certificate is not trusted.\n");
-
-  if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
-    printf ("The certificate hasn't got a known issuer.\n");
-
-  if (status & GNUTLS_CERT_REVOKED)
-    printf ("The certificate has been revoked.\n");
-
-  if (status & GNUTLS_CERT_EXPIRED)
-    printf ("The certificate has expired\n");
-
-  if (status & GNUTLS_CERT_NOT_ACTIVATED)
-    printf ("The certificate is not yet activated\n");
-
-  /* Up to here the process is the same for X.509 certificates and
-   * OpenPGP keys. From now on X.509 certificates are assumed. This can
-   * be easily extended to work with openpgp keys as well.
-   */
-  if (gnutls_certificate_type_get (session) != GNUTLS_CRT_X509)
-    return GNUTLS_E_CERTIFICATE_ERROR;
-
-  if (gnutls_x509_crt_init (&cert) < 0)
-    {
-      printf ("error in initialization\n");
-      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 GNUTLS_E_CERTIFICATE_ERROR;
-    }
-
-  /* This is not a real world example, since we only check the first 
-   * certificate in the given chain.
-   */
-  if (gnutls_x509_crt_import (cert, &cert_list[0], GNUTLS_X509_FMT_DER) < 0)
-    {
-      printf ("error parsing certificate\n");
-      return GNUTLS_E_CERTIFICATE_ERROR;
-    }
-
-
-  if (!gnutls_x509_crt_check_hostname (cert, hostname))
-    {
-      printf ("The certificate's owner does not match hostname '%s'\n",
-              hostname);
-      return GNUTLS_E_CERTIFICATE_ERROR;
-    }
-
-  gnutls_x509_crt_deinit (cert);
-
-  /* notify gnutls to continue handshake normally */
-  return 0;
-}
-
-
-int
-main (void)
+int main (void)
 {
   int ret, sd, ii;
   gnutls_session_t session;
@@ -124,9 +39,7 @@ main (void)
   /* 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);
+  gnutls_certificate_set_verify_function (xcred, _verify_certificate_callback);
 
   /* Initialize TLS session 
    */
@@ -135,7 +48,7 @@ main (void)
   gnutls_session_set_ptr (session, (void *) "my_host_name");
 
   /* Use default priorities */
-  ret = gnutls_priority_set_direct (session, "PERFORMANCE", &err);
+  ret = gnutls_priority_set_direct (session, "NORMAL", &err);
   if (ret < 0)
     {
       if (ret == GNUTLS_E_INVALID_REQUEST)
@@ -205,3 +118,88 @@ end:
 
   return 0;
 }
+
+/* This function will verify the peer's certificate, and check
+ * if the hostname matches, as well as the activation, expiration dates.
+ */
+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 GNUTLS_E_CERTIFICATE_ERROR;
+    }
+
+  if (status & GNUTLS_CERT_INVALID)
+    printf ("The certificate is not trusted.\n");
+
+  if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
+    printf ("The certificate hasn't got a known issuer.\n");
+
+  if (status & GNUTLS_CERT_REVOKED)
+    printf ("The certificate has been revoked.\n");
+
+  if (status & GNUTLS_CERT_EXPIRED)
+    printf ("The certificate has expired\n");
+
+  if (status & GNUTLS_CERT_NOT_ACTIVATED)
+    printf ("The certificate is not yet activated\n");
+
+  /* Up to here the process is the same for X.509 certificates and
+   * OpenPGP keys. From now on X.509 certificates are assumed. This can
+   * be easily extended to work with openpgp keys as well.
+   */
+  if (gnutls_certificate_type_get (session) != GNUTLS_CRT_X509)
+    return GNUTLS_E_CERTIFICATE_ERROR;
+
+  if (gnutls_x509_crt_init (&cert) < 0)
+    {
+      printf ("error in initialization\n");
+      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 GNUTLS_E_CERTIFICATE_ERROR;
+    }
+
+  /* This is not a real world example, since we only check the first 
+   * certificate in the given chain.
+   */
+  if (gnutls_x509_crt_import (cert, &cert_list[0], GNUTLS_X509_FMT_DER) < 0)
+    {
+      printf ("error parsing certificate\n");
+      return GNUTLS_E_CERTIFICATE_ERROR;
+    }
+
+
+  if (!gnutls_x509_crt_check_hostname (cert, hostname))
+    {
+      printf ("The certificate's owner does not match hostname '%s'\n",
+              hostname);
+      return GNUTLS_E_CERTIFICATE_ERROR;
+    }
+
+  gnutls_x509_crt_deinit (cert);
+
+  /* notify gnutls to continue handshake normally */
+  return 0;
+}
+
index 286f4ff185bc6dceb5eea10085c95195164d4f50..e96cb26080ab5f5416457424387f2f5c1f978dd1 100644 (file)
@@ -3,8 +3,7 @@
 
 void check_alert (gnutls_session_t session, int ret);
 
-int
-write_pkcs12 (const gnutls_datum_t * cert,
+int write_pkcs12 (const gnutls_datum_t * cert,
               const gnutls_datum_t * pkcs8_key, const char *password);
 
 void verify_certificate (gnutls_session_t session, const char *hostname);
@@ -18,4 +17,6 @@ verify_certificate_chain (const char *hostname,
                           const gnutls_datum_t * cert_chain,
                           int cert_chain_length);
 
+int verify_certificate_callback (gnutls_session_t session);
+
 #endif /* EXAMPLES_H */
diff --git a/doc/examples/verify.c b/doc/examples/verify.c
new file mode 100644 (file)
index 0000000..da7f4f7
--- /dev/null
@@ -0,0 +1,89 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <gnutls/gnutls.h>
+#include <gnutls/x509.h>
+
+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 GNUTLS_E_CERTIFICATE_ERROR;
+    }
+
+  if (status & GNUTLS_CERT_INVALID)
+    printf ("The certificate is not trusted.\n");
+
+  if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
+    printf ("The certificate hasn't got a known issuer.\n");
+
+  if (status & GNUTLS_CERT_REVOKED)
+    printf ("The certificate has been revoked.\n");
+
+  if (status & GNUTLS_CERT_EXPIRED)
+    printf ("The certificate has expired\n");
+
+  if (status & GNUTLS_CERT_NOT_ACTIVATED)
+    printf ("The certificate is not yet activated\n");
+
+  /* Up to here the process is the same for X.509 certificates and
+   * OpenPGP keys. From now on X.509 certificates are assumed. This can
+   * be easily extended to work with openpgp keys as well.
+   */
+  if (gnutls_certificate_type_get (session) != GNUTLS_CRT_X509)
+    return GNUTLS_E_CERTIFICATE_ERROR;
+
+  if (gnutls_x509_crt_init (&cert) < 0)
+    {
+      printf ("error in initialization\n");
+      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 GNUTLS_E_CERTIFICATE_ERROR;
+    }
+
+  /* This is not a real world example, since we only check the first 
+   * certificate in the given chain.
+   */
+  if (gnutls_x509_crt_import (cert, &cert_list[0], GNUTLS_X509_FMT_DER) < 0)
+    {
+      printf ("error parsing certificate\n");
+      return GNUTLS_E_CERTIFICATE_ERROR;
+    }
+
+
+  if (!gnutls_x509_crt_check_hostname (cert, hostname))
+    {
+      printf ("The certificate's owner does not match hostname '%s'\n",
+              hostname);
+      return GNUTLS_E_CERTIFICATE_ERROR;
+    }
+
+  gnutls_x509_crt_deinit (cert);
+
+  /* notify gnutls to continue handshake normally */
+  return 0;
+}