1 /* This example code is placed in the public domain. */
10 #include <sys/types.h>
11 #include <sys/socket.h>
12 #include <arpa/inet.h>
14 #include <gnutls/gnutls.h>
15 #include <gnutls/x509.h>
16 #include <gnutls/abstract.h>
17 #include <sys/types.h>
21 /* A TLS client that loads the certificate and key.
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
);
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
);
44 /* Helper functions to load a certificate and key
48 load_file (const char *file
)
51 gnutls_datum_t loaded_file
= { NULL
, 0 };
55 if (!(f
= fopen (file
, "r"))
56 || fseek (f
, 0, SEEK_END
) != 0
57 || (filelen
= ftell (f
)) < 0
58 || fseek (f
, 0, SEEK_SET
) != 0
59 || !(ptr
= malloc ((size_t) filelen
))
60 || fread (ptr
, 1, (size_t) filelen
, f
) < (size_t) filelen
)
67 loaded_file
.data
= ptr
;
68 loaded_file
.size
= (unsigned int) filelen
;
73 unload_file (gnutls_datum_t data
)
78 /* Load the certificate and the private key.
85 gnutls_x509_privkey_t x509_key
;
87 data
= load_file (CERT_FILE
);
88 if (data
.data
== NULL
)
90 fprintf (stderr
, "*** Error loading certificate file.\n");
94 ret
= gnutls_pcert_import_x509_raw (&crt
, &data
, GNUTLS_X509_FMT_PEM
, 0);
97 fprintf (stderr
, "*** Error loading certificate file: %s\n",
98 gnutls_strerror (ret
));
104 data
= load_file (KEY_FILE
);
105 if (data
.data
== NULL
)
107 fprintf (stderr
, "*** Error loading key file.\n");
111 gnutls_x509_privkey_init (&x509_key
);
113 ret
= gnutls_x509_privkey_import (x509_key
, &data
, GNUTLS_X509_FMT_PEM
);
116 fprintf (stderr
, "*** Error loading key file: %s\n",
117 gnutls_strerror (ret
));
121 gnutls_privkey_init (&key
);
124 gnutls_privkey_import_x509 (key
, x509_key
,
125 GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE
);
128 fprintf (stderr
, "*** Error importing key: %s\n",
129 gnutls_strerror (ret
));
140 gnutls_session_t session
;
141 gnutls_priority_t priorities_cache
;
142 char buffer
[MAX_BUF
+ 1];
143 gnutls_certificate_credentials_t xcred
;
144 /* Allow connections to servers that have OpenPGP keys as well.
147 gnutls_global_init ();
152 gnutls_certificate_allocate_credentials (&xcred
);
155 gnutls_priority_init (&priorities_cache
, "NORMAL", NULL
);
158 /* sets the trusted cas file
160 gnutls_certificate_set_x509_trust_file (xcred
, CAFILE
, GNUTLS_X509_FMT_PEM
);
162 gnutls_certificate_set_retrieve_function2 (xcred
, cert_callback
);
164 /* Initialize TLS session
166 gnutls_init (&session
, GNUTLS_CLIENT
);
168 /* Use default priorities */
169 gnutls_priority_set (session
, priorities_cache
);
171 /* put the x509 credentials to the current session
173 gnutls_credentials_set (session
, GNUTLS_CRD_CERTIFICATE
, xcred
);
175 /* connect to the peer
179 gnutls_transport_set_ptr (session
, (gnutls_transport_ptr_t
) sd
);
181 /* Perform the TLS handshake
183 ret
= gnutls_handshake (session
);
187 fprintf (stderr
, "*** Handshake failed\n");
193 printf ("- Handshake was completed\n");
196 gnutls_record_send (session
, MSG
, strlen (MSG
));
198 ret
= gnutls_record_recv (session
, buffer
, MAX_BUF
);
201 printf ("- Peer has closed the TLS connection\n");
206 fprintf (stderr
, "*** Error: %s\n", gnutls_strerror (ret
));
210 printf ("- Received %d bytes: ", ret
);
211 for (ii
= 0; ii
< ret
; ii
++)
213 fputc (buffer
[ii
], stdout
);
215 fputs ("\n", stdout
);
217 gnutls_bye (session
, GNUTLS_SHUT_RDWR
);
223 gnutls_deinit (session
);
225 gnutls_certificate_free_credentials (xcred
);
226 gnutls_priority_deinit (priorities_cache
);
228 gnutls_global_deinit ();
235 /* This callback should be associated with a session by calling
236 * gnutls_certificate_client_set_retrieve_function( session, cert_callback),
237 * before a handshake.
241 cert_callback (gnutls_session_t session
,
242 const gnutls_datum_t
* req_ca_rdn
, int nreqs
,
243 const gnutls_pk_algorithm_t
* sign_algos
,
244 int sign_algos_length
, gnutls_pcert_st
** pcert
,
245 unsigned int *pcert_length
, gnutls_privkey_t
* pkey
)
250 gnutls_certificate_type_t type
;
252 /* Print the server's trusted CAs
255 printf ("- Server's trusted authorities:\n");
257 printf ("- Server did not send us any trusted authorities names.\n");
259 /* print the names (if any) */
260 for (i
= 0; i
< nreqs
; i
++)
262 len
= sizeof (issuer_dn
);
263 ret
= gnutls_x509_rdn_get (&req_ca_rdn
[i
], issuer_dn
, &len
);
266 printf (" [%d]: ", i
);
267 printf ("%s\n", issuer_dn
);
271 /* Select a certificate and return it.
272 * The certificate must be of any of the "sign algorithms"
273 * supported by the server.
275 type
= gnutls_certificate_type_get (session
);
276 if (type
== GNUTLS_CRT_X509
)