2 * Copyright (C) 2003, 2004, 2005, 2006, 2007 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 2 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, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 #include <gnutls/gnutls.h>
28 #include <gnutls/x509.h>
30 #include "certtool-gaa.h"
31 #include <gnutls/pkcs12.h>
33 #include <certtool-cfg.h>
37 /* Gnulib portability files. */
39 #include <read-file.h>
42 #include <version-etc.h>
44 static void print_crl_info (gnutls_x509_crl crl
, FILE *out
);
45 int generate_prime (int bits
, int how
);
46 void pkcs7_info (void);
47 void smime_to_pkcs7 (void);
48 void pkcs12_info (void);
49 void generate_pkcs12 (void);
50 void verify_chain (void);
51 void verify_crl (void);
52 gnutls_x509_privkey
load_private_key (int mand
);
53 gnutls_x509_crq
load_request (void);
54 gnutls_x509_privkey
load_ca_private_key (void);
55 gnutls_x509_crt
load_ca_cert (void);
56 gnutls_x509_crt
load_cert (int mand
);
57 void certificate_info (void);
59 void privkey_info (void);
60 static void print_certificate_info (gnutls_x509_crt crt
, FILE *out
,
62 static void gaa_parser (int argc
, char **argv
);
63 void generate_self_signed (void);
64 void generate_request (void);
65 gnutls_x509_crt
*load_cert_list (int mand
, int *size
);
70 gnutls_digest_algorithm_t dig
= GNUTLS_DIG_SHA1
;
72 #define UNKNOWN "Unknown"
74 /* non interactive operation if set
78 unsigned char buffer
[64 * 1024];
79 const int buffer_size
= sizeof (buffer
);
82 tls_log_func (int level
, const char *str
)
84 fprintf (stderr
, "|<%d>| %s", level
, str
);
88 main (int argc
, char **argv
)
90 set_program_name (argv
[0]);
92 gaa_parser (argc
, argv
);
98 raw_to_string (const unsigned char *raw
, size_t raw_size
)
100 static char buf
[1024];
105 if (raw_size
* 3 + 1 >= sizeof (buf
))
108 for (i
= 0; i
< raw_size
; i
++)
110 sprintf (&(buf
[i
* 3]), "%02X%s", raw
[i
],
111 (i
== raw_size
- 1) ? "" : ":");
113 buf
[sizeof (buf
) - 1] = '\0';
118 static gnutls_x509_privkey
119 generate_private_key_int (void)
121 gnutls_x509_privkey key
;
126 key_type
= GNUTLS_PK_DSA
;
128 if (info
.bits
> 1024)
129 error (EXIT_FAILURE
, 0, "--dsa is incompatible with --bits > 1024");
132 key_type
= GNUTLS_PK_RSA
;
134 ret
= gnutls_x509_privkey_init (&key
);
136 error (EXIT_FAILURE
, 0, "privkey_init: %s", gnutls_strerror (ret
));
138 fprintf (stderr
, "Generating a %d bit %s private key...\n", info
.bits
,
139 gnutls_pk_algorithm_get_name (key_type
));
141 ret
= gnutls_x509_privkey_generate (key
, key_type
, info
.bits
, 0);
143 error (EXIT_FAILURE
, 0, "privkey_generate: %s", gnutls_strerror (ret
));
149 print_private_key (gnutls_x509_privkey key
)
159 size
= sizeof (buffer
);
160 ret
= gnutls_x509_privkey_export (key
, info
.outcert_format
,
163 error (EXIT_FAILURE
, 0, "privkey_export: %s", gnutls_strerror (ret
));
171 flags
= GNUTLS_PKCS_USE_PKCS12_RC2_40
;
173 flags
= GNUTLS_PKCS_USE_PKCS12_3DES
;
175 if ((pass
= get_pass ()) == NULL
|| *pass
== '\0')
176 flags
= GNUTLS_PKCS_PLAIN
;
178 size
= sizeof (buffer
);
180 gnutls_x509_privkey_export_pkcs8 (key
, info
.outcert_format
, pass
,
181 flags
, buffer
, &size
);
183 error (EXIT_FAILURE
, 0, "privkey_export_pkcs8: %s",
184 gnutls_strerror (ret
));
187 fwrite (buffer
, 1, size
, outfile
);
191 generate_private_key (void)
193 gnutls_x509_privkey key
;
195 key
= generate_private_key_int ();
197 print_private_key (key
);
199 gnutls_x509_privkey_deinit (key
);
204 generate_certificate (gnutls_x509_privkey
* ret_key
,
205 gnutls_x509_crt ca_crt
,
209 gnutls_x509_privkey key
= NULL
;
213 int days
, result
, ca_status
= 0, path_len
;
215 int vers
= 3; /* the default version in the certificate
217 unsigned int usage
= 0, server
;
218 gnutls_x509_crq crq
; /* request */
220 ret
= gnutls_x509_crt_init (&crt
);
222 error (EXIT_FAILURE
, 0, "crt_init: %s", gnutls_strerror (ret
));
224 crq
= load_request ();
229 key
= load_private_key (1);
233 "Please enter the details of the certificate's distinguished name. "
234 "Just press enter to ignore a field.\n");
240 result
= gnutls_x509_crt_set_proxy_dn (crt
, ca_crt
, 0, NULL
, 0);
242 error (EXIT_FAILURE
, 0, "set_proxy_dn: %s",
243 gnutls_strerror (result
));
245 get_cn_crt_set (crt
);
249 get_country_crt_set (crt
);
250 get_organization_crt_set (crt
);
251 get_unit_crt_set (crt
);
252 get_locality_crt_set (crt
);
253 get_state_crt_set (crt
);
254 get_cn_crt_set (crt
);
255 get_uid_crt_set (crt
);
256 get_oid_crt_set (crt
);
260 "This field should not be used in new certificates.\n");
262 get_pkcs9_email_crt_set (crt
);
265 result
= gnutls_x509_crt_set_key (crt
, key
);
267 error (EXIT_FAILURE
, 0, "set_key: %s", gnutls_strerror (result
));
271 result
= gnutls_x509_crt_set_crq (crt
, crq
);
273 error (EXIT_FAILURE
, 0, "set_crq: %s", gnutls_strerror (result
));
277 serial
= get_serial ();
278 buffer
[4] = serial
& 0xff;
279 buffer
[3] = (serial
>> 8) & 0xff;
280 buffer
[2] = (serial
>> 16) & 0xff;
281 buffer
[1] = (serial
>> 24) & 0xff;
284 result
= gnutls_x509_crt_set_serial (crt
, buffer
, 5);
286 error (EXIT_FAILURE
, 0, "serial: %s", gnutls_strerror (result
));
289 fprintf (stderr
, "\n\nActivation/Expiration time.\n");
291 gnutls_x509_crt_set_activation_time (crt
, time (NULL
));
296 gnutls_x509_crt_set_expiration_time (crt
,
297 time (NULL
) + days
* 24 * 60 * 60);
299 error (EXIT_FAILURE
, 0, "set_expiration: %s", gnutls_strerror (result
));
302 fprintf (stderr
, "\n\nExtensions.\n");
306 const char *policylanguage
;
309 int proxypathlen
= get_path_len ();
313 printf ("1.3.6.1.5.5.7.21.1 ::= id-ppl-inheritALL\n");
314 printf ("1.3.6.1.5.5.7.21.2 ::= id-ppl-independent\n");
317 policylanguage
= get_proxy_policy (&policy
, &policylen
);
319 result
= gnutls_x509_crt_set_proxy (crt
, proxypathlen
, policylanguage
,
322 error (EXIT_FAILURE
, 0, "set_proxy: %s", gnutls_strerror (result
));
326 ca_status
= get_ca_status ();
328 path_len
= get_path_len ();
332 result
= gnutls_x509_crt_set_basic_constraints (crt
, ca_status
, path_len
);
334 error (EXIT_FAILURE
, 0, "basic_constraints: %s", gnutls_strerror (result
));
336 client
= get_tls_client_status ();
339 result
= gnutls_x509_crt_set_key_purpose_oid (crt
,
340 GNUTLS_KP_TLS_WWW_CLIENT
,
343 error (EXIT_FAILURE
, 0, "key_kp: %s", gnutls_strerror (result
));
346 server
= get_tls_server_status ();
353 str
= get_dns_name ();
356 result
= gnutls_x509_crt_set_subject_alternative_name
357 (crt
, GNUTLS_SAN_DNSNAME
, str
);
361 str
= get_ip_addr ();
364 result
= gnutls_x509_crt_set_subject_alternative_name
365 (crt
, GNUTLS_SAN_IPADDRESS
, str
);
370 error (EXIT_FAILURE
, 0, "subject_alt_name: %s",
371 gnutls_strerror (result
));
375 gnutls_x509_crt_set_key_purpose_oid (crt
,
376 GNUTLS_KP_TLS_WWW_SERVER
, 0);
378 error (EXIT_FAILURE
, 0, "key_kp: %s", gnutls_strerror (result
));
386 result
= gnutls_x509_crt_set_subject_alternative_name
387 (crt
, GNUTLS_SAN_RFC822NAME
, str
);
389 error (EXIT_FAILURE
, 0, "subject_alt_name: %s",
390 gnutls_strerror (result
));
395 if (!ca_status
|| server
)
400 pk
= gnutls_x509_crt_get_pk_algorithm (crt
, NULL
);
402 if (pk
!= GNUTLS_PK_DSA
)
403 { /* DSA keys can only sign.
405 result
= get_sign_status (server
);
407 usage
|= GNUTLS_KEY_DIGITAL_SIGNATURE
;
409 result
= get_encrypt_status (server
);
411 usage
|= GNUTLS_KEY_KEY_ENCIPHERMENT
;
414 usage
|= GNUTLS_KEY_DIGITAL_SIGNATURE
;
420 result
= get_cert_sign_status ();
422 usage
|= GNUTLS_KEY_KEY_CERT_SIGN
;
424 result
= get_crl_sign_status ();
426 usage
|= GNUTLS_KEY_CRL_SIGN
;
428 result
= get_code_sign_status ();
432 gnutls_x509_crt_set_key_purpose_oid (crt
,
433 GNUTLS_KP_CODE_SIGNING
, 0);
435 error (EXIT_FAILURE
, 0, "key_kp: %s", gnutls_strerror (result
));
438 result
= get_ocsp_sign_status ();
442 gnutls_x509_crt_set_key_purpose_oid (crt
,
443 GNUTLS_KP_OCSP_SIGNING
, 0);
445 error (EXIT_FAILURE
, 0, "key_kp: %s", gnutls_strerror (result
));
448 result
= get_time_stamp_status ();
452 gnutls_x509_crt_set_key_purpose_oid (crt
,
453 GNUTLS_KP_TIME_STAMPING
, 0);
455 error (EXIT_FAILURE
, 0, "key_kp: %s", gnutls_strerror (result
));
461 result
= gnutls_x509_crt_set_key_usage (crt
, usage
);
463 error (EXIT_FAILURE
, 0, "key_usage: %s", gnutls_strerror (result
));
468 result
= gnutls_x509_crt_set_version (crt
, vers
);
470 error (EXIT_FAILURE
, 0, "set_version: %s", gnutls_strerror (result
));
474 size
= sizeof (buffer
);
475 result
= gnutls_x509_crt_get_key_id (crt
, 0, buffer
, &size
);
478 result
= gnutls_x509_crt_set_subject_key_id (crt
, buffer
, size
);
480 error (EXIT_FAILURE
, 0, "set_subject_key_id: %s",
481 gnutls_strerror (result
));
488 size
= sizeof (buffer
);
489 result
= gnutls_x509_crt_get_subject_key_id (ca_crt
, buffer
,
493 size
= sizeof (buffer
);
494 result
= gnutls_x509_crt_get_key_id (ca_crt
, 0, buffer
, &size
);
498 result
= gnutls_x509_crt_set_authority_key_id (crt
, buffer
, size
);
500 error (EXIT_FAILURE
, 0, "set_authority_key_id: %s",
501 gnutls_strerror (result
));
514 gnutls_x509_crt
*crts
;
517 time_t now
= time (NULL
);
519 result
= gnutls_x509_crl_init (&crl
);
521 error (EXIT_FAILURE
, 0, "crl_init: %s", gnutls_strerror (result
));
523 crts
= load_cert_list (0, &size
);
525 for (i
= 0; i
< size
; i
++)
527 result
= gnutls_x509_crl_set_crt (crl
, crts
[i
], now
);
529 error (EXIT_FAILURE
, 0, "crl_set_crt: %s", gnutls_strerror (result
));
532 result
= gnutls_x509_crl_set_this_update (crl
, now
);
534 error (EXIT_FAILURE
, 0, "this_update: %s", gnutls_strerror (result
));
536 fprintf (stderr
, "Update times.\n");
537 days
= get_crl_next_update ();
539 result
= gnutls_x509_crl_set_next_update (crl
, now
+ days
* 24 * 60 * 60);
541 error (EXIT_FAILURE
, 0, "next_update: %s", gnutls_strerror (result
));
543 result
= gnutls_x509_crl_set_version (crl
, 2);
545 error (EXIT_FAILURE
, 0, "set_version: %s", gnutls_strerror (result
));
551 generate_self_signed (void)
554 gnutls_x509_privkey key
;
559 fprintf (stderr
, "Generating a self signed certificate...\n");
561 crt
= generate_certificate (&key
, NULL
, 0);
564 key
= load_private_key (1);
566 uri
= get_crl_dist_point_url ();
569 result
= gnutls_x509_crt_set_crl_dist_points (crt
, GNUTLS_SAN_URI
,
571 0 /* all reasons */ );
573 error (EXIT_FAILURE
, 0, "crl_dist_points: %s",
574 gnutls_strerror (result
));
577 print_certificate_info (crt
, stderr
, 0);
579 fprintf (stderr
, "\n\nSigning certificate...\n");
581 result
= gnutls_x509_crt_sign2 (crt
, crt
, key
, dig
, 0);
583 error (EXIT_FAILURE
, 0, "crt_sign: %s", gnutls_strerror (result
));
585 size
= sizeof (buffer
);
586 result
= gnutls_x509_crt_export (crt
, info
.outcert_format
, buffer
, &size
);
588 error (EXIT_FAILURE
, 0, "crt_export: %s", gnutls_strerror (result
));
590 fwrite (buffer
, 1, size
, outfile
);
592 gnutls_x509_crt_deinit (crt
);
593 gnutls_x509_privkey_deinit (key
);
597 generate_signed_certificate (void)
600 gnutls_x509_privkey key
;
603 gnutls_x509_privkey ca_key
;
604 gnutls_x509_crt ca_crt
;
606 fprintf (stderr
, "Generating a signed certificate...\n");
608 ca_key
= load_ca_private_key ();
609 ca_crt
= load_ca_cert ();
611 crt
= generate_certificate (&key
, ca_crt
, 0);
613 /* Copy the CRL distribution points.
615 gnutls_x509_crt_cpy_crl_dist_points (crt
, ca_crt
);
616 /* it doesn't matter if we couldn't copy the CRL dist points.
619 print_certificate_info (crt
, stderr
, 0);
621 fprintf (stderr
, "\n\nSigning certificate...\n");
623 result
= gnutls_x509_crt_sign2 (crt
, ca_crt
, ca_key
, dig
, 0);
625 error (EXIT_FAILURE
, 0, "crt_sign: %s", gnutls_strerror (result
));
627 size
= sizeof (buffer
);
628 result
= gnutls_x509_crt_export (crt
, info
.outcert_format
, buffer
, &size
);
630 error (EXIT_FAILURE
, 0, "crt_export: %s", gnutls_strerror (result
));
632 fwrite (buffer
, 1, size
, outfile
);
634 gnutls_x509_crt_deinit (crt
);
635 gnutls_x509_privkey_deinit (key
);
639 generate_proxy_certificate (void)
641 gnutls_x509_crt crt
, eecrt
;
642 gnutls_x509_privkey key
, eekey
;
646 fprintf (stderr
, "Generating a proxy certificate...\n");
648 eekey
= load_ca_private_key ();
649 eecrt
= load_cert (1);
651 crt
= generate_certificate (&key
, eecrt
, 1);
653 print_certificate_info (crt
, stderr
, 0);
655 fprintf (stderr
, "\n\nSigning certificate...\n");
657 result
= gnutls_x509_crt_sign2 (crt
, eecrt
, eekey
, dig
, 0);
659 error (EXIT_FAILURE
, 0, "crt_sign: %s", gnutls_strerror (result
));
661 size
= sizeof (buffer
);
662 result
= gnutls_x509_crt_export (crt
, info
.outcert_format
, buffer
, &size
);
664 error (EXIT_FAILURE
, 0, "crt_export: %s", gnutls_strerror (result
));
666 fwrite (buffer
, 1, size
, outfile
);
668 gnutls_x509_crt_deinit (crt
);
669 gnutls_x509_privkey_deinit (key
);
673 generate_signed_crl (void)
677 gnutls_x509_privkey ca_key
;
678 gnutls_x509_crt ca_crt
;
680 fprintf (stderr
, "Generating a signed CRL...\n");
682 ca_key
= load_ca_private_key ();
683 ca_crt
= load_ca_cert ();
684 crl
= generate_crl ();
686 fprintf (stderr
, "\n");
688 result
= gnutls_x509_crl_sign (crl
, ca_crt
, ca_key
);
690 error (EXIT_FAILURE
, 0, "crl_sign: %s", gnutls_strerror (result
));
692 print_crl_info (crl
, stderr
);
694 gnutls_x509_crl_deinit (crl
);
698 update_signed_certificate (void)
703 gnutls_x509_privkey ca_key
;
704 gnutls_x509_crt ca_crt
;
706 time_t tim
= time (NULL
);
708 fprintf (stderr
, "Generating a signed certificate...\n");
710 ca_key
= load_ca_private_key ();
711 ca_crt
= load_ca_cert ();
714 fprintf (stderr
, "Activation/Expiration time.\n");
715 gnutls_x509_crt_set_activation_time (crt
, tim
);
719 result
= gnutls_x509_crt_set_expiration_time (crt
, tim
+ days
* 24 * 60 * 60);
721 error (EXIT_FAILURE
, 0, "set_expiration: %s", gnutls_strerror (result
));
723 fprintf (stderr
, "\n\nSigning certificate...\n");
725 result
= gnutls_x509_crt_sign2 (crt
, ca_crt
, ca_key
, dig
, 0);
727 error (EXIT_FAILURE
, 0, "crt_sign: %s", gnutls_strerror (result
));
729 size
= sizeof (buffer
);
730 result
= gnutls_x509_crt_export (crt
, info
.outcert_format
, buffer
, &size
);
732 error (EXIT_FAILURE
, 0, "crt_export: %s", gnutls_strerror (result
));
734 fwrite (buffer
, 1, size
, outfile
);
736 gnutls_x509_crt_deinit (crt
);
740 gaa_parser (int argc
, char **argv
)
744 if (gaa (argc
, argv
, &info
) != -1)
746 fprintf (stderr
, "Try `%s --help' for more information.\n",
753 outfile
= fopen (info
.outfile
, "wb");
755 error (EXIT_FAILURE
, errno
, "%s", info
.outfile
);
762 infile
= fopen (info
.infile
, "rb");
764 error (EXIT_FAILURE
, errno
, "%s", info
.infile
);
769 if (info
.incert_format
)
770 info
.incert_format
= GNUTLS_X509_FMT_DER
;
772 info
.incert_format
= GNUTLS_X509_FMT_PEM
;
774 if (info
.outcert_format
)
775 info
.outcert_format
= GNUTLS_X509_FMT_DER
;
777 info
.outcert_format
= GNUTLS_X509_FMT_PEM
;
779 if (info
.hash
!= NULL
)
781 if (strcasecmp (info
.hash
, "md5") == 0)
784 "Warning: MD5 is broken, and should not be used any more for digital signatures.\n");
785 dig
= GNUTLS_DIG_MD5
;
787 else if (strcasecmp (info
.hash
, "sha1") == 0)
788 dig
= GNUTLS_DIG_SHA1
;
789 else if (strcasecmp (info
.hash
, "sha256") == 0)
790 dig
= GNUTLS_DIG_SHA256
;
791 else if (strcasecmp (info
.hash
, "sha384") == 0)
792 dig
= GNUTLS_DIG_SHA384
;
793 else if (strcasecmp (info
.hash
, "sha512") == 0)
794 dig
= GNUTLS_DIG_SHA512
;
795 else if (strcasecmp (info
.hash
, "rmd160") == 0)
796 dig
= GNUTLS_DIG_RMD160
;
798 error (EXIT_FAILURE
, 0, "invalid hash: %s", info
.hash
);
805 template_parse (info
.template);
808 gnutls_global_set_log_function (tls_log_func
);
809 gnutls_global_set_log_level (info
.debug
);
811 if ((ret
= gnutls_global_init ()) < 0)
812 error (EXIT_FAILURE
, 0, "global_init: %s", gnutls_strerror (ret
));
817 generate_self_signed ();
820 generate_private_key ();
829 generate_signed_certificate ();
838 update_signed_certificate ();
847 generate_prime (info
.bits
, 1);
850 generate_prime (info
.bits
, 0);
859 generate_signed_crl ();
868 generate_proxy_certificate ();
879 certificate_info (void)
881 gnutls_x509_crt crt
[MAX_CRTS
];
885 unsigned int crt_num
;
887 pem
.data
= fread_file (infile
, &size
);
891 ret
= gnutls_x509_crt_list_import (crt
, &crt_num
, &pem
, info
.incert_format
,
892 GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED
);
893 if (ret
== GNUTLS_E_SHORT_MEMORY_BUFFER
)
895 error (0, 0, "Too many certificates (%d), will only read the first %d.",
898 ret
= gnutls_x509_crt_list_import (crt
, &crt_num
, &pem
,
899 info
.incert_format
, 0);
902 error (EXIT_FAILURE
, 0, "Import error: %s", gnutls_strerror (ret
));
908 if (count
> 1 && info
.outcert_format
== GNUTLS_X509_FMT_DER
)
910 error(0, 0, "Cannot output multiple certificates in DER format, using PEM instead.");
911 info
.outcert_format
= GNUTLS_X509_FMT_PEM
;
914 for (i
= 0; i
< count
; i
++)
917 fprintf (outfile
, "\n");
919 if (info
.outcert_format
== GNUTLS_X509_FMT_PEM
)
920 print_certificate_info (crt
[i
], outfile
, 1);
924 size
= sizeof (buffer
);
925 ret
= gnutls_x509_crt_export (crt
[i
], info
.outcert_format
, buffer
,
928 error (EXIT_FAILURE
, 0, "Export error: %s",
929 gnutls_strerror (ret
));
930 fprintf (outfile
, "%s", buffer
);
936 ret
= gnutls_x509_crt_to_xml (crt
[i
], &xml
, GNUTLS_XML_SHOW_ALL
);
938 error (EXIT_FAILURE
, 0, "XML encoding error: %s",
939 gnutls_strerror (ret
));
941 fprintf (outfile
, "\n%s\n", xml
.data
);
942 gnutls_free (xml
.data
);
948 print_hex_datum (gnutls_datum
* dat
)
952 fprintf (outfile
, "\n" SPACE
);
953 for (j
= 0; j
< dat
->size
; j
++)
955 fprintf (outfile
, "%.2x:", (unsigned char) dat
->data
[j
]);
956 if ((j
+ 1) % 15 == 0)
957 fprintf (outfile
, "\n" SPACE
);
959 fprintf (outfile
, "\n");
964 print_certificate_info (gnutls_x509_crt crt
, FILE *out
, unsigned int all
)
970 ret
= gnutls_x509_crt_print (crt
, GNUTLS_X509_CRT_FULL
, &info
);
972 ret
= gnutls_x509_crt_print (crt
, GNUTLS_X509_CRT_UNSIGNED_FULL
, &info
);
975 fprintf (out
, "%s\n", info
.data
);
976 gnutls_free (info
.data
);
979 if (out
== stderr
&& batch
== 0) /* interactive */
980 if (read_yesno ("Is the above information ok? (Y/N): ") == 0)
987 print_crl_info (gnutls_x509_crl crl
, FILE *out
)
993 ret
= gnutls_x509_crl_print (crl
, GNUTLS_X509_CRT_FULL
, &info
);
995 error (EXIT_FAILURE
, 0, "crl_print: %s", gnutls_strerror (ret
));
997 fprintf (out
, "%s\n", info
.data
);
999 gnutls_free (info
.data
);
1001 size
= sizeof (buffer
);
1002 ret
= gnutls_x509_crl_export (crl
, GNUTLS_X509_FMT_PEM
, buffer
, &size
);
1004 error (EXIT_FAILURE
, 0, "crl_export: %s", gnutls_strerror (ret
));
1006 fprintf (outfile
, "%s", buffer
);
1012 gnutls_x509_crl crl
;
1017 ret
= gnutls_x509_crl_init (&crl
);
1019 error (EXIT_FAILURE
, 0, "crl_init: %s", gnutls_strerror (ret
));
1021 pem
.data
= fread_file (infile
, &size
);
1025 error (EXIT_FAILURE
, errno
, "%s", info
.infile
? info
.infile
:
1028 ret
= gnutls_x509_crl_import (crl
, &pem
, info
.incert_format
);
1031 error (EXIT_FAILURE
, 0, "Import error: %s", gnutls_strerror (ret
));
1033 print_crl_info (crl
, outfile
);
1039 gnutls_x509_privkey key
;
1046 size
= fread (buffer
, 1, sizeof (buffer
) - 1, infile
);
1049 gnutls_x509_privkey_init (&key
);
1057 ret
= gnutls_x509_privkey_import (key
, &pem
, info
.incert_format
);
1065 ret
= gnutls_x509_privkey_import_pkcs8 (key
, &pem
, info
.incert_format
,
1069 error (EXIT_FAILURE
, 0, "Import error: %s", gnutls_strerror (ret
));
1071 /* Public key algorithm
1073 fprintf (outfile
, "Public Key Info:\n");
1074 ret
= gnutls_x509_privkey_get_pk_algorithm (key
);
1075 fprintf (outfile
, "\tPublic Key Algorithm: ");
1077 cprint
= gnutls_pk_algorithm_get_name (ret
);
1080 fprintf (outfile
, "%s\n", cprint
);
1082 /* Print the raw public and private keys
1084 if (ret
== GNUTLS_PK_RSA
)
1086 gnutls_datum m
, e
, d
, p
, q
, u
;
1088 ret
= gnutls_x509_privkey_export_rsa_raw (key
, &m
, &e
, &d
, &p
, &q
, &u
);
1091 fprintf (stderr
, "Error in key RSA data export: %s\n",
1092 gnutls_strerror (ret
));
1095 fprintf (outfile
, "modulus:");
1096 print_hex_datum (&m
);
1097 fprintf (outfile
, "public exponent:");
1098 print_hex_datum (&e
);
1099 fprintf (outfile
, "private exponent:");
1100 print_hex_datum (&d
);
1101 fprintf (outfile
, "prime1:");
1102 print_hex_datum (&p
);
1103 fprintf (outfile
, "prime2:");
1104 print_hex_datum (&q
);
1105 fprintf (outfile
, "coefficient:");
1106 print_hex_datum (&u
);
1109 else if (ret
== GNUTLS_PK_DSA
)
1111 gnutls_datum p
, q
, g
, y
, x
;
1113 ret
= gnutls_x509_privkey_export_dsa_raw (key
, &p
, &q
, &g
, &y
, &x
);
1116 fprintf (stderr
, "Error in key DSA data export: %s\n",
1117 gnutls_strerror (ret
));
1120 fprintf (outfile
, "private key:");
1121 print_hex_datum (&x
);
1122 fprintf (outfile
, "public key:");
1123 print_hex_datum (&y
);
1124 fprintf (outfile
, "p:");
1125 print_hex_datum (&p
);
1126 fprintf (outfile
, "q:");
1127 print_hex_datum (&q
);
1128 fprintf (outfile
, "g:");
1129 print_hex_datum (&g
);
1132 fprintf (outfile
, "\n");
1134 size
= sizeof (buffer
);
1135 if ((ret
= gnutls_x509_privkey_get_key_id (key
, 0, buffer
, &size
)) < 0)
1137 fprintf (stderr
, "Error in key id calculation: %s\n",
1138 gnutls_strerror (ret
));
1142 fprintf (outfile
, "Public Key ID: %s\n", raw_to_string (buffer
, size
));
1145 if (info
.fix_key
!= 0)
1147 ret
= gnutls_x509_privkey_fix (key
);
1149 error (EXIT_FAILURE
, 0, "privkey_fix: %s", gnutls_strerror (ret
));
1152 size
= sizeof (buffer
);
1153 ret
= gnutls_x509_privkey_export (key
, GNUTLS_X509_FMT_PEM
, buffer
, &size
);
1155 error (EXIT_FAILURE
, 0, "Export error: %s", gnutls_strerror (ret
));
1157 fprintf (outfile
, "\n%s\n", buffer
);
1160 /* Load the private key.
1161 * @mand should be non zero if it is required to read a private key.
1164 load_private_key (int mand
)
1166 gnutls_x509_privkey key
;
1171 if (!info
.privkey
&& !mand
)
1174 if (info
.privkey
== NULL
)
1175 error (EXIT_FAILURE
, 0, "missing --load-privkey");
1177 ret
= gnutls_x509_privkey_init (&key
);
1179 error (EXIT_FAILURE
, 0, "privkey_init: %s", gnutls_strerror (ret
));
1181 dat
.data
= read_binary_file (info
.privkey
, &size
);
1185 error (EXIT_FAILURE
, errno
, "reading --load-privkey: %s",
1190 const char *pass
= get_pass ();
1191 ret
= gnutls_x509_privkey_import_pkcs8 (key
, &dat
, info
.incert_format
,
1195 ret
= gnutls_x509_privkey_import (key
, &dat
, info
.incert_format
);
1198 error (EXIT_FAILURE
, 0, "importing --load-privkey: %s: %s",
1199 info
.privkey
, gnutls_strerror (ret
));
1204 /* Load the Certificate Request.
1209 gnutls_x509_crq crq
;
1217 ret
= gnutls_x509_crq_init (&crq
);
1219 error (EXIT_FAILURE
, 0, "crq_init: %s", gnutls_strerror (ret
));
1221 dat
.data
= read_binary_file (info
.request
, &size
);
1225 error (EXIT_FAILURE
, errno
, "reading --load-request: %s",
1228 ret
= gnutls_x509_crq_import (crq
, &dat
, info
.incert_format
);
1231 error (EXIT_FAILURE
, 0, "importing --load-request: %s: %s",
1232 info
.request
, gnutls_strerror (ret
));
1237 /* Load the CA's private key.
1240 load_ca_private_key (void)
1242 gnutls_x509_privkey key
;
1247 if (info
.ca_privkey
== NULL
)
1248 error (EXIT_FAILURE
, 0, "missing --load-ca-privkey");
1250 ret
= gnutls_x509_privkey_init (&key
);
1252 error (EXIT_FAILURE
, 0, "privkey_init: %s", gnutls_strerror (ret
));
1254 dat
.data
= read_binary_file (info
.ca_privkey
, &size
);
1258 error (EXIT_FAILURE
, errno
, "reading --load-ca-privkey: %s",
1263 const char *pass
= get_pass ();
1264 ret
= gnutls_x509_privkey_import_pkcs8 (key
, &dat
, info
.incert_format
,
1268 ret
= gnutls_x509_privkey_import (key
, &dat
, info
.incert_format
);
1271 error (EXIT_FAILURE
, 0, "importing --load-ca-privkey: %s: %s",
1272 info
.ca_privkey
, gnutls_strerror (ret
));
1277 /* Loads the CA's certificate
1282 gnutls_x509_crt crt
;
1287 if (info
.ca
== NULL
)
1288 error (EXIT_FAILURE
, 0, "missing --load-ca-certificate");
1290 ret
= gnutls_x509_crt_init (&crt
);
1292 error (EXIT_FAILURE
, 0, "crt_init: %s", gnutls_strerror (ret
));
1294 dat
.data
= read_binary_file (info
.ca
, &size
);
1298 error (EXIT_FAILURE
, errno
, "reading --load-ca-certificate: %s",
1301 ret
= gnutls_x509_crt_import (crt
, &dat
, info
.incert_format
);
1304 error (EXIT_FAILURE
, 0, "importing --load-ca-certificate: %s: %s",
1305 info
.ca
, gnutls_strerror (ret
));
1310 /* Loads the certificate
1311 * If mand is non zero then a certificate is mandatory. Otherwise
1312 * null will be returned if the certificate loading fails.
1315 load_cert (int mand
)
1317 gnutls_x509_crt
*crt
;
1320 crt
= load_cert_list (mand
, &size
);
1322 return crt
? crt
[0] : NULL
;
1325 #define MAX_CERTS 256
1327 /* Loads a certificate list
1330 load_cert_list (int mand
, int *crt_size
)
1333 static gnutls_x509_crt crt
[MAX_CERTS
];
1341 fprintf (stderr
, "Loading certificate list...\n");
1343 if (info
.cert
== NULL
)
1346 error (EXIT_FAILURE
, 0, "missing --load-certificate");
1351 fd
= fopen (info
.cert
, "r");
1353 error (EXIT_FAILURE
, 0, "File %s does not exist", info
.cert
);
1355 size
= fread (buffer
, 1, sizeof (buffer
) - 1, fd
);
1363 for (i
= 0; i
< MAX_CERTS
; i
++)
1365 ret
= gnutls_x509_crt_init (&crt
[i
]);
1367 error (EXIT_FAILURE
, 0, "crt_init: %s", gnutls_strerror (ret
));
1370 dat
.size
= ptr_size
;
1372 ret
= gnutls_x509_crt_import (crt
[i
], &dat
, info
.incert_format
);
1373 if (ret
< 0 && *crt_size
> 0)
1376 error (EXIT_FAILURE
, 0, "crt_import: %s", gnutls_strerror (ret
));
1378 ptr
= strstr (ptr
, "---END");
1385 (unsigned int) ((unsigned char *) ptr
- (unsigned char *) buffer
);
1392 fprintf (stderr
, "Loaded %d certificates.\n", *crt_size
);
1398 /* Generate a PKCS #10 certificate request.
1401 generate_request (void)
1403 gnutls_x509_crq crq
;
1404 gnutls_x509_privkey key
;
1409 fprintf (stderr
, "Generating a PKCS #10 certificate request...\n");
1411 ret
= gnutls_x509_crq_init (&crq
);
1413 error (EXIT_FAILURE
, 0, "crq_init: %s", gnutls_strerror (ret
));
1415 /* Load the private key.
1417 key
= load_private_key (0);
1419 key
= generate_private_key_int ();
1423 get_country_crq_set (crq
);
1424 get_organization_crq_set (crq
);
1425 get_unit_crq_set (crq
);
1426 get_locality_crq_set (crq
);
1427 get_state_crq_set (crq
);
1428 get_cn_crq_set (crq
);
1429 get_uid_crq_set (crq
);
1430 get_oid_crq_set (crq
);
1432 ret
= gnutls_x509_crq_set_version (crq
, 1);
1434 error (EXIT_FAILURE
, 0, "set_version: %s", gnutls_strerror (ret
));
1436 pass
= get_challenge_pass ();
1440 ret
= gnutls_x509_crq_set_challenge_password (crq
, pass
);
1442 error (EXIT_FAILURE
, 0, "set_pass: %s", gnutls_strerror (ret
));
1445 ret
= gnutls_x509_crq_set_key (crq
, key
);
1447 error (EXIT_FAILURE
, 0, "set_key: %s", gnutls_strerror (ret
));
1449 ret
= gnutls_x509_crq_sign (crq
, key
);
1451 error (EXIT_FAILURE
, 0, "sign: %s", gnutls_strerror (ret
));
1453 size
= sizeof (buffer
);
1454 ret
= gnutls_x509_crq_export (crq
, info
.outcert_format
, buffer
, &size
);
1456 error (EXIT_FAILURE
, 0, "export: %s", gnutls_strerror (ret
));
1458 fwrite (buffer
, 1, size
, outfile
);
1460 gnutls_x509_crq_deinit (crq
);
1461 gnutls_x509_privkey_deinit (key
);
1465 static void print_verification_res (gnutls_x509_crt crt
,
1466 gnutls_x509_crt issuer
,
1467 gnutls_x509_crl
* crl_list
,
1470 #define CERT_SEP "-----BEGIN CERT"
1471 #define CRL_SEP "-----BEGIN X509 CRL"
1473 _verify_x509_mem (const void *cert
, int cert_size
)
1479 char issuer_name
[256];
1481 size_t issuer_name_size
;
1483 gnutls_x509_crt
*x509_cert_list
= NULL
;
1484 gnutls_x509_crl
*x509_crl_list
= NULL
;
1485 int x509_ncerts
, x509_ncrls
;
1488 /* Decode the CA certificate
1491 /* Decode the CRL list
1498 if (strstr (ptr
, CRL_SEP
) != NULL
) /* if CRLs exist */
1502 (gnutls_x509_crl
*) realloc (x509_crl_list
,
1503 i
* sizeof (gnutls_x509_crl
));
1504 if (x509_crl_list
== NULL
)
1505 error (EXIT_FAILURE
, 0, "memory error");
1507 tmp
.data
= (char *) ptr
;
1510 ret
= gnutls_x509_crl_init (&x509_crl_list
[i
- 1]);
1512 error (EXIT_FAILURE
, 0, "Error parsing the CRL[%d]: %s", i
,
1513 gnutls_strerror (ret
));
1515 ret
= gnutls_x509_crl_import (x509_crl_list
[i
- 1], &tmp
,
1516 GNUTLS_X509_FMT_PEM
);
1518 error (EXIT_FAILURE
, 0, "Error parsing the CRL[%d]: %s", i
,
1519 gnutls_strerror (ret
));
1521 /* now we move ptr after the pem header */
1522 ptr
= strstr (ptr
, CRL_SEP
);
1528 while ((ptr
= strstr (ptr
, CRL_SEP
)) != NULL
);
1533 /* Decode the certificate chain.
1543 (gnutls_x509_crt
*) realloc (x509_cert_list
,
1544 i
* sizeof (gnutls_x509_crt
));
1545 if (x509_cert_list
== NULL
)
1546 error (EXIT_FAILURE
, 0, "memory error");
1548 tmp
.data
= (char *) ptr
;
1551 ret
= gnutls_x509_crt_init (&x509_cert_list
[i
- 1]);
1553 error (EXIT_FAILURE
, 0, "Error parsing the certificate[%d]: %s", i
,
1554 gnutls_strerror (ret
));
1557 gnutls_x509_crt_import (x509_cert_list
[i
- 1], &tmp
,
1558 GNUTLS_X509_FMT_PEM
);
1560 error (EXIT_FAILURE
, 0, "Error parsing the certificate[%d]: %s", i
,
1561 gnutls_strerror (ret
));
1566 /* verify the previous certificate using this one
1570 name_size
= sizeof (name
);
1572 gnutls_x509_crt_get_dn (x509_cert_list
[i
- 2], name
, &name_size
);
1574 error (EXIT_FAILURE
, 0, "get_dn: %s", gnutls_strerror (ret
));
1576 fprintf (outfile
, "Certificate[%d]: %s\n", i
- 2, name
);
1580 issuer_name_size
= sizeof (issuer_name
);
1582 gnutls_x509_crt_get_issuer_dn (x509_cert_list
[i
- 2],
1583 issuer_name
, &issuer_name_size
);
1585 error (EXIT_FAILURE
, 0, "get_issuer_dn: %s", gnutls_strerror (ret
));
1587 fprintf (outfile
, "\tIssued by: %s\n", issuer_name
);
1589 /* Get the Issuer's name
1591 name_size
= sizeof (name
);
1593 gnutls_x509_crt_get_dn (x509_cert_list
[i
- 1], name
, &name_size
);
1595 error (EXIT_FAILURE
, 0, "get_dn: %s", gnutls_strerror (ret
));
1597 fprintf (outfile
, "\tVerifying against certificate[%d].\n", i
- 1);
1599 if (strcmp (issuer_name
, name
) != 0)
1601 fprintf (stderr
, "Error: Issuer's name: %s\n", name
);
1602 error (EXIT_FAILURE
, 0,
1603 "Issuer's name does not match the next certificate");
1606 fprintf (outfile
, "\tVerification output: ");
1607 print_verification_res (x509_cert_list
[i
- 2],
1608 x509_cert_list
[i
- 1], x509_crl_list
,
1610 fprintf (outfile
, ".\n\n");
1615 /* now we move ptr after the pem header
1617 ptr
= strstr (ptr
, CERT_SEP
);
1623 while ((ptr
= strstr (ptr
, CERT_SEP
)) != NULL
);
1625 x509_ncerts
= i
- 1;
1627 /* The last certificate in the list will be used as
1628 * a CA (should be self signed).
1630 name_size
= sizeof (name
);
1631 ret
= gnutls_x509_crt_get_dn (x509_cert_list
[x509_ncerts
- 1], name
,
1634 error (EXIT_FAILURE
, 0, "get_dn: %s", gnutls_strerror (ret
));
1636 fprintf (outfile
, "Certificate[%d]: %s\n", x509_ncerts
- 1, name
);
1640 issuer_name_size
= sizeof (issuer_name
);
1642 gnutls_x509_crt_get_issuer_dn (x509_cert_list
[x509_ncerts
- 1],
1643 issuer_name
, &issuer_name_size
);
1645 error (EXIT_FAILURE
, 0, "get_issuer_dn: %s", gnutls_strerror (ret
));
1647 fprintf (outfile
, "\tIssued by: %s\n", name
);
1649 if (strcmp (issuer_name
, name
) != 0)
1650 error (EXIT_FAILURE
, 0, "Error: The last certificate is not self signed.");
1652 fprintf (outfile
, "\tVerification output: ");
1653 print_verification_res (x509_cert_list
[x509_ncerts
- 1],
1654 x509_cert_list
[x509_ncerts
- 1], x509_crl_list
,
1657 fprintf (outfile
, ".\n\n");
1659 for (i
= 0; i
< x509_ncerts
; i
++)
1660 gnutls_x509_crt_deinit (x509_cert_list
[i
]);
1662 for (i
= 0; i
< x509_ncrls
; i
++)
1663 gnutls_x509_crl_deinit (x509_crl_list
[i
]);
1665 free (x509_cert_list
);
1666 free (x509_crl_list
);
1669 error (EXIT_FAILURE
, 0, "Error in verification: %s", gnutls_strerror (ret
));
1675 print_verification_res (gnutls_x509_crt crt
,
1676 gnutls_x509_crt issuer
,
1677 gnutls_x509_crl
* crl_list
, int crl_list_size
)
1679 unsigned int output
;
1682 time_t now
= time (0);
1684 ret
= gnutls_x509_crt_verify (crt
, &issuer
, 1, 0, &output
);
1686 error (EXIT_FAILURE
, 0, "Error in verification: %s",
1687 gnutls_strerror (ret
));
1689 if (output
& GNUTLS_CERT_INVALID
)
1691 fprintf (outfile
, "Not verified");
1696 fprintf (outfile
, "Verified");
1700 if (output
& GNUTLS_CERT_SIGNER_NOT_CA
)
1703 fprintf (outfile
, ", ");
1704 fprintf (outfile
, "Issuer is not a CA");
1708 if (output
& GNUTLS_CERT_INSECURE_ALGORITHM
)
1711 fprintf (outfile
, ", ");
1712 fprintf (outfile
, "Insecure algorithm");
1716 /* Check expiration dates.
1719 if (gnutls_x509_crt_get_activation_time (crt
) > now
)
1722 fprintf (outfile
, ", ");
1724 fprintf (outfile
, "Not activated");
1727 if (gnutls_x509_crt_get_expiration_time (crt
) < now
)
1730 fprintf (outfile
, ", ");
1732 fprintf (outfile
, "Expired");
1735 ret
= gnutls_x509_crt_check_revocation (crt
, crl_list
, crl_list_size
);
1737 error (EXIT_FAILURE
, 0, "Revocation check: %s", gnutls_strerror (ret
));
1742 fprintf (outfile
, ", ");
1744 fprintf (outfile
, "Revoked");
1753 size
= fread (buffer
, 1, sizeof (buffer
) - 1, infile
);
1756 _verify_x509_mem (buffer
, size
);
1763 size_t size
, dn_size
;
1765 unsigned int output
;
1769 gnutls_x509_crl crl
;
1770 time_t now
= time (0);
1771 gnutls_x509_crt issuer
;
1773 issuer
= load_ca_cert ();
1775 fprintf (outfile
, "\nCA certificate:\n");
1777 dn_size
= sizeof (dn
);
1778 ret
= gnutls_x509_crt_get_dn (issuer
, dn
, &dn_size
);
1780 error (EXIT_FAILURE
, 0, "crt_get_dn: %s", gnutls_strerror (ret
));
1782 fprintf (outfile
, "\tSubject: %s\n\n", dn
);
1784 ret
= gnutls_x509_crl_init (&crl
);
1786 error (EXIT_FAILURE
, 0, "crl_init: %s", gnutls_strerror (ret
));
1788 pem
.data
= fread_file (infile
, &size
);
1791 ret
= gnutls_x509_crl_import (crl
, &pem
, info
.incert_format
);
1794 error (EXIT_FAILURE
, 0, "Import error: %s", gnutls_strerror (ret
));
1796 print_crl_info (crl
, outfile
);
1798 fprintf (outfile
, "Verification output: ");
1799 ret
= gnutls_x509_crl_verify (crl
, &issuer
, 1, 0, &output
);
1801 error (EXIT_FAILURE
, 0, "Verification error: %s", gnutls_strerror (ret
));
1803 if (output
& GNUTLS_CERT_INVALID
)
1805 fprintf (outfile
, "Not verified");
1810 fprintf (outfile
, "Verified");
1814 if (output
& GNUTLS_CERT_SIGNER_NOT_CA
)
1817 fprintf (outfile
, ", ");
1818 fprintf (outfile
, "Issuer is not a CA");
1822 if (output
& GNUTLS_CERT_INSECURE_ALGORITHM
)
1825 fprintf (outfile
, ", ");
1826 fprintf (outfile
, "Insecure algorithm");
1830 /* Check expiration dates.
1833 if (gnutls_x509_crl_get_this_update (crl
) > now
)
1836 fprintf (outfile
, ", ");
1838 fprintf (outfile
, "Issued in the future!");
1841 if (gnutls_x509_crl_get_next_update (crl
) < now
)
1844 fprintf (outfile
, ", ");
1846 fprintf (outfile
, "CRL is not up to date");
1849 fprintf (outfile
, "\n");
1852 #include <gnutls/pkcs12.h>
1856 generate_pkcs12 (void)
1858 gnutls_pkcs12 pkcs12
;
1859 gnutls_x509_crt
*crts
;
1860 gnutls_x509_privkey key
;
1864 const char *password
;
1867 gnutls_datum key_id
;
1868 unsigned char _key_id
[20];
1873 fprintf (stderr
, "Generating a PKCS #12 structure...\n");
1875 key
= load_private_key (0);
1876 crts
= load_cert_list (0, &ncrts
);
1878 name
= get_pkcs12_key_name ();
1880 result
= gnutls_pkcs12_init (&pkcs12
);
1882 error (EXIT_FAILURE
, 0, "pkcs12_init: %s", gnutls_strerror (result
));
1885 password
= info
.pass
;
1887 password
= get_pass ();
1889 for (i
= 0; i
< ncrts
; i
++)
1891 gnutls_pkcs12_bag bag
;
1893 result
= gnutls_pkcs12_bag_init (&bag
);
1895 error (EXIT_FAILURE
, 0, "bag_init: %s", gnutls_strerror (result
));
1897 result
= gnutls_pkcs12_bag_set_crt (bag
, crts
[i
]);
1899 error (EXIT_FAILURE
, 0, "set_crt[%d]: %s", i
, gnutls_strerror (result
));
1903 result
= gnutls_pkcs12_bag_set_friendly_name (bag
, index
, name
);
1905 error (EXIT_FAILURE
, 0, "bag_set_friendly_name: %s",
1906 gnutls_strerror (result
));
1908 size
= sizeof (_key_id
);
1909 result
= gnutls_x509_crt_get_key_id (crts
[i
], 0, _key_id
, &size
);
1911 error (EXIT_FAILURE
, 0, "key_id[%d]: %s", i
, gnutls_strerror (result
));
1913 key_id
.data
= _key_id
;
1916 result
= gnutls_pkcs12_bag_set_key_id (bag
, index
, &key_id
);
1918 error (EXIT_FAILURE
, 0, "bag_set_key_id: %s", gnutls_strerror (result
));
1921 flags
= GNUTLS_PKCS_USE_PKCS12_RC2_40
;
1923 flags
= GNUTLS_PKCS8_USE_PKCS12_3DES
;
1925 result
= gnutls_pkcs12_bag_encrypt (bag
, password
, flags
);
1927 error (EXIT_FAILURE
, 0, "bag_encrypt: %s", gnutls_strerror (result
));
1929 result
= gnutls_pkcs12_set_bag (pkcs12
, bag
);
1931 error (EXIT_FAILURE
, 0, "set_bag: %s", gnutls_strerror (result
));
1936 gnutls_pkcs12_bag kbag
;
1938 result
= gnutls_pkcs12_bag_init (&kbag
);
1940 error (EXIT_FAILURE
, 0, "bag_init: %s", gnutls_strerror (result
));
1943 flags
= GNUTLS_PKCS_USE_PKCS12_RC2_40
;
1945 flags
= GNUTLS_PKCS_USE_PKCS12_3DES
;
1947 size
= sizeof (buffer
);
1949 gnutls_x509_privkey_export_pkcs8 (key
, GNUTLS_X509_FMT_DER
,
1950 password
, flags
, buffer
, &size
);
1952 error (EXIT_FAILURE
, 0, "key_export: %s", gnutls_strerror (result
));
1957 gnutls_pkcs12_bag_set_data (kbag
,
1958 GNUTLS_BAG_PKCS8_ENCRYPTED_KEY
, &data
);
1960 error (EXIT_FAILURE
, 0, "bag_set_data: %s", gnutls_strerror (result
));
1964 result
= gnutls_pkcs12_bag_set_friendly_name (kbag
, index
, name
);
1966 error (EXIT_FAILURE
, 0, "bag_set_friendly_name: %s",
1967 gnutls_strerror (result
));
1969 size
= sizeof (_key_id
);
1970 result
= gnutls_x509_privkey_get_key_id (key
, 0, _key_id
, &size
);
1972 error (EXIT_FAILURE
, 0, "key_id: %s", gnutls_strerror (result
));
1974 key_id
.data
= _key_id
;
1977 result
= gnutls_pkcs12_bag_set_key_id (kbag
, index
, &key_id
);
1979 error (EXIT_FAILURE
, 0, "bag_set_key_id: %s", gnutls_strerror (result
));
1981 result
= gnutls_pkcs12_set_bag (pkcs12
, kbag
);
1983 error (EXIT_FAILURE
, 0, "set_bag: %s", gnutls_strerror (result
));
1986 result
= gnutls_pkcs12_generate_mac (pkcs12
, password
);
1988 error (EXIT_FAILURE
, 0, "generate_mac: %s", gnutls_strerror (result
));
1990 size
= sizeof (buffer
);
1991 result
= gnutls_pkcs12_export (pkcs12
, info
.outcert_format
, buffer
, &size
);
1993 error (EXIT_FAILURE
, 0, "pkcs12_export: %s", gnutls_strerror (result
));
1995 fwrite (buffer
, 1, size
, outfile
);
2000 BAGTYPE (gnutls_pkcs12_bag_type x
)
2004 case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY
:
2005 return "PKCS #8 Encrypted key";
2006 case GNUTLS_BAG_EMPTY
:
2008 case GNUTLS_BAG_PKCS8_KEY
:
2009 return "PKCS #8 Key";
2010 case GNUTLS_BAG_CERTIFICATE
:
2011 return "Certificate";
2012 case GNUTLS_BAG_ENCRYPTED
:
2014 case GNUTLS_BAG_CRL
:
2022 print_bag_data (gnutls_pkcs12_bag bag
)
2026 gnutls_datum cdata
, id
;
2027 const char *str
, *name
;
2030 count
= gnutls_pkcs12_bag_get_count (bag
);
2032 error (EXIT_FAILURE
, 0, "get_count: %s", gnutls_strerror (count
));
2034 fprintf (outfile
, "\tElements: %d\n", count
);
2036 for (i
= 0; i
< count
; i
++)
2038 type
= gnutls_pkcs12_bag_get_type (bag
, i
);
2040 error (EXIT_FAILURE
, 0, "get_type: %s", gnutls_strerror (type
));
2042 fprintf (stderr
, "\tType: %s\n", BAGTYPE (type
));
2045 result
= gnutls_pkcs12_bag_get_friendly_name (bag
, i
, (char **) &name
);
2047 error (EXIT_FAILURE
, 0, "get_friendly_name: %s",
2048 gnutls_strerror (type
));
2050 fprintf (outfile
, "\tFriendly name: %s\n", name
);
2054 result
= gnutls_pkcs12_bag_get_key_id (bag
, i
, &id
);
2056 error (EXIT_FAILURE
, 0, "get_key_id: %s", gnutls_strerror (type
));
2057 fprintf (outfile
, "\tKey ID: %s\n", raw_to_string (id
.data
, id
.size
));
2059 result
= gnutls_pkcs12_bag_get_data (bag
, i
, &cdata
);
2061 error (EXIT_FAILURE
, 0, "get_data: %s", gnutls_strerror (result
));
2065 case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY
:
2066 str
= "ENCRYPTED PRIVATE KEY";
2068 case GNUTLS_BAG_PKCS8_KEY
:
2069 str
= "PRIVATE KEY";
2071 case GNUTLS_BAG_CERTIFICATE
:
2072 str
= "CERTIFICATE";
2074 case GNUTLS_BAG_CRL
:
2077 case GNUTLS_BAG_ENCRYPTED
:
2078 case GNUTLS_BAG_EMPTY
:
2085 gnutls_pem_base64_encode_alloc (str
, &cdata
, &out
);
2086 fprintf (outfile
, "%s\n", out
.data
);
2088 gnutls_free (out
.data
);
2097 gnutls_pkcs12 pkcs12
;
2098 gnutls_pkcs12_bag bag
;
2102 const char *password
;
2105 result
= gnutls_pkcs12_init (&pkcs12
);
2107 error (EXIT_FAILURE
, 0, "p12_init: %s", gnutls_strerror (result
));
2109 data
.data
= fread_file (infile
, &size
);
2112 result
= gnutls_pkcs12_import (pkcs12
, &data
, info
.incert_format
, 0);
2115 error (EXIT_FAILURE
, 0, "p12_import: %s", gnutls_strerror (result
));
2118 password
= info
.pass
;
2120 password
= get_pass ();
2122 result
= gnutls_pkcs12_verify_mac (pkcs12
, password
);
2124 error (EXIT_FAILURE
, 0, "verify_mac: %s", gnutls_strerror (result
));
2128 for (index
= 0; ; index
++)
2130 result
= gnutls_pkcs12_bag_init (&bag
);
2132 error (EXIT_FAILURE
, 0, "bag_init: %s", gnutls_strerror (result
));
2134 result
= gnutls_pkcs12_get_bag (pkcs12
, index
, bag
);
2138 result
= gnutls_pkcs12_bag_get_count (bag
);
2140 error (EXIT_FAILURE
, 0, "bag_count: %s", gnutls_strerror (result
));
2142 fprintf (outfile
, "BAG #%d\n", index
);
2144 result
= gnutls_pkcs12_bag_get_type (bag
, 0);
2146 error (EXIT_FAILURE
, 0, "bag_init: %s", gnutls_strerror (result
));
2148 if (result
== GNUTLS_BAG_ENCRYPTED
)
2150 fprintf (stderr
, "\tType: %s\n", BAGTYPE (result
));
2151 fprintf (stderr
, "\n\tDecrypting...\n");
2153 result
= gnutls_pkcs12_bag_decrypt (bag
, password
);
2156 error (EXIT_FAILURE
, 0, "bag_decrypt: %s",
2157 gnutls_strerror (result
));
2159 result
= gnutls_pkcs12_bag_get_count (bag
);
2161 error (EXIT_FAILURE
, 0, "encrypted bag_count: %s",
2162 gnutls_strerror (result
));
2165 print_bag_data (bag
);
2167 gnutls_pkcs12_bag_deinit (bag
);
2177 gnutls_datum data
, b64
;
2180 result
= gnutls_pkcs7_init (&pkcs7
);
2182 error (EXIT_FAILURE
, 0, "p7_init: %s", gnutls_strerror (result
));
2184 data
.data
= fread_file (infile
, &size
);
2187 result
= gnutls_pkcs7_import (pkcs7
, &data
, info
.incert_format
);
2190 error (EXIT_FAILURE
, 0, "Import error: %s", gnutls_strerror (result
));
2192 /* Read and print the certificates.
2194 result
= gnutls_pkcs7_get_crt_count (pkcs7
);
2196 error (EXIT_FAILURE
, 0, "p7_crt_count: %s", gnutls_strerror (result
));
2201 fprintf (outfile
, "Number of certificates: %u\n", count
);
2203 for (index
= 0; index
< count
; index
++)
2205 fputs ("\n", outfile
);
2207 size
= sizeof (buffer
);
2208 result
= gnutls_pkcs7_get_crt_raw (pkcs7
, index
, buffer
, &size
);
2215 result
= gnutls_pem_base64_encode_alloc ("CERTIFICATE", &data
, &b64
);
2217 error (EXIT_FAILURE
, 0, "encoding: %s", gnutls_strerror (result
));
2219 fputs (b64
.data
, outfile
);
2220 gnutls_free (b64
.data
);
2223 /* Read the CRLs now.
2225 result
= gnutls_pkcs7_get_crl_count (pkcs7
);
2227 error (EXIT_FAILURE
, 0, "p7_crl_count: %s", gnutls_strerror (result
));
2232 fprintf (outfile
, "\nNumber of CRLs: %u\n", count
);
2234 for (index
= 0; index
< count
; index
++)
2236 fputs ("\n", outfile
);
2238 size
= sizeof (buffer
);
2239 result
= gnutls_pkcs7_get_crl_raw (pkcs7
, index
, buffer
, &size
);
2246 result
= gnutls_pem_base64_encode_alloc ("X509 CRL", &data
, &b64
);
2248 error (EXIT_FAILURE
, 0, "encoding: %s", gnutls_strerror (result
));
2250 fputs (b64
.data
, outfile
);
2251 gnutls_free (b64
.data
);
2256 smime_to_pkcs7 (void)
2258 size_t linesize
= 0;
2259 char *lineptr
= NULL
;
2262 /* Find body. FIXME: Handle non-b64 Content-Transfer-Encoding.
2263 Reject non-S/MIME tagged Content-Type's? */
2266 len
= getline (&lineptr
, &linesize
, infile
);
2268 error (EXIT_FAILURE
, 0, "Cannot find RFC 2822 header/body separator");
2270 while (strcmp (lineptr
, "\r\n") != 0 && strcmp (lineptr
, "\n") != 0);
2274 len
= getline (&lineptr
, &linesize
, infile
);
2276 error (EXIT_FAILURE
, 0, "Message has RFC 2822 header but no body");
2278 while (strcmp (lineptr
, "\r\n") == 0 && strcmp (lineptr
, "\n") == 0);
2280 printf ("-----BEGIN PKCS7-----\n");
2285 && (lineptr
[len
- 1] == '\r' || lineptr
[len
- 1] == '\n'))
2286 lineptr
[--len
] = '\0';
2287 if (strcmp (lineptr
, "") != 0)
2288 printf ("%s\n", lineptr
);
2289 len
= getline (&lineptr
, &linesize
, infile
);
2293 printf ("-----END PKCS7-----\n");
2299 certtool_version (void)
2301 version_etc (stdout
, program_name
, PACKAGE_STRING
,
2302 gnutls_check_version (NULL
), "Nikos Mavroyanopoulos",
2303 "Simon Josefsson", (char*) NULL
);