Added boilerplate.
[gnutls.git] / src / certtool.c
blob8779131ef1522d8b52c45806057f0dca32567b10
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 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);
55 void crq_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);
67 void crl_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,
73 unsigned int all);
74 static void verify_certificate (common_info_st * cinfo);
76 FILE *outfile;
77 FILE *infile;
78 static gnutls_digest_algorithm_t default_dig;
79 static unsigned int incert_format, outcert_format;
80 static unsigned int req_key_type;
82 /* non interactive operation if set
84 int batch;
87 static void
88 tls_log_func (int level, const char *str)
90 fprintf (stderr, "|<%d>| %s", level, str);
93 int
94 main (int argc, char **argv)
96 set_program_name (argv[0]);
97 cfg_init ();
98 cmd_parser (argc, argv);
100 return 0;
103 static gnutls_x509_privkey_t
104 generate_private_key_int (common_info_st * cinfo)
106 gnutls_x509_privkey_t key;
107 int ret, key_type, bits;
109 key_type = req_key_type;
111 ret = gnutls_x509_privkey_init (&key);
112 if (ret < 0)
113 error (EXIT_FAILURE, 0, "privkey_init: %s", gnutls_strerror (ret));
115 bits = get_bits (key_type, cinfo->bits, cinfo->sec_param);
117 fprintf (stderr, "Generating a %d bit %s private key...\n",
118 bits, gnutls_pk_algorithm_get_name (key_type));
120 if (bits > 1024 && key_type == GNUTLS_PK_DSA)
121 fprintf (stderr,
122 "Note that DSA keys with size over 1024 can only be used with TLS 1.2 or later.\n\n");
124 ret = gnutls_x509_privkey_generate (key, key_type, bits, 0);
125 if (ret < 0)
126 error (EXIT_FAILURE, 0, "privkey_generate: %s", gnutls_strerror (ret));
128 ret = gnutls_x509_privkey_verify_params (key);
129 if (ret < 0)
130 error (EXIT_FAILURE, 0, "privkey_verify_params: %s", gnutls_strerror (ret));
132 return key;
135 static int
136 cipher_to_flags (const char *cipher)
138 if (cipher == NULL)
140 return GNUTLS_PKCS_USE_PBES2_AES_128;
142 else if (strcasecmp (cipher, "3des") == 0)
144 return GNUTLS_PKCS_USE_PBES2_3DES;
146 else if (strcasecmp (cipher, "3des-pkcs12") == 0)
148 return GNUTLS_PKCS_USE_PKCS12_3DES;
150 else if (strcasecmp (cipher, "arcfour") == 0)
152 return GNUTLS_PKCS_USE_PKCS12_ARCFOUR;
154 else if (strcasecmp (cipher, "aes-128") == 0)
156 return GNUTLS_PKCS_USE_PBES2_AES_128;
158 else if (strcasecmp (cipher, "aes-192") == 0)
160 return GNUTLS_PKCS_USE_PBES2_AES_192;
162 else if (strcasecmp (cipher, "aes-256") == 0)
164 return GNUTLS_PKCS_USE_PBES2_AES_256;
166 else if (strcasecmp (cipher, "rc2-40") == 0)
168 return GNUTLS_PKCS_USE_PKCS12_RC2_40;
171 error (EXIT_FAILURE, 0, "unknown cipher %s\n", cipher);
172 return -1;
176 static void
177 print_private_key (common_info_st* cinfo, gnutls_x509_privkey_t key)
179 int ret;
180 size_t size;
182 if (!key)
183 return;
185 if (outcert_format == GNUTLS_X509_FMT_PEM)
186 privkey_info_int(cinfo, key);
188 if (!cinfo->pkcs8)
190 size = buffer_size;
191 ret = gnutls_x509_privkey_export (key, outcert_format,
192 buffer, &size);
193 if (ret < 0)
194 error (EXIT_FAILURE, 0, "privkey_export: %s", gnutls_strerror (ret));
196 else
198 unsigned int flags = 0;
199 const char *pass;
201 pass = get_password(cinfo, &flags, 0);
202 flags |= cipher_to_flags (cinfo->pkcs_cipher);
204 size = buffer_size;
205 ret =
206 gnutls_x509_privkey_export_pkcs8 (key, outcert_format, pass,
207 flags, buffer, &size);
208 if (ret < 0)
209 error (EXIT_FAILURE, 0, "privkey_export_pkcs8: %s",
210 gnutls_strerror (ret));
213 fwrite (buffer, 1, size, outfile);
216 static void
217 generate_private_key (common_info_st* cinfo)
219 gnutls_x509_privkey_t key;
221 key = generate_private_key_int (cinfo);
223 print_private_key (cinfo, key);
225 gnutls_x509_privkey_deinit (key);
229 static gnutls_x509_crt_t
230 generate_certificate (gnutls_privkey_t * ret_key,
231 gnutls_x509_crt_t ca_crt, int proxy,
232 common_info_st * cinfo)
234 gnutls_x509_crt_t crt;
235 gnutls_privkey_t key = NULL;
236 gnutls_pubkey_t pubkey;
237 size_t size;
238 int ret;
239 int client;
240 int days, result, ca_status = 0, is_ike = 0, path_len;
241 int vers;
242 unsigned int usage = 0, server;
243 gnutls_x509_crq_t crq; /* request */
245 ret = gnutls_x509_crt_init (&crt);
246 if (ret < 0)
247 error (EXIT_FAILURE, 0, "crt_init: %s", gnutls_strerror (ret));
249 crq = load_request (cinfo);
251 if (crq == NULL)
254 key = load_private_key (0, cinfo);
256 pubkey = load_public_key_or_import (1, key, cinfo);
258 if (!batch)
259 fprintf (stderr,
260 "Please enter the details of the certificate's distinguished name. "
261 "Just press enter to ignore a field.\n");
263 /* set the DN.
265 if (proxy)
267 result = gnutls_x509_crt_set_proxy_dn (crt, ca_crt, 0, NULL, 0);
268 if (result < 0)
269 error (EXIT_FAILURE, 0, "set_proxy_dn: %s",
270 gnutls_strerror (result));
272 get_cn_crt_set (crt);
274 else
276 get_country_crt_set (crt);
277 get_organization_crt_set (crt);
278 get_unit_crt_set (crt);
279 get_locality_crt_set (crt);
280 get_state_crt_set (crt);
281 get_cn_crt_set (crt);
282 get_dc_set (TYPE_CRT, crt);
283 get_uid_crt_set (crt);
284 get_oid_crt_set (crt);
285 get_key_purpose_set (crt);
287 if (!batch)
288 fprintf (stderr,
289 "This field should not be used in new certificates.\n");
291 get_pkcs9_email_crt_set (crt);
294 result = gnutls_x509_crt_set_pubkey (crt, pubkey);
295 if (result < 0)
296 error (EXIT_FAILURE, 0, "set_key: %s", gnutls_strerror (result));
298 else
300 result = gnutls_x509_crt_set_crq (crt, crq);
301 if (result < 0)
302 error (EXIT_FAILURE, 0, "set_crq: %s", gnutls_strerror (result));
307 int serial = get_serial ();
308 char bin_serial[5];
310 bin_serial[4] = serial & 0xff;
311 bin_serial[3] = (serial >> 8) & 0xff;
312 bin_serial[2] = (serial >> 16) & 0xff;
313 bin_serial[1] = (serial >> 24) & 0xff;
314 bin_serial[0] = 0;
316 result = gnutls_x509_crt_set_serial (crt, bin_serial, 5);
317 if (result < 0)
318 error (EXIT_FAILURE, 0, "serial: %s", gnutls_strerror (result));
321 if (!batch)
322 fprintf (stderr, "\n\nActivation/Expiration time.\n");
324 gnutls_x509_crt_set_activation_time (crt, time (NULL));
326 days = get_days ();
328 result =
329 gnutls_x509_crt_set_expiration_time (crt,
330 time (NULL) + ((time_t) days) * 24 * 60 * 60);
331 if (result < 0)
332 error (EXIT_FAILURE, 0, "set_expiration: %s", gnutls_strerror (result));
334 if (!batch)
335 fprintf (stderr, "\n\nExtensions.\n");
337 /* do not allow extensions on a v1 certificate */
338 if (crq && get_crq_extensions_status () != 0)
340 result = gnutls_x509_crt_set_crq_extensions (crt, crq);
341 if (result < 0)
342 error (EXIT_FAILURE, 0, "set_crq: %s", gnutls_strerror (result));
345 /* append additional extensions */
346 if (cinfo->v1_cert == 0)
349 if (proxy)
351 const char *policylanguage;
352 char *policy;
353 size_t policylen;
354 int proxypathlen = get_path_len ();
356 if (!batch)
358 printf ("1.3.6.1.5.5.7.21.1 ::= id-ppl-inheritALL\n");
359 printf ("1.3.6.1.5.5.7.21.2 ::= id-ppl-independent\n");
362 policylanguage = get_proxy_policy (&policy, &policylen);
364 result =
365 gnutls_x509_crt_set_proxy (crt, proxypathlen, policylanguage,
366 policy, policylen);
367 if (result < 0)
368 error (EXIT_FAILURE, 0, "set_proxy: %s",
369 gnutls_strerror (result));
372 if (!proxy)
373 ca_status = get_ca_status ();
374 if (ca_status)
375 path_len = get_path_len ();
376 else
377 path_len = -1;
379 result =
380 gnutls_x509_crt_set_basic_constraints (crt, ca_status, path_len);
381 if (result < 0)
382 error (EXIT_FAILURE, 0, "basic_constraints: %s",
383 gnutls_strerror (result));
385 client = get_tls_client_status ();
386 if (client != 0)
388 result = gnutls_x509_crt_set_key_purpose_oid (crt,
389 GNUTLS_KP_TLS_WWW_CLIENT,
391 if (result < 0)
392 error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (result));
395 is_ike = get_ipsec_ike_status ();
396 server = get_tls_server_status ();
398 get_dns_name_set (TYPE_CRT, crt);
399 get_uri_set (TYPE_CRT, crt);
400 get_ip_addr_set (TYPE_CRT, crt);
402 if (server != 0)
404 result = 0;
406 result =
407 gnutls_x509_crt_set_key_purpose_oid (crt,
408 GNUTLS_KP_TLS_WWW_SERVER, 0);
409 if (result < 0)
410 error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (result));
412 else if (!proxy)
414 get_email_set (TYPE_CRT, crt);
417 if (!ca_status || server)
419 int pk;
422 pk = gnutls_x509_crt_get_pk_algorithm (crt, NULL);
424 if (pk == GNUTLS_PK_RSA)
425 { /* DSA and ECDSA keys can only sign. */
426 result = get_sign_status (server);
427 if (result)
428 usage |= GNUTLS_KEY_DIGITAL_SIGNATURE;
430 result = get_encrypt_status (server);
431 if (result)
432 usage |= GNUTLS_KEY_KEY_ENCIPHERMENT;
434 else
435 usage |= GNUTLS_KEY_DIGITAL_SIGNATURE;
437 if (is_ike)
439 result =
440 gnutls_x509_crt_set_key_purpose_oid (crt,
441 GNUTLS_KP_IPSEC_IKE, 0);
442 if (result < 0)
443 error (EXIT_FAILURE, 0, "key_kp: %s",
444 gnutls_strerror (result));
449 if (ca_status)
451 result = get_cert_sign_status ();
452 if (result)
453 usage |= GNUTLS_KEY_KEY_CERT_SIGN;
455 result = get_crl_sign_status ();
456 if (result)
457 usage |= GNUTLS_KEY_CRL_SIGN;
459 result = get_code_sign_status ();
460 if (result)
462 result =
463 gnutls_x509_crt_set_key_purpose_oid (crt,
464 GNUTLS_KP_CODE_SIGNING,
466 if (result < 0)
467 error (EXIT_FAILURE, 0, "key_kp: %s",
468 gnutls_strerror (result));
471 result = get_ocsp_sign_status ();
472 if (result)
474 result =
475 gnutls_x509_crt_set_key_purpose_oid (crt,
476 GNUTLS_KP_OCSP_SIGNING,
478 if (result < 0)
479 error (EXIT_FAILURE, 0, "key_kp: %s",
480 gnutls_strerror (result));
483 result = get_time_stamp_status ();
484 if (result)
486 result =
487 gnutls_x509_crt_set_key_purpose_oid (crt,
488 GNUTLS_KP_TIME_STAMPING,
490 if (result < 0)
491 error (EXIT_FAILURE, 0, "key_kp: %s",
492 gnutls_strerror (result));
495 get_ocsp_issuer_set(crt);
496 get_ca_issuers_set(crt);
498 if (usage != 0)
500 /* http://tools.ietf.org/html/rfc4945#section-5.1.3.2: if any KU is
501 set, then either digitalSignature or the nonRepudiation bits in the
502 KeyUsage extension MUST for all IKE certs */
503 if (is_ike && (get_sign_status (server) != 1))
504 usage |= GNUTLS_KEY_NON_REPUDIATION;
505 result = gnutls_x509_crt_set_key_usage (crt, usage);
506 if (result < 0)
507 error (EXIT_FAILURE, 0, "key_usage: %s",
508 gnutls_strerror (result));
511 /* Subject Key ID.
513 size = buffer_size;
514 result = gnutls_x509_crt_get_key_id (crt, 0, buffer, &size);
515 if (result >= 0)
517 result = gnutls_x509_crt_set_subject_key_id (crt, buffer, size);
518 if (result < 0)
519 error (EXIT_FAILURE, 0, "set_subject_key_id: %s",
520 gnutls_strerror (result));
523 /* Authority Key ID.
525 if (ca_crt != NULL)
527 size = buffer_size;
528 result = gnutls_x509_crt_get_subject_key_id (ca_crt, buffer,
529 &size, NULL);
530 if (result < 0)
532 size = buffer_size;
533 result = gnutls_x509_crt_get_key_id (ca_crt, 0, buffer, &size);
535 if (result >= 0)
537 result =
538 gnutls_x509_crt_set_authority_key_id (crt, buffer, size);
539 if (result < 0)
540 error (EXIT_FAILURE, 0, "set_authority_key_id: %s",
541 gnutls_strerror (result));
546 /* Version.
548 if (cinfo->v1_cert != 0)
549 vers = 1;
550 else
551 vers = 3;
552 result = gnutls_x509_crt_set_version (crt, vers);
553 if (result < 0)
554 error (EXIT_FAILURE, 0, "set_version: %s", gnutls_strerror (result));
556 *ret_key = key;
557 return crt;
561 static gnutls_x509_crl_t
562 generate_crl (gnutls_x509_crt_t ca_crt, common_info_st * cinfo)
564 gnutls_x509_crl_t crl;
565 gnutls_x509_crt_t *crts;
566 size_t size;
567 int days, result;
568 unsigned int i;
569 time_t now = time (NULL);
571 result = gnutls_x509_crl_init (&crl);
572 if (result < 0)
573 error (EXIT_FAILURE, 0, "crl_init: %s", gnutls_strerror (result));
575 crts = load_cert_list (0, &size, cinfo);
577 for (i = 0; i < size; i++)
579 result = gnutls_x509_crl_set_crt (crl, crts[i], now);
580 if (result < 0)
581 error (EXIT_FAILURE, 0, "crl_set_crt: %s", gnutls_strerror (result));
584 result = gnutls_x509_crl_set_this_update (crl, now);
585 if (result < 0)
586 error (EXIT_FAILURE, 0, "this_update: %s", gnutls_strerror (result));
588 fprintf (stderr, "Update times.\n");
589 days = get_crl_next_update ();
591 result = gnutls_x509_crl_set_next_update (crl, now + days * 24 * 60 * 60);
592 if (result < 0)
593 error (EXIT_FAILURE, 0, "next_update: %s", gnutls_strerror (result));
595 result = gnutls_x509_crl_set_version (crl, 2);
596 if (result < 0)
597 error (EXIT_FAILURE, 0, "set_version: %s", gnutls_strerror (result));
599 /* Authority Key ID.
601 if (ca_crt != NULL)
603 size = buffer_size;
604 result = gnutls_x509_crt_get_subject_key_id (ca_crt, buffer,
605 &size, NULL);
606 if (result < 0)
608 size = buffer_size;
609 result = gnutls_x509_crt_get_key_id (ca_crt, 0, buffer, &size);
611 if (result >= 0)
613 result = gnutls_x509_crl_set_authority_key_id (crl, buffer, size);
614 if (result < 0)
615 error (EXIT_FAILURE, 0, "set_authority_key_id: %s",
616 gnutls_strerror (result));
621 unsigned int number = get_crl_number ();
622 char bin_number[5];
624 bin_number[4] = number & 0xff;
625 bin_number[3] = (number >> 8) & 0xff;
626 bin_number[2] = (number >> 16) & 0xff;
627 bin_number[1] = (number >> 24) & 0xff;
628 bin_number[0] = 0;
630 result = gnutls_x509_crl_set_number (crl, bin_number, 5);
631 if (result < 0)
632 error (EXIT_FAILURE, 0, "set_number: %s", gnutls_strerror (result));
635 return crl;
638 static gnutls_digest_algorithm_t
639 get_dig_for_pub (gnutls_pubkey_t pubkey)
641 gnutls_digest_algorithm_t dig;
642 int result;
643 unsigned int mand;
645 result = gnutls_pubkey_get_preferred_hash_algorithm (pubkey, &dig, &mand);
646 if (result < 0)
648 error (EXIT_FAILURE, 0, "crt_get_preferred_hash_algorithm: %s",
649 gnutls_strerror (result));
652 /* if algorithm allows alternatives */
653 if (mand == 0 && default_dig != GNUTLS_DIG_UNKNOWN)
654 dig = default_dig;
656 return dig;
659 static gnutls_digest_algorithm_t
660 get_dig (gnutls_x509_crt_t crt)
662 gnutls_digest_algorithm_t dig;
663 gnutls_pubkey_t pubkey;
664 int result;
666 gnutls_pubkey_init(&pubkey);
668 result = gnutls_pubkey_import_x509(pubkey, crt, 0);
669 if (result < 0)
671 error (EXIT_FAILURE, 0, "gnutls_pubkey_import_x509: %s",
672 gnutls_strerror (result));
675 dig = get_dig_for_pub (pubkey);
677 gnutls_pubkey_deinit(pubkey);
679 return dig;
682 void
683 generate_self_signed (common_info_st * cinfo)
685 gnutls_x509_crt_t crt;
686 gnutls_privkey_t key;
687 size_t size;
688 int result;
689 const char *uri;
691 fprintf (stderr, "Generating a self signed certificate...\n");
693 crt = generate_certificate (&key, NULL, 0, cinfo);
695 if (!key)
696 key = load_private_key (1, cinfo);
698 uri = get_crl_dist_point_url ();
699 if (uri)
701 result = gnutls_x509_crt_set_crl_dist_points (crt, GNUTLS_SAN_URI,
702 uri,
703 0 /* all reasons */ );
704 if (result < 0)
705 error (EXIT_FAILURE, 0, "crl_dist_points: %s",
706 gnutls_strerror (result));
709 print_certificate_info (crt, stderr, 0);
711 fprintf (stderr, "\n\nSigning certificate...\n");
713 result = gnutls_x509_crt_privkey_sign (crt, crt, key, get_dig (crt), 0);
714 if (result < 0)
715 error (EXIT_FAILURE, 0, "crt_sign: %s", gnutls_strerror (result));
717 size = buffer_size;
718 result = gnutls_x509_crt_export (crt, outcert_format, buffer, &size);
719 if (result < 0)
720 error (EXIT_FAILURE, 0, "crt_export: %s", gnutls_strerror (result));
722 fwrite (buffer, 1, size, outfile);
724 gnutls_x509_crt_deinit (crt);
725 gnutls_privkey_deinit (key);
728 static void
729 generate_signed_certificate (common_info_st * cinfo)
731 gnutls_x509_crt_t crt;
732 gnutls_privkey_t key;
733 size_t size;
734 int result;
735 gnutls_privkey_t ca_key;
736 gnutls_x509_crt_t ca_crt;
738 fprintf (stderr, "Generating a signed certificate...\n");
740 ca_key = load_ca_private_key (cinfo);
741 ca_crt = load_ca_cert (cinfo);
743 crt = generate_certificate (&key, ca_crt, 0, cinfo);
745 /* Copy the CRL distribution points.
747 gnutls_x509_crt_cpy_crl_dist_points (crt, ca_crt);
748 /* it doesn't matter if we couldn't copy the CRL dist points.
751 print_certificate_info (crt, stderr, 0);
753 fprintf (stderr, "\n\nSigning certificate...\n");
755 result = gnutls_x509_crt_privkey_sign (crt, ca_crt, ca_key, get_dig (ca_crt), 0);
756 if (result < 0)
757 error (EXIT_FAILURE, 0, "crt_sign: %s", gnutls_strerror (result));
759 size = buffer_size;
760 result = gnutls_x509_crt_export (crt, outcert_format, buffer, &size);
761 if (result < 0)
762 error (EXIT_FAILURE, 0, "crt_export: %s", gnutls_strerror (result));
764 fwrite (buffer, 1, size, outfile);
766 gnutls_x509_crt_deinit (crt);
767 gnutls_privkey_deinit (key);
768 gnutls_privkey_deinit(ca_key);
771 static void
772 generate_proxy_certificate (common_info_st * cinfo)
774 gnutls_x509_crt_t crt, eecrt;
775 gnutls_privkey_t key, eekey;
776 size_t size;
777 int result;
779 fprintf (stderr, "Generating a proxy certificate...\n");
781 eekey = load_ca_private_key (cinfo);
782 eecrt = load_cert (1, cinfo);
784 crt = generate_certificate (&key, eecrt, 1, cinfo);
786 print_certificate_info (crt, stderr, 0);
788 fprintf (stderr, "\n\nSigning certificate...\n");
790 result = gnutls_x509_crt_privkey_sign (crt, eecrt, eekey, get_dig (eecrt), 0);
791 if (result < 0)
792 error (EXIT_FAILURE, 0, "crt_sign: %s", gnutls_strerror (result));
794 size = buffer_size;
795 result = gnutls_x509_crt_export (crt, outcert_format, buffer, &size);
796 if (result < 0)
797 error (EXIT_FAILURE, 0, "crt_export: %s", gnutls_strerror (result));
799 fwrite (buffer, 1, size, outfile);
801 gnutls_x509_crt_deinit (eecrt);
802 gnutls_x509_crt_deinit (crt);
803 gnutls_privkey_deinit (key);
804 gnutls_privkey_deinit (eekey);
807 static void
808 generate_signed_crl (common_info_st * cinfo)
810 gnutls_x509_crl_t crl;
811 int result;
812 gnutls_privkey_t ca_key;
813 gnutls_x509_crt_t ca_crt;
815 fprintf (stderr, "Generating a signed CRL...\n");
817 ca_key = load_ca_private_key (cinfo);
818 ca_crt = load_ca_cert (cinfo);
819 crl = generate_crl (ca_crt, cinfo);
821 fprintf (stderr, "\n");
822 result = gnutls_x509_crl_privkey_sign(crl, ca_crt, ca_key, get_dig (ca_crt), 0);
823 if (result < 0)
824 error (EXIT_FAILURE, 0, "crl_privkey_sign: %s", gnutls_strerror (result));
826 print_crl_info (crl, stderr);
828 gnutls_privkey_deinit( ca_key);
829 gnutls_x509_crl_deinit (crl);
832 static void
833 update_signed_certificate (common_info_st * cinfo)
835 gnutls_x509_crt_t crt;
836 size_t size;
837 int result;
838 gnutls_privkey_t ca_key;
839 gnutls_x509_crt_t ca_crt;
840 int days;
841 time_t tim = time (NULL);
843 fprintf (stderr, "Generating a signed certificate...\n");
845 ca_key = load_ca_private_key (cinfo);
846 ca_crt = load_ca_cert (cinfo);
847 crt = load_cert (1, cinfo);
849 fprintf (stderr, "Activation/Expiration time.\n");
850 gnutls_x509_crt_set_activation_time (crt, tim);
852 days = get_days ();
854 result =
855 gnutls_x509_crt_set_expiration_time (crt, tim + ((time_t) days) * 24 * 60 * 60);
856 if (result < 0)
857 error (EXIT_FAILURE, 0, "set_expiration: %s", gnutls_strerror (result));
859 fprintf (stderr, "\n\nSigning certificate...\n");
861 result = gnutls_x509_crt_privkey_sign (crt, ca_crt, ca_key, get_dig (ca_crt), 0);
862 if (result < 0)
863 error (EXIT_FAILURE, 0, "crt_sign: %s", gnutls_strerror (result));
865 size = buffer_size;
866 result = gnutls_x509_crt_export (crt, outcert_format, buffer, &size);
867 if (result < 0)
868 error (EXIT_FAILURE, 0, "crt_export: %s", gnutls_strerror (result));
870 fwrite (buffer, 1, size, outfile);
872 gnutls_x509_crt_deinit (crt);
875 static void
876 cmd_parser (int argc, char **argv)
878 int ret, privkey_op = 0;
879 common_info_st cinfo;
881 optionProcess( &certtoolOptions, argc, argv);
883 if (HAVE_OPT(GENERATE_PRIVKEY) || HAVE_OPT(GENERATE_REQUEST) ||
884 HAVE_OPT(KEY_INFO) || HAVE_OPT(PGP_KEY_INFO))
885 privkey_op = 1;
887 if (HAVE_OPT(OUTFILE))
889 outfile = safe_open_rw (OPT_ARG(OUTFILE), privkey_op);
890 if (outfile == NULL)
891 error (EXIT_FAILURE, errno, "%s", OPT_ARG(OUTFILE));
893 else
894 outfile = stdout;
896 if (HAVE_OPT(INFILE))
898 infile = fopen (OPT_ARG(INFILE), "rb");
899 if (infile == NULL)
900 error (EXIT_FAILURE, errno, "%s", OPT_ARG(INFILE));
902 else
903 infile = stdin;
905 if (HAVE_OPT(INDER) || HAVE_OPT(INRAW))
906 incert_format = GNUTLS_X509_FMT_DER;
907 else
908 incert_format = GNUTLS_X509_FMT_PEM;
910 if (HAVE_OPT(OUTDER) || HAVE_OPT(OUTRAW))
911 outcert_format = GNUTLS_X509_FMT_DER;
912 else
913 outcert_format = GNUTLS_X509_FMT_PEM;
915 if (HAVE_OPT(DSA))
916 req_key_type = GNUTLS_PK_DSA;
917 else if (HAVE_OPT(ECC))
918 req_key_type = GNUTLS_PK_ECC;
919 else
920 req_key_type = GNUTLS_PK_RSA;
922 default_dig = GNUTLS_DIG_UNKNOWN;
923 if (HAVE_OPT(HASH))
925 if (strcasecmp (OPT_ARG(HASH), "md5") == 0)
927 fprintf (stderr,
928 "Warning: MD5 is broken, and should not be used any more for digital signatures.\n");
929 default_dig = GNUTLS_DIG_MD5;
931 else if (strcasecmp (OPT_ARG(HASH), "sha1") == 0)
932 default_dig = GNUTLS_DIG_SHA1;
933 else if (strcasecmp (OPT_ARG(HASH), "sha256") == 0)
934 default_dig = GNUTLS_DIG_SHA256;
935 else if (strcasecmp (OPT_ARG(HASH), "sha224") == 0)
936 default_dig = GNUTLS_DIG_SHA224;
937 else if (strcasecmp (OPT_ARG(HASH), "sha384") == 0)
938 default_dig = GNUTLS_DIG_SHA384;
939 else if (strcasecmp (OPT_ARG(HASH), "sha512") == 0)
940 default_dig = GNUTLS_DIG_SHA512;
941 else if (strcasecmp (OPT_ARG(HASH), "rmd160") == 0)
942 default_dig = GNUTLS_DIG_RMD160;
943 else
944 error (EXIT_FAILURE, 0, "invalid hash: %s", OPT_ARG(HASH));
947 batch = 0;
948 if (HAVE_OPT(TEMPLATE))
950 batch = 1;
951 template_parse (OPT_ARG(TEMPLATE));
954 gnutls_global_set_log_function (tls_log_func);
956 if (HAVE_OPT(DEBUG))
958 gnutls_global_set_log_level (OPT_VALUE_DEBUG);
959 printf ("Setting log level to %d\n", (int)OPT_VALUE_DEBUG);
962 if ((ret = gnutls_global_init ()) < 0)
963 error (EXIT_FAILURE, 0, "global_init: %s", gnutls_strerror (ret));
965 #ifdef ENABLE_PKCS11
966 pkcs11_common();
967 #endif
969 memset (&cinfo, 0, sizeof (cinfo));
971 if (HAVE_OPT(LOAD_PRIVKEY))
972 cinfo.privkey = OPT_ARG(LOAD_PRIVKEY);
974 cinfo.v1_cert = HAVE_OPT(V1);
975 if (HAVE_OPT(NO_CRQ_EXTENSIONS))
976 cinfo.crq_extensions = 0;
977 else cinfo.crq_extensions = 1;
979 if (HAVE_OPT(LOAD_PUBKEY))
980 cinfo.pubkey = OPT_ARG(LOAD_PUBKEY);
982 cinfo.pkcs8 = HAVE_OPT(PKCS8);
983 cinfo.incert_format = incert_format;
985 if (HAVE_OPT(LOAD_CERTIFICATE))
986 cinfo.cert = OPT_ARG(LOAD_CERTIFICATE);
988 if (HAVE_OPT(LOAD_REQUEST))
989 cinfo.request = OPT_ARG(LOAD_REQUEST);
991 if (HAVE_OPT(LOAD_CA_CERTIFICATE))
992 cinfo.ca = OPT_ARG(LOAD_CA_CERTIFICATE);
994 if (HAVE_OPT(LOAD_CA_PRIVKEY))
995 cinfo.ca_privkey = OPT_ARG(LOAD_CA_PRIVKEY);
997 if (HAVE_OPT(BITS))
998 cinfo.bits = OPT_VALUE_BITS;
1000 if (HAVE_OPT(SEC_PARAM))
1001 cinfo.sec_param = OPT_ARG(SEC_PARAM);
1003 if (HAVE_OPT(PKCS_CIPHER))
1004 cinfo.pkcs_cipher = OPT_ARG(PKCS_CIPHER);
1006 if (HAVE_OPT(PASSWORD))
1008 cinfo.password = OPT_ARG(PASSWORD);
1009 if (HAVE_OPT(GENERATE_PRIVKEY) && cinfo.pkcs8 == 0)
1011 fprintf(stderr, "Assuming PKCS #8 format...\n");
1012 cinfo.pkcs8 = 1;
1016 if (HAVE_OPT(NULL_PASSWORD))
1018 cinfo.null_password = 1;
1019 cinfo.password = "";
1022 if (HAVE_OPT(GENERATE_SELF_SIGNED))
1023 generate_self_signed (&cinfo);
1024 else if (HAVE_OPT(GENERATE_CERTIFICATE))
1025 generate_signed_certificate (&cinfo);
1026 else if (HAVE_OPT(GENERATE_PROXY))
1027 generate_proxy_certificate (&cinfo);
1028 else if (HAVE_OPT(GENERATE_CRL))
1029 generate_signed_crl (&cinfo);
1030 else if (HAVE_OPT(UPDATE_CERTIFICATE))
1031 update_signed_certificate (&cinfo);
1032 else if (HAVE_OPT(GENERATE_PRIVKEY))
1033 generate_private_key (&cinfo);
1034 else if (HAVE_OPT(GENERATE_REQUEST))
1035 generate_request (&cinfo);
1036 else if (HAVE_OPT(VERIFY_CHAIN))
1037 verify_chain ();
1038 else if (HAVE_OPT(VERIFY))
1039 verify_certificate (&cinfo);
1040 else if (HAVE_OPT(VERIFY_CRL))
1041 verify_crl (&cinfo);
1042 else if (HAVE_OPT(CERTIFICATE_INFO))
1043 certificate_info (0, &cinfo);
1044 else if (HAVE_OPT(DH_INFO))
1045 dh_info (&cinfo);
1046 else if (HAVE_OPT(CERTIFICATE_PUBKEY))
1047 certificate_info (1, &cinfo);
1048 else if (HAVE_OPT(KEY_INFO))
1049 privkey_info (&cinfo);
1050 else if (HAVE_OPT(PUBKEY_INFO))
1051 pubkey_info (NULL, &cinfo);
1052 else if (HAVE_OPT(TO_P12))
1053 generate_pkcs12 (&cinfo);
1054 else if (HAVE_OPT(P12_INFO))
1055 pkcs12_info (&cinfo);
1056 else if (HAVE_OPT(GENERATE_DH_PARAMS))
1057 generate_prime (1, &cinfo);
1058 else if (HAVE_OPT(GET_DH_PARAMS))
1059 generate_prime (0, &cinfo);
1060 else if (HAVE_OPT(CRL_INFO))
1061 crl_info ();
1062 else if (HAVE_OPT(P7_INFO))
1063 pkcs7_info ();
1064 else if (HAVE_OPT(SMIME_TO_P7))
1065 smime_to_pkcs7 ();
1066 else if (HAVE_OPT(TO_P8))
1067 generate_pkcs8 (&cinfo);
1068 #ifdef ENABLE_OPENPGP
1069 else if (HAVE_OPT(PGP_CERTIFICATE_INFO))
1070 pgp_certificate_info ();
1071 else if (HAVE_OPT(PGP_KEY_INFO))
1072 pgp_privkey_info ();
1073 else if (HAVE_OPT(PGP_RING_INFO))
1074 pgp_ring_info ();
1075 #endif
1076 else if (HAVE_OPT(CRQ_INFO))
1077 crq_info ();
1078 else
1079 USAGE(1);
1081 fclose (outfile);
1083 #ifdef ENABLE_PKCS11
1084 gnutls_pkcs11_deinit ();
1085 #endif
1086 gnutls_global_deinit ();
1089 #define MAX_CRTS 500
1090 void
1091 certificate_info (int pubkey, common_info_st * cinfo)
1093 gnutls_x509_crt_t crt[MAX_CRTS];
1094 size_t size;
1095 int ret, i, count;
1096 gnutls_datum_t pem;
1097 unsigned int crt_num;
1099 pem.data = (void*)fread_file (infile, &size);
1100 pem.size = size;
1102 crt_num = MAX_CRTS;
1103 ret =
1104 gnutls_x509_crt_list_import (crt, &crt_num, &pem, incert_format,
1105 GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
1106 if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
1108 error (0, 0, "too many certificates (%d); "
1109 "will only read the first %d", crt_num, MAX_CRTS);
1110 crt_num = MAX_CRTS;
1111 ret = gnutls_x509_crt_list_import (crt, &crt_num, &pem,
1112 incert_format, 0);
1114 if (ret < 0)
1115 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (ret));
1117 free (pem.data);
1119 count = ret;
1121 if (count > 1 && outcert_format == GNUTLS_X509_FMT_DER)
1123 error (0, 0, "cannot output multiple certificates in DER format; "
1124 "using PEM instead");
1125 outcert_format = GNUTLS_X509_FMT_PEM;
1128 for (i = 0; i < count; i++)
1130 if (i > 0)
1131 fprintf (outfile, "\n");
1133 if (outcert_format == GNUTLS_X509_FMT_PEM)
1134 print_certificate_info (crt[i], outfile, 1);
1136 if (pubkey)
1137 pubkey_info (crt[i], cinfo);
1138 else
1140 size = buffer_size;
1141 ret = gnutls_x509_crt_export (crt[i], outcert_format, buffer,
1142 &size);
1143 if (ret < 0)
1144 error (EXIT_FAILURE, 0, "export error: %s", gnutls_strerror (ret));
1146 fwrite (buffer, 1, size, outfile);
1149 gnutls_x509_crt_deinit (crt[i]);
1153 #ifdef ENABLE_OPENPGP
1155 void
1156 pgp_certificate_info (void)
1158 gnutls_openpgp_crt_t crt;
1159 size_t size;
1160 int ret;
1161 gnutls_datum_t pem, out_data;
1162 unsigned int verify_status;
1164 pem.data = (void*)fread_file (infile, &size);
1165 pem.size = size;
1167 ret = gnutls_openpgp_crt_init (&crt);
1168 if (ret < 0)
1169 error (EXIT_FAILURE, 0, "openpgp_crt_init: %s", gnutls_strerror (ret));
1171 ret = gnutls_openpgp_crt_import (crt, &pem, incert_format);
1173 if (ret < 0)
1174 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (ret));
1176 free (pem.data);
1178 if (outcert_format == GNUTLS_OPENPGP_FMT_BASE64)
1180 ret = gnutls_openpgp_crt_print (crt, 0, &out_data);
1182 if (ret == 0)
1184 fprintf (outfile, "%s\n", out_data.data);
1185 gnutls_free (out_data.data);
1190 ret = gnutls_openpgp_crt_verify_self (crt, 0, &verify_status);
1191 if (ret < 0)
1193 error (EXIT_FAILURE, 0, "verify signature error: %s",
1194 gnutls_strerror (ret));
1197 if (verify_status & GNUTLS_CERT_INVALID)
1199 fprintf (outfile, "Self Signature verification: failed\n\n");
1201 else
1203 fprintf (outfile, "Self Signature verification: ok (%x)\n\n",
1204 verify_status);
1207 size = buffer_size;
1208 ret = gnutls_openpgp_crt_export (crt, outcert_format, buffer, &size);
1209 if (ret < 0)
1211 error (EXIT_FAILURE, 0, "export error: %s", gnutls_strerror (ret));
1212 fwrite (buffer, 1, size, outfile);
1215 fprintf (outfile, "%s\n", buffer);
1216 gnutls_openpgp_crt_deinit (crt);
1219 void
1220 pgp_privkey_info (void)
1222 gnutls_openpgp_privkey_t key;
1223 unsigned char keyid[GNUTLS_OPENPGP_KEYID_SIZE];
1224 size_t size;
1225 int ret, i, subkeys, bits = 0;
1226 gnutls_datum_t pem;
1227 const char *cprint;
1229 size = fread (buffer, 1, buffer_size - 1, infile);
1230 buffer[size] = 0;
1232 gnutls_openpgp_privkey_init (&key);
1234 pem.data = buffer;
1235 pem.size = size;
1237 ret = gnutls_openpgp_privkey_import (key, &pem, incert_format,
1238 NULL, 0);
1240 if (ret < 0)
1241 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (ret));
1243 /* Public key algorithm
1245 subkeys = gnutls_openpgp_privkey_get_subkey_count (key);
1246 if (subkeys < 0)
1247 error (EXIT_FAILURE, 0, "privkey_get_subkey_count: %s",
1248 gnutls_strerror (subkeys));
1250 for (i = -1; i < subkeys; i++)
1253 if (i != -1)
1254 fprintf (outfile, "Subkey[%d]:\n", i);
1256 fprintf (outfile, "Public Key Info:\n");
1258 if (i == -1)
1259 ret = gnutls_openpgp_privkey_get_pk_algorithm (key, NULL);
1260 else
1261 ret = gnutls_openpgp_privkey_get_subkey_pk_algorithm (key, i, NULL);
1263 fprintf (outfile, "\tPublic Key Algorithm: ");
1264 cprint = gnutls_pk_algorithm_get_name (ret);
1265 fprintf (outfile, "%s\n", cprint ? cprint : "Unknown");
1266 fprintf (outfile, "\tKey Security Level: %s\n",
1267 gnutls_sec_param_get_name (gnutls_openpgp_privkey_sec_param
1268 (key)));
1270 /* Print the raw public and private keys
1273 if (ret == GNUTLS_PK_RSA)
1275 gnutls_datum_t m, e, d, p, q, u;
1277 if (i == -1)
1278 ret =
1279 gnutls_openpgp_privkey_export_rsa_raw (key, &m, &e, &d, &p,
1280 &q, &u);
1281 else
1282 ret =
1283 gnutls_openpgp_privkey_export_subkey_rsa_raw (key, i, &m,
1284 &e, &d, &p,
1285 &q, &u);
1286 if (ret < 0)
1287 fprintf (stderr, "Error in key RSA data export: %s\n",
1288 gnutls_strerror (ret));
1289 else
1290 print_rsa_pkey (outfile, &m, &e, &d, &p, &q, &u, NULL, NULL);
1292 bits = m.size * 8;
1294 else if (ret == GNUTLS_PK_DSA)
1296 gnutls_datum_t p, q, g, y, x;
1298 if (i == -1)
1299 ret =
1300 gnutls_openpgp_privkey_export_dsa_raw (key, &p, &q, &g, &y, &x);
1301 else
1302 ret =
1303 gnutls_openpgp_privkey_export_subkey_dsa_raw (key, i, &p,
1304 &q, &g, &y, &x);
1305 if (ret < 0)
1306 fprintf (stderr, "Error in key DSA data export: %s\n",
1307 gnutls_strerror (ret));
1308 else
1309 print_dsa_pkey (outfile, &x, &y, &p, &q, &g);
1311 bits = y.size * 8;
1314 fprintf (outfile, "\n");
1316 size = buffer_size;
1317 if (i == -1)
1318 ret = gnutls_openpgp_privkey_get_key_id (key, keyid);
1319 else
1320 ret = gnutls_openpgp_privkey_get_subkey_id (key, i, keyid);
1322 if (ret < 0)
1324 fprintf (stderr, "Error in key id calculation: %s\n",
1325 gnutls_strerror (ret));
1327 else
1329 fprintf (outfile, "Public key ID: %s\n", raw_to_string (keyid, 8));
1332 size = buffer_size;
1333 if (i == -1)
1334 ret = gnutls_openpgp_privkey_get_fingerprint (key, buffer, &size);
1335 else
1336 ret = gnutls_openpgp_privkey_get_subkey_fingerprint (key, i, buffer, &size);
1338 if (ret < 0)
1340 fprintf (stderr, "Error in fingerprint calculation: %s\n",
1341 gnutls_strerror (ret));
1343 else
1345 gnutls_datum_t art;
1347 fprintf (outfile, "Fingerprint: %s\n", raw_to_string (buffer, size));
1349 ret = gnutls_random_art(GNUTLS_RANDOM_ART_OPENSSH, cprint, bits, buffer, size, &art);
1350 if (ret >= 0)
1352 fprintf (outfile, "Fingerprint's random art:\n%s\n\n", art.data);
1353 gnutls_free(art.data);
1358 size = buffer_size;
1359 ret = gnutls_openpgp_privkey_export (key, GNUTLS_OPENPGP_FMT_BASE64,
1360 NULL, 0, buffer, &size);
1361 if (ret < 0)
1362 error (EXIT_FAILURE, 0, "export error: %s", gnutls_strerror (ret));
1364 fprintf (outfile, "\n%s\n", buffer);
1366 gnutls_openpgp_privkey_deinit (key);
1369 void
1370 pgp_ring_info (void)
1372 gnutls_openpgp_keyring_t ring;
1373 gnutls_openpgp_crt_t crt;
1374 size_t size;
1375 int ret, i, count;
1376 gnutls_datum_t pem;
1378 pem.data = (void*)fread_file (infile, &size);
1379 pem.size = size;
1381 ret = gnutls_openpgp_keyring_init (&ring);
1382 if (ret < 0)
1383 error (EXIT_FAILURE, 0, "openpgp_keyring_init: %s",
1384 gnutls_strerror (ret));
1386 ret = gnutls_openpgp_keyring_import (ring, &pem, incert_format);
1388 if (ret < 0)
1389 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (ret));
1391 free (pem.data);
1393 count = gnutls_openpgp_keyring_get_crt_count (ring);
1394 if (count >= 0)
1395 fprintf (outfile, "Keyring contains %d OpenPGP certificates\n\n", count);
1396 else
1397 error (EXIT_FAILURE, 0, "keyring error: %s", gnutls_strerror (count));
1399 for (i = 0; i < count; i++)
1401 ret = gnutls_openpgp_keyring_get_crt (ring, i, &crt);
1402 if (ret < 0)
1403 error (EXIT_FAILURE, 0, "export error: %s", gnutls_strerror (ret));
1405 size = buffer_size;
1406 ret = gnutls_openpgp_crt_export (crt, outcert_format,
1407 buffer, &size);
1408 if (ret < 0)
1409 error (EXIT_FAILURE, 0, "export error: %s", gnutls_strerror (ret));
1411 fwrite (buffer, 1, size, outfile);
1412 fprintf (outfile, "\n\n");
1414 gnutls_openpgp_crt_deinit (crt);
1419 gnutls_openpgp_keyring_deinit (ring);
1423 #endif
1427 static void
1428 print_certificate_info (gnutls_x509_crt_t crt, FILE * out, unsigned int all)
1430 gnutls_datum_t data;
1431 int ret;
1433 if (all)
1434 ret = gnutls_x509_crt_print (crt, GNUTLS_CRT_PRINT_FULL, &data);
1435 else
1436 ret = gnutls_x509_crt_print (crt, GNUTLS_CRT_PRINT_UNSIGNED_FULL, &data);
1437 if (ret == 0)
1439 fprintf (out, "%s\n", data.data);
1440 gnutls_free (data.data);
1443 if (out == stderr && batch == 0) /* interactive */
1444 if (read_yesno ("Is the above information ok? (y/N): ") == 0)
1446 exit (1);
1450 static void
1451 print_crl_info (gnutls_x509_crl_t crl, FILE * out)
1453 gnutls_datum_t data;
1454 int ret;
1455 size_t size;
1457 ret = gnutls_x509_crl_print (crl, GNUTLS_CRT_PRINT_FULL, &data);
1458 if (ret < 0)
1459 error (EXIT_FAILURE, 0, "crl_print: %s", gnutls_strerror (ret));
1461 fprintf (out, "%s\n", data.data);
1463 gnutls_free (data.data);
1465 size = buffer_size;
1466 ret = gnutls_x509_crl_export (crl, GNUTLS_X509_FMT_PEM, buffer, &size);
1467 if (ret < 0)
1468 error (EXIT_FAILURE, 0, "crl_export: %s", gnutls_strerror (ret));
1470 fwrite (buffer, 1, size, outfile);
1473 void
1474 crl_info (void)
1476 gnutls_x509_crl_t crl;
1477 int ret;
1478 size_t size;
1479 gnutls_datum_t pem;
1481 ret = gnutls_x509_crl_init (&crl);
1482 if (ret < 0)
1483 error (EXIT_FAILURE, 0, "crl_init: %s", gnutls_strerror (ret));
1485 pem.data = (void*)fread_file (infile, &size);
1486 pem.size = size;
1488 if (!pem.data)
1489 error (EXIT_FAILURE, errno, "%s", infile ? "file" :
1490 "standard input");
1492 ret = gnutls_x509_crl_import (crl, &pem, incert_format);
1494 free (pem.data);
1495 if (ret < 0)
1496 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (ret));
1498 print_crl_info (crl, outfile);
1500 gnutls_x509_crl_deinit (crl);
1503 static void
1504 print_crq_info (gnutls_x509_crq_t crq, FILE * out)
1506 gnutls_datum_t data;
1507 int ret;
1508 size_t size;
1510 if (outcert_format == GNUTLS_X509_FMT_PEM)
1512 ret = gnutls_x509_crq_print (crq, GNUTLS_CRT_PRINT_FULL, &data);
1513 if (ret < 0)
1514 error (EXIT_FAILURE, 0, "crq_print: %s", gnutls_strerror (ret));
1516 fprintf (out, "%s\n", data.data);
1518 gnutls_free (data.data);
1521 ret = gnutls_x509_crq_verify(crq, 0);
1522 if (ret < 0)
1524 fprintf(out, "Self signature: FAILED\n\n");
1526 else
1528 fprintf(out, "Self signature: verified\n\n");
1531 size = buffer_size;
1532 ret = gnutls_x509_crq_export (crq, outcert_format, buffer, &size);
1533 if (ret < 0)
1534 error (EXIT_FAILURE, 0, "crq_export: %s", gnutls_strerror (ret));
1536 fwrite (buffer, 1, size, outfile);
1539 void
1540 crq_info (void)
1542 gnutls_x509_crq_t crq;
1543 int ret;
1544 size_t size;
1545 gnutls_datum_t pem;
1547 ret = gnutls_x509_crq_init (&crq);
1548 if (ret < 0)
1549 error (EXIT_FAILURE, 0, "crq_init: %s", gnutls_strerror (ret));
1551 pem.data = (void*)fread_file (infile, &size);
1552 pem.size = size;
1554 if (!pem.data)
1555 error (EXIT_FAILURE, errno, "%s", infile ? "file" :
1556 "standard input");
1558 ret = gnutls_x509_crq_import (crq, &pem, incert_format);
1560 free (pem.data);
1561 if (ret < 0)
1562 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (ret));
1564 print_crq_info (crq, outfile);
1566 gnutls_x509_crq_deinit (crq);
1569 static void privkey_info_int (common_info_st* cinfo, gnutls_x509_privkey_t key)
1571 int ret, key_type;
1572 unsigned int bits = 0;
1573 size_t size;
1574 const char *cprint;
1576 /* Public key algorithm
1578 fprintf (outfile, "Public Key Info:\n");
1579 ret = gnutls_x509_privkey_get_pk_algorithm2 (key, &bits);
1580 fprintf (outfile, "\tPublic Key Algorithm: ");
1582 key_type = ret;
1584 cprint = gnutls_pk_algorithm_get_name (key_type);
1585 fprintf (outfile, "%s\n", cprint ? cprint : "Unknown");
1586 fprintf (outfile, "\tKey Security Level: %s (%u bits)\n\n",
1587 gnutls_sec_param_get_name (gnutls_x509_privkey_sec_param (key)), bits);
1589 /* Print the raw public and private keys
1591 if (key_type == GNUTLS_PK_RSA)
1593 gnutls_datum_t m, e, d, p, q, u, exp1, exp2;
1595 ret =
1596 gnutls_x509_privkey_export_rsa_raw2 (key, &m, &e, &d, &p, &q, &u,
1597 &exp1, &exp2);
1598 if (ret < 0)
1599 fprintf (stderr, "Error in key RSA data export: %s\n",
1600 gnutls_strerror (ret));
1601 else
1603 print_rsa_pkey (outfile, &m, &e, &d, &p, &q, &u, &exp1, &exp2);
1605 gnutls_free (m.data);
1606 gnutls_free (e.data);
1607 gnutls_free (d.data);
1608 gnutls_free (p.data);
1609 gnutls_free (q.data);
1610 gnutls_free (u.data);
1611 gnutls_free (exp1.data);
1612 gnutls_free (exp2.data);
1615 else if (key_type == GNUTLS_PK_DSA)
1617 gnutls_datum_t p, q, g, y, x;
1619 ret = gnutls_x509_privkey_export_dsa_raw (key, &p, &q, &g, &y, &x);
1620 if (ret < 0)
1621 fprintf (stderr, "Error in key DSA data export: %s\n",
1622 gnutls_strerror (ret));
1623 else
1625 print_dsa_pkey (outfile, &x, &y, &p, &q, &g);
1627 gnutls_free (x.data);
1628 gnutls_free (y.data);
1629 gnutls_free (p.data);
1630 gnutls_free (q.data);
1631 gnutls_free (g.data);
1634 else if (key_type == GNUTLS_PK_EC)
1636 gnutls_datum_t y, x, k;
1637 gnutls_ecc_curve_t curve;
1639 ret = gnutls_x509_privkey_export_ecc_raw (key, &curve, &x, &y, &k);
1640 if (ret < 0)
1641 fprintf (stderr, "Error in key ECC data export: %s\n",
1642 gnutls_strerror (ret));
1643 else
1645 print_ecc_pkey (outfile, curve, &k, &x, &y);
1647 gnutls_free (x.data);
1648 gnutls_free (y.data);
1649 gnutls_free (k.data);
1653 fprintf (outfile, "\n");
1655 size = buffer_size;
1656 if ((ret = gnutls_x509_privkey_get_key_id (key, 0, buffer, &size)) < 0)
1658 fprintf (stderr, "Error in key id calculation: %s\n",
1659 gnutls_strerror (ret));
1661 else
1663 gnutls_datum_t art;
1665 fprintf (outfile, "Public Key ID: %s\n", raw_to_string (buffer, size));
1667 ret = gnutls_random_art(GNUTLS_RANDOM_ART_OPENSSH, cprint, bits, buffer, size, &art);
1668 if (ret >= 0)
1670 fprintf (outfile, "Public key's random art:\n%s\n", art.data);
1671 gnutls_free(art.data);
1674 fprintf (outfile, "\n");
1678 void
1679 privkey_info (common_info_st* cinfo)
1681 gnutls_x509_privkey_t key;
1682 size_t size;
1683 int ret;
1684 gnutls_datum_t pem;
1685 const char *pass;
1686 unsigned int flags = 0;
1688 size = fread (buffer, 1, buffer_size - 1, infile);
1689 buffer[size] = 0;
1691 gnutls_x509_privkey_init (&key);
1693 pem.data = buffer;
1694 pem.size = size;
1696 ret = gnutls_x509_privkey_import2 (key, &pem, incert_format, NULL, 0);
1698 /* If we failed to import the certificate previously try PKCS #8 */
1699 if (ret == GNUTLS_E_DECRYPTION_FAILED)
1701 fprintf(stderr, "Encrypted structure detected...\n");
1702 pass = get_password(cinfo, &flags, 0);
1704 ret = gnutls_x509_privkey_import2 (key, &pem,
1705 incert_format, pass, flags);
1707 if (ret < 0)
1708 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (ret));
1710 if (outcert_format == GNUTLS_X509_FMT_PEM)
1711 privkey_info_int (cinfo, key);
1713 ret = gnutls_x509_privkey_verify_params (key);
1714 if (ret < 0)
1715 fprintf (outfile, "\n** Private key parameters validation failed **\n\n");
1717 size = buffer_size;
1718 ret = gnutls_x509_privkey_export (key, outcert_format, buffer, &size);
1719 if (ret < 0)
1720 error (EXIT_FAILURE, 0, "export error: %s", gnutls_strerror (ret));
1722 fwrite (buffer, 1, size, outfile);
1724 gnutls_x509_privkey_deinit (key);
1728 /* Generate a PKCS #10 certificate request.
1730 void
1731 generate_request (common_info_st * cinfo)
1733 gnutls_x509_crq_t crq;
1734 gnutls_x509_privkey_t xkey;
1735 gnutls_pubkey_t pubkey;
1736 gnutls_privkey_t pkey;
1737 int ret, ca_status, path_len, pk;
1738 const char *pass;
1739 unsigned int usage = 0;
1741 fprintf (stderr, "Generating a PKCS #10 certificate request...\n");
1743 ret = gnutls_x509_crq_init (&crq);
1744 if (ret < 0)
1745 error (EXIT_FAILURE, 0, "crq_init: %s", gnutls_strerror (ret));
1748 /* Load the private key.
1750 pkey = load_private_key (0, cinfo);
1751 if (!pkey)
1753 ret = gnutls_privkey_init (&pkey);
1754 if (ret < 0)
1755 error (EXIT_FAILURE, 0, "privkey_init: %s", gnutls_strerror (ret));
1757 xkey = generate_private_key_int (cinfo);
1759 print_private_key (cinfo, xkey);
1761 ret = gnutls_privkey_import_x509(pkey, xkey, GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
1762 if (ret < 0)
1763 error (EXIT_FAILURE, 0, "privkey_import_x509: %s", gnutls_strerror (ret));
1766 pubkey = load_public_key_or_import (1, pkey, cinfo);
1768 pk = gnutls_pubkey_get_pk_algorithm (pubkey, NULL);
1770 /* Set the DN.
1772 get_country_crq_set (crq);
1773 get_organization_crq_set (crq);
1774 get_unit_crq_set (crq);
1775 get_locality_crq_set (crq);
1776 get_state_crq_set (crq);
1777 get_cn_crq_set (crq);
1778 get_dc_set (TYPE_CRQ, crq);
1779 get_uid_crq_set (crq);
1780 get_oid_crq_set (crq);
1782 get_dns_name_set (TYPE_CRQ, crq);
1783 get_uri_set (TYPE_CRQ, crq);
1784 get_ip_addr_set (TYPE_CRQ, crq);
1785 get_email_set (TYPE_CRQ, crq);
1787 pass = get_challenge_pass ();
1789 if (pass != NULL && pass[0] != 0)
1791 ret = gnutls_x509_crq_set_challenge_password (crq, pass);
1792 if (ret < 0)
1793 error (EXIT_FAILURE, 0, "set_pass: %s", gnutls_strerror (ret));
1796 if (cinfo->crq_extensions != 0)
1798 ca_status = get_ca_status ();
1799 if (ca_status)
1800 path_len = get_path_len ();
1801 else
1802 path_len = -1;
1804 ret = gnutls_x509_crq_set_basic_constraints (crq, ca_status, path_len);
1805 if (ret < 0)
1806 error (EXIT_FAILURE, 0, "set_basic_constraints: %s",
1807 gnutls_strerror (ret));
1809 if (pk == GNUTLS_PK_RSA)
1811 ret = get_sign_status (1);
1812 if (ret)
1813 usage |= GNUTLS_KEY_DIGITAL_SIGNATURE;
1815 /* Only ask for an encryption certificate
1816 * if it is an RSA one */
1817 ret = get_encrypt_status (1);
1818 if (ret)
1819 usage |= GNUTLS_KEY_KEY_ENCIPHERMENT;
1820 else
1821 usage |= GNUTLS_KEY_DIGITAL_SIGNATURE;
1823 else /* DSA and ECDSA are always signing */
1824 usage |= GNUTLS_KEY_DIGITAL_SIGNATURE;
1826 if (ca_status)
1828 ret = get_cert_sign_status ();
1829 if (ret)
1830 usage |= GNUTLS_KEY_KEY_CERT_SIGN;
1832 ret = get_crl_sign_status ();
1833 if (ret)
1834 usage |= GNUTLS_KEY_CRL_SIGN;
1836 ret = get_code_sign_status ();
1837 if (ret)
1839 ret = gnutls_x509_crq_set_key_purpose_oid
1840 (crq, GNUTLS_KP_CODE_SIGNING, 0);
1841 if (ret < 0)
1842 error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (ret));
1845 ret = get_ocsp_sign_status ();
1846 if (ret)
1848 ret = gnutls_x509_crq_set_key_purpose_oid
1849 (crq, GNUTLS_KP_OCSP_SIGNING, 0);
1850 if (ret < 0)
1851 error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (ret));
1854 ret = get_time_stamp_status ();
1855 if (ret)
1857 ret = gnutls_x509_crq_set_key_purpose_oid
1858 (crq, GNUTLS_KP_TIME_STAMPING, 0);
1859 if (ret < 0)
1860 error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (ret));
1863 ret = get_ipsec_ike_status ();
1864 if (ret)
1866 ret = gnutls_x509_crq_set_key_purpose_oid
1867 (crq, GNUTLS_KP_IPSEC_IKE, 0);
1868 if (ret < 0)
1869 error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (ret));
1873 ret = gnutls_x509_crq_set_key_usage (crq, usage);
1874 if (ret < 0)
1875 error (EXIT_FAILURE, 0, "key_usage: %s", gnutls_strerror (ret));
1877 ret = get_tls_client_status ();
1878 if (ret != 0)
1880 ret = gnutls_x509_crq_set_key_purpose_oid
1881 (crq, GNUTLS_KP_TLS_WWW_CLIENT, 0);
1882 if (ret < 0)
1883 error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (ret));
1886 ret = get_tls_server_status ();
1887 if (ret != 0)
1889 ret = gnutls_x509_crq_set_key_purpose_oid
1890 (crq, GNUTLS_KP_TLS_WWW_SERVER, 0);
1891 if (ret < 0)
1892 error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (ret));
1896 ret = gnutls_x509_crq_set_pubkey (crq, pubkey);
1897 if (ret < 0)
1898 error (EXIT_FAILURE, 0, "set_key: %s", gnutls_strerror (ret));
1900 ret = gnutls_x509_crq_privkey_sign (crq, pkey, get_dig_for_pub (pubkey), 0);
1901 if (ret < 0)
1902 error (EXIT_FAILURE, 0, "sign: %s", gnutls_strerror (ret));
1904 print_crq_info (crq, outfile);
1906 gnutls_x509_crq_deinit (crq);
1907 gnutls_privkey_deinit( pkey);
1908 gnutls_pubkey_deinit( pubkey);
1912 static void print_verification_res (FILE* outfile, unsigned int output);
1914 static int detailed_verification(gnutls_x509_crt_t cert,
1915 gnutls_x509_crt_t issuer, gnutls_x509_crl_t crl,
1916 unsigned int verification_output)
1918 char name[512];
1919 char tmp[255];
1920 char issuer_name[512];
1921 size_t name_size;
1922 size_t issuer_name_size;
1923 int ret;
1925 issuer_name_size = sizeof (issuer_name);
1926 ret =
1927 gnutls_x509_crt_get_issuer_dn (cert, issuer_name, &issuer_name_size);
1928 if (ret < 0)
1929 error (EXIT_FAILURE, 0, "gnutls_x509_crt_get_issuer_dn: %s", gnutls_strerror (ret));
1931 name_size = sizeof (name);
1932 ret =
1933 gnutls_x509_crt_get_dn (cert, name, &name_size);
1934 if (ret < 0)
1935 error (EXIT_FAILURE, 0, "gnutls_x509_crt_get_dn: %s", gnutls_strerror (ret));
1937 fprintf (outfile, "\tSubject: %s\n", name);
1938 fprintf (outfile, "\tIssuer: %s\n", issuer_name);
1940 if (issuer != NULL)
1942 issuer_name_size = sizeof (issuer_name);
1943 ret =
1944 gnutls_x509_crt_get_dn (issuer, issuer_name, &issuer_name_size);
1945 if (ret < 0)
1946 error (EXIT_FAILURE, 0, "gnutls_x509_crt_get_issuer_dn: %s", gnutls_strerror (ret));
1948 fprintf (outfile, "\tChecked against: %s\n", issuer_name);
1951 if (crl != NULL)
1953 gnutls_datum_t data;
1955 issuer_name_size = sizeof (issuer_name);
1956 ret =
1957 gnutls_x509_crl_get_issuer_dn (crl, issuer_name, &issuer_name_size);
1958 if (ret < 0)
1959 error (EXIT_FAILURE, 0, "gnutls_x509_crl_get_issuer_dn: %s", gnutls_strerror (ret));
1961 name_size = sizeof(tmp);
1962 ret = gnutls_x509_crl_get_number(crl, tmp, &name_size, NULL);
1963 if (ret < 0)
1964 strcpy(name, "unnumbered");
1965 else
1967 data.data = (void*)tmp;
1968 data.size = name_size;
1970 name_size = sizeof(name);
1971 ret = gnutls_hex_encode(&data, name, &name_size);
1972 if (ret < 0)
1973 error (EXIT_FAILURE, 0, "gnutls_hex_encode: %s", gnutls_strerror (ret));
1975 fprintf (outfile, "\tChecked against CRL[%s] of: %s\n", name, issuer_name);
1978 fprintf (outfile, "\tOutput: ");
1979 print_verification_res(outfile, verification_output);
1981 fputs(".\n\n", outfile);
1983 return 0;
1986 /* Will verify a certificate chain. If no CA certificates
1987 * are provided, then the last certificate in the certificate
1988 * chain is used as a CA.
1990 static int
1991 _verify_x509_mem (const void *cert, int cert_size, const void* ca, int ca_size)
1993 int ret;
1994 gnutls_datum_t tmp;
1995 gnutls_x509_crt_t *x509_cert_list = NULL;
1996 gnutls_x509_crt_t *x509_ca_list = NULL;
1997 gnutls_x509_crl_t *x509_crl_list = NULL;
1998 unsigned int x509_ncerts, x509_ncrls = 0, x509_ncas = 0;
1999 gnutls_x509_trust_list_t list;
2000 unsigned int output;
2002 ret = gnutls_x509_trust_list_init(&list, 0);
2003 if (ret < 0)
2004 error (EXIT_FAILURE, 0, "gnutls_x509_trust_list_init: %s",
2005 gnutls_strerror (ret));
2007 if (ca == NULL)
2009 tmp.data = (void*)cert;
2010 tmp.size = cert_size;
2012 else
2014 tmp.data = (void*)ca;
2015 tmp.size = ca_size;
2017 /* Load CAs */
2018 ret = gnutls_x509_crt_list_import2( &x509_ca_list, &x509_ncas, &tmp,
2019 GNUTLS_X509_FMT_PEM, 0);
2020 if (ret < 0 || x509_ncas < 1)
2021 error (EXIT_FAILURE, 0, "error parsing CAs: %s",
2022 gnutls_strerror (ret));
2025 ret = gnutls_x509_crl_list_import2( &x509_crl_list, &x509_ncrls, &tmp,
2026 GNUTLS_X509_FMT_PEM, 0);
2027 if (ret < 0)
2029 x509_crl_list = NULL;
2030 x509_ncrls = 0;
2033 tmp.data = (void*)cert;
2034 tmp.size = cert_size;
2036 /* ignore errors. CRLs might not be given */
2037 ret = gnutls_x509_crt_list_import2( &x509_cert_list, &x509_ncerts, &tmp,
2038 GNUTLS_X509_FMT_PEM, 0);
2039 if (ret < 0 || x509_ncerts < 1)
2040 error (EXIT_FAILURE, 0, "error parsing CRTs: %s",
2041 gnutls_strerror (ret));
2043 if (ca == NULL)
2045 x509_ca_list = &x509_cert_list[x509_ncerts - 1];
2046 x509_ncas = 1;
2049 fprintf(stdout, "Loaded %d certificates, %d CAs and %d CRLs\n\n",
2050 x509_ncerts, x509_ncas, x509_ncrls);
2052 ret = gnutls_x509_trust_list_add_cas(list, x509_ca_list, x509_ncas, 0);
2053 if (ret < 0)
2054 error (EXIT_FAILURE, 0, "gnutls_x509_trust_add_cas: %s",
2055 gnutls_strerror (ret));
2057 ret = gnutls_x509_trust_list_add_crls(list, x509_crl_list, x509_ncrls, 0, 0);
2058 if (ret < 0)
2059 error (EXIT_FAILURE, 0, "gnutls_x509_trust_add_crls: %s",
2060 gnutls_strerror (ret));
2062 gnutls_free(x509_crl_list);
2064 ret = gnutls_x509_trust_list_verify_crt (list, x509_cert_list, x509_ncerts,
2065 GNUTLS_VERIFY_DO_NOT_ALLOW_SAME|GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT, &output,
2066 detailed_verification);
2067 if (ret < 0)
2068 error (EXIT_FAILURE, 0, "gnutls_x509_trusted_list_verify_crt: %s",
2069 gnutls_strerror (ret));
2071 fprintf (outfile, "Chain verification output: ");
2072 print_verification_res(outfile, output);
2074 fprintf (outfile, ".\n\n");
2076 gnutls_free(x509_cert_list);
2077 gnutls_x509_trust_list_deinit(list, 1);
2079 if (output != 0)
2080 exit(EXIT_FAILURE);
2082 return 0;
2085 static void
2086 print_verification_res (FILE* outfile, unsigned int output)
2088 int comma = 0;
2090 if (output & GNUTLS_CERT_INVALID)
2092 fprintf (outfile, "Not verified");
2093 comma = 1;
2095 else
2097 fprintf (outfile, "Verified");
2098 comma = 1;
2101 if (output & GNUTLS_CERT_SIGNER_NOT_CA)
2103 if (comma)
2104 fprintf (outfile, ", ");
2105 fprintf (outfile, "Issuer is not a CA");
2106 comma = 1;
2109 if (output & GNUTLS_CERT_INSECURE_ALGORITHM)
2111 if (comma)
2112 fprintf (outfile, ", ");
2113 fprintf (outfile, "Insecure algorithm");
2114 comma = 1;
2117 if (output & GNUTLS_CERT_NOT_ACTIVATED)
2119 if (comma)
2120 fprintf (outfile, ", ");
2121 fprintf (outfile, "Not activated");
2122 comma = 1;
2125 if (output & GNUTLS_CERT_EXPIRED)
2127 if (comma)
2128 fprintf (outfile, ", ");
2129 fprintf (outfile, "Expired");
2130 comma = 1;
2133 if (output & GNUTLS_CERT_REVOKED)
2135 if (comma)
2136 fprintf (outfile, ", ");
2137 fprintf (outfile, "Revoked");
2138 comma = 1;
2142 static void
2143 verify_chain (void)
2145 char *buf;
2146 size_t size;
2148 buf = (void*)fread_file (infile, &size);
2149 if (buf == NULL)
2150 error (EXIT_FAILURE, errno, "reading chain");
2152 buf[size] = 0;
2154 _verify_x509_mem (buf, size, NULL, 0);
2158 static void
2159 verify_certificate (common_info_st * cinfo)
2161 char *cert;
2162 char *cas;
2163 size_t cert_size, ca_size;
2164 FILE * ca_file = fopen(cinfo->ca, "r");
2166 if (ca_file == NULL)
2167 error (EXIT_FAILURE, errno, "opening CA file");
2169 cert = (void*)fread_file (infile, &cert_size);
2170 if (cert == NULL)
2171 error (EXIT_FAILURE, errno, "reading certificate chain");
2173 cert[cert_size] = 0;
2175 cas = (void*)fread_file (ca_file, &ca_size);
2176 if (cas == NULL)
2177 error (EXIT_FAILURE, errno, "reading CA list");
2179 cas[ca_size] = 0;
2180 fclose(ca_file);
2182 _verify_x509_mem (cert, cert_size, cas, ca_size);
2187 void
2188 verify_crl (common_info_st * cinfo)
2190 size_t size, dn_size;
2191 char dn[128];
2192 unsigned int output;
2193 int comma = 0;
2194 int ret;
2195 gnutls_datum_t pem;
2196 gnutls_x509_crl_t crl;
2197 time_t now = time (0);
2198 gnutls_x509_crt_t issuer;
2200 issuer = load_ca_cert (cinfo);
2202 fprintf (outfile, "\nCA certificate:\n");
2204 dn_size = sizeof (dn);
2205 ret = gnutls_x509_crt_get_dn (issuer, dn, &dn_size);
2206 if (ret < 0)
2207 error (EXIT_FAILURE, 0, "crt_get_dn: %s", gnutls_strerror (ret));
2209 fprintf (outfile, "\tSubject: %s\n\n", dn);
2211 ret = gnutls_x509_crl_init (&crl);
2212 if (ret < 0)
2213 error (EXIT_FAILURE, 0, "crl_init: %s", gnutls_strerror (ret));
2215 pem.data = (void*)fread_file (infile, &size);
2216 pem.size = size;
2218 ret = gnutls_x509_crl_import (crl, &pem, incert_format);
2219 free (pem.data);
2220 if (ret < 0)
2221 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (ret));
2223 print_crl_info (crl, outfile);
2225 fprintf (outfile, "Verification output: ");
2226 ret = gnutls_x509_crl_verify (crl, &issuer, 1, 0, &output);
2227 if (ret < 0)
2228 error (EXIT_FAILURE, 0, "verification error: %s", gnutls_strerror (ret));
2230 if (output & GNUTLS_CERT_INVALID)
2232 fprintf (outfile, "Not verified");
2233 comma = 1;
2235 else
2237 fprintf (outfile, "Verified");
2238 comma = 1;
2241 if (output & GNUTLS_CERT_SIGNER_NOT_CA)
2243 if (comma)
2244 fprintf (outfile, ", ");
2245 fprintf (outfile, "Issuer is not a CA");
2246 comma = 1;
2249 if (output & GNUTLS_CERT_INSECURE_ALGORITHM)
2251 if (comma)
2252 fprintf (outfile, ", ");
2253 fprintf (outfile, "Insecure algorithm");
2254 comma = 1;
2257 /* Check expiration dates.
2260 if (gnutls_x509_crl_get_this_update (crl) > now)
2262 if (comma)
2263 fprintf (outfile, ", ");
2264 comma = 1;
2265 fprintf (outfile, "Issued in the future!");
2268 if (gnutls_x509_crl_get_next_update (crl) < now)
2270 if (comma)
2271 fprintf (outfile, ", ");
2272 comma = 1;
2273 fprintf (outfile, "CRL is not up to date");
2276 fprintf (outfile, "\n");
2281 void
2282 generate_pkcs8 (common_info_st * cinfo)
2284 gnutls_x509_privkey_t key;
2285 int result;
2286 size_t size;
2287 unsigned int flags = 0;
2288 const char *password;
2290 fprintf (stderr, "Generating a PKCS #8 key structure...\n");
2292 key = load_x509_private_key (1, cinfo);
2294 password = get_password(cinfo, &flags, 1);
2296 flags |= cipher_to_flags (cinfo->pkcs_cipher);
2298 size = buffer_size;
2299 result =
2300 gnutls_x509_privkey_export_pkcs8 (key, outcert_format,
2301 password, flags, buffer, &size);
2303 if (result < 0)
2304 error (EXIT_FAILURE, 0, "key_export: %s", gnutls_strerror (result));
2306 fwrite (buffer, 1, size, outfile);
2311 #include <gnutls/pkcs12.h>
2312 #include <unistd.h>
2314 void
2315 generate_pkcs12 (common_info_st * cinfo)
2317 gnutls_pkcs12_t pkcs12;
2318 gnutls_x509_crt_t *crts;
2319 gnutls_x509_privkey_t *keys;
2320 int result;
2321 size_t size;
2322 gnutls_datum_t data;
2323 const char *pass;
2324 const char *name;
2325 unsigned int flags = 0, i;
2326 gnutls_datum_t key_id;
2327 unsigned char _key_id[32];
2328 int indx;
2329 size_t ncrts;
2330 size_t nkeys;
2332 fprintf (stderr, "Generating a PKCS #12 structure...\n");
2334 keys = load_privkey_list (0, &nkeys, cinfo);
2335 crts = load_cert_list (0, &ncrts, cinfo);
2337 name = get_pkcs12_key_name ();
2339 result = gnutls_pkcs12_init (&pkcs12);
2340 if (result < 0)
2341 error (EXIT_FAILURE, 0, "pkcs12_init: %s", gnutls_strerror (result));
2343 pass = get_password(cinfo, &flags, 1);
2344 flags |= cipher_to_flags (cinfo->pkcs_cipher);
2346 for (i = 0; i < ncrts; i++)
2348 gnutls_pkcs12_bag_t bag;
2350 result = gnutls_pkcs12_bag_init (&bag);
2351 if (result < 0)
2352 error (EXIT_FAILURE, 0, "bag_init: %s", gnutls_strerror (result));
2354 result = gnutls_pkcs12_bag_set_crt (bag, crts[i]);
2355 if (result < 0)
2356 error (EXIT_FAILURE, 0, "set_crt[%d]: %s", i,
2357 gnutls_strerror (result));
2359 indx = result;
2361 if (i==0) /* only the first certificate gets the friendly name */
2363 result = gnutls_pkcs12_bag_set_friendly_name (bag, indx, name);
2364 if (result < 0)
2365 error (EXIT_FAILURE, 0, "bag_set_friendly_name: %s",
2366 gnutls_strerror (result));
2369 size = sizeof (_key_id);
2370 result = gnutls_x509_crt_get_key_id (crts[i], 0, _key_id, &size);
2371 if (result < 0)
2372 error (EXIT_FAILURE, 0, "key_id[%d]: %s", i,
2373 gnutls_strerror (result));
2375 key_id.data = _key_id;
2376 key_id.size = size;
2378 result = gnutls_pkcs12_bag_set_key_id (bag, indx, &key_id);
2379 if (result < 0)
2380 error (EXIT_FAILURE, 0, "bag_set_key_id: %s",
2381 gnutls_strerror (result));
2383 result = gnutls_pkcs12_bag_encrypt (bag, pass, flags);
2384 if (result < 0)
2385 error (EXIT_FAILURE, 0, "bag_encrypt: %s", gnutls_strerror (result));
2387 result = gnutls_pkcs12_set_bag (pkcs12, bag);
2388 if (result < 0)
2389 error (EXIT_FAILURE, 0, "set_bag: %s", gnutls_strerror (result));
2392 for (i = 0; i < nkeys; i++)
2394 gnutls_pkcs12_bag_t kbag;
2396 result = gnutls_pkcs12_bag_init (&kbag);
2397 if (result < 0)
2398 error (EXIT_FAILURE, 0, "bag_init: %s", gnutls_strerror (result));
2400 size = buffer_size;
2401 result =
2402 gnutls_x509_privkey_export_pkcs8 (keys[i], GNUTLS_X509_FMT_DER,
2403 pass, flags, buffer, &size);
2404 if (result < 0)
2405 error (EXIT_FAILURE, 0, "key_export[%d]: %s", i, gnutls_strerror (result));
2407 data.data = buffer;
2408 data.size = size;
2409 result =
2410 gnutls_pkcs12_bag_set_data (kbag,
2411 GNUTLS_BAG_PKCS8_ENCRYPTED_KEY, &data);
2412 if (result < 0)
2413 error (EXIT_FAILURE, 0, "bag_set_data: %s", gnutls_strerror (result));
2415 indx = result;
2417 result = gnutls_pkcs12_bag_set_friendly_name (kbag, indx, name);
2418 if (result < 0)
2419 error (EXIT_FAILURE, 0, "bag_set_friendly_name: %s",
2420 gnutls_strerror (result));
2422 size = sizeof (_key_id);
2423 result = gnutls_x509_privkey_get_key_id (keys[i], 0, _key_id, &size);
2424 if (result < 0)
2425 error (EXIT_FAILURE, 0, "key_id[%d]: %s", i, gnutls_strerror (result));
2427 key_id.data = _key_id;
2428 key_id.size = size;
2430 result = gnutls_pkcs12_bag_set_key_id (kbag, indx, &key_id);
2431 if (result < 0)
2432 error (EXIT_FAILURE, 0, "bag_set_key_id: %s",
2433 gnutls_strerror (result));
2435 result = gnutls_pkcs12_set_bag (pkcs12, kbag);
2436 if (result < 0)
2437 error (EXIT_FAILURE, 0, "set_bag: %s", gnutls_strerror (result));
2440 result = gnutls_pkcs12_generate_mac (pkcs12, pass);
2441 if (result < 0)
2442 error (EXIT_FAILURE, 0, "generate_mac: %s", gnutls_strerror (result));
2444 size = buffer_size;
2445 result = gnutls_pkcs12_export (pkcs12, outcert_format, buffer, &size);
2446 if (result < 0)
2447 error (EXIT_FAILURE, 0, "pkcs12_export: %s", gnutls_strerror (result));
2449 fwrite (buffer, 1, size, outfile);
2453 static const char *
2454 BAGTYPE (gnutls_pkcs12_bag_type_t x)
2456 switch (x)
2458 case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY:
2459 return "PKCS #8 Encrypted key";
2460 case GNUTLS_BAG_EMPTY:
2461 return "Empty";
2462 case GNUTLS_BAG_PKCS8_KEY:
2463 return "PKCS #8 Key";
2464 case GNUTLS_BAG_CERTIFICATE:
2465 return "Certificate";
2466 case GNUTLS_BAG_ENCRYPTED:
2467 return "Encrypted";
2468 case GNUTLS_BAG_CRL:
2469 return "CRL";
2470 case GNUTLS_BAG_SECRET:
2471 return "Secret";
2472 default:
2473 return "Unknown";
2477 static void
2478 print_bag_data (gnutls_pkcs12_bag_t bag)
2480 int result;
2481 int count, i, type;
2482 gnutls_datum_t cdata, id;
2483 const char *str, *name;
2484 gnutls_datum_t out;
2486 count = gnutls_pkcs12_bag_get_count (bag);
2487 if (count < 0)
2488 error (EXIT_FAILURE, 0, "get_count: %s", gnutls_strerror (count));
2490 fprintf (outfile, "\tElements: %d\n", count);
2492 for (i = 0; i < count; i++)
2494 type = gnutls_pkcs12_bag_get_type (bag, i);
2495 if (type < 0)
2496 error (EXIT_FAILURE, 0, "get_type: %s", gnutls_strerror (type));
2498 fprintf (stderr, "\tType: %s\n", BAGTYPE (type));
2500 name = NULL;
2501 result = gnutls_pkcs12_bag_get_friendly_name (bag, i, (char **) &name);
2502 if (result < 0)
2503 error (EXIT_FAILURE, 0, "get_friendly_name: %s",
2504 gnutls_strerror (type));
2505 if (name)
2506 fprintf (outfile, "\tFriendly name: %s\n", name);
2508 id.data = NULL;
2509 id.size = 0;
2510 result = gnutls_pkcs12_bag_get_key_id (bag, i, &id);
2511 if (result < 0)
2512 error (EXIT_FAILURE, 0, "get_key_id: %s", gnutls_strerror (type));
2513 if (id.size > 0)
2514 fprintf (outfile, "\tKey ID: %s\n", raw_to_string (id.data, id.size));
2516 result = gnutls_pkcs12_bag_get_data (bag, i, &cdata);
2517 if (result < 0)
2518 error (EXIT_FAILURE, 0, "get_data: %s", gnutls_strerror (result));
2520 switch (type)
2522 case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY:
2523 str = "ENCRYPTED PRIVATE KEY";
2524 break;
2525 case GNUTLS_BAG_PKCS8_KEY:
2526 str = "PRIVATE KEY";
2527 break;
2528 case GNUTLS_BAG_CERTIFICATE:
2529 str = "CERTIFICATE";
2530 break;
2531 case GNUTLS_BAG_CRL:
2532 str = "CRL";
2533 break;
2534 case GNUTLS_BAG_ENCRYPTED:
2535 case GNUTLS_BAG_EMPTY:
2536 default:
2537 str = NULL;
2540 if (str != NULL)
2542 gnutls_pem_base64_encode_alloc (str, &cdata, &out);
2543 fprintf (outfile, "%s\n", out.data);
2545 gnutls_free (out.data);
2551 void
2552 pkcs12_info (common_info_st* cinfo)
2554 gnutls_pkcs12_t pkcs12;
2555 gnutls_pkcs12_bag_t bag;
2556 int result;
2557 size_t size;
2558 gnutls_datum_t data;
2559 const char *pass;
2560 int indx, fail = 0;
2562 result = gnutls_pkcs12_init (&pkcs12);
2563 if (result < 0)
2564 error (EXIT_FAILURE, 0, "p12_init: %s", gnutls_strerror (result));
2566 data.data = (void*)fread_file (infile, &size);
2567 data.size = size;
2569 result = gnutls_pkcs12_import (pkcs12, &data, incert_format, 0);
2570 free (data.data);
2571 if (result < 0)
2572 error (EXIT_FAILURE, 0, "p12_import: %s", gnutls_strerror (result));
2574 pass = get_password(cinfo, NULL, 0);
2576 result = gnutls_pkcs12_verify_mac (pkcs12, pass);
2577 if (result < 0)
2579 fail = 1;
2580 error (0, 0, "verify_mac: %s", gnutls_strerror (result));
2583 for (indx = 0;; indx++)
2585 result = gnutls_pkcs12_bag_init (&bag);
2586 if (result < 0)
2587 error (EXIT_FAILURE, 0, "bag_init: %s", gnutls_strerror (result));
2589 result = gnutls_pkcs12_get_bag (pkcs12, indx, bag);
2590 if (result < 0)
2591 break;
2593 result = gnutls_pkcs12_bag_get_count (bag);
2594 if (result < 0)
2595 error (EXIT_FAILURE, 0, "bag_count: %s", gnutls_strerror (result));
2597 fprintf (outfile, "BAG #%d\n", indx);
2599 result = gnutls_pkcs12_bag_get_type (bag, 0);
2600 if (result < 0)
2601 error (EXIT_FAILURE, 0, "bag_init: %s", gnutls_strerror (result));
2603 if (result == GNUTLS_BAG_ENCRYPTED)
2605 fprintf (stderr, "\tType: %s\n", BAGTYPE (result));
2606 fprintf (stderr, "\n\tDecrypting...\n");
2608 result = gnutls_pkcs12_bag_decrypt (bag, pass);
2610 if (result < 0)
2612 fail = 1;
2613 error (0, 0, "bag_decrypt: %s", gnutls_strerror (result));
2614 continue;
2617 result = gnutls_pkcs12_bag_get_count (bag);
2618 if (result < 0)
2619 error (EXIT_FAILURE, 0, "encrypted bag_count: %s",
2620 gnutls_strerror (result));
2623 print_bag_data (bag);
2625 gnutls_pkcs12_bag_deinit (bag);
2628 if (fail)
2629 error (EXIT_FAILURE, 0, "There were errors parsing the structure\n");
2632 void
2633 pkcs7_info (void)
2635 gnutls_pkcs7_t pkcs7;
2636 int result;
2637 size_t size;
2638 gnutls_datum_t data, b64;
2639 int indx, count;
2641 result = gnutls_pkcs7_init (&pkcs7);
2642 if (result < 0)
2643 error (EXIT_FAILURE, 0, "p7_init: %s", gnutls_strerror (result));
2645 data.data = (void*)fread_file (infile, &size);
2646 data.size = size;
2648 result = gnutls_pkcs7_import (pkcs7, &data, incert_format);
2649 free (data.data);
2650 if (result < 0)
2651 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (result));
2653 /* Read and print the certificates.
2655 result = gnutls_pkcs7_get_crt_count (pkcs7);
2656 if (result < 0)
2657 error (EXIT_FAILURE, 0, "p7_crt_count: %s", gnutls_strerror (result));
2659 count = result;
2661 if (count > 0)
2662 fprintf (outfile, "Number of certificates: %u\n", count);
2664 for (indx = 0; indx < count; indx++)
2666 fputs ("\n", outfile);
2668 size = buffer_size;
2669 result = gnutls_pkcs7_get_crt_raw (pkcs7, indx, buffer, &size);
2670 if (result < 0)
2671 break;
2673 data.data = buffer;
2674 data.size = size;
2676 result = gnutls_pem_base64_encode_alloc ("CERTIFICATE", &data, &b64);
2677 if (result < 0)
2678 error (EXIT_FAILURE, 0, "encoding: %s", gnutls_strerror (result));
2680 fputs ((void*)b64.data, outfile);
2681 gnutls_free (b64.data);
2684 /* Read the CRLs now.
2686 result = gnutls_pkcs7_get_crl_count (pkcs7);
2687 if (result < 0)
2688 error (EXIT_FAILURE, 0, "p7_crl_count: %s", gnutls_strerror (result));
2690 count = result;
2692 if (count > 0)
2693 fprintf (outfile, "\nNumber of CRLs: %u\n", count);
2695 for (indx = 0; indx < count; indx++)
2697 fputs ("\n", outfile);
2699 size = buffer_size;
2700 result = gnutls_pkcs7_get_crl_raw (pkcs7, indx, buffer, &size);
2701 if (result < 0)
2702 break;
2704 data.data = buffer;
2705 data.size = size;
2707 result = gnutls_pem_base64_encode_alloc ("X509 CRL", &data, &b64);
2708 if (result < 0)
2709 error (EXIT_FAILURE, 0, "encoding: %s", gnutls_strerror (result));
2711 fputs ((void*)b64.data, outfile);
2712 gnutls_free (b64.data);
2716 void
2717 smime_to_pkcs7 (void)
2719 size_t linesize = 0;
2720 char *lineptr = NULL;
2721 ssize_t len;
2723 /* Find body. FIXME: Handle non-b64 Content-Transfer-Encoding.
2724 Reject non-S/MIME tagged Content-Type's? */
2727 len = getline (&lineptr, &linesize, infile);
2728 if (len == -1)
2729 error (EXIT_FAILURE, 0, "cannot find RFC 2822 header/body separator");
2731 while (strcmp (lineptr, "\r\n") != 0 && strcmp (lineptr, "\n") != 0);
2735 len = getline (&lineptr, &linesize, infile);
2736 if (len == -1)
2737 error (EXIT_FAILURE, 0, "message has RFC 2822 header but no body");
2739 while (strcmp (lineptr, "\r\n") == 0 && strcmp (lineptr, "\n") == 0);
2741 fprintf (outfile, "%s", "-----BEGIN PKCS7-----\n");
2745 while (len > 0
2746 && (lineptr[len - 1] == '\r' || lineptr[len - 1] == '\n'))
2747 lineptr[--len] = '\0';
2748 if (strcmp (lineptr, "") != 0)
2749 fprintf (outfile, "%s\n", lineptr);
2750 len = getline (&lineptr, &linesize, infile);
2752 while (len != -1);
2754 fprintf (outfile, "%s", "-----END PKCS7-----\n");
2756 free (lineptr);
2760 void
2761 pubkey_info (gnutls_x509_crt_t crt, common_info_st * cinfo)
2763 gnutls_pubkey_t pubkey;
2764 int ret;
2765 size_t size;
2767 ret = gnutls_pubkey_init (&pubkey);
2768 if (ret < 0)
2770 error (EXIT_FAILURE, 0, "pubkey_init: %s", gnutls_strerror (ret));
2773 if (crt == NULL)
2775 crt = load_cert (0, cinfo);
2778 if (crt != NULL)
2780 ret = gnutls_pubkey_import_x509 (pubkey, crt, 0);
2781 if (ret < 0)
2783 error (EXIT_FAILURE, 0, "pubkey_import_x509: %s",
2784 gnutls_strerror (ret));
2787 else
2789 pubkey = load_pubkey (1, cinfo);
2792 if (outcert_format == GNUTLS_X509_FMT_DER)
2794 size = buffer_size;
2795 ret = gnutls_pubkey_export (pubkey, outcert_format, buffer, &size);
2796 if (ret < 0)
2797 error (EXIT_FAILURE, 0, "export error: %s", gnutls_strerror (ret));
2799 fwrite (buffer, 1, size, outfile);
2801 gnutls_pubkey_deinit (pubkey);
2803 return;
2806 /* PEM */
2808 _pubkey_info(outfile, pubkey);
2809 gnutls_pubkey_deinit (pubkey);