wmbiff: Remove LZO compression.
[dockapps.git] / wmbiff / wmbiff / gnutls-common.c
blob17c8f7e1eab2baf97b71b1944a3e96d22ddd9425
1 #include <config.h>
2 # include <sys/types.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <gnutls/gnutls.h>
7 #include <gnutls/x509.h>
8 #include <gnutls/openpgp.h>
9 #include <time.h>
10 #include <gnutls-common.h>
12 #define TEST_STRING
14 int xml = 0;
15 int print_cert;
17 static char buffer[5*1024];
19 #define PRINTX(x,y) if (y[0]!=0) printf(" # %s %s\n", x, y)
20 #define PRINT_PGP_NAME(X) PRINTX( "NAME:", name)
22 const char str_unknown[] = "(unknown)";
24 static const char *my_ctime(const time_t * tv)
26 static char buf[256];
27 struct tm *tp;
29 if ( ( (tp = localtime(tv)) == NULL ) ||
30 (!strftime(buf, sizeof buf, "%a %b %e %H:%M:%S %Z %Y\n", tp)) )
31 strcpy(buf, str_unknown);/* make sure buf text isn't garbage */
33 return buf;
37 void print_x509_info(gnutls_session session, const char* hostname)
39 gnutls_x509_crt crt;
40 const gnutls_datum *cert_list;
41 unsigned int cert_list_size = 0;
42 int ret;
43 char digest[20];
44 char serial[40];
45 char dn[256];
46 size_t dn_size;
47 size_t digest_size = sizeof(digest);
48 unsigned int i, j;
49 size_t serial_size = sizeof(serial);
50 char printable[256];
51 char *print;
52 unsigned int bits, algo;
53 time_t expiret, activet;
55 cert_list = gnutls_certificate_get_peers(session, &cert_list_size);
58 if (cert_list_size == 0) {
59 fprintf(stderr, "No certificates found!\n");
60 return;
63 printf(" - Got a certificate list of %d certificates.\n\n",
64 cert_list_size);
66 for (j = 0; j < cert_list_size; j++) {
68 gnutls_x509_crt_init(&crt);
69 ret =
70 gnutls_x509_crt_import(crt, &cert_list[j],
71 GNUTLS_X509_FMT_DER);
72 if (ret < 0) {
73 const char* str = gnutls_strerror(ret);
74 if (str == NULL) str = str_unknown;
75 fprintf(stderr, "Decoding error: %s\n", str);
76 return;
79 printf(" - Certificate[%d] info:\n", j);
81 if (print_cert) {
82 size_t size;
84 size = sizeof(buffer);
86 ret = gnutls_x509_crt_export( crt, GNUTLS_X509_FMT_PEM, buffer, &size);
87 if (ret < 0) {
88 fprintf(stderr, "Encoding error: %s\n", gnutls_strerror(ret));
89 return;
91 fputs( "\n", stdout);
92 fputs( buffer, stdout);
93 fputs( "\n", stdout);
96 if (j==0 && hostname != NULL) { /* Check the hostname of the first certificate
97 * if it matches the name of the host we
98 * connected to.
100 if (gnutls_x509_crt_check_hostname( crt, hostname)==0) {
101 printf(" # The hostname in the certificate does NOT match '%s'.\n", hostname);
102 } else {
103 printf(" # The hostname in the certificate matches '%s'.\n", hostname);
108 if (xml) {
109 #ifdef ENABLE_PKI
110 gnutls_datum xml_data;
112 ret = gnutls_x509_crt_to_xml( crt, &xml_data, 0);
113 if (ret < 0) {
114 const char* str = gnutls_strerror(ret);
115 if (str == NULL) str = str_unknown;
116 fprintf(stderr, "XML encoding error: %s\n",
117 str);
118 return;
121 printf("%s", xml_data.data);
122 gnutls_free( xml_data.data);
123 #endif
124 } else {
126 expiret = gnutls_x509_crt_get_expiration_time(crt);
127 activet = gnutls_x509_crt_get_activation_time(crt);
129 printf(" # valid since: %s", my_ctime(&activet));
130 printf(" # expires at: %s", my_ctime(&expiret));
133 /* Print the serial number of the certificate.
135 if (gnutls_x509_crt_get_serial(crt, serial, &serial_size)
136 >= 0) {
137 print = printable;
138 for (i = 0; i < serial_size; i++) {
139 sprintf(print, "%.2x ",
140 (unsigned char) serial[i]);
141 print += 3;
143 printf(" # serial number: %s\n", printable);
146 /* Print the fingerprint of the certificate
148 digest_size = sizeof(digest);
149 if ((ret=gnutls_x509_crt_get_fingerprint(crt, GNUTLS_DIG_MD5, digest, &digest_size))
150 < 0) {
151 const char* str = gnutls_strerror(ret);
152 if (str == NULL) str = str_unknown;
153 fprintf(stderr, "Error in fingerprint calculation: %s\n", str);
154 } else {
155 print = printable;
156 for (i = 0; i < digest_size; i++) {
157 sprintf(print, "%.2x ",
158 (unsigned char) digest[i]);
159 print += 3;
161 printf(" # fingerprint: %s\n", printable);
164 /* Print the version of the X.509
165 * certificate.
167 printf(" # version: #%d\n",
168 gnutls_x509_crt_get_version(crt));
170 algo = gnutls_x509_crt_get_pk_algorithm(crt, &bits);
171 printf(" # public key algorithm: ");
172 if (algo == GNUTLS_PK_RSA) {
173 printf("RSA\n");
174 printf(" # Modulus: %d bits\n", bits);
175 } else if (algo == GNUTLS_PK_DSA) {
176 printf("DSA\n");
177 printf(" # Exponent: %d bits\n", bits);
178 } else {
179 printf("UNKNOWN\n");
182 dn_size = sizeof(dn);
183 ret = gnutls_x509_crt_get_dn(crt, dn, &dn_size);
184 if (ret >= 0)
185 printf(" # Subject's DN: %s\n", dn);
187 dn_size = sizeof(dn);
188 ret = gnutls_x509_crt_get_issuer_dn(crt, dn, &dn_size);
189 if (ret >= 0)
190 printf(" # Issuer's DN: %s\n", dn);
193 gnutls_x509_crt_deinit(crt);
195 printf("\n");
201 #ifdef HAVE_LIBOPENCDK
203 void print_openpgp_info(gnutls_session session, const char* hostname)
206 char digest[20];
207 size_t digest_size = sizeof(digest);
208 unsigned int i;
209 int ret;
210 char printable[120];
211 char *print;
212 char name[256];
213 size_t name_len = sizeof(name);
214 gnutls_openpgp_key crt;
215 const gnutls_datum *cert_list;
216 unsigned int cert_list_size = 0;
217 time_t expiret;
218 time_t activet;
220 cert_list = gnutls_certificate_get_peers(session, &cert_list_size);
222 if (cert_list_size > 0) {
223 unsigned int algo, bits;
225 gnutls_openpgp_key_init(&crt);
226 ret =
227 gnutls_openpgp_key_import(crt, &cert_list[0], GNUTLS_OPENPGP_FMT_RAW);
228 if (ret < 0) {
229 const char* str = gnutls_strerror(ret);
230 if (str == NULL) str = str_unknown;
231 fprintf(stderr, "Decoding error: %s\n", str);
232 return;
235 if (print_cert) {
236 size_t size;
238 size = sizeof(buffer);
240 ret = gnutls_openpgp_key_export( crt, GNUTLS_OPENPGP_FMT_BASE64, buffer, &size);
241 if (ret < 0) {
242 fprintf(stderr, "Encoding error: %s\n", gnutls_strerror(ret));
243 return;
245 fputs( "\n", stdout);
246 fputs( buffer, stdout);
247 fputs( "\n", stdout);
250 if (hostname != NULL) { /* Check the hostname of the first certificate
251 * if it matches the name of the host we
252 * connected to.
254 if (gnutls_openpgp_key_check_hostname( crt, hostname)==0) {
255 printf(" # The hostname in the key does NOT match '%s'.\n", hostname);
256 } else {
257 printf(" # The hostname in the key matches '%s'.\n", hostname);
261 if (xml) {
262 gnutls_datum xml_data;
264 ret = gnutls_openpgp_key_to_xml( crt, &xml_data, 0);
265 if (ret < 0) {
266 const char* str = gnutls_strerror(ret);
267 if (str == NULL) str = str_unknown;
268 fprintf(stderr, "XML encoding error: %s\n",
269 str);
270 return;
273 printf("%s", xml_data.data);
274 gnutls_free( xml_data.data);
276 return;
279 activet = gnutls_openpgp_key_get_creation_time( crt);
280 expiret = gnutls_openpgp_key_get_expiration_time( crt);
282 printf(" # Key was created at: %s", my_ctime(&activet));
283 printf(" # Key expires: ");
284 if (expiret != 0)
285 printf("%s", my_ctime(&expiret));
286 else
287 printf("Never\n");
289 if (gnutls_openpgp_key_get_fingerprint(crt, digest, &digest_size) >= 0)
291 print = printable;
292 for (i = 0; i < digest_size; i++) {
293 sprintf(print, "%.2x ",
294 (unsigned char) digest[i]);
295 print += 3;
298 printf(" # PGP Key version: %d\n",
299 gnutls_openpgp_key_get_version(crt));
301 algo =
302 gnutls_openpgp_key_get_pk_algorithm(crt, &bits);
304 printf(" # PGP Key public key algorithm: ");
306 if (algo == GNUTLS_PK_RSA) {
307 printf("RSA\n");
308 printf(" # Modulus: %d bits\n", bits);
309 } else if (algo == GNUTLS_PK_DSA) {
310 printf("DSA\n");
311 printf(" # Exponent: %d bits\n", bits);
312 } else {
313 printf("UNKNOWN\n");
316 printf(" # PGP Key fingerprint: %s\n", printable);
318 name_len = sizeof(name);
319 if (gnutls_openpgp_key_get_name(crt, 0, name, &name_len) < 0) {
320 fprintf(stderr,
321 "Could not extract name\n");
322 } else {
323 PRINT_PGP_NAME(name);
328 gnutls_openpgp_key_deinit( crt);
333 #endif
335 void print_cert_vrfy(gnutls_session session)
338 unsigned int status;
339 int ret;
341 ret = gnutls_certificate_verify_peers2(session, &status);
343 printf("\n");
345 if(ret < 0)
347 if (ret == GNUTLS_E_NO_CERTIFICATE_FOUND)
348 printf("- Peer did not send any certificate.\n");
349 else
350 printf("- Could not verify certificate (err: %s (%d))\n",
351 gnutls_strerror(ret), ret);
352 return;
355 if (gnutls_certificate_type_get(session)==GNUTLS_CRT_X509) {
356 if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
357 printf("- Peer's certificate issuer is unknown\n");
358 if (status & GNUTLS_CERT_INVALID)
359 printf("- Peer's certificate is NOT trusted\n");
360 else
361 printf("- Peer's certificate is trusted\n");
362 } else {
363 if (status & GNUTLS_CERT_INVALID)
364 printf("- Peer's key is invalid\n");
365 else
366 printf("- Peer's key is valid\n");
367 if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
368 printf("- Could not find a signer of the peer's key\n");
372 int print_info(gnutls_session session, const char* hostname)
374 const char *tmp;
375 gnutls_credentials_type cred;
376 gnutls_kx_algorithm kx;
379 /* print the key exchange's algorithm name
381 kx = gnutls_kx_get(session);
383 cred = gnutls_auth_get_type(session);
384 switch (cred) {
385 #ifdef ENABLE_ANON
386 case GNUTLS_CRD_ANON:
387 printf("- Anonymous DH using prime of %d bits, secret key "
388 "of %d bits, and peer's public key is %d bits.\n",
389 gnutls_dh_get_prime_bits(session),
390 gnutls_dh_get_secret_bits(session),
391 gnutls_dh_get_peers_public_bits(session));
392 break;
393 #endif
394 #ifdef ENABLE_SRP
395 case GNUTLS_CRD_SRP:
396 /* This should be only called in server
397 * side.
399 if (gnutls_srp_server_get_username(session) != NULL)
400 printf("- SRP authentication. Connected as '%s'\n",
401 gnutls_srp_server_get_username(session));
402 break;
403 #endif
404 case GNUTLS_CRD_CERTIFICATE:
406 char dns[256];
407 size_t dns_size = sizeof(dns);
408 unsigned int type;
410 /* This fails in client side */
411 if (gnutls_server_name_get
412 (session, dns, &dns_size, &type, 0) == 0) {
413 printf("- Given server name[%d]: %s\n",
414 type, dns);
418 print_cert_info(session, hostname);
420 print_cert_vrfy(session);
422 /* Check if we have been using ephemeral Diffie Hellman.
424 if (kx == GNUTLS_KX_DHE_RSA || kx == GNUTLS_KX_DHE_DSS) {
425 printf
426 ("- Ephemeral DH using prime of %d bits, secret key "
427 "of %d bits, and peer's public key is %d bits.\n",
428 gnutls_dh_get_prime_bits(session),
429 gnutls_dh_get_secret_bits(session),
430 gnutls_dh_get_peers_public_bits(session));
432 default:
433 break;
436 tmp =
437 gnutls_protocol_get_name(gnutls_protocol_get_version(session));
438 if (tmp != NULL) printf("- Version: %s\n", tmp);
440 tmp = gnutls_kx_get_name(kx);
441 if (tmp != NULL) printf("- Key Exchange: %s\n", tmp);
443 tmp = gnutls_cipher_get_name(gnutls_cipher_get(session));
444 if (tmp != NULL) printf("- Cipher: %s\n", tmp);
446 tmp = gnutls_mac_get_name(gnutls_mac_get(session));
447 if (tmp != NULL) printf("- MAC: %s\n", tmp);
449 tmp = gnutls_compression_get_name(gnutls_compression_get(session));
450 if (tmp != NULL) printf("- Compression: %s\n", tmp);
452 fflush (stdout);
454 return 0;
457 void print_cert_info(gnutls_session session, const char* hostname)
460 printf("- Certificate type: ");
461 switch (gnutls_certificate_type_get(session)) {
462 case GNUTLS_CRT_X509:
463 printf("X.509\n");
464 print_x509_info(session, hostname);
465 break;
466 #ifdef HAVE_LIBOPENCDK
467 case GNUTLS_CRT_OPENPGP:
468 printf("OpenPGP\n");
469 print_openpgp_info(session, hostname);
470 break;
471 #endif
472 default:
473 break;
478 void print_list(void)
480 /* FIXME: This is hard coded. Make it print all the supported
481 * algorithms.
483 printf("\n");
484 printf("Certificate types:");
485 printf(" X.509");
486 printf(", OPENPGP\n");
488 printf("Protocols:");
489 printf(" TLS1.0");
490 printf(", SSL3.0\n");
492 printf("Ciphers:");
493 printf(" AES-128-CBC");
494 printf(", 3DES-CBC");
495 printf(", ARCFOUR");
496 printf(", ARCFOUR-40\n");
498 printf("MACs:");
499 printf(" MD5");
500 printf(", RMD160");
501 printf(", SHA1\n");
503 printf("Key exchange algorithms:");
504 printf(" RSA");
505 printf(", RSA-EXPORT");
506 printf(", DHE-DSS");
507 printf(", DHE-RSA");
508 printf(", SRP");
509 printf(", SRP-RSA");
510 printf(", SRP-DSS");
511 printf(", ANON-DH\n");
513 printf("Compression methods:");
514 printf(" ZLIB");
515 printf(", NULL\n");
518 void print_license(void)
520 fprintf(stdout,
521 "\nCopyright (C) 2001-2003 Nikos Mavroyanopoulos\n"
522 "This program is free software; you can redistribute it and/or modify \n"
523 "it under the terms of the GNU General Public License as published by \n"
524 "the Free Software Foundation; either version 2 of the License, or \n"
525 "(at your option) any later version. \n" "\n"
526 "This program is distributed in the hope that it will be useful, \n"
527 "but WITHOUT ANY WARRANTY; without even the implied warranty of \n"
528 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the \n"
529 "GNU General Public License for more details. \n" "\n"
530 "You should have received a copy of the GNU General Public License \n"
531 "along with this program; if not, write to the Free Software \n"
532 "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n\n");
535 void parse_protocols(char **protocols, int protocols_size,
536 int *protocol_priority)
538 int i, j;
540 if (protocols != NULL && protocols_size > 0) {
541 for (j = i = 0; i < protocols_size; i++) {
542 if (strncasecmp(protocols[i], "SSL", 3) == 0)
543 protocol_priority[j++] = GNUTLS_SSL3;
544 if (strncasecmp(protocols[i], "TLS", 3) == 0)
545 protocol_priority[j++] = GNUTLS_TLS1;
547 protocol_priority[j] = 0;
551 void parse_ciphers(char **ciphers, int nciphers, int *cipher_priority)
553 int j, i;
555 if (ciphers != NULL && nciphers > 0) {
556 for (j = i = 0; i < nciphers; i++) {
557 if (strncasecmp(ciphers[i], "AES", 3) == 0)
558 cipher_priority[j++] =
559 GNUTLS_CIPHER_AES_128_CBC;
560 if (strncasecmp(ciphers[i], "3DE", 3) == 0)
561 cipher_priority[j++] =
562 GNUTLS_CIPHER_3DES_CBC;
563 if (strcasecmp(ciphers[i], "ARCFOUR-40") == 0)
564 cipher_priority[j++] =
565 GNUTLS_CIPHER_ARCFOUR_40;
566 if (strcasecmp(ciphers[i], "ARCFOUR") == 0)
567 cipher_priority[j++] =
568 GNUTLS_CIPHER_ARCFOUR_128;
569 if (strncasecmp(ciphers[i], "NUL", 3) == 0)
570 cipher_priority[j++] = GNUTLS_CIPHER_NULL;
572 cipher_priority[j] = 0;
576 void parse_macs(char **macs, int nmacs, int *mac_priority)
578 int i, j;
579 if (macs != NULL && nmacs > 0) {
580 for (j = i = 0; i < nmacs; i++) {
581 if (strncasecmp(macs[i], "MD5", 3) == 0)
582 mac_priority[j++] = GNUTLS_MAC_MD5;
583 if (strncasecmp(macs[i], "RMD", 3) == 0)
584 mac_priority[j++] = GNUTLS_MAC_RMD160;
585 if (strncasecmp(macs[i], "SHA", 3) == 0)
586 mac_priority[j++] = GNUTLS_MAC_SHA;
588 mac_priority[j] = 0;
592 void parse_ctypes(char **ctype, int nctype, int *cert_type_priority)
594 int i, j;
595 if (ctype != NULL && nctype > 0) {
596 for (j = i = 0; i < nctype; i++) {
597 if (strncasecmp(ctype[i], "OPE", 3) == 0)
598 cert_type_priority[j++] =
599 GNUTLS_CRT_OPENPGP;
600 if (strncasecmp(ctype[i], "X", 1) == 0)
601 cert_type_priority[j++] = GNUTLS_CRT_X509;
603 cert_type_priority[j] = 0;
607 void parse_kx(char **kx, int nkx, int *kx_priority)
609 int i, j;
610 if (kx != NULL && nkx > 0) {
611 for (j = i = 0; i < nkx; i++) {
612 if (strcasecmp(kx[i], "SRP") == 0)
613 kx_priority[j++] = GNUTLS_KX_SRP;
614 if (strcasecmp(kx[i], "SRP-RSA") == 0)
615 kx_priority[j++] = GNUTLS_KX_SRP_RSA;
616 if (strcasecmp(kx[i], "SRP-DSS") == 0)
617 kx_priority[j++] = GNUTLS_KX_SRP_DSS;
618 if (strcasecmp(kx[i], "RSA") == 0)
619 kx_priority[j++] = GNUTLS_KX_RSA;
620 if (strcasecmp(kx[i], "RSA-EXPORT") == 0)
621 kx_priority[j++] = GNUTLS_KX_RSA_EXPORT;
622 if (strncasecmp(kx[i], "DHE-RSA", 7) == 0)
623 kx_priority[j++] = GNUTLS_KX_DHE_RSA;
624 if (strncasecmp(kx[i], "DHE-DSS", 7) == 0)
625 kx_priority[j++] = GNUTLS_KX_DHE_DSS;
626 if (strncasecmp(kx[i], "ANON", 4) == 0)
627 kx_priority[j++] = GNUTLS_KX_ANON_DH;
629 kx_priority[j] = 0;
633 void parse_comp(char **comp, int ncomp, int *comp_priority)
635 int i, j;
636 if (comp != NULL && ncomp > 0) {
637 for (j = i = 0; i < ncomp; i++) {
638 if (strncasecmp(comp[i], "NUL", 3) == 0)
639 comp_priority[j++] = GNUTLS_COMP_NULL;
640 if (strncasecmp(comp[i], "ZLI", 3) == 0)
641 comp_priority[j++] = GNUTLS_COMP_ZLIB;
643 comp_priority[j] = 0;
648 #ifndef HAVE_INET_NTOP
650 #ifdef _WIN32
651 # include <winsock.h>
652 #else
653 # include <sys/socket.h>
654 # include <netinet/in.h>
655 # include <arpa/inet.h>
656 #endif
658 const char *inet_ntop(int af __attribute__((unused)), const void *src,
659 char *dst, size_t cnt)
661 char* ret;
663 ret = inet_ntoa( *((struct in_addr*)src));
665 if (strlen(ret) > cnt) {
666 return NULL;
668 strcpy( dst, ret);
670 return dst;
672 #endif
674 void sockets_init( void)
676 #ifdef _WIN32
677 WORD wVersionRequested;
678 WSADATA wsaData;
680 wVersionRequested = MAKEWORD(1, 1);
681 if (WSAStartup(wVersionRequested, &wsaData) != 0) {
682 perror("WSA_STARTUP_ERROR");
684 #endif