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
15 * verification. Note that error checking for missing files etc. is missing
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
);
30 gnutls_session_t session
;
31 char buffer
[MAX_BUF
+ 1];
33 gnutls_certificate_credentials_t xcred
;
35 gnutls_global_init ();
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",
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
);
65 if (ret
== GNUTLS_E_INVALID_REQUEST
)
67 fprintf (stderr
, "Syntax error at: %s\n", err
);
72 /* put the x509 credentials to the current session
74 gnutls_credentials_set (session
, GNUTLS_CRD_CERTIFICATE
, xcred
);
76 /* connect to the peer
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);
93 fprintf (stderr
, "*** Handshake failed\n");
99 printf ("- Handshake was completed\n");
102 gnutls_record_send (session
, MSG
, strlen (MSG
));
104 ret
= gnutls_record_recv (session
, buffer
, MAX_BUF
);
107 printf ("- Peer has closed the TLS connection\n");
112 fprintf (stderr
, "*** Error: %s\n", gnutls_strerror (ret
));
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
);
129 gnutls_deinit (session
);
131 gnutls_certificate_free_credentials (xcred
);
133 gnutls_global_deinit ();
138 /* This function will verify the peer's certificate, and check
139 * if the hostname matches, as well as the activation, expiration dates.
142 _verify_certificate_callback (gnutls_session_t session
)
146 const char *hostname
;
149 hostname
= gnutls_session_get_ptr (session
);
151 /* This verification function uses the trusted CAs in the credentials
152 * structure. So you must have installed one or more CA certificates.
154 ret
= gnutls_certificate_verify_peers3 (session
, hostname
, &status
);
158 return GNUTLS_E_CERTIFICATE_ERROR
;
161 if (status
& GNUTLS_CERT_SIGNER_NOT_FOUND
)
162 printf ("The certificate hasn't got a known issuer.\n");
164 if (status
& GNUTLS_CERT_REVOKED
)
165 printf ("The certificate has been revoked.\n");
167 if (status
& GNUTLS_CERT_EXPIRED
)
168 printf ("The certificate has expired\n");
170 if (status
& GNUTLS_CERT_NOT_ACTIVATED
)
171 printf ("The certificate is not yet activated\n");
173 if (status
& GNUTLS_CERT_INVALID
)
175 printf ("The certificate is not trusted.\n");
176 return GNUTLS_E_CERTIFICATE_ERROR
;
179 /* notify gnutls to continue handshake normally */