Certtool exports multiple keys in PKCS12 file
[gnutls.git] / src / certtool.c
blob62262b759207a4fe228fedd009bc2bb1b9425544
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 <p11common.h>
49 #include "certtool-args.h"
50 #include "certtool-common.h"
52 #define SIGN_HASH GNUTLS_DIG_SHA256
54 static void privkey_info_int (common_info_st*, gnutls_x509_privkey_t key);
55 static void print_crl_info (gnutls_x509_crl_t crl, FILE * out);
56 void pkcs7_info (void);
57 void crq_info (void);
58 void smime_to_pkcs7 (void);
59 void pkcs12_info (common_info_st*);
60 void generate_pkcs12 (common_info_st *);
61 void generate_pkcs8 (common_info_st *);
62 static void verify_chain (void);
63 void verify_crl (common_info_st * cinfo);
64 void pubkey_info (gnutls_x509_crt_t crt, common_info_st *);
65 void pgp_privkey_info (void);
66 void pgp_ring_info (void);
67 void certificate_info (int, common_info_st *);
68 void pgp_certificate_info (void);
69 void crl_info (void);
70 void privkey_info (common_info_st*);
71 static void cmd_parser (int argc, char **argv);
72 void generate_self_signed (common_info_st *);
73 void generate_request (common_info_st *);
74 static void print_certificate_info (gnutls_x509_crt_t crt, FILE * out,
75 unsigned int all);
76 static void verify_certificate (common_info_st * cinfo);
78 static void print_hex_datum (gnutls_datum_t * dat);
80 FILE *outfile;
81 FILE *infile;
82 static gnutls_digest_algorithm_t default_dig;
83 static unsigned int incert_format, outcert_format;
84 static unsigned int req_key_type;
86 /* non interactive operation if set
88 int batch;
91 static void
92 tls_log_func (int level, const char *str)
94 fprintf (stderr, "|<%d>| %s", level, str);
97 int
98 main (int argc, char **argv)
100 set_program_name (argv[0]);
101 cfg_init ();
102 cmd_parser (argc, argv);
104 return 0;
107 static const char *
108 raw_to_string (const unsigned char *raw, size_t raw_size)
110 static char buf[1024];
111 size_t i;
112 if (raw_size == 0)
113 return NULL;
115 if (raw_size * 3 + 1 >= sizeof (buf))
116 return NULL;
118 for (i = 0; i < raw_size; i++)
120 sprintf (&(buf[i * 3]), "%02X%s", raw[i],
121 (i == raw_size - 1) ? "" : ":");
123 buf[sizeof (buf) - 1] = '\0';
125 return buf;
128 static void
129 print_dsa_pkey (gnutls_datum_t * x, gnutls_datum_t * y, gnutls_datum_t * p,
130 gnutls_datum_t * q, gnutls_datum_t * g)
132 if (x)
134 fprintf (outfile, "private key:");
135 print_hex_datum (x);
137 fprintf (outfile, "public key:");
138 print_hex_datum (y);
139 fprintf (outfile, "p:");
140 print_hex_datum (p);
141 fprintf (outfile, "q:");
142 print_hex_datum (q);
143 fprintf (outfile, "g:");
144 print_hex_datum (g);
147 static void
148 print_ecc_pkey (gnutls_ecc_curve_t curve, gnutls_datum_t* k, gnutls_datum_t * x, gnutls_datum_t * y)
150 fprintf (outfile, "curve:\t%s\n", gnutls_ecc_curve_get_name(curve));
151 if (k)
153 fprintf (outfile, "private key:");
154 print_hex_datum (k);
156 fprintf (outfile, "x:");
157 print_hex_datum (x);
158 fprintf (outfile, "y:");
159 print_hex_datum (y);
162 static void
163 print_rsa_pkey (gnutls_datum_t * m, gnutls_datum_t * e, gnutls_datum_t * d,
164 gnutls_datum_t * p, gnutls_datum_t * q, gnutls_datum_t * u,
165 gnutls_datum_t * exp1, gnutls_datum_t * exp2)
167 fprintf (outfile, "modulus:");
168 print_hex_datum (m);
169 fprintf (outfile, "public exponent:");
170 print_hex_datum (e);
171 if (d)
173 fprintf (outfile, "private exponent:");
174 print_hex_datum (d);
175 fprintf (outfile, "prime1:");
176 print_hex_datum (p);
177 fprintf (outfile, "prime2:");
178 print_hex_datum (q);
179 fprintf (outfile, "coefficient:");
180 print_hex_datum (u);
181 if (exp1 && exp2)
183 fprintf (outfile, "exp1:");
184 print_hex_datum (exp1);
185 fprintf (outfile, "exp2:");
186 print_hex_datum (exp2);
191 static gnutls_x509_privkey_t
192 generate_private_key_int (common_info_st * cinfo)
194 gnutls_x509_privkey_t key;
195 int ret, key_type, bits;
197 key_type = req_key_type;
199 ret = gnutls_x509_privkey_init (&key);
200 if (ret < 0)
201 error (EXIT_FAILURE, 0, "privkey_init: %s", gnutls_strerror (ret));
203 bits = get_bits (key_type, cinfo->bits, cinfo->sec_param);
205 fprintf (stderr, "Generating a %d bit %s private key...\n",
206 bits, gnutls_pk_algorithm_get_name (key_type));
208 if (bits > 1024 && key_type == GNUTLS_PK_DSA)
209 fprintf (stderr,
210 "Note that DSA keys with size over 1024 can only be used with TLS 1.2 or later.\n\n");
212 ret = gnutls_x509_privkey_generate (key, key_type, bits, 0);
213 if (ret < 0)
214 error (EXIT_FAILURE, 0, "privkey_generate: %s", gnutls_strerror (ret));
216 ret = gnutls_x509_privkey_verify_params (key);
217 if (ret < 0)
218 error (EXIT_FAILURE, 0, "privkey_verify_params: %s", gnutls_strerror (ret));
220 return key;
223 static int
224 cipher_to_flags (const char *cipher)
226 if (cipher == NULL)
228 return GNUTLS_PKCS_USE_PBES2_AES_128;
230 else if (strcasecmp (cipher, "3des") == 0)
232 return GNUTLS_PKCS_USE_PBES2_3DES;
234 else if (strcasecmp (cipher, "3des-pkcs12") == 0)
236 return GNUTLS_PKCS_USE_PKCS12_3DES;
238 else if (strcasecmp (cipher, "arcfour") == 0)
240 return GNUTLS_PKCS_USE_PKCS12_ARCFOUR;
242 else if (strcasecmp (cipher, "aes-128") == 0)
244 return GNUTLS_PKCS_USE_PBES2_AES_128;
246 else if (strcasecmp (cipher, "aes-192") == 0)
248 return GNUTLS_PKCS_USE_PBES2_AES_192;
250 else if (strcasecmp (cipher, "aes-256") == 0)
252 return GNUTLS_PKCS_USE_PBES2_AES_256;
254 else if (strcasecmp (cipher, "rc2-40") == 0)
256 return GNUTLS_PKCS_USE_PKCS12_RC2_40;
259 error (EXIT_FAILURE, 0, "unknown cipher %s\n", cipher);
260 return -1;
264 static void
265 print_private_key (common_info_st* cinfo, gnutls_x509_privkey_t key)
267 int ret;
268 size_t size;
270 if (!key)
271 return;
273 if (outcert_format == GNUTLS_X509_FMT_PEM)
274 privkey_info_int(cinfo, key);
276 if (!cinfo->pkcs8)
278 size = buffer_size;
279 ret = gnutls_x509_privkey_export (key, outcert_format,
280 buffer, &size);
281 if (ret < 0)
282 error (EXIT_FAILURE, 0, "privkey_export: %s", gnutls_strerror (ret));
284 else
286 unsigned int flags;
287 const char *pass;
289 flags = cipher_to_flags (cinfo->pkcs_cipher);
291 if ((pass = get_confirmed_pass (true)) == NULL || *pass == '\0')
292 flags = GNUTLS_PKCS_PLAIN;
294 size = buffer_size;
295 ret =
296 gnutls_x509_privkey_export_pkcs8 (key, outcert_format, pass,
297 flags, buffer, &size);
298 if (ret < 0)
299 error (EXIT_FAILURE, 0, "privkey_export_pkcs8: %s",
300 gnutls_strerror (ret));
303 fwrite (buffer, 1, size, outfile);
306 static void
307 generate_private_key (common_info_st* cinfo)
309 gnutls_x509_privkey_t key;
311 key = generate_private_key_int (cinfo);
313 print_private_key (cinfo, key);
315 gnutls_x509_privkey_deinit (key);
319 static gnutls_x509_crt_t
320 generate_certificate (gnutls_privkey_t * ret_key,
321 gnutls_x509_crt_t ca_crt, int proxy,
322 common_info_st * cinfo)
324 gnutls_x509_crt_t crt;
325 gnutls_privkey_t key = NULL;
326 gnutls_pubkey_t pubkey;
327 size_t size;
328 int ret;
329 int client;
330 int days, result, ca_status = 0, is_ike = 0, path_len;
331 int vers;
332 unsigned int usage = 0, server;
333 gnutls_x509_crq_t crq; /* request */
335 ret = gnutls_x509_crt_init (&crt);
336 if (ret < 0)
337 error (EXIT_FAILURE, 0, "crt_init: %s", gnutls_strerror (ret));
339 crq = load_request (cinfo);
341 if (crq == NULL)
344 key = load_private_key (1, cinfo);
346 pubkey = load_public_key_or_import (1, key, cinfo);
348 if (!batch)
349 fprintf (stderr,
350 "Please enter the details of the certificate's distinguished name. "
351 "Just press enter to ignore a field.\n");
353 /* set the DN.
355 if (proxy)
357 result = gnutls_x509_crt_set_proxy_dn (crt, ca_crt, 0, NULL, 0);
358 if (result < 0)
359 error (EXIT_FAILURE, 0, "set_proxy_dn: %s",
360 gnutls_strerror (result));
362 get_cn_crt_set (crt);
364 else
366 get_country_crt_set (crt);
367 get_organization_crt_set (crt);
368 get_unit_crt_set (crt);
369 get_locality_crt_set (crt);
370 get_state_crt_set (crt);
371 get_cn_crt_set (crt);
372 get_dc_set (TYPE_CRT, crt);
373 get_uid_crt_set (crt);
374 get_oid_crt_set (crt);
375 get_key_purpose_set (crt);
377 if (!batch)
378 fprintf (stderr,
379 "This field should not be used in new certificates.\n");
381 get_pkcs9_email_crt_set (crt);
384 result = gnutls_x509_crt_set_pubkey (crt, pubkey);
385 if (result < 0)
386 error (EXIT_FAILURE, 0, "set_key: %s", gnutls_strerror (result));
388 else
390 result = gnutls_x509_crt_set_crq (crt, crq);
391 if (result < 0)
392 error (EXIT_FAILURE, 0, "set_crq: %s", gnutls_strerror (result));
397 int serial = get_serial ();
398 char bin_serial[5];
400 bin_serial[4] = serial & 0xff;
401 bin_serial[3] = (serial >> 8) & 0xff;
402 bin_serial[2] = (serial >> 16) & 0xff;
403 bin_serial[1] = (serial >> 24) & 0xff;
404 bin_serial[0] = 0;
406 result = gnutls_x509_crt_set_serial (crt, bin_serial, 5);
407 if (result < 0)
408 error (EXIT_FAILURE, 0, "serial: %s", gnutls_strerror (result));
411 if (!batch)
412 fprintf (stderr, "\n\nActivation/Expiration time.\n");
414 gnutls_x509_crt_set_activation_time (crt, time (NULL));
416 days = get_days ();
418 result =
419 gnutls_x509_crt_set_expiration_time (crt,
420 time (NULL) + ((time_t) days) * 24 * 60 * 60);
421 if (result < 0)
422 error (EXIT_FAILURE, 0, "set_expiration: %s", gnutls_strerror (result));
424 if (!batch)
425 fprintf (stderr, "\n\nExtensions.\n");
427 /* do not allow extensions on a v1 certificate */
428 if (crq && get_crq_extensions_status () != 0)
430 result = gnutls_x509_crt_set_crq_extensions (crt, crq);
431 if (result < 0)
432 error (EXIT_FAILURE, 0, "set_crq: %s", gnutls_strerror (result));
435 /* append additional extensions */
436 if (cinfo->v1_cert == 0)
439 if (proxy)
441 const char *policylanguage;
442 char *policy;
443 size_t policylen;
444 int proxypathlen = get_path_len ();
446 if (!batch)
448 printf ("1.3.6.1.5.5.7.21.1 ::= id-ppl-inheritALL\n");
449 printf ("1.3.6.1.5.5.7.21.2 ::= id-ppl-independent\n");
452 policylanguage = get_proxy_policy (&policy, &policylen);
454 result =
455 gnutls_x509_crt_set_proxy (crt, proxypathlen, policylanguage,
456 policy, policylen);
457 if (result < 0)
458 error (EXIT_FAILURE, 0, "set_proxy: %s",
459 gnutls_strerror (result));
462 if (!proxy)
463 ca_status = get_ca_status ();
464 if (ca_status)
465 path_len = get_path_len ();
466 else
467 path_len = -1;
469 result =
470 gnutls_x509_crt_set_basic_constraints (crt, ca_status, path_len);
471 if (result < 0)
472 error (EXIT_FAILURE, 0, "basic_constraints: %s",
473 gnutls_strerror (result));
475 client = get_tls_client_status ();
476 if (client != 0)
478 result = gnutls_x509_crt_set_key_purpose_oid (crt,
479 GNUTLS_KP_TLS_WWW_CLIENT,
481 if (result < 0)
482 error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (result));
485 is_ike = get_ipsec_ike_status ();
486 server = get_tls_server_status ();
488 get_dns_name_set (TYPE_CRT, crt);
489 get_uri_set (TYPE_CRT, crt);
490 get_ip_addr_set (TYPE_CRT, crt);
492 if (server != 0)
494 result = 0;
496 result =
497 gnutls_x509_crt_set_key_purpose_oid (crt,
498 GNUTLS_KP_TLS_WWW_SERVER, 0);
499 if (result < 0)
500 error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (result));
502 else if (!proxy)
504 get_email_set (TYPE_CRT, crt);
507 if (!ca_status || server)
509 int pk;
512 pk = gnutls_x509_crt_get_pk_algorithm (crt, NULL);
514 if (pk != GNUTLS_PK_DSA)
515 { /* DSA keys can only sign.
517 result = get_sign_status (server);
518 if (result)
519 usage |= GNUTLS_KEY_DIGITAL_SIGNATURE;
521 result = get_encrypt_status (server);
522 if (result)
523 usage |= GNUTLS_KEY_KEY_ENCIPHERMENT;
525 else
526 usage |= GNUTLS_KEY_DIGITAL_SIGNATURE;
528 if (is_ike)
530 result =
531 gnutls_x509_crt_set_key_purpose_oid (crt,
532 GNUTLS_KP_IPSEC_IKE, 0);
533 if (result < 0)
534 error (EXIT_FAILURE, 0, "key_kp: %s",
535 gnutls_strerror (result));
540 if (ca_status)
542 result = get_cert_sign_status ();
543 if (result)
544 usage |= GNUTLS_KEY_KEY_CERT_SIGN;
546 result = get_crl_sign_status ();
547 if (result)
548 usage |= GNUTLS_KEY_CRL_SIGN;
550 result = get_code_sign_status ();
551 if (result)
553 result =
554 gnutls_x509_crt_set_key_purpose_oid (crt,
555 GNUTLS_KP_CODE_SIGNING,
557 if (result < 0)
558 error (EXIT_FAILURE, 0, "key_kp: %s",
559 gnutls_strerror (result));
562 result = get_ocsp_sign_status ();
563 if (result)
565 result =
566 gnutls_x509_crt_set_key_purpose_oid (crt,
567 GNUTLS_KP_OCSP_SIGNING,
569 if (result < 0)
570 error (EXIT_FAILURE, 0, "key_kp: %s",
571 gnutls_strerror (result));
574 result = get_time_stamp_status ();
575 if (result)
577 result =
578 gnutls_x509_crt_set_key_purpose_oid (crt,
579 GNUTLS_KP_TIME_STAMPING,
581 if (result < 0)
582 error (EXIT_FAILURE, 0, "key_kp: %s",
583 gnutls_strerror (result));
586 get_ocsp_issuer_set(crt);
587 get_ca_issuers_set(crt);
589 if (usage != 0)
591 /* http://tools.ietf.org/html/rfc4945#section-5.1.3.2: if any KU is
592 set, then either digitalSignature or the nonRepudiation bits in the
593 KeyUsage extension MUST for all IKE certs */
594 if (is_ike && (get_sign_status (server) != 1))
595 usage |= GNUTLS_KEY_NON_REPUDIATION;
596 result = gnutls_x509_crt_set_key_usage (crt, usage);
597 if (result < 0)
598 error (EXIT_FAILURE, 0, "key_usage: %s",
599 gnutls_strerror (result));
602 /* Subject Key ID.
604 size = buffer_size;
605 result = gnutls_x509_crt_get_key_id (crt, 0, buffer, &size);
606 if (result >= 0)
608 result = gnutls_x509_crt_set_subject_key_id (crt, buffer, size);
609 if (result < 0)
610 error (EXIT_FAILURE, 0, "set_subject_key_id: %s",
611 gnutls_strerror (result));
614 /* Authority Key ID.
616 if (ca_crt != NULL)
618 size = buffer_size;
619 result = gnutls_x509_crt_get_subject_key_id (ca_crt, buffer,
620 &size, NULL);
621 if (result < 0)
623 size = buffer_size;
624 result = gnutls_x509_crt_get_key_id (ca_crt, 0, buffer, &size);
626 if (result >= 0)
628 result =
629 gnutls_x509_crt_set_authority_key_id (crt, buffer, size);
630 if (result < 0)
631 error (EXIT_FAILURE, 0, "set_authority_key_id: %s",
632 gnutls_strerror (result));
637 /* Version.
639 if (cinfo->v1_cert != 0)
640 vers = 1;
641 else
642 vers = 3;
643 result = gnutls_x509_crt_set_version (crt, vers);
644 if (result < 0)
645 error (EXIT_FAILURE, 0, "set_version: %s", gnutls_strerror (result));
647 *ret_key = key;
648 return crt;
652 static gnutls_x509_crl_t
653 generate_crl (gnutls_x509_crt_t ca_crt, common_info_st * cinfo)
655 gnutls_x509_crl_t crl;
656 gnutls_x509_crt_t *crts;
657 size_t size;
658 int days, result;
659 unsigned int i;
660 time_t now = time (NULL);
662 result = gnutls_x509_crl_init (&crl);
663 if (result < 0)
664 error (EXIT_FAILURE, 0, "crl_init: %s", gnutls_strerror (result));
666 crts = load_cert_list (0, &size, cinfo);
668 for (i = 0; i < size; i++)
670 result = gnutls_x509_crl_set_crt (crl, crts[i], now);
671 if (result < 0)
672 error (EXIT_FAILURE, 0, "crl_set_crt: %s", gnutls_strerror (result));
675 result = gnutls_x509_crl_set_this_update (crl, now);
676 if (result < 0)
677 error (EXIT_FAILURE, 0, "this_update: %s", gnutls_strerror (result));
679 fprintf (stderr, "Update times.\n");
680 days = get_crl_next_update ();
682 result = gnutls_x509_crl_set_next_update (crl, now + days * 24 * 60 * 60);
683 if (result < 0)
684 error (EXIT_FAILURE, 0, "next_update: %s", gnutls_strerror (result));
686 result = gnutls_x509_crl_set_version (crl, 2);
687 if (result < 0)
688 error (EXIT_FAILURE, 0, "set_version: %s", gnutls_strerror (result));
690 /* Authority Key ID.
692 if (ca_crt != NULL)
694 size = buffer_size;
695 result = gnutls_x509_crt_get_subject_key_id (ca_crt, buffer,
696 &size, NULL);
697 if (result < 0)
699 size = buffer_size;
700 result = gnutls_x509_crt_get_key_id (ca_crt, 0, buffer, &size);
702 if (result >= 0)
704 result = gnutls_x509_crl_set_authority_key_id (crl, buffer, size);
705 if (result < 0)
706 error (EXIT_FAILURE, 0, "set_authority_key_id: %s",
707 gnutls_strerror (result));
712 unsigned int number = get_crl_number ();
713 char bin_number[5];
715 bin_number[4] = number & 0xff;
716 bin_number[3] = (number >> 8) & 0xff;
717 bin_number[2] = (number >> 16) & 0xff;
718 bin_number[1] = (number >> 24) & 0xff;
719 bin_number[0] = 0;
721 result = gnutls_x509_crl_set_number (crl, bin_number, 5);
722 if (result < 0)
723 error (EXIT_FAILURE, 0, "set_number: %s", gnutls_strerror (result));
726 return crl;
729 static gnutls_digest_algorithm_t
730 get_dig (gnutls_x509_crt_t crt)
732 gnutls_digest_algorithm_t dig;
733 gnutls_pubkey_t pubkey;
734 int result;
735 unsigned int mand;
737 gnutls_pubkey_init(&pubkey);
739 result = gnutls_pubkey_import_x509(pubkey, crt, 0);
740 if (result < 0)
742 error (EXIT_FAILURE, 0, "gnutls_pubkey_import_x509: %s",
743 gnutls_strerror (result));
746 result = gnutls_pubkey_get_preferred_hash_algorithm (pubkey, &dig, &mand);
747 if (result < 0)
749 error (EXIT_FAILURE, 0, "crt_get_preferred_hash_algorithm: %s",
750 gnutls_strerror (result));
753 gnutls_pubkey_deinit(pubkey);
755 /* if algorithm allows alternatives */
756 if (mand == 0 && default_dig != GNUTLS_DIG_UNKNOWN)
757 dig = default_dig;
759 return dig;
762 void
763 generate_self_signed (common_info_st * cinfo)
765 gnutls_x509_crt_t crt;
766 gnutls_privkey_t key;
767 size_t size;
768 int result;
769 const char *uri;
771 fprintf (stderr, "Generating a self signed certificate...\n");
773 crt = generate_certificate (&key, NULL, 0, cinfo);
775 if (!key)
776 key = load_private_key (1, cinfo);
778 uri = get_crl_dist_point_url ();
779 if (uri)
781 result = gnutls_x509_crt_set_crl_dist_points (crt, GNUTLS_SAN_URI,
782 uri,
783 0 /* all reasons */ );
784 if (result < 0)
785 error (EXIT_FAILURE, 0, "crl_dist_points: %s",
786 gnutls_strerror (result));
789 print_certificate_info (crt, stderr, 0);
791 fprintf (stderr, "\n\nSigning certificate...\n");
793 result = gnutls_x509_crt_privkey_sign (crt, crt, key, get_dig (crt), 0);
794 if (result < 0)
795 error (EXIT_FAILURE, 0, "crt_sign: %s", gnutls_strerror (result));
797 size = buffer_size;
798 result = gnutls_x509_crt_export (crt, outcert_format, buffer, &size);
799 if (result < 0)
800 error (EXIT_FAILURE, 0, "crt_export: %s", gnutls_strerror (result));
802 fwrite (buffer, 1, size, outfile);
804 gnutls_x509_crt_deinit (crt);
805 gnutls_privkey_deinit (key);
808 static void
809 generate_signed_certificate (common_info_st * cinfo)
811 gnutls_x509_crt_t crt;
812 gnutls_privkey_t key;
813 size_t size;
814 int result;
815 gnutls_privkey_t ca_key;
816 gnutls_x509_crt_t ca_crt;
818 fprintf (stderr, "Generating a signed certificate...\n");
820 ca_key = load_ca_private_key (cinfo);
821 ca_crt = load_ca_cert (cinfo);
823 crt = generate_certificate (&key, ca_crt, 0, cinfo);
825 /* Copy the CRL distribution points.
827 gnutls_x509_crt_cpy_crl_dist_points (crt, ca_crt);
828 /* it doesn't matter if we couldn't copy the CRL dist points.
831 print_certificate_info (crt, stderr, 0);
833 fprintf (stderr, "\n\nSigning certificate...\n");
835 result = gnutls_x509_crt_privkey_sign (crt, ca_crt, ca_key, get_dig (ca_crt), 0);
836 if (result < 0)
837 error (EXIT_FAILURE, 0, "crt_sign: %s", gnutls_strerror (result));
839 size = buffer_size;
840 result = gnutls_x509_crt_export (crt, outcert_format, buffer, &size);
841 if (result < 0)
842 error (EXIT_FAILURE, 0, "crt_export: %s", gnutls_strerror (result));
844 fwrite (buffer, 1, size, outfile);
846 gnutls_x509_crt_deinit (crt);
847 gnutls_privkey_deinit (key);
848 gnutls_privkey_deinit(ca_key);
851 static void
852 generate_proxy_certificate (common_info_st * cinfo)
854 gnutls_x509_crt_t crt, eecrt;
855 gnutls_privkey_t key, eekey;
856 size_t size;
857 int result;
859 fprintf (stderr, "Generating a proxy certificate...\n");
861 eekey = load_ca_private_key (cinfo);
862 eecrt = load_cert (1, cinfo);
864 crt = generate_certificate (&key, eecrt, 1, cinfo);
866 print_certificate_info (crt, stderr, 0);
868 fprintf (stderr, "\n\nSigning certificate...\n");
870 result = gnutls_x509_crt_privkey_sign (crt, eecrt, eekey, get_dig (eecrt), 0);
871 if (result < 0)
872 error (EXIT_FAILURE, 0, "crt_sign: %s", gnutls_strerror (result));
874 size = buffer_size;
875 result = gnutls_x509_crt_export (crt, outcert_format, buffer, &size);
876 if (result < 0)
877 error (EXIT_FAILURE, 0, "crt_export: %s", gnutls_strerror (result));
879 fwrite (buffer, 1, size, outfile);
881 gnutls_x509_crt_deinit (eecrt);
882 gnutls_x509_crt_deinit (crt);
883 gnutls_privkey_deinit (key);
884 gnutls_privkey_deinit (eekey);
887 static void
888 generate_signed_crl (common_info_st * cinfo)
890 gnutls_x509_crl_t crl;
891 int result;
892 gnutls_privkey_t ca_key;
893 gnutls_x509_crt_t ca_crt;
895 fprintf (stderr, "Generating a signed CRL...\n");
897 ca_key = load_ca_private_key (cinfo);
898 ca_crt = load_ca_cert (cinfo);
899 crl = generate_crl (ca_crt, cinfo);
901 fprintf (stderr, "\n");
902 result = gnutls_x509_crl_privkey_sign(crl, ca_crt, ca_key, SIGN_HASH, 0);
903 if (result < 0)
904 error (EXIT_FAILURE, 0, "crl_privkey_sign: %s", gnutls_strerror (result));
906 print_crl_info (crl, stderr);
908 gnutls_privkey_deinit( ca_key);
909 gnutls_x509_crl_deinit (crl);
912 static void
913 update_signed_certificate (common_info_st * cinfo)
915 gnutls_x509_crt_t crt;
916 size_t size;
917 int result;
918 gnutls_privkey_t ca_key;
919 gnutls_x509_crt_t ca_crt;
920 int days;
921 time_t tim = time (NULL);
923 fprintf (stderr, "Generating a signed certificate...\n");
925 ca_key = load_ca_private_key (cinfo);
926 ca_crt = load_ca_cert (cinfo);
927 crt = load_cert (1, cinfo);
929 fprintf (stderr, "Activation/Expiration time.\n");
930 gnutls_x509_crt_set_activation_time (crt, tim);
932 days = get_days ();
934 result =
935 gnutls_x509_crt_set_expiration_time (crt, tim + ((time_t) days) * 24 * 60 * 60);
936 if (result < 0)
937 error (EXIT_FAILURE, 0, "set_expiration: %s", gnutls_strerror (result));
939 fprintf (stderr, "\n\nSigning certificate...\n");
941 result = gnutls_x509_crt_privkey_sign (crt, ca_crt, ca_key, get_dig (ca_crt), 0);
942 if (result < 0)
943 error (EXIT_FAILURE, 0, "crt_sign: %s", gnutls_strerror (result));
945 size = buffer_size;
946 result = gnutls_x509_crt_export (crt, outcert_format, buffer, &size);
947 if (result < 0)
948 error (EXIT_FAILURE, 0, "crt_export: %s", gnutls_strerror (result));
950 fwrite (buffer, 1, size, outfile);
952 gnutls_x509_crt_deinit (crt);
955 static void
956 cmd_parser (int argc, char **argv)
958 int ret, privkey_op = 0;
959 common_info_st cinfo;
961 optionProcess( &certtoolOptions, argc, argv);
963 if (HAVE_OPT(GENERATE_PRIVKEY) || HAVE_OPT(GENERATE_REQUEST) ||
964 HAVE_OPT(KEY_INFO) || HAVE_OPT(PGP_KEY_INFO))
965 privkey_op = 1;
967 if (HAVE_OPT(OUTFILE))
969 outfile = safe_open_rw (OPT_ARG(OUTFILE), privkey_op);
970 if (outfile == NULL)
971 error (EXIT_FAILURE, errno, "%s", OPT_ARG(OUTFILE));
973 else
974 outfile = stdout;
976 if (HAVE_OPT(INFILE))
978 infile = fopen (OPT_ARG(INFILE), "rb");
979 if (infile == NULL)
980 error (EXIT_FAILURE, errno, "%s", OPT_ARG(INFILE));
982 else
983 infile = stdin;
985 if (HAVE_OPT(INDER) || HAVE_OPT(INRAW))
986 incert_format = GNUTLS_X509_FMT_DER;
987 else
988 incert_format = GNUTLS_X509_FMT_PEM;
990 if (HAVE_OPT(OUTDER) || HAVE_OPT(OUTRAW))
991 outcert_format = GNUTLS_X509_FMT_DER;
992 else
993 outcert_format = GNUTLS_X509_FMT_PEM;
995 if (HAVE_OPT(DSA))
996 req_key_type = GNUTLS_PK_DSA;
997 else if (HAVE_OPT(ECC))
998 req_key_type = GNUTLS_PK_ECC;
999 else
1000 req_key_type = GNUTLS_PK_RSA;
1002 default_dig = GNUTLS_DIG_UNKNOWN;
1003 if (HAVE_OPT(HASH))
1005 if (strcasecmp (OPT_ARG(HASH), "md5") == 0)
1007 fprintf (stderr,
1008 "Warning: MD5 is broken, and should not be used any more for digital signatures.\n");
1009 default_dig = GNUTLS_DIG_MD5;
1011 else if (strcasecmp (OPT_ARG(HASH), "sha1") == 0)
1012 default_dig = GNUTLS_DIG_SHA1;
1013 else if (strcasecmp (OPT_ARG(HASH), "sha256") == 0)
1014 default_dig = GNUTLS_DIG_SHA256;
1015 else if (strcasecmp (OPT_ARG(HASH), "sha224") == 0)
1016 default_dig = GNUTLS_DIG_SHA224;
1017 else if (strcasecmp (OPT_ARG(HASH), "sha384") == 0)
1018 default_dig = GNUTLS_DIG_SHA384;
1019 else if (strcasecmp (OPT_ARG(HASH), "sha512") == 0)
1020 default_dig = GNUTLS_DIG_SHA512;
1021 else if (strcasecmp (OPT_ARG(HASH), "rmd160") == 0)
1022 default_dig = GNUTLS_DIG_RMD160;
1023 else
1024 error (EXIT_FAILURE, 0, "invalid hash: %s", OPT_ARG(HASH));
1027 batch = 0;
1028 if (HAVE_OPT(TEMPLATE))
1030 batch = 1;
1031 template_parse (OPT_ARG(TEMPLATE));
1034 gnutls_global_set_log_function (tls_log_func);
1036 if (HAVE_OPT(DEBUG))
1038 gnutls_global_set_log_level (OPT_VALUE_DEBUG);
1039 printf ("Setting log level to %d\n", (int)OPT_VALUE_DEBUG);
1042 if ((ret = gnutls_global_init ()) < 0)
1043 error (EXIT_FAILURE, 0, "global_init: %s", gnutls_strerror (ret));
1045 #ifdef ENABLE_PKCS11
1046 pkcs11_common();
1047 #endif
1049 memset (&cinfo, 0, sizeof (cinfo));
1051 if (HAVE_OPT(LOAD_PRIVKEY))
1052 cinfo.privkey = OPT_ARG(LOAD_PRIVKEY);
1054 cinfo.v1_cert = HAVE_OPT(V1);
1055 if (HAVE_OPT(NO_CRQ_EXTENSIONS))
1056 cinfo.crq_extensions = 0;
1057 else cinfo.crq_extensions = 1;
1059 if (HAVE_OPT(LOAD_PUBKEY))
1060 cinfo.pubkey = OPT_ARG(LOAD_PUBKEY);
1062 cinfo.pkcs8 = HAVE_OPT(PKCS8);
1063 cinfo.incert_format = incert_format;
1065 if (HAVE_OPT(LOAD_CERTIFICATE))
1066 cinfo.cert = OPT_ARG(LOAD_CERTIFICATE);
1068 if (HAVE_OPT(LOAD_REQUEST))
1069 cinfo.request = OPT_ARG(LOAD_REQUEST);
1071 if (HAVE_OPT(LOAD_CA_CERTIFICATE))
1072 cinfo.ca = OPT_ARG(LOAD_CA_CERTIFICATE);
1074 if (HAVE_OPT(LOAD_CA_PRIVKEY))
1075 cinfo.ca_privkey = OPT_ARG(LOAD_CA_PRIVKEY);
1077 if (HAVE_OPT(BITS))
1078 cinfo.bits = OPT_VALUE_BITS;
1080 if (HAVE_OPT(SEC_PARAM))
1081 cinfo.sec_param = OPT_ARG(SEC_PARAM);
1083 if (HAVE_OPT(PKCS_CIPHER))
1084 cinfo.pkcs_cipher = OPT_ARG(PKCS_CIPHER);
1086 if (HAVE_OPT(PASSWORD))
1087 cinfo.password = OPT_ARG(PASSWORD);
1089 if (HAVE_OPT(GENERATE_SELF_SIGNED))
1090 generate_self_signed (&cinfo);
1091 else if (HAVE_OPT(GENERATE_CERTIFICATE))
1092 generate_signed_certificate (&cinfo);
1093 else if (HAVE_OPT(GENERATE_PROXY))
1094 generate_proxy_certificate (&cinfo);
1095 else if (HAVE_OPT(GENERATE_CRL))
1096 generate_signed_crl (&cinfo);
1097 else if (HAVE_OPT(UPDATE_CERTIFICATE))
1098 update_signed_certificate (&cinfo);
1099 else if (HAVE_OPT(GENERATE_PRIVKEY))
1100 generate_private_key (&cinfo);
1101 else if (HAVE_OPT(GENERATE_REQUEST))
1102 generate_request (&cinfo);
1103 else if (HAVE_OPT(VERIFY_CHAIN))
1104 verify_chain ();
1105 else if (HAVE_OPT(VERIFY))
1106 verify_certificate (&cinfo);
1107 else if (HAVE_OPT(VERIFY_CRL))
1108 verify_crl (&cinfo);
1109 else if (HAVE_OPT(CERTIFICATE_INFO))
1110 certificate_info (0, &cinfo);
1111 else if (HAVE_OPT(DH_INFO))
1112 dh_info (&cinfo);
1113 else if (HAVE_OPT(CERTIFICATE_PUBKEY))
1114 certificate_info (1, &cinfo);
1115 else if (HAVE_OPT(KEY_INFO))
1116 privkey_info (&cinfo);
1117 else if (HAVE_OPT(PUBKEY_INFO))
1118 pubkey_info (NULL, &cinfo);
1119 else if (HAVE_OPT(TO_P12))
1120 generate_pkcs12 (&cinfo);
1121 else if (HAVE_OPT(P12_INFO))
1122 pkcs12_info (&cinfo);
1123 else if (HAVE_OPT(GENERATE_DH_PARAMS))
1124 generate_prime (1, &cinfo);
1125 else if (HAVE_OPT(GET_DH_PARAMS))
1126 generate_prime (0, &cinfo);
1127 else if (HAVE_OPT(CRL_INFO))
1128 crl_info ();
1129 else if (HAVE_OPT(P7_INFO))
1130 pkcs7_info ();
1131 else if (HAVE_OPT(SMIME_TO_P7))
1132 smime_to_pkcs7 ();
1133 else if (HAVE_OPT(TO_P8))
1134 generate_pkcs8 (&cinfo);
1135 #ifdef ENABLE_OPENPGP
1136 else if (HAVE_OPT(PGP_CERTIFICATE_INFO))
1137 pgp_certificate_info ();
1138 else if (HAVE_OPT(PGP_KEY_INFO))
1139 pgp_privkey_info ();
1140 else if (HAVE_OPT(PGP_RING_INFO))
1141 pgp_ring_info ();
1142 #endif
1143 else if (HAVE_OPT(CRQ_INFO))
1144 crq_info ();
1145 else
1146 USAGE(1);
1148 fclose (outfile);
1150 #ifdef ENABLE_PKCS11
1151 gnutls_pkcs11_deinit ();
1152 #endif
1153 gnutls_global_deinit ();
1156 #define MAX_CRTS 500
1157 void
1158 certificate_info (int pubkey, common_info_st * cinfo)
1160 gnutls_x509_crt_t crt[MAX_CRTS];
1161 size_t size;
1162 int ret, i, count;
1163 gnutls_datum_t pem;
1164 unsigned int crt_num;
1166 pem.data = (void*)fread_file (infile, &size);
1167 pem.size = size;
1169 crt_num = MAX_CRTS;
1170 ret =
1171 gnutls_x509_crt_list_import (crt, &crt_num, &pem, incert_format,
1172 GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
1173 if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
1175 error (0, 0, "too many certificates (%d); "
1176 "will only read the first %d", crt_num, MAX_CRTS);
1177 crt_num = MAX_CRTS;
1178 ret = gnutls_x509_crt_list_import (crt, &crt_num, &pem,
1179 incert_format, 0);
1181 if (ret < 0)
1182 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (ret));
1184 free (pem.data);
1186 count = ret;
1188 if (count > 1 && outcert_format == GNUTLS_X509_FMT_DER)
1190 error (0, 0, "cannot output multiple certificates in DER format; "
1191 "using PEM instead");
1192 outcert_format = GNUTLS_X509_FMT_PEM;
1195 for (i = 0; i < count; i++)
1197 if (i > 0)
1198 fprintf (outfile, "\n");
1200 if (outcert_format == GNUTLS_X509_FMT_PEM)
1201 print_certificate_info (crt[i], outfile, 1);
1203 if (pubkey)
1204 pubkey_info (crt[i], cinfo);
1205 else
1207 size = buffer_size;
1208 ret = gnutls_x509_crt_export (crt[i], outcert_format, buffer,
1209 &size);
1210 if (ret < 0)
1211 error (EXIT_FAILURE, 0, "export error: %s", gnutls_strerror (ret));
1213 fwrite (buffer, 1, size, outfile);
1216 gnutls_x509_crt_deinit (crt[i]);
1220 #ifdef ENABLE_OPENPGP
1222 void
1223 pgp_certificate_info (void)
1225 gnutls_openpgp_crt_t crt;
1226 size_t size;
1227 int ret;
1228 gnutls_datum_t pem, out_data;
1229 unsigned int verify_status;
1231 pem.data = (void*)fread_file (infile, &size);
1232 pem.size = size;
1234 ret = gnutls_openpgp_crt_init (&crt);
1235 if (ret < 0)
1236 error (EXIT_FAILURE, 0, "openpgp_crt_init: %s", gnutls_strerror (ret));
1238 ret = gnutls_openpgp_crt_import (crt, &pem, incert_format);
1240 if (ret < 0)
1241 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (ret));
1243 free (pem.data);
1245 if (outcert_format == GNUTLS_OPENPGP_FMT_BASE64)
1247 ret = gnutls_openpgp_crt_print (crt, 0, &out_data);
1249 if (ret == 0)
1251 fprintf (outfile, "%s\n", out_data.data);
1252 gnutls_free (out_data.data);
1257 ret = gnutls_openpgp_crt_verify_self (crt, 0, &verify_status);
1258 if (ret < 0)
1260 error (EXIT_FAILURE, 0, "verify signature error: %s",
1261 gnutls_strerror (ret));
1264 if (verify_status & GNUTLS_CERT_INVALID)
1266 fprintf (outfile, "Self Signature verification: failed\n\n");
1268 else
1270 fprintf (outfile, "Self Signature verification: ok (%x)\n\n",
1271 verify_status);
1274 size = buffer_size;
1275 ret = gnutls_openpgp_crt_export (crt, outcert_format, buffer, &size);
1276 if (ret < 0)
1278 error (EXIT_FAILURE, 0, "export error: %s", gnutls_strerror (ret));
1279 fwrite (buffer, 1, size, outfile);
1282 fprintf (outfile, "%s\n", buffer);
1283 gnutls_openpgp_crt_deinit (crt);
1286 void
1287 pgp_privkey_info (void)
1289 gnutls_openpgp_privkey_t key;
1290 unsigned char keyid[GNUTLS_OPENPGP_KEYID_SIZE];
1291 size_t size;
1292 int ret, i, subkeys, bits = 0;
1293 gnutls_datum_t pem;
1294 const char *cprint;
1296 size = fread (buffer, 1, buffer_size - 1, infile);
1297 buffer[size] = 0;
1299 gnutls_openpgp_privkey_init (&key);
1301 pem.data = buffer;
1302 pem.size = size;
1304 ret = gnutls_openpgp_privkey_import (key, &pem, incert_format,
1305 NULL, 0);
1307 if (ret < 0)
1308 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (ret));
1310 /* Public key algorithm
1312 subkeys = gnutls_openpgp_privkey_get_subkey_count (key);
1313 if (subkeys < 0)
1314 error (EXIT_FAILURE, 0, "privkey_get_subkey_count: %s",
1315 gnutls_strerror (subkeys));
1317 for (i = -1; i < subkeys; i++)
1320 if (i != -1)
1321 fprintf (outfile, "Subkey[%d]:\n", i);
1323 fprintf (outfile, "Public Key Info:\n");
1325 if (i == -1)
1326 ret = gnutls_openpgp_privkey_get_pk_algorithm (key, NULL);
1327 else
1328 ret = gnutls_openpgp_privkey_get_subkey_pk_algorithm (key, i, NULL);
1330 fprintf (outfile, "\tPublic Key Algorithm: ");
1331 cprint = gnutls_pk_algorithm_get_name (ret);
1332 fprintf (outfile, "%s\n", cprint ? cprint : "Unknown");
1333 fprintf (outfile, "\tKey Security Level: %s\n",
1334 gnutls_sec_param_get_name (gnutls_openpgp_privkey_sec_param
1335 (key)));
1337 /* Print the raw public and private keys
1340 if (ret == GNUTLS_PK_RSA)
1342 gnutls_datum_t m, e, d, p, q, u;
1344 if (i == -1)
1345 ret =
1346 gnutls_openpgp_privkey_export_rsa_raw (key, &m, &e, &d, &p,
1347 &q, &u);
1348 else
1349 ret =
1350 gnutls_openpgp_privkey_export_subkey_rsa_raw (key, i, &m,
1351 &e, &d, &p,
1352 &q, &u);
1353 if (ret < 0)
1354 fprintf (stderr, "Error in key RSA data export: %s\n",
1355 gnutls_strerror (ret));
1356 else
1357 print_rsa_pkey (&m, &e, &d, &p, &q, &u, NULL, NULL);
1359 bits = m.size * 8;
1361 else if (ret == GNUTLS_PK_DSA)
1363 gnutls_datum_t p, q, g, y, x;
1365 if (i == -1)
1366 ret =
1367 gnutls_openpgp_privkey_export_dsa_raw (key, &p, &q, &g, &y, &x);
1368 else
1369 ret =
1370 gnutls_openpgp_privkey_export_subkey_dsa_raw (key, i, &p,
1371 &q, &g, &y, &x);
1372 if (ret < 0)
1373 fprintf (stderr, "Error in key DSA data export: %s\n",
1374 gnutls_strerror (ret));
1375 else
1376 print_dsa_pkey (&x, &y, &p, &q, &g);
1378 bits = y.size * 8;
1381 fprintf (outfile, "\n");
1383 size = buffer_size;
1384 if (i == -1)
1385 ret = gnutls_openpgp_privkey_get_key_id (key, keyid);
1386 else
1387 ret = gnutls_openpgp_privkey_get_subkey_id (key, i, keyid);
1389 if (ret < 0)
1391 fprintf (stderr, "Error in key id calculation: %s\n",
1392 gnutls_strerror (ret));
1394 else
1396 fprintf (outfile, "Public key ID: %s\n", raw_to_string (keyid, 8));
1399 size = buffer_size;
1400 if (i == -1)
1401 ret = gnutls_openpgp_privkey_get_fingerprint (key, buffer, &size);
1402 else
1403 ret = gnutls_openpgp_privkey_get_subkey_fingerprint (key, i, buffer, &size);
1405 if (ret < 0)
1407 fprintf (stderr, "Error in fingerprint calculation: %s\n",
1408 gnutls_strerror (ret));
1410 else
1412 gnutls_datum_t art;
1414 fprintf (outfile, "Fingerprint: %s\n", raw_to_string (buffer, size));
1416 ret = gnutls_random_art(GNUTLS_RANDOM_ART_OPENSSH, cprint, bits, buffer, size, &art);
1417 if (ret >= 0)
1419 fprintf (outfile, "Fingerprint's random art:\n%s\n\n", art.data);
1420 gnutls_free(art.data);
1425 size = buffer_size;
1426 ret = gnutls_openpgp_privkey_export (key, GNUTLS_OPENPGP_FMT_BASE64,
1427 NULL, 0, buffer, &size);
1428 if (ret < 0)
1429 error (EXIT_FAILURE, 0, "export error: %s", gnutls_strerror (ret));
1431 fprintf (outfile, "\n%s\n", buffer);
1433 gnutls_openpgp_privkey_deinit (key);
1436 void
1437 pgp_ring_info (void)
1439 gnutls_openpgp_keyring_t ring;
1440 gnutls_openpgp_crt_t crt;
1441 size_t size;
1442 int ret, i, count;
1443 gnutls_datum_t pem;
1445 pem.data = (void*)fread_file (infile, &size);
1446 pem.size = size;
1448 ret = gnutls_openpgp_keyring_init (&ring);
1449 if (ret < 0)
1450 error (EXIT_FAILURE, 0, "openpgp_keyring_init: %s",
1451 gnutls_strerror (ret));
1453 ret = gnutls_openpgp_keyring_import (ring, &pem, incert_format);
1455 if (ret < 0)
1456 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (ret));
1458 free (pem.data);
1460 count = gnutls_openpgp_keyring_get_crt_count (ring);
1461 if (count >= 0)
1462 fprintf (outfile, "Keyring contains %d OpenPGP certificates\n\n", count);
1463 else
1464 error (EXIT_FAILURE, 0, "keyring error: %s", gnutls_strerror (count));
1466 for (i = 0; i < count; i++)
1468 ret = gnutls_openpgp_keyring_get_crt (ring, i, &crt);
1469 if (ret < 0)
1470 error (EXIT_FAILURE, 0, "export error: %s", gnutls_strerror (ret));
1472 size = buffer_size;
1473 ret = gnutls_openpgp_crt_export (crt, outcert_format,
1474 buffer, &size);
1475 if (ret < 0)
1476 error (EXIT_FAILURE, 0, "export error: %s", gnutls_strerror (ret));
1478 fwrite (buffer, 1, size, outfile);
1479 fprintf (outfile, "\n\n");
1481 gnutls_openpgp_crt_deinit (crt);
1486 gnutls_openpgp_keyring_deinit (ring);
1490 #endif
1492 static void
1493 print_hex_datum (gnutls_datum_t * dat)
1495 unsigned int j;
1496 #define SPACE "\t"
1497 fprintf (outfile, "\n" SPACE);
1498 for (j = 0; j < dat->size; j++)
1500 fprintf (outfile, "%.2x:", (unsigned char) dat->data[j]);
1501 if ((j + 1) % 15 == 0)
1502 fprintf (outfile, "\n" SPACE);
1504 fprintf (outfile, "\n");
1508 static void
1509 print_certificate_info (gnutls_x509_crt_t crt, FILE * out, unsigned int all)
1511 gnutls_datum_t data;
1512 int ret;
1514 if (all)
1515 ret = gnutls_x509_crt_print (crt, GNUTLS_CRT_PRINT_FULL, &data);
1516 else
1517 ret = gnutls_x509_crt_print (crt, GNUTLS_CRT_PRINT_UNSIGNED_FULL, &data);
1518 if (ret == 0)
1520 fprintf (out, "%s\n", data.data);
1521 gnutls_free (data.data);
1524 if (out == stderr && batch == 0) /* interactive */
1525 if (read_yesno ("Is the above information ok? (y/N): ") == 0)
1527 exit (1);
1531 static void
1532 print_crl_info (gnutls_x509_crl_t crl, FILE * out)
1534 gnutls_datum_t data;
1535 int ret;
1536 size_t size;
1538 ret = gnutls_x509_crl_print (crl, GNUTLS_CRT_PRINT_FULL, &data);
1539 if (ret < 0)
1540 error (EXIT_FAILURE, 0, "crl_print: %s", gnutls_strerror (ret));
1542 fprintf (out, "%s\n", data.data);
1544 gnutls_free (data.data);
1546 size = buffer_size;
1547 ret = gnutls_x509_crl_export (crl, GNUTLS_X509_FMT_PEM, buffer, &size);
1548 if (ret < 0)
1549 error (EXIT_FAILURE, 0, "crl_export: %s", gnutls_strerror (ret));
1551 fwrite (buffer, 1, size, outfile);
1554 void
1555 crl_info (void)
1557 gnutls_x509_crl_t crl;
1558 int ret;
1559 size_t size;
1560 gnutls_datum_t pem;
1562 ret = gnutls_x509_crl_init (&crl);
1563 if (ret < 0)
1564 error (EXIT_FAILURE, 0, "crl_init: %s", gnutls_strerror (ret));
1566 pem.data = (void*)fread_file (infile, &size);
1567 pem.size = size;
1569 if (!pem.data)
1570 error (EXIT_FAILURE, errno, "%s", infile ? "file" :
1571 "standard input");
1573 ret = gnutls_x509_crl_import (crl, &pem, incert_format);
1575 free (pem.data);
1576 if (ret < 0)
1577 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (ret));
1579 print_crl_info (crl, outfile);
1581 gnutls_x509_crl_deinit (crl);
1584 static void
1585 print_crq_info (gnutls_x509_crq_t crq, FILE * out)
1587 gnutls_datum_t data;
1588 int ret;
1589 size_t size;
1591 if (outcert_format == GNUTLS_X509_FMT_PEM)
1593 ret = gnutls_x509_crq_print (crq, GNUTLS_CRT_PRINT_FULL, &data);
1594 if (ret < 0)
1595 error (EXIT_FAILURE, 0, "crq_print: %s", gnutls_strerror (ret));
1597 fprintf (out, "%s\n", data.data);
1599 gnutls_free (data.data);
1602 ret = gnutls_x509_crq_verify(crq, 0);
1603 if (ret < 0)
1605 fprintf(out, "Self signature: FAILED\n\n");
1607 else
1609 fprintf(out, "Self signature: verified\n\n");
1612 size = buffer_size;
1613 ret = gnutls_x509_crq_export (crq, outcert_format, buffer, &size);
1614 if (ret < 0)
1615 error (EXIT_FAILURE, 0, "crq_export: %s", gnutls_strerror (ret));
1617 fwrite (buffer, 1, size, outfile);
1620 void
1621 crq_info (void)
1623 gnutls_x509_crq_t crq;
1624 int ret;
1625 size_t size;
1626 gnutls_datum_t pem;
1628 ret = gnutls_x509_crq_init (&crq);
1629 if (ret < 0)
1630 error (EXIT_FAILURE, 0, "crq_init: %s", gnutls_strerror (ret));
1632 pem.data = (void*)fread_file (infile, &size);
1633 pem.size = size;
1635 if (!pem.data)
1636 error (EXIT_FAILURE, errno, "%s", infile ? "file" :
1637 "standard input");
1639 ret = gnutls_x509_crq_import (crq, &pem, incert_format);
1641 free (pem.data);
1642 if (ret < 0)
1643 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (ret));
1645 print_crq_info (crq, outfile);
1647 gnutls_x509_crq_deinit (crq);
1650 static void privkey_info_int (common_info_st* cinfo, gnutls_x509_privkey_t key)
1652 int ret, key_type, bits = 0;
1653 size_t size;
1654 const char *cprint;
1656 /* Public key algorithm
1658 fprintf (outfile, "Public Key Info:\n");
1659 ret = gnutls_x509_privkey_get_pk_algorithm (key);
1660 fprintf (outfile, "\tPublic Key Algorithm: ");
1662 key_type = ret;
1664 cprint = gnutls_pk_algorithm_get_name (key_type);
1665 fprintf (outfile, "%s\n", cprint ? cprint : "Unknown");
1666 fprintf (outfile, "\tKey Security Level: %s\n\n",
1667 gnutls_sec_param_get_name (gnutls_x509_privkey_sec_param (key)));
1669 /* Print the raw public and private keys
1671 if (key_type == GNUTLS_PK_RSA)
1673 gnutls_datum_t m, e, d, p, q, u, exp1, exp2;
1675 ret =
1676 gnutls_x509_privkey_export_rsa_raw2 (key, &m, &e, &d, &p, &q, &u,
1677 &exp1, &exp2);
1678 if (ret < 0)
1679 fprintf (stderr, "Error in key RSA data export: %s\n",
1680 gnutls_strerror (ret));
1681 else
1683 print_rsa_pkey (&m, &e, &d, &p, &q, &u, &exp1, &exp2);
1684 bits = m.size * 8;
1686 gnutls_free (m.data);
1687 gnutls_free (e.data);
1688 gnutls_free (d.data);
1689 gnutls_free (p.data);
1690 gnutls_free (q.data);
1691 gnutls_free (u.data);
1692 gnutls_free (exp1.data);
1693 gnutls_free (exp2.data);
1696 else if (key_type == GNUTLS_PK_DSA)
1698 gnutls_datum_t p, q, g, y, x;
1700 ret = gnutls_x509_privkey_export_dsa_raw (key, &p, &q, &g, &y, &x);
1701 if (ret < 0)
1702 fprintf (stderr, "Error in key DSA data export: %s\n",
1703 gnutls_strerror (ret));
1704 else
1706 print_dsa_pkey (&x, &y, &p, &q, &g);
1707 bits = y.size * 8;
1709 gnutls_free (x.data);
1710 gnutls_free (y.data);
1711 gnutls_free (p.data);
1712 gnutls_free (q.data);
1713 gnutls_free (g.data);
1716 else if (key_type == GNUTLS_PK_EC)
1718 gnutls_datum_t y, x, k;
1719 gnutls_ecc_curve_t curve;
1721 ret = gnutls_x509_privkey_export_ecc_raw (key, &curve, &x, &y, &k);
1722 if (ret < 0)
1723 fprintf (stderr, "Error in key ECC data export: %s\n",
1724 gnutls_strerror (ret));
1725 else
1727 print_ecc_pkey (curve, &k, &x, &y);
1728 bits = gnutls_ecc_curve_get_size(curve) * 8;
1730 gnutls_free (x.data);
1731 gnutls_free (y.data);
1732 gnutls_free (k.data);
1736 fprintf (outfile, "\n");
1738 size = buffer_size;
1739 if ((ret = gnutls_x509_privkey_get_key_id (key, 0, buffer, &size)) < 0)
1741 fprintf (stderr, "Error in key id calculation: %s\n",
1742 gnutls_strerror (ret));
1744 else
1746 gnutls_datum_t art;
1748 fprintf (outfile, "Public Key ID: %s\n", raw_to_string (buffer, size));
1750 ret = gnutls_random_art(GNUTLS_RANDOM_ART_OPENSSH, cprint, bits, buffer, size, &art);
1751 if (ret >= 0)
1753 fprintf (outfile, "Public key's random art:\n%s\n", art.data);
1754 gnutls_free(art.data);
1757 fprintf (outfile, "\n");
1761 void
1762 privkey_info (common_info_st* cinfo)
1764 gnutls_x509_privkey_t key;
1765 size_t size;
1766 int ret;
1767 gnutls_datum_t pem;
1768 const char *pass;
1770 size = fread (buffer, 1, buffer_size - 1, infile);
1771 buffer[size] = 0;
1773 gnutls_x509_privkey_init (&key);
1775 pem.data = buffer;
1776 pem.size = size;
1778 ret = 0;
1779 if (!cinfo->pkcs8)
1780 ret = gnutls_x509_privkey_import (key, &pem, incert_format);
1782 /* If we failed to import the certificate previously try PKCS #8 */
1783 if (cinfo->pkcs8 || ret == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR)
1785 ret = gnutls_x509_privkey_import_pkcs8 (key, &pem,
1786 incert_format, NULL, GNUTLS_PKCS8_PLAIN);
1787 if (ret == GNUTLS_E_DECRYPTION_FAILED)
1789 fprintf(stderr, "Encrypted structure detected...\n");
1790 if (cinfo->password)
1791 pass = cinfo->password;
1792 else
1793 pass = get_pass ();
1795 ret = gnutls_x509_privkey_import_pkcs8 (key, &pem,
1796 incert_format, pass, 0);
1799 if (ret < 0)
1800 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (ret));
1802 if (outcert_format == GNUTLS_X509_FMT_PEM)
1803 privkey_info_int (cinfo, key);
1805 ret = gnutls_x509_privkey_verify_params (key);
1806 if (ret < 0)
1807 fprintf (outfile, "\n** Private key parameters validation failed **\n\n");
1809 size = buffer_size;
1810 ret = gnutls_x509_privkey_export (key, outcert_format, buffer, &size);
1811 if (ret < 0)
1812 error (EXIT_FAILURE, 0, "export error: %s", gnutls_strerror (ret));
1814 fwrite (buffer, 1, size, outfile);
1816 gnutls_x509_privkey_deinit (key);
1820 /* Generate a PKCS #10 certificate request.
1822 void
1823 generate_request (common_info_st * cinfo)
1825 gnutls_x509_crq_t crq;
1826 gnutls_x509_privkey_t xkey;
1827 gnutls_pubkey_t pubkey;
1828 gnutls_privkey_t pkey;
1829 int ret, ca_status, path_len;
1830 const char *pass;
1831 unsigned int usage = 0;
1833 fprintf (stderr, "Generating a PKCS #10 certificate request...\n");
1835 ret = gnutls_x509_crq_init (&crq);
1836 if (ret < 0)
1837 error (EXIT_FAILURE, 0, "crq_init: %s", gnutls_strerror (ret));
1840 /* Load the private key.
1842 pkey = load_private_key (0, cinfo);
1843 if (!pkey)
1845 ret = gnutls_privkey_init (&pkey);
1846 if (ret < 0)
1847 error (EXIT_FAILURE, 0, "privkey_init: %s", gnutls_strerror (ret));
1849 xkey = generate_private_key_int (cinfo);
1851 print_private_key (cinfo, xkey);
1853 ret = gnutls_privkey_import_x509(pkey, xkey, GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
1854 if (ret < 0)
1855 error (EXIT_FAILURE, 0, "privkey_import_x509: %s", gnutls_strerror (ret));
1858 pubkey = load_public_key_or_import (1, pkey, cinfo);
1860 /* Set the DN.
1862 get_country_crq_set (crq);
1863 get_organization_crq_set (crq);
1864 get_unit_crq_set (crq);
1865 get_locality_crq_set (crq);
1866 get_state_crq_set (crq);
1867 get_cn_crq_set (crq);
1868 get_dc_set (TYPE_CRQ, crq);
1869 get_uid_crq_set (crq);
1870 get_oid_crq_set (crq);
1872 get_dns_name_set (TYPE_CRQ, crq);
1873 get_uri_set (TYPE_CRQ, crq);
1874 get_ip_addr_set (TYPE_CRQ, crq);
1875 get_email_set (TYPE_CRQ, crq);
1877 pass = get_challenge_pass ();
1879 if (pass != NULL && pass[0] != 0)
1881 ret = gnutls_x509_crq_set_challenge_password (crq, pass);
1882 if (ret < 0)
1883 error (EXIT_FAILURE, 0, "set_pass: %s", gnutls_strerror (ret));
1886 if (cinfo->crq_extensions != 0)
1888 ca_status = get_ca_status ();
1889 if (ca_status)
1890 path_len = get_path_len ();
1891 else
1892 path_len = -1;
1894 ret = gnutls_x509_crq_set_basic_constraints (crq, ca_status, path_len);
1895 if (ret < 0)
1896 error (EXIT_FAILURE, 0, "set_basic_constraints: %s",
1897 gnutls_strerror (ret));
1899 ret = get_sign_status (1);
1900 if (ret)
1901 usage |= GNUTLS_KEY_DIGITAL_SIGNATURE;
1903 ret = get_encrypt_status (1);
1904 if (ret)
1905 usage |= GNUTLS_KEY_KEY_ENCIPHERMENT;
1906 else
1907 usage |= GNUTLS_KEY_DIGITAL_SIGNATURE;
1909 if (ca_status)
1911 ret = get_cert_sign_status ();
1912 if (ret)
1913 usage |= GNUTLS_KEY_KEY_CERT_SIGN;
1915 ret = get_crl_sign_status ();
1916 if (ret)
1917 usage |= GNUTLS_KEY_CRL_SIGN;
1919 ret = get_code_sign_status ();
1920 if (ret)
1922 ret = gnutls_x509_crq_set_key_purpose_oid
1923 (crq, GNUTLS_KP_CODE_SIGNING, 0);
1924 if (ret < 0)
1925 error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (ret));
1928 ret = get_ocsp_sign_status ();
1929 if (ret)
1931 ret = gnutls_x509_crq_set_key_purpose_oid
1932 (crq, GNUTLS_KP_OCSP_SIGNING, 0);
1933 if (ret < 0)
1934 error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (ret));
1937 ret = get_time_stamp_status ();
1938 if (ret)
1940 ret = gnutls_x509_crq_set_key_purpose_oid
1941 (crq, GNUTLS_KP_TIME_STAMPING, 0);
1942 if (ret < 0)
1943 error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (ret));
1946 ret = get_ipsec_ike_status ();
1947 if (ret)
1949 ret = gnutls_x509_crq_set_key_purpose_oid
1950 (crq, GNUTLS_KP_IPSEC_IKE, 0);
1951 if (ret < 0)
1952 error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (ret));
1956 ret = gnutls_x509_crq_set_key_usage (crq, usage);
1957 if (ret < 0)
1958 error (EXIT_FAILURE, 0, "key_usage: %s", gnutls_strerror (ret));
1960 ret = get_tls_client_status ();
1961 if (ret != 0)
1963 ret = gnutls_x509_crq_set_key_purpose_oid
1964 (crq, GNUTLS_KP_TLS_WWW_CLIENT, 0);
1965 if (ret < 0)
1966 error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (ret));
1969 ret = get_tls_server_status ();
1970 if (ret != 0)
1972 ret = gnutls_x509_crq_set_key_purpose_oid
1973 (crq, GNUTLS_KP_TLS_WWW_SERVER, 0);
1974 if (ret < 0)
1975 error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (ret));
1979 ret = gnutls_x509_crq_set_pubkey (crq, pubkey);
1980 if (ret < 0)
1981 error (EXIT_FAILURE, 0, "set_key: %s", gnutls_strerror (ret));
1983 ret = gnutls_x509_crq_privkey_sign (crq, pkey, SIGN_HASH, 0);
1984 if (ret < 0)
1985 error (EXIT_FAILURE, 0, "sign: %s", gnutls_strerror (ret));
1987 print_crq_info (crq, outfile);
1989 gnutls_x509_crq_deinit (crq);
1990 gnutls_privkey_deinit( pkey);
1991 gnutls_pubkey_deinit( pubkey);
1995 static void print_verification_res (FILE* outfile, unsigned int output);
1997 static int detailed_verification(gnutls_x509_crt_t cert,
1998 gnutls_x509_crt_t issuer, gnutls_x509_crl_t crl,
1999 unsigned int verification_output)
2001 char name[512];
2002 char tmp[255];
2003 char issuer_name[512];
2004 size_t name_size;
2005 size_t issuer_name_size;
2006 int ret;
2008 issuer_name_size = sizeof (issuer_name);
2009 ret =
2010 gnutls_x509_crt_get_issuer_dn (cert, issuer_name, &issuer_name_size);
2011 if (ret < 0)
2012 error (EXIT_FAILURE, 0, "gnutls_x509_crt_get_issuer_dn: %s", gnutls_strerror (ret));
2014 name_size = sizeof (name);
2015 ret =
2016 gnutls_x509_crt_get_dn (cert, name, &name_size);
2017 if (ret < 0)
2018 error (EXIT_FAILURE, 0, "gnutls_x509_crt_get_dn: %s", gnutls_strerror (ret));
2020 fprintf (outfile, "\tSubject: %s\n", name);
2021 fprintf (outfile, "\tIssuer: %s\n", issuer_name);
2023 if (issuer != NULL)
2025 issuer_name_size = sizeof (issuer_name);
2026 ret =
2027 gnutls_x509_crt_get_dn (issuer, issuer_name, &issuer_name_size);
2028 if (ret < 0)
2029 error (EXIT_FAILURE, 0, "gnutls_x509_crt_get_issuer_dn: %s", gnutls_strerror (ret));
2031 fprintf (outfile, "\tChecked against: %s\n", issuer_name);
2034 if (crl != NULL)
2036 gnutls_datum_t data;
2038 issuer_name_size = sizeof (issuer_name);
2039 ret =
2040 gnutls_x509_crl_get_issuer_dn (crl, issuer_name, &issuer_name_size);
2041 if (ret < 0)
2042 error (EXIT_FAILURE, 0, "gnutls_x509_crl_get_issuer_dn: %s", gnutls_strerror (ret));
2044 name_size = sizeof(tmp);
2045 ret = gnutls_x509_crl_get_number(crl, tmp, &name_size, NULL);
2046 if (ret < 0)
2047 strcpy(name, "unnumbered");
2048 else
2050 data.data = (void*)tmp;
2051 data.size = name_size;
2053 name_size = sizeof(name);
2054 ret = gnutls_hex_encode(&data, name, &name_size);
2055 if (ret < 0)
2056 error (EXIT_FAILURE, 0, "gnutls_hex_encode: %s", gnutls_strerror (ret));
2058 fprintf (outfile, "\tChecked against CRL[%s] of: %s\n", name, issuer_name);
2061 fprintf (outfile, "\tOutput: ");
2062 print_verification_res(outfile, verification_output);
2064 fputs(".\n\n", outfile);
2066 return 0;
2069 /* Will verify a certificate chain. If no CA certificates
2070 * are provided, then the last certificate in the certificate
2071 * chain is used as a CA.
2073 static int
2074 _verify_x509_mem (const void *cert, int cert_size, const void* ca, int ca_size)
2076 int ret;
2077 gnutls_datum_t tmp;
2078 gnutls_x509_crt_t *x509_cert_list = NULL;
2079 gnutls_x509_crt_t *x509_ca_list = NULL;
2080 gnutls_x509_crl_t *x509_crl_list = NULL;
2081 unsigned int x509_ncerts, x509_ncrls = 0, x509_ncas = 0;
2082 gnutls_x509_trust_list_t list;
2083 unsigned int output;
2085 ret = gnutls_x509_trust_list_init(&list, 0);
2086 if (ret < 0)
2087 error (EXIT_FAILURE, 0, "gnutls_x509_trust_list_init: %s",
2088 gnutls_strerror (ret));
2090 if (ca == NULL)
2092 tmp.data = (void*)cert;
2093 tmp.size = cert_size;
2095 else
2097 tmp.data = (void*)ca;
2098 tmp.size = ca_size;
2100 /* Load CAs */
2101 ret = gnutls_x509_crt_list_import2( &x509_ca_list, &x509_ncas, &tmp,
2102 GNUTLS_X509_FMT_PEM, 0);
2103 if (ret < 0 || x509_ncas < 1)
2104 error (EXIT_FAILURE, 0, "error parsing CAs: %s",
2105 gnutls_strerror (ret));
2108 ret = gnutls_x509_crl_list_import2( &x509_crl_list, &x509_ncrls, &tmp,
2109 GNUTLS_X509_FMT_PEM, 0);
2110 if (ret < 0)
2112 x509_crl_list = NULL;
2113 x509_ncrls = 0;
2116 tmp.data = (void*)cert;
2117 tmp.size = cert_size;
2119 /* ignore errors. CRLs might not be given */
2120 ret = gnutls_x509_crt_list_import2( &x509_cert_list, &x509_ncerts, &tmp,
2121 GNUTLS_X509_FMT_PEM, 0);
2122 if (ret < 0 || x509_ncerts < 1)
2123 error (EXIT_FAILURE, 0, "error parsing CRTs: %s",
2124 gnutls_strerror (ret));
2126 if (ca == NULL)
2128 x509_ca_list = &x509_cert_list[x509_ncerts - 1];
2129 x509_ncas = 1;
2132 fprintf(stdout, "Loaded %d certificates, %d CAs and %d CRLs\n\n",
2133 x509_ncerts, x509_ncas, x509_ncrls);
2135 ret = gnutls_x509_trust_list_add_cas(list, x509_ca_list, x509_ncas, 0);
2136 if (ret < 0)
2137 error (EXIT_FAILURE, 0, "gnutls_x509_trust_add_cas: %s",
2138 gnutls_strerror (ret));
2140 ret = gnutls_x509_trust_list_add_crls(list, x509_crl_list, x509_ncrls, 0, 0);
2141 if (ret < 0)
2142 error (EXIT_FAILURE, 0, "gnutls_x509_trust_add_crls: %s",
2143 gnutls_strerror (ret));
2145 gnutls_free(x509_crl_list);
2147 ret = gnutls_x509_trust_list_verify_crt (list, x509_cert_list, x509_ncerts,
2148 GNUTLS_VERIFY_DO_NOT_ALLOW_SAME|GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT, &output,
2149 detailed_verification);
2150 if (ret < 0)
2151 error (EXIT_FAILURE, 0, "gnutls_x509_trusted_list_verify_crt: %s",
2152 gnutls_strerror (ret));
2154 fprintf (outfile, "Chain verification output: ");
2155 print_verification_res(outfile, output);
2157 fprintf (outfile, ".\n\n");
2159 gnutls_free(x509_cert_list);
2160 gnutls_x509_trust_list_deinit(list, 1);
2162 if (output != 0)
2163 exit(EXIT_FAILURE);
2165 return 0;
2168 static void
2169 print_verification_res (FILE* outfile, unsigned int output)
2171 int comma = 0;
2173 if (output & GNUTLS_CERT_INVALID)
2175 fprintf (outfile, "Not verified");
2176 comma = 1;
2178 else
2180 fprintf (outfile, "Verified");
2181 comma = 1;
2184 if (output & GNUTLS_CERT_SIGNER_NOT_CA)
2186 if (comma)
2187 fprintf (outfile, ", ");
2188 fprintf (outfile, "Issuer is not a CA");
2189 comma = 1;
2192 if (output & GNUTLS_CERT_INSECURE_ALGORITHM)
2194 if (comma)
2195 fprintf (outfile, ", ");
2196 fprintf (outfile, "Insecure algorithm");
2197 comma = 1;
2200 if (output & GNUTLS_CERT_NOT_ACTIVATED)
2202 if (comma)
2203 fprintf (outfile, ", ");
2204 fprintf (outfile, "Not activated");
2205 comma = 1;
2208 if (output & GNUTLS_CERT_EXPIRED)
2210 if (comma)
2211 fprintf (outfile, ", ");
2212 fprintf (outfile, "Expired");
2213 comma = 1;
2216 if (output & GNUTLS_CERT_REVOKED)
2218 if (comma)
2219 fprintf (outfile, ", ");
2220 fprintf (outfile, "Revoked");
2221 comma = 1;
2225 static void
2226 verify_chain (void)
2228 char *buf;
2229 size_t size;
2231 buf = (void*)fread_file (infile, &size);
2232 if (buf == NULL)
2233 error (EXIT_FAILURE, errno, "reading chain");
2235 buf[size] = 0;
2237 _verify_x509_mem (buf, size, NULL, 0);
2241 static void
2242 verify_certificate (common_info_st * cinfo)
2244 char *cert;
2245 char *cas;
2246 size_t cert_size, ca_size;
2247 FILE * ca_file = fopen(cinfo->ca, "r");
2249 if (ca_file == NULL)
2250 error (EXIT_FAILURE, errno, "opening CA file");
2252 cert = (void*)fread_file (infile, &cert_size);
2253 if (cert == NULL)
2254 error (EXIT_FAILURE, errno, "reading certificate chain");
2256 cert[cert_size] = 0;
2258 cas = (void*)fread_file (ca_file, &ca_size);
2259 if (cas == NULL)
2260 error (EXIT_FAILURE, errno, "reading CA list");
2262 cas[ca_size] = 0;
2263 fclose(ca_file);
2265 _verify_x509_mem (cert, cert_size, cas, ca_size);
2270 void
2271 verify_crl (common_info_st * cinfo)
2273 size_t size, dn_size;
2274 char dn[128];
2275 unsigned int output;
2276 int comma = 0;
2277 int ret;
2278 gnutls_datum_t pem;
2279 gnutls_x509_crl_t crl;
2280 time_t now = time (0);
2281 gnutls_x509_crt_t issuer;
2283 issuer = load_ca_cert (cinfo);
2285 fprintf (outfile, "\nCA certificate:\n");
2287 dn_size = sizeof (dn);
2288 ret = gnutls_x509_crt_get_dn (issuer, dn, &dn_size);
2289 if (ret < 0)
2290 error (EXIT_FAILURE, 0, "crt_get_dn: %s", gnutls_strerror (ret));
2292 fprintf (outfile, "\tSubject: %s\n\n", dn);
2294 ret = gnutls_x509_crl_init (&crl);
2295 if (ret < 0)
2296 error (EXIT_FAILURE, 0, "crl_init: %s", gnutls_strerror (ret));
2298 pem.data = (void*)fread_file (infile, &size);
2299 pem.size = size;
2301 ret = gnutls_x509_crl_import (crl, &pem, incert_format);
2302 free (pem.data);
2303 if (ret < 0)
2304 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (ret));
2306 print_crl_info (crl, outfile);
2308 fprintf (outfile, "Verification output: ");
2309 ret = gnutls_x509_crl_verify (crl, &issuer, 1, 0, &output);
2310 if (ret < 0)
2311 error (EXIT_FAILURE, 0, "verification error: %s", gnutls_strerror (ret));
2313 if (output & GNUTLS_CERT_INVALID)
2315 fprintf (outfile, "Not verified");
2316 comma = 1;
2318 else
2320 fprintf (outfile, "Verified");
2321 comma = 1;
2324 if (output & GNUTLS_CERT_SIGNER_NOT_CA)
2326 if (comma)
2327 fprintf (outfile, ", ");
2328 fprintf (outfile, "Issuer is not a CA");
2329 comma = 1;
2332 if (output & GNUTLS_CERT_INSECURE_ALGORITHM)
2334 if (comma)
2335 fprintf (outfile, ", ");
2336 fprintf (outfile, "Insecure algorithm");
2337 comma = 1;
2340 /* Check expiration dates.
2343 if (gnutls_x509_crl_get_this_update (crl) > now)
2345 if (comma)
2346 fprintf (outfile, ", ");
2347 comma = 1;
2348 fprintf (outfile, "Issued in the future!");
2351 if (gnutls_x509_crl_get_next_update (crl) < now)
2353 if (comma)
2354 fprintf (outfile, ", ");
2355 comma = 1;
2356 fprintf (outfile, "CRL is not up to date");
2359 fprintf (outfile, "\n");
2363 void
2364 generate_pkcs8 (common_info_st * cinfo)
2366 gnutls_x509_privkey_t key;
2367 int result;
2368 size_t size;
2369 int flags = 0;
2370 const char *password;
2372 fprintf (stderr, "Generating a PKCS #8 key structure...\n");
2374 key = load_x509_private_key (1, cinfo);
2376 if (cinfo->password)
2377 password = cinfo->password;
2378 else
2379 password = get_pass ();
2381 flags = cipher_to_flags (cinfo->pkcs_cipher);
2383 if (password == NULL || password[0] == 0)
2385 flags = GNUTLS_PKCS_PLAIN;
2388 size = buffer_size;
2389 result =
2390 gnutls_x509_privkey_export_pkcs8 (key, outcert_format,
2391 password, flags, buffer, &size);
2393 if (result < 0)
2394 error (EXIT_FAILURE, 0, "key_export: %s", gnutls_strerror (result));
2396 fwrite (buffer, 1, size, outfile);
2401 #include <gnutls/pkcs12.h>
2402 #include <unistd.h>
2404 void
2405 generate_pkcs12 (common_info_st * cinfo)
2407 gnutls_pkcs12_t pkcs12;
2408 gnutls_x509_crt_t *crts;
2409 gnutls_x509_privkey_t *keys;
2410 int result;
2411 size_t size;
2412 gnutls_datum_t data;
2413 const char *pass;
2414 const char *name;
2415 unsigned int flags, i;
2416 gnutls_datum_t key_id;
2417 unsigned char _key_id[32];
2418 int indx;
2419 size_t ncrts;
2420 size_t nkeys;
2422 fprintf (stderr, "Generating a PKCS #12 structure...\n");
2424 keys = load_privkey_list (0, &nkeys, cinfo);
2425 crts = load_cert_list (0, &ncrts, cinfo);
2427 name = get_pkcs12_key_name ();
2429 result = gnutls_pkcs12_init (&pkcs12);
2430 if (result < 0)
2431 error (EXIT_FAILURE, 0, "pkcs12_init: %s", gnutls_strerror (result));
2433 if (cinfo->password)
2434 pass = cinfo->password;
2435 else
2436 pass = get_pass ();
2438 if (pass == NULL)
2440 fprintf(stderr, "No password given for PKCS #12. Assuming null password...\n");
2441 pass = "";
2445 for (i = 0; i < ncrts; i++)
2447 gnutls_pkcs12_bag_t bag;
2449 result = gnutls_pkcs12_bag_init (&bag);
2450 if (result < 0)
2451 error (EXIT_FAILURE, 0, "bag_init: %s", gnutls_strerror (result));
2453 result = gnutls_pkcs12_bag_set_crt (bag, crts[i]);
2454 if (result < 0)
2455 error (EXIT_FAILURE, 0, "set_crt[%d]: %s", i,
2456 gnutls_strerror (result));
2458 indx = result;
2460 if (i==0) /* only the first certificate gets the friendly name */
2462 result = gnutls_pkcs12_bag_set_friendly_name (bag, indx, name);
2463 if (result < 0)
2464 error (EXIT_FAILURE, 0, "bag_set_friendly_name: %s",
2465 gnutls_strerror (result));
2468 size = sizeof (_key_id);
2469 result = gnutls_x509_crt_get_key_id (crts[i], 0, _key_id, &size);
2470 if (result < 0)
2471 error (EXIT_FAILURE, 0, "key_id[%d]: %s", i,
2472 gnutls_strerror (result));
2474 key_id.data = _key_id;
2475 key_id.size = size;
2477 result = gnutls_pkcs12_bag_set_key_id (bag, indx, &key_id);
2478 if (result < 0)
2479 error (EXIT_FAILURE, 0, "bag_set_key_id: %s",
2480 gnutls_strerror (result));
2482 flags = cipher_to_flags (cinfo->pkcs_cipher);
2484 result = gnutls_pkcs12_bag_encrypt (bag, pass, flags);
2485 if (result < 0)
2486 error (EXIT_FAILURE, 0, "bag_encrypt: %s", gnutls_strerror (result));
2488 result = gnutls_pkcs12_set_bag (pkcs12, bag);
2489 if (result < 0)
2490 error (EXIT_FAILURE, 0, "set_bag: %s", gnutls_strerror (result));
2493 for (i = 0; i < nkeys; i++)
2495 gnutls_pkcs12_bag_t kbag;
2497 result = gnutls_pkcs12_bag_init (&kbag);
2498 if (result < 0)
2499 error (EXIT_FAILURE, 0, "bag_init: %s", gnutls_strerror (result));
2501 flags = cipher_to_flags (cinfo->pkcs_cipher);
2503 size = buffer_size;
2504 result =
2505 gnutls_x509_privkey_export_pkcs8 (keys[i], GNUTLS_X509_FMT_DER,
2506 pass, flags, buffer, &size);
2507 if (result < 0)
2508 error (EXIT_FAILURE, 0, "key_export[%d]: %s", i, gnutls_strerror (result));
2510 data.data = buffer;
2511 data.size = size;
2512 result =
2513 gnutls_pkcs12_bag_set_data (kbag,
2514 GNUTLS_BAG_PKCS8_ENCRYPTED_KEY, &data);
2515 if (result < 0)
2516 error (EXIT_FAILURE, 0, "bag_set_data: %s", gnutls_strerror (result));
2518 indx = result;
2520 result = gnutls_pkcs12_bag_set_friendly_name (kbag, indx, name);
2521 if (result < 0)
2522 error (EXIT_FAILURE, 0, "bag_set_friendly_name: %s",
2523 gnutls_strerror (result));
2525 size = sizeof (_key_id);
2526 result = gnutls_x509_privkey_get_key_id (keys[i], 0, _key_id, &size);
2527 if (result < 0)
2528 error (EXIT_FAILURE, 0, "key_id[%d]: %s", i, gnutls_strerror (result));
2530 key_id.data = _key_id;
2531 key_id.size = size;
2533 result = gnutls_pkcs12_bag_set_key_id (kbag, indx, &key_id);
2534 if (result < 0)
2535 error (EXIT_FAILURE, 0, "bag_set_key_id: %s",
2536 gnutls_strerror (result));
2538 result = gnutls_pkcs12_set_bag (pkcs12, kbag);
2539 if (result < 0)
2540 error (EXIT_FAILURE, 0, "set_bag: %s", gnutls_strerror (result));
2543 result = gnutls_pkcs12_generate_mac (pkcs12, pass);
2544 if (result < 0)
2545 error (EXIT_FAILURE, 0, "generate_mac: %s", gnutls_strerror (result));
2547 size = buffer_size;
2548 result = gnutls_pkcs12_export (pkcs12, outcert_format, buffer, &size);
2549 if (result < 0)
2550 error (EXIT_FAILURE, 0, "pkcs12_export: %s", gnutls_strerror (result));
2552 fwrite (buffer, 1, size, outfile);
2556 static const char *
2557 BAGTYPE (gnutls_pkcs12_bag_type_t x)
2559 switch (x)
2561 case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY:
2562 return "PKCS #8 Encrypted key";
2563 case GNUTLS_BAG_EMPTY:
2564 return "Empty";
2565 case GNUTLS_BAG_PKCS8_KEY:
2566 return "PKCS #8 Key";
2567 case GNUTLS_BAG_CERTIFICATE:
2568 return "Certificate";
2569 case GNUTLS_BAG_ENCRYPTED:
2570 return "Encrypted";
2571 case GNUTLS_BAG_CRL:
2572 return "CRL";
2573 case GNUTLS_BAG_SECRET:
2574 return "Secret";
2575 default:
2576 return "Unknown";
2580 static void
2581 print_bag_data (gnutls_pkcs12_bag_t bag)
2583 int result;
2584 int count, i, type;
2585 gnutls_datum_t cdata, id;
2586 const char *str, *name;
2587 gnutls_datum_t out;
2589 count = gnutls_pkcs12_bag_get_count (bag);
2590 if (count < 0)
2591 error (EXIT_FAILURE, 0, "get_count: %s", gnutls_strerror (count));
2593 fprintf (outfile, "\tElements: %d\n", count);
2595 for (i = 0; i < count; i++)
2597 type = gnutls_pkcs12_bag_get_type (bag, i);
2598 if (type < 0)
2599 error (EXIT_FAILURE, 0, "get_type: %s", gnutls_strerror (type));
2601 fprintf (stderr, "\tType: %s\n", BAGTYPE (type));
2603 name = NULL;
2604 result = gnutls_pkcs12_bag_get_friendly_name (bag, i, (char **) &name);
2605 if (result < 0)
2606 error (EXIT_FAILURE, 0, "get_friendly_name: %s",
2607 gnutls_strerror (type));
2608 if (name)
2609 fprintf (outfile, "\tFriendly name: %s\n", name);
2611 id.data = NULL;
2612 id.size = 0;
2613 result = gnutls_pkcs12_bag_get_key_id (bag, i, &id);
2614 if (result < 0)
2615 error (EXIT_FAILURE, 0, "get_key_id: %s", gnutls_strerror (type));
2616 if (id.size > 0)
2617 fprintf (outfile, "\tKey ID: %s\n", raw_to_string (id.data, id.size));
2619 result = gnutls_pkcs12_bag_get_data (bag, i, &cdata);
2620 if (result < 0)
2621 error (EXIT_FAILURE, 0, "get_data: %s", gnutls_strerror (result));
2623 switch (type)
2625 case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY:
2626 str = "ENCRYPTED PRIVATE KEY";
2627 break;
2628 case GNUTLS_BAG_PKCS8_KEY:
2629 str = "PRIVATE KEY";
2630 break;
2631 case GNUTLS_BAG_CERTIFICATE:
2632 str = "CERTIFICATE";
2633 break;
2634 case GNUTLS_BAG_CRL:
2635 str = "CRL";
2636 break;
2637 case GNUTLS_BAG_ENCRYPTED:
2638 case GNUTLS_BAG_EMPTY:
2639 default:
2640 str = NULL;
2643 if (str != NULL)
2645 gnutls_pem_base64_encode_alloc (str, &cdata, &out);
2646 fprintf (outfile, "%s\n", out.data);
2648 gnutls_free (out.data);
2654 void
2655 pkcs12_info (common_info_st* cinfo)
2657 gnutls_pkcs12_t pkcs12;
2658 gnutls_pkcs12_bag_t bag;
2659 int result;
2660 size_t size;
2661 gnutls_datum_t data;
2662 const char *pass;
2663 int indx;
2665 result = gnutls_pkcs12_init (&pkcs12);
2666 if (result < 0)
2667 error (EXIT_FAILURE, 0, "p12_init: %s", gnutls_strerror (result));
2669 data.data = (void*)fread_file (infile, &size);
2670 data.size = size;
2672 result = gnutls_pkcs12_import (pkcs12, &data, incert_format, 0);
2673 free (data.data);
2674 if (result < 0)
2675 error (EXIT_FAILURE, 0, "p12_import: %s", gnutls_strerror (result));
2677 if (cinfo->password)
2678 pass = cinfo->password;
2679 else
2680 pass = get_pass ();
2682 result = gnutls_pkcs12_verify_mac (pkcs12, pass);
2683 if (result < 0)
2684 error (0, 0, "verify_mac: %s", gnutls_strerror (result));
2686 for (indx = 0;; indx++)
2688 result = gnutls_pkcs12_bag_init (&bag);
2689 if (result < 0)
2690 error (EXIT_FAILURE, 0, "bag_init: %s", gnutls_strerror (result));
2692 result = gnutls_pkcs12_get_bag (pkcs12, indx, bag);
2693 if (result < 0)
2694 break;
2696 result = gnutls_pkcs12_bag_get_count (bag);
2697 if (result < 0)
2698 error (EXIT_FAILURE, 0, "bag_count: %s", gnutls_strerror (result));
2700 fprintf (outfile, "BAG #%d\n", indx);
2702 result = gnutls_pkcs12_bag_get_type (bag, 0);
2703 if (result < 0)
2704 error (EXIT_FAILURE, 0, "bag_init: %s", gnutls_strerror (result));
2706 if (result == GNUTLS_BAG_ENCRYPTED)
2708 fprintf (stderr, "\tType: %s\n", BAGTYPE (result));
2709 fprintf (stderr, "\n\tDecrypting...\n");
2711 result = gnutls_pkcs12_bag_decrypt (bag, pass);
2713 if (result < 0)
2715 error (0, 0, "bag_decrypt: %s", gnutls_strerror (result));
2716 continue;
2719 result = gnutls_pkcs12_bag_get_count (bag);
2720 if (result < 0)
2721 error (EXIT_FAILURE, 0, "encrypted bag_count: %s",
2722 gnutls_strerror (result));
2725 print_bag_data (bag);
2727 gnutls_pkcs12_bag_deinit (bag);
2731 void
2732 pkcs7_info (void)
2734 gnutls_pkcs7_t pkcs7;
2735 int result;
2736 size_t size;
2737 gnutls_datum_t data, b64;
2738 int indx, count;
2740 result = gnutls_pkcs7_init (&pkcs7);
2741 if (result < 0)
2742 error (EXIT_FAILURE, 0, "p7_init: %s", gnutls_strerror (result));
2744 data.data = (void*)fread_file (infile, &size);
2745 data.size = size;
2747 result = gnutls_pkcs7_import (pkcs7, &data, incert_format);
2748 free (data.data);
2749 if (result < 0)
2750 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (result));
2752 /* Read and print the certificates.
2754 result = gnutls_pkcs7_get_crt_count (pkcs7);
2755 if (result < 0)
2756 error (EXIT_FAILURE, 0, "p7_crt_count: %s", gnutls_strerror (result));
2758 count = result;
2760 if (count > 0)
2761 fprintf (outfile, "Number of certificates: %u\n", count);
2763 for (indx = 0; indx < count; indx++)
2765 fputs ("\n", outfile);
2767 size = buffer_size;
2768 result = gnutls_pkcs7_get_crt_raw (pkcs7, indx, buffer, &size);
2769 if (result < 0)
2770 break;
2772 data.data = buffer;
2773 data.size = size;
2775 result = gnutls_pem_base64_encode_alloc ("CERTIFICATE", &data, &b64);
2776 if (result < 0)
2777 error (EXIT_FAILURE, 0, "encoding: %s", gnutls_strerror (result));
2779 fputs ((void*)b64.data, outfile);
2780 gnutls_free (b64.data);
2783 /* Read the CRLs now.
2785 result = gnutls_pkcs7_get_crl_count (pkcs7);
2786 if (result < 0)
2787 error (EXIT_FAILURE, 0, "p7_crl_count: %s", gnutls_strerror (result));
2789 count = result;
2791 if (count > 0)
2792 fprintf (outfile, "\nNumber of CRLs: %u\n", count);
2794 for (indx = 0; indx < count; indx++)
2796 fputs ("\n", outfile);
2798 size = buffer_size;
2799 result = gnutls_pkcs7_get_crl_raw (pkcs7, indx, buffer, &size);
2800 if (result < 0)
2801 break;
2803 data.data = buffer;
2804 data.size = size;
2806 result = gnutls_pem_base64_encode_alloc ("X509 CRL", &data, &b64);
2807 if (result < 0)
2808 error (EXIT_FAILURE, 0, "encoding: %s", gnutls_strerror (result));
2810 fputs ((void*)b64.data, outfile);
2811 gnutls_free (b64.data);
2815 void
2816 smime_to_pkcs7 (void)
2818 size_t linesize = 0;
2819 char *lineptr = NULL;
2820 ssize_t len;
2822 /* Find body. FIXME: Handle non-b64 Content-Transfer-Encoding.
2823 Reject non-S/MIME tagged Content-Type's? */
2826 len = getline (&lineptr, &linesize, infile);
2827 if (len == -1)
2828 error (EXIT_FAILURE, 0, "cannot find RFC 2822 header/body separator");
2830 while (strcmp (lineptr, "\r\n") != 0 && strcmp (lineptr, "\n") != 0);
2834 len = getline (&lineptr, &linesize, infile);
2835 if (len == -1)
2836 error (EXIT_FAILURE, 0, "message has RFC 2822 header but no body");
2838 while (strcmp (lineptr, "\r\n") == 0 && strcmp (lineptr, "\n") == 0);
2840 fprintf (outfile, "%s", "-----BEGIN PKCS7-----\n");
2844 while (len > 0
2845 && (lineptr[len - 1] == '\r' || lineptr[len - 1] == '\n'))
2846 lineptr[--len] = '\0';
2847 if (strcmp (lineptr, "") != 0)
2848 fprintf (outfile, "%s\n", lineptr);
2849 len = getline (&lineptr, &linesize, infile);
2851 while (len != -1);
2853 fprintf (outfile, "%s", "-----END PKCS7-----\n");
2855 free (lineptr);
2858 static void
2859 print_key_usage (FILE * outfile, unsigned int usage)
2861 if (usage & GNUTLS_KEY_DIGITAL_SIGNATURE)
2863 fprintf (outfile, "\tDigital signature.\n");
2866 if (usage & GNUTLS_KEY_NON_REPUDIATION)
2868 fprintf (outfile, "\tNon repudiation.\n");
2871 if (usage & GNUTLS_KEY_KEY_ENCIPHERMENT)
2873 fprintf (outfile, "\tKey encipherment.\n");
2876 if (usage & GNUTLS_KEY_DATA_ENCIPHERMENT)
2878 fprintf (outfile, "\tData encipherment.\n");
2881 if (usage & GNUTLS_KEY_KEY_AGREEMENT)
2883 fprintf (outfile, "\tKey agreement.\n");
2886 if (usage & GNUTLS_KEY_KEY_CERT_SIGN)
2888 fprintf (outfile, "\tCertificate signing.\n");
2891 if (usage & GNUTLS_KEY_NON_REPUDIATION)
2893 fprintf (outfile, "\tCRL signing.\n");
2896 if (usage & GNUTLS_KEY_ENCIPHER_ONLY)
2898 fprintf (outfile, "\tKey encipher only.\n");
2901 if (usage & GNUTLS_KEY_DECIPHER_ONLY)
2903 fprintf (outfile, "\tKey decipher only.\n");
2907 void
2908 pubkey_info (gnutls_x509_crt_t crt, common_info_st * cinfo)
2910 gnutls_pubkey_t pubkey;
2911 unsigned int bits, usage;
2912 int ret;
2913 size_t size;
2914 const char *cprint;
2916 ret = gnutls_pubkey_init (&pubkey);
2917 if (ret < 0)
2919 error (EXIT_FAILURE, 0, "pubkey_init: %s", gnutls_strerror (ret));
2922 if (crt == NULL)
2924 crt = load_cert (0, cinfo);
2927 if (crt != NULL)
2929 ret = gnutls_pubkey_import_x509 (pubkey, crt, 0);
2930 if (ret < 0)
2932 error (EXIT_FAILURE, 0, "pubkey_import_x509: %s",
2933 gnutls_strerror (ret));
2936 else
2938 pubkey = load_pubkey (1, cinfo);
2941 if (outcert_format == GNUTLS_X509_FMT_DER)
2943 size = buffer_size;
2944 ret = gnutls_pubkey_export (pubkey, outcert_format, buffer, &size);
2945 if (ret < 0)
2946 error (EXIT_FAILURE, 0, "export error: %s", gnutls_strerror (ret));
2948 fwrite (buffer, 1, size, outfile);
2950 gnutls_pubkey_deinit (pubkey);
2952 return;
2955 /* PEM */
2957 fprintf (outfile, "Public Key Info:\n\n");
2958 ret = gnutls_pubkey_get_pk_algorithm (pubkey, &bits);
2959 fprintf (outfile, "Public Key Algorithm: ");
2961 cprint = gnutls_pk_algorithm_get_name (ret);
2962 fprintf (outfile, "%s (%u bits)\n", cprint ? cprint : "Unknown", bits);
2965 /* Print the raw public and private keys
2967 if (ret == GNUTLS_PK_RSA)
2969 gnutls_datum_t m, e;
2971 ret = gnutls_pubkey_get_pk_rsa_raw (pubkey, &m, &e);
2972 if (ret < 0)
2973 fprintf (stderr, "Error in key RSA data export: %s\n",
2974 gnutls_strerror (ret));
2975 else
2977 print_rsa_pkey (&m, &e, NULL, NULL, NULL, NULL, NULL, NULL);
2978 gnutls_free (m.data);
2979 gnutls_free (e.data);
2982 else if (ret == GNUTLS_PK_DSA)
2984 gnutls_datum_t p, q, g, y;
2986 ret = gnutls_pubkey_get_pk_dsa_raw (pubkey, &p, &q, &g, &y);
2987 if (ret < 0)
2988 fprintf (stderr, "Error in key DSA data export: %s\n",
2989 gnutls_strerror (ret));
2990 else
2992 print_dsa_pkey (NULL, &y, &p, &q, &g);
2993 gnutls_free (y.data);
2994 gnutls_free (p.data);
2995 gnutls_free (q.data);
2996 gnutls_free (g.data);
2999 else if (ret == GNUTLS_PK_EC)
3001 gnutls_datum_t x, y;
3002 gnutls_ecc_curve_t curve;
3004 ret = gnutls_pubkey_get_pk_ecc_raw (pubkey, &curve, &x, &y);
3005 if (ret < 0)
3006 fprintf (stderr, "Error in key ECC data export: %s\n",
3007 gnutls_strerror (ret));
3008 else
3010 print_ecc_pkey (curve, NULL, &y, &x);
3011 gnutls_free (y.data);
3012 gnutls_free (x.data);
3016 ret = gnutls_pubkey_get_key_usage (pubkey, &usage);
3017 if (ret < 0)
3019 error (EXIT_FAILURE, 0, "pubkey_get_key_usage: %s",
3020 gnutls_strerror (ret));
3023 fprintf (outfile, "Public Key Usage:\n");
3024 print_key_usage (outfile, usage);
3026 fprintf (outfile, "\n");
3028 size = buffer_size;
3029 if ((ret = gnutls_pubkey_get_key_id (pubkey, 0, buffer, &size)) < 0)
3031 fprintf (stderr, "Error in key id calculation: %s\n",
3032 gnutls_strerror (ret));
3034 else
3036 fprintf (outfile, "Public Key ID: %s\n", raw_to_string (buffer, size));
3039 size = buffer_size;
3040 ret = gnutls_pubkey_export (pubkey, GNUTLS_X509_FMT_PEM, buffer, &size);
3041 if (ret < 0)
3042 error (EXIT_FAILURE, 0, "export error: %s", gnutls_strerror (ret));
3044 fprintf (outfile, "\n%s\n", buffer);
3046 gnutls_pubkey_deinit (pubkey);