danetool is being built even without libgnutls-dane.
[gnutls.git] / doc / examples / ex-cert-select.c
blob7b5173425ad283421780e140b8ffc92beb5d1895
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 <sys/types.h>
11 #include <sys/socket.h>
12 #include <arpa/inet.h>
13 #include <unistd.h>
14 #include <gnutls/gnutls.h>
15 #include <gnutls/x509.h>
16 #include <gnutls/abstract.h>
17 #include <sys/types.h>
18 #include <sys/stat.h>
19 #include <fcntl.h>
21 /* A TLS client that loads the certificate and key.
24 #define MAX_BUF 1024
25 #define MSG "GET / HTTP/1.0\r\n\r\n"
27 #define CERT_FILE "cert.pem"
28 #define KEY_FILE "key.pem"
29 #define CAFILE "/etc/ssl/certs/ca-certificates.crt"
31 extern int tcp_connect (void);
32 extern void tcp_close (int sd);
34 static int
35 cert_callback (gnutls_session_t session,
36 const gnutls_datum_t * req_ca_rdn, int nreqs,
37 const gnutls_pk_algorithm_t * sign_algos,
38 int sign_algos_length, gnutls_pcert_st ** pcert,
39 unsigned int *pcert_length, gnutls_privkey_t * pkey);
41 gnutls_pcert_st pcrt;
42 gnutls_privkey_t key;
44 /* Load the certificate and the private key.
46 static void
47 load_keys (void)
49 int ret;
50 gnutls_datum_t data;
52 ret = gnutls_load_file (CERT_FILE, &data);
53 if (ret < 0)
55 fprintf (stderr, "*** Error loading certificate file.\n");
56 exit (1);
59 ret = gnutls_pcert_import_x509_raw (&pcrt, &data, GNUTLS_X509_FMT_PEM, 0);
60 if (ret < 0)
62 fprintf (stderr, "*** Error loading certificate file: %s\n",
63 gnutls_strerror (ret));
64 exit (1);
67 gnutls_free(data.data);
69 ret = gnutls_load_file (KEY_FILE, &data);
70 if (ret < 0)
72 fprintf (stderr, "*** Error loading key file.\n");
73 exit (1);
76 gnutls_privkey_init (&key);
78 ret = gnutls_privkey_import_x509_raw (key, &data, GNUTLS_X509_FMT_PEM, NULL, 0);
79 if (ret < 0)
81 fprintf (stderr, "*** Error loading key file: %s\n",
82 gnutls_strerror (ret));
83 exit (1);
86 gnutls_free(data.data);
89 int
90 main (void)
92 int ret, sd, ii;
93 gnutls_session_t session;
94 gnutls_priority_t priorities_cache;
95 char buffer[MAX_BUF + 1];
96 gnutls_certificate_credentials_t xcred;
97 /* Allow connections to servers that have OpenPGP keys as well.
100 gnutls_global_init ();
102 load_keys ();
104 /* X509 stuff */
105 gnutls_certificate_allocate_credentials (&xcred);
107 /* priorities */
108 gnutls_priority_init (&priorities_cache, "NORMAL", NULL);
111 /* sets the trusted cas file
113 gnutls_certificate_set_x509_trust_file (xcred, CAFILE, GNUTLS_X509_FMT_PEM);
115 gnutls_certificate_set_retrieve_function2 (xcred, cert_callback);
117 /* Initialize TLS session
119 gnutls_init (&session, GNUTLS_CLIENT);
121 /* Use default priorities */
122 gnutls_priority_set (session, priorities_cache);
124 /* put the x509 credentials to the current session
126 gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
128 /* connect to the peer
130 sd = tcp_connect ();
132 gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) sd);
134 /* Perform the TLS handshake
136 ret = gnutls_handshake (session);
138 if (ret < 0)
140 fprintf (stderr, "*** Handshake failed\n");
141 gnutls_perror (ret);
142 goto end;
144 else
146 printf ("- Handshake was completed\n");
149 gnutls_record_send (session, MSG, strlen (MSG));
151 ret = gnutls_record_recv (session, buffer, MAX_BUF);
152 if (ret == 0)
154 printf ("- Peer has closed the TLS connection\n");
155 goto end;
157 else if (ret < 0)
159 fprintf (stderr, "*** Error: %s\n", gnutls_strerror (ret));
160 goto end;
163 printf ("- Received %d bytes: ", ret);
164 for (ii = 0; ii < ret; ii++)
166 fputc (buffer[ii], stdout);
168 fputs ("\n", stdout);
170 gnutls_bye (session, GNUTLS_SHUT_RDWR);
172 end:
174 tcp_close (sd);
176 gnutls_deinit (session);
178 gnutls_certificate_free_credentials (xcred);
179 gnutls_priority_deinit (priorities_cache);
181 gnutls_global_deinit ();
183 return 0;
188 /* This callback should be associated with a session by calling
189 * gnutls_certificate_client_set_retrieve_function( session, cert_callback),
190 * before a handshake.
193 static int
194 cert_callback (gnutls_session_t session,
195 const gnutls_datum_t * req_ca_rdn, int nreqs,
196 const gnutls_pk_algorithm_t * sign_algos,
197 int sign_algos_length, gnutls_pcert_st ** pcert,
198 unsigned int *pcert_length, gnutls_privkey_t * pkey)
200 char issuer_dn[256];
201 int i, ret;
202 size_t len;
203 gnutls_certificate_type_t type;
205 /* Print the server's trusted CAs
207 if (nreqs > 0)
208 printf ("- Server's trusted authorities:\n");
209 else
210 printf ("- Server did not send us any trusted authorities names.\n");
212 /* print the names (if any) */
213 for (i = 0; i < nreqs; i++)
215 len = sizeof (issuer_dn);
216 ret = gnutls_x509_rdn_get (&req_ca_rdn[i], issuer_dn, &len);
217 if (ret >= 0)
219 printf (" [%d]: ", i);
220 printf ("%s\n", issuer_dn);
224 /* Select a certificate and return it.
225 * The certificate must be of any of the "sign algorithms"
226 * supported by the server.
228 type = gnutls_certificate_type_get (session);
229 if (type == GNUTLS_CRT_X509)
231 *pcert_length = 1;
232 *pcert = &pcrt;
233 *pkey = key;
235 else
237 return -1;
240 return 0;