Update gnutls code (require at least 2.2.0).
[dockapps.git] / wmbiff / wmbiff / gnutls-common.c
blob5f2bf7688a6803d7a47fe60221147c342f6ca58c
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 unsigned int status;
340 int ret;
342 ret = gnutls_certificate_verify_peers2(session, &status);
344 printf("\n");
346 if(ret < 0)
348 if (ret == GNUTLS_E_NO_CERTIFICATE_FOUND)
349 printf("- Peer did not send any certificate.\n");
350 else
351 printf("- Could not verify certificate (err: %s (%d))\n",
352 gnutls_strerror(ret), ret);
353 return;
356 if (gnutls_certificate_type_get(session)==GNUTLS_CRT_X509) {
357 if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
358 printf("- Peer's certificate issuer is unknown\n");
359 if (status & GNUTLS_CERT_INVALID)
360 printf("- Peer's certificate is NOT trusted\n");
361 else
362 printf("- Peer's certificate is trusted\n");
363 } else {
364 if (status & GNUTLS_CERT_INVALID)
365 printf("- Peer's key is invalid\n");
366 else
367 printf("- Peer's key is valid\n");
368 if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
369 printf("- Could not find a signer of the peer's key\n");
373 int print_info(gnutls_session session, const char* hostname)
375 const char *tmp;
376 gnutls_credentials_type cred;
377 gnutls_kx_algorithm kx;
380 /* print the key exchange's algorithm name
382 kx = gnutls_kx_get(session);
384 cred = gnutls_auth_get_type(session);
385 switch (cred) {
386 #ifdef ENABLE_ANON
387 case GNUTLS_CRD_ANON:
388 printf("- Anonymous DH using prime of %d bits, secret key "
389 "of %d bits, and peer's public key is %d bits.\n",
390 gnutls_dh_get_prime_bits(session),
391 gnutls_dh_get_secret_bits(session),
392 gnutls_dh_get_peers_public_bits(session));
393 break;
394 #endif
395 #ifdef ENABLE_SRP
396 case GNUTLS_CRD_SRP:
397 /* This should be only called in server
398 * side.
400 if (gnutls_srp_server_get_username(session) != NULL)
401 printf("- SRP authentication. Connected as '%s'\n",
402 gnutls_srp_server_get_username(session));
403 break;
404 #endif
405 case GNUTLS_CRD_CERTIFICATE:
407 char dns[256];
408 size_t dns_size = sizeof(dns);
409 unsigned int type;
411 /* This fails in client side */
412 if (gnutls_server_name_get
413 (session, dns, &dns_size, &type, 0) == 0) {
414 printf("- Given server name[%d]: %s\n",
415 type, dns);
419 print_cert_info(session, hostname);
421 print_cert_vrfy(session);
423 /* Check if we have been using ephemeral Diffie Hellman.
425 if (kx == GNUTLS_KX_DHE_RSA || kx == GNUTLS_KX_DHE_DSS) {
426 printf
427 ("- Ephemeral DH using prime of %d bits, secret key "
428 "of %d bits, and peer's public key is %d bits.\n",
429 gnutls_dh_get_prime_bits(session),
430 gnutls_dh_get_secret_bits(session),
431 gnutls_dh_get_peers_public_bits(session));
433 default:
434 break;
437 tmp =
438 gnutls_protocol_get_name(gnutls_protocol_get_version(session));
439 if (tmp != NULL) printf("- Version: %s\n", tmp);
441 tmp = gnutls_kx_get_name(kx);
442 if (tmp != NULL) printf("- Key Exchange: %s\n", tmp);
444 tmp = gnutls_cipher_get_name(gnutls_cipher_get(session));
445 if (tmp != NULL) printf("- Cipher: %s\n", tmp);
447 tmp = gnutls_mac_get_name(gnutls_mac_get(session));
448 if (tmp != NULL) printf("- MAC: %s\n", tmp);
450 tmp = gnutls_compression_get_name(gnutls_compression_get(session));
451 if (tmp != NULL) printf("- Compression: %s\n", tmp);
453 fflush (stdout);
455 return 0;
458 void print_cert_info(gnutls_session session, const char* hostname)
461 printf("- Certificate type: ");
462 switch (gnutls_certificate_type_get(session)) {
463 case GNUTLS_CRT_X509:
464 printf("X.509\n");
465 print_x509_info(session, hostname);
466 break;
467 #ifdef HAVE_LIBOPENCDK
468 case GNUTLS_CRT_OPENPGP:
469 printf("OpenPGP\n");
470 print_openpgp_info(session, hostname);
471 break;
472 #endif
473 default:
474 break;
479 void print_list(void)
481 /* FIXME: This is hard coded. Make it print all the supported
482 * algorithms.
484 printf("\n");
485 printf("Certificate types:");
486 printf(" X.509");
487 printf(", OPENPGP\n");
489 printf("Protocols:");
490 printf(" TLS1.0");
491 printf(", SSL3.0\n");
493 printf("Ciphers:");
494 printf(" AES-128-CBC");
495 printf(", 3DES-CBC");
496 printf(", ARCFOUR");
497 printf(", ARCFOUR-40\n");
499 printf("MACs:");
500 printf(" MD5");
501 printf(", RMD160");
502 printf(", SHA1\n");
504 printf("Key exchange algorithms:");
505 printf(" RSA");
506 printf(", RSA-EXPORT");
507 printf(", DHE-DSS");
508 printf(", DHE-RSA");
509 printf(", SRP");
510 printf(", SRP-RSA");
511 printf(", SRP-DSS");
512 printf(", ANON-DH\n");
514 printf("Compression methods:");
515 printf(" ZLIB");
516 printf(", LZO");
517 printf(", NULL\n");
520 void print_license(void)
522 fprintf(stdout,
523 "\nCopyright (C) 2001-2003 Nikos Mavroyanopoulos\n"
524 "This program is free software; you can redistribute it and/or modify \n"
525 "it under the terms of the GNU General Public License as published by \n"
526 "the Free Software Foundation; either version 2 of the License, or \n"
527 "(at your option) any later version. \n" "\n"
528 "This program is distributed in the hope that it will be useful, \n"
529 "but WITHOUT ANY WARRANTY; without even the implied warranty of \n"
530 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the \n"
531 "GNU General Public License for more details. \n" "\n"
532 "You should have received a copy of the GNU General Public License \n"
533 "along with this program; if not, write to the Free Software \n"
534 "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n\n");
537 void parse_protocols(char **protocols, int protocols_size,
538 int *protocol_priority)
540 int i, j;
542 if (protocols != NULL && protocols_size > 0) {
543 for (j = i = 0; i < protocols_size; i++) {
544 if (strncasecmp(protocols[i], "SSL", 3) == 0)
545 protocol_priority[j++] = GNUTLS_SSL3;
546 if (strncasecmp(protocols[i], "TLS", 3) == 0)
547 protocol_priority[j++] = GNUTLS_TLS1;
549 protocol_priority[j] = 0;
553 void parse_ciphers(char **ciphers, int nciphers, int *cipher_priority)
555 int j, i;
557 if (ciphers != NULL && nciphers > 0) {
558 for (j = i = 0; i < nciphers; i++) {
559 if (strncasecmp(ciphers[i], "AES", 3) == 0)
560 cipher_priority[j++] =
561 GNUTLS_CIPHER_AES_128_CBC;
562 if (strncasecmp(ciphers[i], "3DE", 3) == 0)
563 cipher_priority[j++] =
564 GNUTLS_CIPHER_3DES_CBC;
565 if (strcasecmp(ciphers[i], "ARCFOUR-40") == 0)
566 cipher_priority[j++] =
567 GNUTLS_CIPHER_ARCFOUR_40;
568 if (strcasecmp(ciphers[i], "ARCFOUR") == 0)
569 cipher_priority[j++] =
570 GNUTLS_CIPHER_ARCFOUR_128;
571 if (strncasecmp(ciphers[i], "NUL", 3) == 0)
572 cipher_priority[j++] = GNUTLS_CIPHER_NULL;
574 cipher_priority[j] = 0;
578 void parse_macs(char **macs, int nmacs, int *mac_priority)
580 int i, j;
581 if (macs != NULL && nmacs > 0) {
582 for (j = i = 0; i < nmacs; i++) {
583 if (strncasecmp(macs[i], "MD5", 3) == 0)
584 mac_priority[j++] = GNUTLS_MAC_MD5;
585 if (strncasecmp(macs[i], "RMD", 3) == 0)
586 mac_priority[j++] = GNUTLS_MAC_RMD160;
587 if (strncasecmp(macs[i], "SHA", 3) == 0)
588 mac_priority[j++] = GNUTLS_MAC_SHA;
590 mac_priority[j] = 0;
594 void parse_ctypes(char **ctype, int nctype, int *cert_type_priority)
596 int i, j;
597 if (ctype != NULL && nctype > 0) {
598 for (j = i = 0; i < nctype; i++) {
599 if (strncasecmp(ctype[i], "OPE", 3) == 0)
600 cert_type_priority[j++] =
601 GNUTLS_CRT_OPENPGP;
602 if (strncasecmp(ctype[i], "X", 1) == 0)
603 cert_type_priority[j++] = GNUTLS_CRT_X509;
605 cert_type_priority[j] = 0;
609 void parse_kx(char **kx, int nkx, int *kx_priority)
611 int i, j;
612 if (kx != NULL && nkx > 0) {
613 for (j = i = 0; i < nkx; i++) {
614 if (strcasecmp(kx[i], "SRP") == 0)
615 kx_priority[j++] = GNUTLS_KX_SRP;
616 if (strcasecmp(kx[i], "SRP-RSA") == 0)
617 kx_priority[j++] = GNUTLS_KX_SRP_RSA;
618 if (strcasecmp(kx[i], "SRP-DSS") == 0)
619 kx_priority[j++] = GNUTLS_KX_SRP_DSS;
620 if (strcasecmp(kx[i], "RSA") == 0)
621 kx_priority[j++] = GNUTLS_KX_RSA;
622 if (strcasecmp(kx[i], "RSA-EXPORT") == 0)
623 kx_priority[j++] = GNUTLS_KX_RSA_EXPORT;
624 if (strncasecmp(kx[i], "DHE-RSA", 7) == 0)
625 kx_priority[j++] = GNUTLS_KX_DHE_RSA;
626 if (strncasecmp(kx[i], "DHE-DSS", 7) == 0)
627 kx_priority[j++] = GNUTLS_KX_DHE_DSS;
628 if (strncasecmp(kx[i], "ANON", 4) == 0)
629 kx_priority[j++] = GNUTLS_KX_ANON_DH;
631 kx_priority[j] = 0;
635 void parse_comp(char **comp, int ncomp, int *comp_priority)
637 int i, j;
638 if (comp != NULL && ncomp > 0) {
639 for (j = i = 0; i < ncomp; i++) {
640 if (strncasecmp(comp[i], "NUL", 3) == 0)
641 comp_priority[j++] = GNUTLS_COMP_NULL;
642 if (strncasecmp(comp[i], "ZLI", 3) == 0)
643 comp_priority[j++] = GNUTLS_COMP_ZLIB;
644 if (strncasecmp(comp[i], "LZO", 3) == 0)
645 comp_priority[j++] = GNUTLS_COMP_LZO;
647 comp_priority[j] = 0;
652 #ifndef HAVE_INET_NTOP
654 #ifdef _WIN32
655 # include <winsock.h>
656 #else
657 # include <sys/socket.h>
658 # include <netinet/in.h>
659 # include <arpa/inet.h>
660 #endif
662 const char *inet_ntop(int af __attribute__((unused)), const void *src,
663 char *dst, size_t cnt)
665 char* ret;
667 ret = inet_ntoa( *((struct in_addr*)src));
669 if (strlen(ret) > cnt) {
670 return NULL;
672 strcpy( dst, ret);
674 return dst;
676 #endif
678 void sockets_init( void)
680 #ifdef _WIN32
681 WORD wVersionRequested;
682 WSADATA wsaData;
684 wVersionRequested = MAKEWORD(1, 1);
685 if (WSAStartup(wVersionRequested, &wsaData) != 0) {
686 perror("WSA_STARTUP_ERROR");
688 #endif