Check for errors while setting an SRTP profile.
[gnutls.git] / src / certtool.c
blob81ec1425a229dfa70f29f8e7eef22eab22fdefd5
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>
29 #include <gnutls/crypto.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <ctype.h>
35 #include <time.h>
36 #include <unistd.h>
37 #include <errno.h>
38 #include <sys/types.h>
39 #include <sys/stat.h>
40 #include <fcntl.h>
41 #include <error.h>
43 /* Gnulib portability files. */
44 #include <read-file.h>
45 #include <progname.h>
46 #include <version-etc.h>
48 #include <certtool-cfg.h>
49 #include <common.h>
50 #include "certtool-args.h"
51 #include "certtool-common.h"
53 static void privkey_info_int (common_info_st*, gnutls_x509_privkey_t key);
54 static void print_crl_info (gnutls_x509_crl_t crl, FILE * out);
55 void pkcs7_info (void);
56 void crq_info (void);
57 void smime_to_pkcs7 (void);
58 void pkcs12_info (common_info_st*);
59 void generate_pkcs12 (common_info_st *);
60 void generate_pkcs8 (common_info_st *);
61 static void verify_chain (void);
62 void verify_crl (common_info_st * cinfo);
63 void pubkey_info (gnutls_x509_crt_t crt, common_info_st *);
64 void pgp_privkey_info (void);
65 void pgp_ring_info (void);
66 void certificate_info (int, common_info_st *);
67 void pgp_certificate_info (void);
68 void crl_info (void);
69 void privkey_info (common_info_st*);
70 static void cmd_parser (int argc, char **argv);
71 void generate_self_signed (common_info_st *);
72 void generate_request (common_info_st *);
73 static void print_certificate_info (gnutls_x509_crt_t crt, FILE * out,
74 unsigned int all);
75 static void verify_certificate (common_info_st * cinfo);
77 FILE *outfile;
78 FILE *infile;
79 static gnutls_digest_algorithm_t default_dig;
80 static unsigned int incert_format, outcert_format;
81 static unsigned int req_key_type;
83 /* non interactive operation if set
85 int batch;
88 static void
89 tls_log_func (int level, const char *str)
91 fprintf (stderr, "|<%d>| %s", level, str);
94 int
95 main (int argc, char **argv)
97 set_program_name (argv[0]);
98 cfg_init ();
99 cmd_parser (argc, argv);
101 return 0;
104 static gnutls_x509_privkey_t
105 generate_private_key_int (common_info_st * cinfo)
107 gnutls_x509_privkey_t key;
108 int ret, key_type, bits;
110 key_type = req_key_type;
112 ret = gnutls_x509_privkey_init (&key);
113 if (ret < 0)
114 error (EXIT_FAILURE, 0, "privkey_init: %s", gnutls_strerror (ret));
116 bits = get_bits (key_type, cinfo->bits, cinfo->sec_param);
118 fprintf (stderr, "Generating a %d bit %s private key...\n",
119 bits, gnutls_pk_algorithm_get_name (key_type));
121 if (bits > 1024 && key_type == GNUTLS_PK_DSA)
122 fprintf (stderr,
123 "Note that DSA keys with size over 1024 can only be used with TLS 1.2 or later.\n\n");
125 ret = gnutls_x509_privkey_generate (key, key_type, bits, 0);
126 if (ret < 0)
127 error (EXIT_FAILURE, 0, "privkey_generate: %s", gnutls_strerror (ret));
129 ret = gnutls_x509_privkey_verify_params (key);
130 if (ret < 0)
131 error (EXIT_FAILURE, 0, "privkey_verify_params: %s", gnutls_strerror (ret));
133 return key;
136 static int
137 cipher_to_flags (const char *cipher)
139 if (cipher == NULL)
141 return GNUTLS_PKCS_USE_PBES2_AES_128;
143 else if (strcasecmp (cipher, "3des") == 0)
145 return GNUTLS_PKCS_USE_PBES2_3DES;
147 else if (strcasecmp (cipher, "3des-pkcs12") == 0)
149 return GNUTLS_PKCS_USE_PKCS12_3DES;
151 else if (strcasecmp (cipher, "arcfour") == 0)
153 return GNUTLS_PKCS_USE_PKCS12_ARCFOUR;
155 else if (strcasecmp (cipher, "aes-128") == 0)
157 return GNUTLS_PKCS_USE_PBES2_AES_128;
159 else if (strcasecmp (cipher, "aes-192") == 0)
161 return GNUTLS_PKCS_USE_PBES2_AES_192;
163 else if (strcasecmp (cipher, "aes-256") == 0)
165 return GNUTLS_PKCS_USE_PBES2_AES_256;
167 else if (strcasecmp (cipher, "rc2-40") == 0)
169 return GNUTLS_PKCS_USE_PKCS12_RC2_40;
172 error (EXIT_FAILURE, 0, "unknown cipher %s\n", cipher);
173 return -1;
177 static void
178 print_private_key (common_info_st* cinfo, gnutls_x509_privkey_t key)
180 int ret;
181 size_t size;
183 if (!key)
184 return;
186 if (outcert_format == GNUTLS_X509_FMT_PEM)
187 privkey_info_int(cinfo, key);
189 if (!cinfo->pkcs8)
191 size = buffer_size;
192 ret = gnutls_x509_privkey_export (key, outcert_format,
193 buffer, &size);
194 if (ret < 0)
195 error (EXIT_FAILURE, 0, "privkey_export: %s", gnutls_strerror (ret));
197 else
199 unsigned int flags = 0;
200 const char *pass;
202 pass = get_password(cinfo, &flags, 0);
203 flags |= cipher_to_flags (cinfo->pkcs_cipher);
205 size = buffer_size;
206 ret =
207 gnutls_x509_privkey_export_pkcs8 (key, outcert_format, pass,
208 flags, buffer, &size);
209 if (ret < 0)
210 error (EXIT_FAILURE, 0, "privkey_export_pkcs8: %s",
211 gnutls_strerror (ret));
214 fwrite (buffer, 1, size, outfile);
217 static void
218 generate_private_key (common_info_st* cinfo)
220 gnutls_x509_privkey_t key;
222 key = generate_private_key_int (cinfo);
224 print_private_key (cinfo, key);
226 gnutls_x509_privkey_deinit (key);
230 static gnutls_x509_crt_t
231 generate_certificate (gnutls_privkey_t * ret_key,
232 gnutls_x509_crt_t ca_crt, int proxy,
233 common_info_st * cinfo)
235 gnutls_x509_crt_t crt;
236 gnutls_privkey_t key = NULL;
237 gnutls_pubkey_t pubkey;
238 size_t size;
239 int ret;
240 int client;
241 int days, result, ca_status = 0, is_ike = 0, path_len;
242 int vers;
243 unsigned int usage = 0, server;
244 gnutls_x509_crq_t crq; /* request */
246 ret = gnutls_x509_crt_init (&crt);
247 if (ret < 0)
248 error (EXIT_FAILURE, 0, "crt_init: %s", gnutls_strerror (ret));
250 crq = load_request (cinfo);
252 if (crq == NULL)
255 key = load_private_key (0, cinfo);
257 pubkey = load_public_key_or_import (1, key, cinfo);
259 if (!batch)
260 fprintf (stderr,
261 "Please enter the details of the certificate's distinguished name. "
262 "Just press enter to ignore a field.\n");
264 /* set the DN.
266 if (proxy)
268 result = gnutls_x509_crt_set_proxy_dn (crt, ca_crt, 0, NULL, 0);
269 if (result < 0)
270 error (EXIT_FAILURE, 0, "set_proxy_dn: %s",
271 gnutls_strerror (result));
273 get_cn_crt_set (crt);
275 else
277 get_country_crt_set (crt);
278 get_organization_crt_set (crt);
279 get_unit_crt_set (crt);
280 get_locality_crt_set (crt);
281 get_state_crt_set (crt);
282 get_cn_crt_set (crt);
283 get_dc_set (TYPE_CRT, crt);
284 get_uid_crt_set (crt);
285 get_oid_crt_set (crt);
286 get_key_purpose_set (crt);
288 if (!batch)
289 fprintf (stderr,
290 "This field should not be used in new certificates.\n");
292 get_pkcs9_email_crt_set (crt);
295 result = gnutls_x509_crt_set_pubkey (crt, pubkey);
296 if (result < 0)
297 error (EXIT_FAILURE, 0, "set_key: %s", gnutls_strerror (result));
299 else
301 result = gnutls_x509_crt_set_crq (crt, crq);
302 if (result < 0)
303 error (EXIT_FAILURE, 0, "set_crq: %s", gnutls_strerror (result));
308 int serial = get_serial ();
309 char bin_serial[5];
311 bin_serial[4] = serial & 0xff;
312 bin_serial[3] = (serial >> 8) & 0xff;
313 bin_serial[2] = (serial >> 16) & 0xff;
314 bin_serial[1] = (serial >> 24) & 0xff;
315 bin_serial[0] = 0;
317 result = gnutls_x509_crt_set_serial (crt, bin_serial, 5);
318 if (result < 0)
319 error (EXIT_FAILURE, 0, "serial: %s", gnutls_strerror (result));
322 if (!batch)
323 fprintf (stderr, "\n\nActivation/Expiration time.\n");
325 gnutls_x509_crt_set_activation_time (crt, time (NULL));
327 days = get_days ();
329 result =
330 gnutls_x509_crt_set_expiration_time (crt,
331 time (NULL) + ((time_t) days) * 24 * 60 * 60);
332 if (result < 0)
333 error (EXIT_FAILURE, 0, "set_expiration: %s", gnutls_strerror (result));
335 if (!batch)
336 fprintf (stderr, "\n\nExtensions.\n");
338 /* do not allow extensions on a v1 certificate */
339 if (crq && get_crq_extensions_status () != 0)
341 result = gnutls_x509_crt_set_crq_extensions (crt, crq);
342 if (result < 0)
343 error (EXIT_FAILURE, 0, "set_crq: %s", gnutls_strerror (result));
346 /* append additional extensions */
347 if (cinfo->v1_cert == 0)
350 if (proxy)
352 const char *policylanguage;
353 char *policy;
354 size_t policylen;
355 int proxypathlen = get_path_len ();
357 if (!batch)
359 printf ("1.3.6.1.5.5.7.21.1 ::= id-ppl-inheritALL\n");
360 printf ("1.3.6.1.5.5.7.21.2 ::= id-ppl-independent\n");
363 policylanguage = get_proxy_policy (&policy, &policylen);
365 result =
366 gnutls_x509_crt_set_proxy (crt, proxypathlen, policylanguage,
367 policy, policylen);
368 if (result < 0)
369 error (EXIT_FAILURE, 0, "set_proxy: %s",
370 gnutls_strerror (result));
373 if (!proxy)
374 ca_status = get_ca_status ();
375 if (ca_status)
376 path_len = get_path_len ();
377 else
378 path_len = -1;
380 result =
381 gnutls_x509_crt_set_basic_constraints (crt, ca_status, path_len);
382 if (result < 0)
383 error (EXIT_FAILURE, 0, "basic_constraints: %s",
384 gnutls_strerror (result));
386 client = get_tls_client_status ();
387 if (client != 0)
389 result = gnutls_x509_crt_set_key_purpose_oid (crt,
390 GNUTLS_KP_TLS_WWW_CLIENT,
392 if (result < 0)
393 error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (result));
396 is_ike = get_ipsec_ike_status ();
397 server = get_tls_server_status ();
399 get_dns_name_set (TYPE_CRT, crt);
400 get_uri_set (TYPE_CRT, crt);
401 get_ip_addr_set (TYPE_CRT, crt);
403 if (server != 0)
405 result = 0;
407 result =
408 gnutls_x509_crt_set_key_purpose_oid (crt,
409 GNUTLS_KP_TLS_WWW_SERVER, 0);
410 if (result < 0)
411 error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (result));
413 else if (!proxy)
415 get_email_set (TYPE_CRT, crt);
418 if (!ca_status || server)
420 int pk;
423 pk = gnutls_x509_crt_get_pk_algorithm (crt, NULL);
425 if (pk == GNUTLS_PK_RSA)
426 { /* DSA and ECDSA keys can only sign. */
427 result = get_sign_status (server);
428 if (result)
429 usage |= GNUTLS_KEY_DIGITAL_SIGNATURE;
431 result = get_encrypt_status (server);
432 if (result)
433 usage |= GNUTLS_KEY_KEY_ENCIPHERMENT;
435 else
436 usage |= GNUTLS_KEY_DIGITAL_SIGNATURE;
438 if (is_ike)
440 result =
441 gnutls_x509_crt_set_key_purpose_oid (crt,
442 GNUTLS_KP_IPSEC_IKE, 0);
443 if (result < 0)
444 error (EXIT_FAILURE, 0, "key_kp: %s",
445 gnutls_strerror (result));
450 if (ca_status)
452 result = get_cert_sign_status ();
453 if (result)
454 usage |= GNUTLS_KEY_KEY_CERT_SIGN;
456 result = get_crl_sign_status ();
457 if (result)
458 usage |= GNUTLS_KEY_CRL_SIGN;
460 result = get_code_sign_status ();
461 if (result)
463 result =
464 gnutls_x509_crt_set_key_purpose_oid (crt,
465 GNUTLS_KP_CODE_SIGNING,
467 if (result < 0)
468 error (EXIT_FAILURE, 0, "key_kp: %s",
469 gnutls_strerror (result));
472 result = get_ocsp_sign_status ();
473 if (result)
475 result =
476 gnutls_x509_crt_set_key_purpose_oid (crt,
477 GNUTLS_KP_OCSP_SIGNING,
479 if (result < 0)
480 error (EXIT_FAILURE, 0, "key_kp: %s",
481 gnutls_strerror (result));
484 result = get_time_stamp_status ();
485 if (result)
487 result =
488 gnutls_x509_crt_set_key_purpose_oid (crt,
489 GNUTLS_KP_TIME_STAMPING,
491 if (result < 0)
492 error (EXIT_FAILURE, 0, "key_kp: %s",
493 gnutls_strerror (result));
496 get_ocsp_issuer_set(crt);
497 get_ca_issuers_set(crt);
499 if (usage != 0)
501 /* http://tools.ietf.org/html/rfc4945#section-5.1.3.2: if any KU is
502 set, then either digitalSignature or the nonRepudiation bits in the
503 KeyUsage extension MUST for all IKE certs */
504 if (is_ike && (get_sign_status (server) != 1))
505 usage |= GNUTLS_KEY_NON_REPUDIATION;
506 result = gnutls_x509_crt_set_key_usage (crt, usage);
507 if (result < 0)
508 error (EXIT_FAILURE, 0, "key_usage: %s",
509 gnutls_strerror (result));
512 /* Subject Key ID.
514 size = buffer_size;
515 result = gnutls_x509_crt_get_key_id (crt, 0, buffer, &size);
516 if (result >= 0)
518 result = gnutls_x509_crt_set_subject_key_id (crt, buffer, size);
519 if (result < 0)
520 error (EXIT_FAILURE, 0, "set_subject_key_id: %s",
521 gnutls_strerror (result));
524 /* Authority Key ID.
526 if (ca_crt != NULL)
528 size = buffer_size;
529 result = gnutls_x509_crt_get_subject_key_id (ca_crt, buffer,
530 &size, NULL);
531 if (result < 0)
533 size = buffer_size;
534 result = gnutls_x509_crt_get_key_id (ca_crt, 0, buffer, &size);
536 if (result >= 0)
538 result =
539 gnutls_x509_crt_set_authority_key_id (crt, buffer, size);
540 if (result < 0)
541 error (EXIT_FAILURE, 0, "set_authority_key_id: %s",
542 gnutls_strerror (result));
547 /* Version.
549 if (cinfo->v1_cert != 0)
550 vers = 1;
551 else
552 vers = 3;
553 result = gnutls_x509_crt_set_version (crt, vers);
554 if (result < 0)
555 error (EXIT_FAILURE, 0, "set_version: %s", gnutls_strerror (result));
557 *ret_key = key;
558 return crt;
562 static gnutls_x509_crl_t
563 generate_crl (gnutls_x509_crt_t ca_crt, common_info_st * cinfo)
565 gnutls_x509_crl_t crl;
566 gnutls_x509_crt_t *crts;
567 size_t size;
568 int days, result;
569 unsigned int i;
570 time_t now = time (NULL);
572 result = gnutls_x509_crl_init (&crl);
573 if (result < 0)
574 error (EXIT_FAILURE, 0, "crl_init: %s", gnutls_strerror (result));
576 crts = load_cert_list (0, &size, cinfo);
578 for (i = 0; i < size; i++)
580 result = gnutls_x509_crl_set_crt (crl, crts[i], now);
581 if (result < 0)
582 error (EXIT_FAILURE, 0, "crl_set_crt: %s", gnutls_strerror (result));
585 result = gnutls_x509_crl_set_this_update (crl, now);
586 if (result < 0)
587 error (EXIT_FAILURE, 0, "this_update: %s", gnutls_strerror (result));
589 fprintf (stderr, "Update times.\n");
590 days = get_crl_next_update ();
592 result = gnutls_x509_crl_set_next_update (crl, now + days * 24 * 60 * 60);
593 if (result < 0)
594 error (EXIT_FAILURE, 0, "next_update: %s", gnutls_strerror (result));
596 result = gnutls_x509_crl_set_version (crl, 2);
597 if (result < 0)
598 error (EXIT_FAILURE, 0, "set_version: %s", gnutls_strerror (result));
600 /* Authority Key ID.
602 if (ca_crt != NULL)
604 size = buffer_size;
605 result = gnutls_x509_crt_get_subject_key_id (ca_crt, buffer,
606 &size, NULL);
607 if (result < 0)
609 size = buffer_size;
610 result = gnutls_x509_crt_get_key_id (ca_crt, 0, buffer, &size);
612 if (result >= 0)
614 result = gnutls_x509_crl_set_authority_key_id (crl, buffer, size);
615 if (result < 0)
616 error (EXIT_FAILURE, 0, "set_authority_key_id: %s",
617 gnutls_strerror (result));
622 unsigned int number = get_crl_number ();
623 char bin_number[5];
625 bin_number[4] = number & 0xff;
626 bin_number[3] = (number >> 8) & 0xff;
627 bin_number[2] = (number >> 16) & 0xff;
628 bin_number[1] = (number >> 24) & 0xff;
629 bin_number[0] = 0;
631 result = gnutls_x509_crl_set_number (crl, bin_number, 5);
632 if (result < 0)
633 error (EXIT_FAILURE, 0, "set_number: %s", gnutls_strerror (result));
636 return crl;
639 static gnutls_digest_algorithm_t
640 get_dig_for_pub (gnutls_pubkey_t pubkey)
642 gnutls_digest_algorithm_t dig;
643 int result;
644 unsigned int mand;
646 result = gnutls_pubkey_get_preferred_hash_algorithm (pubkey, &dig, &mand);
647 if (result < 0)
649 error (EXIT_FAILURE, 0, "crt_get_preferred_hash_algorithm: %s",
650 gnutls_strerror (result));
653 /* if algorithm allows alternatives */
654 if (mand == 0 && default_dig != GNUTLS_DIG_UNKNOWN)
655 dig = default_dig;
657 return dig;
660 static gnutls_digest_algorithm_t
661 get_dig (gnutls_x509_crt_t crt)
663 gnutls_digest_algorithm_t dig;
664 gnutls_pubkey_t pubkey;
665 int result;
667 gnutls_pubkey_init(&pubkey);
669 result = gnutls_pubkey_import_x509(pubkey, crt, 0);
670 if (result < 0)
672 error (EXIT_FAILURE, 0, "gnutls_pubkey_import_x509: %s",
673 gnutls_strerror (result));
676 dig = get_dig_for_pub (pubkey);
678 gnutls_pubkey_deinit(pubkey);
680 return dig;
683 void
684 generate_self_signed (common_info_st * cinfo)
686 gnutls_x509_crt_t crt;
687 gnutls_privkey_t key;
688 size_t size;
689 int result;
690 const char *uri;
692 fprintf (stderr, "Generating a self signed certificate...\n");
694 crt = generate_certificate (&key, NULL, 0, cinfo);
696 if (!key)
697 key = load_private_key (1, cinfo);
699 uri = get_crl_dist_point_url ();
700 if (uri)
702 result = gnutls_x509_crt_set_crl_dist_points (crt, GNUTLS_SAN_URI,
703 uri,
704 0 /* all reasons */ );
705 if (result < 0)
706 error (EXIT_FAILURE, 0, "crl_dist_points: %s",
707 gnutls_strerror (result));
710 print_certificate_info (crt, stderr, 0);
712 fprintf (stderr, "\n\nSigning certificate...\n");
714 result = gnutls_x509_crt_privkey_sign (crt, crt, key, get_dig (crt), 0);
715 if (result < 0)
716 error (EXIT_FAILURE, 0, "crt_sign: %s", gnutls_strerror (result));
718 size = buffer_size;
719 result = gnutls_x509_crt_export (crt, outcert_format, buffer, &size);
720 if (result < 0)
721 error (EXIT_FAILURE, 0, "crt_export: %s", gnutls_strerror (result));
723 fwrite (buffer, 1, size, outfile);
725 gnutls_x509_crt_deinit (crt);
726 gnutls_privkey_deinit (key);
729 static void
730 generate_signed_certificate (common_info_st * cinfo)
732 gnutls_x509_crt_t crt;
733 gnutls_privkey_t key;
734 size_t size;
735 int result;
736 gnutls_privkey_t ca_key;
737 gnutls_x509_crt_t ca_crt;
739 fprintf (stderr, "Generating a signed certificate...\n");
741 ca_key = load_ca_private_key (cinfo);
742 ca_crt = load_ca_cert (cinfo);
744 crt = generate_certificate (&key, ca_crt, 0, cinfo);
746 /* Copy the CRL distribution points.
748 gnutls_x509_crt_cpy_crl_dist_points (crt, ca_crt);
749 /* it doesn't matter if we couldn't copy the CRL dist points.
752 print_certificate_info (crt, stderr, 0);
754 fprintf (stderr, "\n\nSigning certificate...\n");
756 result = gnutls_x509_crt_privkey_sign (crt, ca_crt, ca_key, get_dig (ca_crt), 0);
757 if (result < 0)
758 error (EXIT_FAILURE, 0, "crt_sign: %s", gnutls_strerror (result));
760 size = buffer_size;
761 result = gnutls_x509_crt_export (crt, outcert_format, buffer, &size);
762 if (result < 0)
763 error (EXIT_FAILURE, 0, "crt_export: %s", gnutls_strerror (result));
765 fwrite (buffer, 1, size, outfile);
767 gnutls_x509_crt_deinit (crt);
768 gnutls_privkey_deinit (key);
769 gnutls_privkey_deinit(ca_key);
772 static void
773 generate_proxy_certificate (common_info_st * cinfo)
775 gnutls_x509_crt_t crt, eecrt;
776 gnutls_privkey_t key, eekey;
777 size_t size;
778 int result;
780 fprintf (stderr, "Generating a proxy certificate...\n");
782 eekey = load_ca_private_key (cinfo);
783 eecrt = load_cert (1, cinfo);
785 crt = generate_certificate (&key, eecrt, 1, cinfo);
787 print_certificate_info (crt, stderr, 0);
789 fprintf (stderr, "\n\nSigning certificate...\n");
791 result = gnutls_x509_crt_privkey_sign (crt, eecrt, eekey, get_dig (eecrt), 0);
792 if (result < 0)
793 error (EXIT_FAILURE, 0, "crt_sign: %s", gnutls_strerror (result));
795 size = buffer_size;
796 result = gnutls_x509_crt_export (crt, outcert_format, buffer, &size);
797 if (result < 0)
798 error (EXIT_FAILURE, 0, "crt_export: %s", gnutls_strerror (result));
800 fwrite (buffer, 1, size, outfile);
802 gnutls_x509_crt_deinit (eecrt);
803 gnutls_x509_crt_deinit (crt);
804 gnutls_privkey_deinit (key);
805 gnutls_privkey_deinit (eekey);
808 static void
809 generate_signed_crl (common_info_st * cinfo)
811 gnutls_x509_crl_t crl;
812 int result;
813 gnutls_privkey_t ca_key;
814 gnutls_x509_crt_t ca_crt;
816 fprintf (stderr, "Generating a signed CRL...\n");
818 ca_key = load_ca_private_key (cinfo);
819 ca_crt = load_ca_cert (cinfo);
820 crl = generate_crl (ca_crt, cinfo);
822 fprintf (stderr, "\n");
823 result = gnutls_x509_crl_privkey_sign(crl, ca_crt, ca_key, get_dig (ca_crt), 0);
824 if (result < 0)
825 error (EXIT_FAILURE, 0, "crl_privkey_sign: %s", gnutls_strerror (result));
827 print_crl_info (crl, stderr);
829 gnutls_privkey_deinit( ca_key);
830 gnutls_x509_crl_deinit (crl);
833 static void
834 update_signed_certificate (common_info_st * cinfo)
836 gnutls_x509_crt_t crt;
837 size_t size;
838 int result;
839 gnutls_privkey_t ca_key;
840 gnutls_x509_crt_t ca_crt;
841 int days;
842 time_t tim = time (NULL);
844 fprintf (stderr, "Generating a signed certificate...\n");
846 ca_key = load_ca_private_key (cinfo);
847 ca_crt = load_ca_cert (cinfo);
848 crt = load_cert (1, cinfo);
850 fprintf (stderr, "Activation/Expiration time.\n");
851 gnutls_x509_crt_set_activation_time (crt, tim);
853 days = get_days ();
855 result =
856 gnutls_x509_crt_set_expiration_time (crt, tim + ((time_t) days) * 24 * 60 * 60);
857 if (result < 0)
858 error (EXIT_FAILURE, 0, "set_expiration: %s", gnutls_strerror (result));
860 fprintf (stderr, "\n\nSigning certificate...\n");
862 result = gnutls_x509_crt_privkey_sign (crt, ca_crt, ca_key, get_dig (ca_crt), 0);
863 if (result < 0)
864 error (EXIT_FAILURE, 0, "crt_sign: %s", gnutls_strerror (result));
866 size = buffer_size;
867 result = gnutls_x509_crt_export (crt, outcert_format, buffer, &size);
868 if (result < 0)
869 error (EXIT_FAILURE, 0, "crt_export: %s", gnutls_strerror (result));
871 fwrite (buffer, 1, size, outfile);
873 gnutls_x509_crt_deinit (crt);
876 static void
877 cmd_parser (int argc, char **argv)
879 int ret, privkey_op = 0;
880 common_info_st cinfo;
882 optionProcess( &certtoolOptions, argc, argv);
884 if (HAVE_OPT(GENERATE_PRIVKEY) || HAVE_OPT(GENERATE_REQUEST) ||
885 HAVE_OPT(KEY_INFO) || HAVE_OPT(PGP_KEY_INFO))
886 privkey_op = 1;
888 if (HAVE_OPT(OUTFILE))
890 outfile = safe_open_rw (OPT_ARG(OUTFILE), privkey_op);
891 if (outfile == NULL)
892 error (EXIT_FAILURE, errno, "%s", OPT_ARG(OUTFILE));
894 else
895 outfile = stdout;
897 if (HAVE_OPT(INFILE))
899 infile = fopen (OPT_ARG(INFILE), "rb");
900 if (infile == NULL)
901 error (EXIT_FAILURE, errno, "%s", OPT_ARG(INFILE));
903 else
904 infile = stdin;
906 if (HAVE_OPT(INDER) || HAVE_OPT(INRAW))
907 incert_format = GNUTLS_X509_FMT_DER;
908 else
909 incert_format = GNUTLS_X509_FMT_PEM;
911 if (HAVE_OPT(OUTDER) || HAVE_OPT(OUTRAW))
912 outcert_format = GNUTLS_X509_FMT_DER;
913 else
914 outcert_format = GNUTLS_X509_FMT_PEM;
916 if (HAVE_OPT(DSA))
917 req_key_type = GNUTLS_PK_DSA;
918 else if (HAVE_OPT(ECC))
919 req_key_type = GNUTLS_PK_ECC;
920 else
921 req_key_type = GNUTLS_PK_RSA;
923 default_dig = GNUTLS_DIG_UNKNOWN;
924 if (HAVE_OPT(HASH))
926 if (strcasecmp (OPT_ARG(HASH), "md5") == 0)
928 fprintf (stderr,
929 "Warning: MD5 is broken, and should not be used any more for digital signatures.\n");
930 default_dig = GNUTLS_DIG_MD5;
932 else if (strcasecmp (OPT_ARG(HASH), "sha1") == 0)
933 default_dig = GNUTLS_DIG_SHA1;
934 else if (strcasecmp (OPT_ARG(HASH), "sha256") == 0)
935 default_dig = GNUTLS_DIG_SHA256;
936 else if (strcasecmp (OPT_ARG(HASH), "sha224") == 0)
937 default_dig = GNUTLS_DIG_SHA224;
938 else if (strcasecmp (OPT_ARG(HASH), "sha384") == 0)
939 default_dig = GNUTLS_DIG_SHA384;
940 else if (strcasecmp (OPT_ARG(HASH), "sha512") == 0)
941 default_dig = GNUTLS_DIG_SHA512;
942 else if (strcasecmp (OPT_ARG(HASH), "rmd160") == 0)
943 default_dig = GNUTLS_DIG_RMD160;
944 else
945 error (EXIT_FAILURE, 0, "invalid hash: %s", OPT_ARG(HASH));
948 batch = 0;
949 if (HAVE_OPT(TEMPLATE))
951 batch = 1;
952 template_parse (OPT_ARG(TEMPLATE));
955 gnutls_global_set_log_function (tls_log_func);
957 if (HAVE_OPT(DEBUG))
959 gnutls_global_set_log_level (OPT_VALUE_DEBUG);
960 printf ("Setting log level to %d\n", (int)OPT_VALUE_DEBUG);
963 if ((ret = gnutls_global_init ()) < 0)
964 error (EXIT_FAILURE, 0, "global_init: %s", gnutls_strerror (ret));
966 #ifdef ENABLE_PKCS11
967 pkcs11_common();
968 #endif
970 memset (&cinfo, 0, sizeof (cinfo));
972 if (HAVE_OPT(VERBOSE))
973 cinfo.verbose = 1;
975 if (HAVE_OPT(LOAD_PRIVKEY))
976 cinfo.privkey = OPT_ARG(LOAD_PRIVKEY);
978 cinfo.v1_cert = HAVE_OPT(V1);
979 if (HAVE_OPT(NO_CRQ_EXTENSIONS))
980 cinfo.crq_extensions = 0;
981 else cinfo.crq_extensions = 1;
983 if (HAVE_OPT(LOAD_PUBKEY))
984 cinfo.pubkey = OPT_ARG(LOAD_PUBKEY);
986 cinfo.pkcs8 = HAVE_OPT(PKCS8);
987 cinfo.incert_format = incert_format;
989 if (HAVE_OPT(LOAD_CERTIFICATE))
990 cinfo.cert = OPT_ARG(LOAD_CERTIFICATE);
992 if (HAVE_OPT(LOAD_REQUEST))
993 cinfo.request = OPT_ARG(LOAD_REQUEST);
995 if (HAVE_OPT(LOAD_CA_CERTIFICATE))
996 cinfo.ca = OPT_ARG(LOAD_CA_CERTIFICATE);
998 if (HAVE_OPT(LOAD_CA_PRIVKEY))
999 cinfo.ca_privkey = OPT_ARG(LOAD_CA_PRIVKEY);
1001 if (HAVE_OPT(BITS))
1002 cinfo.bits = OPT_VALUE_BITS;
1004 if (HAVE_OPT(SEC_PARAM))
1005 cinfo.sec_param = OPT_ARG(SEC_PARAM);
1007 if (HAVE_OPT(PKCS_CIPHER))
1008 cinfo.pkcs_cipher = OPT_ARG(PKCS_CIPHER);
1010 if (HAVE_OPT(PASSWORD))
1012 cinfo.password = OPT_ARG(PASSWORD);
1013 if (HAVE_OPT(GENERATE_PRIVKEY) && cinfo.pkcs8 == 0)
1015 fprintf(stderr, "Assuming PKCS #8 format...\n");
1016 cinfo.pkcs8 = 1;
1020 if (HAVE_OPT(NULL_PASSWORD))
1022 cinfo.null_password = 1;
1023 cinfo.password = "";
1026 if (HAVE_OPT(GENERATE_SELF_SIGNED))
1027 generate_self_signed (&cinfo);
1028 else if (HAVE_OPT(GENERATE_CERTIFICATE))
1029 generate_signed_certificate (&cinfo);
1030 else if (HAVE_OPT(GENERATE_PROXY))
1031 generate_proxy_certificate (&cinfo);
1032 else if (HAVE_OPT(GENERATE_CRL))
1033 generate_signed_crl (&cinfo);
1034 else if (HAVE_OPT(UPDATE_CERTIFICATE))
1035 update_signed_certificate (&cinfo);
1036 else if (HAVE_OPT(GENERATE_PRIVKEY))
1037 generate_private_key (&cinfo);
1038 else if (HAVE_OPT(GENERATE_REQUEST))
1039 generate_request (&cinfo);
1040 else if (HAVE_OPT(VERIFY_CHAIN))
1041 verify_chain ();
1042 else if (HAVE_OPT(VERIFY))
1043 verify_certificate (&cinfo);
1044 else if (HAVE_OPT(VERIFY_CRL))
1045 verify_crl (&cinfo);
1046 else if (HAVE_OPT(CERTIFICATE_INFO))
1047 certificate_info (0, &cinfo);
1048 else if (HAVE_OPT(DH_INFO))
1049 dh_info (&cinfo);
1050 else if (HAVE_OPT(CERTIFICATE_PUBKEY))
1051 certificate_info (1, &cinfo);
1052 else if (HAVE_OPT(KEY_INFO))
1053 privkey_info (&cinfo);
1054 else if (HAVE_OPT(PUBKEY_INFO))
1055 pubkey_info (NULL, &cinfo);
1056 else if (HAVE_OPT(TO_P12))
1057 generate_pkcs12 (&cinfo);
1058 else if (HAVE_OPT(P12_INFO))
1059 pkcs12_info (&cinfo);
1060 else if (HAVE_OPT(GENERATE_DH_PARAMS))
1061 generate_prime (1, &cinfo);
1062 else if (HAVE_OPT(GET_DH_PARAMS))
1063 generate_prime (0, &cinfo);
1064 else if (HAVE_OPT(CRL_INFO))
1065 crl_info ();
1066 else if (HAVE_OPT(P7_INFO))
1067 pkcs7_info ();
1068 else if (HAVE_OPT(SMIME_TO_P7))
1069 smime_to_pkcs7 ();
1070 else if (HAVE_OPT(TO_P8))
1071 generate_pkcs8 (&cinfo);
1072 #ifdef ENABLE_OPENPGP
1073 else if (HAVE_OPT(PGP_CERTIFICATE_INFO))
1074 pgp_certificate_info ();
1075 else if (HAVE_OPT(PGP_KEY_INFO))
1076 pgp_privkey_info ();
1077 else if (HAVE_OPT(PGP_RING_INFO))
1078 pgp_ring_info ();
1079 #endif
1080 else if (HAVE_OPT(CRQ_INFO))
1081 crq_info ();
1082 else
1083 USAGE(1);
1085 fclose (outfile);
1087 #ifdef ENABLE_PKCS11
1088 gnutls_pkcs11_deinit ();
1089 #endif
1090 gnutls_global_deinit ();
1093 #define MAX_CRTS 500
1094 void
1095 certificate_info (int pubkey, common_info_st * cinfo)
1097 gnutls_x509_crt_t crt[MAX_CRTS];
1098 size_t size;
1099 int ret, i, count;
1100 gnutls_datum_t pem;
1101 unsigned int crt_num;
1103 pem.data = (void*)fread_file (infile, &size);
1104 pem.size = size;
1106 crt_num = MAX_CRTS;
1107 ret =
1108 gnutls_x509_crt_list_import (crt, &crt_num, &pem, incert_format,
1109 GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
1110 if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
1112 error (0, 0, "too many certificates (%d); "
1113 "will only read the first %d", crt_num, MAX_CRTS);
1114 crt_num = MAX_CRTS;
1115 ret = gnutls_x509_crt_list_import (crt, &crt_num, &pem,
1116 incert_format, 0);
1118 if (ret < 0)
1119 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (ret));
1121 free (pem.data);
1123 count = ret;
1125 if (count > 1 && outcert_format == GNUTLS_X509_FMT_DER)
1127 error (0, 0, "cannot output multiple certificates in DER format; "
1128 "using PEM instead");
1129 outcert_format = GNUTLS_X509_FMT_PEM;
1132 for (i = 0; i < count; i++)
1134 if (i > 0)
1135 fprintf (outfile, "\n");
1137 if (outcert_format == GNUTLS_X509_FMT_PEM)
1138 print_certificate_info (crt[i], outfile, 1);
1140 if (pubkey)
1141 pubkey_info (crt[i], cinfo);
1142 else
1144 size = buffer_size;
1145 ret = gnutls_x509_crt_export (crt[i], outcert_format, buffer,
1146 &size);
1147 if (ret < 0)
1148 error (EXIT_FAILURE, 0, "export error: %s", gnutls_strerror (ret));
1150 fwrite (buffer, 1, size, outfile);
1153 gnutls_x509_crt_deinit (crt[i]);
1157 #ifdef ENABLE_OPENPGP
1159 void
1160 pgp_certificate_info (void)
1162 gnutls_openpgp_crt_t crt;
1163 size_t size;
1164 int ret;
1165 gnutls_datum_t pem, out_data;
1166 unsigned int verify_status;
1168 pem.data = (void*)fread_file (infile, &size);
1169 pem.size = size;
1171 ret = gnutls_openpgp_crt_init (&crt);
1172 if (ret < 0)
1173 error (EXIT_FAILURE, 0, "openpgp_crt_init: %s", gnutls_strerror (ret));
1175 ret = gnutls_openpgp_crt_import (crt, &pem, incert_format);
1177 if (ret < 0)
1178 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (ret));
1180 free (pem.data);
1182 if (outcert_format == GNUTLS_OPENPGP_FMT_BASE64)
1184 ret = gnutls_openpgp_crt_print (crt, 0, &out_data);
1186 if (ret == 0)
1188 fprintf (outfile, "%s\n", out_data.data);
1189 gnutls_free (out_data.data);
1194 ret = gnutls_openpgp_crt_verify_self (crt, 0, &verify_status);
1195 if (ret < 0)
1197 error (EXIT_FAILURE, 0, "verify signature error: %s",
1198 gnutls_strerror (ret));
1201 if (verify_status & GNUTLS_CERT_INVALID)
1203 fprintf (outfile, "Self Signature verification: failed\n\n");
1205 else
1207 fprintf (outfile, "Self Signature verification: ok (%x)\n\n",
1208 verify_status);
1211 size = buffer_size;
1212 ret = gnutls_openpgp_crt_export (crt, outcert_format, buffer, &size);
1213 if (ret < 0)
1215 error (EXIT_FAILURE, 0, "export error: %s", gnutls_strerror (ret));
1216 fwrite (buffer, 1, size, outfile);
1219 fprintf (outfile, "%s\n", buffer);
1220 gnutls_openpgp_crt_deinit (crt);
1223 void
1224 pgp_privkey_info (void)
1226 gnutls_openpgp_privkey_t key;
1227 unsigned char keyid[GNUTLS_OPENPGP_KEYID_SIZE];
1228 size_t size;
1229 int ret, i, subkeys, bits = 0;
1230 gnutls_datum_t pem;
1231 const char *cprint;
1233 size = fread (buffer, 1, buffer_size - 1, infile);
1234 buffer[size] = 0;
1236 gnutls_openpgp_privkey_init (&key);
1238 pem.data = buffer;
1239 pem.size = size;
1241 ret = gnutls_openpgp_privkey_import (key, &pem, incert_format,
1242 NULL, 0);
1244 if (ret < 0)
1245 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (ret));
1247 /* Public key algorithm
1249 subkeys = gnutls_openpgp_privkey_get_subkey_count (key);
1250 if (subkeys < 0)
1251 error (EXIT_FAILURE, 0, "privkey_get_subkey_count: %s",
1252 gnutls_strerror (subkeys));
1254 for (i = -1; i < subkeys; i++)
1257 if (i != -1)
1258 fprintf (outfile, "Subkey[%d]:\n", i);
1260 fprintf (outfile, "Public Key Info:\n");
1262 if (i == -1)
1263 ret = gnutls_openpgp_privkey_get_pk_algorithm (key, NULL);
1264 else
1265 ret = gnutls_openpgp_privkey_get_subkey_pk_algorithm (key, i, NULL);
1267 fprintf (outfile, "\tPublic Key Algorithm: ");
1268 cprint = gnutls_pk_algorithm_get_name (ret);
1269 fprintf (outfile, "%s\n", cprint ? cprint : "Unknown");
1270 fprintf (outfile, "\tKey Security Level: %s\n",
1271 gnutls_sec_param_get_name (gnutls_openpgp_privkey_sec_param
1272 (key)));
1274 /* Print the raw public and private keys
1277 if (ret == GNUTLS_PK_RSA)
1279 gnutls_datum_t m, e, d, p, q, u;
1281 if (i == -1)
1282 ret =
1283 gnutls_openpgp_privkey_export_rsa_raw (key, &m, &e, &d, &p,
1284 &q, &u);
1285 else
1286 ret =
1287 gnutls_openpgp_privkey_export_subkey_rsa_raw (key, i, &m,
1288 &e, &d, &p,
1289 &q, &u);
1290 if (ret < 0)
1291 fprintf (stderr, "Error in key RSA data export: %s\n",
1292 gnutls_strerror (ret));
1293 else
1294 print_rsa_pkey (outfile, &m, &e, &d, &p, &q, &u, NULL, NULL);
1296 bits = m.size * 8;
1298 else if (ret == GNUTLS_PK_DSA)
1300 gnutls_datum_t p, q, g, y, x;
1302 if (i == -1)
1303 ret =
1304 gnutls_openpgp_privkey_export_dsa_raw (key, &p, &q, &g, &y, &x);
1305 else
1306 ret =
1307 gnutls_openpgp_privkey_export_subkey_dsa_raw (key, i, &p,
1308 &q, &g, &y, &x);
1309 if (ret < 0)
1310 fprintf (stderr, "Error in key DSA data export: %s\n",
1311 gnutls_strerror (ret));
1312 else
1313 print_dsa_pkey (outfile, &x, &y, &p, &q, &g);
1315 bits = y.size * 8;
1318 fprintf (outfile, "\n");
1320 size = buffer_size;
1321 if (i == -1)
1322 ret = gnutls_openpgp_privkey_get_key_id (key, keyid);
1323 else
1324 ret = gnutls_openpgp_privkey_get_subkey_id (key, i, keyid);
1326 if (ret < 0)
1328 fprintf (stderr, "Error in key id calculation: %s\n",
1329 gnutls_strerror (ret));
1331 else
1333 fprintf (outfile, "Public key ID: %s\n", raw_to_string (keyid, 8));
1336 size = buffer_size;
1337 if (i == -1)
1338 ret = gnutls_openpgp_privkey_get_fingerprint (key, buffer, &size);
1339 else
1340 ret = gnutls_openpgp_privkey_get_subkey_fingerprint (key, i, buffer, &size);
1342 if (ret < 0)
1344 fprintf (stderr, "Error in fingerprint calculation: %s\n",
1345 gnutls_strerror (ret));
1347 else
1349 gnutls_datum_t art;
1351 fprintf (outfile, "Fingerprint: %s\n", raw_to_string (buffer, size));
1353 ret = gnutls_random_art(GNUTLS_RANDOM_ART_OPENSSH, cprint, bits, buffer, size, &art);
1354 if (ret >= 0)
1356 fprintf (outfile, "Fingerprint's random art:\n%s\n\n", art.data);
1357 gnutls_free(art.data);
1362 size = buffer_size;
1363 ret = gnutls_openpgp_privkey_export (key, GNUTLS_OPENPGP_FMT_BASE64,
1364 NULL, 0, buffer, &size);
1365 if (ret < 0)
1366 error (EXIT_FAILURE, 0, "export error: %s", gnutls_strerror (ret));
1368 fprintf (outfile, "\n%s\n", buffer);
1370 gnutls_openpgp_privkey_deinit (key);
1373 void
1374 pgp_ring_info (void)
1376 gnutls_openpgp_keyring_t ring;
1377 gnutls_openpgp_crt_t crt;
1378 size_t size;
1379 int ret, i, count;
1380 gnutls_datum_t pem;
1382 pem.data = (void*)fread_file (infile, &size);
1383 pem.size = size;
1385 ret = gnutls_openpgp_keyring_init (&ring);
1386 if (ret < 0)
1387 error (EXIT_FAILURE, 0, "openpgp_keyring_init: %s",
1388 gnutls_strerror (ret));
1390 ret = gnutls_openpgp_keyring_import (ring, &pem, incert_format);
1392 if (ret < 0)
1393 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (ret));
1395 free (pem.data);
1397 count = gnutls_openpgp_keyring_get_crt_count (ring);
1398 if (count >= 0)
1399 fprintf (outfile, "Keyring contains %d OpenPGP certificates\n\n", count);
1400 else
1401 error (EXIT_FAILURE, 0, "keyring error: %s", gnutls_strerror (count));
1403 for (i = 0; i < count; i++)
1405 ret = gnutls_openpgp_keyring_get_crt (ring, i, &crt);
1406 if (ret < 0)
1407 error (EXIT_FAILURE, 0, "export error: %s", gnutls_strerror (ret));
1409 size = buffer_size;
1410 ret = gnutls_openpgp_crt_export (crt, outcert_format,
1411 buffer, &size);
1412 if (ret < 0)
1413 error (EXIT_FAILURE, 0, "export error: %s", gnutls_strerror (ret));
1415 fwrite (buffer, 1, size, outfile);
1416 fprintf (outfile, "\n\n");
1418 gnutls_openpgp_crt_deinit (crt);
1423 gnutls_openpgp_keyring_deinit (ring);
1427 #endif
1431 static void
1432 print_certificate_info (gnutls_x509_crt_t crt, FILE * out, unsigned int all)
1434 gnutls_datum_t data;
1435 int ret;
1437 if (all)
1438 ret = gnutls_x509_crt_print (crt, GNUTLS_CRT_PRINT_FULL, &data);
1439 else
1440 ret = gnutls_x509_crt_print (crt, GNUTLS_CRT_PRINT_UNSIGNED_FULL, &data);
1441 if (ret == 0)
1443 fprintf (out, "%s\n", data.data);
1444 gnutls_free (data.data);
1447 if (out == stderr && batch == 0) /* interactive */
1448 if (read_yesno ("Is the above information ok? (y/N): ") == 0)
1450 exit (1);
1454 static void
1455 print_crl_info (gnutls_x509_crl_t crl, FILE * out)
1457 gnutls_datum_t data;
1458 int ret;
1459 size_t size;
1461 ret = gnutls_x509_crl_print (crl, GNUTLS_CRT_PRINT_FULL, &data);
1462 if (ret < 0)
1463 error (EXIT_FAILURE, 0, "crl_print: %s", gnutls_strerror (ret));
1465 fprintf (out, "%s\n", data.data);
1467 gnutls_free (data.data);
1469 size = buffer_size;
1470 ret = gnutls_x509_crl_export (crl, GNUTLS_X509_FMT_PEM, buffer, &size);
1471 if (ret < 0)
1472 error (EXIT_FAILURE, 0, "crl_export: %s", gnutls_strerror (ret));
1474 fwrite (buffer, 1, size, outfile);
1477 void
1478 crl_info (void)
1480 gnutls_x509_crl_t crl;
1481 int ret;
1482 size_t size;
1483 gnutls_datum_t pem;
1485 ret = gnutls_x509_crl_init (&crl);
1486 if (ret < 0)
1487 error (EXIT_FAILURE, 0, "crl_init: %s", gnutls_strerror (ret));
1489 pem.data = (void*)fread_file (infile, &size);
1490 pem.size = size;
1492 if (!pem.data)
1493 error (EXIT_FAILURE, errno, "%s", infile ? "file" :
1494 "standard input");
1496 ret = gnutls_x509_crl_import (crl, &pem, incert_format);
1498 free (pem.data);
1499 if (ret < 0)
1500 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (ret));
1502 print_crl_info (crl, outfile);
1504 gnutls_x509_crl_deinit (crl);
1507 static void
1508 print_crq_info (gnutls_x509_crq_t crq, FILE * out)
1510 gnutls_datum_t data;
1511 int ret;
1512 size_t size;
1514 if (outcert_format == GNUTLS_X509_FMT_PEM)
1516 ret = gnutls_x509_crq_print (crq, GNUTLS_CRT_PRINT_FULL, &data);
1517 if (ret < 0)
1518 error (EXIT_FAILURE, 0, "crq_print: %s", gnutls_strerror (ret));
1520 fprintf (out, "%s\n", data.data);
1522 gnutls_free (data.data);
1525 ret = gnutls_x509_crq_verify(crq, 0);
1526 if (ret < 0)
1528 fprintf(out, "Self signature: FAILED\n\n");
1530 else
1532 fprintf(out, "Self signature: verified\n\n");
1535 size = buffer_size;
1536 ret = gnutls_x509_crq_export (crq, outcert_format, buffer, &size);
1537 if (ret < 0)
1538 error (EXIT_FAILURE, 0, "crq_export: %s", gnutls_strerror (ret));
1540 fwrite (buffer, 1, size, outfile);
1543 void
1544 crq_info (void)
1546 gnutls_x509_crq_t crq;
1547 int ret;
1548 size_t size;
1549 gnutls_datum_t pem;
1551 ret = gnutls_x509_crq_init (&crq);
1552 if (ret < 0)
1553 error (EXIT_FAILURE, 0, "crq_init: %s", gnutls_strerror (ret));
1555 pem.data = (void*)fread_file (infile, &size);
1556 pem.size = size;
1558 if (!pem.data)
1559 error (EXIT_FAILURE, errno, "%s", infile ? "file" :
1560 "standard input");
1562 ret = gnutls_x509_crq_import (crq, &pem, incert_format);
1564 free (pem.data);
1565 if (ret < 0)
1566 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (ret));
1568 print_crq_info (crq, outfile);
1570 gnutls_x509_crq_deinit (crq);
1573 static void privkey_info_int (common_info_st* cinfo, gnutls_x509_privkey_t key)
1575 int ret, key_type;
1576 unsigned int bits = 0;
1577 size_t size;
1578 const char *cprint;
1580 /* Public key algorithm
1582 fprintf (outfile, "Public Key Info:\n");
1583 ret = gnutls_x509_privkey_get_pk_algorithm2 (key, &bits);
1584 fprintf (outfile, "\tPublic Key Algorithm: ");
1586 key_type = ret;
1588 cprint = gnutls_pk_algorithm_get_name (key_type);
1589 fprintf (outfile, "%s\n", cprint ? cprint : "Unknown");
1590 fprintf (outfile, "\tKey Security Level: %s (%u bits)\n\n",
1591 gnutls_sec_param_get_name (gnutls_x509_privkey_sec_param (key)), bits);
1593 /* Print the raw public and private keys
1595 if (key_type == GNUTLS_PK_RSA)
1597 gnutls_datum_t m, e, d, p, q, u, exp1, exp2;
1599 ret =
1600 gnutls_x509_privkey_export_rsa_raw2 (key, &m, &e, &d, &p, &q, &u,
1601 &exp1, &exp2);
1602 if (ret < 0)
1603 fprintf (stderr, "Error in key RSA data export: %s\n",
1604 gnutls_strerror (ret));
1605 else
1607 print_rsa_pkey (outfile, &m, &e, &d, &p, &q, &u, &exp1, &exp2);
1609 gnutls_free (m.data);
1610 gnutls_free (e.data);
1611 gnutls_free (d.data);
1612 gnutls_free (p.data);
1613 gnutls_free (q.data);
1614 gnutls_free (u.data);
1615 gnutls_free (exp1.data);
1616 gnutls_free (exp2.data);
1619 else if (key_type == GNUTLS_PK_DSA)
1621 gnutls_datum_t p, q, g, y, x;
1623 ret = gnutls_x509_privkey_export_dsa_raw (key, &p, &q, &g, &y, &x);
1624 if (ret < 0)
1625 fprintf (stderr, "Error in key DSA data export: %s\n",
1626 gnutls_strerror (ret));
1627 else
1629 print_dsa_pkey (outfile, &x, &y, &p, &q, &g);
1631 gnutls_free (x.data);
1632 gnutls_free (y.data);
1633 gnutls_free (p.data);
1634 gnutls_free (q.data);
1635 gnutls_free (g.data);
1638 else if (key_type == GNUTLS_PK_EC)
1640 gnutls_datum_t y, x, k;
1641 gnutls_ecc_curve_t curve;
1643 ret = gnutls_x509_privkey_export_ecc_raw (key, &curve, &x, &y, &k);
1644 if (ret < 0)
1645 fprintf (stderr, "Error in key ECC data export: %s\n",
1646 gnutls_strerror (ret));
1647 else
1649 print_ecc_pkey (outfile, curve, &k, &x, &y);
1651 gnutls_free (x.data);
1652 gnutls_free (y.data);
1653 gnutls_free (k.data);
1657 fprintf (outfile, "\n");
1659 size = buffer_size;
1660 if ((ret = gnutls_x509_privkey_get_key_id (key, 0, buffer, &size)) < 0)
1662 fprintf (stderr, "Error in key id calculation: %s\n",
1663 gnutls_strerror (ret));
1665 else
1667 gnutls_datum_t art;
1669 fprintf (outfile, "Public Key ID: %s\n", raw_to_string (buffer, size));
1671 ret = gnutls_random_art(GNUTLS_RANDOM_ART_OPENSSH, cprint, bits, buffer, size, &art);
1672 if (ret >= 0)
1674 fprintf (outfile, "Public key's random art:\n%s\n", art.data);
1675 gnutls_free(art.data);
1678 fprintf (outfile, "\n");
1682 void
1683 privkey_info (common_info_st* cinfo)
1685 gnutls_x509_privkey_t key;
1686 size_t size;
1687 int ret;
1688 gnutls_datum_t pem;
1689 const char *pass;
1690 unsigned int flags = 0;
1692 size = fread (buffer, 1, buffer_size - 1, infile);
1693 buffer[size] = 0;
1695 gnutls_x509_privkey_init (&key);
1697 pem.data = buffer;
1698 pem.size = size;
1700 ret = gnutls_x509_privkey_import2 (key, &pem, incert_format, NULL, 0);
1702 /* If we failed to import the certificate previously try PKCS #8 */
1703 if (ret == GNUTLS_E_DECRYPTION_FAILED)
1705 fprintf(stderr, "Encrypted structure detected...\n");
1706 pass = get_password(cinfo, &flags, 0);
1708 ret = gnutls_x509_privkey_import2 (key, &pem,
1709 incert_format, pass, flags);
1711 if (ret < 0)
1712 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (ret));
1714 if (outcert_format == GNUTLS_X509_FMT_PEM)
1715 privkey_info_int (cinfo, key);
1717 ret = gnutls_x509_privkey_verify_params (key);
1718 if (ret < 0)
1719 fprintf (outfile, "\n** Private key parameters validation failed **\n\n");
1721 size = buffer_size;
1722 ret = gnutls_x509_privkey_export (key, outcert_format, buffer, &size);
1723 if (ret < 0)
1724 error (EXIT_FAILURE, 0, "export error: %s", gnutls_strerror (ret));
1726 fwrite (buffer, 1, size, outfile);
1728 gnutls_x509_privkey_deinit (key);
1732 /* Generate a PKCS #10 certificate request.
1734 void
1735 generate_request (common_info_st * cinfo)
1737 gnutls_x509_crq_t crq;
1738 gnutls_x509_privkey_t xkey;
1739 gnutls_pubkey_t pubkey;
1740 gnutls_privkey_t pkey;
1741 int ret, ca_status, path_len, pk;
1742 const char *pass;
1743 unsigned int usage = 0;
1745 fprintf (stderr, "Generating a PKCS #10 certificate request...\n");
1747 ret = gnutls_x509_crq_init (&crq);
1748 if (ret < 0)
1749 error (EXIT_FAILURE, 0, "crq_init: %s", gnutls_strerror (ret));
1752 /* Load the private key.
1754 pkey = load_private_key (0, cinfo);
1755 if (!pkey)
1757 ret = gnutls_privkey_init (&pkey);
1758 if (ret < 0)
1759 error (EXIT_FAILURE, 0, "privkey_init: %s", gnutls_strerror (ret));
1761 xkey = generate_private_key_int (cinfo);
1763 print_private_key (cinfo, xkey);
1765 ret = gnutls_privkey_import_x509(pkey, xkey, GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
1766 if (ret < 0)
1767 error (EXIT_FAILURE, 0, "privkey_import_x509: %s", gnutls_strerror (ret));
1770 pubkey = load_public_key_or_import (1, pkey, cinfo);
1772 pk = gnutls_pubkey_get_pk_algorithm (pubkey, NULL);
1774 /* Set the DN.
1776 get_country_crq_set (crq);
1777 get_organization_crq_set (crq);
1778 get_unit_crq_set (crq);
1779 get_locality_crq_set (crq);
1780 get_state_crq_set (crq);
1781 get_cn_crq_set (crq);
1782 get_dc_set (TYPE_CRQ, crq);
1783 get_uid_crq_set (crq);
1784 get_oid_crq_set (crq);
1786 get_dns_name_set (TYPE_CRQ, crq);
1787 get_uri_set (TYPE_CRQ, crq);
1788 get_ip_addr_set (TYPE_CRQ, crq);
1789 get_email_set (TYPE_CRQ, crq);
1791 pass = get_challenge_pass ();
1793 if (pass != NULL && pass[0] != 0)
1795 ret = gnutls_x509_crq_set_challenge_password (crq, pass);
1796 if (ret < 0)
1797 error (EXIT_FAILURE, 0, "set_pass: %s", gnutls_strerror (ret));
1800 if (cinfo->crq_extensions != 0)
1802 ca_status = get_ca_status ();
1803 if (ca_status)
1804 path_len = get_path_len ();
1805 else
1806 path_len = -1;
1808 ret = gnutls_x509_crq_set_basic_constraints (crq, ca_status, path_len);
1809 if (ret < 0)
1810 error (EXIT_FAILURE, 0, "set_basic_constraints: %s",
1811 gnutls_strerror (ret));
1813 if (pk == GNUTLS_PK_RSA)
1815 ret = get_sign_status (1);
1816 if (ret)
1817 usage |= GNUTLS_KEY_DIGITAL_SIGNATURE;
1819 /* Only ask for an encryption certificate
1820 * if it is an RSA one */
1821 ret = get_encrypt_status (1);
1822 if (ret)
1823 usage |= GNUTLS_KEY_KEY_ENCIPHERMENT;
1824 else
1825 usage |= GNUTLS_KEY_DIGITAL_SIGNATURE;
1827 else /* DSA and ECDSA are always signing */
1828 usage |= GNUTLS_KEY_DIGITAL_SIGNATURE;
1830 if (ca_status)
1832 ret = get_cert_sign_status ();
1833 if (ret)
1834 usage |= GNUTLS_KEY_KEY_CERT_SIGN;
1836 ret = get_crl_sign_status ();
1837 if (ret)
1838 usage |= GNUTLS_KEY_CRL_SIGN;
1840 ret = get_code_sign_status ();
1841 if (ret)
1843 ret = gnutls_x509_crq_set_key_purpose_oid
1844 (crq, GNUTLS_KP_CODE_SIGNING, 0);
1845 if (ret < 0)
1846 error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (ret));
1849 ret = get_ocsp_sign_status ();
1850 if (ret)
1852 ret = gnutls_x509_crq_set_key_purpose_oid
1853 (crq, GNUTLS_KP_OCSP_SIGNING, 0);
1854 if (ret < 0)
1855 error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (ret));
1858 ret = get_time_stamp_status ();
1859 if (ret)
1861 ret = gnutls_x509_crq_set_key_purpose_oid
1862 (crq, GNUTLS_KP_TIME_STAMPING, 0);
1863 if (ret < 0)
1864 error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (ret));
1867 ret = get_ipsec_ike_status ();
1868 if (ret)
1870 ret = gnutls_x509_crq_set_key_purpose_oid
1871 (crq, GNUTLS_KP_IPSEC_IKE, 0);
1872 if (ret < 0)
1873 error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (ret));
1877 ret = gnutls_x509_crq_set_key_usage (crq, usage);
1878 if (ret < 0)
1879 error (EXIT_FAILURE, 0, "key_usage: %s", gnutls_strerror (ret));
1881 ret = get_tls_client_status ();
1882 if (ret != 0)
1884 ret = gnutls_x509_crq_set_key_purpose_oid
1885 (crq, GNUTLS_KP_TLS_WWW_CLIENT, 0);
1886 if (ret < 0)
1887 error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (ret));
1890 ret = get_tls_server_status ();
1891 if (ret != 0)
1893 ret = gnutls_x509_crq_set_key_purpose_oid
1894 (crq, GNUTLS_KP_TLS_WWW_SERVER, 0);
1895 if (ret < 0)
1896 error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (ret));
1900 ret = gnutls_x509_crq_set_pubkey (crq, pubkey);
1901 if (ret < 0)
1902 error (EXIT_FAILURE, 0, "set_key: %s", gnutls_strerror (ret));
1904 ret = gnutls_x509_crq_privkey_sign (crq, pkey, get_dig_for_pub (pubkey), 0);
1905 if (ret < 0)
1906 error (EXIT_FAILURE, 0, "sign: %s", gnutls_strerror (ret));
1908 print_crq_info (crq, outfile);
1910 gnutls_x509_crq_deinit (crq);
1911 gnutls_privkey_deinit( pkey);
1912 gnutls_pubkey_deinit( pubkey);
1916 static void print_verification_res (FILE* outfile, unsigned int output);
1918 static int detailed_verification(gnutls_x509_crt_t cert,
1919 gnutls_x509_crt_t issuer, gnutls_x509_crl_t crl,
1920 unsigned int verification_output)
1922 char name[512];
1923 char tmp[255];
1924 char issuer_name[512];
1925 size_t name_size;
1926 size_t issuer_name_size;
1927 int ret;
1929 issuer_name_size = sizeof (issuer_name);
1930 ret =
1931 gnutls_x509_crt_get_issuer_dn (cert, issuer_name, &issuer_name_size);
1932 if (ret < 0)
1933 error (EXIT_FAILURE, 0, "gnutls_x509_crt_get_issuer_dn: %s", gnutls_strerror (ret));
1935 name_size = sizeof (name);
1936 ret =
1937 gnutls_x509_crt_get_dn (cert, name, &name_size);
1938 if (ret < 0)
1939 error (EXIT_FAILURE, 0, "gnutls_x509_crt_get_dn: %s", gnutls_strerror (ret));
1941 fprintf (outfile, "\tSubject: %s\n", name);
1942 fprintf (outfile, "\tIssuer: %s\n", issuer_name);
1944 if (issuer != NULL)
1946 issuer_name_size = sizeof (issuer_name);
1947 ret =
1948 gnutls_x509_crt_get_dn (issuer, issuer_name, &issuer_name_size);
1949 if (ret < 0)
1950 error (EXIT_FAILURE, 0, "gnutls_x509_crt_get_issuer_dn: %s", gnutls_strerror (ret));
1952 fprintf (outfile, "\tChecked against: %s\n", issuer_name);
1955 if (crl != NULL)
1957 gnutls_datum_t data;
1959 issuer_name_size = sizeof (issuer_name);
1960 ret =
1961 gnutls_x509_crl_get_issuer_dn (crl, issuer_name, &issuer_name_size);
1962 if (ret < 0)
1963 error (EXIT_FAILURE, 0, "gnutls_x509_crl_get_issuer_dn: %s", gnutls_strerror (ret));
1965 name_size = sizeof(tmp);
1966 ret = gnutls_x509_crl_get_number(crl, tmp, &name_size, NULL);
1967 if (ret < 0)
1968 strcpy(name, "unnumbered");
1969 else
1971 data.data = (void*)tmp;
1972 data.size = name_size;
1974 name_size = sizeof(name);
1975 ret = gnutls_hex_encode(&data, name, &name_size);
1976 if (ret < 0)
1977 error (EXIT_FAILURE, 0, "gnutls_hex_encode: %s", gnutls_strerror (ret));
1979 fprintf (outfile, "\tChecked against CRL[%s] of: %s\n", name, issuer_name);
1982 fprintf (outfile, "\tOutput: ");
1983 print_verification_res(outfile, verification_output);
1985 fputs(".\n\n", outfile);
1987 return 0;
1990 /* Will verify a certificate chain. If no CA certificates
1991 * are provided, then the last certificate in the certificate
1992 * chain is used as a CA.
1994 static int
1995 _verify_x509_mem (const void *cert, int cert_size, const void* ca, int ca_size)
1997 int ret;
1998 gnutls_datum_t tmp;
1999 gnutls_x509_crt_t *x509_cert_list = NULL;
2000 gnutls_x509_crt_t *x509_ca_list = NULL;
2001 gnutls_x509_crl_t *x509_crl_list = NULL;
2002 unsigned int x509_ncerts, x509_ncrls = 0, x509_ncas = 0;
2003 gnutls_x509_trust_list_t list;
2004 unsigned int output;
2006 ret = gnutls_x509_trust_list_init(&list, 0);
2007 if (ret < 0)
2008 error (EXIT_FAILURE, 0, "gnutls_x509_trust_list_init: %s",
2009 gnutls_strerror (ret));
2011 if (ca == NULL)
2013 tmp.data = (void*)cert;
2014 tmp.size = cert_size;
2016 else
2018 tmp.data = (void*)ca;
2019 tmp.size = ca_size;
2021 /* Load CAs */
2022 ret = gnutls_x509_crt_list_import2( &x509_ca_list, &x509_ncas, &tmp,
2023 GNUTLS_X509_FMT_PEM, 0);
2024 if (ret < 0 || x509_ncas < 1)
2025 error (EXIT_FAILURE, 0, "error parsing CAs: %s",
2026 gnutls_strerror (ret));
2029 ret = gnutls_x509_crl_list_import2( &x509_crl_list, &x509_ncrls, &tmp,
2030 GNUTLS_X509_FMT_PEM, 0);
2031 if (ret < 0)
2033 x509_crl_list = NULL;
2034 x509_ncrls = 0;
2037 tmp.data = (void*)cert;
2038 tmp.size = cert_size;
2040 /* ignore errors. CRLs might not be given */
2041 ret = gnutls_x509_crt_list_import2( &x509_cert_list, &x509_ncerts, &tmp,
2042 GNUTLS_X509_FMT_PEM, 0);
2043 if (ret < 0 || x509_ncerts < 1)
2044 error (EXIT_FAILURE, 0, "error parsing CRTs: %s",
2045 gnutls_strerror (ret));
2047 if (ca == NULL)
2049 x509_ca_list = &x509_cert_list[x509_ncerts - 1];
2050 x509_ncas = 1;
2053 fprintf(stdout, "Loaded %d certificates, %d CAs and %d CRLs\n\n",
2054 x509_ncerts, x509_ncas, x509_ncrls);
2056 ret = gnutls_x509_trust_list_add_cas(list, x509_ca_list, x509_ncas, 0);
2057 if (ret < 0)
2058 error (EXIT_FAILURE, 0, "gnutls_x509_trust_add_cas: %s",
2059 gnutls_strerror (ret));
2061 ret = gnutls_x509_trust_list_add_crls(list, x509_crl_list, x509_ncrls, 0, 0);
2062 if (ret < 0)
2063 error (EXIT_FAILURE, 0, "gnutls_x509_trust_add_crls: %s",
2064 gnutls_strerror (ret));
2066 gnutls_free(x509_crl_list);
2068 ret = gnutls_x509_trust_list_verify_crt (list, x509_cert_list, x509_ncerts,
2069 GNUTLS_VERIFY_DO_NOT_ALLOW_SAME|GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT, &output,
2070 detailed_verification);
2071 if (ret < 0)
2072 error (EXIT_FAILURE, 0, "gnutls_x509_trusted_list_verify_crt: %s",
2073 gnutls_strerror (ret));
2075 fprintf (outfile, "Chain verification output: ");
2076 print_verification_res(outfile, output);
2078 fprintf (outfile, ".\n\n");
2080 gnutls_free(x509_cert_list);
2081 gnutls_x509_trust_list_deinit(list, 1);
2083 if (output != 0)
2084 exit(EXIT_FAILURE);
2086 return 0;
2089 static void
2090 print_verification_res (FILE* outfile, unsigned int output)
2092 int comma = 0;
2094 if (output & GNUTLS_CERT_INVALID)
2096 fprintf (outfile, "Not verified");
2097 comma = 1;
2099 else
2101 fprintf (outfile, "Verified");
2102 comma = 1;
2105 if (output & GNUTLS_CERT_SIGNER_NOT_CA)
2107 if (comma)
2108 fprintf (outfile, ", ");
2109 fprintf (outfile, "Issuer is not a CA");
2110 comma = 1;
2113 if (output & GNUTLS_CERT_INSECURE_ALGORITHM)
2115 if (comma)
2116 fprintf (outfile, ", ");
2117 fprintf (outfile, "Insecure algorithm");
2118 comma = 1;
2121 if (output & GNUTLS_CERT_NOT_ACTIVATED)
2123 if (comma)
2124 fprintf (outfile, ", ");
2125 fprintf (outfile, "Not activated");
2126 comma = 1;
2129 if (output & GNUTLS_CERT_EXPIRED)
2131 if (comma)
2132 fprintf (outfile, ", ");
2133 fprintf (outfile, "Expired");
2134 comma = 1;
2137 if (output & GNUTLS_CERT_REVOKED)
2139 if (comma)
2140 fprintf (outfile, ", ");
2141 fprintf (outfile, "Revoked");
2142 comma = 1;
2146 static void
2147 verify_chain (void)
2149 char *buf;
2150 size_t size;
2152 buf = (void*)fread_file (infile, &size);
2153 if (buf == NULL)
2154 error (EXIT_FAILURE, errno, "reading chain");
2156 buf[size] = 0;
2158 _verify_x509_mem (buf, size, NULL, 0);
2162 static void
2163 verify_certificate (common_info_st * cinfo)
2165 char *cert;
2166 char *cas;
2167 size_t cert_size, ca_size;
2168 FILE * ca_file = fopen(cinfo->ca, "r");
2170 if (ca_file == NULL)
2171 error (EXIT_FAILURE, errno, "opening CA file");
2173 cert = (void*)fread_file (infile, &cert_size);
2174 if (cert == NULL)
2175 error (EXIT_FAILURE, errno, "reading certificate chain");
2177 cert[cert_size] = 0;
2179 cas = (void*)fread_file (ca_file, &ca_size);
2180 if (cas == NULL)
2181 error (EXIT_FAILURE, errno, "reading CA list");
2183 cas[ca_size] = 0;
2184 fclose(ca_file);
2186 _verify_x509_mem (cert, cert_size, cas, ca_size);
2191 void
2192 verify_crl (common_info_st * cinfo)
2194 size_t size, dn_size;
2195 char dn[128];
2196 unsigned int output;
2197 int comma = 0;
2198 int ret;
2199 gnutls_datum_t pem;
2200 gnutls_x509_crl_t crl;
2201 time_t now = time (0);
2202 gnutls_x509_crt_t issuer;
2204 issuer = load_ca_cert (cinfo);
2206 fprintf (outfile, "\nCA certificate:\n");
2208 dn_size = sizeof (dn);
2209 ret = gnutls_x509_crt_get_dn (issuer, dn, &dn_size);
2210 if (ret < 0)
2211 error (EXIT_FAILURE, 0, "crt_get_dn: %s", gnutls_strerror (ret));
2213 fprintf (outfile, "\tSubject: %s\n\n", dn);
2215 ret = gnutls_x509_crl_init (&crl);
2216 if (ret < 0)
2217 error (EXIT_FAILURE, 0, "crl_init: %s", gnutls_strerror (ret));
2219 pem.data = (void*)fread_file (infile, &size);
2220 pem.size = size;
2222 ret = gnutls_x509_crl_import (crl, &pem, incert_format);
2223 free (pem.data);
2224 if (ret < 0)
2225 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (ret));
2227 print_crl_info (crl, outfile);
2229 fprintf (outfile, "Verification output: ");
2230 ret = gnutls_x509_crl_verify (crl, &issuer, 1, 0, &output);
2231 if (ret < 0)
2232 error (EXIT_FAILURE, 0, "verification error: %s", gnutls_strerror (ret));
2234 if (output & GNUTLS_CERT_INVALID)
2236 fprintf (outfile, "Not verified");
2237 comma = 1;
2239 else
2241 fprintf (outfile, "Verified");
2242 comma = 1;
2245 if (output & GNUTLS_CERT_SIGNER_NOT_CA)
2247 if (comma)
2248 fprintf (outfile, ", ");
2249 fprintf (outfile, "Issuer is not a CA");
2250 comma = 1;
2253 if (output & GNUTLS_CERT_INSECURE_ALGORITHM)
2255 if (comma)
2256 fprintf (outfile, ", ");
2257 fprintf (outfile, "Insecure algorithm");
2258 comma = 1;
2261 /* Check expiration dates.
2264 if (gnutls_x509_crl_get_this_update (crl) > now)
2266 if (comma)
2267 fprintf (outfile, ", ");
2268 comma = 1;
2269 fprintf (outfile, "Issued in the future!");
2272 if (gnutls_x509_crl_get_next_update (crl) < now)
2274 if (comma)
2275 fprintf (outfile, ", ");
2276 comma = 1;
2277 fprintf (outfile, "CRL is not up to date");
2280 fprintf (outfile, "\n");
2285 void
2286 generate_pkcs8 (common_info_st * cinfo)
2288 gnutls_x509_privkey_t key;
2289 int result;
2290 size_t size;
2291 unsigned int flags = 0;
2292 const char *password;
2294 fprintf (stderr, "Generating a PKCS #8 key structure...\n");
2296 key = load_x509_private_key (1, cinfo);
2298 password = get_password(cinfo, &flags, 1);
2300 flags |= cipher_to_flags (cinfo->pkcs_cipher);
2302 size = buffer_size;
2303 result =
2304 gnutls_x509_privkey_export_pkcs8 (key, outcert_format,
2305 password, flags, buffer, &size);
2307 if (result < 0)
2308 error (EXIT_FAILURE, 0, "key_export: %s", gnutls_strerror (result));
2310 fwrite (buffer, 1, size, outfile);
2315 #include <gnutls/pkcs12.h>
2316 #include <unistd.h>
2318 void
2319 generate_pkcs12 (common_info_st * cinfo)
2321 gnutls_pkcs12_t pkcs12;
2322 gnutls_x509_crt_t *crts;
2323 gnutls_x509_privkey_t *keys;
2324 int result;
2325 size_t size;
2326 gnutls_datum_t data;
2327 const char *pass;
2328 const char *name;
2329 unsigned int flags = 0, i;
2330 gnutls_datum_t key_id;
2331 unsigned char _key_id[32];
2332 int indx;
2333 size_t ncrts;
2334 size_t nkeys;
2336 fprintf (stderr, "Generating a PKCS #12 structure...\n");
2338 keys = load_privkey_list (0, &nkeys, cinfo);
2339 crts = load_cert_list (0, &ncrts, cinfo);
2341 name = get_pkcs12_key_name ();
2343 result = gnutls_pkcs12_init (&pkcs12);
2344 if (result < 0)
2345 error (EXIT_FAILURE, 0, "pkcs12_init: %s", gnutls_strerror (result));
2347 pass = get_password(cinfo, &flags, 1);
2348 flags |= cipher_to_flags (cinfo->pkcs_cipher);
2350 for (i = 0; i < ncrts; i++)
2352 gnutls_pkcs12_bag_t bag;
2354 result = gnutls_pkcs12_bag_init (&bag);
2355 if (result < 0)
2356 error (EXIT_FAILURE, 0, "bag_init: %s", gnutls_strerror (result));
2358 result = gnutls_pkcs12_bag_set_crt (bag, crts[i]);
2359 if (result < 0)
2360 error (EXIT_FAILURE, 0, "set_crt[%d]: %s", i,
2361 gnutls_strerror (result));
2363 indx = result;
2365 if (i==0) /* only the first certificate gets the friendly name */
2367 result = gnutls_pkcs12_bag_set_friendly_name (bag, indx, name);
2368 if (result < 0)
2369 error (EXIT_FAILURE, 0, "bag_set_friendly_name: %s",
2370 gnutls_strerror (result));
2373 size = sizeof (_key_id);
2374 result = gnutls_x509_crt_get_key_id (crts[i], 0, _key_id, &size);
2375 if (result < 0)
2376 error (EXIT_FAILURE, 0, "key_id[%d]: %s", i,
2377 gnutls_strerror (result));
2379 key_id.data = _key_id;
2380 key_id.size = size;
2382 result = gnutls_pkcs12_bag_set_key_id (bag, indx, &key_id);
2383 if (result < 0)
2384 error (EXIT_FAILURE, 0, "bag_set_key_id: %s",
2385 gnutls_strerror (result));
2387 result = gnutls_pkcs12_bag_encrypt (bag, pass, flags);
2388 if (result < 0)
2389 error (EXIT_FAILURE, 0, "bag_encrypt: %s", gnutls_strerror (result));
2391 result = gnutls_pkcs12_set_bag (pkcs12, bag);
2392 if (result < 0)
2393 error (EXIT_FAILURE, 0, "set_bag: %s", gnutls_strerror (result));
2396 for (i = 0; i < nkeys; i++)
2398 gnutls_pkcs12_bag_t kbag;
2400 result = gnutls_pkcs12_bag_init (&kbag);
2401 if (result < 0)
2402 error (EXIT_FAILURE, 0, "bag_init: %s", gnutls_strerror (result));
2404 size = buffer_size;
2405 result =
2406 gnutls_x509_privkey_export_pkcs8 (keys[i], GNUTLS_X509_FMT_DER,
2407 pass, flags, buffer, &size);
2408 if (result < 0)
2409 error (EXIT_FAILURE, 0, "key_export[%d]: %s", i, gnutls_strerror (result));
2411 data.data = buffer;
2412 data.size = size;
2413 result =
2414 gnutls_pkcs12_bag_set_data (kbag,
2415 GNUTLS_BAG_PKCS8_ENCRYPTED_KEY, &data);
2416 if (result < 0)
2417 error (EXIT_FAILURE, 0, "bag_set_data: %s", gnutls_strerror (result));
2419 indx = result;
2421 result = gnutls_pkcs12_bag_set_friendly_name (kbag, indx, name);
2422 if (result < 0)
2423 error (EXIT_FAILURE, 0, "bag_set_friendly_name: %s",
2424 gnutls_strerror (result));
2426 size = sizeof (_key_id);
2427 result = gnutls_x509_privkey_get_key_id (keys[i], 0, _key_id, &size);
2428 if (result < 0)
2429 error (EXIT_FAILURE, 0, "key_id[%d]: %s", i, gnutls_strerror (result));
2431 key_id.data = _key_id;
2432 key_id.size = size;
2434 result = gnutls_pkcs12_bag_set_key_id (kbag, indx, &key_id);
2435 if (result < 0)
2436 error (EXIT_FAILURE, 0, "bag_set_key_id: %s",
2437 gnutls_strerror (result));
2439 result = gnutls_pkcs12_set_bag (pkcs12, kbag);
2440 if (result < 0)
2441 error (EXIT_FAILURE, 0, "set_bag: %s", gnutls_strerror (result));
2444 result = gnutls_pkcs12_generate_mac (pkcs12, pass);
2445 if (result < 0)
2446 error (EXIT_FAILURE, 0, "generate_mac: %s", gnutls_strerror (result));
2448 size = buffer_size;
2449 result = gnutls_pkcs12_export (pkcs12, outcert_format, buffer, &size);
2450 if (result < 0)
2451 error (EXIT_FAILURE, 0, "pkcs12_export: %s", gnutls_strerror (result));
2453 fwrite (buffer, 1, size, outfile);
2457 static const char *
2458 BAGTYPE (gnutls_pkcs12_bag_type_t x)
2460 switch (x)
2462 case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY:
2463 return "PKCS #8 Encrypted key";
2464 case GNUTLS_BAG_EMPTY:
2465 return "Empty";
2466 case GNUTLS_BAG_PKCS8_KEY:
2467 return "PKCS #8 Key";
2468 case GNUTLS_BAG_CERTIFICATE:
2469 return "Certificate";
2470 case GNUTLS_BAG_ENCRYPTED:
2471 return "Encrypted";
2472 case GNUTLS_BAG_CRL:
2473 return "CRL";
2474 case GNUTLS_BAG_SECRET:
2475 return "Secret";
2476 default:
2477 return "Unknown";
2481 static void
2482 print_bag_data (gnutls_pkcs12_bag_t bag)
2484 int result;
2485 int count, i, type;
2486 gnutls_datum_t cdata, id;
2487 const char *str, *name;
2488 gnutls_datum_t out;
2490 count = gnutls_pkcs12_bag_get_count (bag);
2491 if (count < 0)
2492 error (EXIT_FAILURE, 0, "get_count: %s", gnutls_strerror (count));
2494 fprintf (outfile, "\tElements: %d\n", count);
2496 for (i = 0; i < count; i++)
2498 type = gnutls_pkcs12_bag_get_type (bag, i);
2499 if (type < 0)
2500 error (EXIT_FAILURE, 0, "get_type: %s", gnutls_strerror (type));
2502 fprintf (stderr, "\tType: %s\n", BAGTYPE (type));
2504 name = NULL;
2505 result = gnutls_pkcs12_bag_get_friendly_name (bag, i, (char **) &name);
2506 if (result < 0)
2507 error (EXIT_FAILURE, 0, "get_friendly_name: %s",
2508 gnutls_strerror (type));
2509 if (name)
2510 fprintf (outfile, "\tFriendly name: %s\n", name);
2512 id.data = NULL;
2513 id.size = 0;
2514 result = gnutls_pkcs12_bag_get_key_id (bag, i, &id);
2515 if (result < 0)
2516 error (EXIT_FAILURE, 0, "get_key_id: %s", gnutls_strerror (type));
2517 if (id.size > 0)
2518 fprintf (outfile, "\tKey ID: %s\n", raw_to_string (id.data, id.size));
2520 result = gnutls_pkcs12_bag_get_data (bag, i, &cdata);
2521 if (result < 0)
2522 error (EXIT_FAILURE, 0, "get_data: %s", gnutls_strerror (result));
2524 switch (type)
2526 case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY:
2527 str = "ENCRYPTED PRIVATE KEY";
2528 break;
2529 case GNUTLS_BAG_PKCS8_KEY:
2530 str = "PRIVATE KEY";
2531 break;
2532 case GNUTLS_BAG_CERTIFICATE:
2533 str = "CERTIFICATE";
2534 break;
2535 case GNUTLS_BAG_CRL:
2536 str = "CRL";
2537 break;
2538 case GNUTLS_BAG_ENCRYPTED:
2539 case GNUTLS_BAG_EMPTY:
2540 default:
2541 str = NULL;
2544 if (str != NULL)
2546 gnutls_pem_base64_encode_alloc (str, &cdata, &out);
2547 fprintf (outfile, "%s\n", out.data);
2549 gnutls_free (out.data);
2555 void
2556 pkcs12_info (common_info_st* cinfo)
2558 gnutls_pkcs12_t pkcs12;
2559 gnutls_pkcs12_bag_t bag;
2560 int result;
2561 size_t size;
2562 gnutls_datum_t data;
2563 const char *pass;
2564 int indx, fail = 0;
2566 result = gnutls_pkcs12_init (&pkcs12);
2567 if (result < 0)
2568 error (EXIT_FAILURE, 0, "p12_init: %s", gnutls_strerror (result));
2570 data.data = (void*)fread_file (infile, &size);
2571 data.size = size;
2573 result = gnutls_pkcs12_import (pkcs12, &data, incert_format, 0);
2574 free (data.data);
2575 if (result < 0)
2576 error (EXIT_FAILURE, 0, "p12_import: %s", gnutls_strerror (result));
2578 pass = get_password(cinfo, NULL, 0);
2580 result = gnutls_pkcs12_verify_mac (pkcs12, pass);
2581 if (result < 0)
2583 fail = 1;
2584 error (0, 0, "verify_mac: %s", gnutls_strerror (result));
2587 for (indx = 0;; indx++)
2589 result = gnutls_pkcs12_bag_init (&bag);
2590 if (result < 0)
2591 error (EXIT_FAILURE, 0, "bag_init: %s", gnutls_strerror (result));
2593 result = gnutls_pkcs12_get_bag (pkcs12, indx, bag);
2594 if (result < 0)
2595 break;
2597 result = gnutls_pkcs12_bag_get_count (bag);
2598 if (result < 0)
2599 error (EXIT_FAILURE, 0, "bag_count: %s", gnutls_strerror (result));
2601 fprintf (outfile, "BAG #%d\n", indx);
2603 result = gnutls_pkcs12_bag_get_type (bag, 0);
2604 if (result < 0)
2605 error (EXIT_FAILURE, 0, "bag_init: %s", gnutls_strerror (result));
2607 if (result == GNUTLS_BAG_ENCRYPTED)
2609 fprintf (stderr, "\tType: %s\n", BAGTYPE (result));
2610 fprintf (stderr, "\n\tDecrypting...\n");
2612 result = gnutls_pkcs12_bag_decrypt (bag, pass);
2614 if (result < 0)
2616 fail = 1;
2617 error (0, 0, "bag_decrypt: %s", gnutls_strerror (result));
2618 continue;
2621 result = gnutls_pkcs12_bag_get_count (bag);
2622 if (result < 0)
2623 error (EXIT_FAILURE, 0, "encrypted bag_count: %s",
2624 gnutls_strerror (result));
2627 print_bag_data (bag);
2629 gnutls_pkcs12_bag_deinit (bag);
2632 if (fail)
2633 error (EXIT_FAILURE, 0, "There were errors parsing the structure\n");
2636 void
2637 pkcs7_info (void)
2639 gnutls_pkcs7_t pkcs7;
2640 int result;
2641 size_t size;
2642 gnutls_datum_t data, b64;
2643 int indx, count;
2645 result = gnutls_pkcs7_init (&pkcs7);
2646 if (result < 0)
2647 error (EXIT_FAILURE, 0, "p7_init: %s", gnutls_strerror (result));
2649 data.data = (void*)fread_file (infile, &size);
2650 data.size = size;
2652 result = gnutls_pkcs7_import (pkcs7, &data, incert_format);
2653 free (data.data);
2654 if (result < 0)
2655 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (result));
2657 /* Read and print the certificates.
2659 result = gnutls_pkcs7_get_crt_count (pkcs7);
2660 if (result < 0)
2661 error (EXIT_FAILURE, 0, "p7_crt_count: %s", gnutls_strerror (result));
2663 count = result;
2665 if (count > 0)
2666 fprintf (outfile, "Number of certificates: %u\n", count);
2668 for (indx = 0; indx < count; indx++)
2670 fputs ("\n", outfile);
2672 size = buffer_size;
2673 result = gnutls_pkcs7_get_crt_raw (pkcs7, indx, buffer, &size);
2674 if (result < 0)
2675 break;
2677 data.data = buffer;
2678 data.size = size;
2680 result = gnutls_pem_base64_encode_alloc ("CERTIFICATE", &data, &b64);
2681 if (result < 0)
2682 error (EXIT_FAILURE, 0, "encoding: %s", gnutls_strerror (result));
2684 fputs ((void*)b64.data, outfile);
2685 gnutls_free (b64.data);
2688 /* Read the CRLs now.
2690 result = gnutls_pkcs7_get_crl_count (pkcs7);
2691 if (result < 0)
2692 error (EXIT_FAILURE, 0, "p7_crl_count: %s", gnutls_strerror (result));
2694 count = result;
2696 if (count > 0)
2697 fprintf (outfile, "\nNumber of CRLs: %u\n", count);
2699 for (indx = 0; indx < count; indx++)
2701 fputs ("\n", outfile);
2703 size = buffer_size;
2704 result = gnutls_pkcs7_get_crl_raw (pkcs7, indx, buffer, &size);
2705 if (result < 0)
2706 break;
2708 data.data = buffer;
2709 data.size = size;
2711 result = gnutls_pem_base64_encode_alloc ("X509 CRL", &data, &b64);
2712 if (result < 0)
2713 error (EXIT_FAILURE, 0, "encoding: %s", gnutls_strerror (result));
2715 fputs ((void*)b64.data, outfile);
2716 gnutls_free (b64.data);
2720 void
2721 smime_to_pkcs7 (void)
2723 size_t linesize = 0;
2724 char *lineptr = NULL;
2725 ssize_t len;
2727 /* Find body. FIXME: Handle non-b64 Content-Transfer-Encoding.
2728 Reject non-S/MIME tagged Content-Type's? */
2731 len = getline (&lineptr, &linesize, infile);
2732 if (len == -1)
2733 error (EXIT_FAILURE, 0, "cannot find RFC 2822 header/body separator");
2735 while (strcmp (lineptr, "\r\n") != 0 && strcmp (lineptr, "\n") != 0);
2739 len = getline (&lineptr, &linesize, infile);
2740 if (len == -1)
2741 error (EXIT_FAILURE, 0, "message has RFC 2822 header but no body");
2743 while (strcmp (lineptr, "\r\n") == 0 && strcmp (lineptr, "\n") == 0);
2745 fprintf (outfile, "%s", "-----BEGIN PKCS7-----\n");
2749 while (len > 0
2750 && (lineptr[len - 1] == '\r' || lineptr[len - 1] == '\n'))
2751 lineptr[--len] = '\0';
2752 if (strcmp (lineptr, "") != 0)
2753 fprintf (outfile, "%s\n", lineptr);
2754 len = getline (&lineptr, &linesize, infile);
2756 while (len != -1);
2758 fprintf (outfile, "%s", "-----END PKCS7-----\n");
2760 free (lineptr);
2764 void
2765 pubkey_info (gnutls_x509_crt_t crt, common_info_st * cinfo)
2767 gnutls_pubkey_t pubkey;
2768 int ret;
2769 size_t size;
2771 ret = gnutls_pubkey_init (&pubkey);
2772 if (ret < 0)
2774 error (EXIT_FAILURE, 0, "pubkey_init: %s", gnutls_strerror (ret));
2777 if (crt == NULL)
2779 crt = load_cert (0, cinfo);
2782 if (crt != NULL)
2784 ret = gnutls_pubkey_import_x509 (pubkey, crt, 0);
2785 if (ret < 0)
2787 error (EXIT_FAILURE, 0, "pubkey_import_x509: %s",
2788 gnutls_strerror (ret));
2791 else
2793 pubkey = load_pubkey (1, cinfo);
2796 if (outcert_format == GNUTLS_X509_FMT_DER)
2798 size = buffer_size;
2799 ret = gnutls_pubkey_export (pubkey, outcert_format, buffer, &size);
2800 if (ret < 0)
2801 error (EXIT_FAILURE, 0, "export error: %s", gnutls_strerror (ret));
2803 fwrite (buffer, 1, size, outfile);
2805 gnutls_pubkey_deinit (pubkey);
2807 return;
2810 /* PEM */
2812 _pubkey_info(outfile, pubkey);
2813 gnutls_pubkey_deinit (pubkey);