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
33 #include <gnutls/gnutls.h>
34 #include <gnutls/extra.h>
35 #include <gnutls/x509.h>
36 #include <gnutls/openpgp.h>
40 #define SU(x) (x!=NULL?x:"Unknown")
45 static char buffer
[5 * 1024];
47 const char str_unknown
[] = "(unknown)";
49 /* Hex encodes the given data.
52 raw_to_string (const unsigned char *raw
, size_t raw_size
)
54 static char buf
[1024];
59 if (raw_size
* 3 + 1 >= sizeof (buf
))
62 for (i
= 0; i
< raw_size
; i
++)
64 sprintf (&(buf
[i
* 3]), "%02X%s", raw
[i
],
65 (i
== raw_size
- 1) ? "" : ":");
67 buf
[sizeof (buf
) - 1] = '\0';
73 print_x509_info (gnutls_session_t session
, const char *hostname
, int insecure
)
75 gnutls_x509_crt_t crt
;
76 const gnutls_datum_t
*cert_list
;
77 unsigned int cert_list_size
= 0, j
;
81 cert_list
= gnutls_certificate_get_peers (session
, &cert_list_size
);
82 if (cert_list_size
== 0)
84 fprintf (stderr
, "No certificates found!\n");
88 printf (" - Got a certificate list of %d certificates.\n", cert_list_size
);
90 for (j
= 0; j
< cert_list_size
; j
++)
94 gnutls_x509_crt_init (&crt
);
95 ret
= gnutls_x509_crt_import (crt
, &cert_list
[j
], GNUTLS_X509_FMT_DER
);
98 fprintf (stderr
, "Decoding error: %s\n", gnutls_strerror (ret
));
102 printf (" - Certificate[%d] info:\n - ", j
);
105 ret
= gnutls_x509_crt_print (crt
, GNUTLS_CRT_PRINT_FULL
, &cinfo
);
107 ret
= gnutls_x509_crt_print (crt
, GNUTLS_CRT_PRINT_ONELINE
, &cinfo
);
110 printf ("%s\n", cinfo
.data
);
111 gnutls_free (cinfo
.data
);
118 size
= sizeof (buffer
);
120 ret
= gnutls_x509_crt_export (crt
, GNUTLS_X509_FMT_PEM
,
124 fprintf (stderr
, "Encoding error: %s\n", gnutls_strerror (ret
));
128 fputs ("\n", stdout
);
129 fputs (buffer
, stdout
);
130 fputs ("\n", stdout
);
133 if (j
== 0 && hostname
!= NULL
)
135 /* Check the hostname of the first certificate if it matches
136 * the name of the host we connected to.
138 if (gnutls_x509_crt_check_hostname (crt
, hostname
) == 0)
144 gnutls_x509_crt_deinit (crt
);
147 if (hostname_ok
== 1)
149 printf ("- The hostname in the certificate does NOT match '%s'\n",
154 else if (hostname_ok
== 2)
156 printf ("- The hostname in the certificate matches '%s'.\n", hostname
);
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
);
192 gnutls_openpgp_crt_print (crt
, GNUTLS_CRT_PRINT_ONELINE
, &cinfo
);
195 printf (" - %s\n", cinfo
.data
);
196 gnutls_free (cinfo
.data
);
203 size
= sizeof (buffer
);
205 ret
= gnutls_openpgp_crt_export (crt
, GNUTLS_OPENPGP_FMT_BASE64
,
209 fprintf (stderr
, "Encoding error: %s\n", gnutls_strerror (ret
));
212 fputs (buffer
, stdout
);
213 fputs ("\n", stdout
);
216 if (hostname
!= NULL
)
218 /* Check the hostname of the first certificate if it matches
219 * the name of the host we connected to.
221 if (gnutls_openpgp_crt_check_hostname (crt
, hostname
) == 0)
227 gnutls_openpgp_crt_deinit (crt
);
230 if (hostname_ok
== 1)
232 printf ("- The hostname in the certificate does NOT match '%s'\n",
237 else if (hostname_ok
== 2)
239 printf ("- The hostname in the certificate matches '%s'.\n", hostname
);
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
)
277 ("- Peer's certificate chain uses not yet valid certificate\n");
278 if (status
& GNUTLS_CERT_EXPIRED
)
279 printf ("- Peer's certificate chain uses expired certificate\n");
280 if (status
& GNUTLS_CERT_INVALID
)
281 printf ("- Peer's certificate is NOT trusted\n");
283 printf ("- Peer's certificate is trusted\n");
287 if (status
& GNUTLS_CERT_INVALID
)
288 printf ("- Peer's key is invalid\n");
290 printf ("- Peer's key is valid\n");
291 if (status
& GNUTLS_CERT_SIGNER_NOT_FOUND
)
292 printf ("- Could not find a signer of the peer's key\n");
297 print_dh_info (gnutls_session_t session
, const char *str
)
299 printf ("- %sDiffie-Hellman parameters\n", str
);
300 printf (" - Using prime: %d bits\n", gnutls_dh_get_prime_bits (session
));
301 printf (" - Secret key: %d bits\n", gnutls_dh_get_secret_bits (session
));
302 printf (" - Peer's public key: %d bits\n",
303 gnutls_dh_get_peers_public_bits (session
));
308 gnutls_datum_t raw_gen
= { NULL
, 0 };
309 gnutls_datum_t raw_prime
= { NULL
, 0 };
310 gnutls_dh_params_t dh_params
= NULL
;
311 unsigned char *params_data
= NULL
;
312 size_t params_data_size
= 0;
314 ret
= gnutls_dh_get_group (session
, &raw_gen
, &raw_prime
);
317 fprintf (stderr
, "gnutls_dh_get_group %d\n", ret
);
321 ret
= gnutls_dh_params_init (&dh_params
);
324 fprintf (stderr
, "gnutls_dh_params_init %d\n", ret
);
328 ret
= gnutls_dh_params_import_raw (dh_params
, &raw_prime
, &raw_gen
);
331 fprintf (stderr
, "gnutls_dh_params_import_raw %d\n", ret
);
335 ret
= gnutls_dh_params_export_pkcs3 (dh_params
,
337 params_data
, ¶ms_data_size
);
338 if (ret
!= GNUTLS_E_SHORT_MEMORY_BUFFER
)
340 fprintf (stderr
, "gnutls_dh_params_export_pkcs3 %d\n", ret
);
344 params_data
= gnutls_malloc (params_data_size
);
347 fprintf (stderr
, "gnutls_malloc %d\n", ret
);
351 ret
= gnutls_dh_params_export_pkcs3 (dh_params
,
353 params_data
, ¶ms_data_size
);
356 fprintf (stderr
, "gnutls_dh_params_export_pkcs3-2 %d\n", ret
);
360 printf (" - PKCS#3 format:\n\n%.*s\n", (int) params_data_size
,
364 gnutls_free (params_data
);
365 gnutls_free (raw_prime
.data
);
366 gnutls_free (raw_gen
.data
);
367 gnutls_dh_params_deinit (dh_params
);
372 print_info (gnutls_session_t session
, const char *hostname
, int insecure
)
375 gnutls_credentials_type_t cred
;
376 gnutls_kx_algorithm_t kx
;
379 /* print the key exchange's algorithm name
381 kx
= gnutls_kx_get (session
);
383 cred
= gnutls_auth_get_type (session
);
387 case GNUTLS_CRD_ANON
:
388 print_dh_info (session
, "Anonymous ");
393 /* This should be only called in server
396 if (gnutls_srp_server_get_username (session
) != NULL
)
397 printf ("- SRP authentication. Connected as '%s'\n",
398 gnutls_srp_server_get_username (session
));
403 /* This returns NULL in server side.
405 if (gnutls_psk_client_get_hint (session
) != NULL
)
406 printf ("- PSK authentication. PSK hint '%s'\n",
407 gnutls_psk_client_get_hint (session
));
408 /* This returns NULL in client side.
410 if (gnutls_psk_server_get_username (session
) != NULL
)
411 printf ("- PSK authentication. Connected as '%s'\n",
412 gnutls_psk_server_get_username (session
));
413 if (kx
== GNUTLS_KX_DHE_PSK
)
414 print_dh_info (session
, "Ephemeral ");
418 printf ("- TLS/IA authentication\n");
420 case GNUTLS_CRD_CERTIFICATE
:
423 size_t dns_size
= sizeof (dns
);
426 /* This fails in client side */
427 if (gnutls_server_name_get (session
, dns
, &dns_size
, &type
, 0) == 0)
429 printf ("- Given server name[%d]: %s\n", type
, dns
);
433 if (kx
== GNUTLS_KX_DHE_RSA
|| kx
== GNUTLS_KX_DHE_DSS
)
434 print_dh_info (session
, "Ephemeral ");
436 print_cert_info (session
, hostname
, insecure
);
438 print_cert_vrfy (session
);
442 tmp
= SU (gnutls_protocol_get_name (gnutls_protocol_get_version (session
)));
443 printf ("- Version: %s\n", tmp
);
445 tmp
= SU (gnutls_kx_get_name (kx
));
446 printf ("- Key Exchange: %s\n", tmp
);
448 tmp
= SU (gnutls_cipher_get_name (gnutls_cipher_get (session
)));
449 printf ("- Cipher: %s\n", tmp
);
451 tmp
= SU (gnutls_mac_get_name (gnutls_mac_get (session
)));
452 printf ("- MAC: %s\n", tmp
);
454 tmp
= SU (gnutls_compression_get_name (gnutls_compression_get (session
)));
455 printf ("- Compression: %s\n", tmp
);
460 size_t id_size
= sizeof (id
);
461 gnutls_session_get_id (session
, id
, &id_size
);
462 printf ("- Session ID: %s\n", raw_to_string (id
, id_size
));
472 print_cert_info (gnutls_session_t session
, const char *hostname
, int insecure
)
475 if (gnutls_certificate_client_get_request_status (session
) != 0)
476 printf ("- Server has requested a certificate.\n");
478 printf ("- Certificate type: ");
479 switch (gnutls_certificate_type_get (session
))
481 case GNUTLS_CRT_UNKNOWN
:
482 printf ("Unknown\n");
487 case GNUTLS_CRT_X509
:
489 print_x509_info (session
, hostname
, insecure
);
491 #ifdef ENABLE_OPENPGP
492 case GNUTLS_CRT_OPENPGP
:
493 printf ("OpenPGP\n");
494 print_openpgp_info (session
, hostname
, insecure
);
501 print_list (int verbose
)
507 gnutls_kx_algorithm_t kx
;
508 gnutls_cipher_algorithm_t cipher
;
509 gnutls_mac_algorithm_t mac
;
510 gnutls_protocol_t version
;
512 printf ("Cipher suites:\n");
513 for (i
= 0; (name
= gnutls_cipher_suite_info
514 (i
, id
, &kx
, &cipher
, &mac
, &version
)); i
++)
516 printf ("%-50s\t0x%02x, 0x%02x\t%s\n",
518 (unsigned char) id
[0], (unsigned char) id
[1],
519 gnutls_protocol_get_name (version
));
521 printf ("\tKey exchange: %s\n\tCipher: %s\n\tMAC: %s\n\n",
522 gnutls_kx_get_name (kx
),
523 gnutls_cipher_get_name (cipher
), gnutls_mac_get_name (mac
));
528 const gnutls_certificate_type_t
*p
= gnutls_certificate_type_list ();
530 printf ("Certificate types: ");
533 printf ("%s", gnutls_certificate_type_get_name (*p
));
542 const gnutls_protocol_t
*p
= gnutls_protocol_list ();
544 printf ("Protocols: ");
547 printf ("%s", gnutls_protocol_get_name (*p
));
556 const gnutls_cipher_algorithm_t
*p
= gnutls_cipher_list ();
558 printf ("Ciphers: ");
561 printf ("%s", gnutls_cipher_get_name (*p
));
570 const gnutls_mac_algorithm_t
*p
= gnutls_mac_list ();
575 printf ("%s", gnutls_mac_get_name (*p
));
584 const gnutls_kx_algorithm_t
*p
= gnutls_kx_list ();
586 printf ("Key exchange algorithms: ");
589 printf ("%s", gnutls_kx_get_name (*p
));
598 const gnutls_compression_method_t
*p
= gnutls_compression_list ();
600 printf ("Compression: ");
603 printf ("%s", gnutls_compression_get_name (*p
));
612 const gnutls_pk_algorithm_t
*p
= gnutls_pk_list ();
614 printf ("Public Key Systems: ");
617 printf ("%s", gnutls_pk_algorithm_get_name (*p
));
626 const gnutls_sign_algorithm_t
*p
= gnutls_sign_list ();
628 printf ("PK-signatures: ");
631 printf ("%s", gnutls_sign_algorithm_get_name (*p
));
640 static int depr_printed
= 0;
641 #define DEPRECATED if (depr_printed==0) { \
642 fprintf(stderr, "This method of specifying algorithms is deprecated. Please use the --priority option.\n"); \
647 parse_protocols (char **protocols
, int protocols_size
, int *protocol_priority
)
651 if (protocols
!= NULL
&& protocols_size
> 0)
655 for (j
= i
= 0; i
< protocols_size
; i
++)
657 if (strncasecmp (protocols
[i
], "SSL", 3) == 0)
658 protocol_priority
[j
++] = GNUTLS_SSL3
;
659 else if (strncasecmp (protocols
[i
], "TLS1.1", 6) == 0)
660 protocol_priority
[j
++] = GNUTLS_TLS1_1
;
661 else if (strncasecmp (protocols
[i
], "TLS1.2", 6) == 0)
662 protocol_priority
[j
++] = GNUTLS_TLS1_2
;
663 else if (strncasecmp (protocols
[i
], "TLS", 3) == 0)
664 protocol_priority
[j
++] = GNUTLS_TLS1_0
;
666 fprintf (stderr
, "Unknown protocol: '%s'\n", protocols
[i
]);
668 protocol_priority
[j
] = 0;
673 parse_ciphers (char **ciphers
, int nciphers
, int *cipher_priority
)
678 if (ciphers
!= NULL
&& nciphers
> 0)
681 for (j
= i
= 0; i
< nciphers
; i
++)
683 if (strncasecmp (ciphers
[i
], "AES-2", 5) == 0)
684 cipher_priority
[j
++] = GNUTLS_CIPHER_AES_256_CBC
;
685 else if (strncasecmp (ciphers
[i
], "AES", 3) == 0)
686 cipher_priority
[j
++] = GNUTLS_CIPHER_AES_128_CBC
;
687 else if (strncasecmp (ciphers
[i
], "3DE", 3) == 0)
688 cipher_priority
[j
++] = GNUTLS_CIPHER_3DES_CBC
;
689 else if (strcasecmp (ciphers
[i
], "ARCFOUR-40") == 0)
690 cipher_priority
[j
++] = GNUTLS_CIPHER_ARCFOUR_40
;
691 else if (strcasecmp (ciphers
[i
], "ARCFOUR") == 0)
692 cipher_priority
[j
++] = GNUTLS_CIPHER_ARCFOUR_128
;
693 #ifdef ENABLE_CAMELLIA
694 else if (strncasecmp (ciphers
[i
], "CAMELLIA-2", 10) == 0)
695 cipher_priority
[j
++] = GNUTLS_CIPHER_CAMELLIA_256_CBC
;
696 else if (strncasecmp (ciphers
[i
], "CAM", 3) == 0)
697 cipher_priority
[j
++] = GNUTLS_CIPHER_CAMELLIA_128_CBC
;
699 else if (strncasecmp (ciphers
[i
], "NUL", 3) == 0)
700 cipher_priority
[j
++] = GNUTLS_CIPHER_NULL
;
702 fprintf (stderr
, "Unknown cipher: '%s'\n", ciphers
[i
]);
704 cipher_priority
[j
] = 0;
709 parse_macs (char **macs
, int nmacs
, int *mac_priority
)
714 if (macs
!= NULL
&& nmacs
> 0)
717 for (j
= i
= 0; i
< nmacs
; i
++)
719 if (strncasecmp (macs
[i
], "MD5", 3) == 0)
720 mac_priority
[j
++] = GNUTLS_MAC_MD5
;
721 else if (strncasecmp (macs
[i
], "RMD", 3) == 0)
722 mac_priority
[j
++] = GNUTLS_MAC_RMD160
;
723 else if (strncasecmp (macs
[i
], "SHA512", 6) == 0)
724 mac_priority
[j
++] = GNUTLS_MAC_SHA512
;
725 else if (strncasecmp (macs
[i
], "SHA384", 6) == 0)
726 mac_priority
[j
++] = GNUTLS_MAC_SHA384
;
727 else if (strncasecmp (macs
[i
], "SHA256", 6) == 0)
728 mac_priority
[j
++] = GNUTLS_MAC_SHA256
;
729 else if (strncasecmp (macs
[i
], "SHA", 3) == 0)
730 mac_priority
[j
++] = GNUTLS_MAC_SHA1
;
732 fprintf (stderr
, "Unknown MAC: '%s'\n", macs
[i
]);
739 parse_ctypes (char **ctype
, int nctype
, int *cert_type_priority
)
743 if (ctype
!= NULL
&& nctype
> 0)
746 for (j
= i
= 0; i
< nctype
; i
++)
748 if (strncasecmp (ctype
[i
], "OPE", 3) == 0)
749 cert_type_priority
[j
++] = GNUTLS_CRT_OPENPGP
;
750 else if (strncasecmp (ctype
[i
], "X", 1) == 0)
751 cert_type_priority
[j
++] = GNUTLS_CRT_X509
;
753 fprintf (stderr
, "Unknown certificate type: '%s'\n", ctype
[i
]);
755 cert_type_priority
[j
] = 0;
760 parse_kx (char **kx
, int nkx
, int *kx_priority
)
765 if (kx
!= NULL
&& nkx
> 0)
768 for (j
= i
= 0; i
< nkx
; i
++)
770 if (strcasecmp (kx
[i
], "SRP") == 0)
771 kx_priority
[j
++] = GNUTLS_KX_SRP
;
772 else if (strcasecmp (kx
[i
], "SRP-RSA") == 0)
773 kx_priority
[j
++] = GNUTLS_KX_SRP_RSA
;
774 else if (strcasecmp (kx
[i
], "SRP-DSS") == 0)
775 kx_priority
[j
++] = GNUTLS_KX_SRP_DSS
;
776 else if (strcasecmp (kx
[i
], "RSA") == 0)
777 kx_priority
[j
++] = GNUTLS_KX_RSA
;
778 else if (strcasecmp (kx
[i
], "PSK") == 0)
779 kx_priority
[j
++] = GNUTLS_KX_PSK
;
780 else if (strcasecmp (kx
[i
], "DHE-PSK") == 0)
781 kx_priority
[j
++] = GNUTLS_KX_DHE_PSK
;
782 else if (strcasecmp (kx
[i
], "RSA-EXPORT") == 0)
783 kx_priority
[j
++] = GNUTLS_KX_RSA_EXPORT
;
784 else if (strncasecmp (kx
[i
], "DHE-RSA", 7) == 0)
785 kx_priority
[j
++] = GNUTLS_KX_DHE_RSA
;
786 else if (strncasecmp (kx
[i
], "DHE-DSS", 7) == 0)
787 kx_priority
[j
++] = GNUTLS_KX_DHE_DSS
;
788 else if (strncasecmp (kx
[i
], "ANON", 4) == 0)
789 kx_priority
[j
++] = GNUTLS_KX_ANON_DH
;
791 fprintf (stderr
, "Unknown key exchange: '%s'\n", kx
[i
]);
798 parse_comp (char **comp
, int ncomp
, int *comp_priority
)
802 if (comp
!= NULL
&& ncomp
> 0)
805 for (j
= i
= 0; i
< ncomp
; i
++)
807 if (strncasecmp (comp
[i
], "NUL", 3) == 0)
808 comp_priority
[j
++] = GNUTLS_COMP_NULL
;
809 else if (strncasecmp (comp
[i
], "ZLI", 3) == 0)
810 comp_priority
[j
++] = GNUTLS_COMP_DEFLATE
;
811 else if (strncasecmp (comp
[i
], "DEF", 3) == 0)
812 comp_priority
[j
++] = GNUTLS_COMP_DEFLATE
;
813 else if (strncasecmp (comp
[i
], "LZO", 3) == 0)
814 comp_priority
[j
++] = GNUTLS_COMP_LZO
;
816 fprintf (stderr
, "Unknown compression: '%s'\n", comp
[i
]);
818 comp_priority
[j
] = 0;
826 WORD wVersionRequested
;
829 wVersionRequested
= MAKEWORD (1, 1);
830 if (WSAStartup (wVersionRequested
, &wsaData
) != 0)
832 perror ("WSA_STARTUP_ERROR");
837 /* converts a service name or a port (in string) to a
838 * port number. The protocol is assumed to be TCP.
840 * returns -1 on error;
843 service_to_port (const char *service
)
846 struct servent
*server_port
;
848 port
= atoi (service
);
852 server_port
= getservbyname (service
, "tcp");
853 if (server_port
== NULL
)
855 perror ("getservbyname()");
859 return ntohs (server_port
->s_port
);