2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
3 * 2009, 2010 Free Software Foundation, Inc.
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GnuTLS.
8 * GnuTLS is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
13 * GnuTLS is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 /* Work around problem reported in
25 <http://permalink.gmane.org/gmane.comp.lib.gnulib.bugs/15755>.*/
26 #if GETTIMEOFDAY_CLOBBERS_LOCALTIME
35 #include <gnutls/gnutls.h>
36 #include <gnutls/x509.h>
37 #include <gnutls/openpgp.h>
41 #define SU(x) (x!=NULL?x:"Unknown")
46 const char str_unknown[] = "(unknown)";
48 /* Hex encodes the given data.
51 raw_to_string (const unsigned char *raw, size_t raw_size)
53 static char buf[1024];
58 if (raw_size * 3 + 1 >= sizeof (buf))
61 for (i = 0; i < raw_size; i++)
63 sprintf (&(buf[i * 3]), "%02X%s", raw[i],
64 (i == raw_size - 1) ? "" : ":");
66 buf[sizeof (buf) - 1] = '\0';
72 print_x509_info (gnutls_session_t session, const char *hostname, int insecure)
74 gnutls_x509_crt_t crt;
75 const gnutls_datum_t *cert_list;
76 unsigned int cert_list_size = 0, j;
80 cert_list = gnutls_certificate_get_peers (session, &cert_list_size);
81 if (cert_list_size == 0)
83 fprintf (stderr, "No certificates found!\n");
87 printf (" - Got a certificate list of %d certificates.\n", cert_list_size);
89 for (j = 0; j < cert_list_size; j++)
93 gnutls_x509_crt_init (&crt);
94 ret = gnutls_x509_crt_import (crt, &cert_list[j], GNUTLS_X509_FMT_DER);
97 fprintf (stderr, "Decoding error: %s\n", gnutls_strerror (ret));
101 printf (" - Certificate[%d] info:\n - ", j);
104 ret = gnutls_x509_crt_print (crt, GNUTLS_CRT_PRINT_FULL, &cinfo);
106 ret = gnutls_x509_crt_print (crt, GNUTLS_CRT_PRINT_ONELINE, &cinfo);
109 printf ("%s\n", cinfo.data);
110 gnutls_free (cinfo.data);
118 ret = gnutls_x509_crt_export (crt, GNUTLS_X509_FMT_PEM, p, &size);
119 if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
124 fprintf (stderr, "gnutls_malloc\n");
128 ret = gnutls_x509_crt_export (crt, GNUTLS_X509_FMT_PEM,
133 fprintf (stderr, "Encoding error: %s\n", gnutls_strerror (ret));
137 fputs ("\n", stdout);
139 fputs ("\n", stdout);
144 if (j == 0 && hostname != NULL)
146 /* Check the hostname of the first certificate if it matches
147 * the name of the host we connected to.
149 if (gnutls_x509_crt_check_hostname (crt, hostname) == 0)
155 gnutls_x509_crt_deinit (crt);
158 if (hostname_ok == 1)
160 printf ("- The hostname in the certificate does NOT match '%s'\n",
165 else if (hostname_ok == 2)
167 printf ("- The hostname in the certificate matches '%s'.\n", hostname);
171 #ifdef ENABLE_OPENPGP
174 print_openpgp_info (gnutls_session_t session, const char *hostname,
178 gnutls_openpgp_crt_t crt;
179 const gnutls_datum_t *cert_list;
180 int cert_list_size = 0;
184 cert_list = gnutls_certificate_get_peers (session, &cert_list_size);
186 if (cert_list_size > 0)
188 gnutls_datum_t cinfo;
190 gnutls_openpgp_crt_init (&crt);
191 ret = gnutls_openpgp_crt_import (crt, &cert_list[0],
192 GNUTLS_OPENPGP_FMT_RAW);
195 fprintf (stderr, "Decoding error: %s\n", gnutls_strerror (ret));
200 ret = gnutls_openpgp_crt_print (crt, GNUTLS_CRT_PRINT_FULL, &cinfo);
203 gnutls_openpgp_crt_print (crt, GNUTLS_CRT_PRINT_ONELINE, &cinfo);
206 printf (" - %s\n", cinfo.data);
207 gnutls_free (cinfo.data);
215 ret = gnutls_openpgp_crt_export (crt, GNUTLS_OPENPGP_FMT_BASE64,
217 if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
222 fprintf (stderr, "gnutls_malloc\n");
226 ret = gnutls_openpgp_crt_export (crt, GNUTLS_OPENPGP_FMT_BASE64,
231 fprintf (stderr, "Encoding error: %s\n", gnutls_strerror (ret));
236 fputs ("\n", stdout);
241 if (hostname != NULL)
243 /* Check the hostname of the first certificate if it matches
244 * the name of the host we connected to.
246 if (gnutls_openpgp_crt_check_hostname (crt, hostname) == 0)
252 gnutls_openpgp_crt_deinit (crt);
255 if (hostname_ok == 1)
257 printf ("- The hostname in the certificate does NOT match '%s'\n",
262 else if (hostname_ok == 2)
264 printf ("- The hostname in the certificate matches '%s'.\n", hostname);
271 print_cert_vrfy (gnutls_session_t session)
276 rc = gnutls_certificate_verify_peers2 (session, &status);
279 printf ("- Could not verify certificate (err: %s)\n",
280 gnutls_strerror (rc));
284 if (rc == GNUTLS_E_NO_CERTIFICATE_FOUND)
286 printf ("- Peer did not send any certificate.\n");
290 if (gnutls_certificate_type_get (session) == GNUTLS_CRT_X509)
292 if (status & GNUTLS_CERT_REVOKED)
293 printf ("- Peer's certificate chain revoked\n");
294 if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
295 printf ("- Peer's certificate issuer is unknown\n");
296 if (status & GNUTLS_CERT_SIGNER_NOT_CA)
297 printf ("- Peer's certificate issuer is not a CA\n");
298 if (status & GNUTLS_CERT_INSECURE_ALGORITHM)
299 printf ("- Peer's certificate chain uses insecure algorithm\n");
300 if (status & GNUTLS_CERT_NOT_ACTIVATED)
302 ("- Peer's certificate chain uses not yet valid certificate\n");
303 if (status & GNUTLS_CERT_EXPIRED)
304 printf ("- Peer's certificate chain uses expired certificate\n");
305 if (status & GNUTLS_CERT_INVALID)
306 printf ("- Peer's certificate is NOT trusted\n");
308 printf ("- Peer's certificate is trusted\n");
312 if (status & GNUTLS_CERT_INVALID)
313 printf ("- Peer's key is invalid\n");
315 printf ("- Peer's key is valid\n");
316 if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
317 printf ("- Could not find a signer of the peer's key\n");
322 print_dh_info (gnutls_session_t session, const char *str)
324 printf ("- %sDiffie-Hellman parameters\n", str);
325 printf (" - Using prime: %d bits\n", gnutls_dh_get_prime_bits (session));
326 printf (" - Secret key: %d bits\n", gnutls_dh_get_secret_bits (session));
327 printf (" - Peer's public key: %d bits\n",
328 gnutls_dh_get_peers_public_bits (session));
333 gnutls_datum_t raw_gen = { NULL, 0 };
334 gnutls_datum_t raw_prime = { NULL, 0 };
335 gnutls_dh_params_t dh_params = NULL;
336 unsigned char *params_data = NULL;
337 size_t params_data_size = 0;
339 ret = gnutls_dh_get_group (session, &raw_gen, &raw_prime);
342 fprintf (stderr, "gnutls_dh_get_group %d\n", ret);
346 ret = gnutls_dh_params_init (&dh_params);
349 fprintf (stderr, "gnutls_dh_params_init %d\n", ret);
353 ret = gnutls_dh_params_import_raw (dh_params, &raw_prime, &raw_gen);
356 fprintf (stderr, "gnutls_dh_params_import_raw %d\n", ret);
360 ret = gnutls_dh_params_export_pkcs3 (dh_params,
362 params_data, ¶ms_data_size);
363 if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
365 fprintf (stderr, "gnutls_dh_params_export_pkcs3 %d\n", ret);
369 params_data = gnutls_malloc (params_data_size);
372 fprintf (stderr, "gnutls_malloc %d\n", ret);
376 ret = gnutls_dh_params_export_pkcs3 (dh_params,
378 params_data, ¶ms_data_size);
381 fprintf (stderr, "gnutls_dh_params_export_pkcs3-2 %d\n", ret);
385 printf (" - PKCS#3 format:\n\n%.*s\n", (int) params_data_size,
389 gnutls_free (params_data);
390 gnutls_free (raw_prime.data);
391 gnutls_free (raw_gen.data);
392 gnutls_dh_params_deinit (dh_params);
397 print_info (gnutls_session_t session, const char *hostname, int insecure)
400 gnutls_credentials_type_t cred;
401 gnutls_kx_algorithm_t kx;
404 /* print the key exchange's algorithm name
406 kx = gnutls_kx_get (session);
408 cred = gnutls_auth_get_type (session);
412 case GNUTLS_CRD_ANON:
413 print_dh_info (session, "Anonymous ");
418 /* This should be only called in server
421 if (gnutls_srp_server_get_username (session) != NULL)
422 printf ("- SRP authentication. Connected as '%s'\n",
423 gnutls_srp_server_get_username (session));
428 /* This returns NULL in server side.
430 if (gnutls_psk_client_get_hint (session) != NULL)
431 printf ("- PSK authentication. PSK hint '%s'\n",
432 gnutls_psk_client_get_hint (session));
433 /* This returns NULL in client side.
435 if (gnutls_psk_server_get_username (session) != NULL)
436 printf ("- PSK authentication. Connected as '%s'\n",
437 gnutls_psk_server_get_username (session));
438 if (kx == GNUTLS_KX_DHE_PSK)
439 print_dh_info (session, "Ephemeral ");
443 printf ("- TLS/IA authentication\n");
445 case GNUTLS_CRD_CERTIFICATE:
448 size_t dns_size = sizeof (dns);
451 /* This fails in client side */
452 if (gnutls_server_name_get (session, dns, &dns_size, &type, 0) == 0)
454 printf ("- Given server name[%d]: %s\n", type, dns);
458 if (kx == GNUTLS_KX_DHE_RSA || kx == GNUTLS_KX_DHE_DSS)
459 print_dh_info (session, "Ephemeral ");
461 print_cert_info (session, hostname, insecure);
463 print_cert_vrfy (session);
467 tmp = SU (gnutls_protocol_get_name (gnutls_protocol_get_version (session)));
468 printf ("- Version: %s\n", tmp);
470 tmp = SU (gnutls_kx_get_name (kx));
471 printf ("- Key Exchange: %s\n", tmp);
473 tmp = SU (gnutls_cipher_get_name (gnutls_cipher_get (session)));
474 printf ("- Cipher: %s\n", tmp);
476 tmp = SU (gnutls_mac_get_name (gnutls_mac_get (session)));
477 printf ("- MAC: %s\n", tmp);
479 tmp = SU (gnutls_compression_get_name (gnutls_compression_get (session)));
480 printf ("- Compression: %s\n", tmp);
485 size_t id_size = sizeof (id);
486 gnutls_session_get_id (session, id, &id_size);
487 printf ("- Session ID: %s\n", raw_to_string (id, id_size));
496 gnutls_session_channel_binding (session, GNUTLS_CB_TLS_UNIQUE, &cb);
498 fprintf (stderr, "Channel binding error: %s\n", gnutls_strerror (rc));
503 printf ("- Channel binding 'tls-unique': ");
504 for (i = 0; i < cb.size; i++)
505 printf ("%02x", cb.data[i]);
510 /* Warning: Do not print anything more here. The 'Compression:'
511 output MUST be the last non-verbose output. This is used by
512 Emacs starttls.el code. */
520 print_cert_info (gnutls_session_t session, const char *hostname, int insecure)
523 if (gnutls_certificate_client_get_request_status (session) != 0)
524 printf ("- Server has requested a certificate.\n");
526 printf ("- Certificate type: ");
527 switch (gnutls_certificate_type_get (session))
529 case GNUTLS_CRT_UNKNOWN:
530 printf ("Unknown\n");
535 case GNUTLS_CRT_X509:
537 print_x509_info (session, hostname, insecure);
539 #ifdef ENABLE_OPENPGP
540 case GNUTLS_CRT_OPENPGP:
541 printf ("OpenPGP\n");
542 print_openpgp_info (session, hostname, insecure);
549 print_list (int verbose)
555 gnutls_kx_algorithm_t kx;
556 gnutls_cipher_algorithm_t cipher;
557 gnutls_mac_algorithm_t mac;
558 gnutls_protocol_t version;
560 printf ("Cipher suites:\n");
561 for (i = 0; (name = gnutls_cipher_suite_info
562 (i, id, &kx, &cipher, &mac, &version)); i++)
564 printf ("%-50s\t0x%02x, 0x%02x\t%s\n",
566 (unsigned char) id[0], (unsigned char) id[1],
567 gnutls_protocol_get_name (version));
569 printf ("\tKey exchange: %s\n\tCipher: %s\n\tMAC: %s\n\n",
570 gnutls_kx_get_name (kx),
571 gnutls_cipher_get_name (cipher), gnutls_mac_get_name (mac));
576 const gnutls_certificate_type_t *p = gnutls_certificate_type_list ();
578 printf ("Certificate types: ");
581 printf ("CTYPE-%s", gnutls_certificate_type_get_name (*p));
590 const gnutls_protocol_t *p = gnutls_protocol_list ();
592 printf ("Protocols: ");
595 printf ("VERS-%s", gnutls_protocol_get_name (*p));
604 const gnutls_cipher_algorithm_t *p = gnutls_cipher_list ();
606 printf ("Ciphers: ");
609 printf ("%s", gnutls_cipher_get_name (*p));
618 const gnutls_mac_algorithm_t *p = gnutls_mac_list ();
623 printf ("%s", gnutls_mac_get_name (*p));
632 const gnutls_kx_algorithm_t *p = gnutls_kx_list ();
634 printf ("Key exchange algorithms: ");
637 printf ("%s", gnutls_kx_get_name (*p));
646 const gnutls_compression_method_t *p = gnutls_compression_list ();
648 printf ("Compression: ");
651 printf ("COMP-%s", gnutls_compression_get_name (*p));
660 const gnutls_pk_algorithm_t *p = gnutls_pk_list ();
662 printf ("Public Key Systems: ");
665 printf ("%s", gnutls_pk_algorithm_get_name (*p));
674 const gnutls_sign_algorithm_t *p = gnutls_sign_list ();
676 printf ("PK-signatures: ");
679 printf ("SIGN-%s", gnutls_sign_algorithm_get_name (*p));
692 WORD wVersionRequested;
695 wVersionRequested = MAKEWORD (1, 1);
696 if (WSAStartup (wVersionRequested, &wsaData) != 0)
698 perror ("WSA_STARTUP_ERROR");
703 /* converts a service name or a port (in string) to a
704 * port number. The protocol is assumed to be TCP.
706 * returns -1 on error;
709 service_to_port (const char *service)
712 struct servent *server_port;
714 port = atoi (service);
718 server_port = getservbyname (service, "tcp");
719 if (server_port == NULL)
721 perror ("getservbyname()");
725 return ntohs (server_port->s_port);