corrected news entry.
[gnutls.git] / src / certtool.c
blob7cc88d5997bb7796281d830a55a2ff9d4cee2395
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 static void privkey_info_int (common_info_st*, gnutls_x509_privkey_t key);
53 static void print_crl_info (gnutls_x509_crl_t crl, FILE * out);
54 void pkcs7_info (void);
55 void crq_info (void);
56 void smime_to_pkcs7 (void);
57 void pkcs12_info (common_info_st*);
58 void generate_pkcs12 (common_info_st *);
59 void generate_pkcs8 (common_info_st *);
60 static void verify_chain (void);
61 void verify_crl (common_info_st * cinfo);
62 void pubkey_info (gnutls_x509_crt_t crt, common_info_st *);
63 void pgp_privkey_info (void);
64 void pgp_ring_info (void);
65 void certificate_info (int, common_info_st *);
66 void pgp_certificate_info (void);
67 void crl_info (void);
68 void privkey_info (common_info_st*);
69 static void cmd_parser (int argc, char **argv);
70 void generate_self_signed (common_info_st *);
71 void generate_request (common_info_st *);
72 static void print_certificate_info (gnutls_x509_crt_t crt, FILE * out,
73 unsigned int all);
74 static void verify_certificate (common_info_st * cinfo);
76 static void print_hex_datum (gnutls_datum_t * dat);
78 FILE *outfile;
79 FILE *infile;
80 static gnutls_digest_algorithm_t default_dig;
81 static unsigned int incert_format, outcert_format;
82 static unsigned int req_key_type;
84 /* non interactive operation if set
86 int batch;
89 static void
90 tls_log_func (int level, const char *str)
92 fprintf (stderr, "|<%d>| %s", level, str);
95 int
96 main (int argc, char **argv)
98 set_program_name (argv[0]);
99 cfg_init ();
100 cmd_parser (argc, argv);
102 return 0;
105 static const char *
106 raw_to_string (const unsigned char *raw, size_t raw_size)
108 static char buf[1024];
109 size_t i;
110 if (raw_size == 0)
111 return NULL;
113 if (raw_size * 3 + 1 >= sizeof (buf))
114 return NULL;
116 for (i = 0; i < raw_size; i++)
118 sprintf (&(buf[i * 3]), "%02X%s", raw[i],
119 (i == raw_size - 1) ? "" : ":");
121 buf[sizeof (buf) - 1] = '\0';
123 return buf;
126 static void
127 print_dsa_pkey (gnutls_datum_t * x, gnutls_datum_t * y, gnutls_datum_t * p,
128 gnutls_datum_t * q, gnutls_datum_t * g)
130 if (x)
132 fprintf (outfile, "private key:");
133 print_hex_datum (x);
135 fprintf (outfile, "public key:");
136 print_hex_datum (y);
137 fprintf (outfile, "p:");
138 print_hex_datum (p);
139 fprintf (outfile, "q:");
140 print_hex_datum (q);
141 fprintf (outfile, "g:");
142 print_hex_datum (g);
145 static void
146 print_ecc_pkey (gnutls_ecc_curve_t curve, gnutls_datum_t* k, gnutls_datum_t * x, gnutls_datum_t * y)
148 fprintf (outfile, "curve:\t%s\n", gnutls_ecc_curve_get_name(curve));
149 if (k)
151 fprintf (outfile, "private key:");
152 print_hex_datum (k);
154 fprintf (outfile, "x:");
155 print_hex_datum (x);
156 fprintf (outfile, "y:");
157 print_hex_datum (y);
160 static void
161 print_rsa_pkey (gnutls_datum_t * m, gnutls_datum_t * e, gnutls_datum_t * d,
162 gnutls_datum_t * p, gnutls_datum_t * q, gnutls_datum_t * u,
163 gnutls_datum_t * exp1, gnutls_datum_t * exp2)
165 fprintf (outfile, "modulus:");
166 print_hex_datum (m);
167 fprintf (outfile, "public exponent:");
168 print_hex_datum (e);
169 if (d)
171 fprintf (outfile, "private exponent:");
172 print_hex_datum (d);
173 fprintf (outfile, "prime1:");
174 print_hex_datum (p);
175 fprintf (outfile, "prime2:");
176 print_hex_datum (q);
177 fprintf (outfile, "coefficient:");
178 print_hex_datum (u);
179 if (exp1 && exp2)
181 fprintf (outfile, "exp1:");
182 print_hex_datum (exp1);
183 fprintf (outfile, "exp2:");
184 print_hex_datum (exp2);
189 static gnutls_x509_privkey_t
190 generate_private_key_int (common_info_st * cinfo)
192 gnutls_x509_privkey_t key;
193 int ret, key_type, bits;
195 key_type = req_key_type;
197 ret = gnutls_x509_privkey_init (&key);
198 if (ret < 0)
199 error (EXIT_FAILURE, 0, "privkey_init: %s", gnutls_strerror (ret));
201 bits = get_bits (key_type, cinfo->bits, cinfo->sec_param);
203 fprintf (stderr, "Generating a %d bit %s private key...\n",
204 bits, gnutls_pk_algorithm_get_name (key_type));
206 if (bits > 1024 && key_type == GNUTLS_PK_DSA)
207 fprintf (stderr,
208 "Note that DSA keys with size over 1024 can only be used with TLS 1.2 or later.\n\n");
210 ret = gnutls_x509_privkey_generate (key, key_type, bits, 0);
211 if (ret < 0)
212 error (EXIT_FAILURE, 0, "privkey_generate: %s", gnutls_strerror (ret));
214 ret = gnutls_x509_privkey_verify_params (key);
215 if (ret < 0)
216 error (EXIT_FAILURE, 0, "privkey_verify_params: %s", gnutls_strerror (ret));
218 return key;
221 static int
222 cipher_to_flags (const char *cipher)
224 if (cipher == NULL)
226 return GNUTLS_PKCS_USE_PBES2_AES_128;
228 else if (strcasecmp (cipher, "3des") == 0)
230 return GNUTLS_PKCS_USE_PBES2_3DES;
232 else if (strcasecmp (cipher, "3des-pkcs12") == 0)
234 return GNUTLS_PKCS_USE_PKCS12_3DES;
236 else if (strcasecmp (cipher, "arcfour") == 0)
238 return GNUTLS_PKCS_USE_PKCS12_ARCFOUR;
240 else if (strcasecmp (cipher, "aes-128") == 0)
242 return GNUTLS_PKCS_USE_PBES2_AES_128;
244 else if (strcasecmp (cipher, "aes-192") == 0)
246 return GNUTLS_PKCS_USE_PBES2_AES_192;
248 else if (strcasecmp (cipher, "aes-256") == 0)
250 return GNUTLS_PKCS_USE_PBES2_AES_256;
252 else if (strcasecmp (cipher, "rc2-40") == 0)
254 return GNUTLS_PKCS_USE_PKCS12_RC2_40;
257 error (EXIT_FAILURE, 0, "unknown cipher %s\n", cipher);
258 return -1;
262 static void
263 print_private_key (common_info_st* cinfo, gnutls_x509_privkey_t key)
265 int ret;
266 size_t size;
268 if (!key)
269 return;
271 if (outcert_format == GNUTLS_X509_FMT_PEM)
272 privkey_info_int(cinfo, key);
274 if (!cinfo->pkcs8)
276 size = buffer_size;
277 ret = gnutls_x509_privkey_export (key, outcert_format,
278 buffer, &size);
279 if (ret < 0)
280 error (EXIT_FAILURE, 0, "privkey_export: %s", gnutls_strerror (ret));
282 else
284 unsigned int flags;
285 const char *pass;
287 flags = cipher_to_flags (cinfo->pkcs_cipher);
289 if ((pass = get_confirmed_pass (true)) == NULL || *pass == '\0')
290 flags = GNUTLS_PKCS_PLAIN;
292 size = buffer_size;
293 ret =
294 gnutls_x509_privkey_export_pkcs8 (key, outcert_format, pass,
295 flags, buffer, &size);
296 if (ret < 0)
297 error (EXIT_FAILURE, 0, "privkey_export_pkcs8: %s",
298 gnutls_strerror (ret));
301 fwrite (buffer, 1, size, outfile);
304 static void
305 generate_private_key (common_info_st* cinfo)
307 gnutls_x509_privkey_t key;
309 key = generate_private_key_int (cinfo);
311 print_private_key (cinfo, key);
313 gnutls_x509_privkey_deinit (key);
317 static gnutls_x509_crt_t
318 generate_certificate (gnutls_privkey_t * ret_key,
319 gnutls_x509_crt_t ca_crt, int proxy,
320 common_info_st * cinfo)
322 gnutls_x509_crt_t crt;
323 gnutls_privkey_t key = NULL;
324 gnutls_pubkey_t pubkey;
325 size_t size;
326 int ret;
327 int client;
328 int days, result, ca_status = 0, is_ike = 0, path_len;
329 int vers;
330 unsigned int usage = 0, server;
331 gnutls_x509_crq_t crq; /* request */
333 ret = gnutls_x509_crt_init (&crt);
334 if (ret < 0)
335 error (EXIT_FAILURE, 0, "crt_init: %s", gnutls_strerror (ret));
337 crq = load_request (cinfo);
339 if (crq == NULL)
342 key = load_private_key (1, cinfo);
344 pubkey = load_public_key_or_import (1, key, cinfo);
346 if (!batch)
347 fprintf (stderr,
348 "Please enter the details of the certificate's distinguished name. "
349 "Just press enter to ignore a field.\n");
351 /* set the DN.
353 if (proxy)
355 result = gnutls_x509_crt_set_proxy_dn (crt, ca_crt, 0, NULL, 0);
356 if (result < 0)
357 error (EXIT_FAILURE, 0, "set_proxy_dn: %s",
358 gnutls_strerror (result));
360 get_cn_crt_set (crt);
362 else
364 get_country_crt_set (crt);
365 get_organization_crt_set (crt);
366 get_unit_crt_set (crt);
367 get_locality_crt_set (crt);
368 get_state_crt_set (crt);
369 get_cn_crt_set (crt);
370 get_dc_set (TYPE_CRT, crt);
371 get_uid_crt_set (crt);
372 get_oid_crt_set (crt);
373 get_key_purpose_set (crt);
375 if (!batch)
376 fprintf (stderr,
377 "This field should not be used in new certificates.\n");
379 get_pkcs9_email_crt_set (crt);
382 result = gnutls_x509_crt_set_pubkey (crt, pubkey);
383 if (result < 0)
384 error (EXIT_FAILURE, 0, "set_key: %s", gnutls_strerror (result));
386 else
388 result = gnutls_x509_crt_set_crq (crt, crq);
389 if (result < 0)
390 error (EXIT_FAILURE, 0, "set_crq: %s", gnutls_strerror (result));
395 int serial = get_serial ();
396 char bin_serial[5];
398 bin_serial[4] = serial & 0xff;
399 bin_serial[3] = (serial >> 8) & 0xff;
400 bin_serial[2] = (serial >> 16) & 0xff;
401 bin_serial[1] = (serial >> 24) & 0xff;
402 bin_serial[0] = 0;
404 result = gnutls_x509_crt_set_serial (crt, bin_serial, 5);
405 if (result < 0)
406 error (EXIT_FAILURE, 0, "serial: %s", gnutls_strerror (result));
409 if (!batch)
410 fprintf (stderr, "\n\nActivation/Expiration time.\n");
412 gnutls_x509_crt_set_activation_time (crt, time (NULL));
414 days = get_days ();
416 result =
417 gnutls_x509_crt_set_expiration_time (crt,
418 time (NULL) + ((time_t) days) * 24 * 60 * 60);
419 if (result < 0)
420 error (EXIT_FAILURE, 0, "set_expiration: %s", gnutls_strerror (result));
422 if (!batch)
423 fprintf (stderr, "\n\nExtensions.\n");
425 /* do not allow extensions on a v1 certificate */
426 if (crq && get_crq_extensions_status () != 0)
428 result = gnutls_x509_crt_set_crq_extensions (crt, crq);
429 if (result < 0)
430 error (EXIT_FAILURE, 0, "set_crq: %s", gnutls_strerror (result));
433 /* append additional extensions */
434 if (cinfo->v1_cert == 0)
437 if (proxy)
439 const char *policylanguage;
440 char *policy;
441 size_t policylen;
442 int proxypathlen = get_path_len ();
444 if (!batch)
446 printf ("1.3.6.1.5.5.7.21.1 ::= id-ppl-inheritALL\n");
447 printf ("1.3.6.1.5.5.7.21.2 ::= id-ppl-independent\n");
450 policylanguage = get_proxy_policy (&policy, &policylen);
452 result =
453 gnutls_x509_crt_set_proxy (crt, proxypathlen, policylanguage,
454 policy, policylen);
455 if (result < 0)
456 error (EXIT_FAILURE, 0, "set_proxy: %s",
457 gnutls_strerror (result));
460 if (!proxy)
461 ca_status = get_ca_status ();
462 if (ca_status)
463 path_len = get_path_len ();
464 else
465 path_len = -1;
467 result =
468 gnutls_x509_crt_set_basic_constraints (crt, ca_status, path_len);
469 if (result < 0)
470 error (EXIT_FAILURE, 0, "basic_constraints: %s",
471 gnutls_strerror (result));
473 client = get_tls_client_status ();
474 if (client != 0)
476 result = gnutls_x509_crt_set_key_purpose_oid (crt,
477 GNUTLS_KP_TLS_WWW_CLIENT,
479 if (result < 0)
480 error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (result));
483 is_ike = get_ipsec_ike_status ();
484 server = get_tls_server_status ();
486 get_dns_name_set (TYPE_CRT, crt);
487 get_uri_set (TYPE_CRT, crt);
488 get_ip_addr_set (TYPE_CRT, crt);
490 if (server != 0)
492 result = 0;
494 result =
495 gnutls_x509_crt_set_key_purpose_oid (crt,
496 GNUTLS_KP_TLS_WWW_SERVER, 0);
497 if (result < 0)
498 error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (result));
500 else if (!proxy)
502 get_email_set (TYPE_CRT, crt);
505 if (!ca_status || server)
507 int pk;
510 pk = gnutls_x509_crt_get_pk_algorithm (crt, NULL);
512 if (pk != GNUTLS_PK_DSA)
513 { /* DSA keys can only sign.
515 result = get_sign_status (server);
516 if (result)
517 usage |= GNUTLS_KEY_DIGITAL_SIGNATURE;
519 result = get_encrypt_status (server);
520 if (result)
521 usage |= GNUTLS_KEY_KEY_ENCIPHERMENT;
523 else
524 usage |= GNUTLS_KEY_DIGITAL_SIGNATURE;
526 if (is_ike)
528 result =
529 gnutls_x509_crt_set_key_purpose_oid (crt,
530 GNUTLS_KP_IPSEC_IKE, 0);
531 if (result < 0)
532 error (EXIT_FAILURE, 0, "key_kp: %s",
533 gnutls_strerror (result));
538 if (ca_status)
540 result = get_cert_sign_status ();
541 if (result)
542 usage |= GNUTLS_KEY_KEY_CERT_SIGN;
544 result = get_crl_sign_status ();
545 if (result)
546 usage |= GNUTLS_KEY_CRL_SIGN;
548 result = get_code_sign_status ();
549 if (result)
551 result =
552 gnutls_x509_crt_set_key_purpose_oid (crt,
553 GNUTLS_KP_CODE_SIGNING,
555 if (result < 0)
556 error (EXIT_FAILURE, 0, "key_kp: %s",
557 gnutls_strerror (result));
560 result = get_ocsp_sign_status ();
561 if (result)
563 result =
564 gnutls_x509_crt_set_key_purpose_oid (crt,
565 GNUTLS_KP_OCSP_SIGNING,
567 if (result < 0)
568 error (EXIT_FAILURE, 0, "key_kp: %s",
569 gnutls_strerror (result));
572 result = get_time_stamp_status ();
573 if (result)
575 result =
576 gnutls_x509_crt_set_key_purpose_oid (crt,
577 GNUTLS_KP_TIME_STAMPING,
579 if (result < 0)
580 error (EXIT_FAILURE, 0, "key_kp: %s",
581 gnutls_strerror (result));
584 get_ocsp_issuer_set(crt);
585 get_ca_issuers_set(crt);
587 if (usage != 0)
589 /* http://tools.ietf.org/html/rfc4945#section-5.1.3.2: if any KU is
590 set, then either digitalSignature or the nonRepudiation bits in the
591 KeyUsage extension MUST for all IKE certs */
592 if (is_ike && (get_sign_status (server) != 1))
593 usage |= GNUTLS_KEY_NON_REPUDIATION;
594 result = gnutls_x509_crt_set_key_usage (crt, usage);
595 if (result < 0)
596 error (EXIT_FAILURE, 0, "key_usage: %s",
597 gnutls_strerror (result));
600 /* Subject Key ID.
602 size = buffer_size;
603 result = gnutls_x509_crt_get_key_id (crt, 0, buffer, &size);
604 if (result >= 0)
606 result = gnutls_x509_crt_set_subject_key_id (crt, buffer, size);
607 if (result < 0)
608 error (EXIT_FAILURE, 0, "set_subject_key_id: %s",
609 gnutls_strerror (result));
612 /* Authority Key ID.
614 if (ca_crt != NULL)
616 size = buffer_size;
617 result = gnutls_x509_crt_get_subject_key_id (ca_crt, buffer,
618 &size, NULL);
619 if (result < 0)
621 size = buffer_size;
622 result = gnutls_x509_crt_get_key_id (ca_crt, 0, buffer, &size);
624 if (result >= 0)
626 result =
627 gnutls_x509_crt_set_authority_key_id (crt, buffer, size);
628 if (result < 0)
629 error (EXIT_FAILURE, 0, "set_authority_key_id: %s",
630 gnutls_strerror (result));
635 /* Version.
637 if (cinfo->v1_cert != 0)
638 vers = 1;
639 else
640 vers = 3;
641 result = gnutls_x509_crt_set_version (crt, vers);
642 if (result < 0)
643 error (EXIT_FAILURE, 0, "set_version: %s", gnutls_strerror (result));
645 *ret_key = key;
646 return crt;
650 static gnutls_x509_crl_t
651 generate_crl (gnutls_x509_crt_t ca_crt, common_info_st * cinfo)
653 gnutls_x509_crl_t crl;
654 gnutls_x509_crt_t *crts;
655 size_t size;
656 int days, result;
657 unsigned int i;
658 time_t now = time (NULL);
660 result = gnutls_x509_crl_init (&crl);
661 if (result < 0)
662 error (EXIT_FAILURE, 0, "crl_init: %s", gnutls_strerror (result));
664 crts = load_cert_list (0, &size, cinfo);
666 for (i = 0; i < size; i++)
668 result = gnutls_x509_crl_set_crt (crl, crts[i], now);
669 if (result < 0)
670 error (EXIT_FAILURE, 0, "crl_set_crt: %s", gnutls_strerror (result));
673 result = gnutls_x509_crl_set_this_update (crl, now);
674 if (result < 0)
675 error (EXIT_FAILURE, 0, "this_update: %s", gnutls_strerror (result));
677 fprintf (stderr, "Update times.\n");
678 days = get_crl_next_update ();
680 result = gnutls_x509_crl_set_next_update (crl, now + days * 24 * 60 * 60);
681 if (result < 0)
682 error (EXIT_FAILURE, 0, "next_update: %s", gnutls_strerror (result));
684 result = gnutls_x509_crl_set_version (crl, 2);
685 if (result < 0)
686 error (EXIT_FAILURE, 0, "set_version: %s", gnutls_strerror (result));
688 /* Authority Key ID.
690 if (ca_crt != NULL)
692 size = buffer_size;
693 result = gnutls_x509_crt_get_subject_key_id (ca_crt, buffer,
694 &size, NULL);
695 if (result < 0)
697 size = buffer_size;
698 result = gnutls_x509_crt_get_key_id (ca_crt, 0, buffer, &size);
700 if (result >= 0)
702 result = gnutls_x509_crl_set_authority_key_id (crl, buffer, size);
703 if (result < 0)
704 error (EXIT_FAILURE, 0, "set_authority_key_id: %s",
705 gnutls_strerror (result));
710 unsigned int number = get_crl_number ();
711 char bin_number[5];
713 bin_number[4] = number & 0xff;
714 bin_number[3] = (number >> 8) & 0xff;
715 bin_number[2] = (number >> 16) & 0xff;
716 bin_number[1] = (number >> 24) & 0xff;
717 bin_number[0] = 0;
719 result = gnutls_x509_crl_set_number (crl, bin_number, 5);
720 if (result < 0)
721 error (EXIT_FAILURE, 0, "set_number: %s", gnutls_strerror (result));
724 return crl;
727 static gnutls_digest_algorithm_t
728 get_dig_for_pub (gnutls_pubkey_t pubkey)
730 gnutls_digest_algorithm_t dig;
731 int result;
732 unsigned int mand;
734 result = gnutls_pubkey_get_preferred_hash_algorithm (pubkey, &dig, &mand);
735 if (result < 0)
737 error (EXIT_FAILURE, 0, "crt_get_preferred_hash_algorithm: %s",
738 gnutls_strerror (result));
741 /* if algorithm allows alternatives */
742 if (mand == 0 && default_dig != GNUTLS_DIG_UNKNOWN)
743 dig = default_dig;
745 return dig;
748 static gnutls_digest_algorithm_t
749 get_dig (gnutls_x509_crt_t crt)
751 gnutls_digest_algorithm_t dig;
752 gnutls_pubkey_t pubkey;
753 int result;
755 gnutls_pubkey_init(&pubkey);
757 result = gnutls_pubkey_import_x509(pubkey, crt, 0);
758 if (result < 0)
760 error (EXIT_FAILURE, 0, "gnutls_pubkey_import_x509: %s",
761 gnutls_strerror (result));
764 dig = get_dig_for_pub (pubkey);
766 gnutls_pubkey_deinit(pubkey);
768 return dig;
771 void
772 generate_self_signed (common_info_st * cinfo)
774 gnutls_x509_crt_t crt;
775 gnutls_privkey_t key;
776 size_t size;
777 int result;
778 const char *uri;
780 fprintf (stderr, "Generating a self signed certificate...\n");
782 crt = generate_certificate (&key, NULL, 0, cinfo);
784 if (!key)
785 key = load_private_key (1, cinfo);
787 uri = get_crl_dist_point_url ();
788 if (uri)
790 result = gnutls_x509_crt_set_crl_dist_points (crt, GNUTLS_SAN_URI,
791 uri,
792 0 /* all reasons */ );
793 if (result < 0)
794 error (EXIT_FAILURE, 0, "crl_dist_points: %s",
795 gnutls_strerror (result));
798 print_certificate_info (crt, stderr, 0);
800 fprintf (stderr, "\n\nSigning certificate...\n");
802 result = gnutls_x509_crt_privkey_sign (crt, crt, key, get_dig (crt), 0);
803 if (result < 0)
804 error (EXIT_FAILURE, 0, "crt_sign: %s", gnutls_strerror (result));
806 size = buffer_size;
807 result = gnutls_x509_crt_export (crt, outcert_format, buffer, &size);
808 if (result < 0)
809 error (EXIT_FAILURE, 0, "crt_export: %s", gnutls_strerror (result));
811 fwrite (buffer, 1, size, outfile);
813 gnutls_x509_crt_deinit (crt);
814 gnutls_privkey_deinit (key);
817 static void
818 generate_signed_certificate (common_info_st * cinfo)
820 gnutls_x509_crt_t crt;
821 gnutls_privkey_t key;
822 size_t size;
823 int result;
824 gnutls_privkey_t ca_key;
825 gnutls_x509_crt_t ca_crt;
827 fprintf (stderr, "Generating a signed certificate...\n");
829 ca_key = load_ca_private_key (cinfo);
830 ca_crt = load_ca_cert (cinfo);
832 crt = generate_certificate (&key, ca_crt, 0, cinfo);
834 /* Copy the CRL distribution points.
836 gnutls_x509_crt_cpy_crl_dist_points (crt, ca_crt);
837 /* it doesn't matter if we couldn't copy the CRL dist points.
840 print_certificate_info (crt, stderr, 0);
842 fprintf (stderr, "\n\nSigning certificate...\n");
844 result = gnutls_x509_crt_privkey_sign (crt, ca_crt, ca_key, get_dig (ca_crt), 0);
845 if (result < 0)
846 error (EXIT_FAILURE, 0, "crt_sign: %s", gnutls_strerror (result));
848 size = buffer_size;
849 result = gnutls_x509_crt_export (crt, outcert_format, buffer, &size);
850 if (result < 0)
851 error (EXIT_FAILURE, 0, "crt_export: %s", gnutls_strerror (result));
853 fwrite (buffer, 1, size, outfile);
855 gnutls_x509_crt_deinit (crt);
856 gnutls_privkey_deinit (key);
857 gnutls_privkey_deinit(ca_key);
860 static void
861 generate_proxy_certificate (common_info_st * cinfo)
863 gnutls_x509_crt_t crt, eecrt;
864 gnutls_privkey_t key, eekey;
865 size_t size;
866 int result;
868 fprintf (stderr, "Generating a proxy certificate...\n");
870 eekey = load_ca_private_key (cinfo);
871 eecrt = load_cert (1, cinfo);
873 crt = generate_certificate (&key, eecrt, 1, cinfo);
875 print_certificate_info (crt, stderr, 0);
877 fprintf (stderr, "\n\nSigning certificate...\n");
879 result = gnutls_x509_crt_privkey_sign (crt, eecrt, eekey, get_dig (eecrt), 0);
880 if (result < 0)
881 error (EXIT_FAILURE, 0, "crt_sign: %s", gnutls_strerror (result));
883 size = buffer_size;
884 result = gnutls_x509_crt_export (crt, outcert_format, buffer, &size);
885 if (result < 0)
886 error (EXIT_FAILURE, 0, "crt_export: %s", gnutls_strerror (result));
888 fwrite (buffer, 1, size, outfile);
890 gnutls_x509_crt_deinit (eecrt);
891 gnutls_x509_crt_deinit (crt);
892 gnutls_privkey_deinit (key);
893 gnutls_privkey_deinit (eekey);
896 static void
897 generate_signed_crl (common_info_st * cinfo)
899 gnutls_x509_crl_t crl;
900 int result;
901 gnutls_privkey_t ca_key;
902 gnutls_x509_crt_t ca_crt;
904 fprintf (stderr, "Generating a signed CRL...\n");
906 ca_key = load_ca_private_key (cinfo);
907 ca_crt = load_ca_cert (cinfo);
908 crl = generate_crl (ca_crt, cinfo);
910 fprintf (stderr, "\n");
911 result = gnutls_x509_crl_privkey_sign(crl, ca_crt, ca_key, get_dig (ca_crt), 0);
912 if (result < 0)
913 error (EXIT_FAILURE, 0, "crl_privkey_sign: %s", gnutls_strerror (result));
915 print_crl_info (crl, stderr);
917 gnutls_privkey_deinit( ca_key);
918 gnutls_x509_crl_deinit (crl);
921 static void
922 update_signed_certificate (common_info_st * cinfo)
924 gnutls_x509_crt_t crt;
925 size_t size;
926 int result;
927 gnutls_privkey_t ca_key;
928 gnutls_x509_crt_t ca_crt;
929 int days;
930 time_t tim = time (NULL);
932 fprintf (stderr, "Generating a signed certificate...\n");
934 ca_key = load_ca_private_key (cinfo);
935 ca_crt = load_ca_cert (cinfo);
936 crt = load_cert (1, cinfo);
938 fprintf (stderr, "Activation/Expiration time.\n");
939 gnutls_x509_crt_set_activation_time (crt, tim);
941 days = get_days ();
943 result =
944 gnutls_x509_crt_set_expiration_time (crt, tim + ((time_t) days) * 24 * 60 * 60);
945 if (result < 0)
946 error (EXIT_FAILURE, 0, "set_expiration: %s", gnutls_strerror (result));
948 fprintf (stderr, "\n\nSigning certificate...\n");
950 result = gnutls_x509_crt_privkey_sign (crt, ca_crt, ca_key, get_dig (ca_crt), 0);
951 if (result < 0)
952 error (EXIT_FAILURE, 0, "crt_sign: %s", gnutls_strerror (result));
954 size = buffer_size;
955 result = gnutls_x509_crt_export (crt, outcert_format, buffer, &size);
956 if (result < 0)
957 error (EXIT_FAILURE, 0, "crt_export: %s", gnutls_strerror (result));
959 fwrite (buffer, 1, size, outfile);
961 gnutls_x509_crt_deinit (crt);
964 static void
965 cmd_parser (int argc, char **argv)
967 int ret, privkey_op = 0;
968 common_info_st cinfo;
970 optionProcess( &certtoolOptions, argc, argv);
972 if (HAVE_OPT(GENERATE_PRIVKEY) || HAVE_OPT(GENERATE_REQUEST) ||
973 HAVE_OPT(KEY_INFO) || HAVE_OPT(PGP_KEY_INFO))
974 privkey_op = 1;
976 if (HAVE_OPT(OUTFILE))
978 outfile = safe_open_rw (OPT_ARG(OUTFILE), privkey_op);
979 if (outfile == NULL)
980 error (EXIT_FAILURE, errno, "%s", OPT_ARG(OUTFILE));
982 else
983 outfile = stdout;
985 if (HAVE_OPT(INFILE))
987 infile = fopen (OPT_ARG(INFILE), "rb");
988 if (infile == NULL)
989 error (EXIT_FAILURE, errno, "%s", OPT_ARG(INFILE));
991 else
992 infile = stdin;
994 if (HAVE_OPT(INDER) || HAVE_OPT(INRAW))
995 incert_format = GNUTLS_X509_FMT_DER;
996 else
997 incert_format = GNUTLS_X509_FMT_PEM;
999 if (HAVE_OPT(OUTDER) || HAVE_OPT(OUTRAW))
1000 outcert_format = GNUTLS_X509_FMT_DER;
1001 else
1002 outcert_format = GNUTLS_X509_FMT_PEM;
1004 if (HAVE_OPT(DSA))
1005 req_key_type = GNUTLS_PK_DSA;
1006 else if (HAVE_OPT(ECC))
1007 req_key_type = GNUTLS_PK_ECC;
1008 else
1009 req_key_type = GNUTLS_PK_RSA;
1011 default_dig = GNUTLS_DIG_UNKNOWN;
1012 if (HAVE_OPT(HASH))
1014 if (strcasecmp (OPT_ARG(HASH), "md5") == 0)
1016 fprintf (stderr,
1017 "Warning: MD5 is broken, and should not be used any more for digital signatures.\n");
1018 default_dig = GNUTLS_DIG_MD5;
1020 else if (strcasecmp (OPT_ARG(HASH), "sha1") == 0)
1021 default_dig = GNUTLS_DIG_SHA1;
1022 else if (strcasecmp (OPT_ARG(HASH), "sha256") == 0)
1023 default_dig = GNUTLS_DIG_SHA256;
1024 else if (strcasecmp (OPT_ARG(HASH), "sha224") == 0)
1025 default_dig = GNUTLS_DIG_SHA224;
1026 else if (strcasecmp (OPT_ARG(HASH), "sha384") == 0)
1027 default_dig = GNUTLS_DIG_SHA384;
1028 else if (strcasecmp (OPT_ARG(HASH), "sha512") == 0)
1029 default_dig = GNUTLS_DIG_SHA512;
1030 else if (strcasecmp (OPT_ARG(HASH), "rmd160") == 0)
1031 default_dig = GNUTLS_DIG_RMD160;
1032 else
1033 error (EXIT_FAILURE, 0, "invalid hash: %s", OPT_ARG(HASH));
1036 batch = 0;
1037 if (HAVE_OPT(TEMPLATE))
1039 batch = 1;
1040 template_parse (OPT_ARG(TEMPLATE));
1043 gnutls_global_set_log_function (tls_log_func);
1045 if (HAVE_OPT(DEBUG))
1047 gnutls_global_set_log_level (OPT_VALUE_DEBUG);
1048 printf ("Setting log level to %d\n", (int)OPT_VALUE_DEBUG);
1051 if ((ret = gnutls_global_init ()) < 0)
1052 error (EXIT_FAILURE, 0, "global_init: %s", gnutls_strerror (ret));
1054 #ifdef ENABLE_PKCS11
1055 pkcs11_common();
1056 #endif
1058 memset (&cinfo, 0, sizeof (cinfo));
1060 if (HAVE_OPT(LOAD_PRIVKEY))
1061 cinfo.privkey = OPT_ARG(LOAD_PRIVKEY);
1063 cinfo.v1_cert = HAVE_OPT(V1);
1064 if (HAVE_OPT(NO_CRQ_EXTENSIONS))
1065 cinfo.crq_extensions = 0;
1066 else cinfo.crq_extensions = 1;
1068 if (HAVE_OPT(LOAD_PUBKEY))
1069 cinfo.pubkey = OPT_ARG(LOAD_PUBKEY);
1071 cinfo.pkcs8 = HAVE_OPT(PKCS8);
1072 cinfo.incert_format = incert_format;
1074 if (HAVE_OPT(LOAD_CERTIFICATE))
1075 cinfo.cert = OPT_ARG(LOAD_CERTIFICATE);
1077 if (HAVE_OPT(LOAD_REQUEST))
1078 cinfo.request = OPT_ARG(LOAD_REQUEST);
1080 if (HAVE_OPT(LOAD_CA_CERTIFICATE))
1081 cinfo.ca = OPT_ARG(LOAD_CA_CERTIFICATE);
1083 if (HAVE_OPT(LOAD_CA_PRIVKEY))
1084 cinfo.ca_privkey = OPT_ARG(LOAD_CA_PRIVKEY);
1086 if (HAVE_OPT(BITS))
1087 cinfo.bits = OPT_VALUE_BITS;
1089 if (HAVE_OPT(SEC_PARAM))
1090 cinfo.sec_param = OPT_ARG(SEC_PARAM);
1092 if (HAVE_OPT(PKCS_CIPHER))
1093 cinfo.pkcs_cipher = OPT_ARG(PKCS_CIPHER);
1095 if (HAVE_OPT(PASSWORD))
1096 cinfo.password = OPT_ARG(PASSWORD);
1098 if (HAVE_OPT(GENERATE_SELF_SIGNED))
1099 generate_self_signed (&cinfo);
1100 else if (HAVE_OPT(GENERATE_CERTIFICATE))
1101 generate_signed_certificate (&cinfo);
1102 else if (HAVE_OPT(GENERATE_PROXY))
1103 generate_proxy_certificate (&cinfo);
1104 else if (HAVE_OPT(GENERATE_CRL))
1105 generate_signed_crl (&cinfo);
1106 else if (HAVE_OPT(UPDATE_CERTIFICATE))
1107 update_signed_certificate (&cinfo);
1108 else if (HAVE_OPT(GENERATE_PRIVKEY))
1109 generate_private_key (&cinfo);
1110 else if (HAVE_OPT(GENERATE_REQUEST))
1111 generate_request (&cinfo);
1112 else if (HAVE_OPT(VERIFY_CHAIN))
1113 verify_chain ();
1114 else if (HAVE_OPT(VERIFY))
1115 verify_certificate (&cinfo);
1116 else if (HAVE_OPT(VERIFY_CRL))
1117 verify_crl (&cinfo);
1118 else if (HAVE_OPT(CERTIFICATE_INFO))
1119 certificate_info (0, &cinfo);
1120 else if (HAVE_OPT(DH_INFO))
1121 dh_info (&cinfo);
1122 else if (HAVE_OPT(CERTIFICATE_PUBKEY))
1123 certificate_info (1, &cinfo);
1124 else if (HAVE_OPT(KEY_INFO))
1125 privkey_info (&cinfo);
1126 else if (HAVE_OPT(PUBKEY_INFO))
1127 pubkey_info (NULL, &cinfo);
1128 else if (HAVE_OPT(TO_P12))
1129 generate_pkcs12 (&cinfo);
1130 else if (HAVE_OPT(P12_INFO))
1131 pkcs12_info (&cinfo);
1132 else if (HAVE_OPT(GENERATE_DH_PARAMS))
1133 generate_prime (1, &cinfo);
1134 else if (HAVE_OPT(GET_DH_PARAMS))
1135 generate_prime (0, &cinfo);
1136 else if (HAVE_OPT(CRL_INFO))
1137 crl_info ();
1138 else if (HAVE_OPT(P7_INFO))
1139 pkcs7_info ();
1140 else if (HAVE_OPT(SMIME_TO_P7))
1141 smime_to_pkcs7 ();
1142 else if (HAVE_OPT(TO_P8))
1143 generate_pkcs8 (&cinfo);
1144 #ifdef ENABLE_OPENPGP
1145 else if (HAVE_OPT(PGP_CERTIFICATE_INFO))
1146 pgp_certificate_info ();
1147 else if (HAVE_OPT(PGP_KEY_INFO))
1148 pgp_privkey_info ();
1149 else if (HAVE_OPT(PGP_RING_INFO))
1150 pgp_ring_info ();
1151 #endif
1152 else if (HAVE_OPT(CRQ_INFO))
1153 crq_info ();
1154 else
1155 USAGE(1);
1157 fclose (outfile);
1159 #ifdef ENABLE_PKCS11
1160 gnutls_pkcs11_deinit ();
1161 #endif
1162 gnutls_global_deinit ();
1165 #define MAX_CRTS 500
1166 void
1167 certificate_info (int pubkey, common_info_st * cinfo)
1169 gnutls_x509_crt_t crt[MAX_CRTS];
1170 size_t size;
1171 int ret, i, count;
1172 gnutls_datum_t pem;
1173 unsigned int crt_num;
1175 pem.data = (void*)fread_file (infile, &size);
1176 pem.size = size;
1178 crt_num = MAX_CRTS;
1179 ret =
1180 gnutls_x509_crt_list_import (crt, &crt_num, &pem, incert_format,
1181 GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
1182 if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
1184 error (0, 0, "too many certificates (%d); "
1185 "will only read the first %d", crt_num, MAX_CRTS);
1186 crt_num = MAX_CRTS;
1187 ret = gnutls_x509_crt_list_import (crt, &crt_num, &pem,
1188 incert_format, 0);
1190 if (ret < 0)
1191 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (ret));
1193 free (pem.data);
1195 count = ret;
1197 if (count > 1 && outcert_format == GNUTLS_X509_FMT_DER)
1199 error (0, 0, "cannot output multiple certificates in DER format; "
1200 "using PEM instead");
1201 outcert_format = GNUTLS_X509_FMT_PEM;
1204 for (i = 0; i < count; i++)
1206 if (i > 0)
1207 fprintf (outfile, "\n");
1209 if (outcert_format == GNUTLS_X509_FMT_PEM)
1210 print_certificate_info (crt[i], outfile, 1);
1212 if (pubkey)
1213 pubkey_info (crt[i], cinfo);
1214 else
1216 size = buffer_size;
1217 ret = gnutls_x509_crt_export (crt[i], outcert_format, buffer,
1218 &size);
1219 if (ret < 0)
1220 error (EXIT_FAILURE, 0, "export error: %s", gnutls_strerror (ret));
1222 fwrite (buffer, 1, size, outfile);
1225 gnutls_x509_crt_deinit (crt[i]);
1229 #ifdef ENABLE_OPENPGP
1231 void
1232 pgp_certificate_info (void)
1234 gnutls_openpgp_crt_t crt;
1235 size_t size;
1236 int ret;
1237 gnutls_datum_t pem, out_data;
1238 unsigned int verify_status;
1240 pem.data = (void*)fread_file (infile, &size);
1241 pem.size = size;
1243 ret = gnutls_openpgp_crt_init (&crt);
1244 if (ret < 0)
1245 error (EXIT_FAILURE, 0, "openpgp_crt_init: %s", gnutls_strerror (ret));
1247 ret = gnutls_openpgp_crt_import (crt, &pem, incert_format);
1249 if (ret < 0)
1250 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (ret));
1252 free (pem.data);
1254 if (outcert_format == GNUTLS_OPENPGP_FMT_BASE64)
1256 ret = gnutls_openpgp_crt_print (crt, 0, &out_data);
1258 if (ret == 0)
1260 fprintf (outfile, "%s\n", out_data.data);
1261 gnutls_free (out_data.data);
1266 ret = gnutls_openpgp_crt_verify_self (crt, 0, &verify_status);
1267 if (ret < 0)
1269 error (EXIT_FAILURE, 0, "verify signature error: %s",
1270 gnutls_strerror (ret));
1273 if (verify_status & GNUTLS_CERT_INVALID)
1275 fprintf (outfile, "Self Signature verification: failed\n\n");
1277 else
1279 fprintf (outfile, "Self Signature verification: ok (%x)\n\n",
1280 verify_status);
1283 size = buffer_size;
1284 ret = gnutls_openpgp_crt_export (crt, outcert_format, buffer, &size);
1285 if (ret < 0)
1287 error (EXIT_FAILURE, 0, "export error: %s", gnutls_strerror (ret));
1288 fwrite (buffer, 1, size, outfile);
1291 fprintf (outfile, "%s\n", buffer);
1292 gnutls_openpgp_crt_deinit (crt);
1295 void
1296 pgp_privkey_info (void)
1298 gnutls_openpgp_privkey_t key;
1299 unsigned char keyid[GNUTLS_OPENPGP_KEYID_SIZE];
1300 size_t size;
1301 int ret, i, subkeys, bits = 0;
1302 gnutls_datum_t pem;
1303 const char *cprint;
1305 size = fread (buffer, 1, buffer_size - 1, infile);
1306 buffer[size] = 0;
1308 gnutls_openpgp_privkey_init (&key);
1310 pem.data = buffer;
1311 pem.size = size;
1313 ret = gnutls_openpgp_privkey_import (key, &pem, incert_format,
1314 NULL, 0);
1316 if (ret < 0)
1317 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (ret));
1319 /* Public key algorithm
1321 subkeys = gnutls_openpgp_privkey_get_subkey_count (key);
1322 if (subkeys < 0)
1323 error (EXIT_FAILURE, 0, "privkey_get_subkey_count: %s",
1324 gnutls_strerror (subkeys));
1326 for (i = -1; i < subkeys; i++)
1329 if (i != -1)
1330 fprintf (outfile, "Subkey[%d]:\n", i);
1332 fprintf (outfile, "Public Key Info:\n");
1334 if (i == -1)
1335 ret = gnutls_openpgp_privkey_get_pk_algorithm (key, NULL);
1336 else
1337 ret = gnutls_openpgp_privkey_get_subkey_pk_algorithm (key, i, NULL);
1339 fprintf (outfile, "\tPublic Key Algorithm: ");
1340 cprint = gnutls_pk_algorithm_get_name (ret);
1341 fprintf (outfile, "%s\n", cprint ? cprint : "Unknown");
1342 fprintf (outfile, "\tKey Security Level: %s\n",
1343 gnutls_sec_param_get_name (gnutls_openpgp_privkey_sec_param
1344 (key)));
1346 /* Print the raw public and private keys
1349 if (ret == GNUTLS_PK_RSA)
1351 gnutls_datum_t m, e, d, p, q, u;
1353 if (i == -1)
1354 ret =
1355 gnutls_openpgp_privkey_export_rsa_raw (key, &m, &e, &d, &p,
1356 &q, &u);
1357 else
1358 ret =
1359 gnutls_openpgp_privkey_export_subkey_rsa_raw (key, i, &m,
1360 &e, &d, &p,
1361 &q, &u);
1362 if (ret < 0)
1363 fprintf (stderr, "Error in key RSA data export: %s\n",
1364 gnutls_strerror (ret));
1365 else
1366 print_rsa_pkey (&m, &e, &d, &p, &q, &u, NULL, NULL);
1368 bits = m.size * 8;
1370 else if (ret == GNUTLS_PK_DSA)
1372 gnutls_datum_t p, q, g, y, x;
1374 if (i == -1)
1375 ret =
1376 gnutls_openpgp_privkey_export_dsa_raw (key, &p, &q, &g, &y, &x);
1377 else
1378 ret =
1379 gnutls_openpgp_privkey_export_subkey_dsa_raw (key, i, &p,
1380 &q, &g, &y, &x);
1381 if (ret < 0)
1382 fprintf (stderr, "Error in key DSA data export: %s\n",
1383 gnutls_strerror (ret));
1384 else
1385 print_dsa_pkey (&x, &y, &p, &q, &g);
1387 bits = y.size * 8;
1390 fprintf (outfile, "\n");
1392 size = buffer_size;
1393 if (i == -1)
1394 ret = gnutls_openpgp_privkey_get_key_id (key, keyid);
1395 else
1396 ret = gnutls_openpgp_privkey_get_subkey_id (key, i, keyid);
1398 if (ret < 0)
1400 fprintf (stderr, "Error in key id calculation: %s\n",
1401 gnutls_strerror (ret));
1403 else
1405 fprintf (outfile, "Public key ID: %s\n", raw_to_string (keyid, 8));
1408 size = buffer_size;
1409 if (i == -1)
1410 ret = gnutls_openpgp_privkey_get_fingerprint (key, buffer, &size);
1411 else
1412 ret = gnutls_openpgp_privkey_get_subkey_fingerprint (key, i, buffer, &size);
1414 if (ret < 0)
1416 fprintf (stderr, "Error in fingerprint calculation: %s\n",
1417 gnutls_strerror (ret));
1419 else
1421 gnutls_datum_t art;
1423 fprintf (outfile, "Fingerprint: %s\n", raw_to_string (buffer, size));
1425 ret = gnutls_random_art(GNUTLS_RANDOM_ART_OPENSSH, cprint, bits, buffer, size, &art);
1426 if (ret >= 0)
1428 fprintf (outfile, "Fingerprint's random art:\n%s\n\n", art.data);
1429 gnutls_free(art.data);
1434 size = buffer_size;
1435 ret = gnutls_openpgp_privkey_export (key, GNUTLS_OPENPGP_FMT_BASE64,
1436 NULL, 0, buffer, &size);
1437 if (ret < 0)
1438 error (EXIT_FAILURE, 0, "export error: %s", gnutls_strerror (ret));
1440 fprintf (outfile, "\n%s\n", buffer);
1442 gnutls_openpgp_privkey_deinit (key);
1445 void
1446 pgp_ring_info (void)
1448 gnutls_openpgp_keyring_t ring;
1449 gnutls_openpgp_crt_t crt;
1450 size_t size;
1451 int ret, i, count;
1452 gnutls_datum_t pem;
1454 pem.data = (void*)fread_file (infile, &size);
1455 pem.size = size;
1457 ret = gnutls_openpgp_keyring_init (&ring);
1458 if (ret < 0)
1459 error (EXIT_FAILURE, 0, "openpgp_keyring_init: %s",
1460 gnutls_strerror (ret));
1462 ret = gnutls_openpgp_keyring_import (ring, &pem, incert_format);
1464 if (ret < 0)
1465 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (ret));
1467 free (pem.data);
1469 count = gnutls_openpgp_keyring_get_crt_count (ring);
1470 if (count >= 0)
1471 fprintf (outfile, "Keyring contains %d OpenPGP certificates\n\n", count);
1472 else
1473 error (EXIT_FAILURE, 0, "keyring error: %s", gnutls_strerror (count));
1475 for (i = 0; i < count; i++)
1477 ret = gnutls_openpgp_keyring_get_crt (ring, i, &crt);
1478 if (ret < 0)
1479 error (EXIT_FAILURE, 0, "export error: %s", gnutls_strerror (ret));
1481 size = buffer_size;
1482 ret = gnutls_openpgp_crt_export (crt, outcert_format,
1483 buffer, &size);
1484 if (ret < 0)
1485 error (EXIT_FAILURE, 0, "export error: %s", gnutls_strerror (ret));
1487 fwrite (buffer, 1, size, outfile);
1488 fprintf (outfile, "\n\n");
1490 gnutls_openpgp_crt_deinit (crt);
1495 gnutls_openpgp_keyring_deinit (ring);
1499 #endif
1501 static void
1502 print_hex_datum (gnutls_datum_t * dat)
1504 unsigned int j;
1505 #define SPACE "\t"
1506 fprintf (outfile, "\n" SPACE);
1507 for (j = 0; j < dat->size; j++)
1509 fprintf (outfile, "%.2x:", (unsigned char) dat->data[j]);
1510 if ((j + 1) % 15 == 0)
1511 fprintf (outfile, "\n" SPACE);
1513 fprintf (outfile, "\n");
1517 static void
1518 print_certificate_info (gnutls_x509_crt_t crt, FILE * out, unsigned int all)
1520 gnutls_datum_t data;
1521 int ret;
1523 if (all)
1524 ret = gnutls_x509_crt_print (crt, GNUTLS_CRT_PRINT_FULL, &data);
1525 else
1526 ret = gnutls_x509_crt_print (crt, GNUTLS_CRT_PRINT_UNSIGNED_FULL, &data);
1527 if (ret == 0)
1529 fprintf (out, "%s\n", data.data);
1530 gnutls_free (data.data);
1533 if (out == stderr && batch == 0) /* interactive */
1534 if (read_yesno ("Is the above information ok? (y/N): ") == 0)
1536 exit (1);
1540 static void
1541 print_crl_info (gnutls_x509_crl_t crl, FILE * out)
1543 gnutls_datum_t data;
1544 int ret;
1545 size_t size;
1547 ret = gnutls_x509_crl_print (crl, GNUTLS_CRT_PRINT_FULL, &data);
1548 if (ret < 0)
1549 error (EXIT_FAILURE, 0, "crl_print: %s", gnutls_strerror (ret));
1551 fprintf (out, "%s\n", data.data);
1553 gnutls_free (data.data);
1555 size = buffer_size;
1556 ret = gnutls_x509_crl_export (crl, GNUTLS_X509_FMT_PEM, buffer, &size);
1557 if (ret < 0)
1558 error (EXIT_FAILURE, 0, "crl_export: %s", gnutls_strerror (ret));
1560 fwrite (buffer, 1, size, outfile);
1563 void
1564 crl_info (void)
1566 gnutls_x509_crl_t crl;
1567 int ret;
1568 size_t size;
1569 gnutls_datum_t pem;
1571 ret = gnutls_x509_crl_init (&crl);
1572 if (ret < 0)
1573 error (EXIT_FAILURE, 0, "crl_init: %s", gnutls_strerror (ret));
1575 pem.data = (void*)fread_file (infile, &size);
1576 pem.size = size;
1578 if (!pem.data)
1579 error (EXIT_FAILURE, errno, "%s", infile ? "file" :
1580 "standard input");
1582 ret = gnutls_x509_crl_import (crl, &pem, incert_format);
1584 free (pem.data);
1585 if (ret < 0)
1586 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (ret));
1588 print_crl_info (crl, outfile);
1590 gnutls_x509_crl_deinit (crl);
1593 static void
1594 print_crq_info (gnutls_x509_crq_t crq, FILE * out)
1596 gnutls_datum_t data;
1597 int ret;
1598 size_t size;
1600 if (outcert_format == GNUTLS_X509_FMT_PEM)
1602 ret = gnutls_x509_crq_print (crq, GNUTLS_CRT_PRINT_FULL, &data);
1603 if (ret < 0)
1604 error (EXIT_FAILURE, 0, "crq_print: %s", gnutls_strerror (ret));
1606 fprintf (out, "%s\n", data.data);
1608 gnutls_free (data.data);
1611 ret = gnutls_x509_crq_verify(crq, 0);
1612 if (ret < 0)
1614 fprintf(out, "Self signature: FAILED\n\n");
1616 else
1618 fprintf(out, "Self signature: verified\n\n");
1621 size = buffer_size;
1622 ret = gnutls_x509_crq_export (crq, outcert_format, buffer, &size);
1623 if (ret < 0)
1624 error (EXIT_FAILURE, 0, "crq_export: %s", gnutls_strerror (ret));
1626 fwrite (buffer, 1, size, outfile);
1629 void
1630 crq_info (void)
1632 gnutls_x509_crq_t crq;
1633 int ret;
1634 size_t size;
1635 gnutls_datum_t pem;
1637 ret = gnutls_x509_crq_init (&crq);
1638 if (ret < 0)
1639 error (EXIT_FAILURE, 0, "crq_init: %s", gnutls_strerror (ret));
1641 pem.data = (void*)fread_file (infile, &size);
1642 pem.size = size;
1644 if (!pem.data)
1645 error (EXIT_FAILURE, errno, "%s", infile ? "file" :
1646 "standard input");
1648 ret = gnutls_x509_crq_import (crq, &pem, incert_format);
1650 free (pem.data);
1651 if (ret < 0)
1652 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (ret));
1654 print_crq_info (crq, outfile);
1656 gnutls_x509_crq_deinit (crq);
1659 static void privkey_info_int (common_info_st* cinfo, gnutls_x509_privkey_t key)
1661 int ret, key_type, bits = 0;
1662 size_t size;
1663 const char *cprint;
1665 /* Public key algorithm
1667 fprintf (outfile, "Public Key Info:\n");
1668 ret = gnutls_x509_privkey_get_pk_algorithm (key);
1669 fprintf (outfile, "\tPublic Key Algorithm: ");
1671 key_type = ret;
1673 cprint = gnutls_pk_algorithm_get_name (key_type);
1674 fprintf (outfile, "%s\n", cprint ? cprint : "Unknown");
1675 fprintf (outfile, "\tKey Security Level: %s\n\n",
1676 gnutls_sec_param_get_name (gnutls_x509_privkey_sec_param (key)));
1678 /* Print the raw public and private keys
1680 if (key_type == GNUTLS_PK_RSA)
1682 gnutls_datum_t m, e, d, p, q, u, exp1, exp2;
1684 ret =
1685 gnutls_x509_privkey_export_rsa_raw2 (key, &m, &e, &d, &p, &q, &u,
1686 &exp1, &exp2);
1687 if (ret < 0)
1688 fprintf (stderr, "Error in key RSA data export: %s\n",
1689 gnutls_strerror (ret));
1690 else
1692 print_rsa_pkey (&m, &e, &d, &p, &q, &u, &exp1, &exp2);
1693 bits = m.size * 8;
1695 gnutls_free (m.data);
1696 gnutls_free (e.data);
1697 gnutls_free (d.data);
1698 gnutls_free (p.data);
1699 gnutls_free (q.data);
1700 gnutls_free (u.data);
1701 gnutls_free (exp1.data);
1702 gnutls_free (exp2.data);
1705 else if (key_type == GNUTLS_PK_DSA)
1707 gnutls_datum_t p, q, g, y, x;
1709 ret = gnutls_x509_privkey_export_dsa_raw (key, &p, &q, &g, &y, &x);
1710 if (ret < 0)
1711 fprintf (stderr, "Error in key DSA data export: %s\n",
1712 gnutls_strerror (ret));
1713 else
1715 print_dsa_pkey (&x, &y, &p, &q, &g);
1716 bits = y.size * 8;
1718 gnutls_free (x.data);
1719 gnutls_free (y.data);
1720 gnutls_free (p.data);
1721 gnutls_free (q.data);
1722 gnutls_free (g.data);
1725 else if (key_type == GNUTLS_PK_EC)
1727 gnutls_datum_t y, x, k;
1728 gnutls_ecc_curve_t curve;
1730 ret = gnutls_x509_privkey_export_ecc_raw (key, &curve, &x, &y, &k);
1731 if (ret < 0)
1732 fprintf (stderr, "Error in key ECC data export: %s\n",
1733 gnutls_strerror (ret));
1734 else
1736 print_ecc_pkey (curve, &k, &x, &y);
1737 bits = gnutls_ecc_curve_get_size(curve) * 8;
1739 gnutls_free (x.data);
1740 gnutls_free (y.data);
1741 gnutls_free (k.data);
1745 fprintf (outfile, "\n");
1747 size = buffer_size;
1748 if ((ret = gnutls_x509_privkey_get_key_id (key, 0, buffer, &size)) < 0)
1750 fprintf (stderr, "Error in key id calculation: %s\n",
1751 gnutls_strerror (ret));
1753 else
1755 gnutls_datum_t art;
1757 fprintf (outfile, "Public Key ID: %s\n", raw_to_string (buffer, size));
1759 ret = gnutls_random_art(GNUTLS_RANDOM_ART_OPENSSH, cprint, bits, buffer, size, &art);
1760 if (ret >= 0)
1762 fprintf (outfile, "Public key's random art:\n%s\n", art.data);
1763 gnutls_free(art.data);
1766 fprintf (outfile, "\n");
1770 void
1771 privkey_info (common_info_st* cinfo)
1773 gnutls_x509_privkey_t key;
1774 size_t size;
1775 int ret;
1776 gnutls_datum_t pem;
1777 const char *pass;
1779 size = fread (buffer, 1, buffer_size - 1, infile);
1780 buffer[size] = 0;
1782 gnutls_x509_privkey_init (&key);
1784 pem.data = buffer;
1785 pem.size = size;
1787 ret = 0;
1788 if (!cinfo->pkcs8)
1789 ret = gnutls_x509_privkey_import (key, &pem, incert_format);
1791 /* If we failed to import the certificate previously try PKCS #8 */
1792 if (cinfo->pkcs8 || ret == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR)
1794 if (cinfo->password)
1795 pass = cinfo->password;
1796 else
1797 pass = get_pass ();
1798 ret = gnutls_x509_privkey_import_pkcs8 (key, &pem,
1799 incert_format, pass, 0);
1801 if (ret < 0)
1802 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (ret));
1804 if (outcert_format == GNUTLS_X509_FMT_PEM)
1805 privkey_info_int (cinfo, key);
1807 ret = gnutls_x509_privkey_verify_params (key);
1808 if (ret < 0)
1809 fprintf (outfile, "\n** Private key parameters validation failed **\n\n");
1811 size = buffer_size;
1812 ret = gnutls_x509_privkey_export (key, outcert_format, buffer, &size);
1813 if (ret < 0)
1814 error (EXIT_FAILURE, 0, "export error: %s", gnutls_strerror (ret));
1816 fwrite (buffer, 1, size, outfile);
1818 gnutls_x509_privkey_deinit (key);
1822 /* Generate a PKCS #10 certificate request.
1824 void
1825 generate_request (common_info_st * cinfo)
1827 gnutls_x509_crq_t crq;
1828 gnutls_x509_privkey_t xkey;
1829 gnutls_pubkey_t pubkey;
1830 gnutls_privkey_t pkey;
1831 int ret, ca_status, path_len;
1832 const char *pass;
1833 unsigned int usage = 0;
1835 fprintf (stderr, "Generating a PKCS #10 certificate request...\n");
1837 ret = gnutls_x509_crq_init (&crq);
1838 if (ret < 0)
1839 error (EXIT_FAILURE, 0, "crq_init: %s", gnutls_strerror (ret));
1842 /* Load the private key.
1844 pkey = load_private_key (0, cinfo);
1845 if (!pkey)
1847 ret = gnutls_privkey_init (&pkey);
1848 if (ret < 0)
1849 error (EXIT_FAILURE, 0, "privkey_init: %s", gnutls_strerror (ret));
1851 xkey = generate_private_key_int (cinfo);
1853 print_private_key (cinfo, xkey);
1855 ret = gnutls_privkey_import_x509(pkey, xkey, GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
1856 if (ret < 0)
1857 error (EXIT_FAILURE, 0, "privkey_import_x509: %s", gnutls_strerror (ret));
1860 pubkey = load_public_key_or_import (1, pkey, cinfo);
1862 /* Set the DN.
1864 get_country_crq_set (crq);
1865 get_organization_crq_set (crq);
1866 get_unit_crq_set (crq);
1867 get_locality_crq_set (crq);
1868 get_state_crq_set (crq);
1869 get_cn_crq_set (crq);
1870 get_dc_set (TYPE_CRQ, crq);
1871 get_uid_crq_set (crq);
1872 get_oid_crq_set (crq);
1874 get_dns_name_set (TYPE_CRQ, crq);
1875 get_uri_set (TYPE_CRQ, crq);
1876 get_ip_addr_set (TYPE_CRQ, crq);
1877 get_email_set (TYPE_CRQ, crq);
1879 pass = get_challenge_pass ();
1881 if (pass != NULL && pass[0] != 0)
1883 ret = gnutls_x509_crq_set_challenge_password (crq, pass);
1884 if (ret < 0)
1885 error (EXIT_FAILURE, 0, "set_pass: %s", gnutls_strerror (ret));
1888 if (cinfo->crq_extensions != 0)
1890 ca_status = get_ca_status ();
1891 if (ca_status)
1892 path_len = get_path_len ();
1893 else
1894 path_len = -1;
1896 ret = gnutls_x509_crq_set_basic_constraints (crq, ca_status, path_len);
1897 if (ret < 0)
1898 error (EXIT_FAILURE, 0, "set_basic_constraints: %s",
1899 gnutls_strerror (ret));
1901 ret = get_sign_status (1);
1902 if (ret)
1903 usage |= GNUTLS_KEY_DIGITAL_SIGNATURE;
1905 ret = get_encrypt_status (1);
1906 if (ret)
1907 usage |= GNUTLS_KEY_KEY_ENCIPHERMENT;
1908 else
1909 usage |= GNUTLS_KEY_DIGITAL_SIGNATURE;
1911 if (ca_status)
1913 ret = get_cert_sign_status ();
1914 if (ret)
1915 usage |= GNUTLS_KEY_KEY_CERT_SIGN;
1917 ret = get_crl_sign_status ();
1918 if (ret)
1919 usage |= GNUTLS_KEY_CRL_SIGN;
1921 ret = get_code_sign_status ();
1922 if (ret)
1924 ret = gnutls_x509_crq_set_key_purpose_oid
1925 (crq, GNUTLS_KP_CODE_SIGNING, 0);
1926 if (ret < 0)
1927 error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (ret));
1930 ret = get_ocsp_sign_status ();
1931 if (ret)
1933 ret = gnutls_x509_crq_set_key_purpose_oid
1934 (crq, GNUTLS_KP_OCSP_SIGNING, 0);
1935 if (ret < 0)
1936 error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (ret));
1939 ret = get_time_stamp_status ();
1940 if (ret)
1942 ret = gnutls_x509_crq_set_key_purpose_oid
1943 (crq, GNUTLS_KP_TIME_STAMPING, 0);
1944 if (ret < 0)
1945 error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (ret));
1948 ret = get_ipsec_ike_status ();
1949 if (ret)
1951 ret = gnutls_x509_crq_set_key_purpose_oid
1952 (crq, GNUTLS_KP_IPSEC_IKE, 0);
1953 if (ret < 0)
1954 error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (ret));
1958 ret = gnutls_x509_crq_set_key_usage (crq, usage);
1959 if (ret < 0)
1960 error (EXIT_FAILURE, 0, "key_usage: %s", gnutls_strerror (ret));
1962 ret = get_tls_client_status ();
1963 if (ret != 0)
1965 ret = gnutls_x509_crq_set_key_purpose_oid
1966 (crq, GNUTLS_KP_TLS_WWW_CLIENT, 0);
1967 if (ret < 0)
1968 error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (ret));
1971 ret = get_tls_server_status ();
1972 if (ret != 0)
1974 ret = gnutls_x509_crq_set_key_purpose_oid
1975 (crq, GNUTLS_KP_TLS_WWW_SERVER, 0);
1976 if (ret < 0)
1977 error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (ret));
1981 ret = gnutls_x509_crq_set_pubkey (crq, pubkey);
1982 if (ret < 0)
1983 error (EXIT_FAILURE, 0, "set_key: %s", gnutls_strerror (ret));
1985 ret = gnutls_x509_crq_privkey_sign (crq, pkey, get_dig_for_pub (pubkey), 0);
1986 if (ret < 0)
1987 error (EXIT_FAILURE, 0, "sign: %s", gnutls_strerror (ret));
1989 print_crq_info (crq, outfile);
1991 gnutls_x509_crq_deinit (crq);
1992 gnutls_privkey_deinit( pkey);
1993 gnutls_pubkey_deinit( pubkey);
1997 static void print_verification_res (FILE* outfile, unsigned int output);
1999 static int detailed_verification(gnutls_x509_crt_t cert,
2000 gnutls_x509_crt_t issuer, gnutls_x509_crl_t crl,
2001 unsigned int verification_output)
2003 char name[512];
2004 char tmp[255];
2005 char issuer_name[512];
2006 size_t name_size;
2007 size_t issuer_name_size;
2008 int ret;
2010 issuer_name_size = sizeof (issuer_name);
2011 ret =
2012 gnutls_x509_crt_get_issuer_dn (cert, issuer_name, &issuer_name_size);
2013 if (ret < 0)
2014 error (EXIT_FAILURE, 0, "gnutls_x509_crt_get_issuer_dn: %s", gnutls_strerror (ret));
2016 name_size = sizeof (name);
2017 ret =
2018 gnutls_x509_crt_get_dn (cert, name, &name_size);
2019 if (ret < 0)
2020 error (EXIT_FAILURE, 0, "gnutls_x509_crt_get_dn: %s", gnutls_strerror (ret));
2022 fprintf (outfile, "\tSubject: %s\n", name);
2023 fprintf (outfile, "\tIssuer: %s\n", issuer_name);
2025 if (issuer != NULL)
2027 issuer_name_size = sizeof (issuer_name);
2028 ret =
2029 gnutls_x509_crt_get_dn (issuer, issuer_name, &issuer_name_size);
2030 if (ret < 0)
2031 error (EXIT_FAILURE, 0, "gnutls_x509_crt_get_issuer_dn: %s", gnutls_strerror (ret));
2033 fprintf (outfile, "\tChecked against: %s\n", issuer_name);
2036 if (crl != NULL)
2038 gnutls_datum_t data;
2040 issuer_name_size = sizeof (issuer_name);
2041 ret =
2042 gnutls_x509_crl_get_issuer_dn (crl, issuer_name, &issuer_name_size);
2043 if (ret < 0)
2044 error (EXIT_FAILURE, 0, "gnutls_x509_crl_get_issuer_dn: %s", gnutls_strerror (ret));
2046 name_size = sizeof(tmp);
2047 ret = gnutls_x509_crl_get_number(crl, tmp, &name_size, NULL);
2048 if (ret < 0)
2049 strcpy(name, "unnumbered");
2050 else
2052 data.data = (void*)tmp;
2053 data.size = name_size;
2055 name_size = sizeof(name);
2056 ret = gnutls_hex_encode(&data, name, &name_size);
2057 if (ret < 0)
2058 error (EXIT_FAILURE, 0, "gnutls_hex_encode: %s", gnutls_strerror (ret));
2060 fprintf (outfile, "\tChecked against CRL[%s] of: %s\n", name, issuer_name);
2063 fprintf (outfile, "\tOutput: ");
2064 print_verification_res(outfile, verification_output);
2066 fputs(".\n\n", outfile);
2068 return 0;
2071 /* Will verify a certificate chain. If no CA certificates
2072 * are provided, then the last certificate in the certificate
2073 * chain is used as a CA.
2075 static int
2076 _verify_x509_mem (const void *cert, int cert_size, const void* ca, int ca_size)
2078 int ret;
2079 gnutls_datum_t tmp;
2080 gnutls_x509_crt_t *x509_cert_list = NULL;
2081 gnutls_x509_crt_t *x509_ca_list = NULL;
2082 gnutls_x509_crl_t *x509_crl_list = NULL;
2083 unsigned int x509_ncerts, x509_ncrls = 0, x509_ncas = 0;
2084 gnutls_x509_trust_list_t list;
2085 unsigned int output;
2087 ret = gnutls_x509_trust_list_init(&list, 0);
2088 if (ret < 0)
2089 error (EXIT_FAILURE, 0, "gnutls_x509_trust_list_init: %s",
2090 gnutls_strerror (ret));
2092 if (ca == NULL)
2094 tmp.data = (void*)cert;
2095 tmp.size = cert_size;
2097 else
2099 tmp.data = (void*)ca;
2100 tmp.size = ca_size;
2102 /* Load CAs */
2103 ret = gnutls_x509_crt_list_import2( &x509_ca_list, &x509_ncas, &tmp,
2104 GNUTLS_X509_FMT_PEM, 0);
2105 if (ret < 0 || x509_ncas < 1)
2106 error (EXIT_FAILURE, 0, "error parsing CAs: %s",
2107 gnutls_strerror (ret));
2110 ret = gnutls_x509_crl_list_import2( &x509_crl_list, &x509_ncrls, &tmp,
2111 GNUTLS_X509_FMT_PEM, 0);
2112 if (ret < 0)
2114 x509_crl_list = NULL;
2115 x509_ncrls = 0;
2118 tmp.data = (void*)cert;
2119 tmp.size = cert_size;
2121 /* ignore errors. CRLs might not be given */
2122 ret = gnutls_x509_crt_list_import2( &x509_cert_list, &x509_ncerts, &tmp,
2123 GNUTLS_X509_FMT_PEM, 0);
2124 if (ret < 0 || x509_ncerts < 1)
2125 error (EXIT_FAILURE, 0, "error parsing CRTs: %s",
2126 gnutls_strerror (ret));
2128 if (ca == NULL)
2130 x509_ca_list = &x509_cert_list[x509_ncerts - 1];
2131 x509_ncas = 1;
2134 fprintf(stdout, "Loaded %d certificates, %d CAs and %d CRLs\n\n",
2135 x509_ncerts, x509_ncas, x509_ncrls);
2137 ret = gnutls_x509_trust_list_add_cas(list, x509_ca_list, x509_ncas, 0);
2138 if (ret < 0)
2139 error (EXIT_FAILURE, 0, "gnutls_x509_trust_add_cas: %s",
2140 gnutls_strerror (ret));
2142 ret = gnutls_x509_trust_list_add_crls(list, x509_crl_list, x509_ncrls, 0, 0);
2143 if (ret < 0)
2144 error (EXIT_FAILURE, 0, "gnutls_x509_trust_add_crls: %s",
2145 gnutls_strerror (ret));
2147 gnutls_free(x509_crl_list);
2149 ret = gnutls_x509_trust_list_verify_crt (list, x509_cert_list, x509_ncerts,
2150 GNUTLS_VERIFY_DO_NOT_ALLOW_SAME|GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT, &output,
2151 detailed_verification);
2152 if (ret < 0)
2153 error (EXIT_FAILURE, 0, "gnutls_x509_trusted_list_verify_crt: %s",
2154 gnutls_strerror (ret));
2156 fprintf (outfile, "Chain verification output: ");
2157 print_verification_res(outfile, output);
2159 fprintf (outfile, ".\n\n");
2161 gnutls_free(x509_cert_list);
2162 gnutls_x509_trust_list_deinit(list, 1);
2164 if (output != 0)
2165 exit(EXIT_FAILURE);
2167 return 0;
2170 static void
2171 print_verification_res (FILE* outfile, unsigned int output)
2173 int comma = 0;
2175 if (output & GNUTLS_CERT_INVALID)
2177 fprintf (outfile, "Not verified");
2178 comma = 1;
2180 else
2182 fprintf (outfile, "Verified");
2183 comma = 1;
2186 if (output & GNUTLS_CERT_SIGNER_NOT_CA)
2188 if (comma)
2189 fprintf (outfile, ", ");
2190 fprintf (outfile, "Issuer is not a CA");
2191 comma = 1;
2194 if (output & GNUTLS_CERT_INSECURE_ALGORITHM)
2196 if (comma)
2197 fprintf (outfile, ", ");
2198 fprintf (outfile, "Insecure algorithm");
2199 comma = 1;
2202 if (output & GNUTLS_CERT_NOT_ACTIVATED)
2204 if (comma)
2205 fprintf (outfile, ", ");
2206 fprintf (outfile, "Not activated");
2207 comma = 1;
2210 if (output & GNUTLS_CERT_EXPIRED)
2212 if (comma)
2213 fprintf (outfile, ", ");
2214 fprintf (outfile, "Expired");
2215 comma = 1;
2218 if (output & GNUTLS_CERT_REVOKED)
2220 if (comma)
2221 fprintf (outfile, ", ");
2222 fprintf (outfile, "Revoked");
2223 comma = 1;
2227 static void
2228 verify_chain (void)
2230 char *buf;
2231 size_t size;
2233 buf = (void*)fread_file (infile, &size);
2234 if (buf == NULL)
2235 error (EXIT_FAILURE, errno, "reading chain");
2237 buf[size] = 0;
2239 _verify_x509_mem (buf, size, NULL, 0);
2243 static void
2244 verify_certificate (common_info_st * cinfo)
2246 char *cert;
2247 char *cas;
2248 size_t cert_size, ca_size;
2249 FILE * ca_file = fopen(cinfo->ca, "r");
2251 if (ca_file == NULL)
2252 error (EXIT_FAILURE, errno, "opening CA file");
2254 cert = (void*)fread_file (infile, &cert_size);
2255 if (cert == NULL)
2256 error (EXIT_FAILURE, errno, "reading certificate chain");
2258 cert[cert_size] = 0;
2260 cas = (void*)fread_file (ca_file, &ca_size);
2261 if (cas == NULL)
2262 error (EXIT_FAILURE, errno, "reading CA list");
2264 cas[ca_size] = 0;
2265 fclose(ca_file);
2267 _verify_x509_mem (cert, cert_size, cas, ca_size);
2272 void
2273 verify_crl (common_info_st * cinfo)
2275 size_t size, dn_size;
2276 char dn[128];
2277 unsigned int output;
2278 int comma = 0;
2279 int ret;
2280 gnutls_datum_t pem;
2281 gnutls_x509_crl_t crl;
2282 time_t now = time (0);
2283 gnutls_x509_crt_t issuer;
2285 issuer = load_ca_cert (cinfo);
2287 fprintf (outfile, "\nCA certificate:\n");
2289 dn_size = sizeof (dn);
2290 ret = gnutls_x509_crt_get_dn (issuer, dn, &dn_size);
2291 if (ret < 0)
2292 error (EXIT_FAILURE, 0, "crt_get_dn: %s", gnutls_strerror (ret));
2294 fprintf (outfile, "\tSubject: %s\n\n", dn);
2296 ret = gnutls_x509_crl_init (&crl);
2297 if (ret < 0)
2298 error (EXIT_FAILURE, 0, "crl_init: %s", gnutls_strerror (ret));
2300 pem.data = (void*)fread_file (infile, &size);
2301 pem.size = size;
2303 ret = gnutls_x509_crl_import (crl, &pem, incert_format);
2304 free (pem.data);
2305 if (ret < 0)
2306 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (ret));
2308 print_crl_info (crl, outfile);
2310 fprintf (outfile, "Verification output: ");
2311 ret = gnutls_x509_crl_verify (crl, &issuer, 1, 0, &output);
2312 if (ret < 0)
2313 error (EXIT_FAILURE, 0, "verification error: %s", gnutls_strerror (ret));
2315 if (output & GNUTLS_CERT_INVALID)
2317 fprintf (outfile, "Not verified");
2318 comma = 1;
2320 else
2322 fprintf (outfile, "Verified");
2323 comma = 1;
2326 if (output & GNUTLS_CERT_SIGNER_NOT_CA)
2328 if (comma)
2329 fprintf (outfile, ", ");
2330 fprintf (outfile, "Issuer is not a CA");
2331 comma = 1;
2334 if (output & GNUTLS_CERT_INSECURE_ALGORITHM)
2336 if (comma)
2337 fprintf (outfile, ", ");
2338 fprintf (outfile, "Insecure algorithm");
2339 comma = 1;
2342 /* Check expiration dates.
2345 if (gnutls_x509_crl_get_this_update (crl) > now)
2347 if (comma)
2348 fprintf (outfile, ", ");
2349 comma = 1;
2350 fprintf (outfile, "Issued in the future!");
2353 if (gnutls_x509_crl_get_next_update (crl) < now)
2355 if (comma)
2356 fprintf (outfile, ", ");
2357 comma = 1;
2358 fprintf (outfile, "CRL is not up to date");
2361 fprintf (outfile, "\n");
2365 void
2366 generate_pkcs8 (common_info_st * cinfo)
2368 gnutls_x509_privkey_t key;
2369 int result;
2370 size_t size;
2371 int flags = 0;
2372 const char *password;
2374 fprintf (stderr, "Generating a PKCS #8 key structure...\n");
2376 key = load_x509_private_key (1, cinfo);
2378 if (cinfo->password)
2379 password = cinfo->password;
2380 else
2381 password = get_pass ();
2383 flags = cipher_to_flags (cinfo->pkcs_cipher);
2385 if (password == NULL || password[0] == 0)
2387 flags = GNUTLS_PKCS_PLAIN;
2390 size = buffer_size;
2391 result =
2392 gnutls_x509_privkey_export_pkcs8 (key, outcert_format,
2393 password, flags, buffer, &size);
2395 if (result < 0)
2396 error (EXIT_FAILURE, 0, "key_export: %s", gnutls_strerror (result));
2398 fwrite (buffer, 1, size, outfile);
2403 #include <gnutls/pkcs12.h>
2404 #include <unistd.h>
2406 void
2407 generate_pkcs12 (common_info_st * cinfo)
2409 gnutls_pkcs12_t pkcs12;
2410 gnutls_x509_crt_t *crts;
2411 gnutls_x509_privkey_t key;
2412 int result;
2413 size_t size;
2414 gnutls_datum_t data;
2415 const char *pass;
2416 const char *name;
2417 unsigned int flags, i;
2418 gnutls_datum_t key_id;
2419 unsigned char _key_id[32];
2420 int indx;
2421 size_t ncrts;
2423 fprintf (stderr, "Generating a PKCS #12 structure...\n");
2425 key = load_x509_private_key (0, cinfo);
2426 crts = load_cert_list (0, &ncrts, cinfo);
2428 name = get_pkcs12_key_name ();
2430 result = gnutls_pkcs12_init (&pkcs12);
2431 if (result < 0)
2432 error (EXIT_FAILURE, 0, "pkcs12_init: %s", gnutls_strerror (result));
2434 if (cinfo->password)
2435 pass = cinfo->password;
2436 else
2437 pass = get_pass ();
2439 if (pass == NULL)
2441 fprintf(stderr, "No password given for PKCS #12. Assuming null password...\n");
2442 pass = "";
2446 for (i = 0; i < ncrts; i++)
2448 gnutls_pkcs12_bag_t bag;
2450 result = gnutls_pkcs12_bag_init (&bag);
2451 if (result < 0)
2452 error (EXIT_FAILURE, 0, "bag_init: %s", gnutls_strerror (result));
2454 result = gnutls_pkcs12_bag_set_crt (bag, crts[i]);
2455 if (result < 0)
2456 error (EXIT_FAILURE, 0, "set_crt[%d]: %s", i,
2457 gnutls_strerror (result));
2459 indx = result;
2461 result = gnutls_pkcs12_bag_set_friendly_name (bag, indx, name);
2462 if (result < 0)
2463 error (EXIT_FAILURE, 0, "bag_set_friendly_name: %s",
2464 gnutls_strerror (result));
2466 size = sizeof (_key_id);
2467 result = gnutls_x509_crt_get_key_id (crts[i], 0, _key_id, &size);
2468 if (result < 0)
2469 error (EXIT_FAILURE, 0, "key_id[%d]: %s", i,
2470 gnutls_strerror (result));
2472 key_id.data = _key_id;
2473 key_id.size = size;
2475 result = gnutls_pkcs12_bag_set_key_id (bag, indx, &key_id);
2476 if (result < 0)
2477 error (EXIT_FAILURE, 0, "bag_set_key_id: %s",
2478 gnutls_strerror (result));
2480 flags = cipher_to_flags (cinfo->pkcs_cipher);
2482 result = gnutls_pkcs12_bag_encrypt (bag, pass, flags);
2483 if (result < 0)
2484 error (EXIT_FAILURE, 0, "bag_encrypt: %s", gnutls_strerror (result));
2486 result = gnutls_pkcs12_set_bag (pkcs12, bag);
2487 if (result < 0)
2488 error (EXIT_FAILURE, 0, "set_bag: %s", gnutls_strerror (result));
2491 if (key)
2493 gnutls_pkcs12_bag_t kbag;
2495 result = gnutls_pkcs12_bag_init (&kbag);
2496 if (result < 0)
2497 error (EXIT_FAILURE, 0, "bag_init: %s", gnutls_strerror (result));
2499 flags = cipher_to_flags (cinfo->pkcs_cipher);
2501 size = buffer_size;
2502 result =
2503 gnutls_x509_privkey_export_pkcs8 (key, GNUTLS_X509_FMT_DER,
2504 pass, flags, buffer, &size);
2505 if (result < 0)
2506 error (EXIT_FAILURE, 0, "key_export: %s", gnutls_strerror (result));
2508 data.data = buffer;
2509 data.size = size;
2510 result =
2511 gnutls_pkcs12_bag_set_data (kbag,
2512 GNUTLS_BAG_PKCS8_ENCRYPTED_KEY, &data);
2513 if (result < 0)
2514 error (EXIT_FAILURE, 0, "bag_set_data: %s", gnutls_strerror (result));
2516 indx = result;
2518 result = gnutls_pkcs12_bag_set_friendly_name (kbag, indx, name);
2519 if (result < 0)
2520 error (EXIT_FAILURE, 0, "bag_set_friendly_name: %s",
2521 gnutls_strerror (result));
2523 size = sizeof (_key_id);
2524 result = gnutls_x509_privkey_get_key_id (key, 0, _key_id, &size);
2525 if (result < 0)
2526 error (EXIT_FAILURE, 0, "key_id: %s", gnutls_strerror (result));
2528 key_id.data = _key_id;
2529 key_id.size = size;
2531 result = gnutls_pkcs12_bag_set_key_id (kbag, indx, &key_id);
2532 if (result < 0)
2533 error (EXIT_FAILURE, 0, "bag_set_key_id: %s",
2534 gnutls_strerror (result));
2536 result = gnutls_pkcs12_set_bag (pkcs12, kbag);
2537 if (result < 0)
2538 error (EXIT_FAILURE, 0, "set_bag: %s", gnutls_strerror (result));
2541 result = gnutls_pkcs12_generate_mac (pkcs12, pass);
2542 if (result < 0)
2543 error (EXIT_FAILURE, 0, "generate_mac: %s", gnutls_strerror (result));
2545 size = buffer_size;
2546 result = gnutls_pkcs12_export (pkcs12, outcert_format, buffer, &size);
2547 if (result < 0)
2548 error (EXIT_FAILURE, 0, "pkcs12_export: %s", gnutls_strerror (result));
2550 fwrite (buffer, 1, size, outfile);
2554 static const char *
2555 BAGTYPE (gnutls_pkcs12_bag_type_t x)
2557 switch (x)
2559 case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY:
2560 return "PKCS #8 Encrypted key";
2561 case GNUTLS_BAG_EMPTY:
2562 return "Empty";
2563 case GNUTLS_BAG_PKCS8_KEY:
2564 return "PKCS #8 Key";
2565 case GNUTLS_BAG_CERTIFICATE:
2566 return "Certificate";
2567 case GNUTLS_BAG_ENCRYPTED:
2568 return "Encrypted";
2569 case GNUTLS_BAG_CRL:
2570 return "CRL";
2571 case GNUTLS_BAG_SECRET:
2572 return "Secret";
2573 default:
2574 return "Unknown";
2578 static void
2579 print_bag_data (gnutls_pkcs12_bag_t bag)
2581 int result;
2582 int count, i, type;
2583 gnutls_datum_t cdata, id;
2584 const char *str, *name;
2585 gnutls_datum_t out;
2587 count = gnutls_pkcs12_bag_get_count (bag);
2588 if (count < 0)
2589 error (EXIT_FAILURE, 0, "get_count: %s", gnutls_strerror (count));
2591 fprintf (outfile, "\tElements: %d\n", count);
2593 for (i = 0; i < count; i++)
2595 type = gnutls_pkcs12_bag_get_type (bag, i);
2596 if (type < 0)
2597 error (EXIT_FAILURE, 0, "get_type: %s", gnutls_strerror (type));
2599 fprintf (stderr, "\tType: %s\n", BAGTYPE (type));
2601 name = NULL;
2602 result = gnutls_pkcs12_bag_get_friendly_name (bag, i, (char **) &name);
2603 if (result < 0)
2604 error (EXIT_FAILURE, 0, "get_friendly_name: %s",
2605 gnutls_strerror (type));
2606 if (name)
2607 fprintf (outfile, "\tFriendly name: %s\n", name);
2609 id.data = NULL;
2610 id.size = 0;
2611 result = gnutls_pkcs12_bag_get_key_id (bag, i, &id);
2612 if (result < 0)
2613 error (EXIT_FAILURE, 0, "get_key_id: %s", gnutls_strerror (type));
2614 if (id.size > 0)
2615 fprintf (outfile, "\tKey ID: %s\n", raw_to_string (id.data, id.size));
2617 result = gnutls_pkcs12_bag_get_data (bag, i, &cdata);
2618 if (result < 0)
2619 error (EXIT_FAILURE, 0, "get_data: %s", gnutls_strerror (result));
2621 switch (type)
2623 case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY:
2624 str = "ENCRYPTED PRIVATE KEY";
2625 break;
2626 case GNUTLS_BAG_PKCS8_KEY:
2627 str = "PRIVATE KEY";
2628 break;
2629 case GNUTLS_BAG_CERTIFICATE:
2630 str = "CERTIFICATE";
2631 break;
2632 case GNUTLS_BAG_CRL:
2633 str = "CRL";
2634 break;
2635 case GNUTLS_BAG_ENCRYPTED:
2636 case GNUTLS_BAG_EMPTY:
2637 default:
2638 str = NULL;
2641 if (str != NULL)
2643 gnutls_pem_base64_encode_alloc (str, &cdata, &out);
2644 fprintf (outfile, "%s\n", out.data);
2646 gnutls_free (out.data);
2652 void
2653 pkcs12_info (common_info_st* cinfo)
2655 gnutls_pkcs12_t pkcs12;
2656 gnutls_pkcs12_bag_t bag;
2657 int result;
2658 size_t size;
2659 gnutls_datum_t data;
2660 const char *pass;
2661 int indx;
2663 result = gnutls_pkcs12_init (&pkcs12);
2664 if (result < 0)
2665 error (EXIT_FAILURE, 0, "p12_init: %s", gnutls_strerror (result));
2667 data.data = (void*)fread_file (infile, &size);
2668 data.size = size;
2670 result = gnutls_pkcs12_import (pkcs12, &data, incert_format, 0);
2671 free (data.data);
2672 if (result < 0)
2673 error (EXIT_FAILURE, 0, "p12_import: %s", gnutls_strerror (result));
2675 if (cinfo->password)
2676 pass = cinfo->password;
2677 else
2678 pass = get_pass ();
2680 result = gnutls_pkcs12_verify_mac (pkcs12, pass);
2681 if (result < 0)
2682 error (0, 0, "verify_mac: %s", gnutls_strerror (result));
2684 for (indx = 0;; indx++)
2686 result = gnutls_pkcs12_bag_init (&bag);
2687 if (result < 0)
2688 error (EXIT_FAILURE, 0, "bag_init: %s", gnutls_strerror (result));
2690 result = gnutls_pkcs12_get_bag (pkcs12, indx, bag);
2691 if (result < 0)
2692 break;
2694 result = gnutls_pkcs12_bag_get_count (bag);
2695 if (result < 0)
2696 error (EXIT_FAILURE, 0, "bag_count: %s", gnutls_strerror (result));
2698 fprintf (outfile, "BAG #%d\n", indx);
2700 result = gnutls_pkcs12_bag_get_type (bag, 0);
2701 if (result < 0)
2702 error (EXIT_FAILURE, 0, "bag_init: %s", gnutls_strerror (result));
2704 if (result == GNUTLS_BAG_ENCRYPTED)
2706 fprintf (stderr, "\tType: %s\n", BAGTYPE (result));
2707 fprintf (stderr, "\n\tDecrypting...\n");
2709 result = gnutls_pkcs12_bag_decrypt (bag, pass);
2711 if (result < 0)
2713 error (0, 0, "bag_decrypt: %s", gnutls_strerror (result));
2714 continue;
2717 result = gnutls_pkcs12_bag_get_count (bag);
2718 if (result < 0)
2719 error (EXIT_FAILURE, 0, "encrypted bag_count: %s",
2720 gnutls_strerror (result));
2723 print_bag_data (bag);
2725 gnutls_pkcs12_bag_deinit (bag);
2729 void
2730 pkcs7_info (void)
2732 gnutls_pkcs7_t pkcs7;
2733 int result;
2734 size_t size;
2735 gnutls_datum_t data, b64;
2736 int indx, count;
2738 result = gnutls_pkcs7_init (&pkcs7);
2739 if (result < 0)
2740 error (EXIT_FAILURE, 0, "p7_init: %s", gnutls_strerror (result));
2742 data.data = (void*)fread_file (infile, &size);
2743 data.size = size;
2745 result = gnutls_pkcs7_import (pkcs7, &data, incert_format);
2746 free (data.data);
2747 if (result < 0)
2748 error (EXIT_FAILURE, 0, "import error: %s", gnutls_strerror (result));
2750 /* Read and print the certificates.
2752 result = gnutls_pkcs7_get_crt_count (pkcs7);
2753 if (result < 0)
2754 error (EXIT_FAILURE, 0, "p7_crt_count: %s", gnutls_strerror (result));
2756 count = result;
2758 if (count > 0)
2759 fprintf (outfile, "Number of certificates: %u\n", count);
2761 for (indx = 0; indx < count; indx++)
2763 fputs ("\n", outfile);
2765 size = buffer_size;
2766 result = gnutls_pkcs7_get_crt_raw (pkcs7, indx, buffer, &size);
2767 if (result < 0)
2768 break;
2770 data.data = buffer;
2771 data.size = size;
2773 result = gnutls_pem_base64_encode_alloc ("CERTIFICATE", &data, &b64);
2774 if (result < 0)
2775 error (EXIT_FAILURE, 0, "encoding: %s", gnutls_strerror (result));
2777 fputs ((void*)b64.data, outfile);
2778 gnutls_free (b64.data);
2781 /* Read the CRLs now.
2783 result = gnutls_pkcs7_get_crl_count (pkcs7);
2784 if (result < 0)
2785 error (EXIT_FAILURE, 0, "p7_crl_count: %s", gnutls_strerror (result));
2787 count = result;
2789 if (count > 0)
2790 fprintf (outfile, "\nNumber of CRLs: %u\n", count);
2792 for (indx = 0; indx < count; indx++)
2794 fputs ("\n", outfile);
2796 size = buffer_size;
2797 result = gnutls_pkcs7_get_crl_raw (pkcs7, indx, buffer, &size);
2798 if (result < 0)
2799 break;
2801 data.data = buffer;
2802 data.size = size;
2804 result = gnutls_pem_base64_encode_alloc ("X509 CRL", &data, &b64);
2805 if (result < 0)
2806 error (EXIT_FAILURE, 0, "encoding: %s", gnutls_strerror (result));
2808 fputs ((void*)b64.data, outfile);
2809 gnutls_free (b64.data);
2813 void
2814 smime_to_pkcs7 (void)
2816 size_t linesize = 0;
2817 char *lineptr = NULL;
2818 ssize_t len;
2820 /* Find body. FIXME: Handle non-b64 Content-Transfer-Encoding.
2821 Reject non-S/MIME tagged Content-Type's? */
2824 len = getline (&lineptr, &linesize, infile);
2825 if (len == -1)
2826 error (EXIT_FAILURE, 0, "cannot find RFC 2822 header/body separator");
2828 while (strcmp (lineptr, "\r\n") != 0 && strcmp (lineptr, "\n") != 0);
2832 len = getline (&lineptr, &linesize, infile);
2833 if (len == -1)
2834 error (EXIT_FAILURE, 0, "message has RFC 2822 header but no body");
2836 while (strcmp (lineptr, "\r\n") == 0 && strcmp (lineptr, "\n") == 0);
2838 fprintf (outfile, "%s", "-----BEGIN PKCS7-----\n");
2842 while (len > 0
2843 && (lineptr[len - 1] == '\r' || lineptr[len - 1] == '\n'))
2844 lineptr[--len] = '\0';
2845 if (strcmp (lineptr, "") != 0)
2846 fprintf (outfile, "%s\n", lineptr);
2847 len = getline (&lineptr, &linesize, infile);
2849 while (len != -1);
2851 fprintf (outfile, "%s", "-----END PKCS7-----\n");
2853 free (lineptr);
2856 void
2857 certtool_version (void)
2859 const char *p = PACKAGE_NAME;
2860 if (strcmp (gnutls_check_version (NULL), PACKAGE_VERSION) != 0)
2861 p = PACKAGE_STRING;
2862 version_etc (stdout, program_name, p, gnutls_check_version (NULL),
2863 "Nikos Mavrogiannopoulos", "Simon Josefsson", (char *) NULL);
2866 static void
2867 print_key_usage (FILE * outfile, unsigned int usage)
2869 if (usage & GNUTLS_KEY_DIGITAL_SIGNATURE)
2871 fprintf (outfile, "\tDigital signature.\n");
2874 if (usage & GNUTLS_KEY_NON_REPUDIATION)
2876 fprintf (outfile, "\tNon repudiation.\n");
2879 if (usage & GNUTLS_KEY_KEY_ENCIPHERMENT)
2881 fprintf (outfile, "\tKey encipherment.\n");
2884 if (usage & GNUTLS_KEY_DATA_ENCIPHERMENT)
2886 fprintf (outfile, "\tData encipherment.\n");
2889 if (usage & GNUTLS_KEY_KEY_AGREEMENT)
2891 fprintf (outfile, "\tKey agreement.\n");
2894 if (usage & GNUTLS_KEY_KEY_CERT_SIGN)
2896 fprintf (outfile, "\tCertificate signing.\n");
2899 if (usage & GNUTLS_KEY_NON_REPUDIATION)
2901 fprintf (outfile, "\tCRL signing.\n");
2904 if (usage & GNUTLS_KEY_ENCIPHER_ONLY)
2906 fprintf (outfile, "\tKey encipher only.\n");
2909 if (usage & GNUTLS_KEY_DECIPHER_ONLY)
2911 fprintf (outfile, "\tKey decipher only.\n");
2915 void
2916 pubkey_info (gnutls_x509_crt_t crt, common_info_st * cinfo)
2918 gnutls_pubkey_t pubkey;
2919 unsigned int bits, usage;
2920 int ret;
2921 size_t size;
2922 const char *cprint;
2924 ret = gnutls_pubkey_init (&pubkey);
2925 if (ret < 0)
2927 error (EXIT_FAILURE, 0, "pubkey_init: %s", gnutls_strerror (ret));
2930 if (crt == NULL)
2932 crt = load_cert (0, cinfo);
2935 if (crt != NULL)
2937 ret = gnutls_pubkey_import_x509 (pubkey, crt, 0);
2938 if (ret < 0)
2940 error (EXIT_FAILURE, 0, "pubkey_import_x509: %s",
2941 gnutls_strerror (ret));
2944 else
2946 pubkey = load_pubkey (1, cinfo);
2949 if (outcert_format == GNUTLS_X509_FMT_DER)
2951 size = buffer_size;
2952 ret = gnutls_pubkey_export (pubkey, outcert_format, buffer, &size);
2953 if (ret < 0)
2954 error (EXIT_FAILURE, 0, "export error: %s", gnutls_strerror (ret));
2956 fwrite (buffer, 1, size, outfile);
2958 gnutls_pubkey_deinit (pubkey);
2960 return;
2963 /* PEM */
2965 fprintf (outfile, "Public Key Info:\n\n");
2966 ret = gnutls_pubkey_get_pk_algorithm (pubkey, &bits);
2967 fprintf (outfile, "Public Key Algorithm: ");
2969 cprint = gnutls_pk_algorithm_get_name (ret);
2970 fprintf (outfile, "%s (%u bits)\n", cprint ? cprint : "Unknown", bits);
2973 /* Print the raw public and private keys
2975 if (ret == GNUTLS_PK_RSA)
2977 gnutls_datum_t m, e;
2979 ret = gnutls_pubkey_get_pk_rsa_raw (pubkey, &m, &e);
2980 if (ret < 0)
2981 fprintf (stderr, "Error in key RSA data export: %s\n",
2982 gnutls_strerror (ret));
2983 else
2985 print_rsa_pkey (&m, &e, NULL, NULL, NULL, NULL, NULL, NULL);
2986 gnutls_free (m.data);
2987 gnutls_free (e.data);
2990 else if (ret == GNUTLS_PK_DSA)
2992 gnutls_datum_t p, q, g, y;
2994 ret = gnutls_pubkey_get_pk_dsa_raw (pubkey, &p, &q, &g, &y);
2995 if (ret < 0)
2996 fprintf (stderr, "Error in key DSA data export: %s\n",
2997 gnutls_strerror (ret));
2998 else
3000 print_dsa_pkey (NULL, &y, &p, &q, &g);
3001 gnutls_free (y.data);
3002 gnutls_free (p.data);
3003 gnutls_free (q.data);
3004 gnutls_free (g.data);
3007 else if (ret == GNUTLS_PK_EC)
3009 gnutls_datum_t x, y;
3010 gnutls_ecc_curve_t curve;
3012 ret = gnutls_pubkey_get_pk_ecc_raw (pubkey, &curve, &x, &y);
3013 if (ret < 0)
3014 fprintf (stderr, "Error in key ECC data export: %s\n",
3015 gnutls_strerror (ret));
3016 else
3018 print_ecc_pkey (curve, NULL, &y, &x);
3019 gnutls_free (y.data);
3020 gnutls_free (x.data);
3024 ret = gnutls_pubkey_get_key_usage (pubkey, &usage);
3025 if (ret < 0)
3027 error (EXIT_FAILURE, 0, "pubkey_get_key_usage: %s",
3028 gnutls_strerror (ret));
3031 fprintf (outfile, "Public Key Usage:\n");
3032 print_key_usage (outfile, usage);
3034 fprintf (outfile, "\n");
3036 size = buffer_size;
3037 if ((ret = gnutls_pubkey_get_key_id (pubkey, 0, buffer, &size)) < 0)
3039 fprintf (stderr, "Error in key id calculation: %s\n",
3040 gnutls_strerror (ret));
3042 else
3044 fprintf (outfile, "Public Key ID: %s\n", raw_to_string (buffer, size));
3047 size = buffer_size;
3048 ret = gnutls_pubkey_export (pubkey, GNUTLS_X509_FMT_PEM, buffer, &size);
3049 if (ret < 0)
3050 error (EXIT_FAILURE, 0, "export error: %s", gnutls_strerror (ret));
3052 fprintf (outfile, "\n%s\n", buffer);
3054 gnutls_pubkey_deinit (pubkey);