wmbiff: More gnutls casts.
[dockapps.git] / wmbiff / wmbiff / gnutls-common.c
blobdb6bd17d63327aeb6b52ae7fb0f5d46c5fa82071
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/extra.h>
8 #include <gnutls/x509.h>
9 #include <gnutls/openpgp.h>
10 #include <time.h>
11 #include <gnutls-common.h>
13 #define TEST_STRING
15 int xml = 0;
16 int print_cert;
18 static char buffer[5*1024];
20 #define PRINTX(x,y) if (y[0]!=0) printf(" # %s %s\n", x, y)
21 #define PRINT_PGP_NAME(X) PRINTX( "NAME:", name)
23 const char str_unknown[] = "(unknown)";
25 static const char *my_ctime(const time_t * tv)
27 static char buf[256];
28 struct tm *tp;
30 if ( ( (tp = localtime(tv)) == NULL ) ||
31 (!strftime(buf, sizeof buf, "%a %b %e %H:%M:%S %Z %Y\n", tp)) )
32 strcpy(buf, str_unknown);/* make sure buf text isn't garbage */
34 return buf;
38 void print_x509_info(gnutls_session session, const char* hostname)
40 gnutls_x509_crt crt;
41 const gnutls_datum *cert_list;
42 unsigned int cert_list_size = 0;
43 int ret;
44 char digest[20];
45 char serial[40];
46 char dn[256];
47 size_t dn_size;
48 size_t digest_size = sizeof(digest);
49 unsigned int i, j;
50 size_t serial_size = sizeof(serial);
51 char printable[256];
52 char *print;
53 unsigned int bits, algo;
54 time_t expiret, activet;
56 cert_list = gnutls_certificate_get_peers(session, &cert_list_size);
59 if (cert_list_size == 0) {
60 fprintf(stderr, "No certificates found!\n");
61 return;
64 printf(" - Got a certificate list of %d certificates.\n\n",
65 cert_list_size);
67 for (j = 0; j < cert_list_size; j++) {
69 gnutls_x509_crt_init(&crt);
70 ret =
71 gnutls_x509_crt_import(crt, &cert_list[j],
72 GNUTLS_X509_FMT_DER);
73 if (ret < 0) {
74 const char* str = gnutls_strerror(ret);
75 if (str == NULL) str = str_unknown;
76 fprintf(stderr, "Decoding error: %s\n", str);
77 return;
80 printf(" - Certificate[%d] info:\n", j);
82 if (print_cert) {
83 size_t size;
85 size = sizeof(buffer);
87 ret = gnutls_x509_crt_export( crt, GNUTLS_X509_FMT_PEM, buffer, &size);
88 if (ret < 0) {
89 fprintf(stderr, "Encoding error: %s\n", gnutls_strerror(ret));
90 return;
92 fputs( "\n", stdout);
93 fputs( buffer, stdout);
94 fputs( "\n", stdout);
97 if (j==0 && hostname != NULL) { /* Check the hostname of the first certificate
98 * if it matches the name of the host we
99 * connected to.
101 if (gnutls_x509_crt_check_hostname( crt, hostname)==0) {
102 printf(" # The hostname in the certificate does NOT match '%s'.\n", hostname);
103 } else {
104 printf(" # The hostname in the certificate matches '%s'.\n", hostname);
109 if (xml) {
110 #ifdef ENABLE_PKI
111 gnutls_datum xml_data;
113 ret = gnutls_x509_crt_to_xml( crt, &xml_data, 0);
114 if (ret < 0) {
115 const char* str = gnutls_strerror(ret);
116 if (str == NULL) str = str_unknown;
117 fprintf(stderr, "XML encoding error: %s\n",
118 str);
119 return;
122 printf("%s", xml_data.data);
123 gnutls_free( xml_data.data);
124 #endif
125 } else {
127 expiret = gnutls_x509_crt_get_expiration_time(crt);
128 activet = gnutls_x509_crt_get_activation_time(crt);
130 printf(" # valid since: %s", my_ctime(&activet));
131 printf(" # expires at: %s", my_ctime(&expiret));
134 /* Print the serial number of the certificate.
136 if (gnutls_x509_crt_get_serial(crt, serial, &serial_size)
137 >= 0) {
138 print = printable;
139 for (i = 0; i < serial_size; i++) {
140 sprintf(print, "%.2x ",
141 (unsigned char) serial[i]);
142 print += 3;
144 printf(" # serial number: %s\n", printable);
147 /* Print the fingerprint of the certificate
149 digest_size = sizeof(digest);
150 if ((ret=gnutls_x509_crt_get_fingerprint(crt, GNUTLS_DIG_MD5, digest, &digest_size))
151 < 0) {
152 const char* str = gnutls_strerror(ret);
153 if (str == NULL) str = str_unknown;
154 fprintf(stderr, "Error in fingerprint calculation: %s\n", str);
155 } else {
156 print = printable;
157 for (i = 0; i < digest_size; i++) {
158 sprintf(print, "%.2x ",
159 (unsigned char) digest[i]);
160 print += 3;
162 printf(" # fingerprint: %s\n", printable);
165 /* Print the version of the X.509
166 * certificate.
168 printf(" # version: #%d\n",
169 gnutls_x509_crt_get_version(crt));
171 algo = gnutls_x509_crt_get_pk_algorithm(crt, &bits);
172 printf(" # public key algorithm: ");
173 if (algo == GNUTLS_PK_RSA) {
174 printf("RSA\n");
175 printf(" # Modulus: %d bits\n", bits);
176 } else if (algo == GNUTLS_PK_DSA) {
177 printf("DSA\n");
178 printf(" # Exponent: %d bits\n", bits);
179 } else {
180 printf("UNKNOWN\n");
183 dn_size = sizeof(dn);
184 ret = gnutls_x509_crt_get_dn(crt, dn, &dn_size);
185 if (ret >= 0)
186 printf(" # Subject's DN: %s\n", dn);
188 dn_size = sizeof(dn);
189 ret = gnutls_x509_crt_get_issuer_dn(crt, dn, &dn_size);
190 if (ret >= 0)
191 printf(" # Issuer's DN: %s\n", dn);
194 gnutls_x509_crt_deinit(crt);
196 printf("\n");
202 #ifdef HAVE_LIBOPENCDK
204 void print_openpgp_info(gnutls_session session, const char* hostname)
207 char digest[20];
208 size_t digest_size = sizeof(digest);
209 unsigned int i;
210 int ret;
211 char printable[120];
212 char *print;
213 char name[256];
214 size_t name_len = sizeof(name);
215 gnutls_openpgp_key crt;
216 const gnutls_datum *cert_list;
217 unsigned int cert_list_size = 0;
218 time_t expiret;
219 time_t activet;
221 cert_list = gnutls_certificate_get_peers(session, &cert_list_size);
223 if (cert_list_size > 0) {
224 unsigned int algo, bits;
226 gnutls_openpgp_key_init(&crt);
227 ret =
228 gnutls_openpgp_key_import(crt, &cert_list[0], GNUTLS_OPENPGP_FMT_RAW);
229 if (ret < 0) {
230 const char* str = gnutls_strerror(ret);
231 if (str == NULL) str = str_unknown;
232 fprintf(stderr, "Decoding error: %s\n", str);
233 return;
236 if (print_cert) {
237 size_t size;
239 size = sizeof(buffer);
241 ret = gnutls_openpgp_key_export( crt, GNUTLS_OPENPGP_FMT_BASE64, buffer, &size);
242 if (ret < 0) {
243 fprintf(stderr, "Encoding error: %s\n", gnutls_strerror(ret));
244 return;
246 fputs( "\n", stdout);
247 fputs( buffer, stdout);
248 fputs( "\n", stdout);
251 if (hostname != NULL) { /* Check the hostname of the first certificate
252 * if it matches the name of the host we
253 * connected to.
255 if (gnutls_openpgp_key_check_hostname( crt, hostname)==0) {
256 printf(" # The hostname in the key does NOT match '%s'.\n", hostname);
257 } else {
258 printf(" # The hostname in the key matches '%s'.\n", hostname);
262 if (xml) {
263 gnutls_datum xml_data;
265 ret = gnutls_openpgp_key_to_xml( crt, &xml_data, 0);
266 if (ret < 0) {
267 const char* str = gnutls_strerror(ret);
268 if (str == NULL) str = str_unknown;
269 fprintf(stderr, "XML encoding error: %s\n",
270 str);
271 return;
274 printf("%s", xml_data.data);
275 gnutls_free( xml_data.data);
277 return;
280 activet = gnutls_openpgp_key_get_creation_time( crt);
281 expiret = gnutls_openpgp_key_get_expiration_time( crt);
283 printf(" # Key was created at: %s", my_ctime(&activet));
284 printf(" # Key expires: ");
285 if (expiret != 0)
286 printf("%s", my_ctime(&expiret));
287 else
288 printf("Never\n");
290 if (gnutls_openpgp_key_get_fingerprint(crt, digest, &digest_size) >= 0)
292 print = printable;
293 for (i = 0; i < digest_size; i++) {
294 sprintf(print, "%.2x ",
295 (unsigned char) digest[i]);
296 print += 3;
299 printf(" # PGP Key version: %d\n",
300 gnutls_openpgp_key_get_version(crt));
302 algo =
303 gnutls_openpgp_key_get_pk_algorithm(crt, &bits);
305 printf(" # PGP Key public key algorithm: ");
307 if (algo == GNUTLS_PK_RSA) {
308 printf("RSA\n");
309 printf(" # Modulus: %d bits\n", bits);
310 } else if (algo == GNUTLS_PK_DSA) {
311 printf("DSA\n");
312 printf(" # Exponent: %d bits\n", bits);
313 } else {
314 printf("UNKNOWN\n");
317 printf(" # PGP Key fingerprint: %s\n", printable);
319 name_len = sizeof(name);
320 if (gnutls_openpgp_key_get_name(crt, 0, name, &name_len) < 0) {
321 fprintf(stderr,
322 "Could not extract name\n");
323 } else {
324 PRINT_PGP_NAME(name);
329 gnutls_openpgp_key_deinit( crt);
334 #endif
336 void print_cert_vrfy(gnutls_session session)
339 int status;
340 status = gnutls_certificate_verify_peers(session);
341 printf("\n");
343 if (status == GNUTLS_E_NO_CERTIFICATE_FOUND) {
344 printf("- Peer did not send any certificate.\n");
345 return;
347 if (status < 0) {
348 printf("- Could not verify certificate (err: %s)\n",
349 gnutls_strerror(status));
350 return;
353 if (gnutls_certificate_type_get(session)==GNUTLS_CRT_X509) {
354 if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
355 printf("- Peer's certificate issuer is unknown\n");
356 if (status & GNUTLS_CERT_INVALID)
357 printf("- Peer's certificate is NOT trusted\n");
358 else
359 printf("- Peer's certificate is trusted\n");
360 } else {
361 if (status & GNUTLS_CERT_INVALID)
362 printf("- Peer's key is invalid\n");
363 else
364 printf("- Peer's key is valid\n");
365 if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
366 printf("- Could not find a signer of the peer's key\n");
370 int print_info(gnutls_session session, const char* hostname)
372 const char *tmp;
373 gnutls_credentials_type cred;
374 gnutls_kx_algorithm kx;
377 /* print the key exchange's algorithm name
379 kx = gnutls_kx_get(session);
381 cred = gnutls_auth_get_type(session);
382 switch (cred) {
383 #ifdef ENABLE_ANON
384 case GNUTLS_CRD_ANON:
385 printf("- Anonymous DH using prime of %d bits, secret key "
386 "of %d bits, and peer's public key is %d bits.\n",
387 gnutls_dh_get_prime_bits(session),
388 gnutls_dh_get_secret_bits(session),
389 gnutls_dh_get_peers_public_bits(session));
390 break;
391 #endif
392 #ifdef ENABLE_SRP
393 case GNUTLS_CRD_SRP:
394 /* This should be only called in server
395 * side.
397 if (gnutls_srp_server_get_username(session) != NULL)
398 printf("- SRP authentication. Connected as '%s'\n",
399 gnutls_srp_server_get_username(session));
400 break;
401 #endif
402 case GNUTLS_CRD_CERTIFICATE:
404 char dns[256];
405 size_t dns_size = sizeof(dns);
406 unsigned int type;
408 /* This fails in client side */
409 if (gnutls_server_name_get
410 (session, dns, &dns_size, &type, 0) == 0) {
411 printf("- Given server name[%d]: %s\n",
412 type, dns);
416 print_cert_info(session, hostname);
418 print_cert_vrfy(session);
420 /* Check if we have been using ephemeral Diffie Hellman.
422 if (kx == GNUTLS_KX_DHE_RSA || kx == GNUTLS_KX_DHE_DSS) {
423 printf
424 ("- Ephemeral DH using prime of %d bits, secret key "
425 "of %d bits, and peer's public key is %d bits.\n",
426 gnutls_dh_get_prime_bits(session),
427 gnutls_dh_get_secret_bits(session),
428 gnutls_dh_get_peers_public_bits(session));
430 default:
431 break;
434 tmp =
435 gnutls_protocol_get_name(gnutls_protocol_get_version(session));
436 if (tmp != NULL) printf("- Version: %s\n", tmp);
438 tmp = gnutls_kx_get_name(kx);
439 if (tmp != NULL) printf("- Key Exchange: %s\n", tmp);
441 tmp = gnutls_cipher_get_name(gnutls_cipher_get(session));
442 if (tmp != NULL) printf("- Cipher: %s\n", tmp);
444 tmp = gnutls_mac_get_name(gnutls_mac_get(session));
445 if (tmp != NULL) printf("- MAC: %s\n", tmp);
447 tmp = gnutls_compression_get_name(gnutls_compression_get(session));
448 if (tmp != NULL) printf("- Compression: %s\n", tmp);
450 fflush (stdout);
452 return 0;
455 void print_cert_info(gnutls_session session, const char* hostname)
458 printf("- Certificate type: ");
459 switch (gnutls_certificate_type_get(session)) {
460 case GNUTLS_CRT_X509:
461 printf("X.509\n");
462 print_x509_info(session, hostname);
463 break;
464 #ifdef HAVE_LIBOPENCDK
465 case GNUTLS_CRT_OPENPGP:
466 printf("OpenPGP\n");
467 print_openpgp_info(session, hostname);
468 break;
469 #endif
470 default:
471 break;
476 void print_list(void)
478 /* FIXME: This is hard coded. Make it print all the supported
479 * algorithms.
481 printf("\n");
482 printf("Certificate types:");
483 printf(" X.509");
484 printf(", OPENPGP\n");
486 printf("Protocols:");
487 printf(" TLS1.0");
488 printf(", SSL3.0\n");
490 printf("Ciphers:");
491 printf(" AES-128-CBC");
492 printf(", 3DES-CBC");
493 printf(", ARCFOUR");
494 printf(", ARCFOUR-40\n");
496 printf("MACs:");
497 printf(" MD5");
498 printf(", RMD160");
499 printf(", SHA1\n");
501 printf("Key exchange algorithms:");
502 printf(" RSA");
503 printf(", RSA-EXPORT");
504 printf(", DHE-DSS");
505 printf(", DHE-RSA");
506 printf(", SRP");
507 printf(", SRP-RSA");
508 printf(", SRP-DSS");
509 printf(", ANON-DH\n");
511 printf("Compression methods:");
512 printf(" ZLIB");
513 printf(", LZO");
514 printf(", NULL\n");
517 void print_license(void)
519 fprintf(stdout,
520 "\nCopyright (C) 2001-2003 Nikos Mavroyanopoulos\n"
521 "This program is free software; you can redistribute it and/or modify \n"
522 "it under the terms of the GNU General Public License as published by \n"
523 "the Free Software Foundation; either version 2 of the License, or \n"
524 "(at your option) any later version. \n" "\n"
525 "This program is distributed in the hope that it will be useful, \n"
526 "but WITHOUT ANY WARRANTY; without even the implied warranty of \n"
527 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the \n"
528 "GNU General Public License for more details. \n" "\n"
529 "You should have received a copy of the GNU General Public License \n"
530 "along with this program; if not, write to the Free Software \n"
531 "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n\n");
534 void parse_protocols(char **protocols, int protocols_size,
535 int *protocol_priority)
537 int i, j;
539 if (protocols != NULL && protocols_size > 0) {
540 for (j = i = 0; i < protocols_size; i++) {
541 if (strncasecmp(protocols[i], "SSL", 3) == 0)
542 protocol_priority[j++] = GNUTLS_SSL3;
543 if (strncasecmp(protocols[i], "TLS", 3) == 0)
544 protocol_priority[j++] = GNUTLS_TLS1;
546 protocol_priority[j] = 0;
550 void parse_ciphers(char **ciphers, int nciphers, int *cipher_priority)
552 int j, i;
554 if (ciphers != NULL && nciphers > 0) {
555 for (j = i = 0; i < nciphers; i++) {
556 if (strncasecmp(ciphers[i], "AES", 3) == 0)
557 cipher_priority[j++] =
558 GNUTLS_CIPHER_AES_128_CBC;
559 if (strncasecmp(ciphers[i], "3DE", 3) == 0)
560 cipher_priority[j++] =
561 GNUTLS_CIPHER_3DES_CBC;
562 if (strcasecmp(ciphers[i], "ARCFOUR-40") == 0)
563 cipher_priority[j++] =
564 GNUTLS_CIPHER_ARCFOUR_40;
565 if (strcasecmp(ciphers[i], "ARCFOUR") == 0)
566 cipher_priority[j++] =
567 GNUTLS_CIPHER_ARCFOUR_128;
568 if (strncasecmp(ciphers[i], "NUL", 3) == 0)
569 cipher_priority[j++] = GNUTLS_CIPHER_NULL;
571 cipher_priority[j] = 0;
575 void parse_macs(char **macs, int nmacs, int *mac_priority)
577 int i, j;
578 if (macs != NULL && nmacs > 0) {
579 for (j = i = 0; i < nmacs; i++) {
580 if (strncasecmp(macs[i], "MD5", 3) == 0)
581 mac_priority[j++] = GNUTLS_MAC_MD5;
582 if (strncasecmp(macs[i], "RMD", 3) == 0)
583 mac_priority[j++] = GNUTLS_MAC_RMD160;
584 if (strncasecmp(macs[i], "SHA", 3) == 0)
585 mac_priority[j++] = GNUTLS_MAC_SHA;
587 mac_priority[j] = 0;
591 void parse_ctypes(char **ctype, int nctype, int *cert_type_priority)
593 int i, j;
594 if (ctype != NULL && nctype > 0) {
595 for (j = i = 0; i < nctype; i++) {
596 if (strncasecmp(ctype[i], "OPE", 3) == 0)
597 cert_type_priority[j++] =
598 GNUTLS_CRT_OPENPGP;
599 if (strncasecmp(ctype[i], "X", 1) == 0)
600 cert_type_priority[j++] = GNUTLS_CRT_X509;
602 cert_type_priority[j] = 0;
606 void parse_kx(char **kx, int nkx, int *kx_priority)
608 int i, j;
609 if (kx != NULL && nkx > 0) {
610 for (j = i = 0; i < nkx; i++) {
611 if (strcasecmp(kx[i], "SRP") == 0)
612 kx_priority[j++] = GNUTLS_KX_SRP;
613 if (strcasecmp(kx[i], "SRP-RSA") == 0)
614 kx_priority[j++] = GNUTLS_KX_SRP_RSA;
615 if (strcasecmp(kx[i], "SRP-DSS") == 0)
616 kx_priority[j++] = GNUTLS_KX_SRP_DSS;
617 if (strcasecmp(kx[i], "RSA") == 0)
618 kx_priority[j++] = GNUTLS_KX_RSA;
619 if (strcasecmp(kx[i], "RSA-EXPORT") == 0)
620 kx_priority[j++] = GNUTLS_KX_RSA_EXPORT;
621 if (strncasecmp(kx[i], "DHE-RSA", 7) == 0)
622 kx_priority[j++] = GNUTLS_KX_DHE_RSA;
623 if (strncasecmp(kx[i], "DHE-DSS", 7) == 0)
624 kx_priority[j++] = GNUTLS_KX_DHE_DSS;
625 if (strncasecmp(kx[i], "ANON", 4) == 0)
626 kx_priority[j++] = GNUTLS_KX_ANON_DH;
628 kx_priority[j] = 0;
632 void parse_comp(char **comp, int ncomp, int *comp_priority)
634 int i, j;
635 if (comp != NULL && ncomp > 0) {
636 for (j = i = 0; i < ncomp; i++) {
637 if (strncasecmp(comp[i], "NUL", 3) == 0)
638 comp_priority[j++] = GNUTLS_COMP_NULL;
639 if (strncasecmp(comp[i], "ZLI", 3) == 0)
640 comp_priority[j++] = GNUTLS_COMP_ZLIB;
641 if (strncasecmp(comp[i], "LZO", 3) == 0)
642 comp_priority[j++] = GNUTLS_COMP_LZO;
644 comp_priority[j] = 0;
649 #ifndef HAVE_INET_NTOP
651 #ifdef _WIN32
652 # include <winsock.h>
653 #else
654 # include <sys/socket.h>
655 # include <netinet/in.h>
656 # include <arpa/inet.h>
657 #endif
659 const char *inet_ntop(int af __attribute__((unused)), const void *src,
660 char *dst, size_t cnt)
662 char* ret;
664 ret = inet_ntoa( *((struct in_addr*)src));
666 if (strlen(ret) > cnt) {
667 return NULL;
669 strcpy( dst, ret);
671 return dst;
673 #endif
675 void sockets_init( void)
677 #ifdef _WIN32
678 WORD wVersionRequested;
679 WSADATA wsaData;
681 wVersionRequested = MAKEWORD(1, 1);
682 if (WSAStartup(wVersionRequested, &wsaData) != 0) {
683 perror("WSA_STARTUP_ERROR");
685 #endif