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 \
* 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::
@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
@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
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
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
extern int udp_connect (void);
extern void udp_close (int sd);
+extern int verify_certificate_callback (gnutls_session_t session);
int
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);
+++ /dev/null
-/* 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;
-}
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;
/* 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
*/
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)
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;
+}
+
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);
const gnutls_datum_t * cert_chain,
int cert_chain_length);
+int verify_certificate_callback (gnutls_session_t session);
+
#endif /* EXAMPLES_H */
--- /dev/null
+#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;
+}