From: Nikos Mavrogiannopoulos Date: Thu, 8 Jul 2010 15:55:54 +0000 (+0200) Subject: ex-rfc2818 is now a functional program demonstrating the verification procedure. X-Git-Tag: gnutls_2_11_3~105 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ae9f09b7e71dab272b483e22c0888075dfd3aec0;p=thirdparty%2Fgnutls.git ex-rfc2818 is now a functional program demonstrating the verification procedure. --- diff --git a/doc/cha-gtls-app.texi b/doc/cha-gtls-app.texi index a15c4d9ebb..5e08aa3292 100644 --- a/doc/cha-gtls-app.texi +++ b/doc/cha-gtls-app.texi @@ -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 diff --git a/doc/examples/Makefile.am b/doc/examples/Makefile.am index bbdec1fcd7..9a19409c7f 100644 --- a/doc/examples/Makefile.am +++ b/doc/examples/Makefile.am @@ -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 diff --git a/doc/examples/ex-rfc2818.c b/doc/examples/ex-rfc2818.c index 1df60a88e8..693e5f5e3c 100644 --- a/doc/examples/ex-rfc2818.c +++ b/doc/examples/ex-rfc2818.c @@ -5,33 +5,46 @@ #endif #include +#include +#include #include #include - #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; }