Better handling of security parameters to key sizes matching (via a single table...
[gnutls.git] / src / certtool.c
blob107e9ad01603dd00dfe805a054fef7f4f803c278
1 /*
2 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
4 * This file is part of GnuTLS.
6 * GnuTLS is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * GnuTLS is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see
18 * <http://www.gnu.org/licenses/>.
21 #include <config.h>
23 #include <gnutls/gnutls.h>
24 #include <gnutls/extra.h>
25 #include <gnutls/x509.h>
26 #include <gnutls/openpgp.h>
27 #include <gnutls/pkcs12.h>
28 #include <gnutls/pkcs11.h>
29 #include <gnutls/abstract.h>
31 #include <gcrypt.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <ctype.h>
37 #include <time.h>
38 #include <unistd.h>
39 #include <errno.h>
40 #include <sys/types.h>
41 #include <sys/stat.h>
42 #include <fcntl.h>
43 #include <error.h>
45 /* Gnulib portability files. */
46 #include <read-file.h>
47 #include <progname.h>
48 #include <version-etc.h>
50 #include <certtool-cfg.h>
51 #include "certtool-gaa.h"
52 #include "certtool-common.h"
54 static void print_crl_info (gnutls_x509_crl_t crl, FILE * out);
55 void pkcs7_info (void);
56 void crq_info (void);
57 void smime_to_pkcs7 (void);
58 void pkcs12_info (void);
59 void generate_pkcs12 (void);
60 void generate_pkcs8 (void);
61 void verify_chain (void);
62 void verify_crl (void);
63 void pubkey_info (gnutls_x509_crt crt);
64 void pgp_privkey_info (void);
65 void pgp_ring_info (void);
66 void certificate_info (int);
67 void pgp_certificate_info (void);
68 void crl_info (void);
69 void privkey_info (void);
70 static void gaa_parser (int argc, char **argv);
71 void generate_self_signed (void);
72 void generate_request (void);
73 gnutls_x509_crt_t *load_cert_list (int mand, size_t * size);
74 static void print_certificate_info (gnutls_x509_crt_t crt, FILE * out, unsigned int all);
76 static void print_hex_datum (gnutls_datum_t * dat);
78 static gaainfo info;
79 FILE *outfile;
80 FILE *infile;
81 gnutls_digest_algorithm_t default_dig;
83 /* non interactive operation if set
85 int batch;
87 unsigned char buffer[64 * 1024];
88 const int buffer_size = sizeof (buffer);
90 static void
91 tls_log_func (int level, const char *str)
93 fprintf (stderr, "|<%d>| %s", level, str);
96 int
97 main (int argc, char **argv)
99 set_program_name (argv[0]);
100 cfg_init ();
101 gaa_parser (argc, argv);
103 return 0;
106 static const char *
107 raw_to_string (const unsigned char *raw, size_t raw_size)
109 static char buf[1024];
110 size_t i;
111 if (raw_size == 0)
112 return NULL;
114 if (raw_size * 3 + 1 >= sizeof (buf))
115 return NULL;
117 for (i = 0; i < raw_size; i++)
119 sprintf (&(buf[i * 3]), "%02X%s", raw[i],
120 (i == raw_size - 1) ? "" : ":");
122 buf[sizeof (buf) - 1] = '\0';
124 return buf;
127 static void
128 print_dsa_pkey (gnutls_datum_t * x, gnutls_datum_t * y, gnutls_datum_t * p,
129 gnutls_datum_t * q, gnutls_datum_t * g)
131 if (x)
133 fprintf (outfile, "private key:");
134 print_hex_datum (x);
136 fprintf (outfile, "public key:");
137 print_hex_datum (y);
138 fprintf (outfile, "p:");
139 print_hex_datum (p);
140 fprintf (outfile, "q:");
141 print_hex_datum (q);
142 fprintf (outfile, "g:");
143 print_hex_datum (g);
146 static void
147 print_rsa_pkey (gnutls_datum_t * m, gnutls_datum_t * e, gnutls_datum_t * d,
148 gnutls_datum_t * p, gnutls_datum_t * q, gnutls_datum_t * u,
149 gnutls_datum_t * exp1, gnutls_datum_t *exp2)
151 fprintf (outfile, "modulus:");
152 print_hex_datum (m);
153 fprintf (outfile, "public exponent:");
154 print_hex_datum (e);
155 if (d)
157 fprintf (outfile, "private exponent:");
158 print_hex_datum (d);
159 fprintf (outfile, "prime1:");
160 print_hex_datum (p);
161 fprintf (outfile, "prime2:");
162 print_hex_datum (q);
163 fprintf (outfile, "coefficient:");
164 print_hex_datum (u);
165 if (exp1 && exp2)
167 fprintf (outfile, "exp1:");
168 print_hex_datum (exp1);
169 fprintf (outfile, "exp2:");
170 print_hex_datum (exp2);
175 static gnutls_sec_param_t str_to_sec_param(const char* str)
177 if (strcasecmp(str, "low")==0)
179 return GNUTLS_SEC_PARAM_LOW;
181 else if (strcasecmp(str, "normal")==0)
183 return GNUTLS_SEC_PARAM_NORMAL;
185 else if (strcasecmp(str, "high")==0)
187 return GNUTLS_SEC_PARAM_HIGH;
189 else if (strcasecmp(str, "ultra")==0)
191 return GNUTLS_SEC_PARAM_ULTRA;
193 else
195 fprintf(stderr, "Unknown security parameter string: %s\n", str);
196 exit(1);
201 int get_bits(gnutls_pk_algorithm_t key_type)
203 int bits;
205 if (info.bits != 0)
207 static int warned = 0;
209 if (warned == 0)
211 warned = 1;
212 fprintf(stderr, "** Note: Please use the --sec-param instead of --bits\n");
214 bits = info.bits;
216 else
218 if (info.sec_param)
220 bits = gnutls_sec_param_to_pk_bits(key_type, str_to_sec_param(info.sec_param));
222 else bits = gnutls_sec_param_to_pk_bits(key_type, GNUTLS_SEC_PARAM_NORMAL);
225 return bits;
229 static gnutls_x509_privkey_t
230 generate_private_key_int (void)
232 gnutls_x509_privkey_t key;
233 int ret, key_type, bits;
235 if (info.dsa)
237 key_type = GNUTLS_PK_DSA;
239 else
240 key_type = GNUTLS_PK_RSA;
242 ret = gnutls_x509_privkey_init (&key);
243 if (ret < 0)
244 error (EXIT_FAILURE, 0, "privkey_init: %s", gnutls_strerror (ret));
246 bits = get_bits(key_type);
248 fprintf (stderr, "Generating a %d bit %s private key...\n", get_bits(key_type),
249 gnutls_pk_algorithm_get_name (key_type));
251 if (info.quick_random == 0)
252 fprintf (stderr,
253 "This might take several minutes depending on availability of randomness"
254 " in /dev/random.\n");
256 ret = gnutls_x509_privkey_generate (key, key_type, get_bits(key_type), 0);
257 if (ret < 0)
258 error (EXIT_FAILURE, 0, "privkey_generate: %s", gnutls_strerror (ret));
260 return key;
263 static int
264 cipher_to_flags (const char *cipher)
266 if (strcasecmp (cipher, "3des") == 0)
268 return GNUTLS_PKCS_USE_PBES2_3DES;
270 else if (strcasecmp (cipher, "3des-pkcs12") == 0)
272 return GNUTLS_PKCS_USE_PKCS12_3DES;
274 else if (strcasecmp (cipher, "arcfour") == 0)
276 return GNUTLS_PKCS_USE_PKCS12_ARCFOUR;
278 else if (strcasecmp (cipher, "aes-128") == 0)
280 return GNUTLS_PKCS_USE_PBES2_AES_128;
282 else if (strcasecmp (cipher, "aes-192") == 0)
284 return GNUTLS_PKCS_USE_PBES2_AES_192;
286 else if (strcasecmp (cipher, "aes-256") == 0)
288 return GNUTLS_PKCS_USE_PBES2_AES_256;
290 else if (strcasecmp (cipher, "rc2-40") == 0)
292 return GNUTLS_PKCS_USE_PKCS12_RC2_40;
295 error (EXIT_FAILURE, 0, "Unknown cipher %s\n", cipher);
296 return -1;
300 static void
301 print_private_key (gnutls_x509_privkey_t key)
303 int ret;
304 size_t size;
306 if (!key)
307 return;
309 if (!info.pkcs8)
311 size = sizeof (buffer);
312 ret = gnutls_x509_privkey_export (key, info.outcert_format,
313 buffer, &size);
314 if (ret < 0)
315 error (EXIT_FAILURE, 0, "privkey_export: %s", gnutls_strerror (ret));
317 else
319 unsigned int flags;
320 const char *pass;
322 if (info.export)
323 flags = GNUTLS_PKCS_USE_PKCS12_RC2_40;
324 else
325 flags = cipher_to_flags (info.pkcs_cipher);
327 if ((pass = get_confirmed_pass (true)) == NULL || *pass == '\0')
328 flags = GNUTLS_PKCS_PLAIN;
330 size = sizeof (buffer);
331 ret =
332 gnutls_x509_privkey_export_pkcs8 (key, info.outcert_format, pass,
333 flags, buffer, &size);
334 if (ret < 0)
335 error (EXIT_FAILURE, 0, "privkey_export_pkcs8: %s",
336 gnutls_strerror (ret));
339 fwrite (buffer, 1, size, outfile);
342 static void
343 generate_private_key (void)
345 gnutls_x509_privkey_t key;
347 key = generate_private_key_int ();
349 print_private_key (key);
351 gnutls_x509_privkey_deinit (key);
355 static gnutls_x509_crt_t
356 generate_certificate (gnutls_x509_privkey_t * ret_key,
357 gnutls_x509_crt_t ca_crt, int proxy)
359 gnutls_x509_crt_t crt;
360 gnutls_x509_privkey_t key = NULL;
361 size_t size;
362 int ret;
363 int client;
364 int days, result, ca_status = 0, path_len;
365 int vers;
366 unsigned int usage = 0, server;
367 gnutls_x509_crq_t crq; /* request */
369 ret = gnutls_x509_crt_init (&crt);
370 if (ret < 0)
371 error (EXIT_FAILURE, 0, "crt_init: %s", gnutls_strerror (ret));
373 crq = load_request ();
375 if (crq == NULL)
378 key = load_private_key (1);
380 if (!batch)
381 fprintf (stderr,
382 "Please enter the details of the certificate's distinguished name. "
383 "Just press enter to ignore a field.\n");
385 /* set the DN.
387 if (proxy)
389 result = gnutls_x509_crt_set_proxy_dn (crt, ca_crt, 0, NULL, 0);
390 if (result < 0)
391 error (EXIT_FAILURE, 0, "set_proxy_dn: %s",
392 gnutls_strerror (result));
394 get_cn_crt_set (crt);
396 else
398 get_country_crt_set (crt);
399 get_organization_crt_set (crt);
400 get_unit_crt_set (crt);
401 get_locality_crt_set (crt);
402 get_state_crt_set (crt);
403 get_cn_crt_set (crt);
404 get_uid_crt_set (crt);
405 get_oid_crt_set (crt);
406 get_key_purpose_set (crt);
408 if (!batch)
409 fprintf (stderr,
410 "This field should not be used in new certificates.\n");
412 get_pkcs9_email_crt_set (crt);
415 result = gnutls_x509_crt_set_key (crt, key);
416 if (result < 0)
417 error (EXIT_FAILURE, 0, "set_key: %s", gnutls_strerror (result));
419 else
421 result = gnutls_x509_crt_set_crq (crt, crq);
422 if (result < 0)
423 error (EXIT_FAILURE, 0, "set_crq: %s", gnutls_strerror (result));
428 int serial = get_serial ();
429 char bin_serial[5];
431 bin_serial[4] = serial & 0xff;
432 bin_serial[3] = (serial >> 8) & 0xff;
433 bin_serial[2] = (serial >> 16) & 0xff;
434 bin_serial[1] = (serial >> 24) & 0xff;
435 bin_serial[0] = 0;
437 result = gnutls_x509_crt_set_serial (crt, bin_serial, 5);
438 if (result < 0)
439 error (EXIT_FAILURE, 0, "serial: %s", gnutls_strerror (result));
442 if (!batch)
443 fprintf (stderr, "\n\nActivation/Expiration time.\n");
445 gnutls_x509_crt_set_activation_time (crt, time (NULL));
447 days = get_days ();
449 result =
450 gnutls_x509_crt_set_expiration_time (crt,
451 time (NULL) + days * 24 * 60 * 60);
452 if (result < 0)
453 error (EXIT_FAILURE, 0, "set_expiration: %s", gnutls_strerror (result));
455 if (!batch)
456 fprintf (stderr, "\n\nExtensions.\n");
458 /* do not allow extensions on a v1 certificate */
459 if (crq && get_crq_extensions_status () != 0)
461 result = gnutls_x509_crt_set_crq_extensions (crt, crq);
462 if (result < 0)
463 error (EXIT_FAILURE, 0, "set_crq: %s", gnutls_strerror (result));
466 /* append additional extensions */
467 if (info.v1_cert == 0)
470 if (proxy)
472 const char *policylanguage;
473 char *policy;
474 size_t policylen;
475 int proxypathlen = get_path_len ();
477 if (!batch)
479 printf ("1.3.6.1.5.5.7.21.1 ::= id-ppl-inheritALL\n");
480 printf ("1.3.6.1.5.5.7.21.2 ::= id-ppl-independent\n");
483 policylanguage = get_proxy_policy (&policy, &policylen);
485 result =
486 gnutls_x509_crt_set_proxy (crt, proxypathlen, policylanguage,
487 policy, policylen);
488 if (result < 0)
489 error (EXIT_FAILURE, 0, "set_proxy: %s",
490 gnutls_strerror (result));
493 if (!proxy)
494 ca_status = get_ca_status ();
495 if (ca_status)
496 path_len = get_path_len ();
497 else
498 path_len = -1;
500 result =
501 gnutls_x509_crt_set_basic_constraints (crt, ca_status, path_len);
502 if (result < 0)
503 error (EXIT_FAILURE, 0, "basic_constraints: %s",
504 gnutls_strerror (result));
506 client = get_tls_client_status ();
507 if (client != 0)
509 result = gnutls_x509_crt_set_key_purpose_oid (crt,
510 GNUTLS_KP_TLS_WWW_CLIENT,
512 if (result < 0)
513 error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (result));
516 server = get_tls_server_status ();
517 if (server != 0)
519 result = 0;
521 if (!proxy)
523 get_dns_name_set (TYPE_CRT, crt);
524 get_ip_addr_set (TYPE_CRT, crt);
527 result =
528 gnutls_x509_crt_set_key_purpose_oid (crt,
529 GNUTLS_KP_TLS_WWW_SERVER, 0);
530 if (result < 0)
531 error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (result));
533 else if (!proxy)
535 get_email_set (TYPE_CRT, crt);
538 if (!ca_status || server)
540 int pk;
543 pk = gnutls_x509_crt_get_pk_algorithm (crt, NULL);
545 if (pk != GNUTLS_PK_DSA)
546 { /* DSA keys can only sign.
548 result = get_sign_status (server);
549 if (result)
550 usage |= GNUTLS_KEY_DIGITAL_SIGNATURE;
552 result = get_encrypt_status (server);
553 if (result)
554 usage |= GNUTLS_KEY_KEY_ENCIPHERMENT;
556 else
557 usage |= GNUTLS_KEY_DIGITAL_SIGNATURE;
561 if (ca_status)
563 result = get_cert_sign_status ();
564 if (result)
565 usage |= GNUTLS_KEY_KEY_CERT_SIGN;
567 result = get_crl_sign_status ();
568 if (result)
569 usage |= GNUTLS_KEY_CRL_SIGN;
571 result = get_code_sign_status ();
572 if (result)
574 result =
575 gnutls_x509_crt_set_key_purpose_oid (crt,
576 GNUTLS_KP_CODE_SIGNING,
578 if (result < 0)
579 error (EXIT_FAILURE, 0, "key_kp: %s",
580 gnutls_strerror (result));
583 result = get_ocsp_sign_status ();
584 if (result)
586 result =
587 gnutls_x509_crt_set_key_purpose_oid (crt,
588 GNUTLS_KP_OCSP_SIGNING,
590 if (result < 0)
591 error (EXIT_FAILURE, 0, "key_kp: %s",
592 gnutls_strerror (result));
595 result = get_time_stamp_status ();
596 if (result)
598 result =
599 gnutls_x509_crt_set_key_purpose_oid (crt,
600 GNUTLS_KP_TIME_STAMPING,
602 if (result < 0)
603 error (EXIT_FAILURE, 0, "key_kp: %s",
604 gnutls_strerror (result));
608 if (usage != 0)
610 result = gnutls_x509_crt_set_key_usage (crt, usage);
611 if (result < 0)
612 error (EXIT_FAILURE, 0, "key_usage: %s",
613 gnutls_strerror (result));
616 /* Subject Key ID.
618 size = sizeof (buffer);
619 result = gnutls_x509_crt_get_key_id (crt, 0, buffer, &size);
620 if (result >= 0)
622 result = gnutls_x509_crt_set_subject_key_id (crt, buffer, size);
623 if (result < 0)
624 error (EXIT_FAILURE, 0, "set_subject_key_id: %s",
625 gnutls_strerror (result));
628 /* Authority Key ID.
630 if (ca_crt != NULL)
632 size = sizeof (buffer);
633 result = gnutls_x509_crt_get_subject_key_id (ca_crt, buffer,
634 &size, NULL);
635 if (result < 0)
637 size = sizeof (buffer);
638 result = gnutls_x509_crt_get_key_id (ca_crt, 0, buffer, &size);
640 if (result >= 0)
642 result =
643 gnutls_x509_crt_set_authority_key_id (crt, buffer, size);
644 if (result < 0)
645 error (EXIT_FAILURE, 0, "set_authority_key_id: %s",
646 gnutls_strerror (result));
651 /* Version.
653 if (info.v1_cert != 0)
654 vers = 1;
655 else
656 vers = 3;
657 result = gnutls_x509_crt_set_version (crt, vers);
658 if (result < 0)
659 error (EXIT_FAILURE, 0, "set_version: %s", gnutls_strerror (result));
661 *ret_key = key;
662 return crt;
666 static gnutls_x509_crl_t
667 generate_crl (gnutls_x509_crt_t ca_crt)
669 gnutls_x509_crl_t crl;
670 gnutls_x509_crt_t *crts;
671 size_t size;
672 int days, result;
673 unsigned int i;
674 time_t now = time (NULL);
676 result = gnutls_x509_crl_init (&crl);
677 if (result < 0)
678 error (EXIT_FAILURE, 0, "crl_init: %s", gnutls_strerror (result));
680 crts = load_cert_list (0, &size);
682 for (i = 0; i < size; i++)
684 result = gnutls_x509_crl_set_crt (crl, crts[i], now);
685 if (result < 0)
686 error (EXIT_FAILURE, 0, "crl_set_crt: %s", gnutls_strerror (result));
689 result = gnutls_x509_crl_set_this_update (crl, now);
690 if (result < 0)
691 error (EXIT_FAILURE, 0, "this_update: %s", gnutls_strerror (result));
693 fprintf (stderr, "Update times.\n");
694 days = get_crl_next_update ();
696 result = gnutls_x509_crl_set_next_update (crl, now + days * 24 * 60 * 60);
697 if (result < 0)
698 error (EXIT_FAILURE, 0, "next_update: %s", gnutls_strerror (result));
700 result = gnutls_x509_crl_set_version (crl, 2);
701 if (result < 0)
702 error (EXIT_FAILURE, 0, "set_version: %s", gnutls_strerror (result));
704 /* Authority Key ID.
706 if (ca_crt != NULL)
708 size = sizeof (buffer);
709 result = gnutls_x509_crt_get_subject_key_id (ca_crt, buffer,
710 &size, NULL);
711 if (result < 0)
713 size = sizeof (buffer);
714 result = gnutls_x509_crt_get_key_id (ca_crt, 0, buffer, &size);
716 if (result >= 0)
718 result = gnutls_x509_crl_set_authority_key_id (crl, buffer, size);
719 if (result < 0)
720 error (EXIT_FAILURE, 0, "set_authority_key_id: %s",
721 gnutls_strerror (result));
726 unsigned int number = get_crl_number ();
727 char bin_number[5];
729 bin_number[4] = number & 0xff;
730 bin_number[3] = (number >> 8) & 0xff;
731 bin_number[2] = (number >> 16) & 0xff;
732 bin_number[1] = (number >> 24) & 0xff;
733 bin_number[0] = 0;
735 result = gnutls_x509_crl_set_number (crl, bin_number, 5);
736 if (result < 0)
737 error (EXIT_FAILURE, 0, "set_number: %s", gnutls_strerror (result));
740 return crl;
743 static gnutls_digest_algorithm_t get_dig(gnutls_x509_crt crt)
745 gnutls_digest_algorithm_t dig;
746 int result;
747 unsigned int mand;
749 result = gnutls_x509_crt_get_preferred_hash_algorithm(crt, &dig, &mand);
750 if (result < 0)
752 error (EXIT_FAILURE, 0, "crl_preferred_hash_algorithm: %s",
753 gnutls_strerror (result));
756 /* if algorithm allows alternatives */
757 if (mand == 0 && default_dig != GNUTLS_DIG_UNKNOWN)
758 dig = default_dig;
760 return dig;
763 void generate_self_signed (void)
765 gnutls_x509_crt_t crt;
766 gnutls_x509_privkey_t key;
767 size_t size;
768 int result;
769 const char *uri;
771 fprintf (stderr, "Generating a self signed certificate...\n");
773 crt = generate_certificate (&key, NULL, 0);
775 if (!key)
776 key = load_private_key (1);
778 uri = get_crl_dist_point_url ();
779 if (uri)
781 result = gnutls_x509_crt_set_crl_dist_points (crt, GNUTLS_SAN_URI,
782 uri,
783 0 /* all reasons */ );
784 if (result < 0)
785 error (EXIT_FAILURE, 0, "crl_dist_points: %s",
786 gnutls_strerror (result));
789 print_certificate_info (crt, stderr, 0);
791 fprintf (stderr, "\n\nSigning certificate...\n");
793 result = gnutls_x509_crt_sign2 (crt, crt, key, get_dig(crt), 0);
794 if (result < 0)
795 error (EXIT_FAILURE, 0, "crt_sign: %s", gnutls_strerror (result));
797 size = sizeof (buffer);
798 result = gnutls_x509_crt_export (crt, info.outcert_format, buffer, &size);
799 if (result < 0)
800 error (EXIT_FAILURE, 0, "crt_export: %s", gnutls_strerror (result));
802 fwrite (buffer, 1, size, outfile);
804 gnutls_x509_crt_deinit (crt);
805 gnutls_x509_privkey_deinit (key);
808 static void
809 generate_signed_certificate (void)
811 gnutls_x509_crt_t crt;
812 gnutls_x509_privkey_t key;
813 size_t size;
814 int result;
815 gnutls_x509_privkey_t ca_key;
816 gnutls_x509_crt_t ca_crt;
818 fprintf (stderr, "Generating a signed certificate...\n");
820 ca_key = load_ca_private_key ();
821 ca_crt = load_ca_cert ();
823 crt = generate_certificate (&key, ca_crt, 0);
825 /* Copy the CRL distribution points.
827 gnutls_x509_crt_cpy_crl_dist_points (crt, ca_crt);
828 /* it doesn't matter if we couldn't copy the CRL dist points.
831 print_certificate_info (crt, stderr, 0);
833 fprintf (stderr, "\n\nSigning certificate...\n");
835 result = gnutls_x509_crt_sign2 (crt, ca_crt, ca_key, get_dig(ca_crt), 0);
836 if (result < 0)
837 error (EXIT_FAILURE, 0, "crt_sign: %s", gnutls_strerror (result));
839 size = sizeof (buffer);
840 result = gnutls_x509_crt_export (crt, info.outcert_format, buffer, &size);
841 if (result < 0)
842 error (EXIT_FAILURE, 0, "crt_export: %s", gnutls_strerror (result));
844 fwrite (buffer, 1, size, outfile);
846 gnutls_x509_crt_deinit (crt);
847 gnutls_x509_privkey_deinit (key);
850 static void
851 generate_proxy_certificate (void)
853 gnutls_x509_crt_t crt, eecrt;
854 gnutls_x509_privkey_t key, eekey;
855 size_t size;
856 int result;
858 fprintf (stderr, "Generating a proxy certificate...\n");
860 eekey = load_ca_private_key ();
861 eecrt = load_cert (1);
863 crt = generate_certificate (&key, eecrt, 1);
865 print_certificate_info (crt, stderr, 0);
867 fprintf (stderr, "\n\nSigning certificate...\n");
869 result = gnutls_x509_crt_sign2 (crt, eecrt, eekey, get_dig(eecrt), 0);
870 if (result < 0)
871 error (EXIT_FAILURE, 0, "crt_sign: %s", gnutls_strerror (result));
873 size = sizeof (buffer);
874 result = gnutls_x509_crt_export (crt, info.outcert_format, buffer, &size);
875 if (result < 0)
876 error (EXIT_FAILURE, 0, "crt_export: %s", gnutls_strerror (result));
878 fwrite (buffer, 1, size, outfile);
880 gnutls_x509_crt_deinit (crt);
881 gnutls_x509_privkey_deinit (key);
884 static void
885 generate_signed_crl (void)
887 gnutls_x509_crl_t crl;
888 int result;
889 gnutls_x509_privkey_t ca_key;
890 gnutls_x509_crt_t ca_crt;
892 fprintf (stderr, "Generating a signed CRL...\n");
894 ca_key = load_ca_private_key ();
895 ca_crt = load_ca_cert ();
896 crl = generate_crl (ca_crt);
898 fprintf (stderr, "\n");
900 result = gnutls_x509_crl_sign (crl, ca_crt, ca_key);
901 if (result < 0)
902 error (EXIT_FAILURE, 0, "crl_sign: %s", gnutls_strerror (result));
904 print_crl_info (crl, stderr);
906 gnutls_x509_crl_deinit (crl);
909 static void
910 update_signed_certificate (void)
912 gnutls_x509_crt_t crt;
913 size_t size;
914 int result;
915 gnutls_x509_privkey_t ca_key;
916 gnutls_x509_crt_t ca_crt;
917 int days;
918 time_t tim = time (NULL);
920 fprintf (stderr, "Generating a signed certificate...\n");
922 ca_key = load_ca_private_key ();
923 ca_crt = load_ca_cert ();
924 crt = load_cert (1);
926 fprintf (stderr, "Activation/Expiration time.\n");
927 gnutls_x509_crt_set_activation_time (crt, tim);
929 days = get_days ();
931 result =
932 gnutls_x509_crt_set_expiration_time (crt, tim + days * 24 * 60 * 60);
933 if (result < 0)
934 error (EXIT_FAILURE, 0, "set_expiration: %s", gnutls_strerror (result));
936 fprintf (stderr, "\n\nSigning certificate...\n");
938 result = gnutls_x509_crt_sign2 (crt, ca_crt, ca_key, get_dig(ca_crt), 0);
939 if (result < 0)
940 error (EXIT_FAILURE, 0, "crt_sign: %s", gnutls_strerror (result));
942 size = sizeof (buffer);
943 result = gnutls_x509_crt_export (crt, info.outcert_format, buffer, &size);
944 if (result < 0)
945 error (EXIT_FAILURE, 0, "crt_export: %s", gnutls_strerror (result));
947 fwrite (buffer, 1, size, outfile);
949 gnutls_x509_crt_deinit (crt);
952 static FILE *
953 safe_open_rw (const char *file)
955 mode_t omask = 0;
956 FILE *fh;
958 if (info.privkey_op != 0)
960 omask = umask (S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
963 fh = fopen (file, "wb");
965 if (info.privkey_op != 0)
967 umask (omask);
970 return fh;
973 void
974 gaa_parser (int argc, char **argv)
976 int ret;
978 if (gaa (argc, argv, &info) != -1)
980 fprintf (stderr, "Try `%s --help' for more information.\n",
981 program_name);
982 exit (1);
985 if (info.outfile)
987 outfile = safe_open_rw (info.outfile);
988 if (outfile == NULL)
989 error (EXIT_FAILURE, errno, "%s", info.outfile);
991 else
992 outfile = stdout;
994 if (info.infile)
996 infile = fopen (info.infile, "rb");
997 if (infile == NULL)
998 error (EXIT_FAILURE, errno, "%s", info.infile);
1000 else
1001 infile = stdin;
1003 if (info.incert_format)
1004 info.incert_format = GNUTLS_X509_FMT_DER;
1005 else
1006 info.incert_format = GNUTLS_X509_FMT_PEM;
1008 if (info.outcert_format)
1009 info.outcert_format = GNUTLS_X509_FMT_DER;
1010 else
1011 info.outcert_format = GNUTLS_X509_FMT_PEM;
1013 default_dig = GNUTLS_DIG_UNKNOWN;
1014 if (info.hash != NULL)
1016 if (strcasecmp (info.hash, "md5") == 0)
1018 fprintf (stderr,
1019 "Warning: MD5 is broken, and should not be used any more for digital signatures.\n");
1020 default_dig = GNUTLS_DIG_MD5;
1022 else if (strcasecmp (info.hash, "sha1") == 0)
1023 default_dig = GNUTLS_DIG_SHA1;
1024 else if (strcasecmp (info.hash, "sha256") == 0)
1025 default_dig = GNUTLS_DIG_SHA256;
1026 else if (strcasecmp (info.hash, "sha224") == 0)
1027 default_dig = GNUTLS_DIG_SHA224;
1028 else if (strcasecmp (info.hash, "sha384") == 0)
1029 default_dig = GNUTLS_DIG_SHA384;
1030 else if (strcasecmp (info.hash, "sha512") == 0)
1031 default_dig = GNUTLS_DIG_SHA512;
1032 else if (strcasecmp (info.hash, "rmd160") == 0)
1033 default_dig = GNUTLS_DIG_RMD160;
1034 else
1035 error (EXIT_FAILURE, 0, "invalid hash: %s", info.hash);
1038 batch = 0;
1039 if (info.template)
1041 batch = 1;
1042 template_parse (info.template);
1045 gnutls_global_set_log_function (tls_log_func);
1046 gnutls_global_set_log_level (info.debug);
1047 if (info.debug > 1)
1048 printf ("Setting log level to %d\n", info.debug);
1050 if ((ret = gnutls_global_init ()) < 0)
1051 error (EXIT_FAILURE, 0, "global_init: %s", gnutls_strerror (ret));
1053 if (info.pkcs11_provider != NULL)
1055 ret = gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_MANUAL, NULL);
1056 if (ret < 0)
1057 fprintf (stderr, "pkcs11_init: %s", gnutls_strerror (ret));
1058 else {
1059 ret = gnutls_pkcs11_add_provider(info.pkcs11_provider, NULL);
1060 if (ret < 0)
1061 error (EXIT_FAILURE, 0, "pkcs11_add_provider: %s", gnutls_strerror (ret));
1064 else
1066 ret = gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_AUTO, NULL);
1067 if (ret < 0)
1068 fprintf (stderr, "pkcs11_init: %s", gnutls_strerror (ret));
1072 if ((ret = gnutls_global_init_extra ()) < 0)
1073 error (EXIT_FAILURE, 0, "global_init_extra: %s", gnutls_strerror (ret));
1075 switch (info.action)
1077 case ACTION_SELF_SIGNED:
1078 generate_self_signed ();
1079 break;
1080 case ACTION_GENERATE_PRIVKEY:
1081 generate_private_key ();
1082 break;
1083 case ACTION_CERT_INFO:
1084 certificate_info (0);
1085 break;
1086 case ACTION_CERT_PUBKEY:
1087 certificate_info (1);
1088 break;
1089 case ACTION_GENERATE_REQUEST:
1090 generate_request ();
1091 break;
1092 case ACTION_GENERATE_CERTIFICATE:
1093 generate_signed_certificate ();
1094 break;
1095 case ACTION_VERIFY_CHAIN:
1096 verify_chain ();
1097 break;
1098 case ACTION_PRIVKEY_INFO:
1099 privkey_info ();
1100 break;
1101 case ACTION_PUBKEY_INFO:
1102 pubkey_info (NULL);
1103 break;
1104 case ACTION_UPDATE_CERTIFICATE:
1105 update_signed_certificate ();
1106 break;
1107 case ACTION_TO_PKCS12:
1108 generate_pkcs12 ();
1109 break;
1110 case ACTION_PKCS12_INFO:
1111 pkcs12_info ();
1112 break;
1113 case ACTION_GENERATE_DH:
1114 generate_prime (1);
1115 break;
1116 case ACTION_GET_DH:
1117 generate_prime (0);
1118 break;
1119 case ACTION_CRL_INFO:
1120 crl_info ();
1121 break;
1122 case ACTION_P7_INFO:
1123 pkcs7_info ();
1124 break;
1125 case ACTION_GENERATE_CRL:
1126 generate_signed_crl ();
1127 break;
1128 case ACTION_VERIFY_CRL:
1129 verify_crl ();
1130 break;
1131 case ACTION_SMIME_TO_P7:
1132 smime_to_pkcs7 ();
1133 break;
1134 case ACTION_GENERATE_PROXY:
1135 generate_proxy_certificate ();
1136 break;
1137 case ACTION_GENERATE_PKCS8:
1138 generate_pkcs8 ();
1139 break;
1140 case ACTION_PKCS11_LIST:
1141 pkcs11_list(outfile, info.pkcs11_url, info.pkcs11_type, info.pkcs11_login);
1142 break;
1143 case ACTION_PKCS11_TOKENS:
1144 pkcs11_token_list(outfile);
1145 break;
1146 case ACTION_PKCS11_EXPORT_URL:
1147 pkcs11_export(outfile, info.pkcs11_url, info.pkcs11_login);
1148 break;
1149 case ACTION_PKCS11_WRITE_URL:
1150 pkcs11_write(outfile, info.pkcs11_url, info.pkcs11_label, info.pkcs11_trusted, info.pkcs11_login);
1151 break;
1152 case ACTION_PKCS11_DELETE_URL:
1153 pkcs11_delete(outfile, info.pkcs11_url, batch, info.pkcs11_login);
1154 break;
1155 #ifdef ENABLE_OPENPGP
1156 case ACTION_PGP_INFO:
1157 pgp_certificate_info ();
1158 break;
1159 case ACTION_PGP_PRIVKEY_INFO:
1160 pgp_privkey_info ();
1161 break;
1162 case ACTION_RING_INFO:
1163 pgp_ring_info ();
1164 break;
1165 #endif
1166 case ACTION_REQUEST:
1167 crq_info ();
1168 break;
1169 default:
1170 gaa_help ();
1171 exit (0);
1173 fclose (outfile);
1175 gnutls_pkcs11_deinit();
1176 gnutls_global_deinit();
1179 #define MAX_CRTS 500
1180 void
1181 certificate_info (int pubkey)
1183 gnutls_x509_crt_t crt[MAX_CRTS];
1184 size_t size;
1185 int ret, i, count;
1186 gnutls_datum_t pem;
1187 unsigned int crt_num;
1189 pem.data = fread_file (infile, &size);
1190 pem.size = size;
1192 crt_num = MAX_CRTS;
1193 ret =
1194 gnutls_x509_crt_list_import (crt, &crt_num, &pem, info.incert_format,
1195 GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
1196 if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
1198 error (0, 0, "too many certificates (%d); "
1199 "will only read the first %d", crt_num, MAX_CRTS);
1200 crt_num = MAX_CRTS;
1201 ret = gnutls_x509_crt_list_import (crt, &crt_num, &pem,
1202 info.incert_format, 0);
1204 if (ret < 0)
1205 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (ret));
1207 free (pem.data);
1209 count = ret;
1211 if (count > 1 && info.outcert_format == GNUTLS_X509_FMT_DER)
1213 error (0, 0, "cannot output multiple certificates in DER format; "
1214 "using PEM instead");
1215 info.outcert_format = GNUTLS_X509_FMT_PEM;
1218 for (i = 0; i < count; i++)
1220 if (i > 0)
1221 fprintf (outfile, "\n");
1223 if (info.outcert_format == GNUTLS_X509_FMT_PEM)
1224 print_certificate_info (crt[i], outfile, 1);
1226 size = sizeof (buffer);
1227 ret = gnutls_x509_crt_export (crt[i], info.outcert_format, buffer,
1228 &size);
1229 if (ret < 0)
1230 error (EXIT_FAILURE, 0, "export error: %s", gnutls_strerror (ret));
1232 fwrite (buffer, 1, size, outfile);
1234 if (pubkey) pubkey_info(crt[i]);
1236 gnutls_x509_crt_deinit (crt[i]);
1240 #ifdef ENABLE_OPENPGP
1242 void
1243 pgp_certificate_info (void)
1245 gnutls_openpgp_crt_t crt;
1246 size_t size;
1247 int ret;
1248 gnutls_datum_t pem, out_data;
1249 unsigned int verify_status;
1251 pem.data = fread_file (infile, &size);
1252 pem.size = size;
1254 ret = gnutls_openpgp_crt_init (&crt);
1255 if (ret < 0)
1256 error (EXIT_FAILURE, 0, "openpgp_crt_init: %s", gnutls_strerror (ret));
1258 ret = gnutls_openpgp_crt_import (crt, &pem, info.incert_format);
1260 if (ret < 0)
1261 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (ret));
1263 free (pem.data);
1265 if (info.outcert_format == GNUTLS_OPENPGP_FMT_BASE64)
1267 ret = gnutls_openpgp_crt_print (crt, 0, &out_data);
1269 if (ret == 0)
1271 fprintf (outfile, "%s\n", out_data.data);
1272 gnutls_free (out_data.data);
1277 ret = gnutls_openpgp_crt_verify_self (crt, 0, &verify_status);
1278 if (ret < 0)
1280 error (EXIT_FAILURE, 0, "verify signature error: %s",
1281 gnutls_strerror (ret));
1284 if (verify_status & GNUTLS_CERT_INVALID)
1286 fprintf (outfile, "Self Signature verification: failed\n\n");
1288 else
1290 fprintf (outfile, "Self Signature verification: ok (%x)\n\n",
1291 verify_status);
1294 size = sizeof (buffer);
1295 ret = gnutls_openpgp_crt_export (crt, info.outcert_format, buffer, &size);
1296 if (ret < 0)
1298 error (EXIT_FAILURE, 0, "export error: %s", gnutls_strerror (ret));
1299 fwrite (buffer, 1, size, outfile);
1302 fprintf (outfile, "%s\n", buffer);
1303 gnutls_openpgp_crt_deinit (crt);
1306 void
1307 pgp_privkey_info (void)
1309 gnutls_openpgp_privkey_t key;
1310 gnutls_openpgp_keyid_t keyid;
1311 size_t size;
1312 int ret, i, subkeys;
1313 gnutls_datum_t pem;
1314 const char *cprint;
1316 size = fread (buffer, 1, sizeof (buffer) - 1, infile);
1317 buffer[size] = 0;
1319 gnutls_openpgp_privkey_init (&key);
1321 pem.data = buffer;
1322 pem.size = size;
1324 ret = gnutls_openpgp_privkey_import (key, &pem, info.incert_format,
1325 NULL, 0);
1327 if (ret < 0)
1328 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (ret));
1330 /* Public key algorithm
1332 subkeys = gnutls_openpgp_privkey_get_subkey_count (key);
1333 if (subkeys < 0)
1334 error (EXIT_FAILURE, 0, "privkey_get_subkey_count: %s",
1335 gnutls_strerror (subkeys));
1337 for (i = -1; i < subkeys; i++)
1340 if (i != -1)
1341 fprintf (outfile, "Subkey[%d]:\n", i);
1343 fprintf (outfile, "Public Key Info:\n");
1345 if (i == -1)
1346 ret = gnutls_openpgp_privkey_get_pk_algorithm (key, NULL);
1347 else
1348 ret = gnutls_openpgp_privkey_get_subkey_pk_algorithm (key, i, NULL);
1350 fprintf (outfile, "\tPublic Key Algorithm: ");
1351 cprint = gnutls_pk_algorithm_get_name (ret);
1352 fprintf (outfile, "%s\n", cprint ? cprint : "Unknown");
1353 fprintf (outfile, "\tKey Security Level: %s\n", gnutls_sec_param_get_name(gnutls_openpgp_privkey_sec_param(key)));
1355 /* Print the raw public and private keys
1358 if (ret == GNUTLS_PK_RSA)
1360 gnutls_datum_t m, e, d, p, q, u;
1362 if (i == -1)
1363 ret =
1364 gnutls_openpgp_privkey_export_rsa_raw (key, &m, &e, &d, &p,
1365 &q, &u);
1366 else
1367 ret =
1368 gnutls_openpgp_privkey_export_subkey_rsa_raw (key, i, &m,
1369 &e, &d, &p,
1370 &q, &u);
1371 if (ret < 0)
1372 fprintf (stderr, "Error in key RSA data export: %s\n",
1373 gnutls_strerror (ret));
1374 else
1375 print_rsa_pkey (&m, &e, &d, &p, &q, &u, NULL, NULL);
1378 else if (ret == GNUTLS_PK_DSA)
1380 gnutls_datum_t p, q, g, y, x;
1382 if (i == -1)
1383 ret =
1384 gnutls_openpgp_privkey_export_dsa_raw (key, &p, &q, &g, &y, &x);
1385 else
1386 ret =
1387 gnutls_openpgp_privkey_export_subkey_dsa_raw (key, i, &p,
1388 &q, &g, &y, &x);
1389 if (ret < 0)
1390 fprintf (stderr, "Error in key DSA data export: %s\n",
1391 gnutls_strerror (ret));
1392 else
1393 print_dsa_pkey (&x, &y, &p, &q, &g);
1396 fprintf (outfile, "\n");
1398 size = sizeof (buffer);
1399 if (i == -1)
1400 ret = gnutls_openpgp_privkey_get_key_id (key, keyid);
1401 else
1402 ret = gnutls_openpgp_privkey_get_subkey_id (key, i, keyid);
1404 if (ret < 0)
1406 fprintf (stderr, "Error in key id calculation: %s\n",
1407 gnutls_strerror (ret));
1409 else
1411 fprintf (outfile, "Public Key ID: %s\n", raw_to_string (keyid, 8));
1416 size = sizeof (buffer);
1417 ret = gnutls_openpgp_privkey_export (key, GNUTLS_OPENPGP_FMT_BASE64,
1418 NULL, 0, buffer, &size);
1419 if (ret < 0)
1420 error (EXIT_FAILURE, 0, "export error: %s", gnutls_strerror (ret));
1422 fprintf (outfile, "\n%s\n", buffer);
1424 gnutls_openpgp_privkey_deinit (key);
1427 void
1428 pgp_ring_info (void)
1430 gnutls_openpgp_keyring_t ring;
1431 gnutls_openpgp_crt_t crt;
1432 size_t size;
1433 int ret, i, count;
1434 gnutls_datum_t pem;
1436 pem.data = fread_file (infile, &size);
1437 pem.size = size;
1439 ret = gnutls_openpgp_keyring_init (&ring);
1440 if (ret < 0)
1441 error (EXIT_FAILURE, 0, "openpgp_keyring_init: %s",
1442 gnutls_strerror (ret));
1444 ret = gnutls_openpgp_keyring_import (ring, &pem, info.incert_format);
1446 if (ret < 0)
1447 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (ret));
1449 free (pem.data);
1451 count = gnutls_openpgp_keyring_get_crt_count (ring);
1452 if (count > 0)
1453 fprintf (outfile, "Keyring contains %d OpenPGP certificates\n\n", count);
1454 else
1455 error (EXIT_FAILURE, 0, "keyring error: %s", gnutls_strerror (count));
1457 for (i = 0; i < count; i++)
1459 ret = gnutls_openpgp_keyring_get_crt (ring, i, &crt);
1460 if (ret < 0)
1461 error (EXIT_FAILURE, 0, "export error: %s", gnutls_strerror (ret));
1463 size = sizeof (buffer);
1464 ret = gnutls_openpgp_crt_export (crt, info.outcert_format,
1465 buffer, &size);
1466 if (ret < 0)
1467 error (EXIT_FAILURE, 0, "export error: %s", gnutls_strerror (ret));
1469 fwrite (buffer, 1, size, outfile);
1470 fprintf (outfile, "\n\n");
1472 gnutls_openpgp_crt_deinit (crt);
1477 gnutls_openpgp_keyring_deinit (ring);
1481 #endif
1483 static void
1484 print_hex_datum (gnutls_datum_t * dat)
1486 unsigned int j;
1487 #define SPACE "\t"
1488 fprintf (outfile, "\n" SPACE);
1489 for (j = 0; j < dat->size; j++)
1491 fprintf (outfile, "%.2x:", (unsigned char) dat->data[j]);
1492 if ((j + 1) % 15 == 0)
1493 fprintf (outfile, "\n" SPACE);
1495 fprintf (outfile, "\n");
1499 static void
1500 print_certificate_info (gnutls_x509_crt_t crt, FILE * out, unsigned int all)
1502 gnutls_datum_t cinfo;
1503 int ret;
1505 if (all)
1506 ret = gnutls_x509_crt_print (crt, GNUTLS_CRT_PRINT_FULL, &cinfo);
1507 else
1508 ret = gnutls_x509_crt_print (crt, GNUTLS_CRT_PRINT_UNSIGNED_FULL, &cinfo);
1509 if (ret == 0)
1511 fprintf (out, "%s\n", cinfo.data);
1512 gnutls_free (cinfo.data);
1515 if (out == stderr && batch == 0) /* interactive */
1516 if (read_yesno ("Is the above information ok? (Y/N): ") == 0)
1518 exit (1);
1522 static void
1523 print_crl_info (gnutls_x509_crl_t crl, FILE * out)
1525 gnutls_datum_t cinfo;
1526 int ret;
1527 size_t size;
1529 ret = gnutls_x509_crl_print (crl, GNUTLS_CRT_PRINT_FULL, &cinfo);
1530 if (ret < 0)
1531 error (EXIT_FAILURE, 0, "crl_print: %s", gnutls_strerror (ret));
1533 fprintf (out, "%s\n", cinfo.data);
1535 gnutls_free (cinfo.data);
1537 size = sizeof (buffer);
1538 ret = gnutls_x509_crl_export (crl, GNUTLS_X509_FMT_PEM, buffer, &size);
1539 if (ret < 0)
1540 error (EXIT_FAILURE, 0, "crl_export: %s", gnutls_strerror (ret));
1542 fwrite (buffer, 1, size, outfile);
1545 void
1546 crl_info (void)
1548 gnutls_x509_crl_t crl;
1549 int ret;
1550 size_t size;
1551 gnutls_datum_t pem;
1553 ret = gnutls_x509_crl_init (&crl);
1554 if (ret < 0)
1555 error (EXIT_FAILURE, 0, "crl_init: %s", gnutls_strerror (ret));
1557 pem.data = fread_file (infile, &size);
1558 pem.size = size;
1560 if (!pem.data)
1561 error (EXIT_FAILURE, errno, "%s", info.infile ? info.infile :
1562 "standard input");
1564 ret = gnutls_x509_crl_import (crl, &pem, info.incert_format);
1566 free (pem.data);
1567 if (ret < 0)
1568 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (ret));
1570 print_crl_info (crl, outfile);
1572 gnutls_x509_crl_deinit (crl);
1575 static void
1576 print_crq_info (gnutls_x509_crq_t crq, FILE * out)
1578 gnutls_datum_t cinfo;
1579 int ret;
1580 size_t size;
1582 if (info.outcert_format == GNUTLS_X509_FMT_PEM)
1584 ret = gnutls_x509_crq_print (crq, GNUTLS_CRT_PRINT_FULL, &cinfo);
1585 if (ret < 0)
1586 error (EXIT_FAILURE, 0, "crq_print: %s", gnutls_strerror (ret));
1588 fprintf (out, "%s\n", cinfo.data);
1590 gnutls_free (cinfo.data);
1593 size = sizeof (buffer);
1594 ret = gnutls_x509_crq_export (crq, info.outcert_format, buffer, &size);
1595 if (ret < 0)
1596 error (EXIT_FAILURE, 0, "crq_export: %s", gnutls_strerror (ret));
1598 fwrite (buffer, 1, size, outfile);
1601 void
1602 crq_info (void)
1604 gnutls_x509_crq_t crq;
1605 int ret;
1606 size_t size;
1607 gnutls_datum_t pem;
1609 ret = gnutls_x509_crq_init (&crq);
1610 if (ret < 0)
1611 error (EXIT_FAILURE, 0, "crq_init: %s", gnutls_strerror (ret));
1613 pem.data = fread_file (infile, &size);
1614 pem.size = size;
1616 if (!pem.data)
1617 error (EXIT_FAILURE, errno, "%s", info.infile ? info.infile :
1618 "standard input");
1620 ret = gnutls_x509_crq_import (crq, &pem, info.incert_format);
1622 free (pem.data);
1623 if (ret < 0)
1624 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (ret));
1626 print_crq_info (crq, outfile);
1628 gnutls_x509_crq_deinit (crq);
1631 void
1632 privkey_info (void)
1634 gnutls_x509_privkey_t key;
1635 size_t size;
1636 int ret;
1637 gnutls_datum_t pem;
1638 const char *cprint;
1639 const char *pass;
1641 size = fread (buffer, 1, sizeof (buffer) - 1, infile);
1642 buffer[size] = 0;
1644 gnutls_x509_privkey_init (&key);
1646 pem.data = buffer;
1647 pem.size = size;
1649 ret = 0;
1650 if (!info.pkcs8)
1651 ret = gnutls_x509_privkey_import (key, &pem, info.incert_format);
1653 /* If we failed to import the certificate previously try PKCS #8 */
1654 if (info.pkcs8 || ret == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR)
1656 /* first try to import the key without asking any password */
1657 ret = gnutls_x509_privkey_import_pkcs8 (key, &pem,
1658 info.incert_format,
1659 NULL, GNUTLS_PKCS_PLAIN);
1660 if (ret < 0)
1662 if (info.pass)
1663 pass = info.pass;
1664 else
1665 pass = get_pass ();
1666 ret = gnutls_x509_privkey_import_pkcs8 (key, &pem,
1667 info.incert_format,
1668 pass, 0);
1671 if (ret < 0)
1672 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (ret));
1674 /* Public key algorithm
1676 fprintf (outfile, "Public Key Info:\n");
1677 ret = gnutls_x509_privkey_get_pk_algorithm (key);
1678 fprintf (outfile, "\tPublic Key Algorithm: ");
1680 cprint = gnutls_pk_algorithm_get_name (ret);
1681 fprintf (outfile, "%s\n", cprint ? cprint : "Unknown");
1682 fprintf (outfile, "\tKey Security Level: %s\n", gnutls_sec_param_get_name(gnutls_x509_privkey_sec_param(key)));
1684 /* Print the raw public and private keys
1686 if (ret == GNUTLS_PK_RSA)
1688 gnutls_datum_t m, e, d, p, q, u, exp1, exp2;
1690 ret = gnutls_x509_privkey_export_rsa_raw2 (key, &m, &e, &d, &p, &q, &u, &exp1, &exp2);
1691 if (ret < 0)
1692 fprintf (stderr, "Error in key RSA data export: %s\n",
1693 gnutls_strerror (ret));
1694 else
1696 print_rsa_pkey (&m, &e, &d, &p, &q, &u, &exp1, &exp2);
1697 gnutls_free (m.data);
1698 gnutls_free (e.data);
1699 gnutls_free (d.data);
1700 gnutls_free (p.data);
1701 gnutls_free (q.data);
1702 gnutls_free (u.data);
1703 gnutls_free (exp1.data);
1704 gnutls_free (exp2.data);
1707 else if (ret == GNUTLS_PK_DSA)
1709 gnutls_datum_t p, q, g, y, x;
1711 ret = gnutls_x509_privkey_export_dsa_raw (key, &p, &q, &g, &y, &x);
1712 if (ret < 0)
1713 fprintf (stderr, "Error in key DSA data export: %s\n",
1714 gnutls_strerror (ret));
1715 else
1717 print_dsa_pkey (&x, &y, &p, &q, &g);
1718 gnutls_free (x.data);
1719 gnutls_free (y.data);
1720 gnutls_free (p.data);
1721 gnutls_free (q.data);
1722 gnutls_free (g.data);
1726 fprintf (outfile, "\n");
1728 size = sizeof (buffer);
1729 if ((ret = gnutls_x509_privkey_get_key_id (key, 0, buffer, &size)) < 0)
1731 fprintf (stderr, "Error in key id calculation: %s\n",
1732 gnutls_strerror (ret));
1734 else
1736 fprintf (outfile, "Public Key ID: %s\n", raw_to_string (buffer, size));
1739 if (info.fix_key != 0)
1741 ret = gnutls_x509_privkey_fix (key);
1742 if (ret < 0)
1743 error (EXIT_FAILURE, 0, "privkey_fix: %s", gnutls_strerror (ret));
1746 size = sizeof (buffer);
1747 ret = gnutls_x509_privkey_export (key, GNUTLS_X509_FMT_PEM, buffer, &size);
1748 if (ret < 0)
1749 error (EXIT_FAILURE, 0, "export error: %s", gnutls_strerror (ret));
1751 fprintf (outfile, "\n%s\n", buffer);
1753 gnutls_x509_privkey_deinit (key);
1756 /* Load a public key.
1757 * @mand should be non zero if it is required to read a public key.
1759 gnutls_pubkey_t
1760 load_pubkey (int mand)
1762 gnutls_pubkey_t key;
1763 int ret;
1764 gnutls_datum_t dat;
1765 size_t size;
1767 if (!info.pubkey && !mand)
1768 return NULL;
1770 if (info.pubkey == NULL)
1771 error (EXIT_FAILURE, 0, "missing --load-pubkey");
1773 ret = gnutls_pubkey_init (&key);
1774 if (ret < 0)
1775 error (EXIT_FAILURE, 0, "privkey_init: %s", gnutls_strerror (ret));
1777 dat.data = read_binary_file (info.pubkey, &size);
1778 dat.size = size;
1780 if (!dat.data)
1781 error (EXIT_FAILURE, errno, "reading --load-pubkey: %s", info.pubkey);
1783 ret = gnutls_pubkey_import (key, &dat, info.incert_format);
1785 free (dat.data);
1787 if (ret == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR)
1789 error (EXIT_FAILURE, 0,
1790 "import error: could not find a valid PEM header; "
1791 "check if your key has the PUBLIC KEY header");
1794 if (ret < 0)
1795 error (EXIT_FAILURE, 0, "importing --load-pubkey: %s: %s",
1796 info.pubkey, gnutls_strerror (ret));
1798 return key;
1802 /* Load the private key.
1803 * @mand should be non zero if it is required to read a private key.
1805 gnutls_x509_privkey_t
1806 load_private_key (int mand)
1808 gnutls_x509_privkey_t key;
1809 int ret;
1810 gnutls_datum_t dat;
1811 size_t size;
1813 if (!info.privkey && !mand)
1814 return NULL;
1816 if (info.privkey == NULL)
1817 error (EXIT_FAILURE, 0, "missing --load-privkey");
1819 ret = gnutls_x509_privkey_init (&key);
1820 if (ret < 0)
1821 error (EXIT_FAILURE, 0, "privkey_init: %s", gnutls_strerror (ret));
1823 dat.data = read_binary_file (info.privkey, &size);
1824 dat.size = size;
1826 if (!dat.data)
1827 error (EXIT_FAILURE, errno, "reading --load-privkey: %s", info.privkey);
1829 if (info.pkcs8)
1831 const char *pass = get_pass ();
1832 ret =
1833 gnutls_x509_privkey_import_pkcs8 (key, &dat, info.incert_format,
1834 pass, 0);
1836 else
1837 ret = gnutls_x509_privkey_import (key, &dat, info.incert_format);
1839 free (dat.data);
1841 if (ret == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR)
1843 error (EXIT_FAILURE, 0,
1844 "import error: could not find a valid PEM header; "
1845 "check if your key is PKCS #8 or PKCS #12 encoded");
1848 if (ret < 0)
1849 error (EXIT_FAILURE, 0, "importing --load-privkey: %s: %s",
1850 info.privkey, gnutls_strerror (ret));
1852 return key;
1855 /* Load the Certificate Request.
1857 gnutls_x509_crq_t
1858 load_request (void)
1860 gnutls_x509_crq_t crq;
1861 int ret;
1862 gnutls_datum_t dat;
1863 size_t size;
1865 if (!info.request)
1866 return NULL;
1868 ret = gnutls_x509_crq_init (&crq);
1869 if (ret < 0)
1870 error (EXIT_FAILURE, 0, "crq_init: %s", gnutls_strerror (ret));
1872 dat.data = read_binary_file (info.request, &size);
1873 dat.size = size;
1875 if (!dat.data)
1876 error (EXIT_FAILURE, errno, "reading --load-request: %s", info.request);
1878 ret = gnutls_x509_crq_import (crq, &dat, info.incert_format);
1879 if (ret == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR)
1881 error (EXIT_FAILURE, 0,
1882 "import error: could not find a valid PEM header");
1885 free (dat.data);
1886 if (ret < 0)
1887 error (EXIT_FAILURE, 0, "importing --load-request: %s: %s",
1888 info.request, gnutls_strerror (ret));
1890 return crq;
1893 /* Load the CA's private key.
1895 gnutls_x509_privkey_t
1896 load_ca_private_key (void)
1898 gnutls_x509_privkey_t key;
1899 int ret;
1900 gnutls_datum_t dat;
1901 size_t size;
1903 if (info.ca_privkey == NULL)
1904 error (EXIT_FAILURE, 0, "missing --load-ca-privkey");
1906 ret = gnutls_x509_privkey_init (&key);
1907 if (ret < 0)
1908 error (EXIT_FAILURE, 0, "privkey_init: %s", gnutls_strerror (ret));
1910 dat.data = read_binary_file (info.ca_privkey, &size);
1911 dat.size = size;
1913 if (!dat.data)
1914 error (EXIT_FAILURE, errno, "reading --load-ca-privkey: %s",
1915 info.ca_privkey);
1917 if (info.pkcs8)
1919 const char *pass = get_pass ();
1920 ret =
1921 gnutls_x509_privkey_import_pkcs8 (key, &dat, info.incert_format,
1922 pass, 0);
1924 else
1925 ret = gnutls_x509_privkey_import (key, &dat, info.incert_format);
1926 free (dat.data);
1927 if (ret < 0)
1928 error (EXIT_FAILURE, 0, "importing --load-ca-privkey: %s: %s",
1929 info.ca_privkey, gnutls_strerror (ret));
1931 return key;
1934 /* Loads the CA's certificate
1936 gnutls_x509_crt_t
1937 load_ca_cert (void)
1939 gnutls_x509_crt_t crt;
1940 int ret;
1941 gnutls_datum_t dat;
1942 size_t size;
1944 if (info.ca == NULL)
1945 error (EXIT_FAILURE, 0, "missing --load-ca-certificate");
1947 ret = gnutls_x509_crt_init (&crt);
1948 if (ret < 0)
1949 error (EXIT_FAILURE, 0, "crt_init: %s", gnutls_strerror (ret));
1951 dat.data = read_binary_file (info.ca, &size);
1952 dat.size = size;
1954 if (!dat.data)
1955 error (EXIT_FAILURE, errno, "reading --load-ca-certificate: %s", info.ca);
1957 ret = gnutls_x509_crt_import (crt, &dat, info.incert_format);
1958 free (dat.data);
1959 if (ret < 0)
1960 error (EXIT_FAILURE, 0, "importing --load-ca-certificate: %s: %s",
1961 info.ca, gnutls_strerror (ret));
1963 return crt;
1966 /* Loads the certificate
1967 * If mand is non zero then a certificate is mandatory. Otherwise
1968 * null will be returned if the certificate loading fails.
1970 gnutls_x509_crt_t
1971 load_cert (int mand)
1973 gnutls_x509_crt_t *crt;
1974 size_t size;
1976 crt = load_cert_list (mand, &size);
1978 return crt ? crt[0] : NULL;
1981 #define MAX_CERTS 256
1983 /* Loads a certificate list
1985 gnutls_x509_crt_t *
1986 load_cert_list (int mand, size_t * crt_size)
1988 FILE *fd;
1989 static gnutls_x509_crt_t crt[MAX_CERTS];
1990 char *ptr;
1991 int ret, i;
1992 gnutls_datum_t dat;
1993 size_t size;
1994 int ptr_size;
1996 *crt_size = 0;
1997 fprintf (stderr, "Loading certificate list...\n");
1999 if (info.cert == NULL)
2001 if (mand)
2002 error (EXIT_FAILURE, 0, "missing --load-certificate");
2003 else
2004 return NULL;
2007 fd = fopen (info.cert, "r");
2008 if (fd == NULL)
2009 error (EXIT_FAILURE, errno, "%s", info.cert);
2011 size = fread (buffer, 1, sizeof (buffer) - 1, fd);
2012 buffer[size] = 0;
2014 fclose (fd);
2016 ptr = buffer;
2017 ptr_size = size;
2019 for (i = 0; i < MAX_CERTS; i++)
2021 ret = gnutls_x509_crt_init (&crt[i]);
2022 if (ret < 0)
2023 error (EXIT_FAILURE, 0, "crt_init: %s", gnutls_strerror (ret));
2025 dat.data = ptr;
2026 dat.size = ptr_size;
2028 ret = gnutls_x509_crt_import (crt[i], &dat, info.incert_format);
2029 if (ret < 0 && *crt_size > 0)
2030 break;
2031 if (ret < 0)
2032 error (EXIT_FAILURE, 0, "crt_import: %s", gnutls_strerror (ret));
2034 ptr = strstr (ptr, "---END");
2035 if (ptr == NULL)
2036 break;
2037 ptr++;
2039 ptr_size = size;
2040 ptr_size -=
2041 (unsigned int) ((unsigned char *) ptr - (unsigned char *) buffer);
2043 if (ptr_size < 0)
2044 break;
2046 (*crt_size)++;
2048 fprintf (stderr, "Loaded %d certificates.\n", (int) *crt_size);
2050 return crt;
2054 /* Generate a PKCS #10 certificate request.
2056 void
2057 generate_request (void)
2059 gnutls_x509_crq_t crq;
2060 gnutls_x509_privkey_t key;
2061 int ret, ca_status, path_len;
2062 const char *pass;
2063 unsigned int usage = 0;
2065 fprintf (stderr, "Generating a PKCS #10 certificate request...\n");
2067 ret = gnutls_x509_crq_init (&crq);
2068 if (ret < 0)
2069 error (EXIT_FAILURE, 0, "crq_init: %s", gnutls_strerror (ret));
2071 /* Load the private key.
2073 key = load_private_key (0);
2074 if (!key)
2076 key = generate_private_key_int ();
2078 print_private_key (key);
2081 /* Set the DN.
2083 get_country_crq_set (crq);
2084 get_organization_crq_set (crq);
2085 get_unit_crq_set (crq);
2086 get_locality_crq_set (crq);
2087 get_state_crq_set (crq);
2088 get_cn_crq_set (crq);
2089 get_uid_crq_set (crq);
2090 get_oid_crq_set (crq);
2092 get_dns_name_set (TYPE_CRQ, crq);
2093 get_ip_addr_set (TYPE_CRQ, crq);
2094 get_email_set (TYPE_CRQ, crq);
2096 pass = get_challenge_pass ();
2098 if (pass != NULL && pass[0] != 0)
2100 ret = gnutls_x509_crq_set_challenge_password (crq, pass);
2101 if (ret < 0)
2102 error (EXIT_FAILURE, 0, "set_pass: %s", gnutls_strerror (ret));
2105 if (info.crq_extensions != 0)
2107 ca_status = get_ca_status ();
2108 if (ca_status)
2109 path_len = get_path_len ();
2110 else
2111 path_len = -1;
2113 ret = gnutls_x509_crq_set_basic_constraints (crq, ca_status, path_len);
2114 if (ret < 0)
2115 error (EXIT_FAILURE, 0, "set_basic_constraints: %s",
2116 gnutls_strerror (ret));
2118 ret = get_sign_status (1);
2119 if (ret)
2120 usage |= GNUTLS_KEY_DIGITAL_SIGNATURE;
2122 ret = get_encrypt_status (1);
2123 if (ret)
2124 usage |= GNUTLS_KEY_KEY_ENCIPHERMENT;
2125 else
2126 usage |= GNUTLS_KEY_DIGITAL_SIGNATURE;
2128 if (ca_status)
2130 ret = get_cert_sign_status ();
2131 if (ret)
2132 usage |= GNUTLS_KEY_KEY_CERT_SIGN;
2134 ret = get_crl_sign_status ();
2135 if (ret)
2136 usage |= GNUTLS_KEY_CRL_SIGN;
2138 ret = get_code_sign_status ();
2139 if (ret)
2141 ret = gnutls_x509_crq_set_key_purpose_oid
2142 (crq, GNUTLS_KP_CODE_SIGNING, 0);
2143 if (ret < 0)
2144 error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (ret));
2147 ret = get_ocsp_sign_status ();
2148 if (ret)
2150 ret = gnutls_x509_crq_set_key_purpose_oid
2151 (crq, GNUTLS_KP_OCSP_SIGNING, 0);
2152 if (ret < 0)
2153 error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (ret));
2156 ret = get_time_stamp_status ();
2157 if (ret)
2159 ret = gnutls_x509_crq_set_key_purpose_oid
2160 (crq, GNUTLS_KP_TIME_STAMPING, 0);
2161 if (ret < 0)
2162 error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (ret));
2166 ret = gnutls_x509_crq_set_key_usage (crq, usage);
2167 if (ret < 0)
2168 error (EXIT_FAILURE, 0, "key_usage: %s", gnutls_strerror (ret));
2170 ret = get_tls_client_status ();
2171 if (ret != 0)
2173 ret = gnutls_x509_crq_set_key_purpose_oid
2174 (crq, GNUTLS_KP_TLS_WWW_CLIENT, 0);
2175 if (ret < 0)
2176 error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (ret));
2179 ret = get_tls_server_status ();
2180 if (ret != 0)
2182 ret = gnutls_x509_crq_set_key_purpose_oid
2183 (crq, GNUTLS_KP_TLS_WWW_SERVER, 0);
2184 if (ret < 0)
2185 error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (ret));
2189 ret = gnutls_x509_crq_set_key (crq, key);
2190 if (ret < 0)
2191 error (EXIT_FAILURE, 0, "set_key: %s", gnutls_strerror (ret));
2193 ret = gnutls_x509_crq_sign (crq, key);
2194 if (ret < 0)
2195 error (EXIT_FAILURE, 0, "sign: %s", gnutls_strerror (ret));
2197 print_crq_info (crq, outfile);
2199 gnutls_x509_crq_deinit (crq);
2200 gnutls_x509_privkey_deinit (key);
2204 static void print_verification_res (gnutls_x509_crt_t crt,
2205 gnutls_x509_crt_t issuer,
2206 gnutls_x509_crl_t * crl_list,
2207 int crl_list_size, unsigned int flags);
2209 #define CERT_SEP "-----BEGIN CERT"
2210 #define CRL_SEP "-----BEGIN X509 CRL"
2211 static int
2212 _verify_x509_mem (const void *cert, int cert_size)
2214 const char *ptr;
2215 int ret, i;
2216 char name[256];
2217 char issuer_name[256];
2218 size_t name_size;
2219 size_t issuer_name_size;
2220 gnutls_datum_t tmp;
2221 gnutls_x509_crt_t *x509_cert_list = NULL;
2222 gnutls_x509_crl_t *x509_crl_list = NULL;
2223 int x509_ncerts, x509_ncrls;
2226 /* Decode the CA certificate
2229 /* Decode the CRL list
2231 ptr = cert;
2233 i = 1;
2235 if (strstr (ptr, CRL_SEP) != NULL) /* if CRLs exist */
2238 x509_crl_list =
2239 (gnutls_x509_crl_t *) realloc (x509_crl_list,
2240 i * sizeof (gnutls_x509_crl_t));
2241 if (x509_crl_list == NULL)
2242 error (EXIT_FAILURE, 0, "memory error");
2244 tmp.data = (char *) ptr;
2245 tmp.size = cert_size;
2246 tmp.size -=
2247 (unsigned int) ((unsigned char *) ptr - (unsigned char *) cert);
2249 ret = gnutls_x509_crl_init (&x509_crl_list[i - 1]);
2250 if (ret < 0)
2251 error (EXIT_FAILURE, 0, "error parsing CRL[%d]: %s", i,
2252 gnutls_strerror (ret));
2254 ret = gnutls_x509_crl_import (x509_crl_list[i - 1], &tmp,
2255 GNUTLS_X509_FMT_PEM);
2256 if (ret < 0)
2257 error (EXIT_FAILURE, 0, "error parsing CRL[%d]: %s", i,
2258 gnutls_strerror (ret));
2260 /* now we move ptr after the pem header */
2261 ptr = strstr (ptr, CRL_SEP);
2262 if (ptr != NULL)
2263 ptr++;
2265 i++;
2267 while ((ptr = strstr (ptr, CRL_SEP)) != NULL);
2269 x509_ncrls = i - 1;
2272 /* Decode the certificate chain.
2274 ptr = cert;
2276 i = 1;
2280 x509_cert_list =
2281 (gnutls_x509_crt_t *) realloc (x509_cert_list,
2282 i * sizeof (gnutls_x509_crt_t));
2283 if (x509_cert_list == NULL)
2284 error (EXIT_FAILURE, 0, "memory error");
2287 tmp.data = (char *) ptr;
2288 tmp.size = cert_size;
2289 tmp.size -=
2290 (unsigned int) ((unsigned char *) ptr - (unsigned char *) cert);
2292 ret = gnutls_x509_crt_init (&x509_cert_list[i - 1]);
2293 if (ret < 0)
2294 error (EXIT_FAILURE, 0, "error parsing certificate[%d]: %s", i,
2295 gnutls_strerror (ret));
2297 ret =
2298 gnutls_x509_crt_import (x509_cert_list[i - 1], &tmp,
2299 GNUTLS_X509_FMT_PEM);
2300 if (ret < 0)
2301 error (EXIT_FAILURE, 0, "error parsing certificate[%d]: %s", i,
2302 gnutls_strerror (ret));
2305 if (i - 1 != 0)
2307 /* verify the previous certificate using this one
2308 * as CA.
2311 name_size = sizeof (name);
2312 ret =
2313 gnutls_x509_crt_get_dn (x509_cert_list[i - 2], name, &name_size);
2314 if (ret < 0)
2315 error (EXIT_FAILURE, 0, "get_dn: %s", gnutls_strerror (ret));
2317 fprintf (outfile, "Certificate[%d]: %s\n", i - 2, name);
2319 /* print issuer
2321 issuer_name_size = sizeof (issuer_name);
2322 ret =
2323 gnutls_x509_crt_get_issuer_dn (x509_cert_list[i - 2],
2324 issuer_name, &issuer_name_size);
2325 if (ret < 0)
2326 error (EXIT_FAILURE, 0, "get_issuer_dn: %s",
2327 gnutls_strerror (ret));
2329 fprintf (outfile, "\tIssued by: %s\n", issuer_name);
2331 /* Get the Issuer's name
2333 name_size = sizeof (name);
2334 ret =
2335 gnutls_x509_crt_get_dn (x509_cert_list[i - 1], name, &name_size);
2336 if (ret < 0)
2337 error (EXIT_FAILURE, 0, "get_dn: %s", gnutls_strerror (ret));
2339 fprintf (outfile, "\tVerifying against certificate[%d].\n", i - 1);
2341 if (strcmp (issuer_name, name) != 0)
2343 fprintf (stderr, "Error: Issuer's name: %s\n", name);
2344 error (EXIT_FAILURE, 0,
2345 "issuer name does not match the next certificate");
2348 fprintf (outfile, "\tVerification output: ");
2349 print_verification_res (x509_cert_list[i - 2],
2350 x509_cert_list[i - 1], x509_crl_list,
2351 x509_ncrls,
2352 GNUTLS_VERIFY_DO_NOT_ALLOW_SAME);
2353 fprintf (outfile, ".\n\n");
2358 /* now we move ptr after the pem header
2360 ptr = strstr (ptr, CERT_SEP);
2361 if (ptr != NULL)
2362 ptr++;
2364 i++;
2366 while ((ptr = strstr (ptr, CERT_SEP)) != NULL);
2368 x509_ncerts = i - 1;
2370 /* The last certificate in the list will be used as
2371 * a CA (should be self signed).
2373 name_size = sizeof (name);
2374 ret = gnutls_x509_crt_get_dn (x509_cert_list[x509_ncerts - 1], name,
2375 &name_size);
2376 if (ret < 0)
2377 error (EXIT_FAILURE, 0, "get_dn: %s", gnutls_strerror (ret));
2379 fprintf (outfile, "Certificate[%d]: %s\n", x509_ncerts - 1, name);
2381 /* print issuer
2383 issuer_name_size = sizeof (issuer_name);
2384 ret =
2385 gnutls_x509_crt_get_issuer_dn (x509_cert_list[x509_ncerts - 1],
2386 issuer_name, &issuer_name_size);
2387 if (ret < 0)
2388 error (EXIT_FAILURE, 0, "get_issuer_dn: %s", gnutls_strerror (ret));
2390 fprintf (outfile, "\tIssued by: %s\n", name);
2392 if (strcmp (issuer_name, name) != 0)
2393 error (EXIT_FAILURE, 0, "the last certificate is not self signed");
2395 fprintf (outfile, "\tVerification output: ");
2396 print_verification_res (x509_cert_list[x509_ncerts - 1],
2397 x509_cert_list[x509_ncerts - 1], x509_crl_list,
2398 /* we add GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT since it is
2399 * self signed. */
2400 x509_ncrls,
2401 GNUTLS_VERIFY_DO_NOT_ALLOW_SAME |
2402 GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT);
2404 fprintf (outfile, ".\n\n");
2406 /* Verify using internal algorithm too. */
2408 int verify_status;
2410 ret = gnutls_x509_crt_list_verify (x509_cert_list, x509_ncerts,
2411 &x509_cert_list[x509_ncerts - 1], 1,
2412 x509_crl_list,
2413 x509_ncrls,
2414 GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT |
2415 GNUTLS_VERIFY_DO_NOT_ALLOW_SAME,
2416 &verify_status);
2417 if (ret < 0)
2418 error (EXIT_FAILURE, 0, "gnutls_x509_crt_list_verify: %s",
2419 gnutls_strerror (ret));
2421 fprintf (outfile, "Chain verification output: ");
2423 if (verify_status & GNUTLS_CERT_INVALID)
2425 fprintf (outfile, "Not verified");
2427 else
2429 fprintf (outfile, "Verified");
2432 if (verify_status & GNUTLS_CERT_SIGNER_NOT_CA)
2434 fprintf (outfile, ", ");
2435 fprintf (outfile, "Issuer is not a CA");
2438 if (verify_status & GNUTLS_CERT_INSECURE_ALGORITHM)
2440 fprintf (outfile, ", ");
2441 fprintf (outfile, "Insecure algorithm");
2444 fprintf (outfile, ".\n");
2447 for (i = 0; i < x509_ncerts; i++)
2448 gnutls_x509_crt_deinit (x509_cert_list[i]);
2450 for (i = 0; i < x509_ncrls; i++)
2451 gnutls_x509_crl_deinit (x509_crl_list[i]);
2453 free (x509_cert_list);
2454 free (x509_crl_list);
2456 if (ret < 0)
2457 error (EXIT_FAILURE, 0, "verification error: %s", gnutls_strerror (ret));
2459 return 0;
2462 static void
2463 print_verification_res (gnutls_x509_crt_t crt,
2464 gnutls_x509_crt_t issuer,
2465 gnutls_x509_crl_t * crl_list, int crl_list_size,
2466 unsigned int flags)
2468 unsigned int output;
2469 int comma = 0;
2470 int ret;
2472 ret = gnutls_x509_crt_verify (crt, &issuer, 1, flags, &output);
2473 if (ret < 0)
2474 error (EXIT_FAILURE, 0, "verification error: %s", gnutls_strerror (ret));
2476 if (output & GNUTLS_CERT_INVALID)
2478 fprintf (outfile, "Not verified");
2479 comma = 1;
2481 else
2483 fprintf (outfile, "Verified");
2484 comma = 1;
2487 if (output & GNUTLS_CERT_SIGNER_NOT_CA)
2489 if (comma)
2490 fprintf (outfile, ", ");
2491 fprintf (outfile, "Issuer is not a CA");
2492 comma = 1;
2495 if (output & GNUTLS_CERT_INSECURE_ALGORITHM)
2497 if (comma)
2498 fprintf (outfile, ", ");
2499 fprintf (outfile, "Insecure algorithm");
2500 comma = 1;
2503 if (output & GNUTLS_CERT_NOT_ACTIVATED)
2505 if (comma)
2506 fprintf (outfile, ", ");
2507 fprintf (outfile, "Not activated");
2508 comma = 1;
2511 if (output & GNUTLS_CERT_EXPIRED)
2513 if (comma)
2514 fprintf (outfile, ", ");
2515 fprintf (outfile, "Expired");
2516 comma = 1;
2519 ret = gnutls_x509_crt_check_revocation (crt, crl_list, crl_list_size);
2520 if (ret < 0)
2521 error (EXIT_FAILURE, 0, "revocation check: %s", gnutls_strerror (ret));
2523 if (ret == 1)
2524 { /* revoked */
2525 if (comma)
2526 fprintf (outfile, ", ");
2527 comma = 1;
2528 fprintf (outfile, "Revoked");
2532 void
2533 verify_chain (void)
2535 char *buf;
2536 size_t size;
2538 buf = fread_file (infile, &size);
2539 if (buf == NULL)
2540 error (EXIT_FAILURE, errno, "reading chain");
2542 buf[size] = 0;
2544 _verify_x509_mem (buf, size);
2548 void
2549 verify_crl (void)
2551 size_t size, dn_size;
2552 char dn[128];
2553 unsigned int output;
2554 int comma = 0;
2555 int ret;
2556 gnutls_datum_t pem;
2557 gnutls_x509_crl_t crl;
2558 time_t now = time (0);
2559 gnutls_x509_crt_t issuer;
2561 issuer = load_ca_cert ();
2563 fprintf (outfile, "\nCA certificate:\n");
2565 dn_size = sizeof (dn);
2566 ret = gnutls_x509_crt_get_dn (issuer, dn, &dn_size);
2567 if (ret < 0)
2568 error (EXIT_FAILURE, 0, "crt_get_dn: %s", gnutls_strerror (ret));
2570 fprintf (outfile, "\tSubject: %s\n\n", dn);
2572 ret = gnutls_x509_crl_init (&crl);
2573 if (ret < 0)
2574 error (EXIT_FAILURE, 0, "crl_init: %s", gnutls_strerror (ret));
2576 pem.data = fread_file (infile, &size);
2577 pem.size = size;
2579 ret = gnutls_x509_crl_import (crl, &pem, info.incert_format);
2580 free (pem.data);
2581 if (ret < 0)
2582 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (ret));
2584 print_crl_info (crl, outfile);
2586 fprintf (outfile, "Verification output: ");
2587 ret = gnutls_x509_crl_verify (crl, &issuer, 1, 0, &output);
2588 if (ret < 0)
2589 error (EXIT_FAILURE, 0, "verification error: %s", gnutls_strerror (ret));
2591 if (output & GNUTLS_CERT_INVALID)
2593 fprintf (outfile, "Not verified");
2594 comma = 1;
2596 else
2598 fprintf (outfile, "Verified");
2599 comma = 1;
2602 if (output & GNUTLS_CERT_SIGNER_NOT_CA)
2604 if (comma)
2605 fprintf (outfile, ", ");
2606 fprintf (outfile, "Issuer is not a CA");
2607 comma = 1;
2610 if (output & GNUTLS_CERT_INSECURE_ALGORITHM)
2612 if (comma)
2613 fprintf (outfile, ", ");
2614 fprintf (outfile, "Insecure algorithm");
2615 comma = 1;
2618 /* Check expiration dates.
2621 if (gnutls_x509_crl_get_this_update (crl) > now)
2623 if (comma)
2624 fprintf (outfile, ", ");
2625 comma = 1;
2626 fprintf (outfile, "Issued in the future!");
2629 if (gnutls_x509_crl_get_next_update (crl) < now)
2631 if (comma)
2632 fprintf (outfile, ", ");
2633 comma = 1;
2634 fprintf (outfile, "CRL is not up to date");
2637 fprintf (outfile, "\n");
2641 void
2642 generate_pkcs8 (void)
2644 gnutls_x509_privkey_t key;
2645 int result;
2646 size_t size;
2647 int flags = 0;
2648 const char *password;
2650 fprintf (stderr, "Generating a PKCS #8 key structure...\n");
2652 key = load_private_key (1);
2654 if (info.pass)
2655 password = info.pass;
2656 else
2657 password = get_pass ();
2659 if (info.export)
2660 flags = GNUTLS_PKCS_USE_PKCS12_RC2_40;
2661 else
2662 flags = cipher_to_flags (info.pkcs_cipher);
2664 if (password == NULL || password[0] == 0)
2666 flags = GNUTLS_PKCS_PLAIN;
2669 size = sizeof (buffer);
2670 result =
2671 gnutls_x509_privkey_export_pkcs8 (key, info.outcert_format,
2672 password, flags, buffer, &size);
2674 if (result < 0)
2675 error (EXIT_FAILURE, 0, "key_export: %s", gnutls_strerror (result));
2677 fwrite (buffer, 1, size, outfile);
2682 #include <gnutls/pkcs12.h>
2683 #include <unistd.h>
2685 void
2686 generate_pkcs12 (void)
2688 gnutls_pkcs12_t pkcs12;
2689 gnutls_x509_crt_t *crts;
2690 gnutls_x509_privkey_t key;
2691 int result;
2692 size_t size;
2693 gnutls_datum_t data;
2694 const char *pass;
2695 const char *name;
2696 unsigned int flags, i;
2697 gnutls_datum_t key_id;
2698 unsigned char _key_id[20];
2699 int indx;
2700 size_t ncrts;
2702 fprintf (stderr, "Generating a PKCS #12 structure...\n");
2704 key = load_private_key (0);
2705 crts = load_cert_list (0, &ncrts);
2707 name = get_pkcs12_key_name ();
2709 result = gnutls_pkcs12_init (&pkcs12);
2710 if (result < 0)
2711 error (EXIT_FAILURE, 0, "pkcs12_init: %s", gnutls_strerror (result));
2713 if (info.pass)
2714 pass = info.pass;
2715 else
2716 pass = get_pass ();
2718 for (i = 0; i < ncrts; i++)
2720 gnutls_pkcs12_bag_t bag;
2722 result = gnutls_pkcs12_bag_init (&bag);
2723 if (result < 0)
2724 error (EXIT_FAILURE, 0, "bag_init: %s", gnutls_strerror (result));
2726 result = gnutls_pkcs12_bag_set_crt (bag, crts[i]);
2727 if (result < 0)
2728 error (EXIT_FAILURE, 0, "set_crt[%d]: %s", i,
2729 gnutls_strerror (result));
2731 indx = result;
2733 result = gnutls_pkcs12_bag_set_friendly_name (bag, indx, name);
2734 if (result < 0)
2735 error (EXIT_FAILURE, 0, "bag_set_friendly_name: %s",
2736 gnutls_strerror (result));
2738 size = sizeof (_key_id);
2739 result = gnutls_x509_crt_get_key_id (crts[i], 0, _key_id, &size);
2740 if (result < 0)
2741 error (EXIT_FAILURE, 0, "key_id[%d]: %s", i,
2742 gnutls_strerror (result));
2744 key_id.data = _key_id;
2745 key_id.size = size;
2747 result = gnutls_pkcs12_bag_set_key_id (bag, indx, &key_id);
2748 if (result < 0)
2749 error (EXIT_FAILURE, 0, "bag_set_key_id: %s",
2750 gnutls_strerror (result));
2752 if (info.export)
2753 flags = GNUTLS_PKCS_USE_PKCS12_RC2_40;
2754 else
2755 flags = cipher_to_flags (info.pkcs_cipher);
2757 result = gnutls_pkcs12_bag_encrypt (bag, pass, flags);
2758 if (result < 0)
2759 error (EXIT_FAILURE, 0, "bag_encrypt: %s", gnutls_strerror (result));
2761 result = gnutls_pkcs12_set_bag (pkcs12, bag);
2762 if (result < 0)
2763 error (EXIT_FAILURE, 0, "set_bag: %s", gnutls_strerror (result));
2766 if (key)
2768 gnutls_pkcs12_bag_t kbag;
2770 result = gnutls_pkcs12_bag_init (&kbag);
2771 if (result < 0)
2772 error (EXIT_FAILURE, 0, "bag_init: %s", gnutls_strerror (result));
2774 if (info.export)
2775 flags = GNUTLS_PKCS_USE_PKCS12_RC2_40;
2776 else
2777 flags = cipher_to_flags (info.pkcs_cipher);
2779 size = sizeof (buffer);
2780 result =
2781 gnutls_x509_privkey_export_pkcs8 (key, GNUTLS_X509_FMT_DER,
2782 pass, flags, buffer, &size);
2783 if (result < 0)
2784 error (EXIT_FAILURE, 0, "key_export: %s", gnutls_strerror (result));
2786 data.data = buffer;
2787 data.size = size;
2788 result =
2789 gnutls_pkcs12_bag_set_data (kbag,
2790 GNUTLS_BAG_PKCS8_ENCRYPTED_KEY, &data);
2791 if (result < 0)
2792 error (EXIT_FAILURE, 0, "bag_set_data: %s", gnutls_strerror (result));
2794 indx = result;
2796 result = gnutls_pkcs12_bag_set_friendly_name (kbag, indx, name);
2797 if (result < 0)
2798 error (EXIT_FAILURE, 0, "bag_set_friendly_name: %s",
2799 gnutls_strerror (result));
2801 size = sizeof (_key_id);
2802 result = gnutls_x509_privkey_get_key_id (key, 0, _key_id, &size);
2803 if (result < 0)
2804 error (EXIT_FAILURE, 0, "key_id: %s", gnutls_strerror (result));
2806 key_id.data = _key_id;
2807 key_id.size = size;
2809 result = gnutls_pkcs12_bag_set_key_id (kbag, indx, &key_id);
2810 if (result < 0)
2811 error (EXIT_FAILURE, 0, "bag_set_key_id: %s",
2812 gnutls_strerror (result));
2814 result = gnutls_pkcs12_set_bag (pkcs12, kbag);
2815 if (result < 0)
2816 error (EXIT_FAILURE, 0, "set_bag: %s", gnutls_strerror (result));
2819 result = gnutls_pkcs12_generate_mac (pkcs12, pass);
2820 if (result < 0)
2821 error (EXIT_FAILURE, 0, "generate_mac: %s", gnutls_strerror (result));
2823 size = sizeof (buffer);
2824 result = gnutls_pkcs12_export (pkcs12, info.outcert_format, buffer, &size);
2825 if (result < 0)
2826 error (EXIT_FAILURE, 0, "pkcs12_export: %s", gnutls_strerror (result));
2828 fwrite (buffer, 1, size, outfile);
2832 static const char *
2833 BAGTYPE (gnutls_pkcs12_bag_type_t x)
2835 switch (x)
2837 case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY:
2838 return "PKCS #8 Encrypted key";
2839 case GNUTLS_BAG_EMPTY:
2840 return "Empty";
2841 case GNUTLS_BAG_PKCS8_KEY:
2842 return "PKCS #8 Key";
2843 case GNUTLS_BAG_CERTIFICATE:
2844 return "Certificate";
2845 case GNUTLS_BAG_ENCRYPTED:
2846 return "Encrypted";
2847 case GNUTLS_BAG_CRL:
2848 return "CRL";
2849 case GNUTLS_BAG_SECRET:
2850 return "Secret";
2851 default:
2852 return "Unknown";
2856 static void
2857 print_bag_data (gnutls_pkcs12_bag_t bag)
2859 int result;
2860 int count, i, type;
2861 gnutls_datum_t cdata, id;
2862 const char *str, *name;
2863 gnutls_datum_t out;
2865 count = gnutls_pkcs12_bag_get_count (bag);
2866 if (count < 0)
2867 error (EXIT_FAILURE, 0, "get_count: %s", gnutls_strerror (count));
2869 fprintf (outfile, "\tElements: %d\n", count);
2871 for (i = 0; i < count; i++)
2873 type = gnutls_pkcs12_bag_get_type (bag, i);
2874 if (type < 0)
2875 error (EXIT_FAILURE, 0, "get_type: %s", gnutls_strerror (type));
2877 fprintf (stderr, "\tType: %s\n", BAGTYPE (type));
2879 name = NULL;
2880 result = gnutls_pkcs12_bag_get_friendly_name (bag, i, (char **) &name);
2881 if (result < 0)
2882 error (EXIT_FAILURE, 0, "get_friendly_name: %s",
2883 gnutls_strerror (type));
2884 if (name)
2885 fprintf (outfile, "\tFriendly name: %s\n", name);
2887 id.data = NULL;
2888 id.size = 0;
2889 result = gnutls_pkcs12_bag_get_key_id (bag, i, &id);
2890 if (result < 0)
2891 error (EXIT_FAILURE, 0, "get_key_id: %s", gnutls_strerror (type));
2892 fprintf (outfile, "\tKey ID: %s\n", raw_to_string (id.data, id.size));
2894 result = gnutls_pkcs12_bag_get_data (bag, i, &cdata);
2895 if (result < 0)
2896 error (EXIT_FAILURE, 0, "get_data: %s", gnutls_strerror (result));
2898 switch (type)
2900 case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY:
2901 str = "ENCRYPTED PRIVATE KEY";
2902 break;
2903 case GNUTLS_BAG_PKCS8_KEY:
2904 str = "PRIVATE KEY";
2905 break;
2906 case GNUTLS_BAG_CERTIFICATE:
2907 str = "CERTIFICATE";
2908 break;
2909 case GNUTLS_BAG_CRL:
2910 str = "CRL";
2911 break;
2912 case GNUTLS_BAG_ENCRYPTED:
2913 case GNUTLS_BAG_EMPTY:
2914 default:
2915 str = NULL;
2918 if (str != NULL)
2920 gnutls_pem_base64_encode_alloc (str, &cdata, &out);
2921 fprintf (outfile, "%s\n", out.data);
2923 gnutls_free (out.data);
2929 void
2930 pkcs12_info (void)
2932 gnutls_pkcs12_t pkcs12;
2933 gnutls_pkcs12_bag_t bag;
2934 int result;
2935 size_t size;
2936 gnutls_datum_t data;
2937 const char *pass;
2938 int indx;
2940 result = gnutls_pkcs12_init (&pkcs12);
2941 if (result < 0)
2942 error (EXIT_FAILURE, 0, "p12_init: %s", gnutls_strerror (result));
2944 data.data = fread_file (infile, &size);
2945 data.size = size;
2947 result = gnutls_pkcs12_import (pkcs12, &data, info.incert_format, 0);
2948 free (data.data);
2949 if (result < 0)
2950 error (EXIT_FAILURE, 0, "p12_import: %s", gnutls_strerror (result));
2952 if (info.pass)
2953 pass = info.pass;
2954 else
2955 pass = get_pass ();
2957 result = gnutls_pkcs12_verify_mac (pkcs12, pass);
2958 if (result < 0)
2959 error (0, 0, "verify_mac: %s", gnutls_strerror (result));
2961 for (indx = 0;; indx++)
2963 result = gnutls_pkcs12_bag_init (&bag);
2964 if (result < 0)
2965 error (EXIT_FAILURE, 0, "bag_init: %s", gnutls_strerror (result));
2967 result = gnutls_pkcs12_get_bag (pkcs12, indx, bag);
2968 if (result < 0)
2969 break;
2971 result = gnutls_pkcs12_bag_get_count (bag);
2972 if (result < 0)
2973 error (EXIT_FAILURE, 0, "bag_count: %s", gnutls_strerror (result));
2975 fprintf (outfile, "BAG #%d\n", indx);
2977 result = gnutls_pkcs12_bag_get_type (bag, 0);
2978 if (result < 0)
2979 error (EXIT_FAILURE, 0, "bag_init: %s", gnutls_strerror (result));
2981 if (result == GNUTLS_BAG_ENCRYPTED)
2983 fprintf (stderr, "\tType: %s\n", BAGTYPE (result));
2984 fprintf (stderr, "\n\tDecrypting...\n");
2986 result = gnutls_pkcs12_bag_decrypt (bag, pass);
2988 if (result < 0)
2990 error (0, 0, "bag_decrypt: %s", gnutls_strerror (result));
2991 continue;
2994 result = gnutls_pkcs12_bag_get_count (bag);
2995 if (result < 0)
2996 error (EXIT_FAILURE, 0, "encrypted bag_count: %s",
2997 gnutls_strerror (result));
3000 print_bag_data (bag);
3002 gnutls_pkcs12_bag_deinit (bag);
3006 void
3007 pkcs7_info (void)
3009 gnutls_pkcs7_t pkcs7;
3010 int result;
3011 size_t size;
3012 gnutls_datum_t data, b64;
3013 int indx, count;
3015 result = gnutls_pkcs7_init (&pkcs7);
3016 if (result < 0)
3017 error (EXIT_FAILURE, 0, "p7_init: %s", gnutls_strerror (result));
3019 data.data = fread_file (infile, &size);
3020 data.size = size;
3022 result = gnutls_pkcs7_import (pkcs7, &data, info.incert_format);
3023 free (data.data);
3024 if (result < 0)
3025 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (result));
3027 /* Read and print the certificates.
3029 result = gnutls_pkcs7_get_crt_count (pkcs7);
3030 if (result < 0)
3031 error (EXIT_FAILURE, 0, "p7_crt_count: %s", gnutls_strerror (result));
3033 count = result;
3035 if (count > 0)
3036 fprintf (outfile, "Number of certificates: %u\n", count);
3038 for (indx = 0; indx < count; indx++)
3040 fputs ("\n", outfile);
3042 size = sizeof (buffer);
3043 result = gnutls_pkcs7_get_crt_raw (pkcs7, indx, buffer, &size);
3044 if (result < 0)
3045 break;
3047 data.data = buffer;
3048 data.size = size;
3050 result = gnutls_pem_base64_encode_alloc ("CERTIFICATE", &data, &b64);
3051 if (result < 0)
3052 error (EXIT_FAILURE, 0, "encoding: %s", gnutls_strerror (result));
3054 fputs (b64.data, outfile);
3055 gnutls_free (b64.data);
3058 /* Read the CRLs now.
3060 result = gnutls_pkcs7_get_crl_count (pkcs7);
3061 if (result < 0)
3062 error (EXIT_FAILURE, 0, "p7_crl_count: %s", gnutls_strerror (result));
3064 count = result;
3066 if (count > 0)
3067 fprintf (outfile, "\nNumber of CRLs: %u\n", count);
3069 for (indx = 0; indx < count; indx++)
3071 fputs ("\n", outfile);
3073 size = sizeof (buffer);
3074 result = gnutls_pkcs7_get_crl_raw (pkcs7, indx, buffer, &size);
3075 if (result < 0)
3076 break;
3078 data.data = buffer;
3079 data.size = size;
3081 result = gnutls_pem_base64_encode_alloc ("X509 CRL", &data, &b64);
3082 if (result < 0)
3083 error (EXIT_FAILURE, 0, "encoding: %s", gnutls_strerror (result));
3085 fputs (b64.data, outfile);
3086 gnutls_free (b64.data);
3090 void
3091 smime_to_pkcs7 (void)
3093 size_t linesize = 0;
3094 char *lineptr = NULL;
3095 ssize_t len;
3097 /* Find body. FIXME: Handle non-b64 Content-Transfer-Encoding.
3098 Reject non-S/MIME tagged Content-Type's? */
3101 len = getline (&lineptr, &linesize, infile);
3102 if (len == -1)
3103 error (EXIT_FAILURE, 0, "cannot find RFC 2822 header/body separator");
3105 while (strcmp (lineptr, "\r\n") != 0 && strcmp (lineptr, "\n") != 0);
3109 len = getline (&lineptr, &linesize, infile);
3110 if (len == -1)
3111 error (EXIT_FAILURE, 0, "message has RFC 2822 header but no body");
3113 while (strcmp (lineptr, "\r\n") == 0 && strcmp (lineptr, "\n") == 0);
3115 fprintf (outfile, "%s", "-----BEGIN PKCS7-----\n");
3119 while (len > 0
3120 && (lineptr[len - 1] == '\r' || lineptr[len - 1] == '\n'))
3121 lineptr[--len] = '\0';
3122 if (strcmp (lineptr, "") != 0)
3123 fprintf (outfile, "%s\n", lineptr);
3124 len = getline (&lineptr, &linesize, infile);
3126 while (len != -1);
3128 fprintf (outfile, "%s", "-----END PKCS7-----\n");
3130 free (lineptr);
3133 void
3134 certtool_version (void)
3136 const char *p = PACKAGE_NAME;
3137 if (strcmp (gnutls_check_version (NULL), PACKAGE_VERSION) != 0)
3138 p = PACKAGE_STRING;
3139 version_etc (stdout, program_name, p, gnutls_check_version (NULL),
3140 "Nikos Mavrogiannopoulos", "Simon Josefsson", (char *) NULL);
3143 static void print_key_usage(FILE* outfile, unsigned int usage)
3145 if (usage & GNUTLS_KEY_DIGITAL_SIGNATURE) {
3146 fprintf(outfile, "\tDigital signature.\n");
3149 if (usage & GNUTLS_KEY_NON_REPUDIATION) {
3150 fprintf(outfile, "\tNon repudiation.\n");
3153 if (usage & GNUTLS_KEY_KEY_ENCIPHERMENT) {
3154 fprintf(outfile, "\tKey encipherment.\n");
3157 if (usage & GNUTLS_KEY_DATA_ENCIPHERMENT) {
3158 fprintf(outfile, "\tData encipherment.\n");
3161 if (usage & GNUTLS_KEY_KEY_AGREEMENT) {
3162 fprintf(outfile, "\tKey agreement.\n");
3165 if (usage & GNUTLS_KEY_KEY_CERT_SIGN) {
3166 fprintf(outfile, "\tCertificate signing.\n");
3169 if (usage & GNUTLS_KEY_NON_REPUDIATION) {
3170 fprintf(outfile, "\tCRL signing.\n");
3173 if (usage & GNUTLS_KEY_ENCIPHER_ONLY) {
3174 fprintf(outfile, "\tKey encipher only.\n");
3177 if (usage & GNUTLS_KEY_DECIPHER_ONLY) {
3178 fprintf(outfile, "\tKey decipher only.\n");
3182 void pubkey_info (gnutls_x509_crt crt)
3184 gnutls_pubkey_t pubkey;
3185 unsigned int bits, usage;
3186 int ret;
3187 size_t size;
3188 const char* cprint;
3190 ret = gnutls_pubkey_init(&pubkey);
3191 if (ret < 0) {
3192 error (EXIT_FAILURE, 0, "pubkey_init: %s", gnutls_strerror (ret));
3195 if (crt == NULL) {
3196 crt = load_cert(0);
3199 if (crt != NULL) {
3200 ret = gnutls_pubkey_import_x509(pubkey, crt, 0);
3201 if (ret < 0) {
3202 error (EXIT_FAILURE, 0, "pubkey_import_x509: %s", gnutls_strerror (ret));
3204 } else {
3205 pubkey = load_pubkey(1);
3208 fprintf (outfile, "Public Key Info:\n\n");
3209 ret = gnutls_pubkey_get_pk_algorithm (pubkey, &bits);
3210 fprintf (outfile, "Public Key Algorithm: ");
3212 cprint = gnutls_pk_algorithm_get_name (ret);
3213 fprintf (outfile, "%s (%u bits)\n", cprint ? cprint : "Unknown", bits);
3216 /* Print the raw public and private keys
3218 if (ret == GNUTLS_PK_RSA)
3220 gnutls_datum_t m, e;
3222 ret = gnutls_pubkey_get_pk_rsa_raw (pubkey, &m, &e);
3223 if (ret < 0)
3224 fprintf (stderr, "Error in key RSA data export: %s\n",
3225 gnutls_strerror (ret));
3226 else
3228 print_rsa_pkey (&m, &e, NULL, NULL, NULL, NULL, NULL, NULL);
3229 gnutls_free (m.data);
3230 gnutls_free (e.data);
3233 else if (ret == GNUTLS_PK_DSA)
3235 gnutls_datum_t p, q, g, y;
3237 ret = gnutls_pubkey_get_pk_dsa_raw (pubkey, &p, &q, &g, &y);
3238 if (ret < 0)
3239 fprintf (stderr, "Error in key DSA data export: %s\n",
3240 gnutls_strerror (ret));
3241 else
3243 print_dsa_pkey (NULL, &y, &p, &q, &g);
3244 gnutls_free (y.data);
3245 gnutls_free (p.data);
3246 gnutls_free (q.data);
3247 gnutls_free (g.data);
3251 ret = gnutls_pubkey_get_key_usage (pubkey, &usage);
3252 if (ret < 0) {
3253 error (EXIT_FAILURE, 0, "pubkey_get_key_usage: %s", gnutls_strerror (ret));
3256 fprintf (outfile, "Public Key Usage:\n");
3257 print_key_usage(outfile, usage);
3259 fprintf (outfile, "\n");
3261 size = sizeof (buffer);
3262 if ((ret = gnutls_pubkey_get_key_id (pubkey, 0, buffer, &size)) < 0)
3264 fprintf (stderr, "Error in key id calculation: %s\n",
3265 gnutls_strerror (ret));
3267 else
3269 fprintf (outfile, "Public Key ID: %s\n", raw_to_string (buffer, size));
3272 size = sizeof (buffer);
3273 ret = gnutls_pubkey_export (pubkey, GNUTLS_X509_FMT_PEM, buffer, &size);
3274 if (ret < 0)
3275 error (EXIT_FAILURE, 0, "export error: %s", gnutls_strerror (ret));
3277 fprintf (outfile, "\n%s\n", buffer);
3279 gnutls_pubkey_deinit (pubkey);