1 /* This example code is placed in the public domain. */
10 #include <gnutls/gnutls.h>
11 #include <gnutls/x509.h>
14 /* A very basic TLS client, with X.509 authentication and server certificate
19 #define CAFILE "ca.pem"
20 #define MSG "GET / HTTP/1.0\r\n\r\n"
22 extern int tcp_connect (void);
23 extern void tcp_close (int sd
);
25 /* This function will try to verify the peer's certificate, and
26 * also check if the hostname matches, and the activation, expiration dates.
29 verify_certificate_callback (gnutls_session_t session
)
32 const gnutls_datum_t
*cert_list
;
33 unsigned int cert_list_size
;
35 gnutls_x509_crt_t cert
;
39 hostname
= gnutls_session_get_ptr (session
);
41 /* This verification function uses the trusted CAs in the credentials
42 * structure. So you must have installed one or more CA certificates.
44 ret
= gnutls_certificate_verify_peers2 (session
, &status
);
48 return GNUTLS_E_CERTIFICATE_ERROR
;
51 if (status
& GNUTLS_CERT_INVALID
)
52 printf ("The certificate is not trusted.\n");
54 if (status
& GNUTLS_CERT_SIGNER_NOT_FOUND
)
55 printf ("The certificate hasn't got a known issuer.\n");
57 if (status
& GNUTLS_CERT_REVOKED
)
58 printf ("The certificate has been revoked.\n");
60 if (status
& GNUTLS_CERT_EXPIRED
)
61 printf ("The certificate has expired\n");
63 if (status
& GNUTLS_CERT_NOT_ACTIVATED
)
64 printf ("The certificate is not yet activated\n");
66 /* Up to here the process is the same for X.509 certificates and
67 * OpenPGP keys. From now on X.509 certificates are assumed. This can
68 * be easily extended to work with openpgp keys as well.
70 if (gnutls_certificate_type_get (session
) != GNUTLS_CRT_X509
)
71 return GNUTLS_E_CERTIFICATE_ERROR
;
73 if (gnutls_x509_crt_init (&cert
) < 0)
75 printf ("error in initialization\n");
76 return GNUTLS_E_CERTIFICATE_ERROR
;
79 cert_list
= gnutls_certificate_get_peers (session
, &cert_list_size
);
80 if (cert_list
== NULL
)
82 printf ("No certificate was found!\n");
83 return GNUTLS_E_CERTIFICATE_ERROR
;
86 /* This is not a real world example, since we only check the first
87 * certificate in the given chain.
89 if (gnutls_x509_crt_import (cert
, &cert_list
[0], GNUTLS_X509_FMT_DER
) < 0)
91 printf ("error parsing certificate\n");
92 return GNUTLS_E_CERTIFICATE_ERROR
;
96 if (!gnutls_x509_crt_check_hostname (cert
, hostname
))
98 printf ("The certificate's owner does not match hostname '%s'\n",
100 return GNUTLS_E_CERTIFICATE_ERROR
;
103 gnutls_x509_crt_deinit (cert
);
105 /* notify gnutls to continue handshake normally */
114 gnutls_session_t session
;
115 char buffer
[MAX_BUF
+ 1];
117 gnutls_certificate_credentials_t xcred
;
119 gnutls_global_init ();
122 gnutls_certificate_allocate_credentials (&xcred
);
124 /* sets the trusted cas file
126 gnutls_certificate_set_x509_trust_file (xcred
, CAFILE
, GNUTLS_X509_FMT_PEM
);
127 gnutls_certificate_set_verify_function (xcred
, verify_certificate_callback
);
128 gnutls_certificate_set_verify_flags (xcred
,
129 GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT
);
131 /* Initialize TLS session
133 gnutls_init (&session
, GNUTLS_CLIENT
);
135 gnutls_session_set_ptr (session
, (void *) "my_host_name");
137 /* Use default priorities */
138 ret
= gnutls_priority_set_direct (session
, "PERFORMANCE", &err
);
141 if (ret
== GNUTLS_E_INVALID_REQUEST
)
143 fprintf (stderr
, "Syntax error at: %s\n", err
);
148 /* put the x509 credentials to the current session
150 gnutls_credentials_set (session
, GNUTLS_CRD_CERTIFICATE
, xcred
);
152 /* connect to the peer
156 gnutls_transport_set_ptr (session
, (gnutls_transport_ptr_t
) sd
);
158 /* Perform the TLS handshake
160 ret
= gnutls_handshake (session
);
164 fprintf (stderr
, "*** Handshake failed\n");
170 printf ("- Handshake was completed\n");
173 gnutls_record_send (session
, MSG
, strlen (MSG
));
175 ret
= gnutls_record_recv (session
, buffer
, MAX_BUF
);
178 printf ("- Peer has closed the TLS connection\n");
183 fprintf (stderr
, "*** Error: %s\n", gnutls_strerror (ret
));
187 printf ("- Received %d bytes: ", ret
);
188 for (ii
= 0; ii
< ret
; ii
++)
190 fputc (buffer
[ii
], stdout
);
192 fputs ("\n", stdout
);
194 gnutls_bye (session
, GNUTLS_SHUT_RDWR
);
200 gnutls_deinit (session
);
202 gnutls_certificate_free_credentials (xcred
);
204 gnutls_global_deinit ();