2 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
4 * This file is part of GnuTLS.
6 * GnuTLS is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * GnuTLS is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see
18 * <http://www.gnu.org/licenses/>.
23 #include <gnutls/gnutls.h>
24 #include <gnutls/extra.h>
25 #include <gnutls/x509.h>
26 #include <gnutls/openpgp.h>
27 #include <gnutls/pkcs12.h>
28 #include <gnutls/pkcs11.h>
29 #include <gnutls/abstract.h>
40 #include <sys/types.h>
45 /* Gnulib portability files. */
46 #include <read-file.h>
48 #include <version-etc.h>
50 #include <certtool-cfg.h>
51 #include "certtool-gaa.h"
52 #include "certtool-common.h"
54 static void print_crl_info (gnutls_x509_crl_t crl
, FILE * out
);
55 void pkcs7_info (void);
57 void smime_to_pkcs7 (void);
58 void pkcs12_info (void);
59 void generate_pkcs12 (void);
60 void generate_pkcs8 (void);
61 void verify_chain (void);
62 void verify_crl (void);
63 void pubkey_info (gnutls_x509_crt crt
);
64 void pgp_privkey_info (void);
65 void pgp_ring_info (void);
66 void certificate_info (int);
67 void pgp_certificate_info (void);
69 void privkey_info (void);
70 static void gaa_parser (int argc
, char **argv
);
71 void generate_self_signed (void);
72 void generate_request (void);
73 gnutls_x509_crt_t
*load_cert_list (int mand
, size_t * size
);
74 static void print_certificate_info (gnutls_x509_crt_t crt
, FILE * out
, unsigned int all
);
76 static void print_hex_datum (gnutls_datum_t
* dat
);
81 gnutls_digest_algorithm_t default_dig
;
83 /* non interactive operation if set
87 unsigned char buffer
[64 * 1024];
88 const int buffer_size
= sizeof (buffer
);
91 tls_log_func (int level
, const char *str
)
93 fprintf (stderr
, "|<%d>| %s", level
, str
);
97 main (int argc
, char **argv
)
99 set_program_name (argv
[0]);
101 gaa_parser (argc
, argv
);
107 raw_to_string (const unsigned char *raw
, size_t raw_size
)
109 static char buf
[1024];
114 if (raw_size
* 3 + 1 >= sizeof (buf
))
117 for (i
= 0; i
< raw_size
; i
++)
119 sprintf (&(buf
[i
* 3]), "%02X%s", raw
[i
],
120 (i
== raw_size
- 1) ? "" : ":");
122 buf
[sizeof (buf
) - 1] = '\0';
128 print_dsa_pkey (gnutls_datum_t
* x
, gnutls_datum_t
* y
, gnutls_datum_t
* p
,
129 gnutls_datum_t
* q
, gnutls_datum_t
* g
)
133 fprintf (outfile
, "private key:");
136 fprintf (outfile
, "public key:");
138 fprintf (outfile
, "p:");
140 fprintf (outfile
, "q:");
142 fprintf (outfile
, "g:");
147 print_rsa_pkey (gnutls_datum_t
* m
, gnutls_datum_t
* e
, gnutls_datum_t
* d
,
148 gnutls_datum_t
* p
, gnutls_datum_t
* q
, gnutls_datum_t
* u
,
149 gnutls_datum_t
* exp1
, gnutls_datum_t
*exp2
)
151 fprintf (outfile
, "modulus:");
153 fprintf (outfile
, "public exponent:");
157 fprintf (outfile
, "private exponent:");
159 fprintf (outfile
, "prime1:");
161 fprintf (outfile
, "prime2:");
163 fprintf (outfile
, "coefficient:");
167 fprintf (outfile
, "exp1:");
168 print_hex_datum (exp1
);
169 fprintf (outfile
, "exp2:");
170 print_hex_datum (exp2
);
175 static gnutls_sec_param_t
str_to_sec_param(const char* str
)
177 if (strcasecmp(str
, "low")==0)
179 return GNUTLS_SEC_PARAM_LOW
;
181 else if (strcasecmp(str
, "normal")==0)
183 return GNUTLS_SEC_PARAM_NORMAL
;
185 else if (strcasecmp(str
, "high")==0)
187 return GNUTLS_SEC_PARAM_HIGH
;
189 else if (strcasecmp(str
, "ultra")==0)
191 return GNUTLS_SEC_PARAM_ULTRA
;
195 fprintf(stderr
, "Unknown security parameter string: %s\n", str
);
201 int get_bits(gnutls_pk_algorithm_t key_type
)
207 static int warned
= 0;
212 fprintf(stderr
, "** Note: Please use the --sec-param instead of --bits\n");
220 bits
= gnutls_sec_param_to_pk_bits(key_type
, str_to_sec_param(info
.sec_param
));
222 else bits
= gnutls_sec_param_to_pk_bits(key_type
, GNUTLS_SEC_PARAM_NORMAL
);
229 static gnutls_x509_privkey_t
230 generate_private_key_int (void)
232 gnutls_x509_privkey_t key
;
233 int ret
, key_type
, bits
;
237 key_type
= GNUTLS_PK_DSA
;
240 key_type
= GNUTLS_PK_RSA
;
242 ret
= gnutls_x509_privkey_init (&key
);
244 error (EXIT_FAILURE
, 0, "privkey_init: %s", gnutls_strerror (ret
));
246 bits
= get_bits(key_type
);
248 fprintf (stderr
, "Generating a %d bit %s private key...\n", get_bits(key_type
),
249 gnutls_pk_algorithm_get_name (key_type
));
251 if (info
.quick_random
== 0)
253 "This might take several minutes depending on availability of randomness"
254 " in /dev/random.\n");
256 ret
= gnutls_x509_privkey_generate (key
, key_type
, get_bits(key_type
), 0);
258 error (EXIT_FAILURE
, 0, "privkey_generate: %s", gnutls_strerror (ret
));
264 cipher_to_flags (const char *cipher
)
266 if (strcasecmp (cipher
, "3des") == 0)
268 return GNUTLS_PKCS_USE_PBES2_3DES
;
270 else if (strcasecmp (cipher
, "3des-pkcs12") == 0)
272 return GNUTLS_PKCS_USE_PKCS12_3DES
;
274 else if (strcasecmp (cipher
, "arcfour") == 0)
276 return GNUTLS_PKCS_USE_PKCS12_ARCFOUR
;
278 else if (strcasecmp (cipher
, "aes-128") == 0)
280 return GNUTLS_PKCS_USE_PBES2_AES_128
;
282 else if (strcasecmp (cipher
, "aes-192") == 0)
284 return GNUTLS_PKCS_USE_PBES2_AES_192
;
286 else if (strcasecmp (cipher
, "aes-256") == 0)
288 return GNUTLS_PKCS_USE_PBES2_AES_256
;
290 else if (strcasecmp (cipher
, "rc2-40") == 0)
292 return GNUTLS_PKCS_USE_PKCS12_RC2_40
;
295 error (EXIT_FAILURE
, 0, "Unknown cipher %s\n", cipher
);
301 print_private_key (gnutls_x509_privkey_t key
)
311 size
= sizeof (buffer
);
312 ret
= gnutls_x509_privkey_export (key
, info
.outcert_format
,
315 error (EXIT_FAILURE
, 0, "privkey_export: %s", gnutls_strerror (ret
));
323 flags
= GNUTLS_PKCS_USE_PKCS12_RC2_40
;
325 flags
= cipher_to_flags (info
.pkcs_cipher
);
327 if ((pass
= get_confirmed_pass (true)) == NULL
|| *pass
== '\0')
328 flags
= GNUTLS_PKCS_PLAIN
;
330 size
= sizeof (buffer
);
332 gnutls_x509_privkey_export_pkcs8 (key
, info
.outcert_format
, pass
,
333 flags
, buffer
, &size
);
335 error (EXIT_FAILURE
, 0, "privkey_export_pkcs8: %s",
336 gnutls_strerror (ret
));
339 fwrite (buffer
, 1, size
, outfile
);
343 generate_private_key (void)
345 gnutls_x509_privkey_t key
;
347 key
= generate_private_key_int ();
349 print_private_key (key
);
351 gnutls_x509_privkey_deinit (key
);
355 static gnutls_x509_crt_t
356 generate_certificate (gnutls_x509_privkey_t
* ret_key
,
357 gnutls_x509_crt_t ca_crt
, int proxy
)
359 gnutls_x509_crt_t crt
;
360 gnutls_x509_privkey_t key
= NULL
;
364 int days
, result
, ca_status
= 0, path_len
;
366 unsigned int usage
= 0, server
;
367 gnutls_x509_crq_t crq
; /* request */
369 ret
= gnutls_x509_crt_init (&crt
);
371 error (EXIT_FAILURE
, 0, "crt_init: %s", gnutls_strerror (ret
));
373 crq
= load_request ();
378 key
= load_private_key (1);
382 "Please enter the details of the certificate's distinguished name. "
383 "Just press enter to ignore a field.\n");
389 result
= gnutls_x509_crt_set_proxy_dn (crt
, ca_crt
, 0, NULL
, 0);
391 error (EXIT_FAILURE
, 0, "set_proxy_dn: %s",
392 gnutls_strerror (result
));
394 get_cn_crt_set (crt
);
398 get_country_crt_set (crt
);
399 get_organization_crt_set (crt
);
400 get_unit_crt_set (crt
);
401 get_locality_crt_set (crt
);
402 get_state_crt_set (crt
);
403 get_cn_crt_set (crt
);
404 get_uid_crt_set (crt
);
405 get_oid_crt_set (crt
);
406 get_key_purpose_set (crt
);
410 "This field should not be used in new certificates.\n");
412 get_pkcs9_email_crt_set (crt
);
415 result
= gnutls_x509_crt_set_key (crt
, key
);
417 error (EXIT_FAILURE
, 0, "set_key: %s", gnutls_strerror (result
));
421 result
= gnutls_x509_crt_set_crq (crt
, crq
);
423 error (EXIT_FAILURE
, 0, "set_crq: %s", gnutls_strerror (result
));
428 int serial
= get_serial ();
431 bin_serial
[4] = serial
& 0xff;
432 bin_serial
[3] = (serial
>> 8) & 0xff;
433 bin_serial
[2] = (serial
>> 16) & 0xff;
434 bin_serial
[1] = (serial
>> 24) & 0xff;
437 result
= gnutls_x509_crt_set_serial (crt
, bin_serial
, 5);
439 error (EXIT_FAILURE
, 0, "serial: %s", gnutls_strerror (result
));
443 fprintf (stderr
, "\n\nActivation/Expiration time.\n");
445 gnutls_x509_crt_set_activation_time (crt
, time (NULL
));
450 gnutls_x509_crt_set_expiration_time (crt
,
451 time (NULL
) + days
* 24 * 60 * 60);
453 error (EXIT_FAILURE
, 0, "set_expiration: %s", gnutls_strerror (result
));
456 fprintf (stderr
, "\n\nExtensions.\n");
458 /* do not allow extensions on a v1 certificate */
459 if (crq
&& get_crq_extensions_status () != 0)
461 result
= gnutls_x509_crt_set_crq_extensions (crt
, crq
);
463 error (EXIT_FAILURE
, 0, "set_crq: %s", gnutls_strerror (result
));
466 /* append additional extensions */
467 if (info
.v1_cert
== 0)
472 const char *policylanguage
;
475 int proxypathlen
= get_path_len ();
479 printf ("1.3.6.1.5.5.7.21.1 ::= id-ppl-inheritALL\n");
480 printf ("1.3.6.1.5.5.7.21.2 ::= id-ppl-independent\n");
483 policylanguage
= get_proxy_policy (&policy
, &policylen
);
486 gnutls_x509_crt_set_proxy (crt
, proxypathlen
, policylanguage
,
489 error (EXIT_FAILURE
, 0, "set_proxy: %s",
490 gnutls_strerror (result
));
494 ca_status
= get_ca_status ();
496 path_len
= get_path_len ();
501 gnutls_x509_crt_set_basic_constraints (crt
, ca_status
, path_len
);
503 error (EXIT_FAILURE
, 0, "basic_constraints: %s",
504 gnutls_strerror (result
));
506 client
= get_tls_client_status ();
509 result
= gnutls_x509_crt_set_key_purpose_oid (crt
,
510 GNUTLS_KP_TLS_WWW_CLIENT
,
513 error (EXIT_FAILURE
, 0, "key_kp: %s", gnutls_strerror (result
));
516 server
= get_tls_server_status ();
523 get_dns_name_set (TYPE_CRT
, crt
);
524 get_ip_addr_set (TYPE_CRT
, crt
);
528 gnutls_x509_crt_set_key_purpose_oid (crt
,
529 GNUTLS_KP_TLS_WWW_SERVER
, 0);
531 error (EXIT_FAILURE
, 0, "key_kp: %s", gnutls_strerror (result
));
535 get_email_set (TYPE_CRT
, crt
);
538 if (!ca_status
|| server
)
543 pk
= gnutls_x509_crt_get_pk_algorithm (crt
, NULL
);
545 if (pk
!= GNUTLS_PK_DSA
)
546 { /* DSA keys can only sign.
548 result
= get_sign_status (server
);
550 usage
|= GNUTLS_KEY_DIGITAL_SIGNATURE
;
552 result
= get_encrypt_status (server
);
554 usage
|= GNUTLS_KEY_KEY_ENCIPHERMENT
;
557 usage
|= GNUTLS_KEY_DIGITAL_SIGNATURE
;
563 result
= get_cert_sign_status ();
565 usage
|= GNUTLS_KEY_KEY_CERT_SIGN
;
567 result
= get_crl_sign_status ();
569 usage
|= GNUTLS_KEY_CRL_SIGN
;
571 result
= get_code_sign_status ();
575 gnutls_x509_crt_set_key_purpose_oid (crt
,
576 GNUTLS_KP_CODE_SIGNING
,
579 error (EXIT_FAILURE
, 0, "key_kp: %s",
580 gnutls_strerror (result
));
583 result
= get_ocsp_sign_status ();
587 gnutls_x509_crt_set_key_purpose_oid (crt
,
588 GNUTLS_KP_OCSP_SIGNING
,
591 error (EXIT_FAILURE
, 0, "key_kp: %s",
592 gnutls_strerror (result
));
595 result
= get_time_stamp_status ();
599 gnutls_x509_crt_set_key_purpose_oid (crt
,
600 GNUTLS_KP_TIME_STAMPING
,
603 error (EXIT_FAILURE
, 0, "key_kp: %s",
604 gnutls_strerror (result
));
610 result
= gnutls_x509_crt_set_key_usage (crt
, usage
);
612 error (EXIT_FAILURE
, 0, "key_usage: %s",
613 gnutls_strerror (result
));
618 size
= sizeof (buffer
);
619 result
= gnutls_x509_crt_get_key_id (crt
, 0, buffer
, &size
);
622 result
= gnutls_x509_crt_set_subject_key_id (crt
, buffer
, size
);
624 error (EXIT_FAILURE
, 0, "set_subject_key_id: %s",
625 gnutls_strerror (result
));
632 size
= sizeof (buffer
);
633 result
= gnutls_x509_crt_get_subject_key_id (ca_crt
, buffer
,
637 size
= sizeof (buffer
);
638 result
= gnutls_x509_crt_get_key_id (ca_crt
, 0, buffer
, &size
);
643 gnutls_x509_crt_set_authority_key_id (crt
, buffer
, size
);
645 error (EXIT_FAILURE
, 0, "set_authority_key_id: %s",
646 gnutls_strerror (result
));
653 if (info
.v1_cert
!= 0)
657 result
= gnutls_x509_crt_set_version (crt
, vers
);
659 error (EXIT_FAILURE
, 0, "set_version: %s", gnutls_strerror (result
));
666 static gnutls_x509_crl_t
667 generate_crl (gnutls_x509_crt_t ca_crt
)
669 gnutls_x509_crl_t crl
;
670 gnutls_x509_crt_t
*crts
;
674 time_t now
= time (NULL
);
676 result
= gnutls_x509_crl_init (&crl
);
678 error (EXIT_FAILURE
, 0, "crl_init: %s", gnutls_strerror (result
));
680 crts
= load_cert_list (0, &size
);
682 for (i
= 0; i
< size
; i
++)
684 result
= gnutls_x509_crl_set_crt (crl
, crts
[i
], now
);
686 error (EXIT_FAILURE
, 0, "crl_set_crt: %s", gnutls_strerror (result
));
689 result
= gnutls_x509_crl_set_this_update (crl
, now
);
691 error (EXIT_FAILURE
, 0, "this_update: %s", gnutls_strerror (result
));
693 fprintf (stderr
, "Update times.\n");
694 days
= get_crl_next_update ();
696 result
= gnutls_x509_crl_set_next_update (crl
, now
+ days
* 24 * 60 * 60);
698 error (EXIT_FAILURE
, 0, "next_update: %s", gnutls_strerror (result
));
700 result
= gnutls_x509_crl_set_version (crl
, 2);
702 error (EXIT_FAILURE
, 0, "set_version: %s", gnutls_strerror (result
));
708 size
= sizeof (buffer
);
709 result
= gnutls_x509_crt_get_subject_key_id (ca_crt
, buffer
,
713 size
= sizeof (buffer
);
714 result
= gnutls_x509_crt_get_key_id (ca_crt
, 0, buffer
, &size
);
718 result
= gnutls_x509_crl_set_authority_key_id (crl
, buffer
, size
);
720 error (EXIT_FAILURE
, 0, "set_authority_key_id: %s",
721 gnutls_strerror (result
));
726 unsigned int number
= get_crl_number ();
729 bin_number
[4] = number
& 0xff;
730 bin_number
[3] = (number
>> 8) & 0xff;
731 bin_number
[2] = (number
>> 16) & 0xff;
732 bin_number
[1] = (number
>> 24) & 0xff;
735 result
= gnutls_x509_crl_set_number (crl
, bin_number
, 5);
737 error (EXIT_FAILURE
, 0, "set_number: %s", gnutls_strerror (result
));
743 static gnutls_digest_algorithm_t
get_dig(gnutls_x509_crt crt
)
745 gnutls_digest_algorithm_t dig
;
749 result
= gnutls_x509_crt_get_preferred_hash_algorithm(crt
, &dig
, &mand
);
752 error (EXIT_FAILURE
, 0, "crl_preferred_hash_algorithm: %s",
753 gnutls_strerror (result
));
756 /* if algorithm allows alternatives */
757 if (mand
== 0 && default_dig
!= GNUTLS_DIG_UNKNOWN
)
763 void generate_self_signed (void)
765 gnutls_x509_crt_t crt
;
766 gnutls_x509_privkey_t key
;
771 fprintf (stderr
, "Generating a self signed certificate...\n");
773 crt
= generate_certificate (&key
, NULL
, 0);
776 key
= load_private_key (1);
778 uri
= get_crl_dist_point_url ();
781 result
= gnutls_x509_crt_set_crl_dist_points (crt
, GNUTLS_SAN_URI
,
783 0 /* all reasons */ );
785 error (EXIT_FAILURE
, 0, "crl_dist_points: %s",
786 gnutls_strerror (result
));
789 print_certificate_info (crt
, stderr
, 0);
791 fprintf (stderr
, "\n\nSigning certificate...\n");
793 result
= gnutls_x509_crt_sign2 (crt
, crt
, key
, get_dig(crt
), 0);
795 error (EXIT_FAILURE
, 0, "crt_sign: %s", gnutls_strerror (result
));
797 size
= sizeof (buffer
);
798 result
= gnutls_x509_crt_export (crt
, info
.outcert_format
, buffer
, &size
);
800 error (EXIT_FAILURE
, 0, "crt_export: %s", gnutls_strerror (result
));
802 fwrite (buffer
, 1, size
, outfile
);
804 gnutls_x509_crt_deinit (crt
);
805 gnutls_x509_privkey_deinit (key
);
809 generate_signed_certificate (void)
811 gnutls_x509_crt_t crt
;
812 gnutls_x509_privkey_t key
;
815 gnutls_x509_privkey_t ca_key
;
816 gnutls_x509_crt_t ca_crt
;
818 fprintf (stderr
, "Generating a signed certificate...\n");
820 ca_key
= load_ca_private_key ();
821 ca_crt
= load_ca_cert ();
823 crt
= generate_certificate (&key
, ca_crt
, 0);
825 /* Copy the CRL distribution points.
827 gnutls_x509_crt_cpy_crl_dist_points (crt
, ca_crt
);
828 /* it doesn't matter if we couldn't copy the CRL dist points.
831 print_certificate_info (crt
, stderr
, 0);
833 fprintf (stderr
, "\n\nSigning certificate...\n");
835 result
= gnutls_x509_crt_sign2 (crt
, ca_crt
, ca_key
, get_dig(ca_crt
), 0);
837 error (EXIT_FAILURE
, 0, "crt_sign: %s", gnutls_strerror (result
));
839 size
= sizeof (buffer
);
840 result
= gnutls_x509_crt_export (crt
, info
.outcert_format
, buffer
, &size
);
842 error (EXIT_FAILURE
, 0, "crt_export: %s", gnutls_strerror (result
));
844 fwrite (buffer
, 1, size
, outfile
);
846 gnutls_x509_crt_deinit (crt
);
847 gnutls_x509_privkey_deinit (key
);
851 generate_proxy_certificate (void)
853 gnutls_x509_crt_t crt
, eecrt
;
854 gnutls_x509_privkey_t key
, eekey
;
858 fprintf (stderr
, "Generating a proxy certificate...\n");
860 eekey
= load_ca_private_key ();
861 eecrt
= load_cert (1);
863 crt
= generate_certificate (&key
, eecrt
, 1);
865 print_certificate_info (crt
, stderr
, 0);
867 fprintf (stderr
, "\n\nSigning certificate...\n");
869 result
= gnutls_x509_crt_sign2 (crt
, eecrt
, eekey
, get_dig(eecrt
), 0);
871 error (EXIT_FAILURE
, 0, "crt_sign: %s", gnutls_strerror (result
));
873 size
= sizeof (buffer
);
874 result
= gnutls_x509_crt_export (crt
, info
.outcert_format
, buffer
, &size
);
876 error (EXIT_FAILURE
, 0, "crt_export: %s", gnutls_strerror (result
));
878 fwrite (buffer
, 1, size
, outfile
);
880 gnutls_x509_crt_deinit (crt
);
881 gnutls_x509_privkey_deinit (key
);
885 generate_signed_crl (void)
887 gnutls_x509_crl_t crl
;
889 gnutls_x509_privkey_t ca_key
;
890 gnutls_x509_crt_t ca_crt
;
892 fprintf (stderr
, "Generating a signed CRL...\n");
894 ca_key
= load_ca_private_key ();
895 ca_crt
= load_ca_cert ();
896 crl
= generate_crl (ca_crt
);
898 fprintf (stderr
, "\n");
900 result
= gnutls_x509_crl_sign (crl
, ca_crt
, ca_key
);
902 error (EXIT_FAILURE
, 0, "crl_sign: %s", gnutls_strerror (result
));
904 print_crl_info (crl
, stderr
);
906 gnutls_x509_crl_deinit (crl
);
910 update_signed_certificate (void)
912 gnutls_x509_crt_t crt
;
915 gnutls_x509_privkey_t ca_key
;
916 gnutls_x509_crt_t ca_crt
;
918 time_t tim
= time (NULL
);
920 fprintf (stderr
, "Generating a signed certificate...\n");
922 ca_key
= load_ca_private_key ();
923 ca_crt
= load_ca_cert ();
926 fprintf (stderr
, "Activation/Expiration time.\n");
927 gnutls_x509_crt_set_activation_time (crt
, tim
);
932 gnutls_x509_crt_set_expiration_time (crt
, tim
+ days
* 24 * 60 * 60);
934 error (EXIT_FAILURE
, 0, "set_expiration: %s", gnutls_strerror (result
));
936 fprintf (stderr
, "\n\nSigning certificate...\n");
938 result
= gnutls_x509_crt_sign2 (crt
, ca_crt
, ca_key
, get_dig(ca_crt
), 0);
940 error (EXIT_FAILURE
, 0, "crt_sign: %s", gnutls_strerror (result
));
942 size
= sizeof (buffer
);
943 result
= gnutls_x509_crt_export (crt
, info
.outcert_format
, buffer
, &size
);
945 error (EXIT_FAILURE
, 0, "crt_export: %s", gnutls_strerror (result
));
947 fwrite (buffer
, 1, size
, outfile
);
949 gnutls_x509_crt_deinit (crt
);
953 safe_open_rw (const char *file
)
958 if (info
.privkey_op
!= 0)
960 omask
= umask (S_IRGRP
| S_IWGRP
| S_IROTH
| S_IWOTH
);
963 fh
= fopen (file
, "wb");
965 if (info
.privkey_op
!= 0)
974 gaa_parser (int argc
, char **argv
)
978 if (gaa (argc
, argv
, &info
) != -1)
980 fprintf (stderr
, "Try `%s --help' for more information.\n",
987 outfile
= safe_open_rw (info
.outfile
);
989 error (EXIT_FAILURE
, errno
, "%s", info
.outfile
);
996 infile
= fopen (info
.infile
, "rb");
998 error (EXIT_FAILURE
, errno
, "%s", info
.infile
);
1003 if (info
.incert_format
)
1004 info
.incert_format
= GNUTLS_X509_FMT_DER
;
1006 info
.incert_format
= GNUTLS_X509_FMT_PEM
;
1008 if (info
.outcert_format
)
1009 info
.outcert_format
= GNUTLS_X509_FMT_DER
;
1011 info
.outcert_format
= GNUTLS_X509_FMT_PEM
;
1013 default_dig
= GNUTLS_DIG_UNKNOWN
;
1014 if (info
.hash
!= NULL
)
1016 if (strcasecmp (info
.hash
, "md5") == 0)
1019 "Warning: MD5 is broken, and should not be used any more for digital signatures.\n");
1020 default_dig
= GNUTLS_DIG_MD5
;
1022 else if (strcasecmp (info
.hash
, "sha1") == 0)
1023 default_dig
= GNUTLS_DIG_SHA1
;
1024 else if (strcasecmp (info
.hash
, "sha256") == 0)
1025 default_dig
= GNUTLS_DIG_SHA256
;
1026 else if (strcasecmp (info
.hash
, "sha224") == 0)
1027 default_dig
= GNUTLS_DIG_SHA224
;
1028 else if (strcasecmp (info
.hash
, "sha384") == 0)
1029 default_dig
= GNUTLS_DIG_SHA384
;
1030 else if (strcasecmp (info
.hash
, "sha512") == 0)
1031 default_dig
= GNUTLS_DIG_SHA512
;
1032 else if (strcasecmp (info
.hash
, "rmd160") == 0)
1033 default_dig
= GNUTLS_DIG_RMD160
;
1035 error (EXIT_FAILURE
, 0, "invalid hash: %s", info
.hash
);
1042 template_parse (info
.template);
1045 gnutls_global_set_log_function (tls_log_func
);
1046 gnutls_global_set_log_level (info
.debug
);
1048 printf ("Setting log level to %d\n", info
.debug
);
1050 if ((ret
= gnutls_global_init ()) < 0)
1051 error (EXIT_FAILURE
, 0, "global_init: %s", gnutls_strerror (ret
));
1053 if (info
.pkcs11_provider
!= NULL
)
1055 ret
= gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_MANUAL
, NULL
);
1057 fprintf (stderr
, "pkcs11_init: %s", gnutls_strerror (ret
));
1059 ret
= gnutls_pkcs11_add_provider(info
.pkcs11_provider
, NULL
);
1061 error (EXIT_FAILURE
, 0, "pkcs11_add_provider: %s", gnutls_strerror (ret
));
1066 ret
= gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_AUTO
, NULL
);
1068 fprintf (stderr
, "pkcs11_init: %s", gnutls_strerror (ret
));
1072 if ((ret
= gnutls_global_init_extra ()) < 0)
1073 error (EXIT_FAILURE
, 0, "global_init_extra: %s", gnutls_strerror (ret
));
1075 switch (info
.action
)
1077 case ACTION_SELF_SIGNED
:
1078 generate_self_signed ();
1080 case ACTION_GENERATE_PRIVKEY
:
1081 generate_private_key ();
1083 case ACTION_CERT_INFO
:
1084 certificate_info (0);
1086 case ACTION_CERT_PUBKEY
:
1087 certificate_info (1);
1089 case ACTION_GENERATE_REQUEST
:
1090 generate_request ();
1092 case ACTION_GENERATE_CERTIFICATE
:
1093 generate_signed_certificate ();
1095 case ACTION_VERIFY_CHAIN
:
1098 case ACTION_PRIVKEY_INFO
:
1101 case ACTION_PUBKEY_INFO
:
1104 case ACTION_UPDATE_CERTIFICATE
:
1105 update_signed_certificate ();
1107 case ACTION_TO_PKCS12
:
1110 case ACTION_PKCS12_INFO
:
1113 case ACTION_GENERATE_DH
:
1119 case ACTION_CRL_INFO
:
1122 case ACTION_P7_INFO
:
1125 case ACTION_GENERATE_CRL
:
1126 generate_signed_crl ();
1128 case ACTION_VERIFY_CRL
:
1131 case ACTION_SMIME_TO_P7
:
1134 case ACTION_GENERATE_PROXY
:
1135 generate_proxy_certificate ();
1137 case ACTION_GENERATE_PKCS8
:
1140 case ACTION_PKCS11_LIST
:
1141 pkcs11_list(outfile
, info
.pkcs11_url
, info
.pkcs11_type
, info
.pkcs11_login
);
1143 case ACTION_PKCS11_TOKENS
:
1144 pkcs11_token_list(outfile
);
1146 case ACTION_PKCS11_EXPORT_URL
:
1147 pkcs11_export(outfile
, info
.pkcs11_url
, info
.pkcs11_login
);
1149 case ACTION_PKCS11_WRITE_URL
:
1150 pkcs11_write(outfile
, info
.pkcs11_url
, info
.pkcs11_label
, info
.pkcs11_trusted
, info
.pkcs11_login
);
1152 case ACTION_PKCS11_DELETE_URL
:
1153 pkcs11_delete(outfile
, info
.pkcs11_url
, batch
, info
.pkcs11_login
);
1155 #ifdef ENABLE_OPENPGP
1156 case ACTION_PGP_INFO
:
1157 pgp_certificate_info ();
1159 case ACTION_PGP_PRIVKEY_INFO
:
1160 pgp_privkey_info ();
1162 case ACTION_RING_INFO
:
1166 case ACTION_REQUEST
:
1175 gnutls_pkcs11_deinit();
1176 gnutls_global_deinit();
1179 #define MAX_CRTS 500
1181 certificate_info (int pubkey
)
1183 gnutls_x509_crt_t crt
[MAX_CRTS
];
1187 unsigned int crt_num
;
1189 pem
.data
= fread_file (infile
, &size
);
1194 gnutls_x509_crt_list_import (crt
, &crt_num
, &pem
, info
.incert_format
,
1195 GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED
);
1196 if (ret
== GNUTLS_E_SHORT_MEMORY_BUFFER
)
1198 error (0, 0, "too many certificates (%d); "
1199 "will only read the first %d", crt_num
, MAX_CRTS
);
1201 ret
= gnutls_x509_crt_list_import (crt
, &crt_num
, &pem
,
1202 info
.incert_format
, 0);
1205 error (EXIT_FAILURE
, 0, "import error: %s", gnutls_strerror (ret
));
1211 if (count
> 1 && info
.outcert_format
== GNUTLS_X509_FMT_DER
)
1213 error (0, 0, "cannot output multiple certificates in DER format; "
1214 "using PEM instead");
1215 info
.outcert_format
= GNUTLS_X509_FMT_PEM
;
1218 for (i
= 0; i
< count
; i
++)
1221 fprintf (outfile
, "\n");
1223 if (info
.outcert_format
== GNUTLS_X509_FMT_PEM
)
1224 print_certificate_info (crt
[i
], outfile
, 1);
1226 size
= sizeof (buffer
);
1227 ret
= gnutls_x509_crt_export (crt
[i
], info
.outcert_format
, buffer
,
1230 error (EXIT_FAILURE
, 0, "export error: %s", gnutls_strerror (ret
));
1232 fwrite (buffer
, 1, size
, outfile
);
1234 if (pubkey
) pubkey_info(crt
[i
]);
1236 gnutls_x509_crt_deinit (crt
[i
]);
1240 #ifdef ENABLE_OPENPGP
1243 pgp_certificate_info (void)
1245 gnutls_openpgp_crt_t crt
;
1248 gnutls_datum_t pem
, out_data
;
1249 unsigned int verify_status
;
1251 pem
.data
= fread_file (infile
, &size
);
1254 ret
= gnutls_openpgp_crt_init (&crt
);
1256 error (EXIT_FAILURE
, 0, "openpgp_crt_init: %s", gnutls_strerror (ret
));
1258 ret
= gnutls_openpgp_crt_import (crt
, &pem
, info
.incert_format
);
1261 error (EXIT_FAILURE
, 0, "import error: %s", gnutls_strerror (ret
));
1265 if (info
.outcert_format
== GNUTLS_OPENPGP_FMT_BASE64
)
1267 ret
= gnutls_openpgp_crt_print (crt
, 0, &out_data
);
1271 fprintf (outfile
, "%s\n", out_data
.data
);
1272 gnutls_free (out_data
.data
);
1277 ret
= gnutls_openpgp_crt_verify_self (crt
, 0, &verify_status
);
1280 error (EXIT_FAILURE
, 0, "verify signature error: %s",
1281 gnutls_strerror (ret
));
1284 if (verify_status
& GNUTLS_CERT_INVALID
)
1286 fprintf (outfile
, "Self Signature verification: failed\n\n");
1290 fprintf (outfile
, "Self Signature verification: ok (%x)\n\n",
1294 size
= sizeof (buffer
);
1295 ret
= gnutls_openpgp_crt_export (crt
, info
.outcert_format
, buffer
, &size
);
1298 error (EXIT_FAILURE
, 0, "export error: %s", gnutls_strerror (ret
));
1299 fwrite (buffer
, 1, size
, outfile
);
1302 fprintf (outfile
, "%s\n", buffer
);
1303 gnutls_openpgp_crt_deinit (crt
);
1307 pgp_privkey_info (void)
1309 gnutls_openpgp_privkey_t key
;
1310 gnutls_openpgp_keyid_t keyid
;
1312 int ret
, i
, subkeys
;
1316 size
= fread (buffer
, 1, sizeof (buffer
) - 1, infile
);
1319 gnutls_openpgp_privkey_init (&key
);
1324 ret
= gnutls_openpgp_privkey_import (key
, &pem
, info
.incert_format
,
1328 error (EXIT_FAILURE
, 0, "import error: %s", gnutls_strerror (ret
));
1330 /* Public key algorithm
1332 subkeys
= gnutls_openpgp_privkey_get_subkey_count (key
);
1334 error (EXIT_FAILURE
, 0, "privkey_get_subkey_count: %s",
1335 gnutls_strerror (subkeys
));
1337 for (i
= -1; i
< subkeys
; i
++)
1341 fprintf (outfile
, "Subkey[%d]:\n", i
);
1343 fprintf (outfile
, "Public Key Info:\n");
1346 ret
= gnutls_openpgp_privkey_get_pk_algorithm (key
, NULL
);
1348 ret
= gnutls_openpgp_privkey_get_subkey_pk_algorithm (key
, i
, NULL
);
1350 fprintf (outfile
, "\tPublic Key Algorithm: ");
1351 cprint
= gnutls_pk_algorithm_get_name (ret
);
1352 fprintf (outfile
, "%s\n", cprint
? cprint
: "Unknown");
1353 fprintf (outfile
, "\tKey Security Level: %s\n", gnutls_sec_param_get_name(gnutls_openpgp_privkey_sec_param(key
)));
1355 /* Print the raw public and private keys
1358 if (ret
== GNUTLS_PK_RSA
)
1360 gnutls_datum_t m
, e
, d
, p
, q
, u
;
1364 gnutls_openpgp_privkey_export_rsa_raw (key
, &m
, &e
, &d
, &p
,
1368 gnutls_openpgp_privkey_export_subkey_rsa_raw (key
, i
, &m
,
1372 fprintf (stderr
, "Error in key RSA data export: %s\n",
1373 gnutls_strerror (ret
));
1375 print_rsa_pkey (&m
, &e
, &d
, &p
, &q
, &u
, NULL
, NULL
);
1378 else if (ret
== GNUTLS_PK_DSA
)
1380 gnutls_datum_t p
, q
, g
, y
, x
;
1384 gnutls_openpgp_privkey_export_dsa_raw (key
, &p
, &q
, &g
, &y
, &x
);
1387 gnutls_openpgp_privkey_export_subkey_dsa_raw (key
, i
, &p
,
1390 fprintf (stderr
, "Error in key DSA data export: %s\n",
1391 gnutls_strerror (ret
));
1393 print_dsa_pkey (&x
, &y
, &p
, &q
, &g
);
1396 fprintf (outfile
, "\n");
1398 size
= sizeof (buffer
);
1400 ret
= gnutls_openpgp_privkey_get_key_id (key
, keyid
);
1402 ret
= gnutls_openpgp_privkey_get_subkey_id (key
, i
, keyid
);
1406 fprintf (stderr
, "Error in key id calculation: %s\n",
1407 gnutls_strerror (ret
));
1411 fprintf (outfile
, "Public Key ID: %s\n", raw_to_string (keyid
, 8));
1416 size
= sizeof (buffer
);
1417 ret
= gnutls_openpgp_privkey_export (key
, GNUTLS_OPENPGP_FMT_BASE64
,
1418 NULL
, 0, buffer
, &size
);
1420 error (EXIT_FAILURE
, 0, "export error: %s", gnutls_strerror (ret
));
1422 fprintf (outfile
, "\n%s\n", buffer
);
1424 gnutls_openpgp_privkey_deinit (key
);
1428 pgp_ring_info (void)
1430 gnutls_openpgp_keyring_t ring
;
1431 gnutls_openpgp_crt_t crt
;
1436 pem
.data
= fread_file (infile
, &size
);
1439 ret
= gnutls_openpgp_keyring_init (&ring
);
1441 error (EXIT_FAILURE
, 0, "openpgp_keyring_init: %s",
1442 gnutls_strerror (ret
));
1444 ret
= gnutls_openpgp_keyring_import (ring
, &pem
, info
.incert_format
);
1447 error (EXIT_FAILURE
, 0, "import error: %s", gnutls_strerror (ret
));
1451 count
= gnutls_openpgp_keyring_get_crt_count (ring
);
1453 fprintf (outfile
, "Keyring contains %d OpenPGP certificates\n\n", count
);
1455 error (EXIT_FAILURE
, 0, "keyring error: %s", gnutls_strerror (count
));
1457 for (i
= 0; i
< count
; i
++)
1459 ret
= gnutls_openpgp_keyring_get_crt (ring
, i
, &crt
);
1461 error (EXIT_FAILURE
, 0, "export error: %s", gnutls_strerror (ret
));
1463 size
= sizeof (buffer
);
1464 ret
= gnutls_openpgp_crt_export (crt
, info
.outcert_format
,
1467 error (EXIT_FAILURE
, 0, "export error: %s", gnutls_strerror (ret
));
1469 fwrite (buffer
, 1, size
, outfile
);
1470 fprintf (outfile
, "\n\n");
1472 gnutls_openpgp_crt_deinit (crt
);
1477 gnutls_openpgp_keyring_deinit (ring
);
1484 print_hex_datum (gnutls_datum_t
* dat
)
1488 fprintf (outfile
, "\n" SPACE
);
1489 for (j
= 0; j
< dat
->size
; j
++)
1491 fprintf (outfile
, "%.2x:", (unsigned char) dat
->data
[j
]);
1492 if ((j
+ 1) % 15 == 0)
1493 fprintf (outfile
, "\n" SPACE
);
1495 fprintf (outfile
, "\n");
1500 print_certificate_info (gnutls_x509_crt_t crt
, FILE * out
, unsigned int all
)
1502 gnutls_datum_t cinfo
;
1506 ret
= gnutls_x509_crt_print (crt
, GNUTLS_CRT_PRINT_FULL
, &cinfo
);
1508 ret
= gnutls_x509_crt_print (crt
, GNUTLS_CRT_PRINT_UNSIGNED_FULL
, &cinfo
);
1511 fprintf (out
, "%s\n", cinfo
.data
);
1512 gnutls_free (cinfo
.data
);
1515 if (out
== stderr
&& batch
== 0) /* interactive */
1516 if (read_yesno ("Is the above information ok? (Y/N): ") == 0)
1523 print_crl_info (gnutls_x509_crl_t crl
, FILE * out
)
1525 gnutls_datum_t cinfo
;
1529 ret
= gnutls_x509_crl_print (crl
, GNUTLS_CRT_PRINT_FULL
, &cinfo
);
1531 error (EXIT_FAILURE
, 0, "crl_print: %s", gnutls_strerror (ret
));
1533 fprintf (out
, "%s\n", cinfo
.data
);
1535 gnutls_free (cinfo
.data
);
1537 size
= sizeof (buffer
);
1538 ret
= gnutls_x509_crl_export (crl
, GNUTLS_X509_FMT_PEM
, buffer
, &size
);
1540 error (EXIT_FAILURE
, 0, "crl_export: %s", gnutls_strerror (ret
));
1542 fwrite (buffer
, 1, size
, outfile
);
1548 gnutls_x509_crl_t crl
;
1553 ret
= gnutls_x509_crl_init (&crl
);
1555 error (EXIT_FAILURE
, 0, "crl_init: %s", gnutls_strerror (ret
));
1557 pem
.data
= fread_file (infile
, &size
);
1561 error (EXIT_FAILURE
, errno
, "%s", info
.infile
? info
.infile
:
1564 ret
= gnutls_x509_crl_import (crl
, &pem
, info
.incert_format
);
1568 error (EXIT_FAILURE
, 0, "import error: %s", gnutls_strerror (ret
));
1570 print_crl_info (crl
, outfile
);
1572 gnutls_x509_crl_deinit (crl
);
1576 print_crq_info (gnutls_x509_crq_t crq
, FILE * out
)
1578 gnutls_datum_t cinfo
;
1582 if (info
.outcert_format
== GNUTLS_X509_FMT_PEM
)
1584 ret
= gnutls_x509_crq_print (crq
, GNUTLS_CRT_PRINT_FULL
, &cinfo
);
1586 error (EXIT_FAILURE
, 0, "crq_print: %s", gnutls_strerror (ret
));
1588 fprintf (out
, "%s\n", cinfo
.data
);
1590 gnutls_free (cinfo
.data
);
1593 size
= sizeof (buffer
);
1594 ret
= gnutls_x509_crq_export (crq
, info
.outcert_format
, buffer
, &size
);
1596 error (EXIT_FAILURE
, 0, "crq_export: %s", gnutls_strerror (ret
));
1598 fwrite (buffer
, 1, size
, outfile
);
1604 gnutls_x509_crq_t crq
;
1609 ret
= gnutls_x509_crq_init (&crq
);
1611 error (EXIT_FAILURE
, 0, "crq_init: %s", gnutls_strerror (ret
));
1613 pem
.data
= fread_file (infile
, &size
);
1617 error (EXIT_FAILURE
, errno
, "%s", info
.infile
? info
.infile
:
1620 ret
= gnutls_x509_crq_import (crq
, &pem
, info
.incert_format
);
1624 error (EXIT_FAILURE
, 0, "import error: %s", gnutls_strerror (ret
));
1626 print_crq_info (crq
, outfile
);
1628 gnutls_x509_crq_deinit (crq
);
1634 gnutls_x509_privkey_t key
;
1641 size
= fread (buffer
, 1, sizeof (buffer
) - 1, infile
);
1644 gnutls_x509_privkey_init (&key
);
1651 ret
= gnutls_x509_privkey_import (key
, &pem
, info
.incert_format
);
1653 /* If we failed to import the certificate previously try PKCS #8 */
1654 if (info
.pkcs8
|| ret
== GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR
)
1656 /* first try to import the key without asking any password */
1657 ret
= gnutls_x509_privkey_import_pkcs8 (key
, &pem
,
1659 NULL
, GNUTLS_PKCS_PLAIN
);
1666 ret
= gnutls_x509_privkey_import_pkcs8 (key
, &pem
,
1672 error (EXIT_FAILURE
, 0, "import error: %s", gnutls_strerror (ret
));
1674 /* Public key algorithm
1676 fprintf (outfile
, "Public Key Info:\n");
1677 ret
= gnutls_x509_privkey_get_pk_algorithm (key
);
1678 fprintf (outfile
, "\tPublic Key Algorithm: ");
1680 cprint
= gnutls_pk_algorithm_get_name (ret
);
1681 fprintf (outfile
, "%s\n", cprint
? cprint
: "Unknown");
1682 fprintf (outfile
, "\tKey Security Level: %s\n", gnutls_sec_param_get_name(gnutls_x509_privkey_sec_param(key
)));
1684 /* Print the raw public and private keys
1686 if (ret
== GNUTLS_PK_RSA
)
1688 gnutls_datum_t m
, e
, d
, p
, q
, u
, exp1
, exp2
;
1690 ret
= gnutls_x509_privkey_export_rsa_raw2 (key
, &m
, &e
, &d
, &p
, &q
, &u
, &exp1
, &exp2
);
1692 fprintf (stderr
, "Error in key RSA data export: %s\n",
1693 gnutls_strerror (ret
));
1696 print_rsa_pkey (&m
, &e
, &d
, &p
, &q
, &u
, &exp1
, &exp2
);
1697 gnutls_free (m
.data
);
1698 gnutls_free (e
.data
);
1699 gnutls_free (d
.data
);
1700 gnutls_free (p
.data
);
1701 gnutls_free (q
.data
);
1702 gnutls_free (u
.data
);
1703 gnutls_free (exp1
.data
);
1704 gnutls_free (exp2
.data
);
1707 else if (ret
== GNUTLS_PK_DSA
)
1709 gnutls_datum_t p
, q
, g
, y
, x
;
1711 ret
= gnutls_x509_privkey_export_dsa_raw (key
, &p
, &q
, &g
, &y
, &x
);
1713 fprintf (stderr
, "Error in key DSA data export: %s\n",
1714 gnutls_strerror (ret
));
1717 print_dsa_pkey (&x
, &y
, &p
, &q
, &g
);
1718 gnutls_free (x
.data
);
1719 gnutls_free (y
.data
);
1720 gnutls_free (p
.data
);
1721 gnutls_free (q
.data
);
1722 gnutls_free (g
.data
);
1726 fprintf (outfile
, "\n");
1728 size
= sizeof (buffer
);
1729 if ((ret
= gnutls_x509_privkey_get_key_id (key
, 0, buffer
, &size
)) < 0)
1731 fprintf (stderr
, "Error in key id calculation: %s\n",
1732 gnutls_strerror (ret
));
1736 fprintf (outfile
, "Public Key ID: %s\n", raw_to_string (buffer
, size
));
1739 if (info
.fix_key
!= 0)
1741 ret
= gnutls_x509_privkey_fix (key
);
1743 error (EXIT_FAILURE
, 0, "privkey_fix: %s", gnutls_strerror (ret
));
1746 size
= sizeof (buffer
);
1747 ret
= gnutls_x509_privkey_export (key
, GNUTLS_X509_FMT_PEM
, buffer
, &size
);
1749 error (EXIT_FAILURE
, 0, "export error: %s", gnutls_strerror (ret
));
1751 fprintf (outfile
, "\n%s\n", buffer
);
1753 gnutls_x509_privkey_deinit (key
);
1756 /* Load a public key.
1757 * @mand should be non zero if it is required to read a public key.
1760 load_pubkey (int mand
)
1762 gnutls_pubkey_t key
;
1767 if (!info
.pubkey
&& !mand
)
1770 if (info
.pubkey
== NULL
)
1771 error (EXIT_FAILURE
, 0, "missing --load-pubkey");
1773 ret
= gnutls_pubkey_init (&key
);
1775 error (EXIT_FAILURE
, 0, "privkey_init: %s", gnutls_strerror (ret
));
1777 dat
.data
= read_binary_file (info
.pubkey
, &size
);
1781 error (EXIT_FAILURE
, errno
, "reading --load-pubkey: %s", info
.pubkey
);
1783 ret
= gnutls_pubkey_import (key
, &dat
, info
.incert_format
);
1787 if (ret
== GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR
)
1789 error (EXIT_FAILURE
, 0,
1790 "import error: could not find a valid PEM header; "
1791 "check if your key has the PUBLIC KEY header");
1795 error (EXIT_FAILURE
, 0, "importing --load-pubkey: %s: %s",
1796 info
.pubkey
, gnutls_strerror (ret
));
1802 /* Load the private key.
1803 * @mand should be non zero if it is required to read a private key.
1805 gnutls_x509_privkey_t
1806 load_private_key (int mand
)
1808 gnutls_x509_privkey_t key
;
1813 if (!info
.privkey
&& !mand
)
1816 if (info
.privkey
== NULL
)
1817 error (EXIT_FAILURE
, 0, "missing --load-privkey");
1819 ret
= gnutls_x509_privkey_init (&key
);
1821 error (EXIT_FAILURE
, 0, "privkey_init: %s", gnutls_strerror (ret
));
1823 dat
.data
= read_binary_file (info
.privkey
, &size
);
1827 error (EXIT_FAILURE
, errno
, "reading --load-privkey: %s", info
.privkey
);
1831 const char *pass
= get_pass ();
1833 gnutls_x509_privkey_import_pkcs8 (key
, &dat
, info
.incert_format
,
1837 ret
= gnutls_x509_privkey_import (key
, &dat
, info
.incert_format
);
1841 if (ret
== GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR
)
1843 error (EXIT_FAILURE
, 0,
1844 "import error: could not find a valid PEM header; "
1845 "check if your key is PKCS #8 or PKCS #12 encoded");
1849 error (EXIT_FAILURE
, 0, "importing --load-privkey: %s: %s",
1850 info
.privkey
, gnutls_strerror (ret
));
1855 /* Load the Certificate Request.
1860 gnutls_x509_crq_t crq
;
1868 ret
= gnutls_x509_crq_init (&crq
);
1870 error (EXIT_FAILURE
, 0, "crq_init: %s", gnutls_strerror (ret
));
1872 dat
.data
= read_binary_file (info
.request
, &size
);
1876 error (EXIT_FAILURE
, errno
, "reading --load-request: %s", info
.request
);
1878 ret
= gnutls_x509_crq_import (crq
, &dat
, info
.incert_format
);
1879 if (ret
== GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR
)
1881 error (EXIT_FAILURE
, 0,
1882 "import error: could not find a valid PEM header");
1887 error (EXIT_FAILURE
, 0, "importing --load-request: %s: %s",
1888 info
.request
, gnutls_strerror (ret
));
1893 /* Load the CA's private key.
1895 gnutls_x509_privkey_t
1896 load_ca_private_key (void)
1898 gnutls_x509_privkey_t key
;
1903 if (info
.ca_privkey
== NULL
)
1904 error (EXIT_FAILURE
, 0, "missing --load-ca-privkey");
1906 ret
= gnutls_x509_privkey_init (&key
);
1908 error (EXIT_FAILURE
, 0, "privkey_init: %s", gnutls_strerror (ret
));
1910 dat
.data
= read_binary_file (info
.ca_privkey
, &size
);
1914 error (EXIT_FAILURE
, errno
, "reading --load-ca-privkey: %s",
1919 const char *pass
= get_pass ();
1921 gnutls_x509_privkey_import_pkcs8 (key
, &dat
, info
.incert_format
,
1925 ret
= gnutls_x509_privkey_import (key
, &dat
, info
.incert_format
);
1928 error (EXIT_FAILURE
, 0, "importing --load-ca-privkey: %s: %s",
1929 info
.ca_privkey
, gnutls_strerror (ret
));
1934 /* Loads the CA's certificate
1939 gnutls_x509_crt_t crt
;
1944 if (info
.ca
== NULL
)
1945 error (EXIT_FAILURE
, 0, "missing --load-ca-certificate");
1947 ret
= gnutls_x509_crt_init (&crt
);
1949 error (EXIT_FAILURE
, 0, "crt_init: %s", gnutls_strerror (ret
));
1951 dat
.data
= read_binary_file (info
.ca
, &size
);
1955 error (EXIT_FAILURE
, errno
, "reading --load-ca-certificate: %s", info
.ca
);
1957 ret
= gnutls_x509_crt_import (crt
, &dat
, info
.incert_format
);
1960 error (EXIT_FAILURE
, 0, "importing --load-ca-certificate: %s: %s",
1961 info
.ca
, gnutls_strerror (ret
));
1966 /* Loads the certificate
1967 * If mand is non zero then a certificate is mandatory. Otherwise
1968 * null will be returned if the certificate loading fails.
1971 load_cert (int mand
)
1973 gnutls_x509_crt_t
*crt
;
1976 crt
= load_cert_list (mand
, &size
);
1978 return crt
? crt
[0] : NULL
;
1981 #define MAX_CERTS 256
1983 /* Loads a certificate list
1986 load_cert_list (int mand
, size_t * crt_size
)
1989 static gnutls_x509_crt_t crt
[MAX_CERTS
];
1997 fprintf (stderr
, "Loading certificate list...\n");
1999 if (info
.cert
== NULL
)
2002 error (EXIT_FAILURE
, 0, "missing --load-certificate");
2007 fd
= fopen (info
.cert
, "r");
2009 error (EXIT_FAILURE
, errno
, "%s", info
.cert
);
2011 size
= fread (buffer
, 1, sizeof (buffer
) - 1, fd
);
2019 for (i
= 0; i
< MAX_CERTS
; i
++)
2021 ret
= gnutls_x509_crt_init (&crt
[i
]);
2023 error (EXIT_FAILURE
, 0, "crt_init: %s", gnutls_strerror (ret
));
2026 dat
.size
= ptr_size
;
2028 ret
= gnutls_x509_crt_import (crt
[i
], &dat
, info
.incert_format
);
2029 if (ret
< 0 && *crt_size
> 0)
2032 error (EXIT_FAILURE
, 0, "crt_import: %s", gnutls_strerror (ret
));
2034 ptr
= strstr (ptr
, "---END");
2041 (unsigned int) ((unsigned char *) ptr
- (unsigned char *) buffer
);
2048 fprintf (stderr
, "Loaded %d certificates.\n", (int) *crt_size
);
2054 /* Generate a PKCS #10 certificate request.
2057 generate_request (void)
2059 gnutls_x509_crq_t crq
;
2060 gnutls_x509_privkey_t key
;
2061 int ret
, ca_status
, path_len
;
2063 unsigned int usage
= 0;
2065 fprintf (stderr
, "Generating a PKCS #10 certificate request...\n");
2067 ret
= gnutls_x509_crq_init (&crq
);
2069 error (EXIT_FAILURE
, 0, "crq_init: %s", gnutls_strerror (ret
));
2071 /* Load the private key.
2073 key
= load_private_key (0);
2076 key
= generate_private_key_int ();
2078 print_private_key (key
);
2083 get_country_crq_set (crq
);
2084 get_organization_crq_set (crq
);
2085 get_unit_crq_set (crq
);
2086 get_locality_crq_set (crq
);
2087 get_state_crq_set (crq
);
2088 get_cn_crq_set (crq
);
2089 get_uid_crq_set (crq
);
2090 get_oid_crq_set (crq
);
2092 get_dns_name_set (TYPE_CRQ
, crq
);
2093 get_ip_addr_set (TYPE_CRQ
, crq
);
2094 get_email_set (TYPE_CRQ
, crq
);
2096 pass
= get_challenge_pass ();
2098 if (pass
!= NULL
&& pass
[0] != 0)
2100 ret
= gnutls_x509_crq_set_challenge_password (crq
, pass
);
2102 error (EXIT_FAILURE
, 0, "set_pass: %s", gnutls_strerror (ret
));
2105 if (info
.crq_extensions
!= 0)
2107 ca_status
= get_ca_status ();
2109 path_len
= get_path_len ();
2113 ret
= gnutls_x509_crq_set_basic_constraints (crq
, ca_status
, path_len
);
2115 error (EXIT_FAILURE
, 0, "set_basic_constraints: %s",
2116 gnutls_strerror (ret
));
2118 ret
= get_sign_status (1);
2120 usage
|= GNUTLS_KEY_DIGITAL_SIGNATURE
;
2122 ret
= get_encrypt_status (1);
2124 usage
|= GNUTLS_KEY_KEY_ENCIPHERMENT
;
2126 usage
|= GNUTLS_KEY_DIGITAL_SIGNATURE
;
2130 ret
= get_cert_sign_status ();
2132 usage
|= GNUTLS_KEY_KEY_CERT_SIGN
;
2134 ret
= get_crl_sign_status ();
2136 usage
|= GNUTLS_KEY_CRL_SIGN
;
2138 ret
= get_code_sign_status ();
2141 ret
= gnutls_x509_crq_set_key_purpose_oid
2142 (crq
, GNUTLS_KP_CODE_SIGNING
, 0);
2144 error (EXIT_FAILURE
, 0, "key_kp: %s", gnutls_strerror (ret
));
2147 ret
= get_ocsp_sign_status ();
2150 ret
= gnutls_x509_crq_set_key_purpose_oid
2151 (crq
, GNUTLS_KP_OCSP_SIGNING
, 0);
2153 error (EXIT_FAILURE
, 0, "key_kp: %s", gnutls_strerror (ret
));
2156 ret
= get_time_stamp_status ();
2159 ret
= gnutls_x509_crq_set_key_purpose_oid
2160 (crq
, GNUTLS_KP_TIME_STAMPING
, 0);
2162 error (EXIT_FAILURE
, 0, "key_kp: %s", gnutls_strerror (ret
));
2166 ret
= gnutls_x509_crq_set_key_usage (crq
, usage
);
2168 error (EXIT_FAILURE
, 0, "key_usage: %s", gnutls_strerror (ret
));
2170 ret
= get_tls_client_status ();
2173 ret
= gnutls_x509_crq_set_key_purpose_oid
2174 (crq
, GNUTLS_KP_TLS_WWW_CLIENT
, 0);
2176 error (EXIT_FAILURE
, 0, "key_kp: %s", gnutls_strerror (ret
));
2179 ret
= get_tls_server_status ();
2182 ret
= gnutls_x509_crq_set_key_purpose_oid
2183 (crq
, GNUTLS_KP_TLS_WWW_SERVER
, 0);
2185 error (EXIT_FAILURE
, 0, "key_kp: %s", gnutls_strerror (ret
));
2189 ret
= gnutls_x509_crq_set_key (crq
, key
);
2191 error (EXIT_FAILURE
, 0, "set_key: %s", gnutls_strerror (ret
));
2193 ret
= gnutls_x509_crq_sign (crq
, key
);
2195 error (EXIT_FAILURE
, 0, "sign: %s", gnutls_strerror (ret
));
2197 print_crq_info (crq
, outfile
);
2199 gnutls_x509_crq_deinit (crq
);
2200 gnutls_x509_privkey_deinit (key
);
2204 static void print_verification_res (gnutls_x509_crt_t crt
,
2205 gnutls_x509_crt_t issuer
,
2206 gnutls_x509_crl_t
* crl_list
,
2207 int crl_list_size
, unsigned int flags
);
2209 #define CERT_SEP "-----BEGIN CERT"
2210 #define CRL_SEP "-----BEGIN X509 CRL"
2212 _verify_x509_mem (const void *cert
, int cert_size
)
2217 char issuer_name
[256];
2219 size_t issuer_name_size
;
2221 gnutls_x509_crt_t
*x509_cert_list
= NULL
;
2222 gnutls_x509_crl_t
*x509_crl_list
= NULL
;
2223 int x509_ncerts
, x509_ncrls
;
2226 /* Decode the CA certificate
2229 /* Decode the CRL list
2235 if (strstr (ptr
, CRL_SEP
) != NULL
) /* if CRLs exist */
2239 (gnutls_x509_crl_t
*) realloc (x509_crl_list
,
2240 i
* sizeof (gnutls_x509_crl_t
));
2241 if (x509_crl_list
== NULL
)
2242 error (EXIT_FAILURE
, 0, "memory error");
2244 tmp
.data
= (char *) ptr
;
2245 tmp
.size
= cert_size
;
2247 (unsigned int) ((unsigned char *) ptr
- (unsigned char *) cert
);
2249 ret
= gnutls_x509_crl_init (&x509_crl_list
[i
- 1]);
2251 error (EXIT_FAILURE
, 0, "error parsing CRL[%d]: %s", i
,
2252 gnutls_strerror (ret
));
2254 ret
= gnutls_x509_crl_import (x509_crl_list
[i
- 1], &tmp
,
2255 GNUTLS_X509_FMT_PEM
);
2257 error (EXIT_FAILURE
, 0, "error parsing CRL[%d]: %s", i
,
2258 gnutls_strerror (ret
));
2260 /* now we move ptr after the pem header */
2261 ptr
= strstr (ptr
, CRL_SEP
);
2267 while ((ptr
= strstr (ptr
, CRL_SEP
)) != NULL
);
2272 /* Decode the certificate chain.
2281 (gnutls_x509_crt_t
*) realloc (x509_cert_list
,
2282 i
* sizeof (gnutls_x509_crt_t
));
2283 if (x509_cert_list
== NULL
)
2284 error (EXIT_FAILURE
, 0, "memory error");
2287 tmp
.data
= (char *) ptr
;
2288 tmp
.size
= cert_size
;
2290 (unsigned int) ((unsigned char *) ptr
- (unsigned char *) cert
);
2292 ret
= gnutls_x509_crt_init (&x509_cert_list
[i
- 1]);
2294 error (EXIT_FAILURE
, 0, "error parsing certificate[%d]: %s", i
,
2295 gnutls_strerror (ret
));
2298 gnutls_x509_crt_import (x509_cert_list
[i
- 1], &tmp
,
2299 GNUTLS_X509_FMT_PEM
);
2301 error (EXIT_FAILURE
, 0, "error parsing certificate[%d]: %s", i
,
2302 gnutls_strerror (ret
));
2307 /* verify the previous certificate using this one
2311 name_size
= sizeof (name
);
2313 gnutls_x509_crt_get_dn (x509_cert_list
[i
- 2], name
, &name_size
);
2315 error (EXIT_FAILURE
, 0, "get_dn: %s", gnutls_strerror (ret
));
2317 fprintf (outfile
, "Certificate[%d]: %s\n", i
- 2, name
);
2321 issuer_name_size
= sizeof (issuer_name
);
2323 gnutls_x509_crt_get_issuer_dn (x509_cert_list
[i
- 2],
2324 issuer_name
, &issuer_name_size
);
2326 error (EXIT_FAILURE
, 0, "get_issuer_dn: %s",
2327 gnutls_strerror (ret
));
2329 fprintf (outfile
, "\tIssued by: %s\n", issuer_name
);
2331 /* Get the Issuer's name
2333 name_size
= sizeof (name
);
2335 gnutls_x509_crt_get_dn (x509_cert_list
[i
- 1], name
, &name_size
);
2337 error (EXIT_FAILURE
, 0, "get_dn: %s", gnutls_strerror (ret
));
2339 fprintf (outfile
, "\tVerifying against certificate[%d].\n", i
- 1);
2341 if (strcmp (issuer_name
, name
) != 0)
2343 fprintf (stderr
, "Error: Issuer's name: %s\n", name
);
2344 error (EXIT_FAILURE
, 0,
2345 "issuer name does not match the next certificate");
2348 fprintf (outfile
, "\tVerification output: ");
2349 print_verification_res (x509_cert_list
[i
- 2],
2350 x509_cert_list
[i
- 1], x509_crl_list
,
2352 GNUTLS_VERIFY_DO_NOT_ALLOW_SAME
);
2353 fprintf (outfile
, ".\n\n");
2358 /* now we move ptr after the pem header
2360 ptr
= strstr (ptr
, CERT_SEP
);
2366 while ((ptr
= strstr (ptr
, CERT_SEP
)) != NULL
);
2368 x509_ncerts
= i
- 1;
2370 /* The last certificate in the list will be used as
2371 * a CA (should be self signed).
2373 name_size
= sizeof (name
);
2374 ret
= gnutls_x509_crt_get_dn (x509_cert_list
[x509_ncerts
- 1], name
,
2377 error (EXIT_FAILURE
, 0, "get_dn: %s", gnutls_strerror (ret
));
2379 fprintf (outfile
, "Certificate[%d]: %s\n", x509_ncerts
- 1, name
);
2383 issuer_name_size
= sizeof (issuer_name
);
2385 gnutls_x509_crt_get_issuer_dn (x509_cert_list
[x509_ncerts
- 1],
2386 issuer_name
, &issuer_name_size
);
2388 error (EXIT_FAILURE
, 0, "get_issuer_dn: %s", gnutls_strerror (ret
));
2390 fprintf (outfile
, "\tIssued by: %s\n", name
);
2392 if (strcmp (issuer_name
, name
) != 0)
2393 error (EXIT_FAILURE
, 0, "the last certificate is not self signed");
2395 fprintf (outfile
, "\tVerification output: ");
2396 print_verification_res (x509_cert_list
[x509_ncerts
- 1],
2397 x509_cert_list
[x509_ncerts
- 1], x509_crl_list
,
2398 /* we add GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT since it is
2401 GNUTLS_VERIFY_DO_NOT_ALLOW_SAME
|
2402 GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT
);
2404 fprintf (outfile
, ".\n\n");
2406 /* Verify using internal algorithm too. */
2410 ret
= gnutls_x509_crt_list_verify (x509_cert_list
, x509_ncerts
,
2411 &x509_cert_list
[x509_ncerts
- 1], 1,
2414 GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT
|
2415 GNUTLS_VERIFY_DO_NOT_ALLOW_SAME
,
2418 error (EXIT_FAILURE
, 0, "gnutls_x509_crt_list_verify: %s",
2419 gnutls_strerror (ret
));
2421 fprintf (outfile
, "Chain verification output: ");
2423 if (verify_status
& GNUTLS_CERT_INVALID
)
2425 fprintf (outfile
, "Not verified");
2429 fprintf (outfile
, "Verified");
2432 if (verify_status
& GNUTLS_CERT_SIGNER_NOT_CA
)
2434 fprintf (outfile
, ", ");
2435 fprintf (outfile
, "Issuer is not a CA");
2438 if (verify_status
& GNUTLS_CERT_INSECURE_ALGORITHM
)
2440 fprintf (outfile
, ", ");
2441 fprintf (outfile
, "Insecure algorithm");
2444 fprintf (outfile
, ".\n");
2447 for (i
= 0; i
< x509_ncerts
; i
++)
2448 gnutls_x509_crt_deinit (x509_cert_list
[i
]);
2450 for (i
= 0; i
< x509_ncrls
; i
++)
2451 gnutls_x509_crl_deinit (x509_crl_list
[i
]);
2453 free (x509_cert_list
);
2454 free (x509_crl_list
);
2457 error (EXIT_FAILURE
, 0, "verification error: %s", gnutls_strerror (ret
));
2463 print_verification_res (gnutls_x509_crt_t crt
,
2464 gnutls_x509_crt_t issuer
,
2465 gnutls_x509_crl_t
* crl_list
, int crl_list_size
,
2468 unsigned int output
;
2472 ret
= gnutls_x509_crt_verify (crt
, &issuer
, 1, flags
, &output
);
2474 error (EXIT_FAILURE
, 0, "verification error: %s", gnutls_strerror (ret
));
2476 if (output
& GNUTLS_CERT_INVALID
)
2478 fprintf (outfile
, "Not verified");
2483 fprintf (outfile
, "Verified");
2487 if (output
& GNUTLS_CERT_SIGNER_NOT_CA
)
2490 fprintf (outfile
, ", ");
2491 fprintf (outfile
, "Issuer is not a CA");
2495 if (output
& GNUTLS_CERT_INSECURE_ALGORITHM
)
2498 fprintf (outfile
, ", ");
2499 fprintf (outfile
, "Insecure algorithm");
2503 if (output
& GNUTLS_CERT_NOT_ACTIVATED
)
2506 fprintf (outfile
, ", ");
2507 fprintf (outfile
, "Not activated");
2511 if (output
& GNUTLS_CERT_EXPIRED
)
2514 fprintf (outfile
, ", ");
2515 fprintf (outfile
, "Expired");
2519 ret
= gnutls_x509_crt_check_revocation (crt
, crl_list
, crl_list_size
);
2521 error (EXIT_FAILURE
, 0, "revocation check: %s", gnutls_strerror (ret
));
2526 fprintf (outfile
, ", ");
2528 fprintf (outfile
, "Revoked");
2538 buf
= fread_file (infile
, &size
);
2540 error (EXIT_FAILURE
, errno
, "reading chain");
2544 _verify_x509_mem (buf
, size
);
2551 size_t size
, dn_size
;
2553 unsigned int output
;
2557 gnutls_x509_crl_t crl
;
2558 time_t now
= time (0);
2559 gnutls_x509_crt_t issuer
;
2561 issuer
= load_ca_cert ();
2563 fprintf (outfile
, "\nCA certificate:\n");
2565 dn_size
= sizeof (dn
);
2566 ret
= gnutls_x509_crt_get_dn (issuer
, dn
, &dn_size
);
2568 error (EXIT_FAILURE
, 0, "crt_get_dn: %s", gnutls_strerror (ret
));
2570 fprintf (outfile
, "\tSubject: %s\n\n", dn
);
2572 ret
= gnutls_x509_crl_init (&crl
);
2574 error (EXIT_FAILURE
, 0, "crl_init: %s", gnutls_strerror (ret
));
2576 pem
.data
= fread_file (infile
, &size
);
2579 ret
= gnutls_x509_crl_import (crl
, &pem
, info
.incert_format
);
2582 error (EXIT_FAILURE
, 0, "import error: %s", gnutls_strerror (ret
));
2584 print_crl_info (crl
, outfile
);
2586 fprintf (outfile
, "Verification output: ");
2587 ret
= gnutls_x509_crl_verify (crl
, &issuer
, 1, 0, &output
);
2589 error (EXIT_FAILURE
, 0, "verification error: %s", gnutls_strerror (ret
));
2591 if (output
& GNUTLS_CERT_INVALID
)
2593 fprintf (outfile
, "Not verified");
2598 fprintf (outfile
, "Verified");
2602 if (output
& GNUTLS_CERT_SIGNER_NOT_CA
)
2605 fprintf (outfile
, ", ");
2606 fprintf (outfile
, "Issuer is not a CA");
2610 if (output
& GNUTLS_CERT_INSECURE_ALGORITHM
)
2613 fprintf (outfile
, ", ");
2614 fprintf (outfile
, "Insecure algorithm");
2618 /* Check expiration dates.
2621 if (gnutls_x509_crl_get_this_update (crl
) > now
)
2624 fprintf (outfile
, ", ");
2626 fprintf (outfile
, "Issued in the future!");
2629 if (gnutls_x509_crl_get_next_update (crl
) < now
)
2632 fprintf (outfile
, ", ");
2634 fprintf (outfile
, "CRL is not up to date");
2637 fprintf (outfile
, "\n");
2642 generate_pkcs8 (void)
2644 gnutls_x509_privkey_t key
;
2648 const char *password
;
2650 fprintf (stderr
, "Generating a PKCS #8 key structure...\n");
2652 key
= load_private_key (1);
2655 password
= info
.pass
;
2657 password
= get_pass ();
2660 flags
= GNUTLS_PKCS_USE_PKCS12_RC2_40
;
2662 flags
= cipher_to_flags (info
.pkcs_cipher
);
2664 if (password
== NULL
|| password
[0] == 0)
2666 flags
= GNUTLS_PKCS_PLAIN
;
2669 size
= sizeof (buffer
);
2671 gnutls_x509_privkey_export_pkcs8 (key
, info
.outcert_format
,
2672 password
, flags
, buffer
, &size
);
2675 error (EXIT_FAILURE
, 0, "key_export: %s", gnutls_strerror (result
));
2677 fwrite (buffer
, 1, size
, outfile
);
2682 #include <gnutls/pkcs12.h>
2686 generate_pkcs12 (void)
2688 gnutls_pkcs12_t pkcs12
;
2689 gnutls_x509_crt_t
*crts
;
2690 gnutls_x509_privkey_t key
;
2693 gnutls_datum_t data
;
2696 unsigned int flags
, i
;
2697 gnutls_datum_t key_id
;
2698 unsigned char _key_id
[20];
2702 fprintf (stderr
, "Generating a PKCS #12 structure...\n");
2704 key
= load_private_key (0);
2705 crts
= load_cert_list (0, &ncrts
);
2707 name
= get_pkcs12_key_name ();
2709 result
= gnutls_pkcs12_init (&pkcs12
);
2711 error (EXIT_FAILURE
, 0, "pkcs12_init: %s", gnutls_strerror (result
));
2718 for (i
= 0; i
< ncrts
; i
++)
2720 gnutls_pkcs12_bag_t bag
;
2722 result
= gnutls_pkcs12_bag_init (&bag
);
2724 error (EXIT_FAILURE
, 0, "bag_init: %s", gnutls_strerror (result
));
2726 result
= gnutls_pkcs12_bag_set_crt (bag
, crts
[i
]);
2728 error (EXIT_FAILURE
, 0, "set_crt[%d]: %s", i
,
2729 gnutls_strerror (result
));
2733 result
= gnutls_pkcs12_bag_set_friendly_name (bag
, indx
, name
);
2735 error (EXIT_FAILURE
, 0, "bag_set_friendly_name: %s",
2736 gnutls_strerror (result
));
2738 size
= sizeof (_key_id
);
2739 result
= gnutls_x509_crt_get_key_id (crts
[i
], 0, _key_id
, &size
);
2741 error (EXIT_FAILURE
, 0, "key_id[%d]: %s", i
,
2742 gnutls_strerror (result
));
2744 key_id
.data
= _key_id
;
2747 result
= gnutls_pkcs12_bag_set_key_id (bag
, indx
, &key_id
);
2749 error (EXIT_FAILURE
, 0, "bag_set_key_id: %s",
2750 gnutls_strerror (result
));
2753 flags
= GNUTLS_PKCS_USE_PKCS12_RC2_40
;
2755 flags
= cipher_to_flags (info
.pkcs_cipher
);
2757 result
= gnutls_pkcs12_bag_encrypt (bag
, pass
, flags
);
2759 error (EXIT_FAILURE
, 0, "bag_encrypt: %s", gnutls_strerror (result
));
2761 result
= gnutls_pkcs12_set_bag (pkcs12
, bag
);
2763 error (EXIT_FAILURE
, 0, "set_bag: %s", gnutls_strerror (result
));
2768 gnutls_pkcs12_bag_t kbag
;
2770 result
= gnutls_pkcs12_bag_init (&kbag
);
2772 error (EXIT_FAILURE
, 0, "bag_init: %s", gnutls_strerror (result
));
2775 flags
= GNUTLS_PKCS_USE_PKCS12_RC2_40
;
2777 flags
= cipher_to_flags (info
.pkcs_cipher
);
2779 size
= sizeof (buffer
);
2781 gnutls_x509_privkey_export_pkcs8 (key
, GNUTLS_X509_FMT_DER
,
2782 pass
, flags
, buffer
, &size
);
2784 error (EXIT_FAILURE
, 0, "key_export: %s", gnutls_strerror (result
));
2789 gnutls_pkcs12_bag_set_data (kbag
,
2790 GNUTLS_BAG_PKCS8_ENCRYPTED_KEY
, &data
);
2792 error (EXIT_FAILURE
, 0, "bag_set_data: %s", gnutls_strerror (result
));
2796 result
= gnutls_pkcs12_bag_set_friendly_name (kbag
, indx
, name
);
2798 error (EXIT_FAILURE
, 0, "bag_set_friendly_name: %s",
2799 gnutls_strerror (result
));
2801 size
= sizeof (_key_id
);
2802 result
= gnutls_x509_privkey_get_key_id (key
, 0, _key_id
, &size
);
2804 error (EXIT_FAILURE
, 0, "key_id: %s", gnutls_strerror (result
));
2806 key_id
.data
= _key_id
;
2809 result
= gnutls_pkcs12_bag_set_key_id (kbag
, indx
, &key_id
);
2811 error (EXIT_FAILURE
, 0, "bag_set_key_id: %s",
2812 gnutls_strerror (result
));
2814 result
= gnutls_pkcs12_set_bag (pkcs12
, kbag
);
2816 error (EXIT_FAILURE
, 0, "set_bag: %s", gnutls_strerror (result
));
2819 result
= gnutls_pkcs12_generate_mac (pkcs12
, pass
);
2821 error (EXIT_FAILURE
, 0, "generate_mac: %s", gnutls_strerror (result
));
2823 size
= sizeof (buffer
);
2824 result
= gnutls_pkcs12_export (pkcs12
, info
.outcert_format
, buffer
, &size
);
2826 error (EXIT_FAILURE
, 0, "pkcs12_export: %s", gnutls_strerror (result
));
2828 fwrite (buffer
, 1, size
, outfile
);
2833 BAGTYPE (gnutls_pkcs12_bag_type_t x
)
2837 case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY
:
2838 return "PKCS #8 Encrypted key";
2839 case GNUTLS_BAG_EMPTY
:
2841 case GNUTLS_BAG_PKCS8_KEY
:
2842 return "PKCS #8 Key";
2843 case GNUTLS_BAG_CERTIFICATE
:
2844 return "Certificate";
2845 case GNUTLS_BAG_ENCRYPTED
:
2847 case GNUTLS_BAG_CRL
:
2849 case GNUTLS_BAG_SECRET
:
2857 print_bag_data (gnutls_pkcs12_bag_t bag
)
2861 gnutls_datum_t cdata
, id
;
2862 const char *str
, *name
;
2865 count
= gnutls_pkcs12_bag_get_count (bag
);
2867 error (EXIT_FAILURE
, 0, "get_count: %s", gnutls_strerror (count
));
2869 fprintf (outfile
, "\tElements: %d\n", count
);
2871 for (i
= 0; i
< count
; i
++)
2873 type
= gnutls_pkcs12_bag_get_type (bag
, i
);
2875 error (EXIT_FAILURE
, 0, "get_type: %s", gnutls_strerror (type
));
2877 fprintf (stderr
, "\tType: %s\n", BAGTYPE (type
));
2880 result
= gnutls_pkcs12_bag_get_friendly_name (bag
, i
, (char **) &name
);
2882 error (EXIT_FAILURE
, 0, "get_friendly_name: %s",
2883 gnutls_strerror (type
));
2885 fprintf (outfile
, "\tFriendly name: %s\n", name
);
2889 result
= gnutls_pkcs12_bag_get_key_id (bag
, i
, &id
);
2891 error (EXIT_FAILURE
, 0, "get_key_id: %s", gnutls_strerror (type
));
2892 fprintf (outfile
, "\tKey ID: %s\n", raw_to_string (id
.data
, id
.size
));
2894 result
= gnutls_pkcs12_bag_get_data (bag
, i
, &cdata
);
2896 error (EXIT_FAILURE
, 0, "get_data: %s", gnutls_strerror (result
));
2900 case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY
:
2901 str
= "ENCRYPTED PRIVATE KEY";
2903 case GNUTLS_BAG_PKCS8_KEY
:
2904 str
= "PRIVATE KEY";
2906 case GNUTLS_BAG_CERTIFICATE
:
2907 str
= "CERTIFICATE";
2909 case GNUTLS_BAG_CRL
:
2912 case GNUTLS_BAG_ENCRYPTED
:
2913 case GNUTLS_BAG_EMPTY
:
2920 gnutls_pem_base64_encode_alloc (str
, &cdata
, &out
);
2921 fprintf (outfile
, "%s\n", out
.data
);
2923 gnutls_free (out
.data
);
2932 gnutls_pkcs12_t pkcs12
;
2933 gnutls_pkcs12_bag_t bag
;
2936 gnutls_datum_t data
;
2940 result
= gnutls_pkcs12_init (&pkcs12
);
2942 error (EXIT_FAILURE
, 0, "p12_init: %s", gnutls_strerror (result
));
2944 data
.data
= fread_file (infile
, &size
);
2947 result
= gnutls_pkcs12_import (pkcs12
, &data
, info
.incert_format
, 0);
2950 error (EXIT_FAILURE
, 0, "p12_import: %s", gnutls_strerror (result
));
2957 result
= gnutls_pkcs12_verify_mac (pkcs12
, pass
);
2959 error (0, 0, "verify_mac: %s", gnutls_strerror (result
));
2961 for (indx
= 0;; indx
++)
2963 result
= gnutls_pkcs12_bag_init (&bag
);
2965 error (EXIT_FAILURE
, 0, "bag_init: %s", gnutls_strerror (result
));
2967 result
= gnutls_pkcs12_get_bag (pkcs12
, indx
, bag
);
2971 result
= gnutls_pkcs12_bag_get_count (bag
);
2973 error (EXIT_FAILURE
, 0, "bag_count: %s", gnutls_strerror (result
));
2975 fprintf (outfile
, "BAG #%d\n", indx
);
2977 result
= gnutls_pkcs12_bag_get_type (bag
, 0);
2979 error (EXIT_FAILURE
, 0, "bag_init: %s", gnutls_strerror (result
));
2981 if (result
== GNUTLS_BAG_ENCRYPTED
)
2983 fprintf (stderr
, "\tType: %s\n", BAGTYPE (result
));
2984 fprintf (stderr
, "\n\tDecrypting...\n");
2986 result
= gnutls_pkcs12_bag_decrypt (bag
, pass
);
2990 error (0, 0, "bag_decrypt: %s", gnutls_strerror (result
));
2994 result
= gnutls_pkcs12_bag_get_count (bag
);
2996 error (EXIT_FAILURE
, 0, "encrypted bag_count: %s",
2997 gnutls_strerror (result
));
3000 print_bag_data (bag
);
3002 gnutls_pkcs12_bag_deinit (bag
);
3009 gnutls_pkcs7_t pkcs7
;
3012 gnutls_datum_t data
, b64
;
3015 result
= gnutls_pkcs7_init (&pkcs7
);
3017 error (EXIT_FAILURE
, 0, "p7_init: %s", gnutls_strerror (result
));
3019 data
.data
= fread_file (infile
, &size
);
3022 result
= gnutls_pkcs7_import (pkcs7
, &data
, info
.incert_format
);
3025 error (EXIT_FAILURE
, 0, "import error: %s", gnutls_strerror (result
));
3027 /* Read and print the certificates.
3029 result
= gnutls_pkcs7_get_crt_count (pkcs7
);
3031 error (EXIT_FAILURE
, 0, "p7_crt_count: %s", gnutls_strerror (result
));
3036 fprintf (outfile
, "Number of certificates: %u\n", count
);
3038 for (indx
= 0; indx
< count
; indx
++)
3040 fputs ("\n", outfile
);
3042 size
= sizeof (buffer
);
3043 result
= gnutls_pkcs7_get_crt_raw (pkcs7
, indx
, buffer
, &size
);
3050 result
= gnutls_pem_base64_encode_alloc ("CERTIFICATE", &data
, &b64
);
3052 error (EXIT_FAILURE
, 0, "encoding: %s", gnutls_strerror (result
));
3054 fputs (b64
.data
, outfile
);
3055 gnutls_free (b64
.data
);
3058 /* Read the CRLs now.
3060 result
= gnutls_pkcs7_get_crl_count (pkcs7
);
3062 error (EXIT_FAILURE
, 0, "p7_crl_count: %s", gnutls_strerror (result
));
3067 fprintf (outfile
, "\nNumber of CRLs: %u\n", count
);
3069 for (indx
= 0; indx
< count
; indx
++)
3071 fputs ("\n", outfile
);
3073 size
= sizeof (buffer
);
3074 result
= gnutls_pkcs7_get_crl_raw (pkcs7
, indx
, buffer
, &size
);
3081 result
= gnutls_pem_base64_encode_alloc ("X509 CRL", &data
, &b64
);
3083 error (EXIT_FAILURE
, 0, "encoding: %s", gnutls_strerror (result
));
3085 fputs (b64
.data
, outfile
);
3086 gnutls_free (b64
.data
);
3091 smime_to_pkcs7 (void)
3093 size_t linesize
= 0;
3094 char *lineptr
= NULL
;
3097 /* Find body. FIXME: Handle non-b64 Content-Transfer-Encoding.
3098 Reject non-S/MIME tagged Content-Type's? */
3101 len
= getline (&lineptr
, &linesize
, infile
);
3103 error (EXIT_FAILURE
, 0, "cannot find RFC 2822 header/body separator");
3105 while (strcmp (lineptr
, "\r\n") != 0 && strcmp (lineptr
, "\n") != 0);
3109 len
= getline (&lineptr
, &linesize
, infile
);
3111 error (EXIT_FAILURE
, 0, "message has RFC 2822 header but no body");
3113 while (strcmp (lineptr
, "\r\n") == 0 && strcmp (lineptr
, "\n") == 0);
3115 fprintf (outfile
, "%s", "-----BEGIN PKCS7-----\n");
3120 && (lineptr
[len
- 1] == '\r' || lineptr
[len
- 1] == '\n'))
3121 lineptr
[--len
] = '\0';
3122 if (strcmp (lineptr
, "") != 0)
3123 fprintf (outfile
, "%s\n", lineptr
);
3124 len
= getline (&lineptr
, &linesize
, infile
);
3128 fprintf (outfile
, "%s", "-----END PKCS7-----\n");
3134 certtool_version (void)
3136 const char *p
= PACKAGE_NAME
;
3137 if (strcmp (gnutls_check_version (NULL
), PACKAGE_VERSION
) != 0)
3139 version_etc (stdout
, program_name
, p
, gnutls_check_version (NULL
),
3140 "Nikos Mavrogiannopoulos", "Simon Josefsson", (char *) NULL
);
3143 static void print_key_usage(FILE* outfile
, unsigned int usage
)
3145 if (usage
& GNUTLS_KEY_DIGITAL_SIGNATURE
) {
3146 fprintf(outfile
, "\tDigital signature.\n");
3149 if (usage
& GNUTLS_KEY_NON_REPUDIATION
) {
3150 fprintf(outfile
, "\tNon repudiation.\n");
3153 if (usage
& GNUTLS_KEY_KEY_ENCIPHERMENT
) {
3154 fprintf(outfile
, "\tKey encipherment.\n");
3157 if (usage
& GNUTLS_KEY_DATA_ENCIPHERMENT
) {
3158 fprintf(outfile
, "\tData encipherment.\n");
3161 if (usage
& GNUTLS_KEY_KEY_AGREEMENT
) {
3162 fprintf(outfile
, "\tKey agreement.\n");
3165 if (usage
& GNUTLS_KEY_KEY_CERT_SIGN
) {
3166 fprintf(outfile
, "\tCertificate signing.\n");
3169 if (usage
& GNUTLS_KEY_NON_REPUDIATION
) {
3170 fprintf(outfile
, "\tCRL signing.\n");
3173 if (usage
& GNUTLS_KEY_ENCIPHER_ONLY
) {
3174 fprintf(outfile
, "\tKey encipher only.\n");
3177 if (usage
& GNUTLS_KEY_DECIPHER_ONLY
) {
3178 fprintf(outfile
, "\tKey decipher only.\n");
3182 void pubkey_info (gnutls_x509_crt crt
)
3184 gnutls_pubkey_t pubkey
;
3185 unsigned int bits
, usage
;
3190 ret
= gnutls_pubkey_init(&pubkey
);
3192 error (EXIT_FAILURE
, 0, "pubkey_init: %s", gnutls_strerror (ret
));
3200 ret
= gnutls_pubkey_import_x509(pubkey
, crt
, 0);
3202 error (EXIT_FAILURE
, 0, "pubkey_import_x509: %s", gnutls_strerror (ret
));
3205 pubkey
= load_pubkey(1);
3208 fprintf (outfile
, "Public Key Info:\n\n");
3209 ret
= gnutls_pubkey_get_pk_algorithm (pubkey
, &bits
);
3210 fprintf (outfile
, "Public Key Algorithm: ");
3212 cprint
= gnutls_pk_algorithm_get_name (ret
);
3213 fprintf (outfile
, "%s (%u bits)\n", cprint
? cprint
: "Unknown", bits
);
3216 /* Print the raw public and private keys
3218 if (ret
== GNUTLS_PK_RSA
)
3220 gnutls_datum_t m
, e
;
3222 ret
= gnutls_pubkey_get_pk_rsa_raw (pubkey
, &m
, &e
);
3224 fprintf (stderr
, "Error in key RSA data export: %s\n",
3225 gnutls_strerror (ret
));
3228 print_rsa_pkey (&m
, &e
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
3229 gnutls_free (m
.data
);
3230 gnutls_free (e
.data
);
3233 else if (ret
== GNUTLS_PK_DSA
)
3235 gnutls_datum_t p
, q
, g
, y
;
3237 ret
= gnutls_pubkey_get_pk_dsa_raw (pubkey
, &p
, &q
, &g
, &y
);
3239 fprintf (stderr
, "Error in key DSA data export: %s\n",
3240 gnutls_strerror (ret
));
3243 print_dsa_pkey (NULL
, &y
, &p
, &q
, &g
);
3244 gnutls_free (y
.data
);
3245 gnutls_free (p
.data
);
3246 gnutls_free (q
.data
);
3247 gnutls_free (g
.data
);
3251 ret
= gnutls_pubkey_get_key_usage (pubkey
, &usage
);
3253 error (EXIT_FAILURE
, 0, "pubkey_get_key_usage: %s", gnutls_strerror (ret
));
3256 fprintf (outfile
, "Public Key Usage:\n");
3257 print_key_usage(outfile
, usage
);
3259 fprintf (outfile
, "\n");
3261 size
= sizeof (buffer
);
3262 if ((ret
= gnutls_pubkey_get_key_id (pubkey
, 0, buffer
, &size
)) < 0)
3264 fprintf (stderr
, "Error in key id calculation: %s\n",
3265 gnutls_strerror (ret
));
3269 fprintf (outfile
, "Public Key ID: %s\n", raw_to_string (buffer
, size
));
3272 size
= sizeof (buffer
);
3273 ret
= gnutls_pubkey_export (pubkey
, GNUTLS_X509_FMT_PEM
, buffer
, &size
);
3275 error (EXIT_FAILURE
, 0, "export error: %s", gnutls_strerror (ret
));
3277 fprintf (outfile
, "\n%s\n", buffer
);
3279 gnutls_pubkey_deinit (pubkey
);