2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation
3 * Author: Nikos Mavrogiannopoulos
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/>.
23 /* Work around problem reported in
24 <http://permalink.gmane.org/gmane.comp.lib.gnulib.bugs/15755>.*/
25 #if GETTIMEOFDAY_CLOBBERS_LOCALTIME
32 #include <gnutls/gnutls.h>
33 #include <gnutls/extra.h>
34 #include <gnutls/x509.h>
35 #include <gnutls/openpgp.h>
39 #define SU(x) (x!=NULL?x:"Unknown")
44 static char buffer
[5 * 1024];
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
);
117 size
= sizeof (buffer
);
119 ret
= gnutls_x509_crt_export (crt
, GNUTLS_X509_FMT_PEM
,
123 fprintf (stderr
, "Encoding error: %s\n", gnutls_strerror (ret
));
127 fputs ("\n", stdout
);
128 fputs (buffer
, stdout
);
129 fputs ("\n", stdout
);
132 if (j
== 0 && hostname
!= NULL
)
134 /* Check the hostname of the first certificate if it matches
135 * the name of the host we connected to.
137 if (gnutls_x509_crt_check_hostname (crt
, hostname
) == 0)
143 gnutls_x509_crt_deinit (crt
);
146 if (hostname_ok
== 1)
148 printf ("- The hostname in the certificate does NOT match '%s'\n",
153 else if (hostname_ok
== 2)
155 printf ("- The hostname in the certificate matches '%s'.\n",
160 #ifdef ENABLE_OPENPGP
163 print_openpgp_info (gnutls_session_t session
, const char *hostname
,
167 gnutls_openpgp_crt_t crt
;
168 const gnutls_datum_t
*cert_list
;
169 int cert_list_size
= 0;
173 cert_list
= gnutls_certificate_get_peers (session
, &cert_list_size
);
175 if (cert_list_size
> 0)
177 gnutls_datum_t cinfo
;
179 gnutls_openpgp_crt_init (&crt
);
180 ret
= gnutls_openpgp_crt_import (crt
, &cert_list
[0],
181 GNUTLS_OPENPGP_FMT_RAW
);
184 fprintf (stderr
, "Decoding error: %s\n", gnutls_strerror (ret
));
189 ret
= gnutls_openpgp_crt_print (crt
, GNUTLS_CRT_PRINT_FULL
, &cinfo
);
191 ret
= gnutls_openpgp_crt_print (crt
, GNUTLS_CRT_PRINT_ONELINE
, &cinfo
);
194 printf (" - %s\n", cinfo
.data
);
195 gnutls_free (cinfo
.data
);
202 size
= sizeof (buffer
);
204 ret
= gnutls_openpgp_crt_export (crt
, GNUTLS_OPENPGP_FMT_BASE64
,
208 fprintf (stderr
, "Encoding error: %s\n", gnutls_strerror (ret
));
211 fputs (buffer
, stdout
);
212 fputs ("\n", stdout
);
215 if (hostname
!= NULL
)
217 /* Check the hostname of the first certificate if it matches
218 * the name of the host we connected to.
220 if (gnutls_openpgp_crt_check_hostname (crt
, hostname
) == 0)
226 gnutls_openpgp_crt_deinit (crt
);
229 if (hostname_ok
== 1)
231 printf ("- The hostname in the certificate does NOT match '%s'\n",
236 else if (hostname_ok
== 2)
238 printf ("- The hostname in the certificate matches '%s'.\n",
246 print_cert_vrfy (gnutls_session_t session
)
251 rc
= gnutls_certificate_verify_peers2 (session
, &status
);
254 printf ("- Could not verify certificate (err: %s)\n",
255 gnutls_strerror (rc
));
259 if (rc
== GNUTLS_E_NO_CERTIFICATE_FOUND
)
261 printf ("- Peer did not send any certificate.\n");
265 if (gnutls_certificate_type_get (session
) == GNUTLS_CRT_X509
)
267 if (status
& GNUTLS_CERT_REVOKED
)
268 printf ("- Peer's certificate chain revoked\n");
269 if (status
& GNUTLS_CERT_SIGNER_NOT_FOUND
)
270 printf ("- Peer's certificate issuer is unknown\n");
271 if (status
& GNUTLS_CERT_SIGNER_NOT_CA
)
272 printf ("- Peer's certificate issuer is not a CA\n");
273 if (status
& GNUTLS_CERT_INSECURE_ALGORITHM
)
274 printf ("- Peer's certificate chain uses insecure algorithm\n");
275 if (status
& GNUTLS_CERT_NOT_ACTIVATED
)
276 printf ("- Peer's certificate chain uses not yet valid certificate\n");
277 if (status
& GNUTLS_CERT_EXPIRED
)
278 printf ("- Peer's certificate chain uses expired certificate\n");
279 if (status
& GNUTLS_CERT_INVALID
)
280 printf ("- Peer's certificate is NOT trusted\n");
282 printf ("- Peer's certificate is trusted\n");
286 if (status
& GNUTLS_CERT_INVALID
)
287 printf ("- Peer's key is invalid\n");
289 printf ("- Peer's key is valid\n");
290 if (status
& GNUTLS_CERT_SIGNER_NOT_FOUND
)
291 printf ("- Could not find a signer of the peer's key\n");
296 print_dh_info (gnutls_session_t session
, const char *str
)
298 printf ("- %sDiffie-Hellman parameters\n", str
);
299 printf (" - Using prime: %d bits\n", gnutls_dh_get_prime_bits (session
));
300 printf (" - Secret key: %d bits\n", gnutls_dh_get_secret_bits (session
));
301 printf (" - Peer's public key: %d bits\n",
302 gnutls_dh_get_peers_public_bits (session
));
307 gnutls_datum_t raw_gen
= { NULL
, 0 };
308 gnutls_datum_t raw_prime
= { NULL
, 0 };
309 gnutls_dh_params_t dh_params
= NULL
;
310 unsigned char *params_data
= NULL
;
311 size_t params_data_size
= 0;
313 ret
= gnutls_dh_get_group (session
, &raw_gen
, &raw_prime
);
316 fprintf (stderr
, "gnutls_dh_get_group %d\n", ret
);
320 ret
= gnutls_dh_params_init (&dh_params
);
323 fprintf (stderr
, "gnutls_dh_params_init %d\n", ret
);
327 ret
= gnutls_dh_params_import_raw (dh_params
, &raw_prime
, &raw_gen
);
330 fprintf (stderr
, "gnutls_dh_params_import_raw %d\n", ret
);
334 ret
= gnutls_dh_params_export_pkcs3 (dh_params
,
336 params_data
, ¶ms_data_size
);
337 if (ret
!= GNUTLS_E_SHORT_MEMORY_BUFFER
)
339 fprintf (stderr
, "gnutls_dh_params_export_pkcs3 %d\n", ret
);
343 params_data
= gnutls_malloc (params_data_size
);
346 fprintf (stderr
, "gnutls_malloc %d\n", ret
);
350 ret
= gnutls_dh_params_export_pkcs3 (dh_params
,
352 params_data
, ¶ms_data_size
);
355 fprintf (stderr
, "gnutls_dh_params_export_pkcs3-2 %d\n", ret
);
359 printf (" - PKCS#3 format:\n\n%.*s\n", (int) params_data_size
,
363 gnutls_free (params_data
);
364 gnutls_free (raw_prime
.data
);
365 gnutls_free (raw_gen
.data
);
366 gnutls_dh_params_deinit (dh_params
);
371 print_info (gnutls_session_t session
, const char *hostname
, int insecure
)
374 gnutls_credentials_type_t cred
;
375 gnutls_kx_algorithm_t kx
;
378 /* print the key exchange's algorithm name
380 kx
= gnutls_kx_get (session
);
382 cred
= gnutls_auth_get_type (session
);
386 case GNUTLS_CRD_ANON
:
387 print_dh_info (session
, "Anonymous ");
392 /* This should be only called in server
395 if (gnutls_srp_server_get_username (session
) != NULL
)
396 printf ("- SRP authentication. Connected as '%s'\n",
397 gnutls_srp_server_get_username (session
));
402 /* This returns NULL in server side.
404 if (gnutls_psk_client_get_hint (session
) != NULL
)
405 printf ("- PSK authentication. PSK hint '%s'\n",
406 gnutls_psk_client_get_hint (session
));
407 /* This returns NULL in client side.
409 if (gnutls_psk_server_get_username (session
) != NULL
)
410 printf ("- PSK authentication. Connected as '%s'\n",
411 gnutls_psk_server_get_username (session
));
412 if (kx
== GNUTLS_KX_DHE_PSK
)
413 print_dh_info (session
, "Ephemeral ");
417 printf ("- TLS/IA authentication\n");
419 case GNUTLS_CRD_CERTIFICATE
:
422 size_t dns_size
= sizeof (dns
);
425 /* This fails in client side */
426 if (gnutls_server_name_get (session
, dns
, &dns_size
, &type
, 0) == 0)
428 printf ("- Given server name[%d]: %s\n", type
, dns
);
432 if (kx
== GNUTLS_KX_DHE_RSA
|| kx
== GNUTLS_KX_DHE_DSS
)
433 print_dh_info (session
, "Ephemeral ");
435 print_cert_info (session
, hostname
, insecure
);
437 print_cert_vrfy (session
);
441 tmp
= SU (gnutls_protocol_get_name (gnutls_protocol_get_version (session
)));
442 printf ("- Version: %s\n", tmp
);
444 tmp
= SU (gnutls_kx_get_name (kx
));
445 printf ("- Key Exchange: %s\n", tmp
);
447 tmp
= SU (gnutls_cipher_get_name (gnutls_cipher_get (session
)));
448 printf ("- Cipher: %s\n", tmp
);
450 tmp
= SU (gnutls_mac_get_name (gnutls_mac_get (session
)));
451 printf ("- MAC: %s\n", tmp
);
453 tmp
= SU (gnutls_compression_get_name (gnutls_compression_get (session
)));
454 printf ("- Compression: %s\n", tmp
);
459 size_t id_size
= sizeof (id
);
460 gnutls_session_get_id (session
, id
, &id_size
);
461 printf ("- Session ID: %s\n", raw_to_string (id
, id_size
));
471 print_cert_info (gnutls_session_t session
, const char *hostname
, int insecure
)
474 if (gnutls_certificate_client_get_request_status (session
) != 0)
475 printf ("- Server has requested a certificate.\n");
477 printf ("- Certificate type: ");
478 switch (gnutls_certificate_type_get (session
))
480 case GNUTLS_CRT_UNKNOWN
:
481 printf ("Unknown\n");
486 case GNUTLS_CRT_X509
:
488 print_x509_info (session
, hostname
, insecure
);
490 #ifdef ENABLE_OPENPGP
491 case GNUTLS_CRT_OPENPGP
:
492 printf ("OpenPGP\n");
493 print_openpgp_info (session
, hostname
, insecure
);
500 print_list (int verbose
)
506 gnutls_kx_algorithm_t kx
;
507 gnutls_cipher_algorithm_t cipher
;
508 gnutls_mac_algorithm_t mac
;
509 gnutls_protocol_t version
;
511 printf ("Cipher suites:\n");
512 for (i
= 0; (name
= gnutls_cipher_suite_info
513 (i
, id
, &kx
, &cipher
, &mac
, &version
)); i
++)
515 printf ("%-50s\t0x%02x, 0x%02x\t%s\n",
517 (unsigned char) id
[0], (unsigned char) id
[1],
518 gnutls_protocol_get_name (version
));
520 printf ("\tKey exchange: %s\n\tCipher: %s\n\tMAC: %s\n\n",
521 gnutls_kx_get_name (kx
),
522 gnutls_cipher_get_name (cipher
), gnutls_mac_get_name (mac
));
527 const gnutls_certificate_type_t
*p
= gnutls_certificate_type_list ();
529 printf ("Certificate types: ");
532 printf ("%s", gnutls_certificate_type_get_name (*p
));
541 const gnutls_protocol_t
*p
= gnutls_protocol_list ();
543 printf ("Protocols: ");
546 printf ("%s", gnutls_protocol_get_name (*p
));
555 const gnutls_cipher_algorithm_t
*p
= gnutls_cipher_list ();
557 printf ("Ciphers: ");
560 printf ("%s", gnutls_cipher_get_name (*p
));
569 const gnutls_mac_algorithm_t
*p
= gnutls_mac_list ();
574 printf ("%s", gnutls_mac_get_name (*p
));
583 const gnutls_kx_algorithm_t
*p
= gnutls_kx_list ();
585 printf ("Key exchange algorithms: ");
588 printf ("%s", gnutls_kx_get_name (*p
));
597 const gnutls_compression_method_t
*p
= gnutls_compression_list ();
599 printf ("Compression: ");
602 printf ("%s", gnutls_compression_get_name (*p
));
611 const gnutls_pk_algorithm_t
*p
= gnutls_pk_list ();
613 printf ("Public Key Systems: ");
616 printf ("%s", gnutls_pk_algorithm_get_name (*p
));
625 const gnutls_sign_algorithm_t
*p
= gnutls_sign_list ();
627 printf ("PK-signatures: ");
630 printf ("%s", gnutls_sign_algorithm_get_name (*p
));
639 static int depr_printed
= 0;
640 #define DEPRECATED if (depr_printed==0) { \
641 fprintf(stderr, "This method of specifying algorithms is deprecated. Please use the --priority option.\n"); \
646 parse_protocols (char **protocols
, int protocols_size
, int *protocol_priority
)
650 if (protocols
!= NULL
&& protocols_size
> 0)
654 for (j
= i
= 0; i
< protocols_size
; i
++)
656 if (strncasecmp (protocols
[i
], "SSL", 3) == 0)
657 protocol_priority
[j
++] = GNUTLS_SSL3
;
658 else if (strncasecmp (protocols
[i
], "TLS1.1", 6) == 0)
659 protocol_priority
[j
++] = GNUTLS_TLS1_1
;
660 else if (strncasecmp (protocols
[i
], "TLS1.2", 6) == 0)
661 protocol_priority
[j
++] = GNUTLS_TLS1_2
;
662 else if (strncasecmp (protocols
[i
], "TLS", 3) == 0)
663 protocol_priority
[j
++] = GNUTLS_TLS1_0
;
665 fprintf (stderr
, "Unknown protocol: '%s'\n", protocols
[i
]);
667 protocol_priority
[j
] = 0;
672 parse_ciphers (char **ciphers
, int nciphers
, int *cipher_priority
)
677 if (ciphers
!= NULL
&& nciphers
> 0)
680 for (j
= i
= 0; i
< nciphers
; i
++)
682 if (strncasecmp (ciphers
[i
], "AES-2", 5) == 0)
683 cipher_priority
[j
++] = GNUTLS_CIPHER_AES_256_CBC
;
684 else if (strncasecmp (ciphers
[i
], "AES", 3) == 0)
685 cipher_priority
[j
++] = GNUTLS_CIPHER_AES_128_CBC
;
686 else if (strncasecmp (ciphers
[i
], "3DE", 3) == 0)
687 cipher_priority
[j
++] = GNUTLS_CIPHER_3DES_CBC
;
688 else if (strcasecmp (ciphers
[i
], "ARCFOUR-40") == 0)
689 cipher_priority
[j
++] = GNUTLS_CIPHER_ARCFOUR_40
;
690 else if (strcasecmp (ciphers
[i
], "ARCFOUR") == 0)
691 cipher_priority
[j
++] = GNUTLS_CIPHER_ARCFOUR_128
;
692 #ifdef ENABLE_CAMELLIA
693 else if (strncasecmp (ciphers
[i
], "CAMELLIA-2", 10) == 0)
694 cipher_priority
[j
++] = GNUTLS_CIPHER_CAMELLIA_256_CBC
;
695 else if (strncasecmp (ciphers
[i
], "CAM", 3) == 0)
696 cipher_priority
[j
++] = GNUTLS_CIPHER_CAMELLIA_128_CBC
;
698 else if (strncasecmp (ciphers
[i
], "NUL", 3) == 0)
699 cipher_priority
[j
++] = GNUTLS_CIPHER_NULL
;
701 fprintf (stderr
, "Unknown cipher: '%s'\n", ciphers
[i
]);
703 cipher_priority
[j
] = 0;
708 parse_macs (char **macs
, int nmacs
, int *mac_priority
)
713 if (macs
!= NULL
&& nmacs
> 0)
716 for (j
= i
= 0; i
< nmacs
; i
++)
718 if (strncasecmp (macs
[i
], "MD5", 3) == 0)
719 mac_priority
[j
++] = GNUTLS_MAC_MD5
;
720 else if (strncasecmp (macs
[i
], "RMD", 3) == 0)
721 mac_priority
[j
++] = GNUTLS_MAC_RMD160
;
722 else if (strncasecmp (macs
[i
], "SHA512", 6) == 0)
723 mac_priority
[j
++] = GNUTLS_MAC_SHA512
;
724 else if (strncasecmp (macs
[i
], "SHA384", 6) == 0)
725 mac_priority
[j
++] = GNUTLS_MAC_SHA384
;
726 else if (strncasecmp (macs
[i
], "SHA256", 6) == 0)
727 mac_priority
[j
++] = GNUTLS_MAC_SHA256
;
728 else if (strncasecmp (macs
[i
], "SHA", 3) == 0)
729 mac_priority
[j
++] = GNUTLS_MAC_SHA1
;
731 fprintf (stderr
, "Unknown MAC: '%s'\n", macs
[i
]);
738 parse_ctypes (char **ctype
, int nctype
, int *cert_type_priority
)
742 if (ctype
!= NULL
&& nctype
> 0)
745 for (j
= i
= 0; i
< nctype
; i
++)
747 if (strncasecmp (ctype
[i
], "OPE", 3) == 0)
748 cert_type_priority
[j
++] = GNUTLS_CRT_OPENPGP
;
749 else if (strncasecmp (ctype
[i
], "X", 1) == 0)
750 cert_type_priority
[j
++] = GNUTLS_CRT_X509
;
752 fprintf (stderr
, "Unknown certificate type: '%s'\n", ctype
[i
]);
754 cert_type_priority
[j
] = 0;
759 parse_kx (char **kx
, int nkx
, int *kx_priority
)
764 if (kx
!= NULL
&& nkx
> 0)
767 for (j
= i
= 0; i
< nkx
; i
++)
769 if (strcasecmp (kx
[i
], "SRP") == 0)
770 kx_priority
[j
++] = GNUTLS_KX_SRP
;
771 else if (strcasecmp (kx
[i
], "SRP-RSA") == 0)
772 kx_priority
[j
++] = GNUTLS_KX_SRP_RSA
;
773 else if (strcasecmp (kx
[i
], "SRP-DSS") == 0)
774 kx_priority
[j
++] = GNUTLS_KX_SRP_DSS
;
775 else if (strcasecmp (kx
[i
], "RSA") == 0)
776 kx_priority
[j
++] = GNUTLS_KX_RSA
;
777 else if (strcasecmp (kx
[i
], "PSK") == 0)
778 kx_priority
[j
++] = GNUTLS_KX_PSK
;
779 else if (strcasecmp (kx
[i
], "DHE-PSK") == 0)
780 kx_priority
[j
++] = GNUTLS_KX_DHE_PSK
;
781 else if (strcasecmp (kx
[i
], "RSA-EXPORT") == 0)
782 kx_priority
[j
++] = GNUTLS_KX_RSA_EXPORT
;
783 else if (strncasecmp (kx
[i
], "DHE-RSA", 7) == 0)
784 kx_priority
[j
++] = GNUTLS_KX_DHE_RSA
;
785 else if (strncasecmp (kx
[i
], "DHE-DSS", 7) == 0)
786 kx_priority
[j
++] = GNUTLS_KX_DHE_DSS
;
787 else if (strncasecmp (kx
[i
], "ANON", 4) == 0)
788 kx_priority
[j
++] = GNUTLS_KX_ANON_DH
;
790 fprintf (stderr
, "Unknown key exchange: '%s'\n", kx
[i
]);
797 parse_comp (char **comp
, int ncomp
, int *comp_priority
)
801 if (comp
!= NULL
&& ncomp
> 0)
804 for (j
= i
= 0; i
< ncomp
; i
++)
806 if (strncasecmp (comp
[i
], "NUL", 3) == 0)
807 comp_priority
[j
++] = GNUTLS_COMP_NULL
;
808 else if (strncasecmp (comp
[i
], "ZLI", 3) == 0)
809 comp_priority
[j
++] = GNUTLS_COMP_DEFLATE
;
810 else if (strncasecmp (comp
[i
], "DEF", 3) == 0)
811 comp_priority
[j
++] = GNUTLS_COMP_DEFLATE
;
812 else if (strncasecmp (comp
[i
], "LZO", 3) == 0)
813 comp_priority
[j
++] = GNUTLS_COMP_LZO
;
815 fprintf (stderr
, "Unknown compression: '%s'\n", comp
[i
]);
817 comp_priority
[j
] = 0;
825 WORD wVersionRequested
;
828 wVersionRequested
= MAKEWORD (1, 1);
829 if (WSAStartup (wVersionRequested
, &wsaData
) != 0)
831 perror ("WSA_STARTUP_ERROR");
836 /* converts a service name or a port (in string) to a
837 * port number. The protocol is assumed to be TCP.
839 * returns -1 on error;
842 service_to_port (const char *service
)
845 struct servent
*server_port
;
847 port
= atoi (service
);
851 server_port
= getservbyname (service
, "tcp");
852 if (server_port
== NULL
)
854 perror ("getservbyname()");
858 return ntohs (server_port
->s_port
);