2 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation
4 * This file is part of GNUTLS.
6 * GNUTLS is free software: you can redistribute it and/or modify
7 * it 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,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU 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 <http://www.gnu.org/licenses/>.
21 #include <gnutls/gnutls.h>
28 #include <gnutls/x509.h>
29 #include <gnutls/openpgp.h>
31 #include "certtool-gaa.h"
32 #include <gnutls/pkcs12.h>
34 #include <certtool-cfg.h>
37 #include <sys/types.h>
41 /* Gnulib portability files. */
42 #include <read-file.h>
45 #include <version-etc.h>
47 static void print_crl_info (gnutls_x509_crl_t crl
, FILE * out
);
48 int generate_prime (int bits
, int how
);
49 void pkcs7_info (void);
50 void smime_to_pkcs7 (void);
51 void pkcs12_info (void);
52 void generate_pkcs12 (void);
53 void generate_pkcs8 (void);
54 void verify_chain (void);
55 void verify_crl (void);
56 void pgp_privkey_info (void);
57 void pgp_ring_info (void);
58 gnutls_x509_privkey_t
load_private_key (int mand
);
59 gnutls_x509_crq_t
load_request (void);
60 gnutls_x509_privkey_t
load_ca_private_key (void);
61 gnutls_x509_crt_t
load_ca_cert (void);
62 gnutls_x509_crt_t
load_cert (int mand
);
63 void certificate_info (void);
64 void pgp_certificate_info (void);
66 void privkey_info (void);
67 static void print_certificate_info (gnutls_x509_crt_t crt
, FILE * out
,
69 static void gaa_parser (int argc
, char **argv
);
70 void generate_self_signed (void);
71 void generate_request (void);
72 gnutls_x509_crt_t
*load_cert_list (int mand
, int *size
);
74 static void print_hex_datum (gnutls_datum_t
* dat
);
80 gnutls_digest_algorithm_t dig
= GNUTLS_DIG_SHA1
;
82 #define UNKNOWN "Unknown"
84 /* non interactive operation if set
88 unsigned char buffer
[64 * 1024];
89 const int buffer_size
= sizeof (buffer
);
92 tls_log_func (int level
, const char *str
)
94 fprintf (stderr
, "|<%d>| %s", level
, str
);
98 main (int argc
, char **argv
)
100 set_program_name (argv
[0]);
102 gaa_parser (argc
, argv
);
108 raw_to_string (const unsigned char *raw
, size_t raw_size
)
110 static char buf
[1024];
115 if (raw_size
* 3 + 1 >= sizeof (buf
))
118 for (i
= 0; i
< raw_size
; i
++)
120 sprintf (&(buf
[i
* 3]), "%02X%s", raw
[i
],
121 (i
== raw_size
- 1) ? "" : ":");
123 buf
[sizeof (buf
) - 1] = '\0';
129 print_dsa_pkey (gnutls_datum
* x
, gnutls_datum
* y
, gnutls_datum
* p
,
130 gnutls_datum
* q
, gnutls_datum
* g
)
132 fprintf (outfile
, "private key:");
134 fprintf (outfile
, "public key:");
136 fprintf (outfile
, "p:");
138 fprintf (outfile
, "q:");
140 fprintf (outfile
, "g:");
145 print_rsa_pkey (gnutls_datum
* m
, gnutls_datum
* e
, gnutls_datum
* d
,
146 gnutls_datum
* p
, gnutls_datum
* q
, gnutls_datum
* u
)
148 fprintf (outfile
, "modulus:");
150 fprintf (outfile
, "public exponent:");
152 fprintf (outfile
, "private exponent:");
154 fprintf (outfile
, "prime1:");
156 fprintf (outfile
, "prime2:");
158 fprintf (outfile
, "coefficient:");
162 static gnutls_x509_privkey_t
163 generate_private_key_int (void)
165 gnutls_x509_privkey_t key
;
170 key_type
= GNUTLS_PK_DSA
;
171 /* FIXME: Remove me once we depend on 1.3.x */
172 if (info
.bits
> 1024 && gcry_check_version ("1.3.1") == NULL
)
176 key_type
= GNUTLS_PK_RSA
;
178 ret
= gnutls_x509_privkey_init (&key
);
180 error (EXIT_FAILURE
, 0, "privkey_init: %s", gnutls_strerror (ret
));
182 fprintf (stderr
, "Generating a %d bit %s private key...\n", info
.bits
,
183 gnutls_pk_algorithm_get_name (key_type
));
185 if (info
.quick_random
== 0)
187 "This might take several minutes depending on availability of randomness"
188 " in /dev/random.\n");
190 ret
= gnutls_x509_privkey_generate (key
, key_type
, info
.bits
, 0);
192 error (EXIT_FAILURE
, 0, "privkey_generate: %s", gnutls_strerror (ret
));
198 print_private_key (gnutls_x509_privkey_t key
)
208 size
= sizeof (buffer
);
209 ret
= gnutls_x509_privkey_export (key
, info
.outcert_format
,
212 error (EXIT_FAILURE
, 0, "privkey_export: %s",
213 gnutls_strerror (ret
));
221 flags
= GNUTLS_PKCS_USE_PKCS12_RC2_40
;
223 flags
= GNUTLS_PKCS_USE_PKCS12_3DES
;
225 if ((pass
= get_confirmed_pass (true)) == NULL
|| *pass
== '\0')
226 flags
= GNUTLS_PKCS_PLAIN
;
228 size
= sizeof (buffer
);
230 gnutls_x509_privkey_export_pkcs8 (key
, info
.outcert_format
, pass
,
231 flags
, buffer
, &size
);
233 error (EXIT_FAILURE
, 0, "privkey_export_pkcs8: %s",
234 gnutls_strerror (ret
));
238 fwrite (buffer
, 1, size
, outfile
);
242 generate_private_key (void)
244 gnutls_x509_privkey_t key
;
246 key
= generate_private_key_int ();
248 print_private_key (key
);
250 gnutls_x509_privkey_deinit (key
);
255 generate_certificate (gnutls_x509_privkey_t
* ret_key
,
256 gnutls_x509_crt_t ca_crt
, int proxy
)
258 gnutls_x509_crt_t crt
;
259 gnutls_x509_privkey_t key
= NULL
;
263 int days
, result
, ca_status
= 0, path_len
;
266 unsigned int usage
= 0, server
;
267 gnutls_x509_crq_t crq
; /* request */
269 ret
= gnutls_x509_crt_init (&crt
);
271 error (EXIT_FAILURE
, 0, "crt_init: %s", gnutls_strerror (ret
));
273 crq
= load_request ();
278 key
= load_private_key (1);
282 "Please enter the details of the certificate's distinguished name. "
283 "Just press enter to ignore a field.\n");
289 result
= gnutls_x509_crt_set_proxy_dn (crt
, ca_crt
, 0, NULL
, 0);
291 error (EXIT_FAILURE
, 0, "set_proxy_dn: %s",
292 gnutls_strerror (result
));
294 get_cn_crt_set (crt
);
298 get_country_crt_set (crt
);
299 get_organization_crt_set (crt
);
300 get_unit_crt_set (crt
);
301 get_locality_crt_set (crt
);
302 get_state_crt_set (crt
);
303 get_cn_crt_set (crt
);
304 get_uid_crt_set (crt
);
305 get_oid_crt_set (crt
);
309 "This field should not be used in new certificates.\n");
311 get_pkcs9_email_crt_set (crt
);
314 result
= gnutls_x509_crt_set_key (crt
, key
);
316 error (EXIT_FAILURE
, 0, "set_key: %s", gnutls_strerror (result
));
320 result
= gnutls_x509_crt_set_crq (crt
, crq
);
322 error (EXIT_FAILURE
, 0, "set_crq: %s", gnutls_strerror (result
));
326 serial
= get_serial ();
327 buffer
[4] = serial
& 0xff;
328 buffer
[3] = (serial
>> 8) & 0xff;
329 buffer
[2] = (serial
>> 16) & 0xff;
330 buffer
[1] = (serial
>> 24) & 0xff;
333 result
= gnutls_x509_crt_set_serial (crt
, buffer
, 5);
335 error (EXIT_FAILURE
, 0, "serial: %s", gnutls_strerror (result
));
338 fprintf (stderr
, "\n\nActivation/Expiration time.\n");
340 gnutls_x509_crt_set_activation_time (crt
, time (NULL
));
345 gnutls_x509_crt_set_expiration_time (crt
,
347 days
* 24 * 60 * 60);
349 error (EXIT_FAILURE
, 0, "set_expiration: %s",
350 gnutls_strerror (result
));
353 fprintf (stderr
, "\n\nExtensions.\n");
355 /* do not allow extensions on a v1 certificate */
356 if (info
.v1_cert
== 0)
361 const char *policylanguage
;
364 int proxypathlen
= get_path_len ();
368 printf ("1.3.6.1.5.5.7.21.1 ::= id-ppl-inheritALL\n");
369 printf ("1.3.6.1.5.5.7.21.2 ::= id-ppl-independent\n");
372 policylanguage
= get_proxy_policy (&policy
, &policylen
);
375 gnutls_x509_crt_set_proxy (crt
, proxypathlen
, policylanguage
,
378 error (EXIT_FAILURE
, 0, "set_proxy: %s",
379 gnutls_strerror (result
));
383 ca_status
= get_ca_status ();
385 path_len
= get_path_len ();
390 gnutls_x509_crt_set_basic_constraints (crt
, ca_status
, path_len
);
392 error (EXIT_FAILURE
, 0, "basic_constraints: %s",
393 gnutls_strerror (result
));
395 client
= get_tls_client_status ();
398 result
= gnutls_x509_crt_set_key_purpose_oid (crt
,
399 GNUTLS_KP_TLS_WWW_CLIENT
,
402 error (EXIT_FAILURE
, 0, "key_kp: %s",
403 gnutls_strerror (result
));
406 server
= get_tls_server_status ();
413 str
= get_dns_name ();
416 result
= gnutls_x509_crt_set_subject_alternative_name
417 (crt
, GNUTLS_SAN_DNSNAME
, str
);
421 str
= get_ip_addr ();
424 result
= gnutls_x509_crt_set_subject_alternative_name
425 (crt
, GNUTLS_SAN_IPADDRESS
, str
);
430 error (EXIT_FAILURE
, 0, "subject_alt_name: %s",
431 gnutls_strerror (result
));
435 gnutls_x509_crt_set_key_purpose_oid (crt
,
436 GNUTLS_KP_TLS_WWW_SERVER
,
439 error (EXIT_FAILURE
, 0, "key_kp: %s",
440 gnutls_strerror (result
));
448 result
= gnutls_x509_crt_set_subject_alternative_name
449 (crt
, GNUTLS_SAN_RFC822NAME
, str
);
451 error (EXIT_FAILURE
, 0, "subject_alt_name: %s",
452 gnutls_strerror (result
));
456 if (!ca_status
|| server
)
461 pk
= gnutls_x509_crt_get_pk_algorithm (crt
, NULL
);
463 if (pk
!= GNUTLS_PK_DSA
)
464 { /* DSA keys can only sign.
466 result
= get_sign_status (server
);
468 usage
|= GNUTLS_KEY_DIGITAL_SIGNATURE
;
470 result
= get_encrypt_status (server
);
472 usage
|= GNUTLS_KEY_KEY_ENCIPHERMENT
;
475 usage
|= GNUTLS_KEY_DIGITAL_SIGNATURE
;
481 result
= get_cert_sign_status ();
483 usage
|= GNUTLS_KEY_KEY_CERT_SIGN
;
485 result
= get_crl_sign_status ();
487 usage
|= GNUTLS_KEY_CRL_SIGN
;
489 result
= get_code_sign_status ();
493 gnutls_x509_crt_set_key_purpose_oid (crt
,
494 GNUTLS_KP_CODE_SIGNING
,
497 error (EXIT_FAILURE
, 0, "key_kp: %s",
498 gnutls_strerror (result
));
501 result
= get_ocsp_sign_status ();
505 gnutls_x509_crt_set_key_purpose_oid (crt
,
506 GNUTLS_KP_OCSP_SIGNING
,
509 error (EXIT_FAILURE
, 0, "key_kp: %s",
510 gnutls_strerror (result
));
513 result
= get_time_stamp_status ();
517 gnutls_x509_crt_set_key_purpose_oid (crt
,
518 GNUTLS_KP_TIME_STAMPING
,
521 error (EXIT_FAILURE
, 0, "key_kp: %s",
522 gnutls_strerror (result
));
528 result
= gnutls_x509_crt_set_key_usage (crt
, usage
);
530 error (EXIT_FAILURE
, 0, "key_usage: %s",
531 gnutls_strerror (result
));
536 size
= sizeof (buffer
);
537 result
= gnutls_x509_crt_get_key_id (crt
, 0, buffer
, &size
);
540 result
= gnutls_x509_crt_set_subject_key_id (crt
, buffer
, size
);
542 error (EXIT_FAILURE
, 0, "set_subject_key_id: %s",
543 gnutls_strerror (result
));
550 size
= sizeof (buffer
);
551 result
= gnutls_x509_crt_get_subject_key_id (ca_crt
, buffer
,
555 size
= sizeof (buffer
);
557 gnutls_x509_crt_get_key_id (ca_crt
, 0, buffer
, &size
);
562 gnutls_x509_crt_set_authority_key_id (crt
, buffer
, size
);
564 error (EXIT_FAILURE
, 0, "set_authority_key_id: %s",
565 gnutls_strerror (result
));
572 if (info
.v1_cert
!= 0)
576 result
= gnutls_x509_crt_set_version (crt
, vers
);
578 error (EXIT_FAILURE
, 0, "set_version: %s", gnutls_strerror (result
));
588 gnutls_x509_crl_t crl
;
589 gnutls_x509_crt_t
*crts
;
592 time_t now
= time (NULL
);
594 result
= gnutls_x509_crl_init (&crl
);
596 error (EXIT_FAILURE
, 0, "crl_init: %s", gnutls_strerror (result
));
598 crts
= load_cert_list (0, &size
);
600 for (i
= 0; i
< size
; i
++)
602 result
= gnutls_x509_crl_set_crt (crl
, crts
[i
], now
);
604 error (EXIT_FAILURE
, 0, "crl_set_crt: %s",
605 gnutls_strerror (result
));
608 result
= gnutls_x509_crl_set_this_update (crl
, now
);
610 error (EXIT_FAILURE
, 0, "this_update: %s", gnutls_strerror (result
));
612 fprintf (stderr
, "Update times.\n");
613 days
= get_crl_next_update ();
616 gnutls_x509_crl_set_next_update (crl
, now
+ days
* 24 * 60 * 60);
618 error (EXIT_FAILURE
, 0, "next_update: %s", gnutls_strerror (result
));
620 result
= gnutls_x509_crl_set_version (crl
, 2);
622 error (EXIT_FAILURE
, 0, "set_version: %s", gnutls_strerror (result
));
628 generate_self_signed (void)
630 gnutls_x509_crt_t crt
;
631 gnutls_x509_privkey_t key
;
636 fprintf (stderr
, "Generating a self signed certificate...\n");
638 crt
= generate_certificate (&key
, NULL
, 0);
641 key
= load_private_key (1);
643 uri
= get_crl_dist_point_url ();
646 result
= gnutls_x509_crt_set_crl_dist_points (crt
, GNUTLS_SAN_URI
,
648 0 /* all reasons */ );
650 error (EXIT_FAILURE
, 0, "crl_dist_points: %s",
651 gnutls_strerror (result
));
654 print_certificate_info (crt
, stderr
, 0);
656 fprintf (stderr
, "\n\nSigning certificate...\n");
658 result
= gnutls_x509_crt_sign2 (crt
, crt
, key
, dig
, 0);
660 error (EXIT_FAILURE
, 0, "crt_sign: %s", gnutls_strerror (result
));
662 size
= sizeof (buffer
);
664 gnutls_x509_crt_export (crt
, info
.outcert_format
, buffer
, &size
);
666 error (EXIT_FAILURE
, 0, "crt_export: %s", gnutls_strerror (result
));
668 fwrite (buffer
, 1, size
, outfile
);
670 gnutls_x509_crt_deinit (crt
);
671 gnutls_x509_privkey_deinit (key
);
675 generate_signed_certificate (void)
677 gnutls_x509_crt_t crt
;
678 gnutls_x509_privkey_t key
;
681 gnutls_x509_privkey_t ca_key
;
682 gnutls_x509_crt_t ca_crt
;
684 fprintf (stderr
, "Generating a signed certificate...\n");
686 ca_key
= load_ca_private_key ();
687 ca_crt
= load_ca_cert ();
689 crt
= generate_certificate (&key
, ca_crt
, 0);
691 /* Copy the CRL distribution points.
693 gnutls_x509_crt_cpy_crl_dist_points (crt
, ca_crt
);
694 /* it doesn't matter if we couldn't copy the CRL dist points.
697 print_certificate_info (crt
, stderr
, 0);
699 fprintf (stderr
, "\n\nSigning certificate...\n");
701 result
= gnutls_x509_crt_sign2 (crt
, ca_crt
, ca_key
, dig
, 0);
703 error (EXIT_FAILURE
, 0, "crt_sign: %s", gnutls_strerror (result
));
705 size
= sizeof (buffer
);
707 gnutls_x509_crt_export (crt
, info
.outcert_format
, buffer
, &size
);
709 error (EXIT_FAILURE
, 0, "crt_export: %s", gnutls_strerror (result
));
711 fwrite (buffer
, 1, size
, outfile
);
713 gnutls_x509_crt_deinit (crt
);
714 gnutls_x509_privkey_deinit (key
);
718 generate_proxy_certificate (void)
720 gnutls_x509_crt_t crt
, eecrt
;
721 gnutls_x509_privkey_t key
, eekey
;
725 fprintf (stderr
, "Generating a proxy certificate...\n");
727 eekey
= load_ca_private_key ();
728 eecrt
= load_cert (1);
730 crt
= generate_certificate (&key
, eecrt
, 1);
732 print_certificate_info (crt
, stderr
, 0);
734 fprintf (stderr
, "\n\nSigning certificate...\n");
736 result
= gnutls_x509_crt_sign2 (crt
, eecrt
, eekey
, dig
, 0);
738 error (EXIT_FAILURE
, 0, "crt_sign: %s", gnutls_strerror (result
));
740 size
= sizeof (buffer
);
742 gnutls_x509_crt_export (crt
, info
.outcert_format
, buffer
, &size
);
744 error (EXIT_FAILURE
, 0, "crt_export: %s", gnutls_strerror (result
));
746 fwrite (buffer
, 1, size
, outfile
);
748 gnutls_x509_crt_deinit (crt
);
749 gnutls_x509_privkey_deinit (key
);
753 generate_signed_crl (void)
755 gnutls_x509_crl_t crl
;
757 gnutls_x509_privkey_t ca_key
;
758 gnutls_x509_crt_t ca_crt
;
760 fprintf (stderr
, "Generating a signed CRL...\n");
762 ca_key
= load_ca_private_key ();
763 ca_crt
= load_ca_cert ();
764 crl
= generate_crl ();
766 fprintf (stderr
, "\n");
768 result
= gnutls_x509_crl_sign (crl
, ca_crt
, ca_key
);
770 error (EXIT_FAILURE
, 0, "crl_sign: %s", gnutls_strerror (result
));
772 print_crl_info (crl
, stderr
);
774 gnutls_x509_crl_deinit (crl
);
778 update_signed_certificate (void)
780 gnutls_x509_crt_t crt
;
783 gnutls_x509_privkey_t ca_key
;
784 gnutls_x509_crt_t ca_crt
;
786 time_t tim
= time (NULL
);
788 fprintf (stderr
, "Generating a signed certificate...\n");
790 ca_key
= load_ca_private_key ();
791 ca_crt
= load_ca_cert ();
794 fprintf (stderr
, "Activation/Expiration time.\n");
795 gnutls_x509_crt_set_activation_time (crt
, tim
);
800 gnutls_x509_crt_set_expiration_time (crt
, tim
+ days
* 24 * 60 * 60);
802 error (EXIT_FAILURE
, 0, "set_expiration: %s",
803 gnutls_strerror (result
));
805 fprintf (stderr
, "\n\nSigning certificate...\n");
807 result
= gnutls_x509_crt_sign2 (crt
, ca_crt
, ca_key
, dig
, 0);
809 error (EXIT_FAILURE
, 0, "crt_sign: %s", gnutls_strerror (result
));
811 size
= sizeof (buffer
);
813 gnutls_x509_crt_export (crt
, info
.outcert_format
, buffer
, &size
);
815 error (EXIT_FAILURE
, 0, "crt_export: %s", gnutls_strerror (result
));
817 fwrite (buffer
, 1, size
, outfile
);
819 gnutls_x509_crt_deinit (crt
);
822 FILE* safe_open_rw(const char* file
)
827 if (info
.privkey_op
!= 0)
829 oldmask
= umask (S_IRGRP
|S_IWGRP
|S_IROTH
|S_IWOTH
);
832 fh
= fopen (file
, "wb");
834 if (info
.privkey_op
!= 0)
843 gaa_parser (int argc
, char **argv
)
847 if (gaa (argc
, argv
, &info
) != -1)
849 fprintf (stderr
, "Try `%s --help' for more information.\n",
856 outfile
= safe_open_rw (info
.outfile
);
858 error (EXIT_FAILURE
, errno
, "%s", info
.outfile
);
865 infile
= fopen (info
.infile
, "rb");
867 error (EXIT_FAILURE
, errno
, "%s", info
.infile
);
872 if (info
.incert_format
)
873 info
.incert_format
= GNUTLS_X509_FMT_DER
;
875 info
.incert_format
= GNUTLS_X509_FMT_PEM
;
877 if (info
.outcert_format
)
878 info
.outcert_format
= GNUTLS_X509_FMT_DER
;
880 info
.outcert_format
= GNUTLS_X509_FMT_PEM
;
882 if (info
.hash
!= NULL
)
884 if (strcasecmp (info
.hash
, "md5") == 0)
887 "Warning: MD5 is broken, and should not be used any more for digital signatures.\n");
888 dig
= GNUTLS_DIG_MD5
;
890 else if (strcasecmp (info
.hash
, "sha1") == 0)
891 dig
= GNUTLS_DIG_SHA1
;
892 else if (strcasecmp (info
.hash
, "sha256") == 0)
893 dig
= GNUTLS_DIG_SHA256
;
894 else if (strcasecmp (info
.hash
, "sha384") == 0)
895 dig
= GNUTLS_DIG_SHA384
;
896 else if (strcasecmp (info
.hash
, "sha512") == 0)
897 dig
= GNUTLS_DIG_SHA512
;
898 else if (strcasecmp (info
.hash
, "rmd160") == 0)
899 dig
= GNUTLS_DIG_RMD160
;
901 error (EXIT_FAILURE
, 0, "invalid hash: %s", info
.hash
);
908 template_parse (info
.template);
911 if (info
.quick_random
!= 0)
912 gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM
, 0);
914 gnutls_global_set_log_function (tls_log_func
);
915 gnutls_global_set_log_level (info
.debug
);
917 if ((ret
= gnutls_global_init ()) < 0)
918 error (EXIT_FAILURE
, 0, "global_init: %s", gnutls_strerror (ret
));
923 generate_self_signed ();
926 generate_private_key ();
935 generate_signed_certificate ();
944 update_signed_certificate ();
953 generate_prime (info
.bits
, 1);
956 generate_prime (info
.bits
, 0);
965 generate_signed_crl ();
974 generate_proxy_certificate ();
979 #ifdef ENABLE_OPENPGP
981 pgp_certificate_info ();
999 certificate_info (void)
1001 gnutls_x509_crt_t crt
[MAX_CRTS
];
1005 unsigned int crt_num
;
1007 pem
.data
= fread_file (infile
, &size
);
1012 gnutls_x509_crt_list_import (crt
, &crt_num
, &pem
, info
.incert_format
,
1013 GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED
);
1014 if (ret
== GNUTLS_E_SHORT_MEMORY_BUFFER
)
1017 "Too many certificates (%d), will only read the first %d.",
1020 ret
= gnutls_x509_crt_list_import (crt
, &crt_num
, &pem
,
1021 info
.incert_format
, 0);
1024 error (EXIT_FAILURE
, 0, "Import error: %s", gnutls_strerror (ret
));
1030 if (count
> 1 && info
.outcert_format
== GNUTLS_X509_FMT_DER
)
1033 "Cannot output multiple certificates in DER format, using PEM instead.");
1034 info
.outcert_format
= GNUTLS_X509_FMT_PEM
;
1037 for (i
= 0; i
< count
; i
++)
1040 fprintf (outfile
, "\n");
1042 if (info
.outcert_format
== GNUTLS_X509_FMT_PEM
)
1043 print_certificate_info (crt
[i
], outfile
, 1);
1045 size
= sizeof (buffer
);
1046 ret
= gnutls_x509_crt_export (crt
[i
], info
.outcert_format
, buffer
,
1049 error (EXIT_FAILURE
, 0, "Export error: %s", gnutls_strerror (ret
));
1050 fwrite (buffer
, 1, size
, outfile
);
1054 #ifdef ENABLE_OPENPGP
1057 pgp_certificate_info (void)
1059 gnutls_openpgp_crt_t crt
;
1062 gnutls_datum_t pem
, out_data
;
1064 pem
.data
= fread_file (infile
, &size
);
1067 ret
= gnutls_openpgp_crt_init (&crt
);
1069 error (EXIT_FAILURE
, 0, "openpgp_crt_init: %s", gnutls_strerror (ret
));
1071 ret
= gnutls_openpgp_crt_import (crt
, &pem
, info
.incert_format
);
1074 error (EXIT_FAILURE
, 0, "Import error: %s", gnutls_strerror (ret
));
1078 if (info
.outcert_format
== GNUTLS_OPENPGP_FMT_BASE64
)
1080 ret
= gnutls_openpgp_crt_print (crt
, 0, &out_data
);
1084 fprintf (outfile
, "%s\n", out_data
.data
);
1085 gnutls_free (out_data
.data
);
1089 size
= sizeof (buffer
);
1091 gnutls_openpgp_crt_export (crt
, info
.outcert_format
, buffer
, &size
);
1094 error (EXIT_FAILURE
, 0, "Export error: %s", gnutls_strerror (ret
));
1095 fwrite (buffer
, 1, size
, outfile
);
1098 fprintf (outfile
, "%s\n", buffer
);
1100 gnutls_openpgp_crt_deinit (crt
);
1104 pgp_privkey_info (void)
1106 gnutls_openpgp_privkey_t key
;
1107 gnutls_openpgp_keyid_t keyid
;
1109 int ret
, i
, subkeys
;
1113 size
= fread (buffer
, 1, sizeof (buffer
) - 1, infile
);
1116 gnutls_openpgp_privkey_init (&key
);
1122 gnutls_openpgp_privkey_import (key
, &pem
, info
.incert_format
, NULL
,
1126 error (EXIT_FAILURE
, 0, "Import error: %s", gnutls_strerror (ret
));
1128 /* Public key algorithm
1130 subkeys
= gnutls_openpgp_privkey_get_subkey_count (key
);
1132 error (EXIT_FAILURE
, 0, "privkey_get_subkey_count: %s",
1133 gnutls_strerror (subkeys
));
1135 for (i
= -1; i
< subkeys
; i
++)
1139 fprintf (outfile
, "Subkey[%d]:\n", i
);
1141 fprintf (outfile
, "Public Key Info:\n");
1144 ret
= gnutls_openpgp_privkey_get_pk_algorithm (key
, NULL
);
1147 gnutls_openpgp_privkey_get_subkey_pk_algorithm (key
, i
, NULL
);
1149 fprintf (outfile
, "\tPublic Key Algorithm: ");
1151 cprint
= gnutls_pk_algorithm_get_name (ret
);
1154 fprintf (outfile
, "%s\n", cprint
);
1156 /* Print the raw public and private keys
1159 if (ret
== GNUTLS_PK_RSA
)
1161 gnutls_datum_t m
, e
, d
, p
, q
, u
;
1165 gnutls_openpgp_privkey_export_rsa_raw (key
, &m
, &e
, &d
, &p
,
1169 gnutls_openpgp_privkey_export_subkey_rsa_raw (key
, i
, &m
,
1173 fprintf (stderr
, "Error in key RSA data export: %s\n",
1174 gnutls_strerror (ret
));
1176 print_rsa_pkey (&m
, &e
, &d
, &p
, &q
, &u
);
1179 else if (ret
== GNUTLS_PK_DSA
)
1181 gnutls_datum_t p
, q
, g
, y
, x
;
1185 gnutls_openpgp_privkey_export_dsa_raw (key
, &p
, &q
, &g
, &y
,
1189 gnutls_openpgp_privkey_export_subkey_dsa_raw (key
, i
, &p
,
1193 fprintf (stderr
, "Error in key DSA data export: %s\n",
1194 gnutls_strerror (ret
));
1196 print_dsa_pkey (&x
, &y
, &p
, &q
, &g
);
1199 fprintf (outfile
, "\n");
1201 size
= sizeof (buffer
);
1203 ret
= gnutls_openpgp_privkey_get_key_id (key
, keyid
);
1205 ret
= gnutls_openpgp_privkey_get_subkey_id (key
, i
, keyid
);
1209 fprintf (stderr
, "Error in key id calculation: %s\n",
1210 gnutls_strerror (ret
));
1214 fprintf (outfile
, "Public Key ID: %s\n",
1215 raw_to_string (keyid
, 8));
1220 size
= sizeof (buffer
);
1222 gnutls_openpgp_privkey_export (key
, GNUTLS_OPENPGP_FMT_BASE64
,
1223 NULL
, 0, buffer
, &size
);
1225 error (EXIT_FAILURE
, 0, "Export error: %s", gnutls_strerror (ret
));
1227 fprintf (outfile
, "\n%s\n", buffer
);
1231 pgp_ring_info (void)
1233 gnutls_openpgp_keyring_t ring
;
1234 gnutls_openpgp_crt_t crt
;
1239 pem
.data
= fread_file (infile
, &size
);
1242 ret
= gnutls_openpgp_keyring_init (&ring
);
1244 error (EXIT_FAILURE
, 0, "openpgp_keyring_init: %s",
1245 gnutls_strerror (ret
));
1247 ret
= gnutls_openpgp_keyring_import (ring
, &pem
, info
.incert_format
);
1250 error (EXIT_FAILURE
, 0, "Import error: %s", gnutls_strerror (ret
));
1254 count
= gnutls_openpgp_keyring_get_crt_count (ring
);
1256 fprintf (outfile
, "Keyring contains %d OpenPGP certificates\n\n",
1259 error (EXIT_FAILURE
, 0, "Keyring error: %s", gnutls_strerror (count
));
1261 for (i
= 0; i
< count
; i
++)
1263 ret
= gnutls_openpgp_keyring_get_crt (ring
, i
, &crt
);
1267 error (EXIT_FAILURE
, 0, "Export error: %s", gnutls_strerror (ret
));
1270 size
= sizeof (buffer
);
1272 gnutls_openpgp_crt_export (crt
, info
.outcert_format
, buffer
,
1276 error (EXIT_FAILURE
, 0, "Export error: %s", gnutls_strerror (ret
));
1279 fwrite (buffer
, 1, size
, outfile
);
1280 fprintf (outfile
, "\n\n");
1282 gnutls_openpgp_crt_deinit (crt
);
1287 gnutls_openpgp_keyring_deinit (ring
);
1294 print_hex_datum (gnutls_datum_t
* dat
)
1298 fprintf (outfile
, "\n" SPACE
);
1299 for (j
= 0; j
< dat
->size
; j
++)
1301 fprintf (outfile
, "%.2x:", (unsigned char) dat
->data
[j
]);
1302 if ((j
+ 1) % 15 == 0)
1303 fprintf (outfile
, "\n" SPACE
);
1305 fprintf (outfile
, "\n");
1310 print_certificate_info (gnutls_x509_crt_t crt
, FILE * out
,
1313 gnutls_datum_t info
;
1317 ret
= gnutls_x509_crt_print (crt
, GNUTLS_CRT_PRINT_FULL
, &info
);
1320 gnutls_x509_crt_print (crt
, GNUTLS_CRT_PRINT_UNSIGNED_FULL
, &info
);
1323 fprintf (out
, "%s\n", info
.data
);
1324 gnutls_free (info
.data
);
1327 if (out
== stderr
&& batch
== 0) /* interactive */
1328 if (read_yesno ("Is the above information ok? (Y/N): ") == 0)
1335 print_crl_info (gnutls_x509_crl_t crl
, FILE * out
)
1337 gnutls_datum_t info
;
1341 ret
= gnutls_x509_crl_print (crl
, GNUTLS_CRT_PRINT_FULL
, &info
);
1343 error (EXIT_FAILURE
, 0, "crl_print: %s", gnutls_strerror (ret
));
1345 fprintf (out
, "%s\n", info
.data
);
1347 gnutls_free (info
.data
);
1349 size
= sizeof (buffer
);
1350 ret
= gnutls_x509_crl_export (crl
, GNUTLS_X509_FMT_PEM
, buffer
, &size
);
1352 error (EXIT_FAILURE
, 0, "crl_export: %s", gnutls_strerror (ret
));
1354 fwrite (buffer
, 1, size
, outfile
);
1360 gnutls_x509_crl_t crl
;
1365 ret
= gnutls_x509_crl_init (&crl
);
1367 error (EXIT_FAILURE
, 0, "crl_init: %s", gnutls_strerror (ret
));
1369 pem
.data
= fread_file (infile
, &size
);
1373 error (EXIT_FAILURE
, errno
, "%s", info
.infile
? info
.infile
:
1376 ret
= gnutls_x509_crl_import (crl
, &pem
, info
.incert_format
);
1380 error (EXIT_FAILURE
, 0, "Import error: %s", gnutls_strerror (ret
));
1382 print_crl_info (crl
, outfile
);
1388 gnutls_x509_privkey_t key
;
1395 size
= fread (buffer
, 1, sizeof (buffer
) - 1, infile
);
1398 gnutls_x509_privkey_init (&key
);
1405 ret
= gnutls_x509_privkey_import (key
, &pem
, info
.incert_format
);
1407 /* If we failed to import the certificate previously try PKCS #8 */
1408 if (info
.pkcs8
|| ret
== GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR
)
1415 gnutls_x509_privkey_import_pkcs8 (key
, &pem
, info
.incert_format
,
1419 error (EXIT_FAILURE
, 0, "Import error: %s", gnutls_strerror (ret
));
1421 /* Public key algorithm
1423 fprintf (outfile
, "Public Key Info:\n");
1424 ret
= gnutls_x509_privkey_get_pk_algorithm (key
);
1425 fprintf (outfile
, "\tPublic Key Algorithm: ");
1427 cprint
= gnutls_pk_algorithm_get_name (ret
);
1430 fprintf (outfile
, "%s\n", cprint
);
1432 /* Print the raw public and private keys
1434 if (ret
== GNUTLS_PK_RSA
)
1436 gnutls_datum_t m
, e
, d
, p
, q
, u
;
1439 gnutls_x509_privkey_export_rsa_raw (key
, &m
, &e
, &d
, &p
, &q
, &u
);
1441 fprintf (stderr
, "Error in key RSA data export: %s\n",
1442 gnutls_strerror (ret
));
1444 print_rsa_pkey (&m
, &e
, &d
, &p
, &q
, &u
);
1447 else if (ret
== GNUTLS_PK_DSA
)
1449 gnutls_datum_t p
, q
, g
, y
, x
;
1451 ret
= gnutls_x509_privkey_export_dsa_raw (key
, &p
, &q
, &g
, &y
, &x
);
1453 fprintf (stderr
, "Error in key DSA data export: %s\n",
1454 gnutls_strerror (ret
));
1456 print_dsa_pkey (&x
, &y
, &p
, &q
, &g
);
1459 fprintf (outfile
, "\n");
1461 size
= sizeof (buffer
);
1462 if ((ret
= gnutls_x509_privkey_get_key_id (key
, 0, buffer
, &size
)) < 0)
1464 fprintf (stderr
, "Error in key id calculation: %s\n",
1465 gnutls_strerror (ret
));
1469 fprintf (outfile
, "Public Key ID: %s\n",
1470 raw_to_string (buffer
, size
));
1473 if (info
.fix_key
!= 0)
1475 ret
= gnutls_x509_privkey_fix (key
);
1477 error (EXIT_FAILURE
, 0, "privkey_fix: %s", gnutls_strerror (ret
));
1480 size
= sizeof (buffer
);
1482 gnutls_x509_privkey_export (key
, GNUTLS_X509_FMT_PEM
, buffer
, &size
);
1484 error (EXIT_FAILURE
, 0, "Export error: %s", gnutls_strerror (ret
));
1486 fprintf (outfile
, "\n%s\n", buffer
);
1490 /* Load the private key.
1491 * @mand should be non zero if it is required to read a private key.
1493 gnutls_x509_privkey_t
1494 load_private_key (int mand
)
1496 gnutls_x509_privkey_t key
;
1501 if (!info
.privkey
&& !mand
)
1504 if (info
.privkey
== NULL
)
1505 error (EXIT_FAILURE
, 0, "missing --load-privkey");
1507 ret
= gnutls_x509_privkey_init (&key
);
1509 error (EXIT_FAILURE
, 0, "privkey_init: %s", gnutls_strerror (ret
));
1511 dat
.data
= read_binary_file (info
.privkey
, &size
);
1515 error (EXIT_FAILURE
, errno
, "reading --load-privkey: %s",
1520 const char *pass
= get_pass ();
1522 gnutls_x509_privkey_import_pkcs8 (key
, &dat
, info
.incert_format
,
1526 ret
= gnutls_x509_privkey_import (key
, &dat
, info
.incert_format
);
1530 if (ret
== GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR
)
1532 error (EXIT_FAILURE
, 0,
1533 "Import error: Could not find a valid PEM header. Check if your key is PKCS #8 or PKCS #12 encoded.");
1537 error (EXIT_FAILURE
, 0, "importing --load-privkey: %s: %s",
1538 info
.privkey
, gnutls_strerror (ret
));
1543 /* Load the Certificate Request.
1548 gnutls_x509_crq_t crq
;
1556 ret
= gnutls_x509_crq_init (&crq
);
1558 error (EXIT_FAILURE
, 0, "crq_init: %s", gnutls_strerror (ret
));
1560 dat
.data
= read_binary_file (info
.request
, &size
);
1564 error (EXIT_FAILURE
, errno
, "reading --load-request: %s",
1567 ret
= gnutls_x509_crq_import (crq
, &dat
, info
.incert_format
);
1568 if (ret
== GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR
)
1570 error (EXIT_FAILURE
, 0,
1571 "Import error: Could not find a valid PEM header.");
1576 error (EXIT_FAILURE
, 0, "importing --load-request: %s: %s",
1577 info
.request
, gnutls_strerror (ret
));
1582 /* Load the CA's private key.
1584 gnutls_x509_privkey_t
1585 load_ca_private_key (void)
1587 gnutls_x509_privkey_t key
;
1592 if (info
.ca_privkey
== NULL
)
1593 error (EXIT_FAILURE
, 0, "missing --load-ca-privkey");
1595 ret
= gnutls_x509_privkey_init (&key
);
1597 error (EXIT_FAILURE
, 0, "privkey_init: %s", gnutls_strerror (ret
));
1599 dat
.data
= read_binary_file (info
.ca_privkey
, &size
);
1603 error (EXIT_FAILURE
, errno
, "reading --load-ca-privkey: %s",
1608 const char *pass
= get_pass ();
1610 gnutls_x509_privkey_import_pkcs8 (key
, &dat
, info
.incert_format
,
1614 ret
= gnutls_x509_privkey_import (key
, &dat
, info
.incert_format
);
1617 error (EXIT_FAILURE
, 0, "importing --load-ca-privkey: %s: %s",
1618 info
.ca_privkey
, gnutls_strerror (ret
));
1623 /* Loads the CA's certificate
1628 gnutls_x509_crt_t crt
;
1633 if (info
.ca
== NULL
)
1634 error (EXIT_FAILURE
, 0, "missing --load-ca-certificate");
1636 ret
= gnutls_x509_crt_init (&crt
);
1638 error (EXIT_FAILURE
, 0, "crt_init: %s", gnutls_strerror (ret
));
1640 dat
.data
= read_binary_file (info
.ca
, &size
);
1644 error (EXIT_FAILURE
, errno
, "reading --load-ca-certificate: %s",
1647 ret
= gnutls_x509_crt_import (crt
, &dat
, info
.incert_format
);
1650 error (EXIT_FAILURE
, 0, "importing --load-ca-certificate: %s: %s",
1651 info
.ca
, gnutls_strerror (ret
));
1656 /* Loads the certificate
1657 * If mand is non zero then a certificate is mandatory. Otherwise
1658 * null will be returned if the certificate loading fails.
1661 load_cert (int mand
)
1663 gnutls_x509_crt_t
*crt
;
1666 crt
= load_cert_list (mand
, &size
);
1668 return crt
? crt
[0] : NULL
;
1671 #define MAX_CERTS 256
1673 /* Loads a certificate list
1676 load_cert_list (int mand
, int *crt_size
)
1679 static gnutls_x509_crt_t crt
[MAX_CERTS
];
1687 fprintf (stderr
, "Loading certificate list...\n");
1689 if (info
.cert
== NULL
)
1692 error (EXIT_FAILURE
, 0, "missing --load-certificate");
1697 fd
= fopen (info
.cert
, "r");
1699 error (EXIT_FAILURE
, 0, "File %s does not exist", info
.cert
);
1701 size
= fread (buffer
, 1, sizeof (buffer
) - 1, fd
);
1709 for (i
= 0; i
< MAX_CERTS
; i
++)
1711 ret
= gnutls_x509_crt_init (&crt
[i
]);
1713 error (EXIT_FAILURE
, 0, "crt_init: %s", gnutls_strerror (ret
));
1716 dat
.size
= ptr_size
;
1718 ret
= gnutls_x509_crt_import (crt
[i
], &dat
, info
.incert_format
);
1719 if (ret
< 0 && *crt_size
> 0)
1722 error (EXIT_FAILURE
, 0, "crt_import: %s", gnutls_strerror (ret
));
1724 ptr
= strstr (ptr
, "---END");
1731 (unsigned int) ((unsigned char *) ptr
-
1732 (unsigned char *) buffer
);
1739 fprintf (stderr
, "Loaded %d certificates.\n", *crt_size
);
1745 /* Generate a PKCS #10 certificate request.
1748 generate_request (void)
1750 gnutls_x509_crq_t crq
;
1751 gnutls_x509_privkey_t key
;
1756 fprintf (stderr
, "Generating a PKCS #10 certificate request...\n");
1758 ret
= gnutls_x509_crq_init (&crq
);
1760 error (EXIT_FAILURE
, 0, "crq_init: %s", gnutls_strerror (ret
));
1762 /* Load the private key.
1764 key
= load_private_key (0);
1767 key
= generate_private_key_int ();
1769 print_private_key (key
);
1774 get_country_crq_set (crq
);
1775 get_organization_crq_set (crq
);
1776 get_unit_crq_set (crq
);
1777 get_locality_crq_set (crq
);
1778 get_state_crq_set (crq
);
1779 get_cn_crq_set (crq
);
1780 get_uid_crq_set (crq
);
1781 get_oid_crq_set (crq
);
1783 pass
= get_challenge_pass ();
1787 ret
= gnutls_x509_crq_set_challenge_password (crq
, pass
);
1789 error (EXIT_FAILURE
, 0, "set_pass: %s", gnutls_strerror (ret
));
1792 ret
= gnutls_x509_crq_set_key (crq
, key
);
1794 error (EXIT_FAILURE
, 0, "set_key: %s", gnutls_strerror (ret
));
1796 ret
= gnutls_x509_crq_sign (crq
, key
);
1798 error (EXIT_FAILURE
, 0, "sign: %s", gnutls_strerror (ret
));
1800 size
= sizeof (buffer
);
1801 ret
= gnutls_x509_crq_export (crq
, info
.outcert_format
, buffer
, &size
);
1803 error (EXIT_FAILURE
, 0, "export: %s", gnutls_strerror (ret
));
1805 fwrite (buffer
, 1, size
, outfile
);
1807 gnutls_x509_crq_deinit (crq
);
1808 gnutls_x509_privkey_deinit (key
);
1812 static void print_verification_res (gnutls_x509_crt_t crt
,
1813 gnutls_x509_crt_t issuer
,
1814 gnutls_x509_crl_t
* crl_list
,
1817 #define CERT_SEP "-----BEGIN CERT"
1818 #define CRL_SEP "-----BEGIN X509 CRL"
1820 _verify_x509_mem (const void *cert
, int cert_size
)
1826 char issuer_name
[256];
1828 size_t issuer_name_size
;
1830 gnutls_x509_crt_t
*x509_cert_list
= NULL
;
1831 gnutls_x509_crl_t
*x509_crl_list
= NULL
;
1832 int x509_ncerts
, x509_ncrls
;
1835 /* Decode the CA certificate
1838 /* Decode the CRL list
1845 if (strstr (ptr
, CRL_SEP
) != NULL
) /* if CRLs exist */
1849 (gnutls_x509_crl_t
*) realloc (x509_crl_list
,
1850 i
* sizeof (gnutls_x509_crl_t
));
1851 if (x509_crl_list
== NULL
)
1852 error (EXIT_FAILURE
, 0, "memory error");
1854 tmp
.data
= (char *) ptr
;
1855 tmp
.size
= cert_size
;
1857 (unsigned int) ((unsigned char *) ptr
-
1858 (unsigned char *) cert
);
1860 ret
= gnutls_x509_crl_init (&x509_crl_list
[i
- 1]);
1862 error (EXIT_FAILURE
, 0, "Error parsing the CRL[%d]: %s", i
,
1863 gnutls_strerror (ret
));
1865 ret
= gnutls_x509_crl_import (x509_crl_list
[i
- 1], &tmp
,
1866 GNUTLS_X509_FMT_PEM
);
1868 error (EXIT_FAILURE
, 0, "Error parsing the CRL[%d]: %s", i
,
1869 gnutls_strerror (ret
));
1871 /* now we move ptr after the pem header */
1872 ptr
= strstr (ptr
, CRL_SEP
);
1878 while ((ptr
= strstr (ptr
, CRL_SEP
)) != NULL
);
1883 /* Decode the certificate chain.
1893 (gnutls_x509_crt_t
*) realloc (x509_cert_list
,
1894 i
* sizeof (gnutls_x509_crt_t
));
1895 if (x509_cert_list
== NULL
)
1896 error (EXIT_FAILURE
, 0, "memory error");
1899 tmp
.data
= (char *) ptr
;
1900 tmp
.size
= cert_size
;
1902 (unsigned int) ((unsigned char *) ptr
- (unsigned char *) cert
);
1904 ret
= gnutls_x509_crt_init (&x509_cert_list
[i
- 1]);
1906 error (EXIT_FAILURE
, 0, "Error parsing the certificate[%d]: %s", i
,
1907 gnutls_strerror (ret
));
1910 gnutls_x509_crt_import (x509_cert_list
[i
- 1], &tmp
,
1911 GNUTLS_X509_FMT_PEM
);
1913 error (EXIT_FAILURE
, 0, "Error parsing the certificate[%d]: %s", i
,
1914 gnutls_strerror (ret
));
1919 /* verify the previous certificate using this one
1923 name_size
= sizeof (name
);
1925 gnutls_x509_crt_get_dn (x509_cert_list
[i
- 2], name
,
1928 error (EXIT_FAILURE
, 0, "get_dn: %s", gnutls_strerror (ret
));
1930 fprintf (outfile
, "Certificate[%d]: %s\n", i
- 2, name
);
1934 issuer_name_size
= sizeof (issuer_name
);
1936 gnutls_x509_crt_get_issuer_dn (x509_cert_list
[i
- 2],
1940 error (EXIT_FAILURE
, 0, "get_issuer_dn: %s",
1941 gnutls_strerror (ret
));
1943 fprintf (outfile
, "\tIssued by: %s\n", issuer_name
);
1945 /* Get the Issuer's name
1947 name_size
= sizeof (name
);
1949 gnutls_x509_crt_get_dn (x509_cert_list
[i
- 1], name
,
1952 error (EXIT_FAILURE
, 0, "get_dn: %s", gnutls_strerror (ret
));
1954 fprintf (outfile
, "\tVerifying against certificate[%d].\n",
1957 if (strcmp (issuer_name
, name
) != 0)
1959 fprintf (stderr
, "Error: Issuer's name: %s\n", name
);
1960 error (EXIT_FAILURE
, 0,
1961 "Issuer's name does not match the next certificate");
1964 fprintf (outfile
, "\tVerification output: ");
1965 print_verification_res (x509_cert_list
[i
- 2],
1966 x509_cert_list
[i
- 1], x509_crl_list
,
1968 fprintf (outfile
, ".\n\n");
1973 /* now we move ptr after the pem header
1975 ptr
= strstr (ptr
, CERT_SEP
);
1981 while ((ptr
= strstr (ptr
, CERT_SEP
)) != NULL
);
1983 x509_ncerts
= i
- 1;
1985 /* The last certificate in the list will be used as
1986 * a CA (should be self signed).
1988 name_size
= sizeof (name
);
1989 ret
= gnutls_x509_crt_get_dn (x509_cert_list
[x509_ncerts
- 1], name
,
1992 error (EXIT_FAILURE
, 0, "get_dn: %s", gnutls_strerror (ret
));
1994 fprintf (outfile
, "Certificate[%d]: %s\n", x509_ncerts
- 1, name
);
1998 issuer_name_size
= sizeof (issuer_name
);
2000 gnutls_x509_crt_get_issuer_dn (x509_cert_list
[x509_ncerts
- 1],
2001 issuer_name
, &issuer_name_size
);
2003 error (EXIT_FAILURE
, 0, "get_issuer_dn: %s", gnutls_strerror (ret
));
2005 fprintf (outfile
, "\tIssued by: %s\n", name
);
2007 if (strcmp (issuer_name
, name
) != 0)
2008 error (EXIT_FAILURE
, 0,
2009 "Error: The last certificate is not self signed.");
2011 fprintf (outfile
, "\tVerification output: ");
2012 print_verification_res (x509_cert_list
[x509_ncerts
- 1],
2013 x509_cert_list
[x509_ncerts
- 1], x509_crl_list
,
2016 fprintf (outfile
, ".\n\n");
2018 for (i
= 0; i
< x509_ncerts
; i
++)
2019 gnutls_x509_crt_deinit (x509_cert_list
[i
]);
2021 for (i
= 0; i
< x509_ncrls
; i
++)
2022 gnutls_x509_crl_deinit (x509_crl_list
[i
]);
2024 free (x509_cert_list
);
2025 free (x509_crl_list
);
2028 error (EXIT_FAILURE
, 0, "Error in verification: %s",
2029 gnutls_strerror (ret
));
2035 print_verification_res (gnutls_x509_crt_t crt
,
2036 gnutls_x509_crt_t issuer
,
2037 gnutls_x509_crl_t
* crl_list
, int crl_list_size
)
2039 unsigned int output
;
2042 time_t now
= time (0);
2044 ret
= gnutls_x509_crt_verify (crt
, &issuer
, 1, 0, &output
);
2046 error (EXIT_FAILURE
, 0, "Error in verification: %s",
2047 gnutls_strerror (ret
));
2049 if (output
& GNUTLS_CERT_INVALID
)
2051 fprintf (outfile
, "Not verified");
2056 fprintf (outfile
, "Verified");
2060 if (output
& GNUTLS_CERT_SIGNER_NOT_CA
)
2063 fprintf (outfile
, ", ");
2064 fprintf (outfile
, "Issuer is not a CA");
2068 if (output
& GNUTLS_CERT_INSECURE_ALGORITHM
)
2071 fprintf (outfile
, ", ");
2072 fprintf (outfile
, "Insecure algorithm");
2076 /* Check expiration dates.
2079 if (gnutls_x509_crt_get_activation_time (crt
) > now
)
2082 fprintf (outfile
, ", ");
2084 fprintf (outfile
, "Not activated");
2087 if (gnutls_x509_crt_get_expiration_time (crt
) < now
)
2090 fprintf (outfile
, ", ");
2092 fprintf (outfile
, "Expired");
2095 ret
= gnutls_x509_crt_check_revocation (crt
, crl_list
, crl_list_size
);
2097 error (EXIT_FAILURE
, 0, "Revocation check: %s", gnutls_strerror (ret
));
2102 fprintf (outfile
, ", ");
2104 fprintf (outfile
, "Revoked");
2114 buffer
= fread_file (infile
, &size
);
2116 error (EXIT_FAILURE
, errno
, "reading chain");
2120 _verify_x509_mem (buffer
, size
);
2127 size_t size
, dn_size
;
2129 unsigned int output
;
2133 gnutls_x509_crl_t crl
;
2134 time_t now
= time (0);
2135 gnutls_x509_crt_t issuer
;
2137 issuer
= load_ca_cert ();
2139 fprintf (outfile
, "\nCA certificate:\n");
2141 dn_size
= sizeof (dn
);
2142 ret
= gnutls_x509_crt_get_dn (issuer
, dn
, &dn_size
);
2144 error (EXIT_FAILURE
, 0, "crt_get_dn: %s", gnutls_strerror (ret
));
2146 fprintf (outfile
, "\tSubject: %s\n\n", dn
);
2148 ret
= gnutls_x509_crl_init (&crl
);
2150 error (EXIT_FAILURE
, 0, "crl_init: %s", gnutls_strerror (ret
));
2152 pem
.data
= fread_file (infile
, &size
);
2155 ret
= gnutls_x509_crl_import (crl
, &pem
, info
.incert_format
);
2158 error (EXIT_FAILURE
, 0, "Import error: %s", gnutls_strerror (ret
));
2160 print_crl_info (crl
, outfile
);
2162 fprintf (outfile
, "Verification output: ");
2163 ret
= gnutls_x509_crl_verify (crl
, &issuer
, 1, 0, &output
);
2165 error (EXIT_FAILURE
, 0, "Verification error: %s",
2166 gnutls_strerror (ret
));
2168 if (output
& GNUTLS_CERT_INVALID
)
2170 fprintf (outfile
, "Not verified");
2175 fprintf (outfile
, "Verified");
2179 if (output
& GNUTLS_CERT_SIGNER_NOT_CA
)
2182 fprintf (outfile
, ", ");
2183 fprintf (outfile
, "Issuer is not a CA");
2187 if (output
& GNUTLS_CERT_INSECURE_ALGORITHM
)
2190 fprintf (outfile
, ", ");
2191 fprintf (outfile
, "Insecure algorithm");
2195 /* Check expiration dates.
2198 if (gnutls_x509_crl_get_this_update (crl
) > now
)
2201 fprintf (outfile
, ", ");
2203 fprintf (outfile
, "Issued in the future!");
2206 if (gnutls_x509_crl_get_next_update (crl
) < now
)
2209 fprintf (outfile
, ", ");
2211 fprintf (outfile
, "CRL is not up to date");
2214 fprintf (outfile
, "\n");
2218 generate_pkcs8 (void)
2220 gnutls_x509_privkey_t key
;
2224 const char *password
;
2226 fprintf (stderr
, "Generating a PKCS #8 key structure...\n");
2228 key
= load_private_key (1);
2231 password
= info
.pass
;
2233 password
= get_pass ();
2236 flags
= GNUTLS_PKCS_USE_PKCS12_RC2_40
;
2238 flags
= GNUTLS_PKCS_USE_PKCS12_3DES
;
2240 if (password
== NULL
|| password
[0] == 0)
2242 flags
= GNUTLS_PKCS_PLAIN
;
2245 size
= sizeof (buffer
);
2247 gnutls_x509_privkey_export_pkcs8 (key
, info
.outcert_format
,
2248 password
, flags
, buffer
, &size
);
2251 error (EXIT_FAILURE
, 0, "key_export: %s", gnutls_strerror (result
));
2253 fwrite (buffer
, 1, size
, outfile
);
2258 #include <gnutls/pkcs12.h>
2262 generate_pkcs12 (void)
2264 gnutls_pkcs12_t pkcs12
;
2265 gnutls_x509_crt_t
*crts
;
2266 gnutls_x509_privkey_t key
;
2269 gnutls_datum_t data
;
2270 const char *password
;
2273 gnutls_datum_t key_id
;
2274 unsigned char _key_id
[20];
2279 fprintf (stderr
, "Generating a PKCS #12 structure...\n");
2281 key
= load_private_key (0);
2282 crts
= load_cert_list (0, &ncrts
);
2284 name
= get_pkcs12_key_name ();
2286 result
= gnutls_pkcs12_init (&pkcs12
);
2288 error (EXIT_FAILURE
, 0, "pkcs12_init: %s", gnutls_strerror (result
));
2291 password
= info
.pass
;
2293 password
= get_pass ();
2295 for (i
= 0; i
< ncrts
; i
++)
2297 gnutls_pkcs12_bag_t bag
;
2299 result
= gnutls_pkcs12_bag_init (&bag
);
2301 error (EXIT_FAILURE
, 0, "bag_init: %s", gnutls_strerror (result
));
2303 result
= gnutls_pkcs12_bag_set_crt (bag
, crts
[i
]);
2305 error (EXIT_FAILURE
, 0, "set_crt[%d]: %s", i
,
2306 gnutls_strerror (result
));
2310 result
= gnutls_pkcs12_bag_set_friendly_name (bag
, index
, name
);
2312 error (EXIT_FAILURE
, 0, "bag_set_friendly_name: %s",
2313 gnutls_strerror (result
));
2315 size
= sizeof (_key_id
);
2316 result
= gnutls_x509_crt_get_key_id (crts
[i
], 0, _key_id
, &size
);
2318 error (EXIT_FAILURE
, 0, "key_id[%d]: %s", i
,
2319 gnutls_strerror (result
));
2321 key_id
.data
= _key_id
;
2324 result
= gnutls_pkcs12_bag_set_key_id (bag
, index
, &key_id
);
2326 error (EXIT_FAILURE
, 0, "bag_set_key_id: %s",
2327 gnutls_strerror (result
));
2330 flags
= GNUTLS_PKCS_USE_PKCS12_RC2_40
;
2332 flags
= GNUTLS_PKCS8_USE_PKCS12_3DES
;
2334 result
= gnutls_pkcs12_bag_encrypt (bag
, password
, flags
);
2336 error (EXIT_FAILURE
, 0, "bag_encrypt: %s",
2337 gnutls_strerror (result
));
2339 result
= gnutls_pkcs12_set_bag (pkcs12
, bag
);
2341 error (EXIT_FAILURE
, 0, "set_bag: %s", gnutls_strerror (result
));
2346 gnutls_pkcs12_bag_t kbag
;
2348 result
= gnutls_pkcs12_bag_init (&kbag
);
2350 error (EXIT_FAILURE
, 0, "bag_init: %s", gnutls_strerror (result
));
2353 flags
= GNUTLS_PKCS_USE_PKCS12_RC2_40
;
2355 flags
= GNUTLS_PKCS_USE_PKCS12_3DES
;
2357 size
= sizeof (buffer
);
2359 gnutls_x509_privkey_export_pkcs8 (key
, GNUTLS_X509_FMT_DER
,
2360 password
, flags
, buffer
,
2363 error (EXIT_FAILURE
, 0, "key_export: %s",
2364 gnutls_strerror (result
));
2369 gnutls_pkcs12_bag_set_data (kbag
,
2370 GNUTLS_BAG_PKCS8_ENCRYPTED_KEY
,
2373 error (EXIT_FAILURE
, 0, "bag_set_data: %s",
2374 gnutls_strerror (result
));
2378 result
= gnutls_pkcs12_bag_set_friendly_name (kbag
, index
, name
);
2380 error (EXIT_FAILURE
, 0, "bag_set_friendly_name: %s",
2381 gnutls_strerror (result
));
2383 size
= sizeof (_key_id
);
2384 result
= gnutls_x509_privkey_get_key_id (key
, 0, _key_id
, &size
);
2386 error (EXIT_FAILURE
, 0, "key_id: %s", gnutls_strerror (result
));
2388 key_id
.data
= _key_id
;
2391 result
= gnutls_pkcs12_bag_set_key_id (kbag
, index
, &key_id
);
2393 error (EXIT_FAILURE
, 0, "bag_set_key_id: %s",
2394 gnutls_strerror (result
));
2396 result
= gnutls_pkcs12_set_bag (pkcs12
, kbag
);
2398 error (EXIT_FAILURE
, 0, "set_bag: %s", gnutls_strerror (result
));
2401 result
= gnutls_pkcs12_generate_mac (pkcs12
, password
);
2403 error (EXIT_FAILURE
, 0, "generate_mac: %s", gnutls_strerror (result
));
2405 size
= sizeof (buffer
);
2407 gnutls_pkcs12_export (pkcs12
, info
.outcert_format
, buffer
, &size
);
2409 error (EXIT_FAILURE
, 0, "pkcs12_export: %s", gnutls_strerror (result
));
2411 fwrite (buffer
, 1, size
, outfile
);
2416 BAGTYPE (gnutls_pkcs12_bag_type_t x
)
2420 case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY
:
2421 return "PKCS #8 Encrypted key";
2422 case GNUTLS_BAG_EMPTY
:
2424 case GNUTLS_BAG_PKCS8_KEY
:
2425 return "PKCS #8 Key";
2426 case GNUTLS_BAG_CERTIFICATE
:
2427 return "Certificate";
2428 case GNUTLS_BAG_ENCRYPTED
:
2430 case GNUTLS_BAG_CRL
:
2438 print_bag_data (gnutls_pkcs12_bag_t bag
)
2442 gnutls_datum_t cdata
, id
;
2443 const char *str
, *name
;
2446 count
= gnutls_pkcs12_bag_get_count (bag
);
2448 error (EXIT_FAILURE
, 0, "get_count: %s", gnutls_strerror (count
));
2450 fprintf (outfile
, "\tElements: %d\n", count
);
2452 for (i
= 0; i
< count
; i
++)
2454 type
= gnutls_pkcs12_bag_get_type (bag
, i
);
2456 error (EXIT_FAILURE
, 0, "get_type: %s", gnutls_strerror (type
));
2458 fprintf (stderr
, "\tType: %s\n", BAGTYPE (type
));
2462 gnutls_pkcs12_bag_get_friendly_name (bag
, i
, (char **) &name
);
2464 error (EXIT_FAILURE
, 0, "get_friendly_name: %s",
2465 gnutls_strerror (type
));
2467 fprintf (outfile
, "\tFriendly name: %s\n", name
);
2471 result
= gnutls_pkcs12_bag_get_key_id (bag
, i
, &id
);
2473 error (EXIT_FAILURE
, 0, "get_key_id: %s", gnutls_strerror (type
));
2474 fprintf (outfile
, "\tKey ID: %s\n",
2475 raw_to_string (id
.data
, id
.size
));
2477 result
= gnutls_pkcs12_bag_get_data (bag
, i
, &cdata
);
2479 error (EXIT_FAILURE
, 0, "get_data: %s", gnutls_strerror (result
));
2483 case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY
:
2484 str
= "ENCRYPTED PRIVATE KEY";
2486 case GNUTLS_BAG_PKCS8_KEY
:
2487 str
= "PRIVATE KEY";
2489 case GNUTLS_BAG_CERTIFICATE
:
2490 str
= "CERTIFICATE";
2492 case GNUTLS_BAG_CRL
:
2495 case GNUTLS_BAG_ENCRYPTED
:
2496 case GNUTLS_BAG_EMPTY
:
2503 gnutls_pem_base64_encode_alloc (str
, &cdata
, &out
);
2504 fprintf (outfile
, "%s\n", out
.data
);
2506 gnutls_free (out
.data
);
2515 gnutls_pkcs12_t pkcs12
;
2516 gnutls_pkcs12_bag_t bag
;
2519 gnutls_datum_t data
;
2520 const char *password
;
2523 result
= gnutls_pkcs12_init (&pkcs12
);
2525 error (EXIT_FAILURE
, 0, "p12_init: %s", gnutls_strerror (result
));
2527 data
.data
= fread_file (infile
, &size
);
2530 result
= gnutls_pkcs12_import (pkcs12
, &data
, info
.incert_format
, 0);
2533 error (EXIT_FAILURE
, 0, "p12_import: %s", gnutls_strerror (result
));
2536 password
= info
.pass
;
2538 password
= get_pass ();
2540 result
= gnutls_pkcs12_verify_mac (pkcs12
, password
);
2542 error (EXIT_FAILURE
, 0, "verify_mac: %s", gnutls_strerror (result
));
2546 for (index
= 0;; index
++)
2548 result
= gnutls_pkcs12_bag_init (&bag
);
2550 error (EXIT_FAILURE
, 0, "bag_init: %s", gnutls_strerror (result
));
2552 result
= gnutls_pkcs12_get_bag (pkcs12
, index
, bag
);
2556 result
= gnutls_pkcs12_bag_get_count (bag
);
2558 error (EXIT_FAILURE
, 0, "bag_count: %s", gnutls_strerror (result
));
2560 fprintf (outfile
, "BAG #%d\n", index
);
2562 result
= gnutls_pkcs12_bag_get_type (bag
, 0);
2564 error (EXIT_FAILURE
, 0, "bag_init: %s", gnutls_strerror (result
));
2566 if (result
== GNUTLS_BAG_ENCRYPTED
)
2568 fprintf (stderr
, "\tType: %s\n", BAGTYPE (result
));
2569 fprintf (stderr
, "\n\tDecrypting...\n");
2571 result
= gnutls_pkcs12_bag_decrypt (bag
, password
);
2574 error (EXIT_FAILURE
, 0, "bag_decrypt: %s",
2575 gnutls_strerror (result
));
2577 result
= gnutls_pkcs12_bag_get_count (bag
);
2579 error (EXIT_FAILURE
, 0, "encrypted bag_count: %s",
2580 gnutls_strerror (result
));
2583 print_bag_data (bag
);
2585 gnutls_pkcs12_bag_deinit (bag
);
2592 gnutls_pkcs7_t pkcs7
;
2595 gnutls_datum_t data
, b64
;
2598 result
= gnutls_pkcs7_init (&pkcs7
);
2600 error (EXIT_FAILURE
, 0, "p7_init: %s", gnutls_strerror (result
));
2602 data
.data
= fread_file (infile
, &size
);
2605 result
= gnutls_pkcs7_import (pkcs7
, &data
, info
.incert_format
);
2608 error (EXIT_FAILURE
, 0, "Import error: %s", gnutls_strerror (result
));
2610 /* Read and print the certificates.
2612 result
= gnutls_pkcs7_get_crt_count (pkcs7
);
2614 error (EXIT_FAILURE
, 0, "p7_crt_count: %s", gnutls_strerror (result
));
2619 fprintf (outfile
, "Number of certificates: %u\n", count
);
2621 for (index
= 0; index
< count
; index
++)
2623 fputs ("\n", outfile
);
2625 size
= sizeof (buffer
);
2626 result
= gnutls_pkcs7_get_crt_raw (pkcs7
, index
, buffer
, &size
);
2633 result
= gnutls_pem_base64_encode_alloc ("CERTIFICATE", &data
, &b64
);
2635 error (EXIT_FAILURE
, 0, "encoding: %s", gnutls_strerror (result
));
2637 fputs (b64
.data
, outfile
);
2638 gnutls_free (b64
.data
);
2641 /* Read the CRLs now.
2643 result
= gnutls_pkcs7_get_crl_count (pkcs7
);
2645 error (EXIT_FAILURE
, 0, "p7_crl_count: %s", gnutls_strerror (result
));
2650 fprintf (outfile
, "\nNumber of CRLs: %u\n", count
);
2652 for (index
= 0; index
< count
; index
++)
2654 fputs ("\n", outfile
);
2656 size
= sizeof (buffer
);
2657 result
= gnutls_pkcs7_get_crl_raw (pkcs7
, index
, buffer
, &size
);
2664 result
= gnutls_pem_base64_encode_alloc ("X509 CRL", &data
, &b64
);
2666 error (EXIT_FAILURE
, 0, "encoding: %s", gnutls_strerror (result
));
2668 fputs (b64
.data
, outfile
);
2669 gnutls_free (b64
.data
);
2674 smime_to_pkcs7 (void)
2676 size_t linesize
= 0;
2677 char *lineptr
= NULL
;
2680 /* Find body. FIXME: Handle non-b64 Content-Transfer-Encoding.
2681 Reject non-S/MIME tagged Content-Type's? */
2684 len
= getline (&lineptr
, &linesize
, infile
);
2686 error (EXIT_FAILURE
, 0,
2687 "Cannot find RFC 2822 header/body separator");
2689 while (strcmp (lineptr
, "\r\n") != 0 && strcmp (lineptr
, "\n") != 0);
2693 len
= getline (&lineptr
, &linesize
, infile
);
2695 error (EXIT_FAILURE
, 0, "Message has RFC 2822 header but no body");
2697 while (strcmp (lineptr
, "\r\n") == 0 && strcmp (lineptr
, "\n") == 0);
2699 fprintf (outfile
, "%s", "-----BEGIN PKCS7-----\n");
2704 && (lineptr
[len
- 1] == '\r' || lineptr
[len
- 1] == '\n'))
2705 lineptr
[--len
] = '\0';
2706 if (strcmp (lineptr
, "") != 0)
2707 fprintf (outfile
, "%s\n", lineptr
);
2708 len
= getline (&lineptr
, &linesize
, infile
);
2712 fprintf (outfile
, "%s", "-----END PKCS7-----\n");
2718 certtool_version (void)
2720 version_etc (stdout
, program_name
, PACKAGE_STRING
,
2721 gnutls_check_version (NULL
), "Nikos Mavrogiannopoulos",
2722 "Simon Josefsson", (char *) NULL
);