set PIN function when reading a certificate
[gnutls.git] / src / certtool.c
bloba8e5f6c6a7e1d329b115c6686dd048dafacaaa15
1 /*
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/>.
21 #include <config.h>
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>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <ctype.h>
34 #include <time.h>
35 #include <unistd.h>
36 #include <errno.h>
37 #include <sys/types.h>
38 #include <sys/stat.h>
39 #include <fcntl.h>
40 #include <error.h>
42 /* Gnulib portability files. */
43 #include <read-file.h>
44 #include <progname.h>
45 #include <version-etc.h>
47 #include <certtool-cfg.h>
48 #include <common.h>
49 #include "certtool-args.h"
50 #include "certtool-common.h"
52 #define SIGN_HASH GNUTLS_DIG_SHA256
54 static void privkey_info_int (common_info_st*, gnutls_x509_privkey_t key);
55 static void print_crl_info (gnutls_x509_crl_t crl, FILE * out);
56 void pkcs7_info (void);
57 void crq_info (void);
58 void smime_to_pkcs7 (void);
59 void pkcs12_info (common_info_st*);
60 void generate_pkcs12 (common_info_st *);
61 void generate_pkcs8 (common_info_st *);
62 static void verify_chain (void);
63 void verify_crl (common_info_st * cinfo);
64 void pubkey_info (gnutls_x509_crt_t crt, common_info_st *);
65 void pgp_privkey_info (void);
66 void pgp_ring_info (void);
67 void certificate_info (int, common_info_st *);
68 void pgp_certificate_info (void);
69 void crl_info (void);
70 void privkey_info (common_info_st*);
71 static void cmd_parser (int argc, char **argv);
72 void generate_self_signed (common_info_st *);
73 void generate_request (common_info_st *);
74 static void print_certificate_info (gnutls_x509_crt_t crt, FILE * out,
75 unsigned int all);
76 static void verify_certificate (common_info_st * cinfo);
78 FILE *outfile;
79 FILE *infile;
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
86 int batch;
89 static void
90 tls_log_func (int level, const char *str)
92 fprintf (stderr, "|<%d>| %s", level, str);
95 int
96 main (int argc, char **argv)
98 set_program_name (argv[0]);
99 cfg_init ();
100 cmd_parser (argc, argv);
102 return 0;
105 static gnutls_x509_privkey_t
106 generate_private_key_int (common_info_st * cinfo)
108 gnutls_x509_privkey_t key;
109 int ret, key_type, bits;
111 key_type = req_key_type;
113 ret = gnutls_x509_privkey_init (&key);
114 if (ret < 0)
115 error (EXIT_FAILURE, 0, "privkey_init: %s", gnutls_strerror (ret));
117 bits = get_bits (key_type, cinfo->bits, cinfo->sec_param);
119 fprintf (stderr, "Generating a %d bit %s private key...\n",
120 bits, gnutls_pk_algorithm_get_name (key_type));
122 if (bits > 1024 && key_type == GNUTLS_PK_DSA)
123 fprintf (stderr,
124 "Note that DSA keys with size over 1024 can only be used with TLS 1.2 or later.\n\n");
126 ret = gnutls_x509_privkey_generate (key, key_type, bits, 0);
127 if (ret < 0)
128 error (EXIT_FAILURE, 0, "privkey_generate: %s", gnutls_strerror (ret));
130 ret = gnutls_x509_privkey_verify_params (key);
131 if (ret < 0)
132 error (EXIT_FAILURE, 0, "privkey_verify_params: %s", gnutls_strerror (ret));
134 return key;
137 static int
138 cipher_to_flags (const char *cipher)
140 if (cipher == NULL)
142 return GNUTLS_PKCS_USE_PBES2_AES_128;
144 else if (strcasecmp (cipher, "3des") == 0)
146 return GNUTLS_PKCS_USE_PBES2_3DES;
148 else if (strcasecmp (cipher, "3des-pkcs12") == 0)
150 return GNUTLS_PKCS_USE_PKCS12_3DES;
152 else if (strcasecmp (cipher, "arcfour") == 0)
154 return GNUTLS_PKCS_USE_PKCS12_ARCFOUR;
156 else if (strcasecmp (cipher, "aes-128") == 0)
158 return GNUTLS_PKCS_USE_PBES2_AES_128;
160 else if (strcasecmp (cipher, "aes-192") == 0)
162 return GNUTLS_PKCS_USE_PBES2_AES_192;
164 else if (strcasecmp (cipher, "aes-256") == 0)
166 return GNUTLS_PKCS_USE_PBES2_AES_256;
168 else if (strcasecmp (cipher, "rc2-40") == 0)
170 return GNUTLS_PKCS_USE_PKCS12_RC2_40;
173 error (EXIT_FAILURE, 0, "unknown cipher %s\n", cipher);
174 return -1;
178 static void
179 print_private_key (common_info_st* cinfo, gnutls_x509_privkey_t key)
181 int ret;
182 size_t size;
184 if (!key)
185 return;
187 if (outcert_format == GNUTLS_X509_FMT_PEM)
188 privkey_info_int(cinfo, key);
190 if (!cinfo->pkcs8)
192 size = buffer_size;
193 ret = gnutls_x509_privkey_export (key, outcert_format,
194 buffer, &size);
195 if (ret < 0)
196 error (EXIT_FAILURE, 0, "privkey_export: %s", gnutls_strerror (ret));
198 else
200 unsigned int flags;
201 const char *pass;
203 flags = cipher_to_flags (cinfo->pkcs_cipher);
205 if ((pass = get_confirmed_pass (true)) == NULL || *pass == '\0')
206 flags = GNUTLS_PKCS_PLAIN;
208 size = buffer_size;
209 ret =
210 gnutls_x509_privkey_export_pkcs8 (key, outcert_format, pass,
211 flags, buffer, &size);
212 if (ret < 0)
213 error (EXIT_FAILURE, 0, "privkey_export_pkcs8: %s",
214 gnutls_strerror (ret));
217 fwrite (buffer, 1, size, outfile);
220 static void
221 generate_private_key (common_info_st* cinfo)
223 gnutls_x509_privkey_t key;
225 key = generate_private_key_int (cinfo);
227 print_private_key (cinfo, key);
229 gnutls_x509_privkey_deinit (key);
233 static gnutls_x509_crt_t
234 generate_certificate (gnutls_privkey_t * ret_key,
235 gnutls_x509_crt_t ca_crt, int proxy,
236 common_info_st * cinfo)
238 gnutls_x509_crt_t crt;
239 gnutls_privkey_t key = NULL;
240 gnutls_pubkey_t pubkey;
241 size_t size;
242 int ret;
243 int client;
244 int days, result, ca_status = 0, is_ike = 0, path_len;
245 int vers;
246 unsigned int usage = 0, server;
247 gnutls_x509_crq_t crq; /* request */
249 ret = gnutls_x509_crt_init (&crt);
250 if (ret < 0)
251 error (EXIT_FAILURE, 0, "crt_init: %s", gnutls_strerror (ret));
253 crq = load_request (cinfo);
255 if (crq == NULL)
258 key = load_private_key (1, cinfo);
260 pubkey = load_public_key_or_import (1, key, cinfo);
262 if (!batch)
263 fprintf (stderr,
264 "Please enter the details of the certificate's distinguished name. "
265 "Just press enter to ignore a field.\n");
267 /* set the DN.
269 if (proxy)
271 result = gnutls_x509_crt_set_proxy_dn (crt, ca_crt, 0, NULL, 0);
272 if (result < 0)
273 error (EXIT_FAILURE, 0, "set_proxy_dn: %s",
274 gnutls_strerror (result));
276 get_cn_crt_set (crt);
278 else
280 get_country_crt_set (crt);
281 get_organization_crt_set (crt);
282 get_unit_crt_set (crt);
283 get_locality_crt_set (crt);
284 get_state_crt_set (crt);
285 get_cn_crt_set (crt);
286 get_dc_set (TYPE_CRT, crt);
287 get_uid_crt_set (crt);
288 get_oid_crt_set (crt);
289 get_key_purpose_set (crt);
291 if (!batch)
292 fprintf (stderr,
293 "This field should not be used in new certificates.\n");
295 get_pkcs9_email_crt_set (crt);
298 result = gnutls_x509_crt_set_pubkey (crt, pubkey);
299 if (result < 0)
300 error (EXIT_FAILURE, 0, "set_key: %s", gnutls_strerror (result));
302 else
304 result = gnutls_x509_crt_set_crq (crt, crq);
305 if (result < 0)
306 error (EXIT_FAILURE, 0, "set_crq: %s", gnutls_strerror (result));
311 int serial = get_serial ();
312 char bin_serial[5];
314 bin_serial[4] = serial & 0xff;
315 bin_serial[3] = (serial >> 8) & 0xff;
316 bin_serial[2] = (serial >> 16) & 0xff;
317 bin_serial[1] = (serial >> 24) & 0xff;
318 bin_serial[0] = 0;
320 result = gnutls_x509_crt_set_serial (crt, bin_serial, 5);
321 if (result < 0)
322 error (EXIT_FAILURE, 0, "serial: %s", gnutls_strerror (result));
325 if (!batch)
326 fprintf (stderr, "\n\nActivation/Expiration time.\n");
328 gnutls_x509_crt_set_activation_time (crt, time (NULL));
330 days = get_days ();
332 result =
333 gnutls_x509_crt_set_expiration_time (crt,
334 time (NULL) + ((time_t) days) * 24 * 60 * 60);
335 if (result < 0)
336 error (EXIT_FAILURE, 0, "set_expiration: %s", gnutls_strerror (result));
338 if (!batch)
339 fprintf (stderr, "\n\nExtensions.\n");
341 /* do not allow extensions on a v1 certificate */
342 if (crq && get_crq_extensions_status () != 0)
344 result = gnutls_x509_crt_set_crq_extensions (crt, crq);
345 if (result < 0)
346 error (EXIT_FAILURE, 0, "set_crq: %s", gnutls_strerror (result));
349 /* append additional extensions */
350 if (cinfo->v1_cert == 0)
353 if (proxy)
355 const char *policylanguage;
356 char *policy;
357 size_t policylen;
358 int proxypathlen = get_path_len ();
360 if (!batch)
362 printf ("1.3.6.1.5.5.7.21.1 ::= id-ppl-inheritALL\n");
363 printf ("1.3.6.1.5.5.7.21.2 ::= id-ppl-independent\n");
366 policylanguage = get_proxy_policy (&policy, &policylen);
368 result =
369 gnutls_x509_crt_set_proxy (crt, proxypathlen, policylanguage,
370 policy, policylen);
371 if (result < 0)
372 error (EXIT_FAILURE, 0, "set_proxy: %s",
373 gnutls_strerror (result));
376 if (!proxy)
377 ca_status = get_ca_status ();
378 if (ca_status)
379 path_len = get_path_len ();
380 else
381 path_len = -1;
383 result =
384 gnutls_x509_crt_set_basic_constraints (crt, ca_status, path_len);
385 if (result < 0)
386 error (EXIT_FAILURE, 0, "basic_constraints: %s",
387 gnutls_strerror (result));
389 client = get_tls_client_status ();
390 if (client != 0)
392 result = gnutls_x509_crt_set_key_purpose_oid (crt,
393 GNUTLS_KP_TLS_WWW_CLIENT,
395 if (result < 0)
396 error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (result));
399 is_ike = get_ipsec_ike_status ();
400 server = get_tls_server_status ();
402 get_dns_name_set (TYPE_CRT, crt);
403 get_uri_set (TYPE_CRT, crt);
404 get_ip_addr_set (TYPE_CRT, crt);
406 if (server != 0)
408 result = 0;
410 result =
411 gnutls_x509_crt_set_key_purpose_oid (crt,
412 GNUTLS_KP_TLS_WWW_SERVER, 0);
413 if (result < 0)
414 error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (result));
416 else if (!proxy)
418 get_email_set (TYPE_CRT, crt);
421 if (!ca_status || server)
423 int pk;
426 pk = gnutls_x509_crt_get_pk_algorithm (crt, NULL);
428 if (pk != GNUTLS_PK_DSA)
429 { /* DSA keys can only sign.
431 result = get_sign_status (server);
432 if (result)
433 usage |= GNUTLS_KEY_DIGITAL_SIGNATURE;
435 result = get_encrypt_status (server);
436 if (result)
437 usage |= GNUTLS_KEY_KEY_ENCIPHERMENT;
439 else
440 usage |= GNUTLS_KEY_DIGITAL_SIGNATURE;
442 if (is_ike)
444 result =
445 gnutls_x509_crt_set_key_purpose_oid (crt,
446 GNUTLS_KP_IPSEC_IKE, 0);
447 if (result < 0)
448 error (EXIT_FAILURE, 0, "key_kp: %s",
449 gnutls_strerror (result));
454 if (ca_status)
456 result = get_cert_sign_status ();
457 if (result)
458 usage |= GNUTLS_KEY_KEY_CERT_SIGN;
460 result = get_crl_sign_status ();
461 if (result)
462 usage |= GNUTLS_KEY_CRL_SIGN;
464 result = get_code_sign_status ();
465 if (result)
467 result =
468 gnutls_x509_crt_set_key_purpose_oid (crt,
469 GNUTLS_KP_CODE_SIGNING,
471 if (result < 0)
472 error (EXIT_FAILURE, 0, "key_kp: %s",
473 gnutls_strerror (result));
476 result = get_ocsp_sign_status ();
477 if (result)
479 result =
480 gnutls_x509_crt_set_key_purpose_oid (crt,
481 GNUTLS_KP_OCSP_SIGNING,
483 if (result < 0)
484 error (EXIT_FAILURE, 0, "key_kp: %s",
485 gnutls_strerror (result));
488 result = get_time_stamp_status ();
489 if (result)
491 result =
492 gnutls_x509_crt_set_key_purpose_oid (crt,
493 GNUTLS_KP_TIME_STAMPING,
495 if (result < 0)
496 error (EXIT_FAILURE, 0, "key_kp: %s",
497 gnutls_strerror (result));
500 get_ocsp_issuer_set(crt);
501 get_ca_issuers_set(crt);
503 if (usage != 0)
505 /* http://tools.ietf.org/html/rfc4945#section-5.1.3.2: if any KU is
506 set, then either digitalSignature or the nonRepudiation bits in the
507 KeyUsage extension MUST for all IKE certs */
508 if (is_ike && (get_sign_status (server) != 1))
509 usage |= GNUTLS_KEY_NON_REPUDIATION;
510 result = gnutls_x509_crt_set_key_usage (crt, usage);
511 if (result < 0)
512 error (EXIT_FAILURE, 0, "key_usage: %s",
513 gnutls_strerror (result));
516 /* Subject Key ID.
518 size = buffer_size;
519 result = gnutls_x509_crt_get_key_id (crt, 0, buffer, &size);
520 if (result >= 0)
522 result = gnutls_x509_crt_set_subject_key_id (crt, buffer, size);
523 if (result < 0)
524 error (EXIT_FAILURE, 0, "set_subject_key_id: %s",
525 gnutls_strerror (result));
528 /* Authority Key ID.
530 if (ca_crt != NULL)
532 size = buffer_size;
533 result = gnutls_x509_crt_get_subject_key_id (ca_crt, buffer,
534 &size, NULL);
535 if (result < 0)
537 size = buffer_size;
538 result = gnutls_x509_crt_get_key_id (ca_crt, 0, buffer, &size);
540 if (result >= 0)
542 result =
543 gnutls_x509_crt_set_authority_key_id (crt, buffer, size);
544 if (result < 0)
545 error (EXIT_FAILURE, 0, "set_authority_key_id: %s",
546 gnutls_strerror (result));
551 /* Version.
553 if (cinfo->v1_cert != 0)
554 vers = 1;
555 else
556 vers = 3;
557 result = gnutls_x509_crt_set_version (crt, vers);
558 if (result < 0)
559 error (EXIT_FAILURE, 0, "set_version: %s", gnutls_strerror (result));
561 *ret_key = key;
562 return crt;
566 static gnutls_x509_crl_t
567 generate_crl (gnutls_x509_crt_t ca_crt, common_info_st * cinfo)
569 gnutls_x509_crl_t crl;
570 gnutls_x509_crt_t *crts;
571 size_t size;
572 int days, result;
573 unsigned int i;
574 time_t now = time (NULL);
576 result = gnutls_x509_crl_init (&crl);
577 if (result < 0)
578 error (EXIT_FAILURE, 0, "crl_init: %s", gnutls_strerror (result));
580 crts = load_cert_list (0, &size, cinfo);
582 for (i = 0; i < size; i++)
584 result = gnutls_x509_crl_set_crt (crl, crts[i], now);
585 if (result < 0)
586 error (EXIT_FAILURE, 0, "crl_set_crt: %s", gnutls_strerror (result));
589 result = gnutls_x509_crl_set_this_update (crl, now);
590 if (result < 0)
591 error (EXIT_FAILURE, 0, "this_update: %s", gnutls_strerror (result));
593 fprintf (stderr, "Update times.\n");
594 days = get_crl_next_update ();
596 result = gnutls_x509_crl_set_next_update (crl, now + days * 24 * 60 * 60);
597 if (result < 0)
598 error (EXIT_FAILURE, 0, "next_update: %s", gnutls_strerror (result));
600 result = gnutls_x509_crl_set_version (crl, 2);
601 if (result < 0)
602 error (EXIT_FAILURE, 0, "set_version: %s", gnutls_strerror (result));
604 /* Authority Key ID.
606 if (ca_crt != NULL)
608 size = buffer_size;
609 result = gnutls_x509_crt_get_subject_key_id (ca_crt, buffer,
610 &size, NULL);
611 if (result < 0)
613 size = buffer_size;
614 result = gnutls_x509_crt_get_key_id (ca_crt, 0, buffer, &size);
616 if (result >= 0)
618 result = gnutls_x509_crl_set_authority_key_id (crl, buffer, size);
619 if (result < 0)
620 error (EXIT_FAILURE, 0, "set_authority_key_id: %s",
621 gnutls_strerror (result));
626 unsigned int number = get_crl_number ();
627 char bin_number[5];
629 bin_number[4] = number & 0xff;
630 bin_number[3] = (number >> 8) & 0xff;
631 bin_number[2] = (number >> 16) & 0xff;
632 bin_number[1] = (number >> 24) & 0xff;
633 bin_number[0] = 0;
635 result = gnutls_x509_crl_set_number (crl, bin_number, 5);
636 if (result < 0)
637 error (EXIT_FAILURE, 0, "set_number: %s", gnutls_strerror (result));
640 return crl;
643 static gnutls_digest_algorithm_t
644 get_dig (gnutls_x509_crt_t crt)
646 gnutls_digest_algorithm_t dig;
647 gnutls_pubkey_t pubkey;
648 int result;
649 unsigned int mand;
651 gnutls_pubkey_init(&pubkey);
653 result = gnutls_pubkey_import_x509(pubkey, crt, 0);
654 if (result < 0)
656 error (EXIT_FAILURE, 0, "gnutls_pubkey_import_x509: %s",
657 gnutls_strerror (result));
660 result = gnutls_pubkey_get_preferred_hash_algorithm (pubkey, &dig, &mand);
661 if (result < 0)
663 error (EXIT_FAILURE, 0, "crt_get_preferred_hash_algorithm: %s",
664 gnutls_strerror (result));
667 gnutls_pubkey_deinit(pubkey);
669 /* if algorithm allows alternatives */
670 if (mand == 0 && default_dig != GNUTLS_DIG_UNKNOWN)
671 dig = default_dig;
673 return dig;
676 void
677 generate_self_signed (common_info_st * cinfo)
679 gnutls_x509_crt_t crt;
680 gnutls_privkey_t key;
681 size_t size;
682 int result;
683 const char *uri;
685 fprintf (stderr, "Generating a self signed certificate...\n");
687 crt = generate_certificate (&key, NULL, 0, cinfo);
689 if (!key)
690 key = load_private_key (1, cinfo);
692 uri = get_crl_dist_point_url ();
693 if (uri)
695 result = gnutls_x509_crt_set_crl_dist_points (crt, GNUTLS_SAN_URI,
696 uri,
697 0 /* all reasons */ );
698 if (result < 0)
699 error (EXIT_FAILURE, 0, "crl_dist_points: %s",
700 gnutls_strerror (result));
703 print_certificate_info (crt, stderr, 0);
705 fprintf (stderr, "\n\nSigning certificate...\n");
707 result = gnutls_x509_crt_privkey_sign (crt, crt, key, get_dig (crt), 0);
708 if (result < 0)
709 error (EXIT_FAILURE, 0, "crt_sign: %s", gnutls_strerror (result));
711 size = buffer_size;
712 result = gnutls_x509_crt_export (crt, outcert_format, buffer, &size);
713 if (result < 0)
714 error (EXIT_FAILURE, 0, "crt_export: %s", gnutls_strerror (result));
716 fwrite (buffer, 1, size, outfile);
718 gnutls_x509_crt_deinit (crt);
719 gnutls_privkey_deinit (key);
722 static void
723 generate_signed_certificate (common_info_st * cinfo)
725 gnutls_x509_crt_t crt;
726 gnutls_privkey_t key;
727 size_t size;
728 int result;
729 gnutls_privkey_t ca_key;
730 gnutls_x509_crt_t ca_crt;
732 fprintf (stderr, "Generating a signed certificate...\n");
734 ca_key = load_ca_private_key (cinfo);
735 ca_crt = load_ca_cert (cinfo);
737 crt = generate_certificate (&key, ca_crt, 0, cinfo);
739 /* Copy the CRL distribution points.
741 gnutls_x509_crt_cpy_crl_dist_points (crt, ca_crt);
742 /* it doesn't matter if we couldn't copy the CRL dist points.
745 print_certificate_info (crt, stderr, 0);
747 fprintf (stderr, "\n\nSigning certificate...\n");
749 result = gnutls_x509_crt_privkey_sign (crt, ca_crt, ca_key, get_dig (ca_crt), 0);
750 if (result < 0)
751 error (EXIT_FAILURE, 0, "crt_sign: %s", gnutls_strerror (result));
753 size = buffer_size;
754 result = gnutls_x509_crt_export (crt, outcert_format, buffer, &size);
755 if (result < 0)
756 error (EXIT_FAILURE, 0, "crt_export: %s", gnutls_strerror (result));
758 fwrite (buffer, 1, size, outfile);
760 gnutls_x509_crt_deinit (crt);
761 gnutls_privkey_deinit (key);
762 gnutls_privkey_deinit(ca_key);
765 static void
766 generate_proxy_certificate (common_info_st * cinfo)
768 gnutls_x509_crt_t crt, eecrt;
769 gnutls_privkey_t key, eekey;
770 size_t size;
771 int result;
773 fprintf (stderr, "Generating a proxy certificate...\n");
775 eekey = load_ca_private_key (cinfo);
776 eecrt = load_cert (1, cinfo);
778 crt = generate_certificate (&key, eecrt, 1, cinfo);
780 print_certificate_info (crt, stderr, 0);
782 fprintf (stderr, "\n\nSigning certificate...\n");
784 result = gnutls_x509_crt_privkey_sign (crt, eecrt, eekey, get_dig (eecrt), 0);
785 if (result < 0)
786 error (EXIT_FAILURE, 0, "crt_sign: %s", gnutls_strerror (result));
788 size = buffer_size;
789 result = gnutls_x509_crt_export (crt, outcert_format, buffer, &size);
790 if (result < 0)
791 error (EXIT_FAILURE, 0, "crt_export: %s", gnutls_strerror (result));
793 fwrite (buffer, 1, size, outfile);
795 gnutls_x509_crt_deinit (eecrt);
796 gnutls_x509_crt_deinit (crt);
797 gnutls_privkey_deinit (key);
798 gnutls_privkey_deinit (eekey);
801 static void
802 generate_signed_crl (common_info_st * cinfo)
804 gnutls_x509_crl_t crl;
805 int result;
806 gnutls_privkey_t ca_key;
807 gnutls_x509_crt_t ca_crt;
809 fprintf (stderr, "Generating a signed CRL...\n");
811 ca_key = load_ca_private_key (cinfo);
812 ca_crt = load_ca_cert (cinfo);
813 crl = generate_crl (ca_crt, cinfo);
815 fprintf (stderr, "\n");
816 result = gnutls_x509_crl_privkey_sign(crl, ca_crt, ca_key, SIGN_HASH, 0);
817 if (result < 0)
818 error (EXIT_FAILURE, 0, "crl_privkey_sign: %s", gnutls_strerror (result));
820 print_crl_info (crl, stderr);
822 gnutls_privkey_deinit( ca_key);
823 gnutls_x509_crl_deinit (crl);
826 static void
827 update_signed_certificate (common_info_st * cinfo)
829 gnutls_x509_crt_t crt;
830 size_t size;
831 int result;
832 gnutls_privkey_t ca_key;
833 gnutls_x509_crt_t ca_crt;
834 int days;
835 time_t tim = time (NULL);
837 fprintf (stderr, "Generating a signed certificate...\n");
839 ca_key = load_ca_private_key (cinfo);
840 ca_crt = load_ca_cert (cinfo);
841 crt = load_cert (1, cinfo);
843 fprintf (stderr, "Activation/Expiration time.\n");
844 gnutls_x509_crt_set_activation_time (crt, tim);
846 days = get_days ();
848 result =
849 gnutls_x509_crt_set_expiration_time (crt, tim + ((time_t) days) * 24 * 60 * 60);
850 if (result < 0)
851 error (EXIT_FAILURE, 0, "set_expiration: %s", gnutls_strerror (result));
853 fprintf (stderr, "\n\nSigning certificate...\n");
855 result = gnutls_x509_crt_privkey_sign (crt, ca_crt, ca_key, get_dig (ca_crt), 0);
856 if (result < 0)
857 error (EXIT_FAILURE, 0, "crt_sign: %s", gnutls_strerror (result));
859 size = buffer_size;
860 result = gnutls_x509_crt_export (crt, outcert_format, buffer, &size);
861 if (result < 0)
862 error (EXIT_FAILURE, 0, "crt_export: %s", gnutls_strerror (result));
864 fwrite (buffer, 1, size, outfile);
866 gnutls_x509_crt_deinit (crt);
869 static void
870 cmd_parser (int argc, char **argv)
872 int ret, privkey_op = 0;
873 common_info_st cinfo;
875 optionProcess( &certtoolOptions, argc, argv);
877 if (HAVE_OPT(GENERATE_PRIVKEY) || HAVE_OPT(GENERATE_REQUEST) ||
878 HAVE_OPT(KEY_INFO) || HAVE_OPT(PGP_KEY_INFO))
879 privkey_op = 1;
881 if (HAVE_OPT(OUTFILE))
883 outfile = safe_open_rw (OPT_ARG(OUTFILE), privkey_op);
884 if (outfile == NULL)
885 error (EXIT_FAILURE, errno, "%s", OPT_ARG(OUTFILE));
887 else
888 outfile = stdout;
890 if (HAVE_OPT(INFILE))
892 infile = fopen (OPT_ARG(INFILE), "rb");
893 if (infile == NULL)
894 error (EXIT_FAILURE, errno, "%s", OPT_ARG(INFILE));
896 else
897 infile = stdin;
899 if (HAVE_OPT(INDER) || HAVE_OPT(INRAW))
900 incert_format = GNUTLS_X509_FMT_DER;
901 else
902 incert_format = GNUTLS_X509_FMT_PEM;
904 if (HAVE_OPT(OUTDER) || HAVE_OPT(OUTRAW))
905 outcert_format = GNUTLS_X509_FMT_DER;
906 else
907 outcert_format = GNUTLS_X509_FMT_PEM;
909 if (HAVE_OPT(DSA))
910 req_key_type = GNUTLS_PK_DSA;
911 else if (HAVE_OPT(ECC))
912 req_key_type = GNUTLS_PK_ECC;
913 else
914 req_key_type = GNUTLS_PK_RSA;
916 default_dig = GNUTLS_DIG_UNKNOWN;
917 if (HAVE_OPT(HASH))
919 if (strcasecmp (OPT_ARG(HASH), "md5") == 0)
921 fprintf (stderr,
922 "Warning: MD5 is broken, and should not be used any more for digital signatures.\n");
923 default_dig = GNUTLS_DIG_MD5;
925 else if (strcasecmp (OPT_ARG(HASH), "sha1") == 0)
926 default_dig = GNUTLS_DIG_SHA1;
927 else if (strcasecmp (OPT_ARG(HASH), "sha256") == 0)
928 default_dig = GNUTLS_DIG_SHA256;
929 else if (strcasecmp (OPT_ARG(HASH), "sha224") == 0)
930 default_dig = GNUTLS_DIG_SHA224;
931 else if (strcasecmp (OPT_ARG(HASH), "sha384") == 0)
932 default_dig = GNUTLS_DIG_SHA384;
933 else if (strcasecmp (OPT_ARG(HASH), "sha512") == 0)
934 default_dig = GNUTLS_DIG_SHA512;
935 else if (strcasecmp (OPT_ARG(HASH), "rmd160") == 0)
936 default_dig = GNUTLS_DIG_RMD160;
937 else
938 error (EXIT_FAILURE, 0, "invalid hash: %s", OPT_ARG(HASH));
941 batch = 0;
942 if (HAVE_OPT(TEMPLATE))
944 batch = 1;
945 template_parse (OPT_ARG(TEMPLATE));
948 gnutls_global_set_log_function (tls_log_func);
950 if (HAVE_OPT(DEBUG))
952 gnutls_global_set_log_level (OPT_VALUE_DEBUG);
953 printf ("Setting log level to %d\n", (int)OPT_VALUE_DEBUG);
956 if ((ret = gnutls_global_init ()) < 0)
957 error (EXIT_FAILURE, 0, "global_init: %s", gnutls_strerror (ret));
959 #ifdef ENABLE_PKCS11
960 pkcs11_common();
961 #endif
963 memset (&cinfo, 0, sizeof (cinfo));
965 if (HAVE_OPT(LOAD_PRIVKEY))
966 cinfo.privkey = OPT_ARG(LOAD_PRIVKEY);
968 cinfo.v1_cert = HAVE_OPT(V1);
969 if (HAVE_OPT(NO_CRQ_EXTENSIONS))
970 cinfo.crq_extensions = 0;
971 else cinfo.crq_extensions = 1;
973 if (HAVE_OPT(LOAD_PUBKEY))
974 cinfo.pubkey = OPT_ARG(LOAD_PUBKEY);
976 cinfo.pkcs8 = HAVE_OPT(PKCS8);
977 cinfo.incert_format = incert_format;
979 if (HAVE_OPT(LOAD_CERTIFICATE))
980 cinfo.cert = OPT_ARG(LOAD_CERTIFICATE);
982 if (HAVE_OPT(LOAD_REQUEST))
983 cinfo.request = OPT_ARG(LOAD_REQUEST);
985 if (HAVE_OPT(LOAD_CA_CERTIFICATE))
986 cinfo.ca = OPT_ARG(LOAD_CA_CERTIFICATE);
988 if (HAVE_OPT(LOAD_CA_PRIVKEY))
989 cinfo.ca_privkey = OPT_ARG(LOAD_CA_PRIVKEY);
991 if (HAVE_OPT(BITS))
992 cinfo.bits = OPT_VALUE_BITS;
994 if (HAVE_OPT(SEC_PARAM))
995 cinfo.sec_param = OPT_ARG(SEC_PARAM);
997 if (HAVE_OPT(PKCS_CIPHER))
998 cinfo.pkcs_cipher = OPT_ARG(PKCS_CIPHER);
1000 if (HAVE_OPT(PASSWORD))
1001 cinfo.password = OPT_ARG(PASSWORD);
1003 if (HAVE_OPT(GENERATE_SELF_SIGNED))
1004 generate_self_signed (&cinfo);
1005 else if (HAVE_OPT(GENERATE_CERTIFICATE))
1006 generate_signed_certificate (&cinfo);
1007 else if (HAVE_OPT(GENERATE_PROXY))
1008 generate_proxy_certificate (&cinfo);
1009 else if (HAVE_OPT(GENERATE_CRL))
1010 generate_signed_crl (&cinfo);
1011 else if (HAVE_OPT(UPDATE_CERTIFICATE))
1012 update_signed_certificate (&cinfo);
1013 else if (HAVE_OPT(GENERATE_PRIVKEY))
1014 generate_private_key (&cinfo);
1015 else if (HAVE_OPT(GENERATE_REQUEST))
1016 generate_request (&cinfo);
1017 else if (HAVE_OPT(VERIFY_CHAIN))
1018 verify_chain ();
1019 else if (HAVE_OPT(VERIFY))
1020 verify_certificate (&cinfo);
1021 else if (HAVE_OPT(VERIFY_CRL))
1022 verify_crl (&cinfo);
1023 else if (HAVE_OPT(CERTIFICATE_INFO))
1024 certificate_info (0, &cinfo);
1025 else if (HAVE_OPT(DH_INFO))
1026 dh_info (&cinfo);
1027 else if (HAVE_OPT(CERTIFICATE_PUBKEY))
1028 certificate_info (1, &cinfo);
1029 else if (HAVE_OPT(KEY_INFO))
1030 privkey_info (&cinfo);
1031 else if (HAVE_OPT(PUBKEY_INFO))
1032 pubkey_info (NULL, &cinfo);
1033 else if (HAVE_OPT(TO_P12))
1034 generate_pkcs12 (&cinfo);
1035 else if (HAVE_OPT(P12_INFO))
1036 pkcs12_info (&cinfo);
1037 else if (HAVE_OPT(GENERATE_DH_PARAMS))
1038 generate_prime (1, &cinfo);
1039 else if (HAVE_OPT(GET_DH_PARAMS))
1040 generate_prime (0, &cinfo);
1041 else if (HAVE_OPT(CRL_INFO))
1042 crl_info ();
1043 else if (HAVE_OPT(P7_INFO))
1044 pkcs7_info ();
1045 else if (HAVE_OPT(SMIME_TO_P7))
1046 smime_to_pkcs7 ();
1047 else if (HAVE_OPT(TO_P8))
1048 generate_pkcs8 (&cinfo);
1049 #ifdef ENABLE_OPENPGP
1050 else if (HAVE_OPT(PGP_CERTIFICATE_INFO))
1051 pgp_certificate_info ();
1052 else if (HAVE_OPT(PGP_KEY_INFO))
1053 pgp_privkey_info ();
1054 else if (HAVE_OPT(PGP_RING_INFO))
1055 pgp_ring_info ();
1056 #endif
1057 else if (HAVE_OPT(CRQ_INFO))
1058 crq_info ();
1059 else
1060 USAGE(1);
1062 fclose (outfile);
1064 #ifdef ENABLE_PKCS11
1065 gnutls_pkcs11_deinit ();
1066 #endif
1067 gnutls_global_deinit ();
1070 #define MAX_CRTS 500
1071 void
1072 certificate_info (int pubkey, common_info_st * cinfo)
1074 gnutls_x509_crt_t crt[MAX_CRTS];
1075 size_t size;
1076 int ret, i, count;
1077 gnutls_datum_t pem;
1078 unsigned int crt_num;
1080 pem.data = (void*)fread_file (infile, &size);
1081 pem.size = size;
1083 crt_num = MAX_CRTS;
1084 ret =
1085 gnutls_x509_crt_list_import (crt, &crt_num, &pem, incert_format,
1086 GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
1087 if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
1089 error (0, 0, "too many certificates (%d); "
1090 "will only read the first %d", crt_num, MAX_CRTS);
1091 crt_num = MAX_CRTS;
1092 ret = gnutls_x509_crt_list_import (crt, &crt_num, &pem,
1093 incert_format, 0);
1095 if (ret < 0)
1096 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (ret));
1098 free (pem.data);
1100 count = ret;
1102 if (count > 1 && outcert_format == GNUTLS_X509_FMT_DER)
1104 error (0, 0, "cannot output multiple certificates in DER format; "
1105 "using PEM instead");
1106 outcert_format = GNUTLS_X509_FMT_PEM;
1109 for (i = 0; i < count; i++)
1111 if (i > 0)
1112 fprintf (outfile, "\n");
1114 if (outcert_format == GNUTLS_X509_FMT_PEM)
1115 print_certificate_info (crt[i], outfile, 1);
1117 if (pubkey)
1118 pubkey_info (crt[i], cinfo);
1119 else
1121 size = buffer_size;
1122 ret = gnutls_x509_crt_export (crt[i], outcert_format, buffer,
1123 &size);
1124 if (ret < 0)
1125 error (EXIT_FAILURE, 0, "export error: %s", gnutls_strerror (ret));
1127 fwrite (buffer, 1, size, outfile);
1130 gnutls_x509_crt_deinit (crt[i]);
1134 #ifdef ENABLE_OPENPGP
1136 void
1137 pgp_certificate_info (void)
1139 gnutls_openpgp_crt_t crt;
1140 size_t size;
1141 int ret;
1142 gnutls_datum_t pem, out_data;
1143 unsigned int verify_status;
1145 pem.data = (void*)fread_file (infile, &size);
1146 pem.size = size;
1148 ret = gnutls_openpgp_crt_init (&crt);
1149 if (ret < 0)
1150 error (EXIT_FAILURE, 0, "openpgp_crt_init: %s", gnutls_strerror (ret));
1152 ret = gnutls_openpgp_crt_import (crt, &pem, incert_format);
1154 if (ret < 0)
1155 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (ret));
1157 free (pem.data);
1159 if (outcert_format == GNUTLS_OPENPGP_FMT_BASE64)
1161 ret = gnutls_openpgp_crt_print (crt, 0, &out_data);
1163 if (ret == 0)
1165 fprintf (outfile, "%s\n", out_data.data);
1166 gnutls_free (out_data.data);
1171 ret = gnutls_openpgp_crt_verify_self (crt, 0, &verify_status);
1172 if (ret < 0)
1174 error (EXIT_FAILURE, 0, "verify signature error: %s",
1175 gnutls_strerror (ret));
1178 if (verify_status & GNUTLS_CERT_INVALID)
1180 fprintf (outfile, "Self Signature verification: failed\n\n");
1182 else
1184 fprintf (outfile, "Self Signature verification: ok (%x)\n\n",
1185 verify_status);
1188 size = buffer_size;
1189 ret = gnutls_openpgp_crt_export (crt, outcert_format, buffer, &size);
1190 if (ret < 0)
1192 error (EXIT_FAILURE, 0, "export error: %s", gnutls_strerror (ret));
1193 fwrite (buffer, 1, size, outfile);
1196 fprintf (outfile, "%s\n", buffer);
1197 gnutls_openpgp_crt_deinit (crt);
1200 void
1201 pgp_privkey_info (void)
1203 gnutls_openpgp_privkey_t key;
1204 unsigned char keyid[GNUTLS_OPENPGP_KEYID_SIZE];
1205 size_t size;
1206 int ret, i, subkeys, bits = 0;
1207 gnutls_datum_t pem;
1208 const char *cprint;
1210 size = fread (buffer, 1, buffer_size - 1, infile);
1211 buffer[size] = 0;
1213 gnutls_openpgp_privkey_init (&key);
1215 pem.data = buffer;
1216 pem.size = size;
1218 ret = gnutls_openpgp_privkey_import (key, &pem, incert_format,
1219 NULL, 0);
1221 if (ret < 0)
1222 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (ret));
1224 /* Public key algorithm
1226 subkeys = gnutls_openpgp_privkey_get_subkey_count (key);
1227 if (subkeys < 0)
1228 error (EXIT_FAILURE, 0, "privkey_get_subkey_count: %s",
1229 gnutls_strerror (subkeys));
1231 for (i = -1; i < subkeys; i++)
1234 if (i != -1)
1235 fprintf (outfile, "Subkey[%d]:\n", i);
1237 fprintf (outfile, "Public Key Info:\n");
1239 if (i == -1)
1240 ret = gnutls_openpgp_privkey_get_pk_algorithm (key, NULL);
1241 else
1242 ret = gnutls_openpgp_privkey_get_subkey_pk_algorithm (key, i, NULL);
1244 fprintf (outfile, "\tPublic Key Algorithm: ");
1245 cprint = gnutls_pk_algorithm_get_name (ret);
1246 fprintf (outfile, "%s\n", cprint ? cprint : "Unknown");
1247 fprintf (outfile, "\tKey Security Level: %s\n",
1248 gnutls_sec_param_get_name (gnutls_openpgp_privkey_sec_param
1249 (key)));
1251 /* Print the raw public and private keys
1254 if (ret == GNUTLS_PK_RSA)
1256 gnutls_datum_t m, e, d, p, q, u;
1258 if (i == -1)
1259 ret =
1260 gnutls_openpgp_privkey_export_rsa_raw (key, &m, &e, &d, &p,
1261 &q, &u);
1262 else
1263 ret =
1264 gnutls_openpgp_privkey_export_subkey_rsa_raw (key, i, &m,
1265 &e, &d, &p,
1266 &q, &u);
1267 if (ret < 0)
1268 fprintf (stderr, "Error in key RSA data export: %s\n",
1269 gnutls_strerror (ret));
1270 else
1271 print_rsa_pkey (outfile, &m, &e, &d, &p, &q, &u, NULL, NULL);
1273 bits = m.size * 8;
1275 else if (ret == GNUTLS_PK_DSA)
1277 gnutls_datum_t p, q, g, y, x;
1279 if (i == -1)
1280 ret =
1281 gnutls_openpgp_privkey_export_dsa_raw (key, &p, &q, &g, &y, &x);
1282 else
1283 ret =
1284 gnutls_openpgp_privkey_export_subkey_dsa_raw (key, i, &p,
1285 &q, &g, &y, &x);
1286 if (ret < 0)
1287 fprintf (stderr, "Error in key DSA data export: %s\n",
1288 gnutls_strerror (ret));
1289 else
1290 print_dsa_pkey (outfile, &x, &y, &p, &q, &g);
1292 bits = y.size * 8;
1295 fprintf (outfile, "\n");
1297 size = buffer_size;
1298 if (i == -1)
1299 ret = gnutls_openpgp_privkey_get_key_id (key, keyid);
1300 else
1301 ret = gnutls_openpgp_privkey_get_subkey_id (key, i, keyid);
1303 if (ret < 0)
1305 fprintf (stderr, "Error in key id calculation: %s\n",
1306 gnutls_strerror (ret));
1308 else
1310 fprintf (outfile, "Public key ID: %s\n", raw_to_string (keyid, 8));
1313 size = buffer_size;
1314 if (i == -1)
1315 ret = gnutls_openpgp_privkey_get_fingerprint (key, buffer, &size);
1316 else
1317 ret = gnutls_openpgp_privkey_get_subkey_fingerprint (key, i, buffer, &size);
1319 if (ret < 0)
1321 fprintf (stderr, "Error in fingerprint calculation: %s\n",
1322 gnutls_strerror (ret));
1324 else
1326 gnutls_datum_t art;
1328 fprintf (outfile, "Fingerprint: %s\n", raw_to_string (buffer, size));
1330 ret = gnutls_random_art(GNUTLS_RANDOM_ART_OPENSSH, cprint, bits, buffer, size, &art);
1331 if (ret >= 0)
1333 fprintf (outfile, "Fingerprint's random art:\n%s\n\n", art.data);
1334 gnutls_free(art.data);
1339 size = buffer_size;
1340 ret = gnutls_openpgp_privkey_export (key, GNUTLS_OPENPGP_FMT_BASE64,
1341 NULL, 0, buffer, &size);
1342 if (ret < 0)
1343 error (EXIT_FAILURE, 0, "export error: %s", gnutls_strerror (ret));
1345 fprintf (outfile, "\n%s\n", buffer);
1347 gnutls_openpgp_privkey_deinit (key);
1350 void
1351 pgp_ring_info (void)
1353 gnutls_openpgp_keyring_t ring;
1354 gnutls_openpgp_crt_t crt;
1355 size_t size;
1356 int ret, i, count;
1357 gnutls_datum_t pem;
1359 pem.data = (void*)fread_file (infile, &size);
1360 pem.size = size;
1362 ret = gnutls_openpgp_keyring_init (&ring);
1363 if (ret < 0)
1364 error (EXIT_FAILURE, 0, "openpgp_keyring_init: %s",
1365 gnutls_strerror (ret));
1367 ret = gnutls_openpgp_keyring_import (ring, &pem, incert_format);
1369 if (ret < 0)
1370 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (ret));
1372 free (pem.data);
1374 count = gnutls_openpgp_keyring_get_crt_count (ring);
1375 if (count >= 0)
1376 fprintf (outfile, "Keyring contains %d OpenPGP certificates\n\n", count);
1377 else
1378 error (EXIT_FAILURE, 0, "keyring error: %s", gnutls_strerror (count));
1380 for (i = 0; i < count; i++)
1382 ret = gnutls_openpgp_keyring_get_crt (ring, i, &crt);
1383 if (ret < 0)
1384 error (EXIT_FAILURE, 0, "export error: %s", gnutls_strerror (ret));
1386 size = buffer_size;
1387 ret = gnutls_openpgp_crt_export (crt, outcert_format,
1388 buffer, &size);
1389 if (ret < 0)
1390 error (EXIT_FAILURE, 0, "export error: %s", gnutls_strerror (ret));
1392 fwrite (buffer, 1, size, outfile);
1393 fprintf (outfile, "\n\n");
1395 gnutls_openpgp_crt_deinit (crt);
1400 gnutls_openpgp_keyring_deinit (ring);
1404 #endif
1408 static void
1409 print_certificate_info (gnutls_x509_crt_t crt, FILE * out, unsigned int all)
1411 gnutls_datum_t data;
1412 int ret;
1414 if (all)
1415 ret = gnutls_x509_crt_print (crt, GNUTLS_CRT_PRINT_FULL, &data);
1416 else
1417 ret = gnutls_x509_crt_print (crt, GNUTLS_CRT_PRINT_UNSIGNED_FULL, &data);
1418 if (ret == 0)
1420 fprintf (out, "%s\n", data.data);
1421 gnutls_free (data.data);
1424 if (out == stderr && batch == 0) /* interactive */
1425 if (read_yesno ("Is the above information ok? (y/N): ") == 0)
1427 exit (1);
1431 static void
1432 print_crl_info (gnutls_x509_crl_t crl, FILE * out)
1434 gnutls_datum_t data;
1435 int ret;
1436 size_t size;
1438 ret = gnutls_x509_crl_print (crl, GNUTLS_CRT_PRINT_FULL, &data);
1439 if (ret < 0)
1440 error (EXIT_FAILURE, 0, "crl_print: %s", gnutls_strerror (ret));
1442 fprintf (out, "%s\n", data.data);
1444 gnutls_free (data.data);
1446 size = buffer_size;
1447 ret = gnutls_x509_crl_export (crl, GNUTLS_X509_FMT_PEM, buffer, &size);
1448 if (ret < 0)
1449 error (EXIT_FAILURE, 0, "crl_export: %s", gnutls_strerror (ret));
1451 fwrite (buffer, 1, size, outfile);
1454 void
1455 crl_info (void)
1457 gnutls_x509_crl_t crl;
1458 int ret;
1459 size_t size;
1460 gnutls_datum_t pem;
1462 ret = gnutls_x509_crl_init (&crl);
1463 if (ret < 0)
1464 error (EXIT_FAILURE, 0, "crl_init: %s", gnutls_strerror (ret));
1466 pem.data = (void*)fread_file (infile, &size);
1467 pem.size = size;
1469 if (!pem.data)
1470 error (EXIT_FAILURE, errno, "%s", infile ? "file" :
1471 "standard input");
1473 ret = gnutls_x509_crl_import (crl, &pem, incert_format);
1475 free (pem.data);
1476 if (ret < 0)
1477 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (ret));
1479 print_crl_info (crl, outfile);
1481 gnutls_x509_crl_deinit (crl);
1484 static void
1485 print_crq_info (gnutls_x509_crq_t crq, FILE * out)
1487 gnutls_datum_t data;
1488 int ret;
1489 size_t size;
1491 if (outcert_format == GNUTLS_X509_FMT_PEM)
1493 ret = gnutls_x509_crq_print (crq, GNUTLS_CRT_PRINT_FULL, &data);
1494 if (ret < 0)
1495 error (EXIT_FAILURE, 0, "crq_print: %s", gnutls_strerror (ret));
1497 fprintf (out, "%s\n", data.data);
1499 gnutls_free (data.data);
1502 ret = gnutls_x509_crq_verify(crq, 0);
1503 if (ret < 0)
1505 fprintf(out, "Self signature: FAILED\n\n");
1507 else
1509 fprintf(out, "Self signature: verified\n\n");
1512 size = buffer_size;
1513 ret = gnutls_x509_crq_export (crq, outcert_format, buffer, &size);
1514 if (ret < 0)
1515 error (EXIT_FAILURE, 0, "crq_export: %s", gnutls_strerror (ret));
1517 fwrite (buffer, 1, size, outfile);
1520 void
1521 crq_info (void)
1523 gnutls_x509_crq_t crq;
1524 int ret;
1525 size_t size;
1526 gnutls_datum_t pem;
1528 ret = gnutls_x509_crq_init (&crq);
1529 if (ret < 0)
1530 error (EXIT_FAILURE, 0, "crq_init: %s", gnutls_strerror (ret));
1532 pem.data = (void*)fread_file (infile, &size);
1533 pem.size = size;
1535 if (!pem.data)
1536 error (EXIT_FAILURE, errno, "%s", infile ? "file" :
1537 "standard input");
1539 ret = gnutls_x509_crq_import (crq, &pem, incert_format);
1541 free (pem.data);
1542 if (ret < 0)
1543 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (ret));
1545 print_crq_info (crq, outfile);
1547 gnutls_x509_crq_deinit (crq);
1550 static void privkey_info_int (common_info_st* cinfo, gnutls_x509_privkey_t key)
1552 int ret, key_type, bits = 0;
1553 size_t size;
1554 const char *cprint;
1556 /* Public key algorithm
1558 fprintf (outfile, "Public Key Info:\n");
1559 ret = gnutls_x509_privkey_get_pk_algorithm (key);
1560 fprintf (outfile, "\tPublic Key Algorithm: ");
1562 key_type = ret;
1564 cprint = gnutls_pk_algorithm_get_name (key_type);
1565 fprintf (outfile, "%s\n", cprint ? cprint : "Unknown");
1566 fprintf (outfile, "\tKey Security Level: %s\n\n",
1567 gnutls_sec_param_get_name (gnutls_x509_privkey_sec_param (key)));
1569 /* Print the raw public and private keys
1571 if (key_type == GNUTLS_PK_RSA)
1573 gnutls_datum_t m, e, d, p, q, u, exp1, exp2;
1575 ret =
1576 gnutls_x509_privkey_export_rsa_raw2 (key, &m, &e, &d, &p, &q, &u,
1577 &exp1, &exp2);
1578 if (ret < 0)
1579 fprintf (stderr, "Error in key RSA data export: %s\n",
1580 gnutls_strerror (ret));
1581 else
1583 print_rsa_pkey (outfile, &m, &e, &d, &p, &q, &u, &exp1, &exp2);
1584 bits = m.size * 8;
1586 gnutls_free (m.data);
1587 gnutls_free (e.data);
1588 gnutls_free (d.data);
1589 gnutls_free (p.data);
1590 gnutls_free (q.data);
1591 gnutls_free (u.data);
1592 gnutls_free (exp1.data);
1593 gnutls_free (exp2.data);
1596 else if (key_type == GNUTLS_PK_DSA)
1598 gnutls_datum_t p, q, g, y, x;
1600 ret = gnutls_x509_privkey_export_dsa_raw (key, &p, &q, &g, &y, &x);
1601 if (ret < 0)
1602 fprintf (stderr, "Error in key DSA data export: %s\n",
1603 gnutls_strerror (ret));
1604 else
1606 print_dsa_pkey (outfile, &x, &y, &p, &q, &g);
1607 bits = y.size * 8;
1609 gnutls_free (x.data);
1610 gnutls_free (y.data);
1611 gnutls_free (p.data);
1612 gnutls_free (q.data);
1613 gnutls_free (g.data);
1616 else if (key_type == GNUTLS_PK_EC)
1618 gnutls_datum_t y, x, k;
1619 gnutls_ecc_curve_t curve;
1621 ret = gnutls_x509_privkey_export_ecc_raw (key, &curve, &x, &y, &k);
1622 if (ret < 0)
1623 fprintf (stderr, "Error in key ECC data export: %s\n",
1624 gnutls_strerror (ret));
1625 else
1627 print_ecc_pkey (outfile, curve, &k, &x, &y);
1628 bits = gnutls_ecc_curve_get_size(curve) * 8;
1630 gnutls_free (x.data);
1631 gnutls_free (y.data);
1632 gnutls_free (k.data);
1636 fprintf (outfile, "\n");
1638 size = buffer_size;
1639 if ((ret = gnutls_x509_privkey_get_key_id (key, 0, buffer, &size)) < 0)
1641 fprintf (stderr, "Error in key id calculation: %s\n",
1642 gnutls_strerror (ret));
1644 else
1646 gnutls_datum_t art;
1648 fprintf (outfile, "Public Key ID: %s\n", raw_to_string (buffer, size));
1650 ret = gnutls_random_art(GNUTLS_RANDOM_ART_OPENSSH, cprint, bits, buffer, size, &art);
1651 if (ret >= 0)
1653 fprintf (outfile, "Public key's random art:\n%s\n", art.data);
1654 gnutls_free(art.data);
1657 fprintf (outfile, "\n");
1661 void
1662 privkey_info (common_info_st* cinfo)
1664 gnutls_x509_privkey_t key;
1665 size_t size;
1666 int ret;
1667 gnutls_datum_t pem;
1668 const char *pass;
1670 size = fread (buffer, 1, buffer_size - 1, infile);
1671 buffer[size] = 0;
1673 gnutls_x509_privkey_init (&key);
1675 pem.data = buffer;
1676 pem.size = size;
1678 ret = gnutls_x509_privkey_import2 (key, &pem, incert_format, NULL);
1680 /* If we failed to import the certificate previously try PKCS #8 */
1681 if (ret == GNUTLS_E_DECRYPTION_FAILED)
1683 fprintf(stderr, "Encrypted structure detected...\n");
1684 if (cinfo->password)
1685 pass = cinfo->password;
1686 else
1687 pass = get_pass ();
1689 ret = gnutls_x509_privkey_import2 (key, &pem,
1690 incert_format, pass);
1692 if (ret < 0)
1693 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (ret));
1695 if (outcert_format == GNUTLS_X509_FMT_PEM)
1696 privkey_info_int (cinfo, key);
1698 ret = gnutls_x509_privkey_verify_params (key);
1699 if (ret < 0)
1700 fprintf (outfile, "\n** Private key parameters validation failed **\n\n");
1702 size = buffer_size;
1703 ret = gnutls_x509_privkey_export (key, outcert_format, buffer, &size);
1704 if (ret < 0)
1705 error (EXIT_FAILURE, 0, "export error: %s", gnutls_strerror (ret));
1707 fwrite (buffer, 1, size, outfile);
1709 gnutls_x509_privkey_deinit (key);
1713 /* Generate a PKCS #10 certificate request.
1715 void
1716 generate_request (common_info_st * cinfo)
1718 gnutls_x509_crq_t crq;
1719 gnutls_x509_privkey_t xkey;
1720 gnutls_pubkey_t pubkey;
1721 gnutls_privkey_t pkey;
1722 int ret, ca_status, path_len;
1723 const char *pass;
1724 unsigned int usage = 0;
1726 fprintf (stderr, "Generating a PKCS #10 certificate request...\n");
1728 ret = gnutls_x509_crq_init (&crq);
1729 if (ret < 0)
1730 error (EXIT_FAILURE, 0, "crq_init: %s", gnutls_strerror (ret));
1733 /* Load the private key.
1735 pkey = load_private_key (0, cinfo);
1736 if (!pkey)
1738 ret = gnutls_privkey_init (&pkey);
1739 if (ret < 0)
1740 error (EXIT_FAILURE, 0, "privkey_init: %s", gnutls_strerror (ret));
1742 xkey = generate_private_key_int (cinfo);
1744 print_private_key (cinfo, xkey);
1746 ret = gnutls_privkey_import_x509(pkey, xkey, GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
1747 if (ret < 0)
1748 error (EXIT_FAILURE, 0, "privkey_import_x509: %s", gnutls_strerror (ret));
1751 pubkey = load_public_key_or_import (1, pkey, cinfo);
1753 /* Set the DN.
1755 get_country_crq_set (crq);
1756 get_organization_crq_set (crq);
1757 get_unit_crq_set (crq);
1758 get_locality_crq_set (crq);
1759 get_state_crq_set (crq);
1760 get_cn_crq_set (crq);
1761 get_dc_set (TYPE_CRQ, crq);
1762 get_uid_crq_set (crq);
1763 get_oid_crq_set (crq);
1765 get_dns_name_set (TYPE_CRQ, crq);
1766 get_uri_set (TYPE_CRQ, crq);
1767 get_ip_addr_set (TYPE_CRQ, crq);
1768 get_email_set (TYPE_CRQ, crq);
1770 pass = get_challenge_pass ();
1772 if (pass != NULL && pass[0] != 0)
1774 ret = gnutls_x509_crq_set_challenge_password (crq, pass);
1775 if (ret < 0)
1776 error (EXIT_FAILURE, 0, "set_pass: %s", gnutls_strerror (ret));
1779 if (cinfo->crq_extensions != 0)
1781 ca_status = get_ca_status ();
1782 if (ca_status)
1783 path_len = get_path_len ();
1784 else
1785 path_len = -1;
1787 ret = gnutls_x509_crq_set_basic_constraints (crq, ca_status, path_len);
1788 if (ret < 0)
1789 error (EXIT_FAILURE, 0, "set_basic_constraints: %s",
1790 gnutls_strerror (ret));
1792 ret = get_sign_status (1);
1793 if (ret)
1794 usage |= GNUTLS_KEY_DIGITAL_SIGNATURE;
1796 ret = get_encrypt_status (1);
1797 if (ret)
1798 usage |= GNUTLS_KEY_KEY_ENCIPHERMENT;
1799 else
1800 usage |= GNUTLS_KEY_DIGITAL_SIGNATURE;
1802 if (ca_status)
1804 ret = get_cert_sign_status ();
1805 if (ret)
1806 usage |= GNUTLS_KEY_KEY_CERT_SIGN;
1808 ret = get_crl_sign_status ();
1809 if (ret)
1810 usage |= GNUTLS_KEY_CRL_SIGN;
1812 ret = get_code_sign_status ();
1813 if (ret)
1815 ret = gnutls_x509_crq_set_key_purpose_oid
1816 (crq, GNUTLS_KP_CODE_SIGNING, 0);
1817 if (ret < 0)
1818 error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (ret));
1821 ret = get_ocsp_sign_status ();
1822 if (ret)
1824 ret = gnutls_x509_crq_set_key_purpose_oid
1825 (crq, GNUTLS_KP_OCSP_SIGNING, 0);
1826 if (ret < 0)
1827 error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (ret));
1830 ret = get_time_stamp_status ();
1831 if (ret)
1833 ret = gnutls_x509_crq_set_key_purpose_oid
1834 (crq, GNUTLS_KP_TIME_STAMPING, 0);
1835 if (ret < 0)
1836 error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (ret));
1839 ret = get_ipsec_ike_status ();
1840 if (ret)
1842 ret = gnutls_x509_crq_set_key_purpose_oid
1843 (crq, GNUTLS_KP_IPSEC_IKE, 0);
1844 if (ret < 0)
1845 error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (ret));
1849 ret = gnutls_x509_crq_set_key_usage (crq, usage);
1850 if (ret < 0)
1851 error (EXIT_FAILURE, 0, "key_usage: %s", gnutls_strerror (ret));
1853 ret = get_tls_client_status ();
1854 if (ret != 0)
1856 ret = gnutls_x509_crq_set_key_purpose_oid
1857 (crq, GNUTLS_KP_TLS_WWW_CLIENT, 0);
1858 if (ret < 0)
1859 error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (ret));
1862 ret = get_tls_server_status ();
1863 if (ret != 0)
1865 ret = gnutls_x509_crq_set_key_purpose_oid
1866 (crq, GNUTLS_KP_TLS_WWW_SERVER, 0);
1867 if (ret < 0)
1868 error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (ret));
1872 ret = gnutls_x509_crq_set_pubkey (crq, pubkey);
1873 if (ret < 0)
1874 error (EXIT_FAILURE, 0, "set_key: %s", gnutls_strerror (ret));
1876 ret = gnutls_x509_crq_privkey_sign (crq, pkey, SIGN_HASH, 0);
1877 if (ret < 0)
1878 error (EXIT_FAILURE, 0, "sign: %s", gnutls_strerror (ret));
1880 print_crq_info (crq, outfile);
1882 gnutls_x509_crq_deinit (crq);
1883 gnutls_privkey_deinit( pkey);
1884 gnutls_pubkey_deinit( pubkey);
1888 static void print_verification_res (FILE* outfile, unsigned int output);
1890 static int detailed_verification(gnutls_x509_crt_t cert,
1891 gnutls_x509_crt_t issuer, gnutls_x509_crl_t crl,
1892 unsigned int verification_output)
1894 char name[512];
1895 char tmp[255];
1896 char issuer_name[512];
1897 size_t name_size;
1898 size_t issuer_name_size;
1899 int ret;
1901 issuer_name_size = sizeof (issuer_name);
1902 ret =
1903 gnutls_x509_crt_get_issuer_dn (cert, issuer_name, &issuer_name_size);
1904 if (ret < 0)
1905 error (EXIT_FAILURE, 0, "gnutls_x509_crt_get_issuer_dn: %s", gnutls_strerror (ret));
1907 name_size = sizeof (name);
1908 ret =
1909 gnutls_x509_crt_get_dn (cert, name, &name_size);
1910 if (ret < 0)
1911 error (EXIT_FAILURE, 0, "gnutls_x509_crt_get_dn: %s", gnutls_strerror (ret));
1913 fprintf (outfile, "\tSubject: %s\n", name);
1914 fprintf (outfile, "\tIssuer: %s\n", issuer_name);
1916 if (issuer != NULL)
1918 issuer_name_size = sizeof (issuer_name);
1919 ret =
1920 gnutls_x509_crt_get_dn (issuer, issuer_name, &issuer_name_size);
1921 if (ret < 0)
1922 error (EXIT_FAILURE, 0, "gnutls_x509_crt_get_issuer_dn: %s", gnutls_strerror (ret));
1924 fprintf (outfile, "\tChecked against: %s\n", issuer_name);
1927 if (crl != NULL)
1929 gnutls_datum_t data;
1931 issuer_name_size = sizeof (issuer_name);
1932 ret =
1933 gnutls_x509_crl_get_issuer_dn (crl, issuer_name, &issuer_name_size);
1934 if (ret < 0)
1935 error (EXIT_FAILURE, 0, "gnutls_x509_crl_get_issuer_dn: %s", gnutls_strerror (ret));
1937 name_size = sizeof(tmp);
1938 ret = gnutls_x509_crl_get_number(crl, tmp, &name_size, NULL);
1939 if (ret < 0)
1940 strcpy(name, "unnumbered");
1941 else
1943 data.data = (void*)tmp;
1944 data.size = name_size;
1946 name_size = sizeof(name);
1947 ret = gnutls_hex_encode(&data, name, &name_size);
1948 if (ret < 0)
1949 error (EXIT_FAILURE, 0, "gnutls_hex_encode: %s", gnutls_strerror (ret));
1951 fprintf (outfile, "\tChecked against CRL[%s] of: %s\n", name, issuer_name);
1954 fprintf (outfile, "\tOutput: ");
1955 print_verification_res(outfile, verification_output);
1957 fputs(".\n\n", outfile);
1959 return 0;
1962 /* Will verify a certificate chain. If no CA certificates
1963 * are provided, then the last certificate in the certificate
1964 * chain is used as a CA.
1966 static int
1967 _verify_x509_mem (const void *cert, int cert_size, const void* ca, int ca_size)
1969 int ret;
1970 gnutls_datum_t tmp;
1971 gnutls_x509_crt_t *x509_cert_list = NULL;
1972 gnutls_x509_crt_t *x509_ca_list = NULL;
1973 gnutls_x509_crl_t *x509_crl_list = NULL;
1974 unsigned int x509_ncerts, x509_ncrls = 0, x509_ncas = 0;
1975 gnutls_x509_trust_list_t list;
1976 unsigned int output;
1978 ret = gnutls_x509_trust_list_init(&list, 0);
1979 if (ret < 0)
1980 error (EXIT_FAILURE, 0, "gnutls_x509_trust_list_init: %s",
1981 gnutls_strerror (ret));
1983 if (ca == NULL)
1985 tmp.data = (void*)cert;
1986 tmp.size = cert_size;
1988 else
1990 tmp.data = (void*)ca;
1991 tmp.size = ca_size;
1993 /* Load CAs */
1994 ret = gnutls_x509_crt_list_import2( &x509_ca_list, &x509_ncas, &tmp,
1995 GNUTLS_X509_FMT_PEM, 0);
1996 if (ret < 0 || x509_ncas < 1)
1997 error (EXIT_FAILURE, 0, "error parsing CAs: %s",
1998 gnutls_strerror (ret));
2001 ret = gnutls_x509_crl_list_import2( &x509_crl_list, &x509_ncrls, &tmp,
2002 GNUTLS_X509_FMT_PEM, 0);
2003 if (ret < 0)
2005 x509_crl_list = NULL;
2006 x509_ncrls = 0;
2009 tmp.data = (void*)cert;
2010 tmp.size = cert_size;
2012 /* ignore errors. CRLs might not be given */
2013 ret = gnutls_x509_crt_list_import2( &x509_cert_list, &x509_ncerts, &tmp,
2014 GNUTLS_X509_FMT_PEM, 0);
2015 if (ret < 0 || x509_ncerts < 1)
2016 error (EXIT_FAILURE, 0, "error parsing CRTs: %s",
2017 gnutls_strerror (ret));
2019 if (ca == NULL)
2021 x509_ca_list = &x509_cert_list[x509_ncerts - 1];
2022 x509_ncas = 1;
2025 fprintf(stdout, "Loaded %d certificates, %d CAs and %d CRLs\n\n",
2026 x509_ncerts, x509_ncas, x509_ncrls);
2028 ret = gnutls_x509_trust_list_add_cas(list, x509_ca_list, x509_ncas, 0);
2029 if (ret < 0)
2030 error (EXIT_FAILURE, 0, "gnutls_x509_trust_add_cas: %s",
2031 gnutls_strerror (ret));
2033 ret = gnutls_x509_trust_list_add_crls(list, x509_crl_list, x509_ncrls, 0, 0);
2034 if (ret < 0)
2035 error (EXIT_FAILURE, 0, "gnutls_x509_trust_add_crls: %s",
2036 gnutls_strerror (ret));
2038 gnutls_free(x509_crl_list);
2040 ret = gnutls_x509_trust_list_verify_crt (list, x509_cert_list, x509_ncerts,
2041 GNUTLS_VERIFY_DO_NOT_ALLOW_SAME|GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT, &output,
2042 detailed_verification);
2043 if (ret < 0)
2044 error (EXIT_FAILURE, 0, "gnutls_x509_trusted_list_verify_crt: %s",
2045 gnutls_strerror (ret));
2047 fprintf (outfile, "Chain verification output: ");
2048 print_verification_res(outfile, output);
2050 fprintf (outfile, ".\n\n");
2052 gnutls_free(x509_cert_list);
2053 gnutls_x509_trust_list_deinit(list, 1);
2055 if (output != 0)
2056 exit(EXIT_FAILURE);
2058 return 0;
2061 static void
2062 print_verification_res (FILE* outfile, unsigned int output)
2064 int comma = 0;
2066 if (output & GNUTLS_CERT_INVALID)
2068 fprintf (outfile, "Not verified");
2069 comma = 1;
2071 else
2073 fprintf (outfile, "Verified");
2074 comma = 1;
2077 if (output & GNUTLS_CERT_SIGNER_NOT_CA)
2079 if (comma)
2080 fprintf (outfile, ", ");
2081 fprintf (outfile, "Issuer is not a CA");
2082 comma = 1;
2085 if (output & GNUTLS_CERT_INSECURE_ALGORITHM)
2087 if (comma)
2088 fprintf (outfile, ", ");
2089 fprintf (outfile, "Insecure algorithm");
2090 comma = 1;
2093 if (output & GNUTLS_CERT_NOT_ACTIVATED)
2095 if (comma)
2096 fprintf (outfile, ", ");
2097 fprintf (outfile, "Not activated");
2098 comma = 1;
2101 if (output & GNUTLS_CERT_EXPIRED)
2103 if (comma)
2104 fprintf (outfile, ", ");
2105 fprintf (outfile, "Expired");
2106 comma = 1;
2109 if (output & GNUTLS_CERT_REVOKED)
2111 if (comma)
2112 fprintf (outfile, ", ");
2113 fprintf (outfile, "Revoked");
2114 comma = 1;
2118 static void
2119 verify_chain (void)
2121 char *buf;
2122 size_t size;
2124 buf = (void*)fread_file (infile, &size);
2125 if (buf == NULL)
2126 error (EXIT_FAILURE, errno, "reading chain");
2128 buf[size] = 0;
2130 _verify_x509_mem (buf, size, NULL, 0);
2134 static void
2135 verify_certificate (common_info_st * cinfo)
2137 char *cert;
2138 char *cas;
2139 size_t cert_size, ca_size;
2140 FILE * ca_file = fopen(cinfo->ca, "r");
2142 if (ca_file == NULL)
2143 error (EXIT_FAILURE, errno, "opening CA file");
2145 cert = (void*)fread_file (infile, &cert_size);
2146 if (cert == NULL)
2147 error (EXIT_FAILURE, errno, "reading certificate chain");
2149 cert[cert_size] = 0;
2151 cas = (void*)fread_file (ca_file, &ca_size);
2152 if (cas == NULL)
2153 error (EXIT_FAILURE, errno, "reading CA list");
2155 cas[ca_size] = 0;
2156 fclose(ca_file);
2158 _verify_x509_mem (cert, cert_size, cas, ca_size);
2163 void
2164 verify_crl (common_info_st * cinfo)
2166 size_t size, dn_size;
2167 char dn[128];
2168 unsigned int output;
2169 int comma = 0;
2170 int ret;
2171 gnutls_datum_t pem;
2172 gnutls_x509_crl_t crl;
2173 time_t now = time (0);
2174 gnutls_x509_crt_t issuer;
2176 issuer = load_ca_cert (cinfo);
2178 fprintf (outfile, "\nCA certificate:\n");
2180 dn_size = sizeof (dn);
2181 ret = gnutls_x509_crt_get_dn (issuer, dn, &dn_size);
2182 if (ret < 0)
2183 error (EXIT_FAILURE, 0, "crt_get_dn: %s", gnutls_strerror (ret));
2185 fprintf (outfile, "\tSubject: %s\n\n", dn);
2187 ret = gnutls_x509_crl_init (&crl);
2188 if (ret < 0)
2189 error (EXIT_FAILURE, 0, "crl_init: %s", gnutls_strerror (ret));
2191 pem.data = (void*)fread_file (infile, &size);
2192 pem.size = size;
2194 ret = gnutls_x509_crl_import (crl, &pem, incert_format);
2195 free (pem.data);
2196 if (ret < 0)
2197 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (ret));
2199 print_crl_info (crl, outfile);
2201 fprintf (outfile, "Verification output: ");
2202 ret = gnutls_x509_crl_verify (crl, &issuer, 1, 0, &output);
2203 if (ret < 0)
2204 error (EXIT_FAILURE, 0, "verification error: %s", gnutls_strerror (ret));
2206 if (output & GNUTLS_CERT_INVALID)
2208 fprintf (outfile, "Not verified");
2209 comma = 1;
2211 else
2213 fprintf (outfile, "Verified");
2214 comma = 1;
2217 if (output & GNUTLS_CERT_SIGNER_NOT_CA)
2219 if (comma)
2220 fprintf (outfile, ", ");
2221 fprintf (outfile, "Issuer is not a CA");
2222 comma = 1;
2225 if (output & GNUTLS_CERT_INSECURE_ALGORITHM)
2227 if (comma)
2228 fprintf (outfile, ", ");
2229 fprintf (outfile, "Insecure algorithm");
2230 comma = 1;
2233 /* Check expiration dates.
2236 if (gnutls_x509_crl_get_this_update (crl) > now)
2238 if (comma)
2239 fprintf (outfile, ", ");
2240 comma = 1;
2241 fprintf (outfile, "Issued in the future!");
2244 if (gnutls_x509_crl_get_next_update (crl) < now)
2246 if (comma)
2247 fprintf (outfile, ", ");
2248 comma = 1;
2249 fprintf (outfile, "CRL is not up to date");
2252 fprintf (outfile, "\n");
2256 void
2257 generate_pkcs8 (common_info_st * cinfo)
2259 gnutls_x509_privkey_t key;
2260 int result;
2261 size_t size;
2262 int flags = 0;
2263 const char *password;
2265 fprintf (stderr, "Generating a PKCS #8 key structure...\n");
2267 key = load_x509_private_key (1, cinfo);
2269 if (cinfo->password)
2270 password = cinfo->password;
2271 else
2272 password = get_pass ();
2274 flags = cipher_to_flags (cinfo->pkcs_cipher);
2276 if (password == NULL || password[0] == 0)
2278 flags = GNUTLS_PKCS_PLAIN;
2281 size = buffer_size;
2282 result =
2283 gnutls_x509_privkey_export_pkcs8 (key, outcert_format,
2284 password, flags, buffer, &size);
2286 if (result < 0)
2287 error (EXIT_FAILURE, 0, "key_export: %s", gnutls_strerror (result));
2289 fwrite (buffer, 1, size, outfile);
2294 #include <gnutls/pkcs12.h>
2295 #include <unistd.h>
2297 void
2298 generate_pkcs12 (common_info_st * cinfo)
2300 gnutls_pkcs12_t pkcs12;
2301 gnutls_x509_crt_t *crts;
2302 gnutls_x509_privkey_t *keys;
2303 int result;
2304 size_t size;
2305 gnutls_datum_t data;
2306 const char *pass;
2307 const char *name;
2308 unsigned int flags, i;
2309 gnutls_datum_t key_id;
2310 unsigned char _key_id[32];
2311 int indx;
2312 size_t ncrts;
2313 size_t nkeys;
2315 fprintf (stderr, "Generating a PKCS #12 structure...\n");
2317 keys = load_privkey_list (0, &nkeys, cinfo);
2318 crts = load_cert_list (0, &ncrts, cinfo);
2320 name = get_pkcs12_key_name ();
2322 result = gnutls_pkcs12_init (&pkcs12);
2323 if (result < 0)
2324 error (EXIT_FAILURE, 0, "pkcs12_init: %s", gnutls_strerror (result));
2326 if (cinfo->password)
2327 pass = cinfo->password;
2328 else
2329 pass = get_pass ();
2331 if (pass == NULL)
2333 fprintf(stderr, "No password given for PKCS #12. Assuming null password...\n");
2334 pass = "";
2338 for (i = 0; i < ncrts; i++)
2340 gnutls_pkcs12_bag_t bag;
2342 result = gnutls_pkcs12_bag_init (&bag);
2343 if (result < 0)
2344 error (EXIT_FAILURE, 0, "bag_init: %s", gnutls_strerror (result));
2346 result = gnutls_pkcs12_bag_set_crt (bag, crts[i]);
2347 if (result < 0)
2348 error (EXIT_FAILURE, 0, "set_crt[%d]: %s", i,
2349 gnutls_strerror (result));
2351 indx = result;
2353 if (i==0) /* only the first certificate gets the friendly name */
2355 result = gnutls_pkcs12_bag_set_friendly_name (bag, indx, name);
2356 if (result < 0)
2357 error (EXIT_FAILURE, 0, "bag_set_friendly_name: %s",
2358 gnutls_strerror (result));
2361 size = sizeof (_key_id);
2362 result = gnutls_x509_crt_get_key_id (crts[i], 0, _key_id, &size);
2363 if (result < 0)
2364 error (EXIT_FAILURE, 0, "key_id[%d]: %s", i,
2365 gnutls_strerror (result));
2367 key_id.data = _key_id;
2368 key_id.size = size;
2370 result = gnutls_pkcs12_bag_set_key_id (bag, indx, &key_id);
2371 if (result < 0)
2372 error (EXIT_FAILURE, 0, "bag_set_key_id: %s",
2373 gnutls_strerror (result));
2375 flags = cipher_to_flags (cinfo->pkcs_cipher);
2377 result = gnutls_pkcs12_bag_encrypt (bag, pass, flags);
2378 if (result < 0)
2379 error (EXIT_FAILURE, 0, "bag_encrypt: %s", gnutls_strerror (result));
2381 result = gnutls_pkcs12_set_bag (pkcs12, bag);
2382 if (result < 0)
2383 error (EXIT_FAILURE, 0, "set_bag: %s", gnutls_strerror (result));
2386 for (i = 0; i < nkeys; i++)
2388 gnutls_pkcs12_bag_t kbag;
2390 result = gnutls_pkcs12_bag_init (&kbag);
2391 if (result < 0)
2392 error (EXIT_FAILURE, 0, "bag_init: %s", gnutls_strerror (result));
2394 flags = cipher_to_flags (cinfo->pkcs_cipher);
2396 size = buffer_size;
2397 result =
2398 gnutls_x509_privkey_export_pkcs8 (keys[i], GNUTLS_X509_FMT_DER,
2399 pass, flags, buffer, &size);
2400 if (result < 0)
2401 error (EXIT_FAILURE, 0, "key_export[%d]: %s", i, gnutls_strerror (result));
2403 data.data = buffer;
2404 data.size = size;
2405 result =
2406 gnutls_pkcs12_bag_set_data (kbag,
2407 GNUTLS_BAG_PKCS8_ENCRYPTED_KEY, &data);
2408 if (result < 0)
2409 error (EXIT_FAILURE, 0, "bag_set_data: %s", gnutls_strerror (result));
2411 indx = result;
2413 result = gnutls_pkcs12_bag_set_friendly_name (kbag, indx, name);
2414 if (result < 0)
2415 error (EXIT_FAILURE, 0, "bag_set_friendly_name: %s",
2416 gnutls_strerror (result));
2418 size = sizeof (_key_id);
2419 result = gnutls_x509_privkey_get_key_id (keys[i], 0, _key_id, &size);
2420 if (result < 0)
2421 error (EXIT_FAILURE, 0, "key_id[%d]: %s", i, gnutls_strerror (result));
2423 key_id.data = _key_id;
2424 key_id.size = size;
2426 result = gnutls_pkcs12_bag_set_key_id (kbag, indx, &key_id);
2427 if (result < 0)
2428 error (EXIT_FAILURE, 0, "bag_set_key_id: %s",
2429 gnutls_strerror (result));
2431 result = gnutls_pkcs12_set_bag (pkcs12, kbag);
2432 if (result < 0)
2433 error (EXIT_FAILURE, 0, "set_bag: %s", gnutls_strerror (result));
2436 result = gnutls_pkcs12_generate_mac (pkcs12, pass);
2437 if (result < 0)
2438 error (EXIT_FAILURE, 0, "generate_mac: %s", gnutls_strerror (result));
2440 size = buffer_size;
2441 result = gnutls_pkcs12_export (pkcs12, outcert_format, buffer, &size);
2442 if (result < 0)
2443 error (EXIT_FAILURE, 0, "pkcs12_export: %s", gnutls_strerror (result));
2445 fwrite (buffer, 1, size, outfile);
2449 static const char *
2450 BAGTYPE (gnutls_pkcs12_bag_type_t x)
2452 switch (x)
2454 case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY:
2455 return "PKCS #8 Encrypted key";
2456 case GNUTLS_BAG_EMPTY:
2457 return "Empty";
2458 case GNUTLS_BAG_PKCS8_KEY:
2459 return "PKCS #8 Key";
2460 case GNUTLS_BAG_CERTIFICATE:
2461 return "Certificate";
2462 case GNUTLS_BAG_ENCRYPTED:
2463 return "Encrypted";
2464 case GNUTLS_BAG_CRL:
2465 return "CRL";
2466 case GNUTLS_BAG_SECRET:
2467 return "Secret";
2468 default:
2469 return "Unknown";
2473 static void
2474 print_bag_data (gnutls_pkcs12_bag_t bag)
2476 int result;
2477 int count, i, type;
2478 gnutls_datum_t cdata, id;
2479 const char *str, *name;
2480 gnutls_datum_t out;
2482 count = gnutls_pkcs12_bag_get_count (bag);
2483 if (count < 0)
2484 error (EXIT_FAILURE, 0, "get_count: %s", gnutls_strerror (count));
2486 fprintf (outfile, "\tElements: %d\n", count);
2488 for (i = 0; i < count; i++)
2490 type = gnutls_pkcs12_bag_get_type (bag, i);
2491 if (type < 0)
2492 error (EXIT_FAILURE, 0, "get_type: %s", gnutls_strerror (type));
2494 fprintf (stderr, "\tType: %s\n", BAGTYPE (type));
2496 name = NULL;
2497 result = gnutls_pkcs12_bag_get_friendly_name (bag, i, (char **) &name);
2498 if (result < 0)
2499 error (EXIT_FAILURE, 0, "get_friendly_name: %s",
2500 gnutls_strerror (type));
2501 if (name)
2502 fprintf (outfile, "\tFriendly name: %s\n", name);
2504 id.data = NULL;
2505 id.size = 0;
2506 result = gnutls_pkcs12_bag_get_key_id (bag, i, &id);
2507 if (result < 0)
2508 error (EXIT_FAILURE, 0, "get_key_id: %s", gnutls_strerror (type));
2509 if (id.size > 0)
2510 fprintf (outfile, "\tKey ID: %s\n", raw_to_string (id.data, id.size));
2512 result = gnutls_pkcs12_bag_get_data (bag, i, &cdata);
2513 if (result < 0)
2514 error (EXIT_FAILURE, 0, "get_data: %s", gnutls_strerror (result));
2516 switch (type)
2518 case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY:
2519 str = "ENCRYPTED PRIVATE KEY";
2520 break;
2521 case GNUTLS_BAG_PKCS8_KEY:
2522 str = "PRIVATE KEY";
2523 break;
2524 case GNUTLS_BAG_CERTIFICATE:
2525 str = "CERTIFICATE";
2526 break;
2527 case GNUTLS_BAG_CRL:
2528 str = "CRL";
2529 break;
2530 case GNUTLS_BAG_ENCRYPTED:
2531 case GNUTLS_BAG_EMPTY:
2532 default:
2533 str = NULL;
2536 if (str != NULL)
2538 gnutls_pem_base64_encode_alloc (str, &cdata, &out);
2539 fprintf (outfile, "%s\n", out.data);
2541 gnutls_free (out.data);
2547 void
2548 pkcs12_info (common_info_st* cinfo)
2550 gnutls_pkcs12_t pkcs12;
2551 gnutls_pkcs12_bag_t bag;
2552 int result;
2553 size_t size;
2554 gnutls_datum_t data;
2555 const char *pass;
2556 int indx;
2558 result = gnutls_pkcs12_init (&pkcs12);
2559 if (result < 0)
2560 error (EXIT_FAILURE, 0, "p12_init: %s", gnutls_strerror (result));
2562 data.data = (void*)fread_file (infile, &size);
2563 data.size = size;
2565 result = gnutls_pkcs12_import (pkcs12, &data, incert_format, 0);
2566 free (data.data);
2567 if (result < 0)
2568 error (EXIT_FAILURE, 0, "p12_import: %s", gnutls_strerror (result));
2570 if (cinfo->password)
2571 pass = cinfo->password;
2572 else
2573 pass = get_pass ();
2575 result = gnutls_pkcs12_verify_mac (pkcs12, pass);
2576 if (result < 0)
2577 error (0, 0, "verify_mac: %s", gnutls_strerror (result));
2579 for (indx = 0;; indx++)
2581 result = gnutls_pkcs12_bag_init (&bag);
2582 if (result < 0)
2583 error (EXIT_FAILURE, 0, "bag_init: %s", gnutls_strerror (result));
2585 result = gnutls_pkcs12_get_bag (pkcs12, indx, bag);
2586 if (result < 0)
2587 break;
2589 result = gnutls_pkcs12_bag_get_count (bag);
2590 if (result < 0)
2591 error (EXIT_FAILURE, 0, "bag_count: %s", gnutls_strerror (result));
2593 fprintf (outfile, "BAG #%d\n", indx);
2595 result = gnutls_pkcs12_bag_get_type (bag, 0);
2596 if (result < 0)
2597 error (EXIT_FAILURE, 0, "bag_init: %s", gnutls_strerror (result));
2599 if (result == GNUTLS_BAG_ENCRYPTED)
2601 fprintf (stderr, "\tType: %s\n", BAGTYPE (result));
2602 fprintf (stderr, "\n\tDecrypting...\n");
2604 result = gnutls_pkcs12_bag_decrypt (bag, pass);
2606 if (result < 0)
2608 error (0, 0, "bag_decrypt: %s", gnutls_strerror (result));
2609 continue;
2612 result = gnutls_pkcs12_bag_get_count (bag);
2613 if (result < 0)
2614 error (EXIT_FAILURE, 0, "encrypted bag_count: %s",
2615 gnutls_strerror (result));
2618 print_bag_data (bag);
2620 gnutls_pkcs12_bag_deinit (bag);
2624 void
2625 pkcs7_info (void)
2627 gnutls_pkcs7_t pkcs7;
2628 int result;
2629 size_t size;
2630 gnutls_datum_t data, b64;
2631 int indx, count;
2633 result = gnutls_pkcs7_init (&pkcs7);
2634 if (result < 0)
2635 error (EXIT_FAILURE, 0, "p7_init: %s", gnutls_strerror (result));
2637 data.data = (void*)fread_file (infile, &size);
2638 data.size = size;
2640 result = gnutls_pkcs7_import (pkcs7, &data, incert_format);
2641 free (data.data);
2642 if (result < 0)
2643 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (result));
2645 /* Read and print the certificates.
2647 result = gnutls_pkcs7_get_crt_count (pkcs7);
2648 if (result < 0)
2649 error (EXIT_FAILURE, 0, "p7_crt_count: %s", gnutls_strerror (result));
2651 count = result;
2653 if (count > 0)
2654 fprintf (outfile, "Number of certificates: %u\n", count);
2656 for (indx = 0; indx < count; indx++)
2658 fputs ("\n", outfile);
2660 size = buffer_size;
2661 result = gnutls_pkcs7_get_crt_raw (pkcs7, indx, buffer, &size);
2662 if (result < 0)
2663 break;
2665 data.data = buffer;
2666 data.size = size;
2668 result = gnutls_pem_base64_encode_alloc ("CERTIFICATE", &data, &b64);
2669 if (result < 0)
2670 error (EXIT_FAILURE, 0, "encoding: %s", gnutls_strerror (result));
2672 fputs ((void*)b64.data, outfile);
2673 gnutls_free (b64.data);
2676 /* Read the CRLs now.
2678 result = gnutls_pkcs7_get_crl_count (pkcs7);
2679 if (result < 0)
2680 error (EXIT_FAILURE, 0, "p7_crl_count: %s", gnutls_strerror (result));
2682 count = result;
2684 if (count > 0)
2685 fprintf (outfile, "\nNumber of CRLs: %u\n", count);
2687 for (indx = 0; indx < count; indx++)
2689 fputs ("\n", outfile);
2691 size = buffer_size;
2692 result = gnutls_pkcs7_get_crl_raw (pkcs7, indx, buffer, &size);
2693 if (result < 0)
2694 break;
2696 data.data = buffer;
2697 data.size = size;
2699 result = gnutls_pem_base64_encode_alloc ("X509 CRL", &data, &b64);
2700 if (result < 0)
2701 error (EXIT_FAILURE, 0, "encoding: %s", gnutls_strerror (result));
2703 fputs ((void*)b64.data, outfile);
2704 gnutls_free (b64.data);
2708 void
2709 smime_to_pkcs7 (void)
2711 size_t linesize = 0;
2712 char *lineptr = NULL;
2713 ssize_t len;
2715 /* Find body. FIXME: Handle non-b64 Content-Transfer-Encoding.
2716 Reject non-S/MIME tagged Content-Type's? */
2719 len = getline (&lineptr, &linesize, infile);
2720 if (len == -1)
2721 error (EXIT_FAILURE, 0, "cannot find RFC 2822 header/body separator");
2723 while (strcmp (lineptr, "\r\n") != 0 && strcmp (lineptr, "\n") != 0);
2727 len = getline (&lineptr, &linesize, infile);
2728 if (len == -1)
2729 error (EXIT_FAILURE, 0, "message has RFC 2822 header but no body");
2731 while (strcmp (lineptr, "\r\n") == 0 && strcmp (lineptr, "\n") == 0);
2733 fprintf (outfile, "%s", "-----BEGIN PKCS7-----\n");
2737 while (len > 0
2738 && (lineptr[len - 1] == '\r' || lineptr[len - 1] == '\n'))
2739 lineptr[--len] = '\0';
2740 if (strcmp (lineptr, "") != 0)
2741 fprintf (outfile, "%s\n", lineptr);
2742 len = getline (&lineptr, &linesize, infile);
2744 while (len != -1);
2746 fprintf (outfile, "%s", "-----END PKCS7-----\n");
2748 free (lineptr);
2752 void
2753 pubkey_info (gnutls_x509_crt_t crt, common_info_st * cinfo)
2755 gnutls_pubkey_t pubkey;
2756 int ret;
2757 size_t size;
2759 ret = gnutls_pubkey_init (&pubkey);
2760 if (ret < 0)
2762 error (EXIT_FAILURE, 0, "pubkey_init: %s", gnutls_strerror (ret));
2765 if (crt == NULL)
2767 crt = load_cert (0, cinfo);
2770 if (crt != NULL)
2772 ret = gnutls_pubkey_import_x509 (pubkey, crt, 0);
2773 if (ret < 0)
2775 error (EXIT_FAILURE, 0, "pubkey_import_x509: %s",
2776 gnutls_strerror (ret));
2779 else
2781 pubkey = load_pubkey (1, cinfo);
2784 if (outcert_format == GNUTLS_X509_FMT_DER)
2786 size = buffer_size;
2787 ret = gnutls_pubkey_export (pubkey, outcert_format, buffer, &size);
2788 if (ret < 0)
2789 error (EXIT_FAILURE, 0, "export error: %s", gnutls_strerror (ret));
2791 fwrite (buffer, 1, size, outfile);
2793 gnutls_pubkey_deinit (pubkey);
2795 return;
2798 /* PEM */
2800 _pubkey_info(outfile, pubkey);
2801 gnutls_pubkey_deinit (pubkey);