2 * Copyright (C) 2000-2012 Free Software Foundation, Inc.
4 * This file is part of GnuTLS.
6 * GnuTLS is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * GnuTLS is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see
18 * <http://www.gnu.org/licenses/>.
25 #include <sys/types.h>
27 #include <gnutls/gnutls.h>
30 # include <sys/socket.h>
32 # include <ws2tcpip.h>
37 #include <cli-debug-args.h>
40 /* Gnulib portability files. */
42 #include <version-etc.h>
45 static void cmd_parser (int argc
, char **argv
);
47 #define ERR(err,s) if (err==-1) {perror(s);return(1);}
50 /* global stuff here */
52 const char *hostname
= NULL
;
58 gnutls_srp_client_credentials_t srp_cred
;
59 gnutls_anon_client_credentials_t anon_cred
;
60 gnutls_certificate_credentials_t xcred
;
62 /* end of global stuff */
64 unsigned int verbose
= 0;
71 tls_log_func (int level
, const char *str
)
73 fprintf (stderr
, "|<%d>| %s", level
, str
);
76 typedef test_code_t (*TEST_FUNC
) (gnutls_session_t
);
80 const char *test_name
;
84 const char *unsure_str
;
87 static const TLS_TEST tls_tests
[] = {
88 {"for SSL 3.0 support", test_ssl3
, "yes", "no", "dunno"},
89 {"whether \%COMPAT is required", test_record_padding
, "no", "yes", "dunno"},
90 {"for TLS 1.0 support", test_tls1
, "yes", "no", "dunno"},
91 {"for TLS 1.1 support", test_tls1_1
, "yes", "no", "dunno"},
92 {"fallback from TLS 1.1 to", test_tls1_1_fallback
, "TLS 1.0", "failed",
94 {"for TLS 1.2 support", test_tls1_2
, "yes", "no", "dunno"},
95 /* The following tests will disable TLS 1.x if the server is
97 {"whether we need to disable TLS 1.2", test_tls_disable2
, "no", "yes",
99 {"whether we need to disable TLS 1.1", test_tls_disable1
, "no", "yes",
101 {"whether we need to disable TLS 1.0", test_tls_disable0
, "no", "yes",
103 {"for Safe renegotiation support", test_safe_renegotiation
, "yes", "no",
105 {"for Safe renegotiation support (SCSV)", test_safe_renegotiation_scsv
,
106 "yes", "no", "dunno"},
107 {"for HTTPS server name", test_server
, "", "failed", "not checked"},
108 {"for version rollback bug in RSA PMS", test_rsa_pms
, "no", "yes",
110 {"for version rollback bug in Client Hello", test_version_rollback
,
111 "no", "yes", "dunno"},
114 {"whether the server ignores the RSA PMS version",
115 test_rsa_pms_version_check
, "yes", "no", "dunno"},
116 {"whether the server can accept Hello Extensions",
117 test_hello_extension
, "yes", "no", "dunno"},
118 {"whether the server can accept HeartBeat Extension", test_heartbeat_extension
, "yes", "no", "dunno"},
119 {"whether the server can accept small records (512 bytes)",
120 test_small_records
, "yes", "no", "dunno"},
121 {"whether the server can accept cipher suites not in SSL 3.0 spec",
122 test_unknown_ciphersuites
, "yes", "no", "dunno"},
123 {"whether the server can accept a bogus TLS record version in the client hello", test_version_oob
, "yes", "no", "dunno"},
124 {"for certificate information", test_certificate
, "", "", ""},
125 {"for trusted CAs", test_server_cas
, "", "", ""},
126 {"whether the server understands TLS closure alerts", test_bye
, "yes",
128 /* the fact that is after the closure alert test does matter.
130 {"whether the server supports session resumption",
131 test_session_resume2
, "yes", "no", "dunno"},
132 {"for export-grade ciphersuite support", test_export
, "yes", "no",
134 {"RSA-export ciphersuite info", test_export_info
, "", "N/A", "N/A"},
136 {"for anonymous authentication support", test_anonymous
, "yes", "no",
138 {"anonymous Diffie-Hellman group info", test_dhe_group
, "", "N/A",
141 {"for ephemeral Diffie-Hellman support", test_dhe
, "yes", "no",
143 {"ephemeral Diffie-Hellman group info", test_dhe_group
, "", "N/A",
145 {"for ephemeral EC Diffie-Hellman support", test_ecdhe
, "yes", "no",
147 {"ephemeral EC Diffie-Hellman group info", test_ecdhe_curve
, "", "N/A",
149 {"for AES-GCM cipher support", test_aes_gcm
, "yes", "no",
151 {"for AES-CBC cipher support", test_aes
, "yes", "no",
153 {"for CAMELLIA cipher support", test_camellia
, "yes", "no",
155 {"for 3DES-CBC cipher support", test_3des
, "yes", "no", "dunno"},
156 {"for ARCFOUR 128 cipher support", test_arcfour
, "yes", "no", "dunno"},
157 {"for ARCFOUR 40 cipher support", test_arcfour_40
, "yes", "no",
159 {"for MD5 MAC support", test_md5
, "yes", "no", "dunno"},
160 {"for SHA1 MAC support", test_sha
, "yes", "no", "dunno"},
161 {"for SHA256 MAC support", test_sha256
, "yes", "no", "dunno"},
163 {"for ZLIB compression support", test_zlib
, "yes",
166 {"for max record size", test_max_record_size
, "yes",
168 {"for OpenPGP authentication support", test_openpgp1
,
169 "yes", "no", "dunno"},
170 {NULL
, NULL
, NULL
, NULL
, NULL
}
177 main (int argc
, char **argv
)
181 gnutls_session_t state
;
182 char buffer
[MAX_BUF
+ 1];
184 struct addrinfo hints
, *res
, *ptr
;
186 set_program_name (argv
[0]);
187 cmd_parser(argc
, argv
);
190 signal (SIGPIPE
, SIG_IGN
);
195 if (gnutls_global_init () < 0)
197 fprintf (stderr
, "global state initialization error\n");
201 gnutls_global_set_log_function (tls_log_func
);
202 gnutls_global_set_log_level (debug
);
204 printf ("Resolving '%s'...\n", hostname
);
205 /* get server name */
206 memset (&hints
, 0, sizeof (hints
));
207 hints
.ai_socktype
= SOCK_STREAM
;
209 snprintf (portname
, sizeof (portname
), "%d", port
);
210 if ((err
= getaddrinfo (hostname
, portname
, &hints
, &res
)) != 0)
212 fprintf (stderr
, "Cannot resolve %s: %s\n", hostname
,
218 if (gnutls_certificate_allocate_credentials (&xcred
) < 0)
219 { /* space for 2 certificates */
220 fprintf (stderr
, "memory error\n");
226 if (gnutls_srp_allocate_client_credentials (&srp_cred
) < 0)
228 fprintf (stderr
, "memory error\n");
235 if (gnutls_anon_allocate_client_credentials (&anon_cred
) < 0)
237 fprintf (stderr
, "memory error\n");
247 if (tls_tests
[i
].test_name
== NULL
)
248 break; /* finished */
250 /* if neither of SSL3 and TLSv1 are supported, exit
252 if (i
> 6 && tls1_1_ok
== 0 && tls1_ok
== 0 && ssl3_ok
== 0)
255 "\nServer does not support any of SSL 3.0, TLS 1.0 and TLS 1.1\n");
260 for (ptr
= res
; ptr
!= NULL
; ptr
= ptr
->ai_next
)
262 sd
= socket (ptr
->ai_family
, ptr
->ai_socktype
, ptr
->ai_protocol
);
268 getnameinfo (ptr
->ai_addr
, ptr
->ai_addrlen
, buffer
, MAX_BUF
,
269 NULL
, 0, NI_NUMERICHOST
);
271 printf ("Connecting to '%s:%d'...\n", buffer
, port
);
272 if ((err
= connect (sd
, ptr
->ai_addr
, ptr
->ai_addrlen
)) != 0)
279 ERR (err
, "connect");
281 gnutls_init (&state
, GNUTLS_CLIENT
|GNUTLS_NO_EXTENSIONS
);
283 gnutls_transport_set_ptr (state
, (gnutls_transport_ptr_t
)
284 gl_fd_to_handle (sd
));
285 if (hostname
&& !isdigit(hostname
[0]) && strchr(hostname
, ':') == 0)
286 gnutls_server_name_set (state
, GNUTLS_NAME_DNS
, hostname
,
291 printf ("Checking %s...", tls_tests
[i
].test_name
);
294 ret
= tls_tests
[i
].func (state
);
296 if (ret
== TEST_SUCCEED
)
297 printf (" %s\n", tls_tests
[i
].suc_str
);
298 else if (ret
== TEST_FAILED
)
299 printf (" %s\n", tls_tests
[i
].fail_str
);
300 else if (ret
== TEST_UNSURE
)
301 printf (" %s\n", tls_tests
[i
].unsure_str
);
302 else if (ret
== TEST_IGNORE
)
308 while (ret
== TEST_IGNORE
&& tls_tests
[i
].test_name
!= NULL
);
310 gnutls_deinit (state
);
312 shutdown (sd
, SHUT_RDWR
); /* no more receptions */
322 gnutls_srp_free_client_credentials (srp_cred
);
324 gnutls_certificate_free_credentials (xcred
);
326 gnutls_anon_free_client_credentials (anon_cred
);
328 gnutls_global_deinit ();
333 static void cmd_parser (int argc
, char **argv
)
335 const char* rest
= NULL
;
336 int optct
= optionProcess( &gnutls_cli_debugOptions
, argc
, argv
);
340 if (rest
== NULL
&& argc
> 0)
344 port
= OPT_VALUE_PORT
;
349 hostname
= "localhost";
354 debug
= OPT_VALUE_DEBUG
;
356 if (HAVE_OPT(VERBOSE
))