Add.
[gnutls.git] / src / tls_test.c
blobc88c33eb7c75aabc97b5b5022a60cb1b92c3a10f
1 /*
2 * Copyright (C) 2000,2001,2002,2003,2006,2007,2008,2009 Nikos Mavrogiannopoulos
3 * Copyright (C) 2004,2005, 2008 Free Software Foundation
5 * This file is part of GNUTLS.
7 * GNUTLS is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * GNUTLS is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include <config.h>
22 #include <stdio.h>
23 #include <errno.h>
24 #include <stdlib.h>
25 #include <sys/types.h>
26 #include <string.h>
27 #include <gnutls/gnutls.h>
28 #include <gnutls/extra.h>
29 #include <sys/time.h>
30 #include <sys/socket.h>
31 #include <tests.h>
32 #include <common.h>
33 #include <tls_test-gaa.h>
35 /* Gnulib portability files. */
36 #include <progname.h>
37 #include <version-etc.h>
38 #include "sockets.h"
40 #define ERR(err,s) if (err==-1) {perror(s);return(1);}
41 #define MAX_BUF 4096
43 /* global stuff here */
44 int resume;
45 const char *hostname = NULL;
46 int port;
47 int record_max_size;
48 int fingerprint;
49 static int debug;
51 gnutls_srp_client_credentials_t srp_cred;
52 gnutls_anon_client_credentials_t anon_cred;
53 gnutls_certificate_credentials_t xcred;
55 /* end of global stuff */
58 int verbose = 0;
60 extern int tls1_ok;
61 extern int tls1_1_ok;
62 extern int ssl3_ok;
64 static void
65 tls_log_func (int level, const char *str)
67 fprintf (stderr, "|<%d>| %s", level, str);
70 typedef test_code_t (*TEST_FUNC) (gnutls_session_t);
72 typedef struct
74 const char *test_name;
75 TEST_FUNC func;
76 const char *suc_str;
77 const char *fail_str;
78 const char *unsure_str;
79 } TLS_TEST;
81 static const TLS_TEST tls_tests[] = {
82 {"for TLS 1.1 support", test_tls1_1, "yes", "no", "dunno"},
83 {"fallback from TLS 1.1 to", test_tls1_1_fallback, "TLS 1.0", "failed",
84 "SSL 3.0"},
85 {"for TLS 1.0 support", test_tls1, "yes", "no", "dunno"},
86 {"for SSL 3.0 support", test_ssl3, "yes", "no", "dunno"},
87 {"for HTTPS server name", test_server, "", "failed", "not checked"},
88 {"for version rollback bug in RSA PMS", test_rsa_pms, "no", "yes",
89 "dunno"},
90 {"for version rollback bug in Client Hello", test_version_rollback,
91 "no", "yes", "dunno"},
93 /* this test will disable TLS 1.0 if the server is
94 * buggy */
95 {"whether we need to disable TLS 1.0", test_tls_disable, "no", "yes",
96 "dunno"},
98 {"whether the server ignores the RSA PMS version",
99 test_rsa_pms_version_check, "yes", "no", "dunno"},
100 {"whether the server can accept Hello Extensions",
101 test_hello_extension, "yes", "no", "dunno"},
102 {"whether the server can accept cipher suites not in SSL 3.0 spec",
103 test_unknown_ciphersuites, "yes", "no", "dunno"},
104 {"whether the server can accept a bogus TLS record version in the client hello", test_version_oob, "yes", "no", "dunno"},
105 {"for certificate information", test_certificate, "", "", ""},
106 {"for trusted CAs", test_server_cas, "", "", ""},
107 {"whether the server understands TLS closure alerts", test_bye, "yes",
108 "no", "partially"},
109 /* the fact that is after the closure alert test does matter.
111 {"whether the server supports session resumption",
112 test_session_resume2, "yes", "no", "dunno"},
113 {"for export-grade ciphersuite support", test_export, "yes", "no",
114 "dunno"},
115 {"RSA-export ciphersuite info", test_export_info, "", "N/A", "N/A"},
116 #ifdef ENABLE_ANON
117 {"for anonymous authentication support", test_anonymous, "yes", "no",
118 "dunno"},
119 {"anonymous Diffie-Hellman group info", test_dhe_group, "", "N/A",
120 "N/A"},
121 #endif
122 {"for ephemeral Diffie-Hellman support", test_dhe, "yes", "no",
123 "dunno"},
124 {"ephemeral Diffie-Hellman group info", test_dhe_group, "", "N/A",
125 "N/A"},
126 {"for AES cipher support (TLS extension)", test_aes, "yes", "no",
127 "dunno"},
128 #ifdef ENABLE_CAMELLIA
129 {"for CAMELLIA cipher support (TLS extension)", test_camellia, "yes", "no",
130 "dunno"},
131 #endif
132 {"for 3DES cipher support", test_3des, "yes", "no", "dunno"},
133 {"for ARCFOUR 128 cipher support", test_arcfour, "yes", "no", "dunno"},
134 {"for ARCFOUR 40 cipher support", test_arcfour_40, "yes", "no",
135 "dunno"},
136 {"for MD5 MAC support", test_md5, "yes", "no", "dunno"},
137 {"for SHA1 MAC support", test_sha, "yes", "no", "dunno"},
138 #ifdef HAVE_LIBZ
139 {"for ZLIB compression support (TLS extension)", test_zlib, "yes",
140 "no", "dunno"},
141 #endif
142 {"for LZO compression support (GnuTLS extension)", test_lzo, "yes",
143 "no", "dunno"},
144 {"for max record size (TLS extension)", test_max_record_size, "yes",
145 "no", "dunno"},
146 #ifdef ENABLE_SRP
147 {"for SRP authentication support (TLS extension)", test_srp, "yes",
148 "no", "dunno"},
149 #endif
150 {"for OpenPGP authentication support (TLS extension)", test_openpgp1,
151 "yes", "no", "dunno"},
152 {NULL, NULL, NULL, NULL, NULL}
155 static int tt = 0;
156 const char *ip;
158 static void gaa_parser (int argc, char **argv);
161 main (int argc, char **argv)
163 int err, ret;
164 int sd, i;
165 gnutls_session_t state;
166 char buffer[MAX_BUF + 1];
167 char portname[6];
168 struct addrinfo hints, *res, *ptr;
170 set_program_name (argv[0]);
171 gaa_parser (argc, argv);
173 #ifndef _WIN32
174 signal (SIGPIPE, SIG_IGN);
175 #endif
177 sockets_init ();
179 if (gnutls_global_init () < 0)
181 fprintf (stderr, "global state initialization error\n");
182 exit (1);
185 gnutls_global_set_log_function (tls_log_func);
186 gnutls_global_set_log_level (debug);
188 printf ("Resolving '%s'...\n", hostname);
189 /* get server name */
190 memset (&hints, 0, sizeof (hints));
191 hints.ai_socktype = SOCK_STREAM;
192 hints.ai_flags = 0;
193 snprintf (portname, sizeof (portname), "%d", port);
194 if ((err = getaddrinfo (hostname, portname, &hints, &res)) != 0)
196 fprintf (stderr, "Cannot resolve %s: %s\n", hostname,
197 gai_strerror (err));
198 exit (1);
201 /* X509 stuff */
202 if (gnutls_certificate_allocate_credentials (&xcred) < 0)
203 { /* space for 2 certificates */
204 fprintf (stderr, "memory error\n");
205 exit (1);
208 /* SRP stuff */
209 #ifdef ENABLE_SRP
210 if (gnutls_srp_allocate_client_credentials (&srp_cred) < 0)
212 fprintf (stderr, "memory error\n");
213 exit (1);
215 #endif
217 #ifdef ENABLE_ANON
218 /* ANON stuff */
219 if (gnutls_anon_allocate_client_credentials (&anon_cred) < 0)
221 fprintf (stderr, "memory error\n");
222 exit (1);
224 #endif
226 i = 0;
231 if (tls_tests[i].test_name == NULL)
232 break; /* finished */
234 /* if neither of SSL3 and TLSv1 are supported, exit
236 if (i > 3 && tls1_1_ok == 0 && tls1_ok == 0 && ssl3_ok == 0)
238 fprintf (stderr,
239 "\nServer does not support any of SSL 3.0, TLS 1.0 and TLS 1.1\n");
240 break;
243 sd = -1;
244 for (ptr = res; ptr != NULL; ptr = ptr->ai_next)
246 sd = socket (ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
247 if (sd == -1)
249 continue;
252 getnameinfo (ptr->ai_addr, ptr->ai_addrlen, buffer, MAX_BUF,
253 NULL, 0, NI_NUMERICHOST);
254 if (tt++ == 0)
255 printf ("Connecting to '%s:%d'...\n", buffer, port);
256 if ((err = connect (sd, ptr->ai_addr, ptr->ai_addrlen)) != 0)
258 close (sd);
259 sd = -1;
260 continue;
263 ERR (err, "connect") gnutls_init (&state, GNUTLS_CLIENT);
264 gnutls_transport_set_ptr (state, (gnutls_transport_ptr_t)
265 gl_fd_to_handle (sd));
269 printf ("Checking %s...", tls_tests[i].test_name);
271 ret = tls_tests[i].func (state);
273 if (ret == TEST_SUCCEED)
274 printf (" %s\n", tls_tests[i].suc_str);
275 else if (ret == TEST_FAILED)
276 printf (" %s\n", tls_tests[i].fail_str);
277 else if (ret == TEST_UNSURE)
278 printf (" %s\n", tls_tests[i].unsure_str);
279 else if (ret == TEST_IGNORE)
281 printf (" N/A\n");
282 i++;
285 while (ret == TEST_IGNORE && tls_tests[i].test_name != NULL);
287 gnutls_deinit (state);
289 shutdown (sd, SHUT_RDWR); /* no more receptions */
290 close (sd);
292 i++;
294 while (1);
296 freeaddrinfo (res);
298 #ifdef ENABLE_SRP
299 gnutls_srp_free_client_credentials (srp_cred);
300 #endif
301 gnutls_certificate_free_credentials (xcred);
302 #ifdef ENABLE_ANON
303 gnutls_anon_free_client_credentials (anon_cred);
304 #endif
305 gnutls_global_deinit ();
307 return 0;
310 static gaainfo info;
311 void
312 gaa_parser (int argc, char **argv)
314 if (gaa (argc, argv, &info) != -1)
316 fprintf (stderr,
317 "Error in the arguments. Use the -h or --help parameters to get more info.\n");
318 exit (1);
321 port = info.pp;
322 if (info.rest_args == NULL)
323 hostname = "localhost";
324 else
325 hostname = info.rest_args;
327 debug = info.debug;
329 verbose = info.more_info;
333 void tls_test_version (void);
335 void
336 tls_test_version (void)
338 const char *p = PACKAGE_NAME;
339 if (strcmp (gnutls_check_version (NULL), PACKAGE_VERSION) != 0)
340 p = PACKAGE_STRING;
341 version_etc (stdout, "gnutls-cli-debug", p, gnutls_check_version (NULL),
342 "Nikos Mavrogiannopoulos", (char *) NULL);