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/>.
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>
38 #include <sys/types.h>
43 /* Gnulib portability files. */
44 #include <read-file.h>
46 #include <version-etc.h>
48 #include <certtool-cfg.h>
49 #include "certtool-gaa.h"
50 #include "certtool-common.h"
52 static void print_crl_info (gnutls_x509_crl_t crl
, FILE * out
);
53 int generate_prime (int bits
, int how
);
54 void pkcs7_info (void);
56 void smime_to_pkcs7 (void);
57 void pkcs12_info (void);
58 void generate_pkcs12 (void);
59 void generate_pkcs8 (void);
60 void verify_chain (void);
61 void verify_crl (void);
62 void pgp_privkey_info (void);
63 void pgp_ring_info (void);
64 gnutls_x509_privkey_t
load_private_key (int mand
);
65 gnutls_x509_crq_t
load_request (void);
66 gnutls_x509_privkey_t
load_ca_private_key (void);
67 gnutls_x509_crt_t
load_ca_cert (void);
68 gnutls_x509_crt_t
load_cert (int mand
);
69 void certificate_info (void);
70 void pgp_certificate_info (void);
72 void privkey_info (void);
73 static void print_certificate_info (gnutls_x509_crt_t crt
, FILE * out
,
75 static void gaa_parser (int argc
, char **argv
);
76 void generate_self_signed (void);
77 void generate_request (void);
78 gnutls_x509_crt_t
*load_cert_list (int mand
, size_t * size
);
80 static void print_hex_datum (gnutls_datum_t
* dat
);
86 gnutls_digest_algorithm_t dig
= GNUTLS_DIG_SHA1
;
88 /* non interactive operation if set
92 unsigned char buffer
[64 * 1024];
93 const int buffer_size
= sizeof (buffer
);
96 tls_log_func (int level
, const char *str
)
98 fprintf (stderr
, "|<%d>| %s", level
, str
);
102 main (int argc
, char **argv
)
104 set_program_name (argv
[0]);
106 gaa_parser (argc
, argv
);
112 raw_to_string (const unsigned char *raw
, size_t raw_size
)
114 static char buf
[1024];
119 if (raw_size
* 3 + 1 >= sizeof (buf
))
122 for (i
= 0; i
< raw_size
; i
++)
124 sprintf (&(buf
[i
* 3]), "%02X%s", raw
[i
],
125 (i
== raw_size
- 1) ? "" : ":");
127 buf
[sizeof (buf
) - 1] = '\0';
133 print_dsa_pkey (gnutls_datum_t
* x
, gnutls_datum_t
* y
, gnutls_datum_t
* p
,
134 gnutls_datum_t
* q
, gnutls_datum_t
* g
)
136 fprintf (outfile
, "private key:");
138 fprintf (outfile
, "public key:");
140 fprintf (outfile
, "p:");
142 fprintf (outfile
, "q:");
144 fprintf (outfile
, "g:");
149 print_rsa_pkey (gnutls_datum_t
* m
, gnutls_datum_t
* e
, gnutls_datum_t
* d
,
150 gnutls_datum_t
* p
, gnutls_datum_t
* q
, gnutls_datum_t
* u
)
152 fprintf (outfile
, "modulus:");
154 fprintf (outfile
, "public exponent:");
156 fprintf (outfile
, "private exponent:");
158 fprintf (outfile
, "prime1:");
160 fprintf (outfile
, "prime2:");
162 fprintf (outfile
, "coefficient:");
166 static gnutls_x509_privkey_t
167 generate_private_key_int (void)
169 gnutls_x509_privkey_t key
;
174 key_type
= GNUTLS_PK_DSA
;
175 /* FIXME: Remove me once we depend on 1.3.x */
176 if (info
.bits
> 1024 && gcry_check_version ("1.3.1") == NULL
)
180 key_type
= GNUTLS_PK_RSA
;
182 ret
= gnutls_x509_privkey_init (&key
);
184 error (EXIT_FAILURE
, 0, "privkey_init: %s", gnutls_strerror (ret
));
186 fprintf (stderr
, "Generating a %d bit %s private key...\n", info
.bits
,
187 gnutls_pk_algorithm_get_name (key_type
));
189 if (info
.quick_random
== 0)
191 "This might take several minutes depending on availability of randomness"
192 " in /dev/random.\n");
194 ret
= gnutls_x509_privkey_generate (key
, key_type
, info
.bits
, 0);
196 error (EXIT_FAILURE
, 0, "privkey_generate: %s", gnutls_strerror (ret
));
202 print_private_key (gnutls_x509_privkey_t key
)
212 size
= sizeof (buffer
);
213 ret
= gnutls_x509_privkey_export (key
, info
.outcert_format
,
216 error (EXIT_FAILURE
, 0, "privkey_export: %s", gnutls_strerror (ret
));
224 flags
= GNUTLS_PKCS_USE_PKCS12_RC2_40
;
226 flags
= GNUTLS_PKCS_USE_PKCS12_3DES
;
228 if ((pass
= get_confirmed_pass (true)) == NULL
|| *pass
== '\0')
229 flags
= GNUTLS_PKCS_PLAIN
;
231 size
= sizeof (buffer
);
233 gnutls_x509_privkey_export_pkcs8 (key
, info
.outcert_format
, pass
,
234 flags
, buffer
, &size
);
236 error (EXIT_FAILURE
, 0, "privkey_export_pkcs8: %s",
237 gnutls_strerror (ret
));
240 fwrite (buffer
, 1, size
, outfile
);
244 generate_private_key (void)
246 gnutls_x509_privkey_t key
;
248 key
= generate_private_key_int ();
250 print_private_key (key
);
252 gnutls_x509_privkey_deinit (key
);
256 static gnutls_x509_crt_t
257 generate_certificate (gnutls_x509_privkey_t
* ret_key
,
258 gnutls_x509_crt_t ca_crt
, int proxy
)
260 gnutls_x509_crt_t crt
;
261 gnutls_x509_privkey_t key
= NULL
;
265 int days
, result
, ca_status
= 0, path_len
;
267 unsigned int usage
= 0, server
;
268 gnutls_x509_crq_t crq
; /* request */
270 ret
= gnutls_x509_crt_init (&crt
);
272 error (EXIT_FAILURE
, 0, "crt_init: %s", gnutls_strerror (ret
));
274 crq
= load_request ();
279 key
= load_private_key (1);
283 "Please enter the details of the certificate's distinguished name. "
284 "Just press enter to ignore a field.\n");
290 result
= gnutls_x509_crt_set_proxy_dn (crt
, ca_crt
, 0, NULL
, 0);
292 error (EXIT_FAILURE
, 0, "set_proxy_dn: %s",
293 gnutls_strerror (result
));
295 get_cn_crt_set (crt
);
299 get_country_crt_set (crt
);
300 get_organization_crt_set (crt
);
301 get_unit_crt_set (crt
);
302 get_locality_crt_set (crt
);
303 get_state_crt_set (crt
);
304 get_cn_crt_set (crt
);
305 get_uid_crt_set (crt
);
306 get_oid_crt_set (crt
);
307 get_key_purpose_set (crt
);
311 "This field should not be used in new certificates.\n");
313 get_pkcs9_email_crt_set (crt
);
316 result
= gnutls_x509_crt_set_key (crt
, key
);
318 error (EXIT_FAILURE
, 0, "set_key: %s", gnutls_strerror (result
));
322 result
= gnutls_x509_crt_set_crq (crt
, crq
);
324 error (EXIT_FAILURE
, 0, "set_crq: %s", gnutls_strerror (result
));
329 int serial
= get_serial ();
332 bin_serial
[4] = serial
& 0xff;
333 bin_serial
[3] = (serial
>> 8) & 0xff;
334 bin_serial
[2] = (serial
>> 16) & 0xff;
335 bin_serial
[1] = (serial
>> 24) & 0xff;
338 result
= gnutls_x509_crt_set_serial (crt
, bin_serial
, 5);
340 error (EXIT_FAILURE
, 0, "serial: %s", gnutls_strerror (result
));
344 fprintf (stderr
, "\n\nActivation/Expiration time.\n");
346 gnutls_x509_crt_set_activation_time (crt
, time (NULL
));
351 gnutls_x509_crt_set_expiration_time (crt
,
352 time (NULL
) + days
* 24 * 60 * 60);
354 error (EXIT_FAILURE
, 0, "set_expiration: %s", gnutls_strerror (result
));
357 fprintf (stderr
, "\n\nExtensions.\n");
359 /* do not allow extensions on a v1 certificate */
360 if (crq
&& get_crq_extensions_status () != 0)
362 result
= gnutls_x509_crt_set_crq_extensions (crt
, crq
);
364 error (EXIT_FAILURE
, 0, "set_crq: %s", gnutls_strerror (result
));
367 /* append additional extensions */
368 if (info
.v1_cert
== 0)
373 const char *policylanguage
;
376 int proxypathlen
= get_path_len ();
380 printf ("1.3.6.1.5.5.7.21.1 ::= id-ppl-inheritALL\n");
381 printf ("1.3.6.1.5.5.7.21.2 ::= id-ppl-independent\n");
384 policylanguage
= get_proxy_policy (&policy
, &policylen
);
387 gnutls_x509_crt_set_proxy (crt
, proxypathlen
, policylanguage
,
390 error (EXIT_FAILURE
, 0, "set_proxy: %s",
391 gnutls_strerror (result
));
395 ca_status
= get_ca_status ();
397 path_len
= get_path_len ();
402 gnutls_x509_crt_set_basic_constraints (crt
, ca_status
, path_len
);
404 error (EXIT_FAILURE
, 0, "basic_constraints: %s",
405 gnutls_strerror (result
));
407 client
= get_tls_client_status ();
410 result
= gnutls_x509_crt_set_key_purpose_oid (crt
,
411 GNUTLS_KP_TLS_WWW_CLIENT
,
414 error (EXIT_FAILURE
, 0, "key_kp: %s", gnutls_strerror (result
));
417 server
= get_tls_server_status ();
424 get_dns_name_set (TYPE_CRT
, crt
);
425 get_ip_addr_set (TYPE_CRT
, crt
);
429 gnutls_x509_crt_set_key_purpose_oid (crt
,
430 GNUTLS_KP_TLS_WWW_SERVER
, 0);
432 error (EXIT_FAILURE
, 0, "key_kp: %s", gnutls_strerror (result
));
436 get_email_set (TYPE_CRT
, crt
);
439 if (!ca_status
|| server
)
444 pk
= gnutls_x509_crt_get_pk_algorithm (crt
, NULL
);
446 if (pk
!= GNUTLS_PK_DSA
)
447 { /* DSA keys can only sign.
449 result
= get_sign_status (server
);
451 usage
|= GNUTLS_KEY_DIGITAL_SIGNATURE
;
453 result
= get_encrypt_status (server
);
455 usage
|= GNUTLS_KEY_KEY_ENCIPHERMENT
;
458 usage
|= GNUTLS_KEY_DIGITAL_SIGNATURE
;
464 result
= get_cert_sign_status ();
466 usage
|= GNUTLS_KEY_KEY_CERT_SIGN
;
468 result
= get_crl_sign_status ();
470 usage
|= GNUTLS_KEY_CRL_SIGN
;
472 result
= get_code_sign_status ();
476 gnutls_x509_crt_set_key_purpose_oid (crt
,
477 GNUTLS_KP_CODE_SIGNING
,
480 error (EXIT_FAILURE
, 0, "key_kp: %s",
481 gnutls_strerror (result
));
484 result
= get_ocsp_sign_status ();
488 gnutls_x509_crt_set_key_purpose_oid (crt
,
489 GNUTLS_KP_OCSP_SIGNING
,
492 error (EXIT_FAILURE
, 0, "key_kp: %s",
493 gnutls_strerror (result
));
496 result
= get_time_stamp_status ();
500 gnutls_x509_crt_set_key_purpose_oid (crt
,
501 GNUTLS_KP_TIME_STAMPING
,
504 error (EXIT_FAILURE
, 0, "key_kp: %s",
505 gnutls_strerror (result
));
511 result
= gnutls_x509_crt_set_key_usage (crt
, usage
);
513 error (EXIT_FAILURE
, 0, "key_usage: %s",
514 gnutls_strerror (result
));
519 size
= sizeof (buffer
);
520 result
= gnutls_x509_crt_get_key_id (crt
, 0, buffer
, &size
);
523 result
= gnutls_x509_crt_set_subject_key_id (crt
, buffer
, size
);
525 error (EXIT_FAILURE
, 0, "set_subject_key_id: %s",
526 gnutls_strerror (result
));
533 size
= sizeof (buffer
);
534 result
= gnutls_x509_crt_get_subject_key_id (ca_crt
, buffer
,
538 size
= sizeof (buffer
);
539 result
= gnutls_x509_crt_get_key_id (ca_crt
, 0, buffer
, &size
);
544 gnutls_x509_crt_set_authority_key_id (crt
, buffer
, size
);
546 error (EXIT_FAILURE
, 0, "set_authority_key_id: %s",
547 gnutls_strerror (result
));
554 if (info
.v1_cert
!= 0)
558 result
= gnutls_x509_crt_set_version (crt
, vers
);
560 error (EXIT_FAILURE
, 0, "set_version: %s", gnutls_strerror (result
));
567 static gnutls_x509_crl_t
568 generate_crl (gnutls_x509_crt_t ca_crt
)
570 gnutls_x509_crl_t crl
;
571 gnutls_x509_crt_t
*crts
;
575 time_t now
= time (NULL
);
577 result
= gnutls_x509_crl_init (&crl
);
579 error (EXIT_FAILURE
, 0, "crl_init: %s", gnutls_strerror (result
));
581 crts
= load_cert_list (0, &size
);
583 for (i
= 0; i
< size
; i
++)
585 result
= gnutls_x509_crl_set_crt (crl
, crts
[i
], now
);
587 error (EXIT_FAILURE
, 0, "crl_set_crt: %s", gnutls_strerror (result
));
590 result
= gnutls_x509_crl_set_this_update (crl
, now
);
592 error (EXIT_FAILURE
, 0, "this_update: %s", gnutls_strerror (result
));
594 fprintf (stderr
, "Update times.\n");
595 days
= get_crl_next_update ();
597 result
= gnutls_x509_crl_set_next_update (crl
, now
+ days
* 24 * 60 * 60);
599 error (EXIT_FAILURE
, 0, "next_update: %s", gnutls_strerror (result
));
601 result
= gnutls_x509_crl_set_version (crl
, 2);
603 error (EXIT_FAILURE
, 0, "set_version: %s", gnutls_strerror (result
));
609 size
= sizeof (buffer
);
610 result
= gnutls_x509_crt_get_subject_key_id (ca_crt
, buffer
,
614 size
= sizeof (buffer
);
615 result
= gnutls_x509_crt_get_key_id (ca_crt
, 0, buffer
, &size
);
619 result
= gnutls_x509_crl_set_authority_key_id (crl
, buffer
, size
);
621 error (EXIT_FAILURE
, 0, "set_authority_key_id: %s",
622 gnutls_strerror (result
));
627 unsigned int number
= get_crl_number ();
630 bin_number
[4] = number
& 0xff;
631 bin_number
[3] = (number
>> 8) & 0xff;
632 bin_number
[2] = (number
>> 16) & 0xff;
633 bin_number
[1] = (number
>> 24) & 0xff;
636 result
= gnutls_x509_crl_set_number (crl
, bin_number
, 5);
638 error (EXIT_FAILURE
, 0, "set_number: %s", gnutls_strerror (result
));
645 generate_self_signed (void)
647 gnutls_x509_crt_t crt
;
648 gnutls_x509_privkey_t key
;
653 fprintf (stderr
, "Generating a self signed certificate...\n");
655 crt
= generate_certificate (&key
, NULL
, 0);
658 key
= load_private_key (1);
660 uri
= get_crl_dist_point_url ();
663 result
= gnutls_x509_crt_set_crl_dist_points (crt
, GNUTLS_SAN_URI
,
665 0 /* all reasons */ );
667 error (EXIT_FAILURE
, 0, "crl_dist_points: %s",
668 gnutls_strerror (result
));
671 print_certificate_info (crt
, stderr
, 0);
673 fprintf (stderr
, "\n\nSigning certificate...\n");
675 result
= gnutls_x509_crt_sign2 (crt
, crt
, key
, dig
, 0);
677 error (EXIT_FAILURE
, 0, "crt_sign: %s", gnutls_strerror (result
));
679 size
= sizeof (buffer
);
680 result
= gnutls_x509_crt_export (crt
, info
.outcert_format
, buffer
, &size
);
682 error (EXIT_FAILURE
, 0, "crt_export: %s", gnutls_strerror (result
));
684 fwrite (buffer
, 1, size
, outfile
);
686 gnutls_x509_crt_deinit (crt
);
687 gnutls_x509_privkey_deinit (key
);
691 generate_signed_certificate (void)
693 gnutls_x509_crt_t crt
;
694 gnutls_x509_privkey_t key
;
697 gnutls_x509_privkey_t ca_key
;
698 gnutls_x509_crt_t ca_crt
;
700 fprintf (stderr
, "Generating a signed certificate...\n");
702 ca_key
= load_ca_private_key ();
703 ca_crt
= load_ca_cert ();
705 crt
= generate_certificate (&key
, ca_crt
, 0);
707 /* Copy the CRL distribution points.
709 gnutls_x509_crt_cpy_crl_dist_points (crt
, ca_crt
);
710 /* it doesn't matter if we couldn't copy the CRL dist points.
713 print_certificate_info (crt
, stderr
, 0);
715 fprintf (stderr
, "\n\nSigning certificate...\n");
717 result
= gnutls_x509_crt_sign2 (crt
, ca_crt
, ca_key
, dig
, 0);
719 error (EXIT_FAILURE
, 0, "crt_sign: %s", gnutls_strerror (result
));
721 size
= sizeof (buffer
);
722 result
= gnutls_x509_crt_export (crt
, info
.outcert_format
, buffer
, &size
);
724 error (EXIT_FAILURE
, 0, "crt_export: %s", gnutls_strerror (result
));
726 fwrite (buffer
, 1, size
, outfile
);
728 gnutls_x509_crt_deinit (crt
);
729 gnutls_x509_privkey_deinit (key
);
733 generate_proxy_certificate (void)
735 gnutls_x509_crt_t crt
, eecrt
;
736 gnutls_x509_privkey_t key
, eekey
;
740 fprintf (stderr
, "Generating a proxy certificate...\n");
742 eekey
= load_ca_private_key ();
743 eecrt
= load_cert (1);
745 crt
= generate_certificate (&key
, eecrt
, 1);
747 print_certificate_info (crt
, stderr
, 0);
749 fprintf (stderr
, "\n\nSigning certificate...\n");
751 result
= gnutls_x509_crt_sign2 (crt
, eecrt
, eekey
, dig
, 0);
753 error (EXIT_FAILURE
, 0, "crt_sign: %s", gnutls_strerror (result
));
755 size
= sizeof (buffer
);
756 result
= gnutls_x509_crt_export (crt
, info
.outcert_format
, buffer
, &size
);
758 error (EXIT_FAILURE
, 0, "crt_export: %s", gnutls_strerror (result
));
760 fwrite (buffer
, 1, size
, outfile
);
762 gnutls_x509_crt_deinit (crt
);
763 gnutls_x509_privkey_deinit (key
);
767 generate_signed_crl (void)
769 gnutls_x509_crl_t crl
;
771 gnutls_x509_privkey_t ca_key
;
772 gnutls_x509_crt_t ca_crt
;
774 fprintf (stderr
, "Generating a signed CRL...\n");
776 ca_key
= load_ca_private_key ();
777 ca_crt
= load_ca_cert ();
778 crl
= generate_crl (ca_crt
);
780 fprintf (stderr
, "\n");
782 result
= gnutls_x509_crl_sign (crl
, ca_crt
, ca_key
);
784 error (EXIT_FAILURE
, 0, "crl_sign: %s", gnutls_strerror (result
));
786 print_crl_info (crl
, stderr
);
788 gnutls_x509_crl_deinit (crl
);
792 update_signed_certificate (void)
794 gnutls_x509_crt_t crt
;
797 gnutls_x509_privkey_t ca_key
;
798 gnutls_x509_crt_t ca_crt
;
800 time_t tim
= time (NULL
);
802 fprintf (stderr
, "Generating a signed certificate...\n");
804 ca_key
= load_ca_private_key ();
805 ca_crt
= load_ca_cert ();
808 fprintf (stderr
, "Activation/Expiration time.\n");
809 gnutls_x509_crt_set_activation_time (crt
, tim
);
814 gnutls_x509_crt_set_expiration_time (crt
, tim
+ days
* 24 * 60 * 60);
816 error (EXIT_FAILURE
, 0, "set_expiration: %s", gnutls_strerror (result
));
818 fprintf (stderr
, "\n\nSigning certificate...\n");
820 result
= gnutls_x509_crt_sign2 (crt
, ca_crt
, ca_key
, dig
, 0);
822 error (EXIT_FAILURE
, 0, "crt_sign: %s", gnutls_strerror (result
));
824 size
= sizeof (buffer
);
825 result
= gnutls_x509_crt_export (crt
, info
.outcert_format
, buffer
, &size
);
827 error (EXIT_FAILURE
, 0, "crt_export: %s", gnutls_strerror (result
));
829 fwrite (buffer
, 1, size
, outfile
);
831 gnutls_x509_crt_deinit (crt
);
835 safe_open_rw (const char *file
)
840 if (info
.privkey_op
!= 0)
842 omask
= umask (S_IRGRP
| S_IWGRP
| S_IROTH
| S_IWOTH
);
845 fh
= fopen (file
, "wb");
847 if (info
.privkey_op
!= 0)
856 gaa_parser (int argc
, char **argv
)
860 if (gaa (argc
, argv
, &info
) != -1)
862 fprintf (stderr
, "Try `%s --help' for more information.\n",
869 outfile
= safe_open_rw (info
.outfile
);
871 error (EXIT_FAILURE
, errno
, "%s", info
.outfile
);
878 infile
= fopen (info
.infile
, "rb");
880 error (EXIT_FAILURE
, errno
, "%s", info
.infile
);
885 if (info
.incert_format
)
886 info
.incert_format
= GNUTLS_X509_FMT_DER
;
888 info
.incert_format
= GNUTLS_X509_FMT_PEM
;
890 if (info
.outcert_format
)
891 info
.outcert_format
= GNUTLS_X509_FMT_DER
;
893 info
.outcert_format
= GNUTLS_X509_FMT_PEM
;
895 if (info
.hash
!= NULL
)
897 if (strcasecmp (info
.hash
, "md5") == 0)
900 "Warning: MD5 is broken, and should not be used any more for digital signatures.\n");
901 dig
= GNUTLS_DIG_MD5
;
903 else if (strcasecmp (info
.hash
, "sha1") == 0)
904 dig
= GNUTLS_DIG_SHA1
;
905 else if (strcasecmp (info
.hash
, "sha256") == 0)
906 dig
= GNUTLS_DIG_SHA256
;
907 else if (strcasecmp (info
.hash
, "sha384") == 0)
908 dig
= GNUTLS_DIG_SHA384
;
909 else if (strcasecmp (info
.hash
, "sha512") == 0)
910 dig
= GNUTLS_DIG_SHA512
;
911 else if (strcasecmp (info
.hash
, "rmd160") == 0)
912 dig
= GNUTLS_DIG_RMD160
;
914 error (EXIT_FAILURE
, 0, "invalid hash: %s", info
.hash
);
921 template_parse (info
.template);
924 #ifdef gcry_fips_mode_active
925 /* Libgcrypt manual says that gcry_version_check must be called
926 before calling gcry_fips_mode_active. */
927 gcry_check_version (NULL
);
928 if (gcry_fips_mode_active ())
930 ret
= gnutls_register_md5_handler ();
932 fprintf (stderr
, "gnutls_register_md5_handler: %s\n",
933 gnutls_strerror (ret
));
937 gnutls_global_set_log_function (tls_log_func
);
938 gnutls_global_set_log_level (info
.debug
);
940 printf ("Setting log level to %d\n", info
.debug
);
942 if ((ret
= gnutls_global_init ()) < 0)
943 error (EXIT_FAILURE
, 0, "global_init: %s", gnutls_strerror (ret
));
945 if ((ret
= gnutls_global_init_extra ()) < 0)
946 error (EXIT_FAILURE
, 0, "global_init_extra: %s", gnutls_strerror (ret
));
948 if (info
.quick_random
!= 0)
949 gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM
, 0);
953 case ACTION_SELF_SIGNED
:
954 generate_self_signed ();
956 case ACTION_GENERATE_PRIVKEY
:
957 generate_private_key ();
959 case ACTION_CERT_INFO
:
962 case ACTION_GENERATE_REQUEST
:
965 case ACTION_GENERATE_CERTIFICATE
:
966 generate_signed_certificate ();
968 case ACTION_VERIFY_CHAIN
:
971 case ACTION_PRIVKEY_INFO
:
974 case ACTION_UPDATE_CERTIFICATE
:
975 update_signed_certificate ();
977 case ACTION_TO_PKCS12
:
980 case ACTION_PKCS12_INFO
:
983 case ACTION_GENERATE_DH
:
984 generate_prime (info
.bits
, 1);
987 generate_prime (info
.bits
, 0);
989 case ACTION_CRL_INFO
:
995 case ACTION_GENERATE_CRL
:
996 generate_signed_crl ();
998 case ACTION_VERIFY_CRL
:
1001 case ACTION_SMIME_TO_P7
:
1004 case ACTION_GENERATE_PROXY
:
1005 generate_proxy_certificate ();
1007 case ACTION_GENERATE_PKCS8
:
1010 #ifdef ENABLE_OPENPGP
1011 case ACTION_PGP_INFO
:
1012 pgp_certificate_info ();
1014 case ACTION_PGP_PRIVKEY_INFO
:
1015 pgp_privkey_info ();
1017 case ACTION_RING_INFO
:
1021 case ACTION_REQUEST
:
1031 #define MAX_CRTS 500
1033 certificate_info (void)
1035 gnutls_x509_crt_t crt
[MAX_CRTS
];
1039 unsigned int crt_num
;
1041 pem
.data
= fread_file (infile
, &size
);
1046 gnutls_x509_crt_list_import (crt
, &crt_num
, &pem
, info
.incert_format
,
1047 GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED
);
1048 if (ret
== GNUTLS_E_SHORT_MEMORY_BUFFER
)
1050 error (0, 0, "too many certificates (%d); "
1051 "will only read the first %d", crt_num
, MAX_CRTS
);
1053 ret
= gnutls_x509_crt_list_import (crt
, &crt_num
, &pem
,
1054 info
.incert_format
, 0);
1057 error (EXIT_FAILURE
, 0, "import error: %s", gnutls_strerror (ret
));
1063 if (count
> 1 && info
.outcert_format
== GNUTLS_X509_FMT_DER
)
1065 error (0, 0, "cannot output multiple certificates in DER format; "
1066 "using PEM instead");
1067 info
.outcert_format
= GNUTLS_X509_FMT_PEM
;
1070 for (i
= 0; i
< count
; i
++)
1073 fprintf (outfile
, "\n");
1075 if (info
.outcert_format
== GNUTLS_X509_FMT_PEM
)
1076 print_certificate_info (crt
[i
], outfile
, 1);
1078 size
= sizeof (buffer
);
1079 ret
= gnutls_x509_crt_export (crt
[i
], info
.outcert_format
, buffer
,
1082 error (EXIT_FAILURE
, 0, "export error: %s", gnutls_strerror (ret
));
1083 fwrite (buffer
, 1, size
, outfile
);
1085 gnutls_x509_crt_deinit (crt
[i
]);
1089 #ifdef ENABLE_OPENPGP
1092 pgp_certificate_info (void)
1094 gnutls_openpgp_crt_t crt
;
1097 gnutls_datum_t pem
, out_data
;
1098 unsigned int verify_status
;
1100 pem
.data
= fread_file (infile
, &size
);
1103 ret
= gnutls_openpgp_crt_init (&crt
);
1105 error (EXIT_FAILURE
, 0, "openpgp_crt_init: %s", gnutls_strerror (ret
));
1107 ret
= gnutls_openpgp_crt_import (crt
, &pem
, info
.incert_format
);
1110 error (EXIT_FAILURE
, 0, "import error: %s", gnutls_strerror (ret
));
1114 if (info
.outcert_format
== GNUTLS_OPENPGP_FMT_BASE64
)
1116 ret
= gnutls_openpgp_crt_print (crt
, 0, &out_data
);
1120 fprintf (outfile
, "%s\n", out_data
.data
);
1121 gnutls_free (out_data
.data
);
1126 ret
= gnutls_openpgp_crt_verify_self(crt
, 0, &verify_status
);
1129 error (EXIT_FAILURE
, 0, "verify signature error: %s", gnutls_strerror (ret
));
1132 if (verify_status
& GNUTLS_CERT_INVALID
)
1134 fprintf (outfile
, "Self Signature verification: failed\n\n");
1138 fprintf (outfile
, "Self Signature verification: ok (%x)\n\n", verify_status
);
1141 size
= sizeof (buffer
);
1142 ret
= gnutls_openpgp_crt_export (crt
, info
.outcert_format
, buffer
, &size
);
1145 error (EXIT_FAILURE
, 0, "export error: %s", gnutls_strerror (ret
));
1146 fwrite (buffer
, 1, size
, outfile
);
1149 fprintf (outfile
, "%s\n", buffer
);
1150 gnutls_openpgp_crt_deinit (crt
);
1154 pgp_privkey_info (void)
1156 gnutls_openpgp_privkey_t key
;
1157 gnutls_openpgp_keyid_t keyid
;
1159 int ret
, i
, subkeys
;
1163 size
= fread (buffer
, 1, sizeof (buffer
) - 1, infile
);
1166 gnutls_openpgp_privkey_init (&key
);
1171 ret
= gnutls_openpgp_privkey_import (key
, &pem
, info
.incert_format
,
1175 error (EXIT_FAILURE
, 0, "import error: %s", gnutls_strerror (ret
));
1177 /* Public key algorithm
1179 subkeys
= gnutls_openpgp_privkey_get_subkey_count (key
);
1181 error (EXIT_FAILURE
, 0, "privkey_get_subkey_count: %s",
1182 gnutls_strerror (subkeys
));
1184 for (i
= -1; i
< subkeys
; i
++)
1188 fprintf (outfile
, "Subkey[%d]:\n", i
);
1190 fprintf (outfile
, "Public Key Info:\n");
1193 ret
= gnutls_openpgp_privkey_get_pk_algorithm (key
, NULL
);
1195 ret
= gnutls_openpgp_privkey_get_subkey_pk_algorithm (key
, i
, NULL
);
1197 fprintf (outfile
, "\tPublic Key Algorithm: ");
1198 cprint
= gnutls_pk_algorithm_get_name (ret
);
1199 fprintf (outfile
, "%s\n", cprint
? cprint
: "Unknown");
1201 /* Print the raw public and private keys
1204 if (ret
== GNUTLS_PK_RSA
)
1206 gnutls_datum_t m
, e
, d
, p
, q
, u
;
1210 gnutls_openpgp_privkey_export_rsa_raw (key
, &m
, &e
, &d
, &p
,
1214 gnutls_openpgp_privkey_export_subkey_rsa_raw (key
, i
, &m
,
1218 fprintf (stderr
, "Error in key RSA data export: %s\n",
1219 gnutls_strerror (ret
));
1221 print_rsa_pkey (&m
, &e
, &d
, &p
, &q
, &u
);
1224 else if (ret
== GNUTLS_PK_DSA
)
1226 gnutls_datum_t p
, q
, g
, y
, x
;
1230 gnutls_openpgp_privkey_export_dsa_raw (key
, &p
, &q
, &g
, &y
, &x
);
1233 gnutls_openpgp_privkey_export_subkey_dsa_raw (key
, i
, &p
,
1236 fprintf (stderr
, "Error in key DSA data export: %s\n",
1237 gnutls_strerror (ret
));
1239 print_dsa_pkey (&x
, &y
, &p
, &q
, &g
);
1242 fprintf (outfile
, "\n");
1244 size
= sizeof (buffer
);
1246 ret
= gnutls_openpgp_privkey_get_key_id (key
, keyid
);
1248 ret
= gnutls_openpgp_privkey_get_subkey_id (key
, i
, keyid
);
1252 fprintf (stderr
, "Error in key id calculation: %s\n",
1253 gnutls_strerror (ret
));
1257 fprintf (outfile
, "Public Key ID: %s\n", raw_to_string (keyid
, 8));
1262 size
= sizeof (buffer
);
1263 ret
= gnutls_openpgp_privkey_export (key
, GNUTLS_OPENPGP_FMT_BASE64
,
1264 NULL
, 0, buffer
, &size
);
1266 error (EXIT_FAILURE
, 0, "export error: %s", gnutls_strerror (ret
));
1268 fprintf (outfile
, "\n%s\n", buffer
);
1270 gnutls_openpgp_privkey_deinit (key
);
1274 pgp_ring_info (void)
1276 gnutls_openpgp_keyring_t ring
;
1277 gnutls_openpgp_crt_t crt
;
1282 pem
.data
= fread_file (infile
, &size
);
1285 ret
= gnutls_openpgp_keyring_init (&ring
);
1287 error (EXIT_FAILURE
, 0, "openpgp_keyring_init: %s",
1288 gnutls_strerror (ret
));
1290 ret
= gnutls_openpgp_keyring_import (ring
, &pem
, info
.incert_format
);
1293 error (EXIT_FAILURE
, 0, "import error: %s", gnutls_strerror (ret
));
1297 count
= gnutls_openpgp_keyring_get_crt_count (ring
);
1299 fprintf (outfile
, "Keyring contains %d OpenPGP certificates\n\n", count
);
1301 error (EXIT_FAILURE
, 0, "keyring error: %s", gnutls_strerror (count
));
1303 for (i
= 0; i
< count
; i
++)
1305 ret
= gnutls_openpgp_keyring_get_crt (ring
, i
, &crt
);
1307 error (EXIT_FAILURE
, 0, "export error: %s", gnutls_strerror (ret
));
1309 size
= sizeof (buffer
);
1310 ret
= gnutls_openpgp_crt_export (crt
, info
.outcert_format
,
1313 error (EXIT_FAILURE
, 0, "export error: %s", gnutls_strerror (ret
));
1315 fwrite (buffer
, 1, size
, outfile
);
1316 fprintf (outfile
, "\n\n");
1318 gnutls_openpgp_crt_deinit (crt
);
1323 gnutls_openpgp_keyring_deinit (ring
);
1330 print_hex_datum (gnutls_datum_t
* dat
)
1334 fprintf (outfile
, "\n" SPACE
);
1335 for (j
= 0; j
< dat
->size
; j
++)
1337 fprintf (outfile
, "%.2x:", (unsigned char) dat
->data
[j
]);
1338 if ((j
+ 1) % 15 == 0)
1339 fprintf (outfile
, "\n" SPACE
);
1341 fprintf (outfile
, "\n");
1346 print_certificate_info (gnutls_x509_crt_t crt
, FILE * out
, unsigned int all
)
1348 gnutls_datum_t cinfo
;
1352 ret
= gnutls_x509_crt_print (crt
, GNUTLS_CRT_PRINT_FULL
, &cinfo
);
1354 ret
= gnutls_x509_crt_print (crt
, GNUTLS_CRT_PRINT_UNSIGNED_FULL
, &cinfo
);
1357 fprintf (out
, "%s\n", cinfo
.data
);
1358 gnutls_free (cinfo
.data
);
1361 if (out
== stderr
&& batch
== 0) /* interactive */
1362 if (read_yesno ("Is the above information ok? (Y/N): ") == 0)
1369 print_crl_info (gnutls_x509_crl_t crl
, FILE * out
)
1371 gnutls_datum_t cinfo
;
1375 ret
= gnutls_x509_crl_print (crl
, GNUTLS_CRT_PRINT_FULL
, &cinfo
);
1377 error (EXIT_FAILURE
, 0, "crl_print: %s", gnutls_strerror (ret
));
1379 fprintf (out
, "%s\n", cinfo
.data
);
1381 gnutls_free (cinfo
.data
);
1383 size
= sizeof (buffer
);
1384 ret
= gnutls_x509_crl_export (crl
, GNUTLS_X509_FMT_PEM
, buffer
, &size
);
1386 error (EXIT_FAILURE
, 0, "crl_export: %s", gnutls_strerror (ret
));
1388 fwrite (buffer
, 1, size
, outfile
);
1394 gnutls_x509_crl_t crl
;
1399 ret
= gnutls_x509_crl_init (&crl
);
1401 error (EXIT_FAILURE
, 0, "crl_init: %s", gnutls_strerror (ret
));
1403 pem
.data
= fread_file (infile
, &size
);
1407 error (EXIT_FAILURE
, errno
, "%s", info
.infile
? info
.infile
:
1410 ret
= gnutls_x509_crl_import (crl
, &pem
, info
.incert_format
);
1414 error (EXIT_FAILURE
, 0, "import error: %s", gnutls_strerror (ret
));
1416 print_crl_info (crl
, outfile
);
1418 gnutls_x509_crl_deinit (crl
);
1422 print_crq_info (gnutls_x509_crq_t crq
, FILE * out
)
1424 gnutls_datum_t cinfo
;
1428 if (info
.outcert_format
== GNUTLS_X509_FMT_PEM
)
1430 ret
= gnutls_x509_crq_print (crq
, GNUTLS_CRT_PRINT_FULL
, &cinfo
);
1432 error (EXIT_FAILURE
, 0, "crq_print: %s", gnutls_strerror (ret
));
1434 fprintf (out
, "%s\n", cinfo
.data
);
1436 gnutls_free (cinfo
.data
);
1439 size
= sizeof (buffer
);
1440 ret
= gnutls_x509_crq_export (crq
, info
.outcert_format
, buffer
, &size
);
1442 error (EXIT_FAILURE
, 0, "crq_export: %s", gnutls_strerror (ret
));
1444 fwrite (buffer
, 1, size
, outfile
);
1450 gnutls_x509_crq_t crq
;
1455 ret
= gnutls_x509_crq_init (&crq
);
1457 error (EXIT_FAILURE
, 0, "crq_init: %s", gnutls_strerror (ret
));
1459 pem
.data
= fread_file (infile
, &size
);
1463 error (EXIT_FAILURE
, errno
, "%s", info
.infile
? info
.infile
:
1466 ret
= gnutls_x509_crq_import (crq
, &pem
, info
.incert_format
);
1470 error (EXIT_FAILURE
, 0, "import error: %s", gnutls_strerror (ret
));
1472 print_crq_info (crq
, outfile
);
1474 gnutls_x509_crq_deinit (crq
);
1480 gnutls_x509_privkey_t key
;
1487 size
= fread (buffer
, 1, sizeof (buffer
) - 1, infile
);
1490 gnutls_x509_privkey_init (&key
);
1497 ret
= gnutls_x509_privkey_import (key
, &pem
, info
.incert_format
);
1499 /* If we failed to import the certificate previously try PKCS #8 */
1500 if (info
.pkcs8
|| ret
== GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR
)
1502 /* first try to import the key without asking any password */
1503 ret
= gnutls_x509_privkey_import_pkcs8 (key
, &pem
,
1505 NULL
, GNUTLS_PKCS_PLAIN
);
1512 ret
= gnutls_x509_privkey_import_pkcs8 (key
, &pem
,
1518 error (EXIT_FAILURE
, 0, "import error: %s", gnutls_strerror (ret
));
1520 /* Public key algorithm
1522 fprintf (outfile
, "Public Key Info:\n");
1523 ret
= gnutls_x509_privkey_get_pk_algorithm (key
);
1524 fprintf (outfile
, "\tPublic Key Algorithm: ");
1526 cprint
= gnutls_pk_algorithm_get_name (ret
);
1527 fprintf (outfile
, "%s\n", cprint
? cprint
: "Unknown");
1529 /* Print the raw public and private keys
1531 if (ret
== GNUTLS_PK_RSA
)
1533 gnutls_datum_t m
, e
, d
, p
, q
, u
;
1535 ret
= gnutls_x509_privkey_export_rsa_raw (key
, &m
, &e
, &d
, &p
, &q
, &u
);
1537 fprintf (stderr
, "Error in key RSA data export: %s\n",
1538 gnutls_strerror (ret
));
1541 print_rsa_pkey (&m
, &e
, &d
, &p
, &q
, &u
);
1542 gnutls_free (m
.data
);
1543 gnutls_free (e
.data
);
1544 gnutls_free (d
.data
);
1545 gnutls_free (p
.data
);
1546 gnutls_free (q
.data
);
1547 gnutls_free (u
.data
);
1550 else if (ret
== GNUTLS_PK_DSA
)
1552 gnutls_datum_t p
, q
, g
, y
, x
;
1554 ret
= gnutls_x509_privkey_export_dsa_raw (key
, &p
, &q
, &g
, &y
, &x
);
1556 fprintf (stderr
, "Error in key DSA data export: %s\n",
1557 gnutls_strerror (ret
));
1560 print_dsa_pkey (&x
, &y
, &p
, &q
, &g
);
1561 gnutls_free (x
.data
);
1562 gnutls_free (y
.data
);
1563 gnutls_free (p
.data
);
1564 gnutls_free (q
.data
);
1565 gnutls_free (g
.data
);
1569 fprintf (outfile
, "\n");
1571 size
= sizeof (buffer
);
1572 if ((ret
= gnutls_x509_privkey_get_key_id (key
, 0, buffer
, &size
)) < 0)
1574 fprintf (stderr
, "Error in key id calculation: %s\n",
1575 gnutls_strerror (ret
));
1579 fprintf (outfile
, "Public Key ID: %s\n", raw_to_string (buffer
, size
));
1582 if (info
.fix_key
!= 0)
1584 ret
= gnutls_x509_privkey_fix (key
);
1586 error (EXIT_FAILURE
, 0, "privkey_fix: %s", gnutls_strerror (ret
));
1589 size
= sizeof (buffer
);
1590 ret
= gnutls_x509_privkey_export (key
, GNUTLS_X509_FMT_PEM
, buffer
, &size
);
1592 error (EXIT_FAILURE
, 0, "export error: %s", gnutls_strerror (ret
));
1594 fprintf (outfile
, "\n%s\n", buffer
);
1596 gnutls_x509_privkey_deinit (key
);
1600 /* Load the private key.
1601 * @mand should be non zero if it is required to read a private key.
1603 gnutls_x509_privkey_t
1604 load_private_key (int mand
)
1606 gnutls_x509_privkey_t key
;
1611 if (!info
.privkey
&& !mand
)
1614 if (info
.privkey
== NULL
)
1615 error (EXIT_FAILURE
, 0, "missing --load-privkey");
1617 ret
= gnutls_x509_privkey_init (&key
);
1619 error (EXIT_FAILURE
, 0, "privkey_init: %s", gnutls_strerror (ret
));
1621 dat
.data
= read_binary_file (info
.privkey
, &size
);
1625 error (EXIT_FAILURE
, errno
, "reading --load-privkey: %s", info
.privkey
);
1629 const char *pass
= get_pass ();
1631 gnutls_x509_privkey_import_pkcs8 (key
, &dat
, info
.incert_format
,
1635 ret
= gnutls_x509_privkey_import (key
, &dat
, info
.incert_format
);
1639 if (ret
== GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR
)
1641 error (EXIT_FAILURE
, 0,
1642 "import error: could not find a valid PEM header; "
1643 "check if your key is PKCS #8 or PKCS #12 encoded");
1647 error (EXIT_FAILURE
, 0, "importing --load-privkey: %s: %s",
1648 info
.privkey
, gnutls_strerror (ret
));
1653 /* Load the Certificate Request.
1658 gnutls_x509_crq_t crq
;
1666 ret
= gnutls_x509_crq_init (&crq
);
1668 error (EXIT_FAILURE
, 0, "crq_init: %s", gnutls_strerror (ret
));
1670 dat
.data
= read_binary_file (info
.request
, &size
);
1674 error (EXIT_FAILURE
, errno
, "reading --load-request: %s", info
.request
);
1676 ret
= gnutls_x509_crq_import (crq
, &dat
, info
.incert_format
);
1677 if (ret
== GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR
)
1679 error (EXIT_FAILURE
, 0,
1680 "import error: could not find a valid PEM header");
1685 error (EXIT_FAILURE
, 0, "importing --load-request: %s: %s",
1686 info
.request
, gnutls_strerror (ret
));
1691 /* Load the CA's private key.
1693 gnutls_x509_privkey_t
1694 load_ca_private_key (void)
1696 gnutls_x509_privkey_t key
;
1701 if (info
.ca_privkey
== NULL
)
1702 error (EXIT_FAILURE
, 0, "missing --load-ca-privkey");
1704 ret
= gnutls_x509_privkey_init (&key
);
1706 error (EXIT_FAILURE
, 0, "privkey_init: %s", gnutls_strerror (ret
));
1708 dat
.data
= read_binary_file (info
.ca_privkey
, &size
);
1712 error (EXIT_FAILURE
, errno
, "reading --load-ca-privkey: %s",
1717 const char *pass
= get_pass ();
1719 gnutls_x509_privkey_import_pkcs8 (key
, &dat
, info
.incert_format
,
1723 ret
= gnutls_x509_privkey_import (key
, &dat
, info
.incert_format
);
1726 error (EXIT_FAILURE
, 0, "importing --load-ca-privkey: %s: %s",
1727 info
.ca_privkey
, gnutls_strerror (ret
));
1732 /* Loads the CA's certificate
1737 gnutls_x509_crt_t crt
;
1742 if (info
.ca
== NULL
)
1743 error (EXIT_FAILURE
, 0, "missing --load-ca-certificate");
1745 ret
= gnutls_x509_crt_init (&crt
);
1747 error (EXIT_FAILURE
, 0, "crt_init: %s", gnutls_strerror (ret
));
1749 dat
.data
= read_binary_file (info
.ca
, &size
);
1753 error (EXIT_FAILURE
, errno
, "reading --load-ca-certificate: %s", info
.ca
);
1755 ret
= gnutls_x509_crt_import (crt
, &dat
, info
.incert_format
);
1758 error (EXIT_FAILURE
, 0, "importing --load-ca-certificate: %s: %s",
1759 info
.ca
, gnutls_strerror (ret
));
1764 /* Loads the certificate
1765 * If mand is non zero then a certificate is mandatory. Otherwise
1766 * null will be returned if the certificate loading fails.
1769 load_cert (int mand
)
1771 gnutls_x509_crt_t
*crt
;
1774 crt
= load_cert_list (mand
, &size
);
1776 return crt
? crt
[0] : NULL
;
1779 #define MAX_CERTS 256
1781 /* Loads a certificate list
1784 load_cert_list (int mand
, size_t * crt_size
)
1787 static gnutls_x509_crt_t crt
[MAX_CERTS
];
1795 fprintf (stderr
, "Loading certificate list...\n");
1797 if (info
.cert
== NULL
)
1800 error (EXIT_FAILURE
, 0, "missing --load-certificate");
1805 fd
= fopen (info
.cert
, "r");
1807 error (EXIT_FAILURE
, errno
, "%s", info
.cert
);
1809 size
= fread (buffer
, 1, sizeof (buffer
) - 1, fd
);
1817 for (i
= 0; i
< MAX_CERTS
; i
++)
1819 ret
= gnutls_x509_crt_init (&crt
[i
]);
1821 error (EXIT_FAILURE
, 0, "crt_init: %s", gnutls_strerror (ret
));
1824 dat
.size
= ptr_size
;
1826 ret
= gnutls_x509_crt_import (crt
[i
], &dat
, info
.incert_format
);
1827 if (ret
< 0 && *crt_size
> 0)
1830 error (EXIT_FAILURE
, 0, "crt_import: %s", gnutls_strerror (ret
));
1832 ptr
= strstr (ptr
, "---END");
1839 (unsigned int) ((unsigned char *) ptr
- (unsigned char *) buffer
);
1846 fprintf (stderr
, "Loaded %d certificates.\n", (int) *crt_size
);
1852 /* Generate a PKCS #10 certificate request.
1855 generate_request (void)
1857 gnutls_x509_crq_t crq
;
1858 gnutls_x509_privkey_t key
;
1859 int ret
, ca_status
, path_len
;
1861 unsigned int usage
= 0;
1863 fprintf (stderr
, "Generating a PKCS #10 certificate request...\n");
1865 ret
= gnutls_x509_crq_init (&crq
);
1867 error (EXIT_FAILURE
, 0, "crq_init: %s", gnutls_strerror (ret
));
1869 /* Load the private key.
1871 key
= load_private_key (0);
1874 key
= generate_private_key_int ();
1876 print_private_key (key
);
1881 get_country_crq_set (crq
);
1882 get_organization_crq_set (crq
);
1883 get_unit_crq_set (crq
);
1884 get_locality_crq_set (crq
);
1885 get_state_crq_set (crq
);
1886 get_cn_crq_set (crq
);
1887 get_uid_crq_set (crq
);
1888 get_oid_crq_set (crq
);
1890 get_dns_name_set (TYPE_CRQ
, crq
);
1891 get_ip_addr_set (TYPE_CRQ
, crq
);
1892 get_email_set (TYPE_CRQ
, crq
);
1894 pass
= get_challenge_pass ();
1896 if (pass
!= NULL
&& pass
[0] != 0)
1898 ret
= gnutls_x509_crq_set_challenge_password (crq
, pass
);
1900 error (EXIT_FAILURE
, 0, "set_pass: %s", gnutls_strerror (ret
));
1903 if (info
.crq_extensions
!= 0)
1905 ca_status
= get_ca_status ();
1907 path_len
= get_path_len ();
1911 ret
= gnutls_x509_crq_set_basic_constraints (crq
, ca_status
, path_len
);
1913 error (EXIT_FAILURE
, 0, "set_basic_constraints: %s",
1914 gnutls_strerror (ret
));
1917 ret
= get_sign_status (1);
1919 usage
|= GNUTLS_KEY_DIGITAL_SIGNATURE
;
1921 ret
= get_encrypt_status (1);
1923 usage
|= GNUTLS_KEY_KEY_ENCIPHERMENT
;
1925 usage
|= GNUTLS_KEY_DIGITAL_SIGNATURE
;
1929 ret
= get_cert_sign_status ();
1931 usage
|= GNUTLS_KEY_KEY_CERT_SIGN
;
1933 ret
= get_crl_sign_status ();
1935 usage
|= GNUTLS_KEY_CRL_SIGN
;
1937 ret
= get_code_sign_status ();
1941 gnutls_x509_crq_set_key_purpose_oid (crq
,
1942 GNUTLS_KP_CODE_SIGNING
, 0);
1944 error (EXIT_FAILURE
, 0, "key_kp: %s", gnutls_strerror (ret
));
1947 ret
= get_ocsp_sign_status ();
1951 gnutls_x509_crq_set_key_purpose_oid (crq
,
1952 GNUTLS_KP_OCSP_SIGNING
, 0);
1954 error (EXIT_FAILURE
, 0, "key_kp: %s", gnutls_strerror (ret
));
1957 ret
= get_time_stamp_status ();
1961 gnutls_x509_crq_set_key_purpose_oid (crq
,
1962 GNUTLS_KP_TIME_STAMPING
, 0);
1964 error (EXIT_FAILURE
, 0, "key_kp: %s", gnutls_strerror (ret
));
1969 ret
= gnutls_x509_crq_set_key_usage (crq
, usage
);
1971 error (EXIT_FAILURE
, 0, "key_usage: %s", gnutls_strerror (ret
));
1973 ret
= get_tls_client_status ();
1976 ret
= gnutls_x509_crq_set_key_purpose_oid (crq
,
1977 GNUTLS_KP_TLS_WWW_CLIENT
, 0);
1979 error (EXIT_FAILURE
, 0, "key_kp: %s", gnutls_strerror (ret
));
1982 ret
= get_tls_server_status ();
1985 ret
= gnutls_x509_crq_set_key_purpose_oid (crq
,
1986 GNUTLS_KP_TLS_WWW_SERVER
, 0);
1988 error (EXIT_FAILURE
, 0, "key_kp: %s", gnutls_strerror (ret
));
1991 ret
= gnutls_x509_crq_set_key (crq
, key
);
1993 error (EXIT_FAILURE
, 0, "set_key: %s", gnutls_strerror (ret
));
1995 ret
= gnutls_x509_crq_sign (crq
, key
);
1997 error (EXIT_FAILURE
, 0, "sign: %s", gnutls_strerror (ret
));
1999 print_crq_info (crq
, outfile
);
2001 gnutls_x509_crq_deinit (crq
);
2002 gnutls_x509_privkey_deinit (key
);
2006 static void print_verification_res (gnutls_x509_crt_t crt
,
2007 gnutls_x509_crt_t issuer
,
2008 gnutls_x509_crl_t
* crl_list
,
2011 #define CERT_SEP "-----BEGIN CERT"
2012 #define CRL_SEP "-----BEGIN X509 CRL"
2014 _verify_x509_mem (const void *cert
, int cert_size
)
2019 char issuer_name
[256];
2021 size_t issuer_name_size
;
2023 gnutls_x509_crt_t
*x509_cert_list
= NULL
;
2024 gnutls_x509_crl_t
*x509_crl_list
= NULL
;
2025 int x509_ncerts
, x509_ncrls
;
2028 /* Decode the CA certificate
2031 /* Decode the CRL list
2037 if (strstr (ptr
, CRL_SEP
) != NULL
) /* if CRLs exist */
2041 (gnutls_x509_crl_t
*) realloc (x509_crl_list
,
2042 i
* sizeof (gnutls_x509_crl_t
));
2043 if (x509_crl_list
== NULL
)
2044 error (EXIT_FAILURE
, 0, "memory error");
2046 tmp
.data
= (char *) ptr
;
2047 tmp
.size
= cert_size
;
2049 (unsigned int) ((unsigned char *) ptr
- (unsigned char *) cert
);
2051 ret
= gnutls_x509_crl_init (&x509_crl_list
[i
- 1]);
2053 error (EXIT_FAILURE
, 0, "error parsing CRL[%d]: %s", i
,
2054 gnutls_strerror (ret
));
2056 ret
= gnutls_x509_crl_import (x509_crl_list
[i
- 1], &tmp
,
2057 GNUTLS_X509_FMT_PEM
);
2059 error (EXIT_FAILURE
, 0, "error parsing CRL[%d]: %s", i
,
2060 gnutls_strerror (ret
));
2062 /* now we move ptr after the pem header */
2063 ptr
= strstr (ptr
, CRL_SEP
);
2069 while ((ptr
= strstr (ptr
, CRL_SEP
)) != NULL
);
2074 /* Decode the certificate chain.
2083 (gnutls_x509_crt_t
*) realloc (x509_cert_list
,
2084 i
* sizeof (gnutls_x509_crt_t
));
2085 if (x509_cert_list
== NULL
)
2086 error (EXIT_FAILURE
, 0, "memory error");
2089 tmp
.data
= (char *) ptr
;
2090 tmp
.size
= cert_size
;
2092 (unsigned int) ((unsigned char *) ptr
- (unsigned char *) cert
);
2094 ret
= gnutls_x509_crt_init (&x509_cert_list
[i
- 1]);
2096 error (EXIT_FAILURE
, 0, "error parsing certificate[%d]: %s", i
,
2097 gnutls_strerror (ret
));
2100 gnutls_x509_crt_import (x509_cert_list
[i
- 1], &tmp
,
2101 GNUTLS_X509_FMT_PEM
);
2103 error (EXIT_FAILURE
, 0, "error parsing certificate[%d]: %s", i
,
2104 gnutls_strerror (ret
));
2109 /* verify the previous certificate using this one
2113 name_size
= sizeof (name
);
2115 gnutls_x509_crt_get_dn (x509_cert_list
[i
- 2], name
, &name_size
);
2117 error (EXIT_FAILURE
, 0, "get_dn: %s", gnutls_strerror (ret
));
2119 fprintf (outfile
, "Certificate[%d]: %s\n", i
- 2, name
);
2123 issuer_name_size
= sizeof (issuer_name
);
2125 gnutls_x509_crt_get_issuer_dn (x509_cert_list
[i
- 2],
2126 issuer_name
, &issuer_name_size
);
2128 error (EXIT_FAILURE
, 0, "get_issuer_dn: %s",
2129 gnutls_strerror (ret
));
2131 fprintf (outfile
, "\tIssued by: %s\n", issuer_name
);
2133 /* Get the Issuer's name
2135 name_size
= sizeof (name
);
2137 gnutls_x509_crt_get_dn (x509_cert_list
[i
- 1], name
, &name_size
);
2139 error (EXIT_FAILURE
, 0, "get_dn: %s", gnutls_strerror (ret
));
2141 fprintf (outfile
, "\tVerifying against certificate[%d].\n", i
- 1);
2143 if (strcmp (issuer_name
, name
) != 0)
2145 fprintf (stderr
, "Error: Issuer's name: %s\n", name
);
2146 error (EXIT_FAILURE
, 0,
2147 "issuer name does not match the next certificate");
2150 fprintf (outfile
, "\tVerification output: ");
2151 print_verification_res (x509_cert_list
[i
- 2],
2152 x509_cert_list
[i
- 1], x509_crl_list
,
2154 fprintf (outfile
, ".\n\n");
2159 /* now we move ptr after the pem header
2161 ptr
= strstr (ptr
, CERT_SEP
);
2167 while ((ptr
= strstr (ptr
, CERT_SEP
)) != NULL
);
2169 x509_ncerts
= i
- 1;
2171 /* The last certificate in the list will be used as
2172 * a CA (should be self signed).
2174 name_size
= sizeof (name
);
2175 ret
= gnutls_x509_crt_get_dn (x509_cert_list
[x509_ncerts
- 1], name
,
2178 error (EXIT_FAILURE
, 0, "get_dn: %s", gnutls_strerror (ret
));
2180 fprintf (outfile
, "Certificate[%d]: %s\n", x509_ncerts
- 1, name
);
2184 issuer_name_size
= sizeof (issuer_name
);
2186 gnutls_x509_crt_get_issuer_dn (x509_cert_list
[x509_ncerts
- 1],
2187 issuer_name
, &issuer_name_size
);
2189 error (EXIT_FAILURE
, 0, "get_issuer_dn: %s", gnutls_strerror (ret
));
2191 fprintf (outfile
, "\tIssued by: %s\n", name
);
2193 if (strcmp (issuer_name
, name
) != 0)
2194 error (EXIT_FAILURE
, 0, "the last certificate is not self signed");
2196 fprintf (outfile
, "\tVerification output: ");
2197 print_verification_res (x509_cert_list
[x509_ncerts
- 1],
2198 x509_cert_list
[x509_ncerts
- 1], x509_crl_list
,
2201 fprintf (outfile
, ".\n\n");
2203 /* Verify using internal algorithm too. */
2207 ret
= gnutls_x509_crt_list_verify (x509_cert_list
, x509_ncerts
,
2208 &x509_cert_list
[x509_ncerts
- 1], 1,
2211 GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT
,
2214 error (EXIT_FAILURE
, 0, "gnutls_x509_crt_list_verify: %s",
2215 gnutls_strerror (ret
));
2217 fprintf (outfile
, "Chain verification output: ");
2219 if (verify_status
& GNUTLS_CERT_INVALID
)
2221 fprintf (outfile
, "Not verified");
2225 fprintf (outfile
, "Verified");
2228 if (verify_status
& GNUTLS_CERT_SIGNER_NOT_CA
)
2230 fprintf (outfile
, ", ");
2231 fprintf (outfile
, "Issuer is not a CA");
2234 if (verify_status
& GNUTLS_CERT_INSECURE_ALGORITHM
)
2236 fprintf (outfile
, ", ");
2237 fprintf (outfile
, "Insecure algorithm");
2240 fprintf (outfile
, ".\n");
2243 for (i
= 0; i
< x509_ncerts
; i
++)
2244 gnutls_x509_crt_deinit (x509_cert_list
[i
]);
2246 for (i
= 0; i
< x509_ncrls
; i
++)
2247 gnutls_x509_crl_deinit (x509_crl_list
[i
]);
2249 free (x509_cert_list
);
2250 free (x509_crl_list
);
2253 error (EXIT_FAILURE
, 0, "verification error: %s", gnutls_strerror (ret
));
2259 print_verification_res (gnutls_x509_crt_t crt
,
2260 gnutls_x509_crt_t issuer
,
2261 gnutls_x509_crl_t
* crl_list
, int crl_list_size
)
2263 unsigned int output
;
2266 time_t now
= time (0);
2268 ret
= gnutls_x509_crt_verify (crt
, &issuer
, 1, 0, &output
);
2270 error (EXIT_FAILURE
, 0, "verification error: %s", gnutls_strerror (ret
));
2272 if (output
& GNUTLS_CERT_INVALID
)
2274 fprintf (outfile
, "Not verified");
2279 fprintf (outfile
, "Verified");
2283 if (output
& GNUTLS_CERT_SIGNER_NOT_CA
)
2286 fprintf (outfile
, ", ");
2287 fprintf (outfile
, "Issuer is not a CA");
2291 if (output
& GNUTLS_CERT_INSECURE_ALGORITHM
)
2294 fprintf (outfile
, ", ");
2295 fprintf (outfile
, "Insecure algorithm");
2299 /* Check expiration dates.
2302 if (gnutls_x509_crt_get_activation_time (crt
) > now
)
2305 fprintf (outfile
, ", ");
2307 fprintf (outfile
, "Not activated");
2310 if (gnutls_x509_crt_get_expiration_time (crt
) < now
)
2313 fprintf (outfile
, ", ");
2315 fprintf (outfile
, "Expired");
2318 ret
= gnutls_x509_crt_check_revocation (crt
, crl_list
, crl_list_size
);
2320 error (EXIT_FAILURE
, 0, "revocation check: %s", gnutls_strerror (ret
));
2325 fprintf (outfile
, ", ");
2327 fprintf (outfile
, "Revoked");
2337 buf
= fread_file (infile
, &size
);
2339 error (EXIT_FAILURE
, errno
, "reading chain");
2343 _verify_x509_mem (buf
, size
);
2350 size_t size
, dn_size
;
2352 unsigned int output
;
2356 gnutls_x509_crl_t crl
;
2357 time_t now
= time (0);
2358 gnutls_x509_crt_t issuer
;
2360 issuer
= load_ca_cert ();
2362 fprintf (outfile
, "\nCA certificate:\n");
2364 dn_size
= sizeof (dn
);
2365 ret
= gnutls_x509_crt_get_dn (issuer
, dn
, &dn_size
);
2367 error (EXIT_FAILURE
, 0, "crt_get_dn: %s", gnutls_strerror (ret
));
2369 fprintf (outfile
, "\tSubject: %s\n\n", dn
);
2371 ret
= gnutls_x509_crl_init (&crl
);
2373 error (EXIT_FAILURE
, 0, "crl_init: %s", gnutls_strerror (ret
));
2375 pem
.data
= fread_file (infile
, &size
);
2378 ret
= gnutls_x509_crl_import (crl
, &pem
, info
.incert_format
);
2381 error (EXIT_FAILURE
, 0, "import error: %s", gnutls_strerror (ret
));
2383 print_crl_info (crl
, outfile
);
2385 fprintf (outfile
, "Verification output: ");
2386 ret
= gnutls_x509_crl_verify (crl
, &issuer
, 1, 0, &output
);
2388 error (EXIT_FAILURE
, 0, "verification error: %s", gnutls_strerror (ret
));
2390 if (output
& GNUTLS_CERT_INVALID
)
2392 fprintf (outfile
, "Not verified");
2397 fprintf (outfile
, "Verified");
2401 if (output
& GNUTLS_CERT_SIGNER_NOT_CA
)
2404 fprintf (outfile
, ", ");
2405 fprintf (outfile
, "Issuer is not a CA");
2409 if (output
& GNUTLS_CERT_INSECURE_ALGORITHM
)
2412 fprintf (outfile
, ", ");
2413 fprintf (outfile
, "Insecure algorithm");
2417 /* Check expiration dates.
2420 if (gnutls_x509_crl_get_this_update (crl
) > now
)
2423 fprintf (outfile
, ", ");
2425 fprintf (outfile
, "Issued in the future!");
2428 if (gnutls_x509_crl_get_next_update (crl
) < now
)
2431 fprintf (outfile
, ", ");
2433 fprintf (outfile
, "CRL is not up to date");
2436 fprintf (outfile
, "\n");
2440 cipher_to_flags (const char *cipher
)
2442 if (strcasecmp (cipher
, "3des") == 0)
2444 return GNUTLS_PKCS_USE_PBES2_3DES
;
2446 else if (strcasecmp (cipher
, "aes-128") == 0)
2448 return GNUTLS_PKCS_USE_PBES2_AES_128
;
2450 else if (strcasecmp (cipher
, "aes-192") == 0)
2452 return GNUTLS_PKCS_USE_PBES2_AES_192
;
2454 else if (strcasecmp (cipher
, "aes-256") == 0)
2456 return GNUTLS_PKCS_USE_PBES2_AES_256
;
2458 else if (strcasecmp (cipher
, "rc2-40") == 0)
2460 return GNUTLS_PKCS_USE_PKCS12_RC2_40
;
2463 error (EXIT_FAILURE
, 0, "Unknown cipher %s\n", cipher
);
2468 generate_pkcs8 (void)
2470 gnutls_x509_privkey_t key
;
2474 const char *password
;
2476 fprintf (stderr
, "Generating a PKCS #8 key structure...\n");
2478 key
= load_private_key (1);
2481 password
= info
.pass
;
2483 password
= get_pass ();
2486 flags
= GNUTLS_PKCS_USE_PKCS12_RC2_40
;
2488 flags
= cipher_to_flags (info
.pkcs_cipher
);
2490 if (password
== NULL
|| password
[0] == 0)
2492 flags
= GNUTLS_PKCS_PLAIN
;
2495 size
= sizeof (buffer
);
2497 gnutls_x509_privkey_export_pkcs8 (key
, info
.outcert_format
,
2498 password
, flags
, buffer
, &size
);
2501 error (EXIT_FAILURE
, 0, "key_export: %s", gnutls_strerror (result
));
2503 fwrite (buffer
, 1, size
, outfile
);
2508 #include <gnutls/pkcs12.h>
2512 generate_pkcs12 (void)
2514 gnutls_pkcs12_t pkcs12
;
2515 gnutls_x509_crt_t
*crts
;
2516 gnutls_x509_privkey_t key
;
2519 gnutls_datum_t data
;
2522 unsigned int flags
, i
;
2523 gnutls_datum_t key_id
;
2524 unsigned char _key_id
[20];
2528 fprintf (stderr
, "Generating a PKCS #12 structure...\n");
2530 key
= load_private_key (0);
2531 crts
= load_cert_list (0, &ncrts
);
2533 name
= get_pkcs12_key_name ();
2535 result
= gnutls_pkcs12_init (&pkcs12
);
2537 error (EXIT_FAILURE
, 0, "pkcs12_init: %s", gnutls_strerror (result
));
2544 for (i
= 0; i
< ncrts
; i
++)
2546 gnutls_pkcs12_bag_t bag
;
2548 result
= gnutls_pkcs12_bag_init (&bag
);
2550 error (EXIT_FAILURE
, 0, "bag_init: %s", gnutls_strerror (result
));
2552 result
= gnutls_pkcs12_bag_set_crt (bag
, crts
[i
]);
2554 error (EXIT_FAILURE
, 0, "set_crt[%d]: %s", i
,
2555 gnutls_strerror (result
));
2559 result
= gnutls_pkcs12_bag_set_friendly_name (bag
, indx
, name
);
2561 error (EXIT_FAILURE
, 0, "bag_set_friendly_name: %s",
2562 gnutls_strerror (result
));
2564 size
= sizeof (_key_id
);
2565 result
= gnutls_x509_crt_get_key_id (crts
[i
], 0, _key_id
, &size
);
2567 error (EXIT_FAILURE
, 0, "key_id[%d]: %s", i
,
2568 gnutls_strerror (result
));
2570 key_id
.data
= _key_id
;
2573 result
= gnutls_pkcs12_bag_set_key_id (bag
, indx
, &key_id
);
2575 error (EXIT_FAILURE
, 0, "bag_set_key_id: %s",
2576 gnutls_strerror (result
));
2579 flags
= GNUTLS_PKCS_USE_PKCS12_RC2_40
;
2581 flags
= cipher_to_flags (info
.pkcs_cipher
);
2583 result
= gnutls_pkcs12_bag_encrypt (bag
, pass
, flags
);
2585 error (EXIT_FAILURE
, 0, "bag_encrypt: %s", gnutls_strerror (result
));
2587 result
= gnutls_pkcs12_set_bag (pkcs12
, bag
);
2589 error (EXIT_FAILURE
, 0, "set_bag: %s", gnutls_strerror (result
));
2594 gnutls_pkcs12_bag_t kbag
;
2596 result
= gnutls_pkcs12_bag_init (&kbag
);
2598 error (EXIT_FAILURE
, 0, "bag_init: %s", gnutls_strerror (result
));
2601 flags
= GNUTLS_PKCS_USE_PKCS12_RC2_40
;
2603 flags
= cipher_to_flags (info
.pkcs_cipher
);
2605 size
= sizeof (buffer
);
2607 gnutls_x509_privkey_export_pkcs8 (key
, GNUTLS_X509_FMT_DER
,
2608 pass
, flags
, buffer
, &size
);
2610 error (EXIT_FAILURE
, 0, "key_export: %s", gnutls_strerror (result
));
2615 gnutls_pkcs12_bag_set_data (kbag
,
2616 GNUTLS_BAG_PKCS8_ENCRYPTED_KEY
, &data
);
2618 error (EXIT_FAILURE
, 0, "bag_set_data: %s", gnutls_strerror (result
));
2622 result
= gnutls_pkcs12_bag_set_friendly_name (kbag
, indx
, name
);
2624 error (EXIT_FAILURE
, 0, "bag_set_friendly_name: %s",
2625 gnutls_strerror (result
));
2627 size
= sizeof (_key_id
);
2628 result
= gnutls_x509_privkey_get_key_id (key
, 0, _key_id
, &size
);
2630 error (EXIT_FAILURE
, 0, "key_id: %s", gnutls_strerror (result
));
2632 key_id
.data
= _key_id
;
2635 result
= gnutls_pkcs12_bag_set_key_id (kbag
, indx
, &key_id
);
2637 error (EXIT_FAILURE
, 0, "bag_set_key_id: %s",
2638 gnutls_strerror (result
));
2640 result
= gnutls_pkcs12_set_bag (pkcs12
, kbag
);
2642 error (EXIT_FAILURE
, 0, "set_bag: %s", gnutls_strerror (result
));
2645 result
= gnutls_pkcs12_generate_mac (pkcs12
, pass
);
2647 error (EXIT_FAILURE
, 0, "generate_mac: %s", gnutls_strerror (result
));
2649 size
= sizeof (buffer
);
2650 result
= gnutls_pkcs12_export (pkcs12
, info
.outcert_format
, buffer
, &size
);
2652 error (EXIT_FAILURE
, 0, "pkcs12_export: %s", gnutls_strerror (result
));
2654 fwrite (buffer
, 1, size
, outfile
);
2659 BAGTYPE (gnutls_pkcs12_bag_type_t x
)
2663 case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY
:
2664 return "PKCS #8 Encrypted key";
2665 case GNUTLS_BAG_EMPTY
:
2667 case GNUTLS_BAG_PKCS8_KEY
:
2668 return "PKCS #8 Key";
2669 case GNUTLS_BAG_CERTIFICATE
:
2670 return "Certificate";
2671 case GNUTLS_BAG_ENCRYPTED
:
2673 case GNUTLS_BAG_CRL
:
2675 case GNUTLS_BAG_SECRET
:
2683 print_bag_data (gnutls_pkcs12_bag_t bag
)
2687 gnutls_datum_t cdata
, id
;
2688 const char *str
, *name
;
2691 count
= gnutls_pkcs12_bag_get_count (bag
);
2693 error (EXIT_FAILURE
, 0, "get_count: %s", gnutls_strerror (count
));
2695 fprintf (outfile
, "\tElements: %d\n", count
);
2697 for (i
= 0; i
< count
; i
++)
2699 type
= gnutls_pkcs12_bag_get_type (bag
, i
);
2701 error (EXIT_FAILURE
, 0, "get_type: %s", gnutls_strerror (type
));
2703 fprintf (stderr
, "\tType: %s\n", BAGTYPE (type
));
2706 result
= gnutls_pkcs12_bag_get_friendly_name (bag
, i
, (char **) &name
);
2708 error (EXIT_FAILURE
, 0, "get_friendly_name: %s",
2709 gnutls_strerror (type
));
2711 fprintf (outfile
, "\tFriendly name: %s\n", name
);
2715 result
= gnutls_pkcs12_bag_get_key_id (bag
, i
, &id
);
2717 error (EXIT_FAILURE
, 0, "get_key_id: %s", gnutls_strerror (type
));
2718 fprintf (outfile
, "\tKey ID: %s\n", raw_to_string (id
.data
, id
.size
));
2720 result
= gnutls_pkcs12_bag_get_data (bag
, i
, &cdata
);
2722 error (EXIT_FAILURE
, 0, "get_data: %s", gnutls_strerror (result
));
2726 case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY
:
2727 str
= "ENCRYPTED PRIVATE KEY";
2729 case GNUTLS_BAG_PKCS8_KEY
:
2730 str
= "PRIVATE KEY";
2732 case GNUTLS_BAG_CERTIFICATE
:
2733 str
= "CERTIFICATE";
2735 case GNUTLS_BAG_CRL
:
2738 case GNUTLS_BAG_ENCRYPTED
:
2739 case GNUTLS_BAG_EMPTY
:
2746 gnutls_pem_base64_encode_alloc (str
, &cdata
, &out
);
2747 fprintf (outfile
, "%s\n", out
.data
);
2749 gnutls_free (out
.data
);
2758 gnutls_pkcs12_t pkcs12
;
2759 gnutls_pkcs12_bag_t bag
;
2762 gnutls_datum_t data
;
2766 result
= gnutls_pkcs12_init (&pkcs12
);
2768 error (EXIT_FAILURE
, 0, "p12_init: %s", gnutls_strerror (result
));
2770 data
.data
= fread_file (infile
, &size
);
2773 result
= gnutls_pkcs12_import (pkcs12
, &data
, info
.incert_format
, 0);
2776 error (EXIT_FAILURE
, 0, "p12_import: %s", gnutls_strerror (result
));
2783 result
= gnutls_pkcs12_verify_mac (pkcs12
, pass
);
2785 error (0, 0, "verify_mac: %s", gnutls_strerror (result
));
2787 for (indx
= 0;; indx
++)
2789 result
= gnutls_pkcs12_bag_init (&bag
);
2791 error (EXIT_FAILURE
, 0, "bag_init: %s", gnutls_strerror (result
));
2793 result
= gnutls_pkcs12_get_bag (pkcs12
, indx
, bag
);
2797 result
= gnutls_pkcs12_bag_get_count (bag
);
2799 error (EXIT_FAILURE
, 0, "bag_count: %s", gnutls_strerror (result
));
2801 fprintf (outfile
, "BAG #%d\n", indx
);
2803 result
= gnutls_pkcs12_bag_get_type (bag
, 0);
2805 error (EXIT_FAILURE
, 0, "bag_init: %s", gnutls_strerror (result
));
2807 if (result
== GNUTLS_BAG_ENCRYPTED
)
2809 fprintf (stderr
, "\tType: %s\n", BAGTYPE (result
));
2810 fprintf (stderr
, "\n\tDecrypting...\n");
2812 result
= gnutls_pkcs12_bag_decrypt (bag
, pass
);
2816 error (0, 0, "bag_decrypt: %s", gnutls_strerror (result
));
2820 result
= gnutls_pkcs12_bag_get_count (bag
);
2822 error (EXIT_FAILURE
, 0, "encrypted bag_count: %s",
2823 gnutls_strerror (result
));
2826 print_bag_data (bag
);
2828 gnutls_pkcs12_bag_deinit (bag
);
2835 gnutls_pkcs7_t pkcs7
;
2838 gnutls_datum_t data
, b64
;
2841 result
= gnutls_pkcs7_init (&pkcs7
);
2843 error (EXIT_FAILURE
, 0, "p7_init: %s", gnutls_strerror (result
));
2845 data
.data
= fread_file (infile
, &size
);
2848 result
= gnutls_pkcs7_import (pkcs7
, &data
, info
.incert_format
);
2851 error (EXIT_FAILURE
, 0, "import error: %s", gnutls_strerror (result
));
2853 /* Read and print the certificates.
2855 result
= gnutls_pkcs7_get_crt_count (pkcs7
);
2857 error (EXIT_FAILURE
, 0, "p7_crt_count: %s", gnutls_strerror (result
));
2862 fprintf (outfile
, "Number of certificates: %u\n", count
);
2864 for (indx
= 0; indx
< count
; indx
++)
2866 fputs ("\n", outfile
);
2868 size
= sizeof (buffer
);
2869 result
= gnutls_pkcs7_get_crt_raw (pkcs7
, indx
, buffer
, &size
);
2876 result
= gnutls_pem_base64_encode_alloc ("CERTIFICATE", &data
, &b64
);
2878 error (EXIT_FAILURE
, 0, "encoding: %s", gnutls_strerror (result
));
2880 fputs (b64
.data
, outfile
);
2881 gnutls_free (b64
.data
);
2884 /* Read the CRLs now.
2886 result
= gnutls_pkcs7_get_crl_count (pkcs7
);
2888 error (EXIT_FAILURE
, 0, "p7_crl_count: %s", gnutls_strerror (result
));
2893 fprintf (outfile
, "\nNumber of CRLs: %u\n", count
);
2895 for (indx
= 0; indx
< count
; indx
++)
2897 fputs ("\n", outfile
);
2899 size
= sizeof (buffer
);
2900 result
= gnutls_pkcs7_get_crl_raw (pkcs7
, indx
, buffer
, &size
);
2907 result
= gnutls_pem_base64_encode_alloc ("X509 CRL", &data
, &b64
);
2909 error (EXIT_FAILURE
, 0, "encoding: %s", gnutls_strerror (result
));
2911 fputs (b64
.data
, outfile
);
2912 gnutls_free (b64
.data
);
2917 smime_to_pkcs7 (void)
2919 size_t linesize
= 0;
2920 char *lineptr
= NULL
;
2923 /* Find body. FIXME: Handle non-b64 Content-Transfer-Encoding.
2924 Reject non-S/MIME tagged Content-Type's? */
2927 len
= getline (&lineptr
, &linesize
, infile
);
2929 error (EXIT_FAILURE
, 0, "cannot find RFC 2822 header/body separator");
2931 while (strcmp (lineptr
, "\r\n") != 0 && strcmp (lineptr
, "\n") != 0);
2935 len
= getline (&lineptr
, &linesize
, infile
);
2937 error (EXIT_FAILURE
, 0, "message has RFC 2822 header but no body");
2939 while (strcmp (lineptr
, "\r\n") == 0 && strcmp (lineptr
, "\n") == 0);
2941 fprintf (outfile
, "%s", "-----BEGIN PKCS7-----\n");
2946 && (lineptr
[len
- 1] == '\r' || lineptr
[len
- 1] == '\n'))
2947 lineptr
[--len
] = '\0';
2948 if (strcmp (lineptr
, "") != 0)
2949 fprintf (outfile
, "%s\n", lineptr
);
2950 len
= getline (&lineptr
, &linesize
, infile
);
2954 fprintf (outfile
, "%s", "-----END PKCS7-----\n");
2960 certtool_version (void)
2962 const char *p
= PACKAGE_NAME
;
2963 if (strcmp (gnutls_check_version (NULL
), PACKAGE_VERSION
) != 0)
2965 version_etc (stdout
, program_name
, p
, gnutls_check_version (NULL
),
2966 "Nikos Mavrogiannopoulos", "Simon Josefsson", (char *) NULL
);