2 * Copyright (C) 2003-2012 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/x509.h>
25 #include <gnutls/openpgp.h>
26 #include <gnutls/pkcs12.h>
27 #include <gnutls/pkcs11.h>
28 #include <gnutls/abstract.h>
37 #include <sys/types.h>
42 /* Gnulib portability files. */
43 #include <read-file.h>
45 #include <version-etc.h>
47 #include <certtool-cfg.h>
48 #include <p11common.h>
49 #include "certtool-args.h"
50 #include "certtool-common.h"
52 static void privkey_info_int (common_info_st
*, gnutls_x509_privkey_t key
);
53 static void print_crl_info (gnutls_x509_crl_t crl
, FILE * out
);
54 void pkcs7_info (void);
56 void smime_to_pkcs7 (void);
57 void pkcs12_info (common_info_st
*);
58 void generate_pkcs12 (common_info_st
*);
59 void generate_pkcs8 (common_info_st
*);
60 static void verify_chain (void);
61 void verify_crl (common_info_st
* cinfo
);
62 void pubkey_info (gnutls_x509_crt_t crt
, common_info_st
*);
63 void pgp_privkey_info (void);
64 void pgp_ring_info (void);
65 void certificate_info (int, common_info_st
*);
66 void pgp_certificate_info (void);
68 void privkey_info (common_info_st
*);
69 static void cmd_parser (int argc
, char **argv
);
70 void generate_self_signed (common_info_st
*);
71 void generate_request (common_info_st
*);
72 static void print_certificate_info (gnutls_x509_crt_t crt
, FILE * out
,
74 static void verify_certificate (common_info_st
* cinfo
);
76 static void print_hex_datum (gnutls_datum_t
* dat
);
80 static gnutls_digest_algorithm_t default_dig
;
81 static unsigned int incert_format
, outcert_format
;
82 static unsigned int req_key_type
;
84 /* non interactive operation if set
90 tls_log_func (int level
, const char *str
)
92 fprintf (stderr
, "|<%d>| %s", level
, str
);
96 main (int argc
, char **argv
)
98 set_program_name (argv
[0]);
100 cmd_parser (argc
, argv
);
106 raw_to_string (const unsigned char *raw
, size_t raw_size
)
108 static char buf
[1024];
113 if (raw_size
* 3 + 1 >= sizeof (buf
))
116 for (i
= 0; i
< raw_size
; i
++)
118 sprintf (&(buf
[i
* 3]), "%02X%s", raw
[i
],
119 (i
== raw_size
- 1) ? "" : ":");
121 buf
[sizeof (buf
) - 1] = '\0';
127 print_dsa_pkey (gnutls_datum_t
* x
, gnutls_datum_t
* y
, gnutls_datum_t
* p
,
128 gnutls_datum_t
* q
, gnutls_datum_t
* g
)
132 fprintf (outfile
, "private key:");
135 fprintf (outfile
, "public key:");
137 fprintf (outfile
, "p:");
139 fprintf (outfile
, "q:");
141 fprintf (outfile
, "g:");
146 print_ecc_pkey (gnutls_ecc_curve_t curve
, gnutls_datum_t
* k
, gnutls_datum_t
* x
, gnutls_datum_t
* y
)
148 fprintf (outfile
, "curve:\t%s\n", gnutls_ecc_curve_get_name(curve
));
151 fprintf (outfile
, "private key:");
154 fprintf (outfile
, "x:");
156 fprintf (outfile
, "y:");
161 print_rsa_pkey (gnutls_datum_t
* m
, gnutls_datum_t
* e
, gnutls_datum_t
* d
,
162 gnutls_datum_t
* p
, gnutls_datum_t
* q
, gnutls_datum_t
* u
,
163 gnutls_datum_t
* exp1
, gnutls_datum_t
* exp2
)
165 fprintf (outfile
, "modulus:");
167 fprintf (outfile
, "public exponent:");
171 fprintf (outfile
, "private exponent:");
173 fprintf (outfile
, "prime1:");
175 fprintf (outfile
, "prime2:");
177 fprintf (outfile
, "coefficient:");
181 fprintf (outfile
, "exp1:");
182 print_hex_datum (exp1
);
183 fprintf (outfile
, "exp2:");
184 print_hex_datum (exp2
);
189 static gnutls_x509_privkey_t
190 generate_private_key_int (common_info_st
* cinfo
)
192 gnutls_x509_privkey_t key
;
193 int ret
, key_type
, bits
;
195 key_type
= req_key_type
;
197 ret
= gnutls_x509_privkey_init (&key
);
199 error (EXIT_FAILURE
, 0, "privkey_init: %s", gnutls_strerror (ret
));
201 bits
= get_bits (key_type
, cinfo
->bits
, cinfo
->sec_param
);
203 fprintf (stderr
, "Generating a %d bit %s private key...\n",
204 bits
, gnutls_pk_algorithm_get_name (key_type
));
206 if (bits
> 1024 && key_type
== GNUTLS_PK_DSA
)
208 "Note that DSA keys with size over 1024 can only be used with TLS 1.2 or later.\n\n");
210 ret
= gnutls_x509_privkey_generate (key
, key_type
, bits
, 0);
212 error (EXIT_FAILURE
, 0, "privkey_generate: %s", gnutls_strerror (ret
));
214 ret
= gnutls_x509_privkey_verify_params (key
);
216 error (EXIT_FAILURE
, 0, "privkey_verify_params: %s", gnutls_strerror (ret
));
222 cipher_to_flags (const char *cipher
)
226 return GNUTLS_PKCS_USE_PBES2_AES_128
;
228 else if (strcasecmp (cipher
, "3des") == 0)
230 return GNUTLS_PKCS_USE_PBES2_3DES
;
232 else if (strcasecmp (cipher
, "3des-pkcs12") == 0)
234 return GNUTLS_PKCS_USE_PKCS12_3DES
;
236 else if (strcasecmp (cipher
, "arcfour") == 0)
238 return GNUTLS_PKCS_USE_PKCS12_ARCFOUR
;
240 else if (strcasecmp (cipher
, "aes-128") == 0)
242 return GNUTLS_PKCS_USE_PBES2_AES_128
;
244 else if (strcasecmp (cipher
, "aes-192") == 0)
246 return GNUTLS_PKCS_USE_PBES2_AES_192
;
248 else if (strcasecmp (cipher
, "aes-256") == 0)
250 return GNUTLS_PKCS_USE_PBES2_AES_256
;
252 else if (strcasecmp (cipher
, "rc2-40") == 0)
254 return GNUTLS_PKCS_USE_PKCS12_RC2_40
;
257 error (EXIT_FAILURE
, 0, "unknown cipher %s\n", cipher
);
263 print_private_key (common_info_st
* cinfo
, gnutls_x509_privkey_t key
)
271 if (outcert_format
== GNUTLS_X509_FMT_PEM
)
272 privkey_info_int(cinfo
, key
);
277 ret
= gnutls_x509_privkey_export (key
, outcert_format
,
280 error (EXIT_FAILURE
, 0, "privkey_export: %s", gnutls_strerror (ret
));
287 flags
= cipher_to_flags (cinfo
->pkcs_cipher
);
289 if ((pass
= get_confirmed_pass (true)) == NULL
|| *pass
== '\0')
290 flags
= GNUTLS_PKCS_PLAIN
;
294 gnutls_x509_privkey_export_pkcs8 (key
, outcert_format
, pass
,
295 flags
, buffer
, &size
);
297 error (EXIT_FAILURE
, 0, "privkey_export_pkcs8: %s",
298 gnutls_strerror (ret
));
301 fwrite (buffer
, 1, size
, outfile
);
305 generate_private_key (common_info_st
* cinfo
)
307 gnutls_x509_privkey_t key
;
309 key
= generate_private_key_int (cinfo
);
311 print_private_key (cinfo
, key
);
313 gnutls_x509_privkey_deinit (key
);
317 static gnutls_x509_crt_t
318 generate_certificate (gnutls_privkey_t
* ret_key
,
319 gnutls_x509_crt_t ca_crt
, int proxy
,
320 common_info_st
* cinfo
)
322 gnutls_x509_crt_t crt
;
323 gnutls_privkey_t key
= NULL
;
324 gnutls_pubkey_t pubkey
;
328 int days
, result
, ca_status
= 0, is_ike
= 0, path_len
;
330 unsigned int usage
= 0, server
;
331 gnutls_x509_crq_t crq
; /* request */
333 ret
= gnutls_x509_crt_init (&crt
);
335 error (EXIT_FAILURE
, 0, "crt_init: %s", gnutls_strerror (ret
));
337 crq
= load_request (cinfo
);
342 key
= load_private_key (1, cinfo
);
344 pubkey
= load_public_key_or_import (1, key
, cinfo
);
348 "Please enter the details of the certificate's distinguished name. "
349 "Just press enter to ignore a field.\n");
355 result
= gnutls_x509_crt_set_proxy_dn (crt
, ca_crt
, 0, NULL
, 0);
357 error (EXIT_FAILURE
, 0, "set_proxy_dn: %s",
358 gnutls_strerror (result
));
360 get_cn_crt_set (crt
);
364 get_country_crt_set (crt
);
365 get_organization_crt_set (crt
);
366 get_unit_crt_set (crt
);
367 get_locality_crt_set (crt
);
368 get_state_crt_set (crt
);
369 get_cn_crt_set (crt
);
370 get_dc_set (TYPE_CRT
, crt
);
371 get_uid_crt_set (crt
);
372 get_oid_crt_set (crt
);
373 get_key_purpose_set (crt
);
377 "This field should not be used in new certificates.\n");
379 get_pkcs9_email_crt_set (crt
);
382 result
= gnutls_x509_crt_set_pubkey (crt
, pubkey
);
384 error (EXIT_FAILURE
, 0, "set_key: %s", gnutls_strerror (result
));
388 result
= gnutls_x509_crt_set_crq (crt
, crq
);
390 error (EXIT_FAILURE
, 0, "set_crq: %s", gnutls_strerror (result
));
395 int serial
= get_serial ();
398 bin_serial
[4] = serial
& 0xff;
399 bin_serial
[3] = (serial
>> 8) & 0xff;
400 bin_serial
[2] = (serial
>> 16) & 0xff;
401 bin_serial
[1] = (serial
>> 24) & 0xff;
404 result
= gnutls_x509_crt_set_serial (crt
, bin_serial
, 5);
406 error (EXIT_FAILURE
, 0, "serial: %s", gnutls_strerror (result
));
410 fprintf (stderr
, "\n\nActivation/Expiration time.\n");
412 gnutls_x509_crt_set_activation_time (crt
, time (NULL
));
417 gnutls_x509_crt_set_expiration_time (crt
,
418 time (NULL
) + ((time_t) days
) * 24 * 60 * 60);
420 error (EXIT_FAILURE
, 0, "set_expiration: %s", gnutls_strerror (result
));
423 fprintf (stderr
, "\n\nExtensions.\n");
425 /* do not allow extensions on a v1 certificate */
426 if (crq
&& get_crq_extensions_status () != 0)
428 result
= gnutls_x509_crt_set_crq_extensions (crt
, crq
);
430 error (EXIT_FAILURE
, 0, "set_crq: %s", gnutls_strerror (result
));
433 /* append additional extensions */
434 if (cinfo
->v1_cert
== 0)
439 const char *policylanguage
;
442 int proxypathlen
= get_path_len ();
446 printf ("1.3.6.1.5.5.7.21.1 ::= id-ppl-inheritALL\n");
447 printf ("1.3.6.1.5.5.7.21.2 ::= id-ppl-independent\n");
450 policylanguage
= get_proxy_policy (&policy
, &policylen
);
453 gnutls_x509_crt_set_proxy (crt
, proxypathlen
, policylanguage
,
456 error (EXIT_FAILURE
, 0, "set_proxy: %s",
457 gnutls_strerror (result
));
461 ca_status
= get_ca_status ();
463 path_len
= get_path_len ();
468 gnutls_x509_crt_set_basic_constraints (crt
, ca_status
, path_len
);
470 error (EXIT_FAILURE
, 0, "basic_constraints: %s",
471 gnutls_strerror (result
));
473 client
= get_tls_client_status ();
476 result
= gnutls_x509_crt_set_key_purpose_oid (crt
,
477 GNUTLS_KP_TLS_WWW_CLIENT
,
480 error (EXIT_FAILURE
, 0, "key_kp: %s", gnutls_strerror (result
));
483 is_ike
= get_ipsec_ike_status ();
484 server
= get_tls_server_status ();
486 get_dns_name_set (TYPE_CRT
, crt
);
487 get_uri_set (TYPE_CRT
, crt
);
488 get_ip_addr_set (TYPE_CRT
, crt
);
495 gnutls_x509_crt_set_key_purpose_oid (crt
,
496 GNUTLS_KP_TLS_WWW_SERVER
, 0);
498 error (EXIT_FAILURE
, 0, "key_kp: %s", gnutls_strerror (result
));
502 get_email_set (TYPE_CRT
, crt
);
505 if (!ca_status
|| server
)
510 pk
= gnutls_x509_crt_get_pk_algorithm (crt
, NULL
);
512 if (pk
!= GNUTLS_PK_DSA
)
513 { /* DSA keys can only sign.
515 result
= get_sign_status (server
);
517 usage
|= GNUTLS_KEY_DIGITAL_SIGNATURE
;
519 result
= get_encrypt_status (server
);
521 usage
|= GNUTLS_KEY_KEY_ENCIPHERMENT
;
524 usage
|= GNUTLS_KEY_DIGITAL_SIGNATURE
;
529 gnutls_x509_crt_set_key_purpose_oid (crt
,
530 GNUTLS_KP_IPSEC_IKE
, 0);
532 error (EXIT_FAILURE
, 0, "key_kp: %s",
533 gnutls_strerror (result
));
540 result
= get_cert_sign_status ();
542 usage
|= GNUTLS_KEY_KEY_CERT_SIGN
;
544 result
= get_crl_sign_status ();
546 usage
|= GNUTLS_KEY_CRL_SIGN
;
548 result
= get_code_sign_status ();
552 gnutls_x509_crt_set_key_purpose_oid (crt
,
553 GNUTLS_KP_CODE_SIGNING
,
556 error (EXIT_FAILURE
, 0, "key_kp: %s",
557 gnutls_strerror (result
));
560 result
= get_ocsp_sign_status ();
564 gnutls_x509_crt_set_key_purpose_oid (crt
,
565 GNUTLS_KP_OCSP_SIGNING
,
568 error (EXIT_FAILURE
, 0, "key_kp: %s",
569 gnutls_strerror (result
));
572 result
= get_time_stamp_status ();
576 gnutls_x509_crt_set_key_purpose_oid (crt
,
577 GNUTLS_KP_TIME_STAMPING
,
580 error (EXIT_FAILURE
, 0, "key_kp: %s",
581 gnutls_strerror (result
));
584 get_ocsp_issuer_set(crt
);
585 get_ca_issuers_set(crt
);
589 /* http://tools.ietf.org/html/rfc4945#section-5.1.3.2: if any KU is
590 set, then either digitalSignature or the nonRepudiation bits in the
591 KeyUsage extension MUST for all IKE certs */
592 if (is_ike
&& (get_sign_status (server
) != 1))
593 usage
|= GNUTLS_KEY_NON_REPUDIATION
;
594 result
= gnutls_x509_crt_set_key_usage (crt
, usage
);
596 error (EXIT_FAILURE
, 0, "key_usage: %s",
597 gnutls_strerror (result
));
603 result
= gnutls_x509_crt_get_key_id (crt
, 0, buffer
, &size
);
606 result
= gnutls_x509_crt_set_subject_key_id (crt
, buffer
, size
);
608 error (EXIT_FAILURE
, 0, "set_subject_key_id: %s",
609 gnutls_strerror (result
));
617 result
= gnutls_x509_crt_get_subject_key_id (ca_crt
, buffer
,
622 result
= gnutls_x509_crt_get_key_id (ca_crt
, 0, buffer
, &size
);
627 gnutls_x509_crt_set_authority_key_id (crt
, buffer
, size
);
629 error (EXIT_FAILURE
, 0, "set_authority_key_id: %s",
630 gnutls_strerror (result
));
637 if (cinfo
->v1_cert
!= 0)
641 result
= gnutls_x509_crt_set_version (crt
, vers
);
643 error (EXIT_FAILURE
, 0, "set_version: %s", gnutls_strerror (result
));
650 static gnutls_x509_crl_t
651 generate_crl (gnutls_x509_crt_t ca_crt
, common_info_st
* cinfo
)
653 gnutls_x509_crl_t crl
;
654 gnutls_x509_crt_t
*crts
;
658 time_t now
= time (NULL
);
660 result
= gnutls_x509_crl_init (&crl
);
662 error (EXIT_FAILURE
, 0, "crl_init: %s", gnutls_strerror (result
));
664 crts
= load_cert_list (0, &size
, cinfo
);
666 for (i
= 0; i
< size
; i
++)
668 result
= gnutls_x509_crl_set_crt (crl
, crts
[i
], now
);
670 error (EXIT_FAILURE
, 0, "crl_set_crt: %s", gnutls_strerror (result
));
673 result
= gnutls_x509_crl_set_this_update (crl
, now
);
675 error (EXIT_FAILURE
, 0, "this_update: %s", gnutls_strerror (result
));
677 fprintf (stderr
, "Update times.\n");
678 days
= get_crl_next_update ();
680 result
= gnutls_x509_crl_set_next_update (crl
, now
+ days
* 24 * 60 * 60);
682 error (EXIT_FAILURE
, 0, "next_update: %s", gnutls_strerror (result
));
684 result
= gnutls_x509_crl_set_version (crl
, 2);
686 error (EXIT_FAILURE
, 0, "set_version: %s", gnutls_strerror (result
));
693 result
= gnutls_x509_crt_get_subject_key_id (ca_crt
, buffer
,
698 result
= gnutls_x509_crt_get_key_id (ca_crt
, 0, buffer
, &size
);
702 result
= gnutls_x509_crl_set_authority_key_id (crl
, buffer
, size
);
704 error (EXIT_FAILURE
, 0, "set_authority_key_id: %s",
705 gnutls_strerror (result
));
710 unsigned int number
= get_crl_number ();
713 bin_number
[4] = number
& 0xff;
714 bin_number
[3] = (number
>> 8) & 0xff;
715 bin_number
[2] = (number
>> 16) & 0xff;
716 bin_number
[1] = (number
>> 24) & 0xff;
719 result
= gnutls_x509_crl_set_number (crl
, bin_number
, 5);
721 error (EXIT_FAILURE
, 0, "set_number: %s", gnutls_strerror (result
));
727 static gnutls_digest_algorithm_t
728 get_dig_for_pub (gnutls_pubkey_t pubkey
)
730 gnutls_digest_algorithm_t dig
;
734 result
= gnutls_pubkey_get_preferred_hash_algorithm (pubkey
, &dig
, &mand
);
737 error (EXIT_FAILURE
, 0, "crt_get_preferred_hash_algorithm: %s",
738 gnutls_strerror (result
));
741 /* if algorithm allows alternatives */
742 if (mand
== 0 && default_dig
!= GNUTLS_DIG_UNKNOWN
)
748 static gnutls_digest_algorithm_t
749 get_dig (gnutls_x509_crt_t crt
)
751 gnutls_digest_algorithm_t dig
;
752 gnutls_pubkey_t pubkey
;
755 gnutls_pubkey_init(&pubkey
);
757 result
= gnutls_pubkey_import_x509(pubkey
, crt
, 0);
760 error (EXIT_FAILURE
, 0, "gnutls_pubkey_import_x509: %s",
761 gnutls_strerror (result
));
764 dig
= get_dig_for_pub (pubkey
);
766 gnutls_pubkey_deinit(pubkey
);
772 generate_self_signed (common_info_st
* cinfo
)
774 gnutls_x509_crt_t crt
;
775 gnutls_privkey_t key
;
780 fprintf (stderr
, "Generating a self signed certificate...\n");
782 crt
= generate_certificate (&key
, NULL
, 0, cinfo
);
785 key
= load_private_key (1, cinfo
);
787 uri
= get_crl_dist_point_url ();
790 result
= gnutls_x509_crt_set_crl_dist_points (crt
, GNUTLS_SAN_URI
,
792 0 /* all reasons */ );
794 error (EXIT_FAILURE
, 0, "crl_dist_points: %s",
795 gnutls_strerror (result
));
798 print_certificate_info (crt
, stderr
, 0);
800 fprintf (stderr
, "\n\nSigning certificate...\n");
802 result
= gnutls_x509_crt_privkey_sign (crt
, crt
, key
, get_dig (crt
), 0);
804 error (EXIT_FAILURE
, 0, "crt_sign: %s", gnutls_strerror (result
));
807 result
= gnutls_x509_crt_export (crt
, outcert_format
, buffer
, &size
);
809 error (EXIT_FAILURE
, 0, "crt_export: %s", gnutls_strerror (result
));
811 fwrite (buffer
, 1, size
, outfile
);
813 gnutls_x509_crt_deinit (crt
);
814 gnutls_privkey_deinit (key
);
818 generate_signed_certificate (common_info_st
* cinfo
)
820 gnutls_x509_crt_t crt
;
821 gnutls_privkey_t key
;
824 gnutls_privkey_t ca_key
;
825 gnutls_x509_crt_t ca_crt
;
827 fprintf (stderr
, "Generating a signed certificate...\n");
829 ca_key
= load_ca_private_key (cinfo
);
830 ca_crt
= load_ca_cert (cinfo
);
832 crt
= generate_certificate (&key
, ca_crt
, 0, cinfo
);
834 /* Copy the CRL distribution points.
836 gnutls_x509_crt_cpy_crl_dist_points (crt
, ca_crt
);
837 /* it doesn't matter if we couldn't copy the CRL dist points.
840 print_certificate_info (crt
, stderr
, 0);
842 fprintf (stderr
, "\n\nSigning certificate...\n");
844 result
= gnutls_x509_crt_privkey_sign (crt
, ca_crt
, ca_key
, get_dig (ca_crt
), 0);
846 error (EXIT_FAILURE
, 0, "crt_sign: %s", gnutls_strerror (result
));
849 result
= gnutls_x509_crt_export (crt
, outcert_format
, buffer
, &size
);
851 error (EXIT_FAILURE
, 0, "crt_export: %s", gnutls_strerror (result
));
853 fwrite (buffer
, 1, size
, outfile
);
855 gnutls_x509_crt_deinit (crt
);
856 gnutls_privkey_deinit (key
);
857 gnutls_privkey_deinit(ca_key
);
861 generate_proxy_certificate (common_info_st
* cinfo
)
863 gnutls_x509_crt_t crt
, eecrt
;
864 gnutls_privkey_t key
, eekey
;
868 fprintf (stderr
, "Generating a proxy certificate...\n");
870 eekey
= load_ca_private_key (cinfo
);
871 eecrt
= load_cert (1, cinfo
);
873 crt
= generate_certificate (&key
, eecrt
, 1, cinfo
);
875 print_certificate_info (crt
, stderr
, 0);
877 fprintf (stderr
, "\n\nSigning certificate...\n");
879 result
= gnutls_x509_crt_privkey_sign (crt
, eecrt
, eekey
, get_dig (eecrt
), 0);
881 error (EXIT_FAILURE
, 0, "crt_sign: %s", gnutls_strerror (result
));
884 result
= gnutls_x509_crt_export (crt
, outcert_format
, buffer
, &size
);
886 error (EXIT_FAILURE
, 0, "crt_export: %s", gnutls_strerror (result
));
888 fwrite (buffer
, 1, size
, outfile
);
890 gnutls_x509_crt_deinit (eecrt
);
891 gnutls_x509_crt_deinit (crt
);
892 gnutls_privkey_deinit (key
);
893 gnutls_privkey_deinit (eekey
);
897 generate_signed_crl (common_info_st
* cinfo
)
899 gnutls_x509_crl_t crl
;
901 gnutls_privkey_t ca_key
;
902 gnutls_x509_crt_t ca_crt
;
904 fprintf (stderr
, "Generating a signed CRL...\n");
906 ca_key
= load_ca_private_key (cinfo
);
907 ca_crt
= load_ca_cert (cinfo
);
908 crl
= generate_crl (ca_crt
, cinfo
);
910 fprintf (stderr
, "\n");
911 result
= gnutls_x509_crl_privkey_sign(crl
, ca_crt
, ca_key
, get_dig (ca_crt
), 0);
913 error (EXIT_FAILURE
, 0, "crl_privkey_sign: %s", gnutls_strerror (result
));
915 print_crl_info (crl
, stderr
);
917 gnutls_privkey_deinit( ca_key
);
918 gnutls_x509_crl_deinit (crl
);
922 update_signed_certificate (common_info_st
* cinfo
)
924 gnutls_x509_crt_t crt
;
927 gnutls_privkey_t ca_key
;
928 gnutls_x509_crt_t ca_crt
;
930 time_t tim
= time (NULL
);
932 fprintf (stderr
, "Generating a signed certificate...\n");
934 ca_key
= load_ca_private_key (cinfo
);
935 ca_crt
= load_ca_cert (cinfo
);
936 crt
= load_cert (1, cinfo
);
938 fprintf (stderr
, "Activation/Expiration time.\n");
939 gnutls_x509_crt_set_activation_time (crt
, tim
);
944 gnutls_x509_crt_set_expiration_time (crt
, tim
+ ((time_t) days
) * 24 * 60 * 60);
946 error (EXIT_FAILURE
, 0, "set_expiration: %s", gnutls_strerror (result
));
948 fprintf (stderr
, "\n\nSigning certificate...\n");
950 result
= gnutls_x509_crt_privkey_sign (crt
, ca_crt
, ca_key
, get_dig (ca_crt
), 0);
952 error (EXIT_FAILURE
, 0, "crt_sign: %s", gnutls_strerror (result
));
955 result
= gnutls_x509_crt_export (crt
, outcert_format
, buffer
, &size
);
957 error (EXIT_FAILURE
, 0, "crt_export: %s", gnutls_strerror (result
));
959 fwrite (buffer
, 1, size
, outfile
);
961 gnutls_x509_crt_deinit (crt
);
965 cmd_parser (int argc
, char **argv
)
967 int ret
, privkey_op
= 0;
968 common_info_st cinfo
;
970 optionProcess( &certtoolOptions
, argc
, argv
);
972 if (HAVE_OPT(GENERATE_PRIVKEY
) || HAVE_OPT(GENERATE_REQUEST
) ||
973 HAVE_OPT(KEY_INFO
) || HAVE_OPT(PGP_KEY_INFO
))
976 if (HAVE_OPT(OUTFILE
))
978 outfile
= safe_open_rw (OPT_ARG(OUTFILE
), privkey_op
);
980 error (EXIT_FAILURE
, errno
, "%s", OPT_ARG(OUTFILE
));
985 if (HAVE_OPT(INFILE
))
987 infile
= fopen (OPT_ARG(INFILE
), "rb");
989 error (EXIT_FAILURE
, errno
, "%s", OPT_ARG(INFILE
));
994 if (HAVE_OPT(INDER
) || HAVE_OPT(INRAW
))
995 incert_format
= GNUTLS_X509_FMT_DER
;
997 incert_format
= GNUTLS_X509_FMT_PEM
;
999 if (HAVE_OPT(OUTDER
) || HAVE_OPT(OUTRAW
))
1000 outcert_format
= GNUTLS_X509_FMT_DER
;
1002 outcert_format
= GNUTLS_X509_FMT_PEM
;
1005 req_key_type
= GNUTLS_PK_DSA
;
1006 else if (HAVE_OPT(ECC
))
1007 req_key_type
= GNUTLS_PK_ECC
;
1009 req_key_type
= GNUTLS_PK_RSA
;
1011 default_dig
= GNUTLS_DIG_UNKNOWN
;
1014 if (strcasecmp (OPT_ARG(HASH
), "md5") == 0)
1017 "Warning: MD5 is broken, and should not be used any more for digital signatures.\n");
1018 default_dig
= GNUTLS_DIG_MD5
;
1020 else if (strcasecmp (OPT_ARG(HASH
), "sha1") == 0)
1021 default_dig
= GNUTLS_DIG_SHA1
;
1022 else if (strcasecmp (OPT_ARG(HASH
), "sha256") == 0)
1023 default_dig
= GNUTLS_DIG_SHA256
;
1024 else if (strcasecmp (OPT_ARG(HASH
), "sha224") == 0)
1025 default_dig
= GNUTLS_DIG_SHA224
;
1026 else if (strcasecmp (OPT_ARG(HASH
), "sha384") == 0)
1027 default_dig
= GNUTLS_DIG_SHA384
;
1028 else if (strcasecmp (OPT_ARG(HASH
), "sha512") == 0)
1029 default_dig
= GNUTLS_DIG_SHA512
;
1030 else if (strcasecmp (OPT_ARG(HASH
), "rmd160") == 0)
1031 default_dig
= GNUTLS_DIG_RMD160
;
1033 error (EXIT_FAILURE
, 0, "invalid hash: %s", OPT_ARG(HASH
));
1037 if (HAVE_OPT(TEMPLATE
))
1040 template_parse (OPT_ARG(TEMPLATE
));
1043 gnutls_global_set_log_function (tls_log_func
);
1045 if (HAVE_OPT(DEBUG
))
1047 gnutls_global_set_log_level (OPT_VALUE_DEBUG
);
1048 printf ("Setting log level to %d\n", (int)OPT_VALUE_DEBUG
);
1051 if ((ret
= gnutls_global_init ()) < 0)
1052 error (EXIT_FAILURE
, 0, "global_init: %s", gnutls_strerror (ret
));
1054 #ifdef ENABLE_PKCS11
1058 memset (&cinfo
, 0, sizeof (cinfo
));
1060 if (HAVE_OPT(LOAD_PRIVKEY
))
1061 cinfo
.privkey
= OPT_ARG(LOAD_PRIVKEY
);
1063 cinfo
.v1_cert
= HAVE_OPT(V1
);
1064 if (HAVE_OPT(NO_CRQ_EXTENSIONS
))
1065 cinfo
.crq_extensions
= 0;
1066 else cinfo
.crq_extensions
= 1;
1068 if (HAVE_OPT(LOAD_PUBKEY
))
1069 cinfo
.pubkey
= OPT_ARG(LOAD_PUBKEY
);
1071 cinfo
.pkcs8
= HAVE_OPT(PKCS8
);
1072 cinfo
.incert_format
= incert_format
;
1074 if (HAVE_OPT(LOAD_CERTIFICATE
))
1075 cinfo
.cert
= OPT_ARG(LOAD_CERTIFICATE
);
1077 if (HAVE_OPT(LOAD_REQUEST
))
1078 cinfo
.request
= OPT_ARG(LOAD_REQUEST
);
1080 if (HAVE_OPT(LOAD_CA_CERTIFICATE
))
1081 cinfo
.ca
= OPT_ARG(LOAD_CA_CERTIFICATE
);
1083 if (HAVE_OPT(LOAD_CA_PRIVKEY
))
1084 cinfo
.ca_privkey
= OPT_ARG(LOAD_CA_PRIVKEY
);
1087 cinfo
.bits
= OPT_VALUE_BITS
;
1089 if (HAVE_OPT(SEC_PARAM
))
1090 cinfo
.sec_param
= OPT_ARG(SEC_PARAM
);
1092 if (HAVE_OPT(PKCS_CIPHER
))
1093 cinfo
.pkcs_cipher
= OPT_ARG(PKCS_CIPHER
);
1095 if (HAVE_OPT(PASSWORD
))
1096 cinfo
.password
= OPT_ARG(PASSWORD
);
1098 if (HAVE_OPT(GENERATE_SELF_SIGNED
))
1099 generate_self_signed (&cinfo
);
1100 else if (HAVE_OPT(GENERATE_CERTIFICATE
))
1101 generate_signed_certificate (&cinfo
);
1102 else if (HAVE_OPT(GENERATE_PROXY
))
1103 generate_proxy_certificate (&cinfo
);
1104 else if (HAVE_OPT(GENERATE_CRL
))
1105 generate_signed_crl (&cinfo
);
1106 else if (HAVE_OPT(UPDATE_CERTIFICATE
))
1107 update_signed_certificate (&cinfo
);
1108 else if (HAVE_OPT(GENERATE_PRIVKEY
))
1109 generate_private_key (&cinfo
);
1110 else if (HAVE_OPT(GENERATE_REQUEST
))
1111 generate_request (&cinfo
);
1112 else if (HAVE_OPT(VERIFY_CHAIN
))
1114 else if (HAVE_OPT(VERIFY
))
1115 verify_certificate (&cinfo
);
1116 else if (HAVE_OPT(VERIFY_CRL
))
1117 verify_crl (&cinfo
);
1118 else if (HAVE_OPT(CERTIFICATE_INFO
))
1119 certificate_info (0, &cinfo
);
1120 else if (HAVE_OPT(DH_INFO
))
1122 else if (HAVE_OPT(CERTIFICATE_PUBKEY
))
1123 certificate_info (1, &cinfo
);
1124 else if (HAVE_OPT(KEY_INFO
))
1125 privkey_info (&cinfo
);
1126 else if (HAVE_OPT(PUBKEY_INFO
))
1127 pubkey_info (NULL
, &cinfo
);
1128 else if (HAVE_OPT(TO_P12
))
1129 generate_pkcs12 (&cinfo
);
1130 else if (HAVE_OPT(P12_INFO
))
1131 pkcs12_info (&cinfo
);
1132 else if (HAVE_OPT(GENERATE_DH_PARAMS
))
1133 generate_prime (1, &cinfo
);
1134 else if (HAVE_OPT(GET_DH_PARAMS
))
1135 generate_prime (0, &cinfo
);
1136 else if (HAVE_OPT(CRL_INFO
))
1138 else if (HAVE_OPT(P7_INFO
))
1140 else if (HAVE_OPT(SMIME_TO_P7
))
1142 else if (HAVE_OPT(TO_P8
))
1143 generate_pkcs8 (&cinfo
);
1144 #ifdef ENABLE_OPENPGP
1145 else if (HAVE_OPT(PGP_CERTIFICATE_INFO
))
1146 pgp_certificate_info ();
1147 else if (HAVE_OPT(PGP_KEY_INFO
))
1148 pgp_privkey_info ();
1149 else if (HAVE_OPT(PGP_RING_INFO
))
1152 else if (HAVE_OPT(CRQ_INFO
))
1159 #ifdef ENABLE_PKCS11
1160 gnutls_pkcs11_deinit ();
1162 gnutls_global_deinit ();
1165 #define MAX_CRTS 500
1167 certificate_info (int pubkey
, common_info_st
* cinfo
)
1169 gnutls_x509_crt_t crt
[MAX_CRTS
];
1173 unsigned int crt_num
;
1175 pem
.data
= (void*)fread_file (infile
, &size
);
1180 gnutls_x509_crt_list_import (crt
, &crt_num
, &pem
, incert_format
,
1181 GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED
);
1182 if (ret
== GNUTLS_E_SHORT_MEMORY_BUFFER
)
1184 error (0, 0, "too many certificates (%d); "
1185 "will only read the first %d", crt_num
, MAX_CRTS
);
1187 ret
= gnutls_x509_crt_list_import (crt
, &crt_num
, &pem
,
1191 error (EXIT_FAILURE
, 0, "import error: %s", gnutls_strerror (ret
));
1197 if (count
> 1 && outcert_format
== GNUTLS_X509_FMT_DER
)
1199 error (0, 0, "cannot output multiple certificates in DER format; "
1200 "using PEM instead");
1201 outcert_format
= GNUTLS_X509_FMT_PEM
;
1204 for (i
= 0; i
< count
; i
++)
1207 fprintf (outfile
, "\n");
1209 if (outcert_format
== GNUTLS_X509_FMT_PEM
)
1210 print_certificate_info (crt
[i
], outfile
, 1);
1213 pubkey_info (crt
[i
], cinfo
);
1217 ret
= gnutls_x509_crt_export (crt
[i
], outcert_format
, buffer
,
1220 error (EXIT_FAILURE
, 0, "export error: %s", gnutls_strerror (ret
));
1222 fwrite (buffer
, 1, size
, outfile
);
1225 gnutls_x509_crt_deinit (crt
[i
]);
1229 #ifdef ENABLE_OPENPGP
1232 pgp_certificate_info (void)
1234 gnutls_openpgp_crt_t crt
;
1237 gnutls_datum_t pem
, out_data
;
1238 unsigned int verify_status
;
1240 pem
.data
= (void*)fread_file (infile
, &size
);
1243 ret
= gnutls_openpgp_crt_init (&crt
);
1245 error (EXIT_FAILURE
, 0, "openpgp_crt_init: %s", gnutls_strerror (ret
));
1247 ret
= gnutls_openpgp_crt_import (crt
, &pem
, incert_format
);
1250 error (EXIT_FAILURE
, 0, "import error: %s", gnutls_strerror (ret
));
1254 if (outcert_format
== GNUTLS_OPENPGP_FMT_BASE64
)
1256 ret
= gnutls_openpgp_crt_print (crt
, 0, &out_data
);
1260 fprintf (outfile
, "%s\n", out_data
.data
);
1261 gnutls_free (out_data
.data
);
1266 ret
= gnutls_openpgp_crt_verify_self (crt
, 0, &verify_status
);
1269 error (EXIT_FAILURE
, 0, "verify signature error: %s",
1270 gnutls_strerror (ret
));
1273 if (verify_status
& GNUTLS_CERT_INVALID
)
1275 fprintf (outfile
, "Self Signature verification: failed\n\n");
1279 fprintf (outfile
, "Self Signature verification: ok (%x)\n\n",
1284 ret
= gnutls_openpgp_crt_export (crt
, outcert_format
, buffer
, &size
);
1287 error (EXIT_FAILURE
, 0, "export error: %s", gnutls_strerror (ret
));
1288 fwrite (buffer
, 1, size
, outfile
);
1291 fprintf (outfile
, "%s\n", buffer
);
1292 gnutls_openpgp_crt_deinit (crt
);
1296 pgp_privkey_info (void)
1298 gnutls_openpgp_privkey_t key
;
1299 unsigned char keyid
[GNUTLS_OPENPGP_KEYID_SIZE
];
1301 int ret
, i
, subkeys
, bits
= 0;
1305 size
= fread (buffer
, 1, buffer_size
- 1, infile
);
1308 gnutls_openpgp_privkey_init (&key
);
1313 ret
= gnutls_openpgp_privkey_import (key
, &pem
, incert_format
,
1317 error (EXIT_FAILURE
, 0, "import error: %s", gnutls_strerror (ret
));
1319 /* Public key algorithm
1321 subkeys
= gnutls_openpgp_privkey_get_subkey_count (key
);
1323 error (EXIT_FAILURE
, 0, "privkey_get_subkey_count: %s",
1324 gnutls_strerror (subkeys
));
1326 for (i
= -1; i
< subkeys
; i
++)
1330 fprintf (outfile
, "Subkey[%d]:\n", i
);
1332 fprintf (outfile
, "Public Key Info:\n");
1335 ret
= gnutls_openpgp_privkey_get_pk_algorithm (key
, NULL
);
1337 ret
= gnutls_openpgp_privkey_get_subkey_pk_algorithm (key
, i
, NULL
);
1339 fprintf (outfile
, "\tPublic Key Algorithm: ");
1340 cprint
= gnutls_pk_algorithm_get_name (ret
);
1341 fprintf (outfile
, "%s\n", cprint
? cprint
: "Unknown");
1342 fprintf (outfile
, "\tKey Security Level: %s\n",
1343 gnutls_sec_param_get_name (gnutls_openpgp_privkey_sec_param
1346 /* Print the raw public and private keys
1349 if (ret
== GNUTLS_PK_RSA
)
1351 gnutls_datum_t m
, e
, d
, p
, q
, u
;
1355 gnutls_openpgp_privkey_export_rsa_raw (key
, &m
, &e
, &d
, &p
,
1359 gnutls_openpgp_privkey_export_subkey_rsa_raw (key
, i
, &m
,
1363 fprintf (stderr
, "Error in key RSA data export: %s\n",
1364 gnutls_strerror (ret
));
1366 print_rsa_pkey (&m
, &e
, &d
, &p
, &q
, &u
, NULL
, NULL
);
1370 else if (ret
== GNUTLS_PK_DSA
)
1372 gnutls_datum_t p
, q
, g
, y
, x
;
1376 gnutls_openpgp_privkey_export_dsa_raw (key
, &p
, &q
, &g
, &y
, &x
);
1379 gnutls_openpgp_privkey_export_subkey_dsa_raw (key
, i
, &p
,
1382 fprintf (stderr
, "Error in key DSA data export: %s\n",
1383 gnutls_strerror (ret
));
1385 print_dsa_pkey (&x
, &y
, &p
, &q
, &g
);
1390 fprintf (outfile
, "\n");
1394 ret
= gnutls_openpgp_privkey_get_key_id (key
, keyid
);
1396 ret
= gnutls_openpgp_privkey_get_subkey_id (key
, i
, keyid
);
1400 fprintf (stderr
, "Error in key id calculation: %s\n",
1401 gnutls_strerror (ret
));
1405 fprintf (outfile
, "Public key ID: %s\n", raw_to_string (keyid
, 8));
1410 ret
= gnutls_openpgp_privkey_get_fingerprint (key
, buffer
, &size
);
1412 ret
= gnutls_openpgp_privkey_get_subkey_fingerprint (key
, i
, buffer
, &size
);
1416 fprintf (stderr
, "Error in fingerprint calculation: %s\n",
1417 gnutls_strerror (ret
));
1423 fprintf (outfile
, "Fingerprint: %s\n", raw_to_string (buffer
, size
));
1425 ret
= gnutls_random_art(GNUTLS_RANDOM_ART_OPENSSH
, cprint
, bits
, buffer
, size
, &art
);
1428 fprintf (outfile
, "Fingerprint's random art:\n%s\n\n", art
.data
);
1429 gnutls_free(art
.data
);
1435 ret
= gnutls_openpgp_privkey_export (key
, GNUTLS_OPENPGP_FMT_BASE64
,
1436 NULL
, 0, buffer
, &size
);
1438 error (EXIT_FAILURE
, 0, "export error: %s", gnutls_strerror (ret
));
1440 fprintf (outfile
, "\n%s\n", buffer
);
1442 gnutls_openpgp_privkey_deinit (key
);
1446 pgp_ring_info (void)
1448 gnutls_openpgp_keyring_t ring
;
1449 gnutls_openpgp_crt_t crt
;
1454 pem
.data
= (void*)fread_file (infile
, &size
);
1457 ret
= gnutls_openpgp_keyring_init (&ring
);
1459 error (EXIT_FAILURE
, 0, "openpgp_keyring_init: %s",
1460 gnutls_strerror (ret
));
1462 ret
= gnutls_openpgp_keyring_import (ring
, &pem
, incert_format
);
1465 error (EXIT_FAILURE
, 0, "import error: %s", gnutls_strerror (ret
));
1469 count
= gnutls_openpgp_keyring_get_crt_count (ring
);
1471 fprintf (outfile
, "Keyring contains %d OpenPGP certificates\n\n", count
);
1473 error (EXIT_FAILURE
, 0, "keyring error: %s", gnutls_strerror (count
));
1475 for (i
= 0; i
< count
; i
++)
1477 ret
= gnutls_openpgp_keyring_get_crt (ring
, i
, &crt
);
1479 error (EXIT_FAILURE
, 0, "export error: %s", gnutls_strerror (ret
));
1482 ret
= gnutls_openpgp_crt_export (crt
, outcert_format
,
1485 error (EXIT_FAILURE
, 0, "export error: %s", gnutls_strerror (ret
));
1487 fwrite (buffer
, 1, size
, outfile
);
1488 fprintf (outfile
, "\n\n");
1490 gnutls_openpgp_crt_deinit (crt
);
1495 gnutls_openpgp_keyring_deinit (ring
);
1502 print_hex_datum (gnutls_datum_t
* dat
)
1506 fprintf (outfile
, "\n" SPACE
);
1507 for (j
= 0; j
< dat
->size
; j
++)
1509 fprintf (outfile
, "%.2x:", (unsigned char) dat
->data
[j
]);
1510 if ((j
+ 1) % 15 == 0)
1511 fprintf (outfile
, "\n" SPACE
);
1513 fprintf (outfile
, "\n");
1518 print_certificate_info (gnutls_x509_crt_t crt
, FILE * out
, unsigned int all
)
1520 gnutls_datum_t data
;
1524 ret
= gnutls_x509_crt_print (crt
, GNUTLS_CRT_PRINT_FULL
, &data
);
1526 ret
= gnutls_x509_crt_print (crt
, GNUTLS_CRT_PRINT_UNSIGNED_FULL
, &data
);
1529 fprintf (out
, "%s\n", data
.data
);
1530 gnutls_free (data
.data
);
1533 if (out
== stderr
&& batch
== 0) /* interactive */
1534 if (read_yesno ("Is the above information ok? (y/N): ") == 0)
1541 print_crl_info (gnutls_x509_crl_t crl
, FILE * out
)
1543 gnutls_datum_t data
;
1547 ret
= gnutls_x509_crl_print (crl
, GNUTLS_CRT_PRINT_FULL
, &data
);
1549 error (EXIT_FAILURE
, 0, "crl_print: %s", gnutls_strerror (ret
));
1551 fprintf (out
, "%s\n", data
.data
);
1553 gnutls_free (data
.data
);
1556 ret
= gnutls_x509_crl_export (crl
, GNUTLS_X509_FMT_PEM
, buffer
, &size
);
1558 error (EXIT_FAILURE
, 0, "crl_export: %s", gnutls_strerror (ret
));
1560 fwrite (buffer
, 1, size
, outfile
);
1566 gnutls_x509_crl_t crl
;
1571 ret
= gnutls_x509_crl_init (&crl
);
1573 error (EXIT_FAILURE
, 0, "crl_init: %s", gnutls_strerror (ret
));
1575 pem
.data
= (void*)fread_file (infile
, &size
);
1579 error (EXIT_FAILURE
, errno
, "%s", infile
? "file" :
1582 ret
= gnutls_x509_crl_import (crl
, &pem
, incert_format
);
1586 error (EXIT_FAILURE
, 0, "import error: %s", gnutls_strerror (ret
));
1588 print_crl_info (crl
, outfile
);
1590 gnutls_x509_crl_deinit (crl
);
1594 print_crq_info (gnutls_x509_crq_t crq
, FILE * out
)
1596 gnutls_datum_t data
;
1600 if (outcert_format
== GNUTLS_X509_FMT_PEM
)
1602 ret
= gnutls_x509_crq_print (crq
, GNUTLS_CRT_PRINT_FULL
, &data
);
1604 error (EXIT_FAILURE
, 0, "crq_print: %s", gnutls_strerror (ret
));
1606 fprintf (out
, "%s\n", data
.data
);
1608 gnutls_free (data
.data
);
1611 ret
= gnutls_x509_crq_verify(crq
, 0);
1614 fprintf(out
, "Self signature: FAILED\n\n");
1618 fprintf(out
, "Self signature: verified\n\n");
1622 ret
= gnutls_x509_crq_export (crq
, outcert_format
, buffer
, &size
);
1624 error (EXIT_FAILURE
, 0, "crq_export: %s", gnutls_strerror (ret
));
1626 fwrite (buffer
, 1, size
, outfile
);
1632 gnutls_x509_crq_t crq
;
1637 ret
= gnutls_x509_crq_init (&crq
);
1639 error (EXIT_FAILURE
, 0, "crq_init: %s", gnutls_strerror (ret
));
1641 pem
.data
= (void*)fread_file (infile
, &size
);
1645 error (EXIT_FAILURE
, errno
, "%s", infile
? "file" :
1648 ret
= gnutls_x509_crq_import (crq
, &pem
, incert_format
);
1652 error (EXIT_FAILURE
, 0, "import error: %s", gnutls_strerror (ret
));
1654 print_crq_info (crq
, outfile
);
1656 gnutls_x509_crq_deinit (crq
);
1659 static void privkey_info_int (common_info_st
* cinfo
, gnutls_x509_privkey_t key
)
1661 int ret
, key_type
, bits
= 0;
1665 /* Public key algorithm
1667 fprintf (outfile
, "Public Key Info:\n");
1668 ret
= gnutls_x509_privkey_get_pk_algorithm (key
);
1669 fprintf (outfile
, "\tPublic Key Algorithm: ");
1673 cprint
= gnutls_pk_algorithm_get_name (key_type
);
1674 fprintf (outfile
, "%s\n", cprint
? cprint
: "Unknown");
1675 fprintf (outfile
, "\tKey Security Level: %s\n\n",
1676 gnutls_sec_param_get_name (gnutls_x509_privkey_sec_param (key
)));
1678 /* Print the raw public and private keys
1680 if (key_type
== GNUTLS_PK_RSA
)
1682 gnutls_datum_t m
, e
, d
, p
, q
, u
, exp1
, exp2
;
1685 gnutls_x509_privkey_export_rsa_raw2 (key
, &m
, &e
, &d
, &p
, &q
, &u
,
1688 fprintf (stderr
, "Error in key RSA data export: %s\n",
1689 gnutls_strerror (ret
));
1692 print_rsa_pkey (&m
, &e
, &d
, &p
, &q
, &u
, &exp1
, &exp2
);
1695 gnutls_free (m
.data
);
1696 gnutls_free (e
.data
);
1697 gnutls_free (d
.data
);
1698 gnutls_free (p
.data
);
1699 gnutls_free (q
.data
);
1700 gnutls_free (u
.data
);
1701 gnutls_free (exp1
.data
);
1702 gnutls_free (exp2
.data
);
1705 else if (key_type
== GNUTLS_PK_DSA
)
1707 gnutls_datum_t p
, q
, g
, y
, x
;
1709 ret
= gnutls_x509_privkey_export_dsa_raw (key
, &p
, &q
, &g
, &y
, &x
);
1711 fprintf (stderr
, "Error in key DSA data export: %s\n",
1712 gnutls_strerror (ret
));
1715 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
);
1725 else if (key_type
== GNUTLS_PK_EC
)
1727 gnutls_datum_t y
, x
, k
;
1728 gnutls_ecc_curve_t curve
;
1730 ret
= gnutls_x509_privkey_export_ecc_raw (key
, &curve
, &x
, &y
, &k
);
1732 fprintf (stderr
, "Error in key ECC data export: %s\n",
1733 gnutls_strerror (ret
));
1736 print_ecc_pkey (curve
, &k
, &x
, &y
);
1737 bits
= gnutls_ecc_curve_get_size(curve
) * 8;
1739 gnutls_free (x
.data
);
1740 gnutls_free (y
.data
);
1741 gnutls_free (k
.data
);
1745 fprintf (outfile
, "\n");
1748 if ((ret
= gnutls_x509_privkey_get_key_id (key
, 0, buffer
, &size
)) < 0)
1750 fprintf (stderr
, "Error in key id calculation: %s\n",
1751 gnutls_strerror (ret
));
1757 fprintf (outfile
, "Public Key ID: %s\n", raw_to_string (buffer
, size
));
1759 ret
= gnutls_random_art(GNUTLS_RANDOM_ART_OPENSSH
, cprint
, bits
, buffer
, size
, &art
);
1762 fprintf (outfile
, "Public key's random art:\n%s\n", art
.data
);
1763 gnutls_free(art
.data
);
1766 fprintf (outfile
, "\n");
1771 privkey_info (common_info_st
* cinfo
)
1773 gnutls_x509_privkey_t key
;
1779 size
= fread (buffer
, 1, buffer_size
- 1, infile
);
1782 gnutls_x509_privkey_init (&key
);
1789 ret
= gnutls_x509_privkey_import (key
, &pem
, incert_format
);
1791 /* If we failed to import the certificate previously try PKCS #8 */
1792 if (cinfo
->pkcs8
|| ret
== GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR
)
1794 if (cinfo
->password
)
1795 pass
= cinfo
->password
;
1798 ret
= gnutls_x509_privkey_import_pkcs8 (key
, &pem
,
1799 incert_format
, pass
, 0);
1802 error (EXIT_FAILURE
, 0, "import error: %s", gnutls_strerror (ret
));
1804 if (outcert_format
== GNUTLS_X509_FMT_PEM
)
1805 privkey_info_int (cinfo
, key
);
1807 ret
= gnutls_x509_privkey_verify_params (key
);
1809 fprintf (outfile
, "\n** Private key parameters validation failed **\n\n");
1812 ret
= gnutls_x509_privkey_export (key
, outcert_format
, buffer
, &size
);
1814 error (EXIT_FAILURE
, 0, "export error: %s", gnutls_strerror (ret
));
1816 fwrite (buffer
, 1, size
, outfile
);
1818 gnutls_x509_privkey_deinit (key
);
1822 /* Generate a PKCS #10 certificate request.
1825 generate_request (common_info_st
* cinfo
)
1827 gnutls_x509_crq_t crq
;
1828 gnutls_x509_privkey_t xkey
;
1829 gnutls_pubkey_t pubkey
;
1830 gnutls_privkey_t pkey
;
1831 int ret
, ca_status
, path_len
;
1833 unsigned int usage
= 0;
1835 fprintf (stderr
, "Generating a PKCS #10 certificate request...\n");
1837 ret
= gnutls_x509_crq_init (&crq
);
1839 error (EXIT_FAILURE
, 0, "crq_init: %s", gnutls_strerror (ret
));
1842 /* Load the private key.
1844 pkey
= load_private_key (0, cinfo
);
1847 ret
= gnutls_privkey_init (&pkey
);
1849 error (EXIT_FAILURE
, 0, "privkey_init: %s", gnutls_strerror (ret
));
1851 xkey
= generate_private_key_int (cinfo
);
1853 print_private_key (cinfo
, xkey
);
1855 ret
= gnutls_privkey_import_x509(pkey
, xkey
, GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE
);
1857 error (EXIT_FAILURE
, 0, "privkey_import_x509: %s", gnutls_strerror (ret
));
1860 pubkey
= load_public_key_or_import (1, pkey
, cinfo
);
1864 get_country_crq_set (crq
);
1865 get_organization_crq_set (crq
);
1866 get_unit_crq_set (crq
);
1867 get_locality_crq_set (crq
);
1868 get_state_crq_set (crq
);
1869 get_cn_crq_set (crq
);
1870 get_dc_set (TYPE_CRQ
, crq
);
1871 get_uid_crq_set (crq
);
1872 get_oid_crq_set (crq
);
1874 get_dns_name_set (TYPE_CRQ
, crq
);
1875 get_uri_set (TYPE_CRQ
, crq
);
1876 get_ip_addr_set (TYPE_CRQ
, crq
);
1877 get_email_set (TYPE_CRQ
, crq
);
1879 pass
= get_challenge_pass ();
1881 if (pass
!= NULL
&& pass
[0] != 0)
1883 ret
= gnutls_x509_crq_set_challenge_password (crq
, pass
);
1885 error (EXIT_FAILURE
, 0, "set_pass: %s", gnutls_strerror (ret
));
1888 if (cinfo
->crq_extensions
!= 0)
1890 ca_status
= get_ca_status ();
1892 path_len
= get_path_len ();
1896 ret
= gnutls_x509_crq_set_basic_constraints (crq
, ca_status
, path_len
);
1898 error (EXIT_FAILURE
, 0, "set_basic_constraints: %s",
1899 gnutls_strerror (ret
));
1901 ret
= get_sign_status (1);
1903 usage
|= GNUTLS_KEY_DIGITAL_SIGNATURE
;
1905 ret
= get_encrypt_status (1);
1907 usage
|= GNUTLS_KEY_KEY_ENCIPHERMENT
;
1909 usage
|= GNUTLS_KEY_DIGITAL_SIGNATURE
;
1913 ret
= get_cert_sign_status ();
1915 usage
|= GNUTLS_KEY_KEY_CERT_SIGN
;
1917 ret
= get_crl_sign_status ();
1919 usage
|= GNUTLS_KEY_CRL_SIGN
;
1921 ret
= get_code_sign_status ();
1924 ret
= gnutls_x509_crq_set_key_purpose_oid
1925 (crq
, GNUTLS_KP_CODE_SIGNING
, 0);
1927 error (EXIT_FAILURE
, 0, "key_kp: %s", gnutls_strerror (ret
));
1930 ret
= get_ocsp_sign_status ();
1933 ret
= gnutls_x509_crq_set_key_purpose_oid
1934 (crq
, GNUTLS_KP_OCSP_SIGNING
, 0);
1936 error (EXIT_FAILURE
, 0, "key_kp: %s", gnutls_strerror (ret
));
1939 ret
= get_time_stamp_status ();
1942 ret
= gnutls_x509_crq_set_key_purpose_oid
1943 (crq
, GNUTLS_KP_TIME_STAMPING
, 0);
1945 error (EXIT_FAILURE
, 0, "key_kp: %s", gnutls_strerror (ret
));
1948 ret
= get_ipsec_ike_status ();
1951 ret
= gnutls_x509_crq_set_key_purpose_oid
1952 (crq
, GNUTLS_KP_IPSEC_IKE
, 0);
1954 error (EXIT_FAILURE
, 0, "key_kp: %s", gnutls_strerror (ret
));
1958 ret
= gnutls_x509_crq_set_key_usage (crq
, usage
);
1960 error (EXIT_FAILURE
, 0, "key_usage: %s", gnutls_strerror (ret
));
1962 ret
= get_tls_client_status ();
1965 ret
= gnutls_x509_crq_set_key_purpose_oid
1966 (crq
, GNUTLS_KP_TLS_WWW_CLIENT
, 0);
1968 error (EXIT_FAILURE
, 0, "key_kp: %s", gnutls_strerror (ret
));
1971 ret
= get_tls_server_status ();
1974 ret
= gnutls_x509_crq_set_key_purpose_oid
1975 (crq
, GNUTLS_KP_TLS_WWW_SERVER
, 0);
1977 error (EXIT_FAILURE
, 0, "key_kp: %s", gnutls_strerror (ret
));
1981 ret
= gnutls_x509_crq_set_pubkey (crq
, pubkey
);
1983 error (EXIT_FAILURE
, 0, "set_key: %s", gnutls_strerror (ret
));
1985 ret
= gnutls_x509_crq_privkey_sign (crq
, pkey
, get_dig_for_pub (pubkey
), 0);
1987 error (EXIT_FAILURE
, 0, "sign: %s", gnutls_strerror (ret
));
1989 print_crq_info (crq
, outfile
);
1991 gnutls_x509_crq_deinit (crq
);
1992 gnutls_privkey_deinit( pkey
);
1993 gnutls_pubkey_deinit( pubkey
);
1997 static void print_verification_res (FILE* outfile
, unsigned int output
);
1999 static int detailed_verification(gnutls_x509_crt_t cert
,
2000 gnutls_x509_crt_t issuer
, gnutls_x509_crl_t crl
,
2001 unsigned int verification_output
)
2005 char issuer_name
[512];
2007 size_t issuer_name_size
;
2010 issuer_name_size
= sizeof (issuer_name
);
2012 gnutls_x509_crt_get_issuer_dn (cert
, issuer_name
, &issuer_name_size
);
2014 error (EXIT_FAILURE
, 0, "gnutls_x509_crt_get_issuer_dn: %s", gnutls_strerror (ret
));
2016 name_size
= sizeof (name
);
2018 gnutls_x509_crt_get_dn (cert
, name
, &name_size
);
2020 error (EXIT_FAILURE
, 0, "gnutls_x509_crt_get_dn: %s", gnutls_strerror (ret
));
2022 fprintf (outfile
, "\tSubject: %s\n", name
);
2023 fprintf (outfile
, "\tIssuer: %s\n", issuer_name
);
2027 issuer_name_size
= sizeof (issuer_name
);
2029 gnutls_x509_crt_get_dn (issuer
, issuer_name
, &issuer_name_size
);
2031 error (EXIT_FAILURE
, 0, "gnutls_x509_crt_get_issuer_dn: %s", gnutls_strerror (ret
));
2033 fprintf (outfile
, "\tChecked against: %s\n", issuer_name
);
2038 gnutls_datum_t data
;
2040 issuer_name_size
= sizeof (issuer_name
);
2042 gnutls_x509_crl_get_issuer_dn (crl
, issuer_name
, &issuer_name_size
);
2044 error (EXIT_FAILURE
, 0, "gnutls_x509_crl_get_issuer_dn: %s", gnutls_strerror (ret
));
2046 name_size
= sizeof(tmp
);
2047 ret
= gnutls_x509_crl_get_number(crl
, tmp
, &name_size
, NULL
);
2049 strcpy(name
, "unnumbered");
2052 data
.data
= (void*)tmp
;
2053 data
.size
= name_size
;
2055 name_size
= sizeof(name
);
2056 ret
= gnutls_hex_encode(&data
, name
, &name_size
);
2058 error (EXIT_FAILURE
, 0, "gnutls_hex_encode: %s", gnutls_strerror (ret
));
2060 fprintf (outfile
, "\tChecked against CRL[%s] of: %s\n", name
, issuer_name
);
2063 fprintf (outfile
, "\tOutput: ");
2064 print_verification_res(outfile
, verification_output
);
2066 fputs(".\n\n", outfile
);
2071 /* Will verify a certificate chain. If no CA certificates
2072 * are provided, then the last certificate in the certificate
2073 * chain is used as a CA.
2076 _verify_x509_mem (const void *cert
, int cert_size
, const void* ca
, int ca_size
)
2080 gnutls_x509_crt_t
*x509_cert_list
= NULL
;
2081 gnutls_x509_crt_t
*x509_ca_list
= NULL
;
2082 gnutls_x509_crl_t
*x509_crl_list
= NULL
;
2083 unsigned int x509_ncerts
, x509_ncrls
= 0, x509_ncas
= 0;
2084 gnutls_x509_trust_list_t list
;
2085 unsigned int output
;
2087 ret
= gnutls_x509_trust_list_init(&list
, 0);
2089 error (EXIT_FAILURE
, 0, "gnutls_x509_trust_list_init: %s",
2090 gnutls_strerror (ret
));
2094 tmp
.data
= (void*)cert
;
2095 tmp
.size
= cert_size
;
2099 tmp
.data
= (void*)ca
;
2103 ret
= gnutls_x509_crt_list_import2( &x509_ca_list
, &x509_ncas
, &tmp
,
2104 GNUTLS_X509_FMT_PEM
, 0);
2105 if (ret
< 0 || x509_ncas
< 1)
2106 error (EXIT_FAILURE
, 0, "error parsing CAs: %s",
2107 gnutls_strerror (ret
));
2110 ret
= gnutls_x509_crl_list_import2( &x509_crl_list
, &x509_ncrls
, &tmp
,
2111 GNUTLS_X509_FMT_PEM
, 0);
2114 x509_crl_list
= NULL
;
2118 tmp
.data
= (void*)cert
;
2119 tmp
.size
= cert_size
;
2121 /* ignore errors. CRLs might not be given */
2122 ret
= gnutls_x509_crt_list_import2( &x509_cert_list
, &x509_ncerts
, &tmp
,
2123 GNUTLS_X509_FMT_PEM
, 0);
2124 if (ret
< 0 || x509_ncerts
< 1)
2125 error (EXIT_FAILURE
, 0, "error parsing CRTs: %s",
2126 gnutls_strerror (ret
));
2130 x509_ca_list
= &x509_cert_list
[x509_ncerts
- 1];
2134 fprintf(stdout
, "Loaded %d certificates, %d CAs and %d CRLs\n\n",
2135 x509_ncerts
, x509_ncas
, x509_ncrls
);
2137 ret
= gnutls_x509_trust_list_add_cas(list
, x509_ca_list
, x509_ncas
, 0);
2139 error (EXIT_FAILURE
, 0, "gnutls_x509_trust_add_cas: %s",
2140 gnutls_strerror (ret
));
2142 ret
= gnutls_x509_trust_list_add_crls(list
, x509_crl_list
, x509_ncrls
, 0, 0);
2144 error (EXIT_FAILURE
, 0, "gnutls_x509_trust_add_crls: %s",
2145 gnutls_strerror (ret
));
2147 gnutls_free(x509_crl_list
);
2149 ret
= gnutls_x509_trust_list_verify_crt (list
, x509_cert_list
, x509_ncerts
,
2150 GNUTLS_VERIFY_DO_NOT_ALLOW_SAME
|GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT
, &output
,
2151 detailed_verification
);
2153 error (EXIT_FAILURE
, 0, "gnutls_x509_trusted_list_verify_crt: %s",
2154 gnutls_strerror (ret
));
2156 fprintf (outfile
, "Chain verification output: ");
2157 print_verification_res(outfile
, output
);
2159 fprintf (outfile
, ".\n\n");
2161 gnutls_free(x509_cert_list
);
2162 gnutls_x509_trust_list_deinit(list
, 1);
2171 print_verification_res (FILE* outfile
, unsigned int output
)
2175 if (output
& GNUTLS_CERT_INVALID
)
2177 fprintf (outfile
, "Not verified");
2182 fprintf (outfile
, "Verified");
2186 if (output
& GNUTLS_CERT_SIGNER_NOT_CA
)
2189 fprintf (outfile
, ", ");
2190 fprintf (outfile
, "Issuer is not a CA");
2194 if (output
& GNUTLS_CERT_INSECURE_ALGORITHM
)
2197 fprintf (outfile
, ", ");
2198 fprintf (outfile
, "Insecure algorithm");
2202 if (output
& GNUTLS_CERT_NOT_ACTIVATED
)
2205 fprintf (outfile
, ", ");
2206 fprintf (outfile
, "Not activated");
2210 if (output
& GNUTLS_CERT_EXPIRED
)
2213 fprintf (outfile
, ", ");
2214 fprintf (outfile
, "Expired");
2218 if (output
& GNUTLS_CERT_REVOKED
)
2221 fprintf (outfile
, ", ");
2222 fprintf (outfile
, "Revoked");
2233 buf
= (void*)fread_file (infile
, &size
);
2235 error (EXIT_FAILURE
, errno
, "reading chain");
2239 _verify_x509_mem (buf
, size
, NULL
, 0);
2244 verify_certificate (common_info_st
* cinfo
)
2248 size_t cert_size
, ca_size
;
2249 FILE * ca_file
= fopen(cinfo
->ca
, "r");
2251 if (ca_file
== NULL
)
2252 error (EXIT_FAILURE
, errno
, "opening CA file");
2254 cert
= (void*)fread_file (infile
, &cert_size
);
2256 error (EXIT_FAILURE
, errno
, "reading certificate chain");
2258 cert
[cert_size
] = 0;
2260 cas
= (void*)fread_file (ca_file
, &ca_size
);
2262 error (EXIT_FAILURE
, errno
, "reading CA list");
2267 _verify_x509_mem (cert
, cert_size
, cas
, ca_size
);
2273 verify_crl (common_info_st
* cinfo
)
2275 size_t size
, dn_size
;
2277 unsigned int output
;
2281 gnutls_x509_crl_t crl
;
2282 time_t now
= time (0);
2283 gnutls_x509_crt_t issuer
;
2285 issuer
= load_ca_cert (cinfo
);
2287 fprintf (outfile
, "\nCA certificate:\n");
2289 dn_size
= sizeof (dn
);
2290 ret
= gnutls_x509_crt_get_dn (issuer
, dn
, &dn_size
);
2292 error (EXIT_FAILURE
, 0, "crt_get_dn: %s", gnutls_strerror (ret
));
2294 fprintf (outfile
, "\tSubject: %s\n\n", dn
);
2296 ret
= gnutls_x509_crl_init (&crl
);
2298 error (EXIT_FAILURE
, 0, "crl_init: %s", gnutls_strerror (ret
));
2300 pem
.data
= (void*)fread_file (infile
, &size
);
2303 ret
= gnutls_x509_crl_import (crl
, &pem
, incert_format
);
2306 error (EXIT_FAILURE
, 0, "import error: %s", gnutls_strerror (ret
));
2308 print_crl_info (crl
, outfile
);
2310 fprintf (outfile
, "Verification output: ");
2311 ret
= gnutls_x509_crl_verify (crl
, &issuer
, 1, 0, &output
);
2313 error (EXIT_FAILURE
, 0, "verification error: %s", gnutls_strerror (ret
));
2315 if (output
& GNUTLS_CERT_INVALID
)
2317 fprintf (outfile
, "Not verified");
2322 fprintf (outfile
, "Verified");
2326 if (output
& GNUTLS_CERT_SIGNER_NOT_CA
)
2329 fprintf (outfile
, ", ");
2330 fprintf (outfile
, "Issuer is not a CA");
2334 if (output
& GNUTLS_CERT_INSECURE_ALGORITHM
)
2337 fprintf (outfile
, ", ");
2338 fprintf (outfile
, "Insecure algorithm");
2342 /* Check expiration dates.
2345 if (gnutls_x509_crl_get_this_update (crl
) > now
)
2348 fprintf (outfile
, ", ");
2350 fprintf (outfile
, "Issued in the future!");
2353 if (gnutls_x509_crl_get_next_update (crl
) < now
)
2356 fprintf (outfile
, ", ");
2358 fprintf (outfile
, "CRL is not up to date");
2361 fprintf (outfile
, "\n");
2366 generate_pkcs8 (common_info_st
* cinfo
)
2368 gnutls_x509_privkey_t key
;
2372 const char *password
;
2374 fprintf (stderr
, "Generating a PKCS #8 key structure...\n");
2376 key
= load_x509_private_key (1, cinfo
);
2378 if (cinfo
->password
)
2379 password
= cinfo
->password
;
2381 password
= get_pass ();
2383 flags
= cipher_to_flags (cinfo
->pkcs_cipher
);
2385 if (password
== NULL
|| password
[0] == 0)
2387 flags
= GNUTLS_PKCS_PLAIN
;
2392 gnutls_x509_privkey_export_pkcs8 (key
, outcert_format
,
2393 password
, flags
, buffer
, &size
);
2396 error (EXIT_FAILURE
, 0, "key_export: %s", gnutls_strerror (result
));
2398 fwrite (buffer
, 1, size
, outfile
);
2403 #include <gnutls/pkcs12.h>
2407 generate_pkcs12 (common_info_st
* cinfo
)
2409 gnutls_pkcs12_t pkcs12
;
2410 gnutls_x509_crt_t
*crts
;
2411 gnutls_x509_privkey_t key
;
2414 gnutls_datum_t data
;
2417 unsigned int flags
, i
;
2418 gnutls_datum_t key_id
;
2419 unsigned char _key_id
[32];
2423 fprintf (stderr
, "Generating a PKCS #12 structure...\n");
2425 key
= load_x509_private_key (0, cinfo
);
2426 crts
= load_cert_list (0, &ncrts
, cinfo
);
2428 name
= get_pkcs12_key_name ();
2430 result
= gnutls_pkcs12_init (&pkcs12
);
2432 error (EXIT_FAILURE
, 0, "pkcs12_init: %s", gnutls_strerror (result
));
2434 if (cinfo
->password
)
2435 pass
= cinfo
->password
;
2441 fprintf(stderr
, "No password given for PKCS #12. Assuming null password...\n");
2446 for (i
= 0; i
< ncrts
; i
++)
2448 gnutls_pkcs12_bag_t bag
;
2450 result
= gnutls_pkcs12_bag_init (&bag
);
2452 error (EXIT_FAILURE
, 0, "bag_init: %s", gnutls_strerror (result
));
2454 result
= gnutls_pkcs12_bag_set_crt (bag
, crts
[i
]);
2456 error (EXIT_FAILURE
, 0, "set_crt[%d]: %s", i
,
2457 gnutls_strerror (result
));
2461 result
= gnutls_pkcs12_bag_set_friendly_name (bag
, indx
, name
);
2463 error (EXIT_FAILURE
, 0, "bag_set_friendly_name: %s",
2464 gnutls_strerror (result
));
2466 size
= sizeof (_key_id
);
2467 result
= gnutls_x509_crt_get_key_id (crts
[i
], 0, _key_id
, &size
);
2469 error (EXIT_FAILURE
, 0, "key_id[%d]: %s", i
,
2470 gnutls_strerror (result
));
2472 key_id
.data
= _key_id
;
2475 result
= gnutls_pkcs12_bag_set_key_id (bag
, indx
, &key_id
);
2477 error (EXIT_FAILURE
, 0, "bag_set_key_id: %s",
2478 gnutls_strerror (result
));
2480 flags
= cipher_to_flags (cinfo
->pkcs_cipher
);
2482 result
= gnutls_pkcs12_bag_encrypt (bag
, pass
, flags
);
2484 error (EXIT_FAILURE
, 0, "bag_encrypt: %s", gnutls_strerror (result
));
2486 result
= gnutls_pkcs12_set_bag (pkcs12
, bag
);
2488 error (EXIT_FAILURE
, 0, "set_bag: %s", gnutls_strerror (result
));
2493 gnutls_pkcs12_bag_t kbag
;
2495 result
= gnutls_pkcs12_bag_init (&kbag
);
2497 error (EXIT_FAILURE
, 0, "bag_init: %s", gnutls_strerror (result
));
2499 flags
= cipher_to_flags (cinfo
->pkcs_cipher
);
2503 gnutls_x509_privkey_export_pkcs8 (key
, GNUTLS_X509_FMT_DER
,
2504 pass
, flags
, buffer
, &size
);
2506 error (EXIT_FAILURE
, 0, "key_export: %s", gnutls_strerror (result
));
2511 gnutls_pkcs12_bag_set_data (kbag
,
2512 GNUTLS_BAG_PKCS8_ENCRYPTED_KEY
, &data
);
2514 error (EXIT_FAILURE
, 0, "bag_set_data: %s", gnutls_strerror (result
));
2518 result
= gnutls_pkcs12_bag_set_friendly_name (kbag
, indx
, name
);
2520 error (EXIT_FAILURE
, 0, "bag_set_friendly_name: %s",
2521 gnutls_strerror (result
));
2523 size
= sizeof (_key_id
);
2524 result
= gnutls_x509_privkey_get_key_id (key
, 0, _key_id
, &size
);
2526 error (EXIT_FAILURE
, 0, "key_id: %s", gnutls_strerror (result
));
2528 key_id
.data
= _key_id
;
2531 result
= gnutls_pkcs12_bag_set_key_id (kbag
, indx
, &key_id
);
2533 error (EXIT_FAILURE
, 0, "bag_set_key_id: %s",
2534 gnutls_strerror (result
));
2536 result
= gnutls_pkcs12_set_bag (pkcs12
, kbag
);
2538 error (EXIT_FAILURE
, 0, "set_bag: %s", gnutls_strerror (result
));
2541 result
= gnutls_pkcs12_generate_mac (pkcs12
, pass
);
2543 error (EXIT_FAILURE
, 0, "generate_mac: %s", gnutls_strerror (result
));
2546 result
= gnutls_pkcs12_export (pkcs12
, outcert_format
, buffer
, &size
);
2548 error (EXIT_FAILURE
, 0, "pkcs12_export: %s", gnutls_strerror (result
));
2550 fwrite (buffer
, 1, size
, outfile
);
2555 BAGTYPE (gnutls_pkcs12_bag_type_t x
)
2559 case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY
:
2560 return "PKCS #8 Encrypted key";
2561 case GNUTLS_BAG_EMPTY
:
2563 case GNUTLS_BAG_PKCS8_KEY
:
2564 return "PKCS #8 Key";
2565 case GNUTLS_BAG_CERTIFICATE
:
2566 return "Certificate";
2567 case GNUTLS_BAG_ENCRYPTED
:
2569 case GNUTLS_BAG_CRL
:
2571 case GNUTLS_BAG_SECRET
:
2579 print_bag_data (gnutls_pkcs12_bag_t bag
)
2583 gnutls_datum_t cdata
, id
;
2584 const char *str
, *name
;
2587 count
= gnutls_pkcs12_bag_get_count (bag
);
2589 error (EXIT_FAILURE
, 0, "get_count: %s", gnutls_strerror (count
));
2591 fprintf (outfile
, "\tElements: %d\n", count
);
2593 for (i
= 0; i
< count
; i
++)
2595 type
= gnutls_pkcs12_bag_get_type (bag
, i
);
2597 error (EXIT_FAILURE
, 0, "get_type: %s", gnutls_strerror (type
));
2599 fprintf (stderr
, "\tType: %s\n", BAGTYPE (type
));
2602 result
= gnutls_pkcs12_bag_get_friendly_name (bag
, i
, (char **) &name
);
2604 error (EXIT_FAILURE
, 0, "get_friendly_name: %s",
2605 gnutls_strerror (type
));
2607 fprintf (outfile
, "\tFriendly name: %s\n", name
);
2611 result
= gnutls_pkcs12_bag_get_key_id (bag
, i
, &id
);
2613 error (EXIT_FAILURE
, 0, "get_key_id: %s", gnutls_strerror (type
));
2615 fprintf (outfile
, "\tKey ID: %s\n", raw_to_string (id
.data
, id
.size
));
2617 result
= gnutls_pkcs12_bag_get_data (bag
, i
, &cdata
);
2619 error (EXIT_FAILURE
, 0, "get_data: %s", gnutls_strerror (result
));
2623 case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY
:
2624 str
= "ENCRYPTED PRIVATE KEY";
2626 case GNUTLS_BAG_PKCS8_KEY
:
2627 str
= "PRIVATE KEY";
2629 case GNUTLS_BAG_CERTIFICATE
:
2630 str
= "CERTIFICATE";
2632 case GNUTLS_BAG_CRL
:
2635 case GNUTLS_BAG_ENCRYPTED
:
2636 case GNUTLS_BAG_EMPTY
:
2643 gnutls_pem_base64_encode_alloc (str
, &cdata
, &out
);
2644 fprintf (outfile
, "%s\n", out
.data
);
2646 gnutls_free (out
.data
);
2653 pkcs12_info (common_info_st
* cinfo
)
2655 gnutls_pkcs12_t pkcs12
;
2656 gnutls_pkcs12_bag_t bag
;
2659 gnutls_datum_t data
;
2663 result
= gnutls_pkcs12_init (&pkcs12
);
2665 error (EXIT_FAILURE
, 0, "p12_init: %s", gnutls_strerror (result
));
2667 data
.data
= (void*)fread_file (infile
, &size
);
2670 result
= gnutls_pkcs12_import (pkcs12
, &data
, incert_format
, 0);
2673 error (EXIT_FAILURE
, 0, "p12_import: %s", gnutls_strerror (result
));
2675 if (cinfo
->password
)
2676 pass
= cinfo
->password
;
2680 result
= gnutls_pkcs12_verify_mac (pkcs12
, pass
);
2682 error (0, 0, "verify_mac: %s", gnutls_strerror (result
));
2684 for (indx
= 0;; indx
++)
2686 result
= gnutls_pkcs12_bag_init (&bag
);
2688 error (EXIT_FAILURE
, 0, "bag_init: %s", gnutls_strerror (result
));
2690 result
= gnutls_pkcs12_get_bag (pkcs12
, indx
, bag
);
2694 result
= gnutls_pkcs12_bag_get_count (bag
);
2696 error (EXIT_FAILURE
, 0, "bag_count: %s", gnutls_strerror (result
));
2698 fprintf (outfile
, "BAG #%d\n", indx
);
2700 result
= gnutls_pkcs12_bag_get_type (bag
, 0);
2702 error (EXIT_FAILURE
, 0, "bag_init: %s", gnutls_strerror (result
));
2704 if (result
== GNUTLS_BAG_ENCRYPTED
)
2706 fprintf (stderr
, "\tType: %s\n", BAGTYPE (result
));
2707 fprintf (stderr
, "\n\tDecrypting...\n");
2709 result
= gnutls_pkcs12_bag_decrypt (bag
, pass
);
2713 error (0, 0, "bag_decrypt: %s", gnutls_strerror (result
));
2717 result
= gnutls_pkcs12_bag_get_count (bag
);
2719 error (EXIT_FAILURE
, 0, "encrypted bag_count: %s",
2720 gnutls_strerror (result
));
2723 print_bag_data (bag
);
2725 gnutls_pkcs12_bag_deinit (bag
);
2732 gnutls_pkcs7_t pkcs7
;
2735 gnutls_datum_t data
, b64
;
2738 result
= gnutls_pkcs7_init (&pkcs7
);
2740 error (EXIT_FAILURE
, 0, "p7_init: %s", gnutls_strerror (result
));
2742 data
.data
= (void*)fread_file (infile
, &size
);
2745 result
= gnutls_pkcs7_import (pkcs7
, &data
, incert_format
);
2748 error (EXIT_FAILURE
, 0, "import error: %s", gnutls_strerror (result
));
2750 /* Read and print the certificates.
2752 result
= gnutls_pkcs7_get_crt_count (pkcs7
);
2754 error (EXIT_FAILURE
, 0, "p7_crt_count: %s", gnutls_strerror (result
));
2759 fprintf (outfile
, "Number of certificates: %u\n", count
);
2761 for (indx
= 0; indx
< count
; indx
++)
2763 fputs ("\n", outfile
);
2766 result
= gnutls_pkcs7_get_crt_raw (pkcs7
, indx
, buffer
, &size
);
2773 result
= gnutls_pem_base64_encode_alloc ("CERTIFICATE", &data
, &b64
);
2775 error (EXIT_FAILURE
, 0, "encoding: %s", gnutls_strerror (result
));
2777 fputs ((void*)b64
.data
, outfile
);
2778 gnutls_free (b64
.data
);
2781 /* Read the CRLs now.
2783 result
= gnutls_pkcs7_get_crl_count (pkcs7
);
2785 error (EXIT_FAILURE
, 0, "p7_crl_count: %s", gnutls_strerror (result
));
2790 fprintf (outfile
, "\nNumber of CRLs: %u\n", count
);
2792 for (indx
= 0; indx
< count
; indx
++)
2794 fputs ("\n", outfile
);
2797 result
= gnutls_pkcs7_get_crl_raw (pkcs7
, indx
, buffer
, &size
);
2804 result
= gnutls_pem_base64_encode_alloc ("X509 CRL", &data
, &b64
);
2806 error (EXIT_FAILURE
, 0, "encoding: %s", gnutls_strerror (result
));
2808 fputs ((void*)b64
.data
, outfile
);
2809 gnutls_free (b64
.data
);
2814 smime_to_pkcs7 (void)
2816 size_t linesize
= 0;
2817 char *lineptr
= NULL
;
2820 /* Find body. FIXME: Handle non-b64 Content-Transfer-Encoding.
2821 Reject non-S/MIME tagged Content-Type's? */
2824 len
= getline (&lineptr
, &linesize
, infile
);
2826 error (EXIT_FAILURE
, 0, "cannot find RFC 2822 header/body separator");
2828 while (strcmp (lineptr
, "\r\n") != 0 && strcmp (lineptr
, "\n") != 0);
2832 len
= getline (&lineptr
, &linesize
, infile
);
2834 error (EXIT_FAILURE
, 0, "message has RFC 2822 header but no body");
2836 while (strcmp (lineptr
, "\r\n") == 0 && strcmp (lineptr
, "\n") == 0);
2838 fprintf (outfile
, "%s", "-----BEGIN PKCS7-----\n");
2843 && (lineptr
[len
- 1] == '\r' || lineptr
[len
- 1] == '\n'))
2844 lineptr
[--len
] = '\0';
2845 if (strcmp (lineptr
, "") != 0)
2846 fprintf (outfile
, "%s\n", lineptr
);
2847 len
= getline (&lineptr
, &linesize
, infile
);
2851 fprintf (outfile
, "%s", "-----END PKCS7-----\n");
2857 certtool_version (void)
2859 const char *p
= PACKAGE_NAME
;
2860 if (strcmp (gnutls_check_version (NULL
), PACKAGE_VERSION
) != 0)
2862 version_etc (stdout
, program_name
, p
, gnutls_check_version (NULL
),
2863 "Nikos Mavrogiannopoulos", "Simon Josefsson", (char *) NULL
);
2867 print_key_usage (FILE * outfile
, unsigned int usage
)
2869 if (usage
& GNUTLS_KEY_DIGITAL_SIGNATURE
)
2871 fprintf (outfile
, "\tDigital signature.\n");
2874 if (usage
& GNUTLS_KEY_NON_REPUDIATION
)
2876 fprintf (outfile
, "\tNon repudiation.\n");
2879 if (usage
& GNUTLS_KEY_KEY_ENCIPHERMENT
)
2881 fprintf (outfile
, "\tKey encipherment.\n");
2884 if (usage
& GNUTLS_KEY_DATA_ENCIPHERMENT
)
2886 fprintf (outfile
, "\tData encipherment.\n");
2889 if (usage
& GNUTLS_KEY_KEY_AGREEMENT
)
2891 fprintf (outfile
, "\tKey agreement.\n");
2894 if (usage
& GNUTLS_KEY_KEY_CERT_SIGN
)
2896 fprintf (outfile
, "\tCertificate signing.\n");
2899 if (usage
& GNUTLS_KEY_NON_REPUDIATION
)
2901 fprintf (outfile
, "\tCRL signing.\n");
2904 if (usage
& GNUTLS_KEY_ENCIPHER_ONLY
)
2906 fprintf (outfile
, "\tKey encipher only.\n");
2909 if (usage
& GNUTLS_KEY_DECIPHER_ONLY
)
2911 fprintf (outfile
, "\tKey decipher only.\n");
2916 pubkey_info (gnutls_x509_crt_t crt
, common_info_st
* cinfo
)
2918 gnutls_pubkey_t pubkey
;
2919 unsigned int bits
, usage
;
2924 ret
= gnutls_pubkey_init (&pubkey
);
2927 error (EXIT_FAILURE
, 0, "pubkey_init: %s", gnutls_strerror (ret
));
2932 crt
= load_cert (0, cinfo
);
2937 ret
= gnutls_pubkey_import_x509 (pubkey
, crt
, 0);
2940 error (EXIT_FAILURE
, 0, "pubkey_import_x509: %s",
2941 gnutls_strerror (ret
));
2946 pubkey
= load_pubkey (1, cinfo
);
2949 if (outcert_format
== GNUTLS_X509_FMT_DER
)
2952 ret
= gnutls_pubkey_export (pubkey
, outcert_format
, buffer
, &size
);
2954 error (EXIT_FAILURE
, 0, "export error: %s", gnutls_strerror (ret
));
2956 fwrite (buffer
, 1, size
, outfile
);
2958 gnutls_pubkey_deinit (pubkey
);
2965 fprintf (outfile
, "Public Key Info:\n\n");
2966 ret
= gnutls_pubkey_get_pk_algorithm (pubkey
, &bits
);
2967 fprintf (outfile
, "Public Key Algorithm: ");
2969 cprint
= gnutls_pk_algorithm_get_name (ret
);
2970 fprintf (outfile
, "%s (%u bits)\n", cprint
? cprint
: "Unknown", bits
);
2973 /* Print the raw public and private keys
2975 if (ret
== GNUTLS_PK_RSA
)
2977 gnutls_datum_t m
, e
;
2979 ret
= gnutls_pubkey_get_pk_rsa_raw (pubkey
, &m
, &e
);
2981 fprintf (stderr
, "Error in key RSA data export: %s\n",
2982 gnutls_strerror (ret
));
2985 print_rsa_pkey (&m
, &e
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
2986 gnutls_free (m
.data
);
2987 gnutls_free (e
.data
);
2990 else if (ret
== GNUTLS_PK_DSA
)
2992 gnutls_datum_t p
, q
, g
, y
;
2994 ret
= gnutls_pubkey_get_pk_dsa_raw (pubkey
, &p
, &q
, &g
, &y
);
2996 fprintf (stderr
, "Error in key DSA data export: %s\n",
2997 gnutls_strerror (ret
));
3000 print_dsa_pkey (NULL
, &y
, &p
, &q
, &g
);
3001 gnutls_free (y
.data
);
3002 gnutls_free (p
.data
);
3003 gnutls_free (q
.data
);
3004 gnutls_free (g
.data
);
3007 else if (ret
== GNUTLS_PK_EC
)
3009 gnutls_datum_t x
, y
;
3010 gnutls_ecc_curve_t curve
;
3012 ret
= gnutls_pubkey_get_pk_ecc_raw (pubkey
, &curve
, &x
, &y
);
3014 fprintf (stderr
, "Error in key ECC data export: %s\n",
3015 gnutls_strerror (ret
));
3018 print_ecc_pkey (curve
, NULL
, &y
, &x
);
3019 gnutls_free (y
.data
);
3020 gnutls_free (x
.data
);
3024 ret
= gnutls_pubkey_get_key_usage (pubkey
, &usage
);
3027 error (EXIT_FAILURE
, 0, "pubkey_get_key_usage: %s",
3028 gnutls_strerror (ret
));
3031 fprintf (outfile
, "Public Key Usage:\n");
3032 print_key_usage (outfile
, usage
);
3034 fprintf (outfile
, "\n");
3037 if ((ret
= gnutls_pubkey_get_key_id (pubkey
, 0, buffer
, &size
)) < 0)
3039 fprintf (stderr
, "Error in key id calculation: %s\n",
3040 gnutls_strerror (ret
));
3044 fprintf (outfile
, "Public Key ID: %s\n", raw_to_string (buffer
, size
));
3048 ret
= gnutls_pubkey_export (pubkey
, GNUTLS_X509_FMT_PEM
, buffer
, &size
);
3050 error (EXIT_FAILURE
, 0, "export error: %s", gnutls_strerror (ret
));
3052 fprintf (outfile
, "\n%s\n", buffer
);
3054 gnutls_pubkey_deinit (pubkey
);