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 /* Load the certificate and the private key.
52 ret
= gnutls_load_file (CERT_FILE
, &data
);
55 fprintf (stderr
, "*** Error loading certificate file.\n");
59 ret
= gnutls_pcert_import_x509_raw (&pcrt
, &data
, GNUTLS_X509_FMT_PEM
, 0);
62 fprintf (stderr
, "*** Error loading certificate file: %s\n",
63 gnutls_strerror (ret
));
67 gnutls_free(data
.data
);
69 ret
= gnutls_load_file (KEY_FILE
, &data
);
72 fprintf (stderr
, "*** Error loading key file.\n");
76 gnutls_privkey_init (&key
);
78 ret
= gnutls_privkey_import_x509_raw (key
, &data
, GNUTLS_X509_FMT_PEM
, NULL
, 0);
81 fprintf (stderr
, "*** Error loading key file: %s\n",
82 gnutls_strerror (ret
));
86 gnutls_free(data
.data
);
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 ();
105 gnutls_certificate_allocate_credentials (&xcred
);
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
132 gnutls_transport_set_ptr (session
, (gnutls_transport_ptr_t
) sd
);
134 /* Perform the TLS handshake
136 ret
= gnutls_handshake (session
);
140 fprintf (stderr
, "*** Handshake failed\n");
146 printf ("- Handshake was completed\n");
149 gnutls_record_send (session
, MSG
, strlen (MSG
));
151 ret
= gnutls_record_recv (session
, buffer
, MAX_BUF
);
154 printf ("- Peer has closed the TLS connection\n");
159 fprintf (stderr
, "*** Error: %s\n", gnutls_strerror (ret
));
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
);
176 gnutls_deinit (session
);
178 gnutls_certificate_free_credentials (xcred
);
179 gnutls_priority_deinit (priorities_cache
);
181 gnutls_global_deinit ();
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.
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
)
203 gnutls_certificate_type_t type
;
205 /* Print the server's trusted CAs
208 printf ("- Server's trusted authorities:\n");
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
);
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
)