corrected copyright notices
[gnutls.git] / doc / examples / ex-client-x509.c
blobe4a5293abc059743aba49491f7ed44b95fe4649d
1 /* This example code is placed in the public domain. */
3 #ifdef HAVE_CONFIG_H
4 #include <config.h>
5 #endif
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <gnutls/gnutls.h>
11 #include <gnutls/x509.h>
12 #include "examples.h"
14 /* A very basic TLS client, with X.509 authentication and server certificate
15 * verification. Note that error checking for missing files etc. is missing
16 * for simplicity.
19 #define MAX_BUF 1024
20 #define CAFILE "/etc/ssl/certs/ca-certificates.crt"
21 #define MSG "GET / HTTP/1.0\r\n\r\n"
23 extern int tcp_connect (void);
24 extern void tcp_close (int sd);
25 static int _verify_certificate_callback (gnutls_session_t session);
27 int main (void)
29 int ret, sd, ii;
30 gnutls_session_t session;
31 char buffer[MAX_BUF + 1];
32 const char *err;
33 gnutls_certificate_credentials_t xcred;
35 gnutls_global_init ();
37 /* X509 stuff */
38 gnutls_certificate_allocate_credentials (&xcred);
40 /* sets the trusted cas file
42 gnutls_certificate_set_x509_trust_file (xcred, CAFILE, GNUTLS_X509_FMT_PEM);
43 gnutls_certificate_set_verify_function (xcred, _verify_certificate_callback);
45 /* If client holds a certificate it can be set using the following:
47 gnutls_certificate_set_x509_key_file (xcred,
48 "cert.pem", "key.pem",
49 GNUTLS_X509_FMT_PEM);
52 /* Initialize TLS session
54 gnutls_init (&session, GNUTLS_CLIENT);
56 gnutls_session_set_ptr (session, (void *) "my_host_name");
58 gnutls_server_name_set (session, GNUTLS_NAME_DNS, "my_host_name",
59 strlen("my_host_name"));
61 /* Use default priorities */
62 ret = gnutls_priority_set_direct (session, "NORMAL", &err);
63 if (ret < 0)
65 if (ret == GNUTLS_E_INVALID_REQUEST)
67 fprintf (stderr, "Syntax error at: %s\n", err);
69 exit (1);
72 /* put the x509 credentials to the current session
74 gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
76 /* connect to the peer
78 sd = tcp_connect ();
80 gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) sd);
81 gnutls_handshake_set_timeout (session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);
83 /* Perform the TLS handshake
87 ret = gnutls_handshake (session);
89 while (ret < 0 && gnutls_error_is_fatal (ret) == 0);
91 if (ret < 0)
93 fprintf (stderr, "*** Handshake failed\n");
94 gnutls_perror (ret);
95 goto end;
97 else
99 printf ("- Handshake was completed\n");
102 gnutls_record_send (session, MSG, strlen (MSG));
104 ret = gnutls_record_recv (session, buffer, MAX_BUF);
105 if (ret == 0)
107 printf ("- Peer has closed the TLS connection\n");
108 goto end;
110 else if (ret < 0)
112 fprintf (stderr, "*** Error: %s\n", gnutls_strerror (ret));
113 goto end;
116 printf ("- Received %d bytes: ", ret);
117 for (ii = 0; ii < ret; ii++)
119 fputc (buffer[ii], stdout);
121 fputs ("\n", stdout);
123 gnutls_bye (session, GNUTLS_SHUT_RDWR);
125 end:
127 tcp_close (sd);
129 gnutls_deinit (session);
131 gnutls_certificate_free_credentials (xcred);
133 gnutls_global_deinit ();
135 return 0;
138 /* This function will verify the peer's certificate, and check
139 * if the hostname matches, as well as the activation, expiration dates.
141 static int
142 _verify_certificate_callback (gnutls_session_t session)
144 unsigned int status;
145 int ret, type;
146 const char *hostname;
147 gnutls_datum_t out;
149 /* read hostname */
150 hostname = gnutls_session_get_ptr (session);
152 /* This verification function uses the trusted CAs in the credentials
153 * structure. So you must have installed one or more CA certificates.
155 ret = gnutls_certificate_verify_peers3 (session, hostname, &status);
156 if (ret < 0)
158 printf ("Error\n");
159 return GNUTLS_E_CERTIFICATE_ERROR;
162 type = gnutls_certificate_type_get (session);
164 ret = gnutls_certificate_verification_status_print( status, type, &out, 0);
165 if (ret < 0)
167 printf ("Error\n");
168 return GNUTLS_E_CERTIFICATE_ERROR;
171 printf ("%s", out.data);
173 gnutls_free(out.data);
175 if (status != 0) /* Certificate is not trusted */
176 return GNUTLS_E_CERTIFICATE_ERROR;
178 /* notify gnutls to continue handshake normally */
179 return 0;