1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | #include <config.h> |
22 | |
23 | #include <gnutls/gnutls.h> |
24 | #include <gnutls/x509.h> |
25 | #include <gnutls/openpgp.h> |
26 | #include <gnutls/pkcs12.h> |
27 | #include <gnutls/pkcs11.h> |
28 | #include <gnutls/abstract.h> |
29 | |
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(*__errno_location ()).h> |
37 | #include <sys/types.h> |
38 | #include <sys/stat.h> |
39 | #include <fcntl.h> |
40 | #include <error.h> |
41 | |
42 | |
43 | #include <read-file.h> |
44 | #include <progname.h> |
45 | #include <version-etc.h> |
46 | |
47 | #include <certtool-cfg.h> |
48 | #include <p11common.h> |
49 | #include "certtool-gaa.h" |
50 | #include "certtool-common.h" |
51 | |
52 | #define SIGN_HASHGNUTLS_DIG_SHA256 GNUTLS_DIG_SHA256 |
53 | |
54 | static void privkey_info_int (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 (void); |
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 (void); |
71 | static void gaa_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); |
77 | |
78 | static void print_hex_datum (gnutls_datum_t * dat); |
79 | |
80 | static gaainfo info; |
81 | FILE *outfile; |
82 | FILE *infile; |
83 | gnutls_digest_algorithm_t default_dig; |
84 | |
85 | |
86 | |
87 | int batch; |
88 | |
89 | |
90 | static void |
91 | tls_log_func (int level, const char *str) |
92 | { |
93 | fprintf (stderrstderr, "|<%d>| %s", level, str); |
94 | } |
95 | |
96 | int |
97 | main (int argc, char **argv) |
98 | { |
99 | set_program_name (argv[0]); |
100 | cfg_init (); |
101 | gaa_parser (argc, argv); |
102 | |
103 | return 0; |
104 | } |
105 | |
106 | static const char * |
107 | raw_to_string (const unsigned char *raw, size_t raw_size) |
108 | { |
109 | static char buf[1024]; |
110 | size_t i; |
111 | if (raw_size == 0) |
112 | return NULL((void*)0); |
113 | |
114 | if (raw_size * 3 + 1 >= sizeof (buf)) |
115 | return NULL((void*)0); |
116 | |
117 | for (i = 0; i < raw_size; i++) |
118 | { |
119 | sprintf (&(buf[i * 3]), "%02X%s", raw[i], |
120 | (i == raw_size - 1) ? "" : ":"); |
121 | } |
122 | buf[sizeof (buf) - 1] = '\0'; |
123 | |
124 | return buf; |
125 | } |
126 | |
127 | static void |
128 | print_dsa_pkey (gnutls_datum_t * x, gnutls_datum_t * y, gnutls_datum_t * p, |
129 | gnutls_datum_t * q, gnutls_datum_t * g) |
130 | { |
131 | if (x) |
132 | { |
133 | fprintf (outfile, "private key:"); |
134 | print_hex_datum (x); |
135 | } |
136 | fprintf (outfile, "public key:"); |
137 | print_hex_datum (y); |
138 | fprintf (outfile, "p:"); |
139 | print_hex_datum (p); |
140 | fprintf (outfile, "q:"); |
141 | print_hex_datum (q); |
142 | fprintf (outfile, "g:"); |
143 | print_hex_datum (g); |
144 | } |
145 | |
146 | static void |
147 | print_ecc_pkey (gnutls_ecc_curve_t curve, gnutls_datum_t* k, gnutls_datum_t * x, gnutls_datum_t * y) |
148 | { |
149 | fprintf (outfile, "curve:\t%s\n", gnutls_ecc_curve_get_name(curve)); |
150 | if (k) |
151 | { |
152 | fprintf (outfile, "private key:"); |
153 | print_hex_datum (k); |
154 | } |
155 | fprintf (outfile, "x:"); |
156 | print_hex_datum (x); |
157 | fprintf (outfile, "y:"); |
158 | print_hex_datum (y); |
159 | } |
160 | |
161 | static void |
162 | print_rsa_pkey (gnutls_datum_t * m, gnutls_datum_t * e, gnutls_datum_t * d, |
163 | gnutls_datum_t * p, gnutls_datum_t * q, gnutls_datum_t * u, |
164 | gnutls_datum_t * exp1, gnutls_datum_t * exp2) |
165 | { |
166 | fprintf (outfile, "modulus:"); |
167 | print_hex_datum (m); |
168 | fprintf (outfile, "public exponent:"); |
169 | print_hex_datum (e); |
170 | if (d) |
171 | { |
172 | fprintf (outfile, "private exponent:"); |
173 | print_hex_datum (d); |
174 | fprintf (outfile, "prime1:"); |
175 | print_hex_datum (p); |
176 | fprintf (outfile, "prime2:"); |
177 | print_hex_datum (q); |
178 | fprintf (outfile, "coefficient:"); |
179 | print_hex_datum (u); |
180 | if (exp1 && exp2) |
181 | { |
182 | fprintf (outfile, "exp1:"); |
183 | print_hex_datum (exp1); |
184 | fprintf (outfile, "exp2:"); |
185 | print_hex_datum (exp2); |
186 | } |
187 | } |
188 | } |
189 | |
190 | static gnutls_x509_privkey_t |
191 | generate_private_key_int (void) |
192 | { |
193 | gnutls_x509_privkey_t key; |
194 | int ret, key_type, bits; |
195 | |
196 | if (info.dsa) |
197 | key_type = GNUTLS_PK_DSA; |
198 | else if (info.ecc) |
199 | key_type = GNUTLS_PK_EC; |
200 | else |
201 | key_type = GNUTLS_PK_RSA; |
202 | |
203 | ret = gnutls_x509_privkey_init (&key); |
204 | if (ret < 0) |
205 | error (EXIT_FAILURE1, 0, "privkey_init: %s", gnutls_strerror (ret)); |
206 | |
207 | bits = get_bits (key_type, info.bits, info.sec_param); |
208 | |
209 | fprintf (stderrstderr, "Generating a %d bit %s private key...\n", |
210 | bits, gnutls_pk_algorithm_get_name (key_type)); |
211 | |
212 | if (info.quick_random == 0) |
213 | fprintf (stderrstderr, |
214 | "This might take several minutes depending on availability of randomness" |
215 | " in /dev/random.\n"); |
216 | |
217 | if (bits > 1024 && key_type == GNUTLS_PK_DSA) |
218 | fprintf (stderrstderr, |
219 | "Note that DSA keys with size over 1024 can only be used with TLS 1.2 or later.\n\n"); |
220 | |
221 | ret = gnutls_x509_privkey_generate (key, key_type, bits, 0); |
222 | if (ret < 0) |
223 | error (EXIT_FAILURE1, 0, "privkey_generate: %s", gnutls_strerror (ret)); |
224 | |
225 | ret = gnutls_x509_privkey_verify_params (key); |
226 | if (ret < 0) |
227 | error (EXIT_FAILURE1, 0, "privkey_verify_params: %s", gnutls_strerror (ret)); |
228 | |
229 | return key; |
230 | } |
231 | |
232 | static int |
233 | cipher_to_flags (const char *cipher) |
234 | { |
235 | if (strcasecmp (cipher, "3des") == 0) |
236 | { |
237 | return GNUTLS_PKCS_USE_PBES2_3DES; |
238 | } |
239 | else if (strcasecmp (cipher, "3des-pkcs12") == 0) |
240 | { |
241 | return GNUTLS_PKCS_USE_PKCS12_3DES; |
242 | } |
243 | else if (strcasecmp (cipher, "arcfour") == 0) |
244 | { |
245 | return GNUTLS_PKCS_USE_PKCS12_ARCFOUR; |
246 | } |
247 | else if (strcasecmp (cipher, "aes-128") == 0) |
248 | { |
249 | return GNUTLS_PKCS_USE_PBES2_AES_128; |
250 | } |
251 | else if (strcasecmp (cipher, "aes-192") == 0) |
252 | { |
253 | return GNUTLS_PKCS_USE_PBES2_AES_192; |
254 | } |
255 | else if (strcasecmp (cipher, "aes-256") == 0) |
256 | { |
257 | return GNUTLS_PKCS_USE_PBES2_AES_256; |
258 | } |
259 | else if (strcasecmp (cipher, "rc2-40") == 0) |
260 | { |
261 | return GNUTLS_PKCS_USE_PKCS12_RC2_40; |
262 | } |
263 | |
264 | error (EXIT_FAILURE1, 0, "unknown cipher %s\n", cipher); |
265 | return -1; |
266 | } |
267 | |
268 | |
269 | static void |
270 | print_private_key (gnutls_x509_privkey_t key) |
271 | { |
272 | int ret; |
273 | size_t size; |
274 | |
275 | if (!key) |
276 | return; |
277 | |
278 | if (info.outcert_format == GNUTLS_X509_FMT_PEM) |
279 | privkey_info_int(key); |
280 | |
281 | if (!info.pkcs8) |
282 | { |
283 | size = buffer_size; |
284 | ret = gnutls_x509_privkey_export (key, info.outcert_format, |
285 | buffer, &size); |
286 | if (ret < 0) |
287 | error (EXIT_FAILURE1, 0, "privkey_export: %s", gnutls_strerror (ret)); |
288 | } |
289 | else |
290 | { |
291 | unsigned int flags; |
292 | const char *pass; |
293 | |
294 | if (info.export) |
295 | flags = GNUTLS_PKCS_USE_PKCS12_RC2_40; |
296 | else |
297 | flags = cipher_to_flags (info.pkcs_cipher); |
298 | |
299 | if ((pass = get_confirmed_pass (true1)) == NULL((void*)0) || *pass == '\0') |
300 | flags = GNUTLS_PKCS_PLAIN; |
301 | |
302 | size = buffer_size; |
303 | ret = |
304 | gnutls_x509_privkey_export_pkcs8 (key, info.outcert_format, pass, |
305 | flags, buffer, &size); |
306 | if (ret < 0) |
307 | error (EXIT_FAILURE1, 0, "privkey_export_pkcs8: %s", |
308 | gnutls_strerror (ret)); |
309 | } |
310 | |
311 | fwrite (buffer, 1, size, outfile); |
312 | } |
313 | |
314 | static void |
315 | generate_private_key (void) |
316 | { |
317 | gnutls_x509_privkey_t key; |
318 | |
319 | key = generate_private_key_int (); |
320 | |
321 | print_private_key (key); |
322 | |
323 | gnutls_x509_privkey_deinit (key); |
324 | } |
325 | |
326 | |
327 | static gnutls_x509_crt_t |
328 | generate_certificate (gnutls_privkey_t * ret_key, |
329 | gnutls_x509_crt_t ca_crt, int proxy, |
330 | common_info_st * cinfo) |
331 | { |
332 | gnutls_x509_crt_t crt; |
333 | gnutls_privkey_t key = NULL((void*)0); |
334 | gnutls_pubkey_t pubkey; |
335 | size_t size; |
336 | int ret; |
337 | int client; |
338 | int days, result, ca_status = 0, is_ike = 0, path_len; |
339 | int vers; |
340 | unsigned int usage = 0, server; |
341 | gnutls_x509_crq_t crq; |
342 | |
343 | ret = gnutls_x509_crt_init (&crt); |
344 | if (ret < 0) |
345 | error (EXIT_FAILURE1, 0, "crt_init: %s", gnutls_strerror (ret)); |
346 | |
347 | crq = load_request (cinfo); |
348 | |
349 | if (crq == NULL((void*)0)) |
350 | { |
351 | |
352 | key = load_private_key (1, cinfo); |
353 | |
354 | pubkey = load_public_key_or_import (1, key, cinfo); |
355 | |
356 | if (!batch) |
357 | fprintf (stderrstderr, |
358 | "Please enter the details of the certificate's distinguished name. " |
359 | "Just press enter to ignore a field.\n"); |
360 | |
361 | |
362 | |
363 | if (proxy) |
364 | { |
365 | result = gnutls_x509_crt_set_proxy_dn (crt, ca_crt, 0, NULL((void*)0), 0); |
366 | if (result < 0) |
367 | error (EXIT_FAILURE1, 0, "set_proxy_dn: %s", |
368 | gnutls_strerror (result)); |
369 | |
370 | get_cn_crt_set (crt); |
371 | } |
372 | else |
373 | { |
374 | get_country_crt_set (crt); |
375 | get_organization_crt_set (crt); |
376 | get_unit_crt_set (crt); |
377 | get_locality_crt_set (crt); |
378 | get_state_crt_set (crt); |
379 | get_cn_crt_set (crt); |
380 | get_uid_crt_set (crt); |
381 | get_oid_crt_set (crt); |
382 | get_key_purpose_set (crt); |
383 | |
384 | if (!batch) |
385 | fprintf (stderrstderr, |
386 | "This field should not be used in new certificates.\n"); |
387 | |
388 | get_pkcs9_email_crt_set (crt); |
389 | } |
390 | |
391 | result = gnutls_x509_crt_set_pubkey (crt, pubkey); |
392 | if (result < 0) |
393 | error (EXIT_FAILURE1, 0, "set_key: %s", gnutls_strerror (result)); |
394 | } |
395 | else |
396 | { |
397 | result = gnutls_x509_crt_set_crq (crt, crq); |
398 | if (result < 0) |
399 | error (EXIT_FAILURE1, 0, "set_crq: %s", gnutls_strerror (result)); |
400 | } |
401 | |
402 | |
403 | { |
404 | int serial = get_serial (); |
405 | char bin_serial[5]; |
406 | |
407 | bin_serial[4] = serial & 0xff; |
408 | bin_serial[3] = (serial >> 8) & 0xff; |
409 | bin_serial[2] = (serial >> 16) & 0xff; |
410 | bin_serial[1] = (serial >> 24) & 0xff; |
411 | bin_serial[0] = 0; |
412 | |
413 | result = gnutls_x509_crt_set_serial (crt, bin_serial, 5); |
414 | if (result < 0) |
415 | error (EXIT_FAILURE1, 0, "serial: %s", gnutls_strerror (result)); |
416 | } |
417 | |
418 | if (!batch) |
419 | fprintf (stderrstderr, "\n\nActivation/Expiration time.\n"); |
420 | |
421 | gnutls_x509_crt_set_activation_time (crt, time (NULL((void*)0))); |
422 | |
423 | days = get_days (); |
424 | |
425 | result = |
426 | gnutls_x509_crt_set_expiration_time (crt, |
427 | time (NULL((void*)0)) + days * 24 * 60 * 60); |
428 | if (result < 0) |
429 | error (EXIT_FAILURE1, 0, "set_expiration: %s", gnutls_strerror (result)); |
430 | |
431 | if (!batch) |
432 | fprintf (stderrstderr, "\n\nExtensions.\n"); |
433 | |
434 | |
435 | if (crq && get_crq_extensions_status () != 0) |
436 | { |
437 | result = gnutls_x509_crt_set_crq_extensions (crt, crq); |
438 | if (result < 0) |
439 | error (EXIT_FAILURE1, 0, "set_crq: %s", gnutls_strerror (result)); |
440 | } |
441 | |
442 | |
443 | if (info.v1_cert == 0) |
444 | { |
445 | |
446 | if (proxy) |
447 | { |
448 | const char *policylanguage; |
449 | char *policy; |
450 | size_t policylen; |
451 | int proxypathlen = get_path_len (); |
452 | |
453 | if (!batch) |
454 | { |
455 | printf ("1.3.6.1.5.5.7.21.1 ::= id-ppl-inheritALL\n"); |
456 | printf ("1.3.6.1.5.5.7.21.2 ::= id-ppl-independent\n"); |
457 | } |
458 | |
459 | policylanguage = get_proxy_policy (&policy, &policylen); |
460 | |
461 | result = |
462 | gnutls_x509_crt_set_proxy (crt, proxypathlen, policylanguage, |
463 | policy, policylen); |
464 | if (result < 0) |
465 | error (EXIT_FAILURE1, 0, "set_proxy: %s", |
466 | gnutls_strerror (result)); |
467 | } |
468 | |
469 | if (!proxy) |
470 | ca_status = get_ca_status (); |
471 | if (ca_status) |
472 | path_len = get_path_len (); |
473 | else |
474 | path_len = -1; |
475 | |
476 | result = |
477 | gnutls_x509_crt_set_basic_constraints (crt, ca_status, path_len); |
478 | if (result < 0) |
479 | error (EXIT_FAILURE1, 0, "basic_constraints: %s", |
480 | gnutls_strerror (result)); |
481 | |
482 | client = get_tls_client_status (); |
483 | if (client != 0) |
484 | { |
485 | result = gnutls_x509_crt_set_key_purpose_oid (crt, |
486 | GNUTLS_KP_TLS_WWW_CLIENT"1.3.6.1.5.5.7.3.2", |
487 | 0); |
488 | if (result < 0) |
489 | error (EXIT_FAILURE1, 0, "key_kp: %s", gnutls_strerror (result)); |
490 | } |
491 | |
492 | is_ike = get_ipsec_ike_status (); |
493 | server = get_tls_server_status (); |
494 | if ((server != 0 && !proxy) || is_ike) |
495 | { |
496 | get_dns_name_set (TYPE_CRT1, crt); |
497 | get_ip_addr_set (TYPE_CRT1, crt); |
498 | } |
499 | |
500 | if (server != 0) |
501 | { |
502 | result = 0; |
503 | |
504 | result = |
505 | gnutls_x509_crt_set_key_purpose_oid (crt, |
506 | GNUTLS_KP_TLS_WWW_SERVER"1.3.6.1.5.5.7.3.1", 0); |
507 | if (result < 0) |
508 | error (EXIT_FAILURE1, 0, "key_kp: %s", gnutls_strerror (result)); |
509 | } |
510 | else if (!proxy) |
511 | { |
512 | get_email_set (TYPE_CRT1, crt); |
513 | } |
514 | |
515 | if (!ca_status || server) |
516 | { |
517 | int pk; |
518 | |
519 | |
520 | pk = gnutls_x509_crt_get_pk_algorithm (crt, NULL((void*)0)); |
521 | |
522 | if (pk != GNUTLS_PK_DSA) |
523 | { |
524 | |
525 | result = get_sign_status (server); |
526 | if (result) |
527 | usage |= GNUTLS_KEY_DIGITAL_SIGNATURE128; |
528 | |
529 | result = get_encrypt_status (server); |
530 | if (result) |
531 | usage |= GNUTLS_KEY_KEY_ENCIPHERMENT32; |
532 | } |
533 | else |
534 | usage |= GNUTLS_KEY_DIGITAL_SIGNATURE128; |
535 | |
536 | if (is_ike) |
537 | { |
538 | result = |
539 | gnutls_x509_crt_set_key_purpose_oid (crt, |
540 | GNUTLS_KP_IPSEC_IKE"1.3.6.1.5.5.7.3.17", 0); |
541 | if (result < 0) |
542 | error (EXIT_FAILURE1, 0, "key_kp: %s", |
543 | gnutls_strerror (result)); |
544 | } |
545 | } |
546 | |
547 | |
548 | if (ca_status) |
549 | { |
550 | result = get_cert_sign_status (); |
551 | if (result) |
552 | usage |= GNUTLS_KEY_KEY_CERT_SIGN4; |
553 | |
554 | result = get_crl_sign_status (); |
555 | if (result) |
556 | usage |= GNUTLS_KEY_CRL_SIGN2; |
557 | |
558 | result = get_code_sign_status (); |
559 | if (result) |
560 | { |
561 | result = |
562 | gnutls_x509_crt_set_key_purpose_oid (crt, |
563 | GNUTLS_KP_CODE_SIGNING"1.3.6.1.5.5.7.3.3", |
564 | 0); |
565 | if (result < 0) |
566 | error (EXIT_FAILURE1, 0, "key_kp: %s", |
567 | gnutls_strerror (result)); |
568 | } |
569 | |
570 | result = get_ocsp_sign_status (); |
571 | if (result) |
572 | { |
573 | result = |
574 | gnutls_x509_crt_set_key_purpose_oid (crt, |
575 | GNUTLS_KP_OCSP_SIGNING"1.3.6.1.5.5.7.3.9", |
576 | 0); |
577 | if (result < 0) |
578 | error (EXIT_FAILURE1, 0, "key_kp: %s", |
579 | gnutls_strerror (result)); |
580 | } |
581 | |
582 | result = get_time_stamp_status (); |
583 | if (result) |
584 | { |
585 | result = |
586 | gnutls_x509_crt_set_key_purpose_oid (crt, |
587 | GNUTLS_KP_TIME_STAMPING"1.3.6.1.5.5.7.3.8", |
588 | 0); |
589 | if (result < 0) |
590 | error (EXIT_FAILURE1, 0, "key_kp: %s", |
591 | gnutls_strerror (result)); |
592 | } |
593 | } |
594 | |
595 | if (usage != 0) |
596 | { |
597 | |
598 | |
599 | |
600 | if (is_ike && (get_sign_status (server) != 1)) |
601 | usage |= GNUTLS_KEY_NON_REPUDIATION64; |
602 | result = gnutls_x509_crt_set_key_usage (crt, usage); |
603 | if (result < 0) |
604 | error (EXIT_FAILURE1, 0, "key_usage: %s", |
605 | gnutls_strerror (result)); |
606 | } |
607 | |
608 | |
609 | |
610 | size = buffer_size; |
611 | result = gnutls_x509_crt_get_key_id (crt, 0, buffer, &size); |
612 | if (result >= 0) |
613 | { |
614 | result = gnutls_x509_crt_set_subject_key_id (crt, buffer, size); |
615 | if (result < 0) |
616 | error (EXIT_FAILURE1, 0, "set_subject_key_id: %s", |
617 | gnutls_strerror (result)); |
618 | } |
619 | |
620 | |
621 | |
622 | if (ca_crt != NULL((void*)0)) |
623 | { |
624 | size = buffer_size; |
625 | result = gnutls_x509_crt_get_subject_key_id (ca_crt, buffer, |
626 | &size, NULL((void*)0)); |
627 | if (result < 0) |
628 | { |
629 | size = buffer_size; |
630 | result = gnutls_x509_crt_get_key_id (ca_crt, 0, buffer, &size); |
631 | } |
632 | if (result >= 0) |
633 | { |
634 | result = |
635 | gnutls_x509_crt_set_authority_key_id (crt, buffer, size); |
636 | if (result < 0) |
637 | error (EXIT_FAILURE1, 0, "set_authority_key_id: %s", |
638 | gnutls_strerror (result)); |
639 | } |
640 | } |
641 | } |
642 | |
643 | |
644 | |
645 | if (info.v1_cert != 0) |
646 | vers = 1; |
647 | else |
648 | vers = 3; |
649 | result = gnutls_x509_crt_set_version (crt, vers); |
650 | if (result < 0) |
651 | error (EXIT_FAILURE1, 0, "set_version: %s", gnutls_strerror (result)); |
652 | |
653 | *ret_key = key; |
654 | return crt; |
655 | |
656 | } |
657 | |
658 | static gnutls_x509_crl_t |
659 | generate_crl (gnutls_x509_crt_t ca_crt, common_info_st * cinfo) |
660 | { |
661 | gnutls_x509_crl_t crl; |
662 | gnutls_x509_crt_t *crts; |
663 | size_t size; |
664 | int days, result; |
665 | unsigned int i; |
666 | time_t now = time (NULL((void*)0)); |
667 | |
668 | result = gnutls_x509_crl_init (&crl); |
669 | if (result < 0) |
670 | error (EXIT_FAILURE1, 0, "crl_init: %s", gnutls_strerror (result)); |
671 | |
672 | crts = load_cert_list (0, &size, cinfo); |
673 | |
674 | for (i = 0; i < size; i++) |
675 | { |
676 | result = gnutls_x509_crl_set_crt (crl, crts[i], now); |
677 | if (result < 0) |
678 | error (EXIT_FAILURE1, 0, "crl_set_crt: %s", gnutls_strerror (result)); |
679 | } |
680 | |
681 | result = gnutls_x509_crl_set_this_update (crl, now); |
682 | if (result < 0) |
683 | error (EXIT_FAILURE1, 0, "this_update: %s", gnutls_strerror (result)); |
684 | |
685 | fprintf (stderrstderr, "Update times.\n"); |
686 | days = get_crl_next_update (); |
687 | |
688 | result = gnutls_x509_crl_set_next_update (crl, now + days * 24 * 60 * 60); |
689 | if (result < 0) |
690 | error (EXIT_FAILURE1, 0, "next_update: %s", gnutls_strerror (result)); |
691 | |
692 | result = gnutls_x509_crl_set_version (crl, 2); |
693 | if (result < 0) |
694 | error (EXIT_FAILURE1, 0, "set_version: %s", gnutls_strerror (result)); |
695 | |
696 | |
697 | |
698 | if (ca_crt != NULL((void*)0)) |
699 | { |
700 | size = buffer_size; |
701 | result = gnutls_x509_crt_get_subject_key_id (ca_crt, buffer, |
702 | &size, NULL((void*)0)); |
703 | if (result < 0) |
704 | { |
705 | size = buffer_size; |
706 | result = gnutls_x509_crt_get_key_id (ca_crt, 0, buffer, &size); |
707 | } |
708 | if (result >= 0) |
709 | { |
710 | result = gnutls_x509_crl_set_authority_key_id (crl, buffer, size); |
711 | if (result < 0) |
712 | error (EXIT_FAILURE1, 0, "set_authority_key_id: %s", |
713 | gnutls_strerror (result)); |
714 | } |
715 | } |
716 | |
717 | { |
718 | unsigned int number = get_crl_number (); |
719 | char bin_number[5]; |
720 | |
721 | bin_number[4] = number & 0xff; |
722 | bin_number[3] = (number >> 8) & 0xff; |
723 | bin_number[2] = (number >> 16) & 0xff; |
724 | bin_number[1] = (number >> 24) & 0xff; |
725 | bin_number[0] = 0; |
726 | |
727 | result = gnutls_x509_crl_set_number (crl, bin_number, 5); |
728 | if (result < 0) |
729 | error (EXIT_FAILURE1, 0, "set_number: %s", gnutls_strerror (result)); |
730 | } |
731 | |
732 | return crl; |
733 | } |
734 | |
735 | static gnutls_digest_algorithm_t |
736 | get_dig (gnutls_x509_crt_t crt) |
737 | { |
738 | gnutls_digest_algorithm_t dig; |
739 | gnutls_pubkey_t pubkey; |
740 | int result; |
741 | unsigned int mand; |
742 | |
743 | gnutls_pubkey_init(&pubkey); |
744 | |
745 | result = gnutls_pubkey_import_x509(pubkey, crt, 0); |
746 | if (result < 0) |
747 | { |
748 | error (EXIT_FAILURE1, 0, "gnutls_pubkey_import_x509: %s", |
749 | gnutls_strerror (result)); |
750 | } |
751 | |
752 | result = gnutls_pubkey_get_preferred_hash_algorithm (pubkey, &dig, &mand); |
753 | if (result < 0) |
754 | { |
755 | error (EXIT_FAILURE1, 0, "crt_get_preferred_hash_algorithm: %s", |
756 | gnutls_strerror (result)); |
757 | } |
758 | |
759 | gnutls_pubkey_deinit(pubkey); |
760 | |
761 | |
762 | if (mand == 0 && default_dig != GNUTLS_DIG_UNKNOWN) |
763 | dig = default_dig; |
764 | |
765 | return dig; |
766 | } |
767 | |
768 | void |
769 | generate_self_signed (common_info_st * cinfo) |
770 | { |
771 | gnutls_x509_crt_t crt; |
772 | gnutls_privkey_t key; |
773 | size_t size; |
774 | int result; |
775 | const char *uri; |
776 | |
777 | fprintf (stderrstderr, "Generating a self signed certificate...\n"); |
778 | |
779 | crt = generate_certificate (&key, NULL((void*)0), 0, cinfo); |
780 | |
781 | if (!key) |
782 | key = load_private_key (1, cinfo); |
783 | |
784 | uri = get_crl_dist_point_url (); |
785 | if (uri) |
786 | { |
787 | result = gnutls_x509_crt_set_crl_dist_points (crt, GNUTLS_SAN_URI, |
788 | uri, |
789 | 0 ); |
790 | if (result < 0) |
791 | error (EXIT_FAILURE1, 0, "crl_dist_points: %s", |
792 | gnutls_strerror (result)); |
793 | } |
794 | |
795 | print_certificate_info (crt, stderrstderr, 0); |
796 | |
797 | fprintf (stderrstderr, "\n\nSigning certificate...\n"); |
798 | |
799 | result = gnutls_x509_crt_privkey_sign (crt, crt, key, get_dig (crt), 0); |
800 | if (result < 0) |
801 | error (EXIT_FAILURE1, 0, "crt_sign: %s", gnutls_strerror (result)); |
802 | |
803 | size = buffer_size; |
804 | result = gnutls_x509_crt_export (crt, info.outcert_format, buffer, &size); |
805 | if (result < 0) |
806 | error (EXIT_FAILURE1, 0, "crt_export: %s", gnutls_strerror (result)); |
807 | |
808 | fwrite (buffer, 1, size, outfile); |
809 | |
810 | gnutls_x509_crt_deinit (crt); |
811 | gnutls_privkey_deinit (key); |
812 | } |
813 | |
814 | static void |
815 | generate_signed_certificate (common_info_st * cinfo) |
816 | { |
817 | gnutls_x509_crt_t crt; |
818 | gnutls_privkey_t key; |
819 | size_t size; |
820 | int result; |
821 | gnutls_privkey_t ca_key; |
822 | gnutls_x509_crt_t ca_crt; |
823 | |
824 | fprintf (stderrstderr, "Generating a signed certificate...\n"); |
825 | |
826 | ca_key = load_ca_private_key (cinfo); |
827 | ca_crt = load_ca_cert (cinfo); |
828 | |
829 | crt = generate_certificate (&key, ca_crt, 0, cinfo); |
830 | |
831 | |
832 | |
833 | gnutls_x509_crt_cpy_crl_dist_points (crt, ca_crt); |
834 | |
835 | |
836 | |
837 | print_certificate_info (crt, stderrstderr, 0); |
838 | |
839 | fprintf (stderrstderr, "\n\nSigning certificate...\n"); |
840 | |
841 | result = gnutls_x509_crt_privkey_sign (crt, ca_crt, ca_key, get_dig (ca_crt), 0); |
842 | if (result < 0) |
843 | error (EXIT_FAILURE1, 0, "crt_sign: %s", gnutls_strerror (result)); |
844 | |
845 | size = buffer_size; |
846 | result = gnutls_x509_crt_export (crt, info.outcert_format, buffer, &size); |
847 | if (result < 0) |
848 | error (EXIT_FAILURE1, 0, "crt_export: %s", gnutls_strerror (result)); |
849 | |
850 | fwrite (buffer, 1, size, outfile); |
851 | |
852 | gnutls_x509_crt_deinit (crt); |
853 | gnutls_privkey_deinit (key); |
854 | gnutls_privkey_deinit(ca_key); |
855 | } |
856 | |
857 | static void |
858 | generate_proxy_certificate (common_info_st * cinfo) |
859 | { |
860 | gnutls_x509_crt_t crt, eecrt; |
861 | gnutls_privkey_t key, eekey; |
862 | size_t size; |
863 | int result; |
864 | |
865 | fprintf (stderrstderr, "Generating a proxy certificate...\n"); |
866 | |
867 | eekey = load_ca_private_key (cinfo); |
868 | eecrt = load_cert (1, cinfo); |
869 | |
870 | crt = generate_certificate (&key, eecrt, 1, cinfo); |
871 | |
872 | print_certificate_info (crt, stderrstderr, 0); |
873 | |
874 | fprintf (stderrstderr, "\n\nSigning certificate...\n"); |
875 | |
876 | result = gnutls_x509_crt_privkey_sign (crt, eecrt, eekey, get_dig (eecrt), 0); |
877 | if (result < 0) |
878 | error (EXIT_FAILURE1, 0, "crt_sign: %s", gnutls_strerror (result)); |
879 | |
880 | size = buffer_size; |
881 | result = gnutls_x509_crt_export (crt, info.outcert_format, buffer, &size); |
882 | if (result < 0) |
883 | error (EXIT_FAILURE1, 0, "crt_export: %s", gnutls_strerror (result)); |
884 | |
885 | fwrite (buffer, 1, size, outfile); |
886 | |
887 | gnutls_x509_crt_deinit (eecrt); |
888 | gnutls_x509_crt_deinit (crt); |
889 | gnutls_privkey_deinit (key); |
890 | gnutls_privkey_deinit (eekey); |
891 | } |
892 | |
893 | static void |
894 | generate_signed_crl (common_info_st * cinfo) |
895 | { |
896 | gnutls_x509_crl_t crl; |
897 | int result; |
898 | gnutls_privkey_t ca_key; |
899 | gnutls_x509_crt_t ca_crt; |
900 | |
901 | fprintf (stderrstderr, "Generating a signed CRL...\n"); |
902 | |
903 | ca_key = load_ca_private_key (cinfo); |
904 | ca_crt = load_ca_cert (cinfo); |
905 | crl = generate_crl (ca_crt, cinfo); |
906 | |
907 | fprintf (stderrstderr, "\n"); |
908 | result = gnutls_x509_crl_privkey_sign(crl, ca_crt, ca_key, SIGN_HASHGNUTLS_DIG_SHA256, 0); |
909 | if (result < 0) |
910 | error (EXIT_FAILURE1, 0, "crl_privkey_sign: %s", gnutls_strerror (result)); |
911 | |
912 | print_crl_info (crl, stderrstderr); |
913 | |
914 | gnutls_privkey_deinit( ca_key); |
915 | gnutls_x509_crl_deinit (crl); |
916 | } |
917 | |
918 | static void |
919 | update_signed_certificate (common_info_st * cinfo) |
920 | { |
921 | gnutls_x509_crt_t crt; |
922 | size_t size; |
923 | int result; |
924 | gnutls_privkey_t ca_key; |
925 | gnutls_x509_crt_t ca_crt; |
926 | int days; |
927 | time_t tim = time (NULL((void*)0)); |
928 | |
929 | fprintf (stderrstderr, "Generating a signed certificate...\n"); |
930 | |
931 | ca_key = load_ca_private_key (cinfo); |
932 | ca_crt = load_ca_cert (cinfo); |
933 | crt = load_cert (1, cinfo); |
934 | |
935 | fprintf (stderrstderr, "Activation/Expiration time.\n"); |
936 | gnutls_x509_crt_set_activation_time (crt, tim); |
937 | |
938 | days = get_days (); |
939 | |
940 | result = |
941 | gnutls_x509_crt_set_expiration_time (crt, tim + days * 24 * 60 * 60); |
942 | if (result < 0) |
943 | error (EXIT_FAILURE1, 0, "set_expiration: %s", gnutls_strerror (result)); |
944 | |
945 | fprintf (stderrstderr, "\n\nSigning certificate...\n"); |
946 | |
947 | result = gnutls_x509_crt_privkey_sign (crt, ca_crt, ca_key, get_dig (ca_crt), 0); |
948 | if (result < 0) |
949 | error (EXIT_FAILURE1, 0, "crt_sign: %s", gnutls_strerror (result)); |
950 | |
951 | size = buffer_size; |
952 | result = gnutls_x509_crt_export (crt, info.outcert_format, buffer, &size); |
953 | if (result < 0) |
954 | error (EXIT_FAILURE1, 0, "crt_export: %s", gnutls_strerror (result)); |
955 | |
956 | fwrite (buffer, 1, size, outfile); |
957 | |
958 | gnutls_x509_crt_deinit (crt); |
959 | } |
960 | |
961 | void |
962 | gaa_parser (int argc, char **argv) |
963 | { |
964 | int ret; |
965 | common_info_st cinfo; |
966 | |
967 | if (gaa (argc, argv, &info) != -1) |
968 | { |
969 | fprintf (stderrstderr, "Try `%s --help' for more information.\n", |
970 | program_name); |
971 | exit (1); |
972 | } |
973 | |
974 | if (info.outfile) |
975 | { |
976 | outfile = safe_open_rw (info.outfile, info.privkey_op); |
977 | if (outfile == NULL((void*)0)) |
978 | error (EXIT_FAILURE1, errno(*__errno_location ()), "%s", info.outfile); |
979 | } |
980 | else |
981 | outfile = stdoutstdout; |
982 | |
983 | if (info.infile) |
984 | { |
985 | infile = fopen (info.infile, "rb"); |
986 | if (infile == NULL((void*)0)) |
987 | error (EXIT_FAILURE1, errno(*__errno_location ()), "%s", info.infile); |
988 | } |
989 | else |
990 | infile = stdinstdin; |
991 | |
992 | if (info.incert_format) |
993 | info.incert_format = GNUTLS_X509_FMT_DER; |
994 | else |
995 | info.incert_format = GNUTLS_X509_FMT_PEM; |
996 | |
997 | if (info.outcert_format) |
998 | info.outcert_format = GNUTLS_X509_FMT_DER; |
999 | else |
1000 | info.outcert_format = GNUTLS_X509_FMT_PEM; |
1001 | |
1002 | default_dig = GNUTLS_DIG_UNKNOWN; |
1003 | if (info.hash != NULL((void*)0)) |
1004 | { |
1005 | if (strcasecmp (info.hash, "md5") == 0) |
1006 | { |
1007 | fprintf (stderrstderr, |
1008 | "Warning: MD5 is broken, and should not be used any more for digital signatures.\n"); |
1009 | default_dig = GNUTLS_DIG_MD5; |
1010 | } |
1011 | else if (strcasecmp (info.hash, "sha1") == 0) |
1012 | default_dig = GNUTLS_DIG_SHA1; |
1013 | else if (strcasecmp (info.hash, "sha256") == 0) |
1014 | default_dig = GNUTLS_DIG_SHA256; |
1015 | else if (strcasecmp (info.hash, "sha224") == 0) |
1016 | default_dig = GNUTLS_DIG_SHA224; |
1017 | else if (strcasecmp (info.hash, "sha384") == 0) |
1018 | default_dig = GNUTLS_DIG_SHA384; |
1019 | else if (strcasecmp (info.hash, "sha512") == 0) |
1020 | default_dig = GNUTLS_DIG_SHA512; |
1021 | else if (strcasecmp (info.hash, "rmd160") == 0) |
1022 | default_dig = GNUTLS_DIG_RMD160; |
1023 | else |
1024 | error (EXIT_FAILURE1, 0, "invalid hash: %s", info.hash); |
1025 | } |
1026 | |
1027 | batch = 0; |
1028 | if (info.template) |
1029 | { |
1030 | batch = 1; |
1031 | template_parse (info.template); |
1032 | } |
1033 | |
1034 | gnutls_global_set_log_function (tls_log_func); |
1035 | gnutls_global_set_log_level (info.debug); |
1036 | if (info.debug > 1) |
1037 | printf ("Setting log level to %d\n", info.debug); |
1038 | |
1039 | if ((ret = gnutls_global_init ()) < 0) |
1040 | error (EXIT_FAILURE1, 0, "global_init: %s", gnutls_strerror (ret)); |
1041 | |
1042 | #ifdef ENABLE_PKCS111 |
1043 | pkcs11_common(); |
1044 | #endif |
1045 | |
1046 | memset (&cinfo, 0, sizeof (cinfo)); |
1047 | cinfo.privkey = info.privkey; |
1048 | cinfo.pubkey = info.pubkey; |
1049 | cinfo.pkcs8 = info.pkcs8; |
1050 | cinfo.incert_format = info.incert_format; |
1051 | cinfo.cert = info.cert; |
1052 | cinfo.request = info.request; |
1053 | cinfo.ca = info.ca; |
1054 | cinfo.ca_privkey = info.ca_privkey; |
1055 | cinfo.bits = info.bits; |
1056 | cinfo.sec_param = info.sec_param; |
1057 | |
1058 | switch (info.action) |
1059 | { |
1060 | case ACTION_SELF_SIGNED: |
1061 | generate_self_signed (&cinfo); |
1062 | break; |
1063 | case ACTION_GENERATE_PRIVKEY: |
1064 | generate_private_key (); |
1065 | break; |
1066 | case ACTION_CERT_INFO: |
1067 | certificate_info (0, &cinfo); |
1068 | break; |
1069 | case ACTION_DH_INFO: |
1070 | dh_info (&cinfo); |
1071 | break; |
1072 | case ACTION_CERT_PUBKEY: |
1073 | certificate_info (1, &cinfo); |
1074 | break; |
1075 | case ACTION_GENERATE_REQUEST: |
1076 | generate_request (&cinfo); |
1077 | break; |
1078 | case ACTION_GENERATE_CERTIFICATE: |
1079 | generate_signed_certificate (&cinfo); |
1080 | break; |
1081 | case ACTION_VERIFY_CHAIN: |
1082 | verify_chain (); |
1083 | break; |
1084 | case ACTION_VERIFY: |
1085 | verify_certificate (&cinfo); |
1086 | break; |
1087 | case ACTION_PRIVKEY_INFO: |
1088 | privkey_info (); |
1089 | break; |
1090 | case ACTION_PUBKEY_INFO: |
1091 | pubkey_info (NULL((void*)0), &cinfo); |
1092 | break; |
1093 | case ACTION_UPDATE_CERTIFICATE: |
1094 | update_signed_certificate (&cinfo); |
1095 | break; |
1096 | case ACTION_TO_PKCS12: |
1097 | generate_pkcs12 (&cinfo); |
1098 | break; |
1099 | case ACTION_PKCS12_INFO: |
1100 | pkcs12_info (); |
1101 | break; |
1102 | case ACTION_GENERATE_DH: |
1103 | generate_prime (1, &cinfo); |
1104 | break; |
1105 | case ACTION_GET_DH: |
1106 | generate_prime (0, &cinfo); |
1107 | break; |
1108 | case ACTION_CRL_INFO: |
1109 | crl_info (); |
1110 | break; |
1111 | case ACTION_P7_INFO: |
1112 | pkcs7_info (); |
1113 | break; |
1114 | case ACTION_GENERATE_CRL: |
1115 | generate_signed_crl (&cinfo); |
1116 | break; |
1117 | case ACTION_VERIFY_CRL: |
1118 | verify_crl (&cinfo); |
1119 | break; |
1120 | case ACTION_SMIME_TO_P7: |
1121 | smime_to_pkcs7 (); |
1122 | break; |
1123 | case ACTION_GENERATE_PROXY: |
1124 | generate_proxy_certificate (&cinfo); |
1125 | break; |
1126 | case ACTION_GENERATE_PKCS8: |
1127 | generate_pkcs8 (&cinfo); |
1128 | break; |
1129 | #ifdef ENABLE_OPENPGP1 |
1130 | case ACTION_PGP_INFO: |
1131 | pgp_certificate_info (); |
1132 | break; |
1133 | case ACTION_PGP_PRIVKEY_INFO: |
1134 | pgp_privkey_info (); |
1135 | break; |
1136 | case ACTION_RING_INFO: |
1137 | pgp_ring_info (); |
1138 | break; |
1139 | #endif |
1140 | case ACTION_REQUEST: |
1141 | crq_info (); |
1142 | break; |
1143 | default: |
1144 | gaa_help (); |
1145 | exit (0); |
1146 | } |
1147 | fclose (outfile); |
1148 | |
1149 | #ifdef ENABLE_PKCS111 |
1150 | gnutls_pkcs11_deinit (); |
1151 | #endif |
1152 | gnutls_global_deinit (); |
1153 | } |
1154 | |
1155 | #define MAX_CRTS500 500 |
1156 | void |
1157 | certificate_info (int pubkey, common_info_st * cinfo) |
1158 | { |
1159 | gnutls_x509_crt_t crt[MAX_CRTS500]; |
1160 | size_t size; |
1161 | int ret, i, count; |
1162 | gnutls_datum_t pem; |
1163 | unsigned int crt_num; |
1164 | |
1165 | pem.data = fread_file_gnutls_fread_file (infile, &size); |
1166 | pem.size = size; |
1167 | |
1168 | crt_num = MAX_CRTS500; |
1169 | ret = |
1170 | gnutls_x509_crt_list_import (crt, &crt_num, &pem, info.incert_format, |
1171 | GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED); |
1172 | if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER-51) |
1173 | { |
1174 | error (0, 0, "too many certificates (%d); " |
1175 | "will only read the first %d", crt_num, MAX_CRTS500); |
1176 | crt_num = MAX_CRTS500; |
1177 | ret = gnutls_x509_crt_list_import (crt, &crt_num, &pem, |
1178 | info.incert_format, 0); |
1179 | } |
1180 | if (ret < 0) |
1181 | error (EXIT_FAILURE1, 0, "import error: %s", gnutls_strerror (ret)); |
1182 | |
1183 | free (pem.data); |
1184 | |
1185 | count = ret; |
1186 | |
1187 | if (count > 1 && info.outcert_format == GNUTLS_X509_FMT_DER) |
1188 | { |
1189 | error (0, 0, "cannot output multiple certificates in DER format; " |
1190 | "using PEM instead"); |
1191 | info.outcert_format = GNUTLS_X509_FMT_PEM; |
1192 | } |
1193 | |
1194 | for (i = 0; i < count; i++) |
1195 | { |
1196 | if (i > 0) |
1197 | fprintf (outfile, "\n"); |
1198 | |
1199 | if (info.outcert_format == GNUTLS_X509_FMT_PEM) |
1200 | print_certificate_info (crt[i], outfile, 1); |
1201 | |
1202 | if (pubkey) |
1203 | pubkey_info (crt[i], cinfo); |
1204 | else |
1205 | { |
1206 | size = buffer_size; |
1207 | ret = gnutls_x509_crt_export (crt[i], info.outcert_format, buffer, |
1208 | &size); |
1209 | if (ret < 0) |
1210 | error (EXIT_FAILURE1, 0, "export error: %s", gnutls_strerror (ret)); |
1211 | |
1212 | fwrite (buffer, 1, size, outfile); |
1213 | } |
1214 | |
1215 | gnutls_x509_crt_deinit (crt[i]); |
1216 | } |
1217 | } |
1218 | |
1219 | #ifdef ENABLE_OPENPGP1 |
1220 | |
1221 | void |
1222 | pgp_certificate_info (void) |
1223 | { |
1224 | gnutls_openpgp_crt_t crt; |
1225 | size_t size; |
1226 | int ret; |
1227 | gnutls_datum_t pem, out_data; |
1228 | unsigned int verify_status; |
1229 | |
1230 | pem.data = fread_file_gnutls_fread_file (infile, &size); |
1231 | pem.size = size; |
1232 | |
1233 | ret = gnutls_openpgp_crt_init (&crt); |
1234 | if (ret < 0) |
1235 | error (EXIT_FAILURE1, 0, "openpgp_crt_init: %s", gnutls_strerror (ret)); |
1236 | |
1237 | ret = gnutls_openpgp_crt_import (crt, &pem, info.incert_format); |
1238 | |
1239 | if (ret < 0) |
1240 | error (EXIT_FAILURE1, 0, "import error: %s", gnutls_strerror (ret)); |
1241 | |
1242 | free (pem.data); |
1243 | |
1244 | if (info.outcert_format == GNUTLS_OPENPGP_FMT_BASE64) |
1245 | { |
1246 | ret = gnutls_openpgp_crt_print (crt, 0, &out_data); |
1247 | |
1248 | if (ret == 0) |
1249 | { |
1250 | fprintf (outfile, "%s\n", out_data.data); |
1251 | gnutls_free (out_data.data); |
1252 | } |
1253 | } |
1254 | |
1255 | |
1256 | ret = gnutls_openpgp_crt_verify_self (crt, 0, &verify_status); |
1257 | if (ret < 0) |
1258 | { |
1259 | error (EXIT_FAILURE1, 0, "verify signature error: %s", |
1260 | gnutls_strerror (ret)); |
1261 | } |
1262 | |
1263 | if (verify_status & GNUTLS_CERT_INVALID) |
1264 | { |
1265 | fprintf (outfile, "Self Signature verification: failed\n\n"); |
1266 | } |
1267 | else |
1268 | { |
1269 | fprintf (outfile, "Self Signature verification: ok (%x)\n\n", |
1270 | verify_status); |
1271 | } |
1272 | |
1273 | size = buffer_size; |
1274 | ret = gnutls_openpgp_crt_export (crt, info.outcert_format, buffer, &size); |
1275 | if (ret < 0) |
1276 | { |
1277 | error (EXIT_FAILURE1, 0, "export error: %s", gnutls_strerror (ret)); |
1278 | fwrite (buffer, 1, size, outfile); |
1279 | } |
1280 | |
1281 | fprintf (outfile, "%s\n", buffer); |
1282 | gnutls_openpgp_crt_deinit (crt); |
1283 | } |
1284 | |
1285 | void |
1286 | pgp_privkey_info (void) |
1287 | { |
1288 | gnutls_openpgp_privkey_t key; |
1289 | unsigned char keyid[GNUTLS_OPENPGP_KEYID_SIZE8]; |
1290 | size_t size; |
1291 | int ret, i, subkeys, bits = 0; |
1292 | gnutls_datum_t pem; |
1293 | const char *cprint; |
1294 | |
1295 | size = fread (buffer, 1, buffer_size - 1, infile); |
1296 | buffer[size] = 0; |
1297 | |
1298 | gnutls_openpgp_privkey_init (&key); |
1299 | |
1300 | pem.data = buffer; |
1301 | pem.size = size; |
1302 | |
1303 | ret = gnutls_openpgp_privkey_import (key, &pem, info.incert_format, |
1304 | NULL((void*)0), 0); |
1305 | |
1306 | if (ret < 0) |
1307 | error (EXIT_FAILURE1, 0, "import error: %s", gnutls_strerror (ret)); |
1308 | |
1309 | |
1310 | |
1311 | subkeys = gnutls_openpgp_privkey_get_subkey_count (key); |
1312 | if (subkeys < 0) |
1313 | error (EXIT_FAILURE1, 0, "privkey_get_subkey_count: %s", |
1314 | gnutls_strerror (subkeys)); |
1315 | |
1316 | for (i = -1; i < subkeys; i++) |
1317 | { |
1318 | |
1319 | if (i != -1) |
1320 | fprintf (outfile, "Subkey[%d]:\n", i); |
1321 | |
1322 | fprintf (outfile, "Public Key Info:\n"); |
1323 | |
1324 | if (i == -1) |
1325 | ret = gnutls_openpgp_privkey_get_pk_algorithm (key, NULL((void*)0)); |
1326 | else |
1327 | ret = gnutls_openpgp_privkey_get_subkey_pk_algorithm (key, i, NULL((void*)0)); |
1328 | |
1329 | fprintf (outfile, "\tPublic Key Algorithm: "); |
1330 | cprint = gnutls_pk_algorithm_get_name (ret); |
1331 | fprintf (outfile, "%s\n", cprint ? cprint : "Unknown"); |
1332 | fprintf (outfile, "\tKey Security Level: %s\n", |
1333 | gnutls_sec_param_get_name (gnutls_openpgp_privkey_sec_param |
1334 | (key))); |
1335 | |
1336 | |
1337 | |
1338 | |
1339 | if (ret == GNUTLS_PK_RSA) |
1340 | { |
1341 | gnutls_datum_t m, e, d, p, q, u; |
1342 | |
1343 | if (i == -1) |
1344 | ret = |
1345 | gnutls_openpgp_privkey_export_rsa_raw (key, &m, &e, &d, &p, |
1346 | &q, &u); |
1347 | else |
1348 | ret = |
1349 | gnutls_openpgp_privkey_export_subkey_rsa_raw (key, i, &m, |
1350 | &e, &d, &p, |
1351 | &q, &u); |
1352 | if (ret < 0) |
1353 | fprintf (stderrstderr, "Error in key RSA data export: %s\n", |
1354 | gnutls_strerror (ret)); |
1355 | else |
1356 | print_rsa_pkey (&m, &e, &d, &p, &q, &u, NULL((void*)0), NULL((void*)0)); |
1357 | |
1358 | bits = m.size * 8; |
1359 | } |
1360 | else if (ret == GNUTLS_PK_DSA) |
1361 | { |
1362 | gnutls_datum_t p, q, g, y, x; |
1363 | |
1364 | if (i == -1) |
1365 | ret = |
1366 | gnutls_openpgp_privkey_export_dsa_raw (key, &p, &q, &g, &y, &x); |
1367 | else |
1368 | ret = |
1369 | gnutls_openpgp_privkey_export_subkey_dsa_raw (key, i, &p, |
1370 | &q, &g, &y, &x); |
1371 | if (ret < 0) |
1372 | fprintf (stderrstderr, "Error in key DSA data export: %s\n", |
1373 | gnutls_strerror (ret)); |
1374 | else |
1375 | print_dsa_pkey (&x, &y, &p, &q, &g); |
1376 | |
1377 | bits = y.size * 8; |
1378 | } |
1379 | |
1380 | fprintf (outfile, "\n"); |
1381 | |
1382 | size = buffer_size; |
1383 | if (i == -1) |
1384 | ret = gnutls_openpgp_privkey_get_key_id (key, keyid); |
1385 | else |
1386 | ret = gnutls_openpgp_privkey_get_subkey_id (key, i, keyid); |
1387 | |
1388 | if (ret < 0) |
1389 | { |
1390 | fprintf (stderrstderr, "Error in key id calculation: %s\n", |
1391 | gnutls_strerror (ret)); |
1392 | } |
1393 | else |
1394 | { |
1395 | fprintf (outfile, "Public key ID: %s\n", raw_to_string (keyid, 8)); |
1396 | } |
1397 | |
1398 | size = buffer_size; |
1399 | if (i == -1) |
1400 | ret = gnutls_openpgp_privkey_get_fingerprint (key, buffer, &size); |
1401 | else |
1402 | ret = gnutls_openpgp_privkey_get_subkey_fingerprint (key, i, buffer, &size); |
1403 | |
1404 | if (ret < 0) |
1405 | { |
1406 | fprintf (stderrstderr, "Error in fingerprint calculation: %s\n", |
1407 | gnutls_strerror (ret)); |
1408 | } |
1409 | else |
1410 | { |
1411 | gnutls_datum_t art; |
1412 | |
1413 | fprintf (outfile, "Fingerprint: %s\n", raw_to_string (buffer, size)); |
1414 | |
1415 | ret = gnutls_random_art(GNUTLS_RANDOM_ART_OPENSSH, cprint, bits, buffer, size, &art); |
1416 | if (ret >= 0) |
1417 | { |
1418 | fprintf (outfile, "Fingerprint's random art:\n%s\n\n", art.data); |
1419 | gnutls_free(art.data); |
1420 | } |
1421 | } |
1422 | } |
1423 | |
1424 | size = buffer_size; |
1425 | ret = gnutls_openpgp_privkey_export (key, GNUTLS_OPENPGP_FMT_BASE64, |
1426 | NULL((void*)0), 0, buffer, &size); |
1427 | if (ret < 0) |
1428 | error (EXIT_FAILURE1, 0, "export error: %s", gnutls_strerror (ret)); |
1429 | |
1430 | fprintf (outfile, "\n%s\n", buffer); |
1431 | |
1432 | gnutls_openpgp_privkey_deinit (key); |
1433 | } |
1434 | |
1435 | void |
1436 | pgp_ring_info (void) |
1437 | { |
1438 | gnutls_openpgp_keyring_t ring; |
1439 | gnutls_openpgp_crt_t crt; |
1440 | size_t size; |
1441 | int ret, i, count; |
1442 | gnutls_datum_t pem; |
1443 | |
1444 | pem.data = fread_file_gnutls_fread_file (infile, &size); |
1445 | pem.size = size; |
1446 | |
1447 | ret = gnutls_openpgp_keyring_init (&ring); |
1448 | if (ret < 0) |
1449 | error (EXIT_FAILURE1, 0, "openpgp_keyring_init: %s", |
1450 | gnutls_strerror (ret)); |
1451 | |
1452 | ret = gnutls_openpgp_keyring_import (ring, &pem, info.incert_format); |
1453 | |
1454 | if (ret < 0) |
1455 | error (EXIT_FAILURE1, 0, "import error: %s", gnutls_strerror (ret)); |
1456 | |
1457 | free (pem.data); |
1458 | |
1459 | count = gnutls_openpgp_keyring_get_crt_count (ring); |
1460 | if (count >= 0) |
1461 | fprintf (outfile, "Keyring contains %d OpenPGP certificates\n\n", count); |
1462 | else |
1463 | error (EXIT_FAILURE1, 0, "keyring error: %s", gnutls_strerror (count)); |
1464 | |
1465 | for (i = 0; i < count; i++) |
1466 | { |
1467 | ret = gnutls_openpgp_keyring_get_crt (ring, i, &crt); |
1468 | if (ret < 0) |
1469 | error (EXIT_FAILURE1, 0, "export error: %s", gnutls_strerror (ret)); |
1470 | |
1471 | size = buffer_size; |
1472 | ret = gnutls_openpgp_crt_export (crt, info.outcert_format, |
1473 | buffer, &size); |
1474 | if (ret < 0) |
1475 | error (EXIT_FAILURE1, 0, "export error: %s", gnutls_strerror (ret)); |
1476 | |
1477 | fwrite (buffer, 1, size, outfile); |
1478 | fprintf (outfile, "\n\n"); |
1479 | |
1480 | gnutls_openpgp_crt_deinit (crt); |
1481 | |
1482 | |
1483 | } |
1484 | |
1485 | gnutls_openpgp_keyring_deinit (ring); |
1486 | } |
1487 | |
1488 | |
1489 | #endif |
1490 | |
1491 | static void |
1492 | print_hex_datum (gnutls_datum_t * dat) |
1493 | { |
1494 | unsigned int j; |
1495 | #define SPACE"\t" "\t" |
1496 | fprintf (outfile, "\n" SPACE"\t"); |
1497 | for (j = 0; j < dat->size; j++) |
1498 | { |
1499 | fprintf (outfile, "%.2x:", (unsigned char) dat->data[j]); |
1500 | if ((j + 1) % 15 == 0) |
1501 | fprintf (outfile, "\n" SPACE"\t"); |
1502 | } |
1503 | fprintf (outfile, "\n"); |
1504 | } |
1505 | |
1506 | |
1507 | static void |
1508 | print_certificate_info (gnutls_x509_crt_t crt, FILE * out, unsigned int all) |
1509 | { |
1510 | gnutls_datum_t cinfo; |
1511 | int ret; |
1512 | |
1513 | if (all) |
1514 | ret = gnutls_x509_crt_print (crt, GNUTLS_CRT_PRINT_FULL, &cinfo); |
1515 | else |
1516 | ret = gnutls_x509_crt_print (crt, GNUTLS_CRT_PRINT_UNSIGNED_FULL, &cinfo); |
1517 | if (ret == 0) |
1518 | { |
1519 | fprintf (out, "%s\n", cinfo.data); |
1520 | gnutls_free (cinfo.data); |
1521 | } |
1522 | |
1523 | if (out == stderrstderr && batch == 0) |
1524 | if (read_yesno ("Is the above information ok? (y/N): ") == 0) |
1525 | { |
1526 | exit (1); |
1527 | } |
1528 | } |
1529 | |
1530 | static void |
1531 | print_crl_info (gnutls_x509_crl_t crl, FILE * out) |
1532 | { |
1533 | gnutls_datum_t cinfo; |
1534 | int ret; |
1535 | size_t size; |
1536 | |
1537 | ret = gnutls_x509_crl_print (crl, GNUTLS_CRT_PRINT_FULL, &cinfo); |
1538 | if (ret < 0) |
1539 | error (EXIT_FAILURE1, 0, "crl_print: %s", gnutls_strerror (ret)); |
1540 | |
1541 | fprintf (out, "%s\n", cinfo.data); |
1542 | |
1543 | gnutls_free (cinfo.data); |
1544 | |
1545 | size = buffer_size; |
1546 | ret = gnutls_x509_crl_export (crl, GNUTLS_X509_FMT_PEM, buffer, &size); |
1547 | if (ret < 0) |
1548 | error (EXIT_FAILURE1, 0, "crl_export: %s", gnutls_strerror (ret)); |
1549 | |
1550 | fwrite (buffer, 1, size, outfile); |
1551 | } |
1552 | |
1553 | void |
1554 | crl_info (void) |
1555 | { |
1556 | gnutls_x509_crl_t crl; |
1557 | int ret; |
1558 | size_t size; |
1559 | gnutls_datum_t pem; |
1560 | |
1561 | ret = gnutls_x509_crl_init (&crl); |
1562 | if (ret < 0) |
1563 | error (EXIT_FAILURE1, 0, "crl_init: %s", gnutls_strerror (ret)); |
1564 | |
1565 | pem.data = fread_file_gnutls_fread_file (infile, &size); |
1566 | pem.size = size; |
1567 | |
1568 | if (!pem.data) |
1569 | error (EXIT_FAILURE1, errno(*__errno_location ()), "%s", info.infile ? info.infile : |
1570 | "standard input"); |
1571 | |
1572 | ret = gnutls_x509_crl_import (crl, &pem, info.incert_format); |
1573 | |
1574 | free (pem.data); |
1575 | if (ret < 0) |
1576 | error (EXIT_FAILURE1, 0, "import error: %s", gnutls_strerror (ret)); |
1577 | |
1578 | print_crl_info (crl, outfile); |
1579 | |
1580 | gnutls_x509_crl_deinit (crl); |
1581 | } |
1582 | |
1583 | static void |
1584 | print_crq_info (gnutls_x509_crq_t crq, FILE * out) |
1585 | { |
1586 | gnutls_datum_t cinfo; |
1587 | int ret; |
1588 | size_t size; |
1589 | |
1590 | if (info.outcert_format == GNUTLS_X509_FMT_PEM) |
1591 | { |
1592 | ret = gnutls_x509_crq_print (crq, GNUTLS_CRT_PRINT_FULL, &cinfo); |
1593 | if (ret < 0) |
1594 | error (EXIT_FAILURE1, 0, "crq_print: %s", gnutls_strerror (ret)); |
1595 | |
1596 | fprintf (out, "%s\n", cinfo.data); |
1597 | |
1598 | gnutls_free (cinfo.data); |
1599 | } |
1600 | |
1601 | ret = gnutls_x509_crq_verify(crq, 0); |
1602 | if (ret < 0) |
1603 | { |
1604 | fprintf(out, "Self signature: FAILED\n\n"); |
1605 | } |
1606 | else |
1607 | { |
1608 | fprintf(out, "Self signature: verified\n\n"); |
1609 | } |
1610 | |
1611 | size = buffer_size; |
1612 | ret = gnutls_x509_crq_export (crq, info.outcert_format, buffer, &size); |
1613 | if (ret < 0) |
1614 | error (EXIT_FAILURE1, 0, "crq_export: %s", gnutls_strerror (ret)); |
1615 | |
1616 | fwrite (buffer, 1, size, outfile); |
1617 | } |
1618 | |
1619 | void |
1620 | crq_info (void) |
1621 | { |
1622 | gnutls_x509_crq_t crq; |
1623 | int ret; |
1624 | size_t size; |
1625 | gnutls_datum_t pem; |
1626 | |
1627 | ret = gnutls_x509_crq_init (&crq); |
1628 | if (ret < 0) |
1629 | error (EXIT_FAILURE1, 0, "crq_init: %s", gnutls_strerror (ret)); |
1630 | |
1631 | pem.data = fread_file_gnutls_fread_file (infile, &size); |
1632 | pem.size = size; |
1633 | |
1634 | if (!pem.data) |
1635 | error (EXIT_FAILURE1, errno(*__errno_location ()), "%s", info.infile ? info.infile : |
1636 | "standard input"); |
1637 | |
1638 | ret = gnutls_x509_crq_import (crq, &pem, info.incert_format); |
1639 | |
1640 | free (pem.data); |
1641 | if (ret < 0) |
1642 | error (EXIT_FAILURE1, 0, "import error: %s", gnutls_strerror (ret)); |
1643 | |
1644 | print_crq_info (crq, outfile); |
1645 | |
1646 | gnutls_x509_crq_deinit (crq); |
1647 | } |
1648 | |
1649 | static void privkey_info_int (gnutls_x509_privkey_t key) |
1650 | { |
1651 | int ret, key_type, bits = 0; |
1652 | size_t size; |
1653 | const char *cprint; |
1654 | |
1655 | |
1656 | |
1657 | fprintf (outfile, "Public Key Info:\n"); |
1658 | ret = gnutls_x509_privkey_get_pk_algorithm (key); |
1659 | fprintf (outfile, "\tPublic Key Algorithm: "); |
1660 | |
1661 | key_type = ret; |
1662 | |
1663 | cprint = gnutls_pk_algorithm_get_name (key_type); |
1664 | fprintf (outfile, "%s\n", cprint ? cprint : "Unknown"); |
1665 | fprintf (outfile, "\tKey Security Level: %s\n\n", |
1666 | gnutls_sec_param_get_name (gnutls_x509_privkey_sec_param (key))); |
1667 | |
1668 | |
1669 | |
1670 | if (key_type == GNUTLS_PK_RSA) |
1671 | { |
1672 | gnutls_datum_t m, e, d, p, q, u, exp1, exp2; |
1673 | |
1674 | ret = |
1675 | gnutls_x509_privkey_export_rsa_raw2 (key, &m, &e, &d, &p, &q, &u, |
1676 | &exp1, &exp2); |
1677 | if (ret < 0) |
1678 | fprintf (stderrstderr, "Error in key RSA data export: %s\n", |
1679 | gnutls_strerror (ret)); |
1680 | else |
1681 | { |
1682 | print_rsa_pkey (&m, &e, &d, &p, &q, &u, &exp1, &exp2); |
1683 | bits = m.size * 8; |
1684 | |
1685 | gnutls_free (m.data); |
1686 | gnutls_free (e.data); |
1687 | gnutls_free (d.data); |
1688 | gnutls_free (p.data); |
1689 | gnutls_free (q.data); |
1690 | gnutls_free (u.data); |
1691 | gnutls_free (exp1.data); |
1692 | gnutls_free (exp2.data); |
1693 | } |
1694 | } |
1695 | else if (key_type == GNUTLS_PK_DSA) |
1696 | { |
1697 | gnutls_datum_t p, q, g, y, x; |
1698 | |
1699 | ret = gnutls_x509_privkey_export_dsa_raw (key, &p, &q, &g, &y, &x); |
1700 | if (ret < 0) |
1701 | fprintf (stderrstderr, "Error in key DSA data export: %s\n", |
1702 | gnutls_strerror (ret)); |
1703 | else |
1704 | { |
1705 | print_dsa_pkey (&x, &y, &p, &q, &g); |
1706 | bits = y.size * 8; |
1707 | |
1708 | gnutls_free (x.data); |
1709 | gnutls_free (y.data); |
1710 | gnutls_free (p.data); |
1711 | gnutls_free (q.data); |
1712 | gnutls_free (g.data); |
1713 | } |
1714 | } |
1715 | else if (key_type == GNUTLS_PK_EC) |
1716 | { |
1717 | gnutls_datum_t y, x, k; |
1718 | gnutls_ecc_curve_t curve; |
1719 | |
1720 | ret = gnutls_x509_privkey_export_ecc_raw (key, &curve, &x, &y, &k); |
1721 | if (ret < 0) |
1722 | fprintf (stderrstderr, "Error in key ECC data export: %s\n", |
1723 | gnutls_strerror (ret)); |
1724 | else |
1725 | { |
1726 | print_ecc_pkey (curve, &k, &x, &y); |
1727 | bits = gnutls_ecc_curve_get_size(curve) * 8; |
1728 | |
1729 | gnutls_free (x.data); |
1730 | gnutls_free (y.data); |
1731 | gnutls_free (k.data); |
1732 | } |
1733 | } |
1734 | |
1735 | fprintf (outfile, "\n"); |
1736 | |
1737 | size = buffer_size; |
1738 | if ((ret = gnutls_x509_privkey_get_key_id (key, 0, buffer, &size)) < 0) |
1739 | { |
1740 | fprintf (stderrstderr, "Error in key id calculation: %s\n", |
1741 | gnutls_strerror (ret)); |
1742 | } |
1743 | else |
1744 | { |
1745 | gnutls_datum_t art; |
1746 | |
1747 | fprintf (outfile, "Public Key ID: %s\n", raw_to_string (buffer, size)); |
1748 | |
1749 | ret = gnutls_random_art(GNUTLS_RANDOM_ART_OPENSSH, cprint, bits, buffer, size, &art); |
1750 | if (ret >= 0) |
1751 | { |
1752 | fprintf (outfile, "Public key's random art:\n%s\n", art.data); |
1753 | gnutls_free(art.data); |
1754 | } |
1755 | } |
1756 | fprintf (outfile, "\n"); |
1757 | |
1758 | } |
1759 | |
1760 | void |
1761 | privkey_info (void) |
1762 | { |
1763 | gnutls_x509_privkey_t key; |
1764 | size_t size; |
1765 | int ret; |
1766 | gnutls_datum_t pem; |
1767 | const char *pass; |
1768 | |
1769 | size = fread (buffer, 1, buffer_size - 1, infile); |
1770 | buffer[size] = 0; |
1771 | |
1772 | gnutls_x509_privkey_init (&key); |
1773 | |
1774 | pem.data = buffer; |
1775 | pem.size = size; |
1776 | |
1777 | ret = 0; |
1778 | if (!info.pkcs8) |
1779 | ret = gnutls_x509_privkey_import (key, &pem, info.incert_format); |
1780 | |
1781 | |
1782 | if (info.pkcs8 || ret == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR-207) |
1783 | { |
1784 | if (info.pass) |
1785 | pass = info.pass; |
1786 | else |
1787 | pass = get_pass (); |
1788 | ret = gnutls_x509_privkey_import_pkcs8 (key, &pem, |
1789 | info.incert_format, pass, 0); |
1790 | } |
1791 | if (ret < 0) |
1792 | error (EXIT_FAILURE1, 0, "import error: %s", gnutls_strerror (ret)); |
1793 | |
1794 | if (info.outcert_format == GNUTLS_X509_FMT_PEM) |
1795 | privkey_info_int (key); |
1796 | |
1797 | ret = gnutls_x509_privkey_verify_params (key); |
1798 | if (ret < 0) |
1799 | fprintf (outfile, "\n** Private key parameters validation failed **\n\n"); |
1800 | |
1801 | if (info.fix_key != 0) |
1802 | { |
1803 | ret = gnutls_x509_privkey_fix (key); |
1804 | if (ret < 0) |
1805 | error (EXIT_FAILURE1, 0, "privkey_fix: %s", gnutls_strerror (ret)); |
1806 | } |
1807 | |
1808 | size = buffer_size; |
1809 | ret = gnutls_x509_privkey_export (key, info.outcert_format, buffer, &size); |
1810 | if (ret < 0) |
1811 | error (EXIT_FAILURE1, 0, "export error: %s", gnutls_strerror (ret)); |
1812 | |
1813 | fwrite (buffer, 1, size, outfile); |
1814 | |
1815 | gnutls_x509_privkey_deinit (key); |
1816 | } |
1817 | |
1818 | |
1819 | |
1820 | |
1821 | void |
1822 | generate_request (common_info_st * cinfo) |
1823 | { |
1824 | gnutls_x509_crq_t crq; |
1825 | gnutls_x509_privkey_t xkey; |
1826 | gnutls_pubkey_t pubkey; |
1827 | gnutls_privkey_t pkey; |
1828 | int ret, ca_status, path_len; |
1829 | const char *pass; |
1830 | unsigned int usage = 0; |
1831 | |
1832 | fprintf (stderrstderr, "Generating a PKCS #10 certificate request...\n"); |
1833 | |
1834 | ret = gnutls_x509_crq_init (&crq); |
1835 | if (ret < 0) |
1836 | error (EXIT_FAILURE1, 0, "crq_init: %s", gnutls_strerror (ret)); |
1837 | |
1838 | |
1839 | |
1840 | |
1841 | pkey = load_private_key (0, cinfo); |
1842 | if (!pkey) |
1843 | { |
1844 | ret = gnutls_privkey_init (&pkey); |
1845 | if (ret < 0) |
1846 | error (EXIT_FAILURE1, 0, "privkey_init: %s", gnutls_strerror (ret)); |
1847 | |
1848 | xkey = generate_private_key_int (); |
1849 | |
1850 | print_private_key (xkey); |
1851 | |
1852 | ret = gnutls_privkey_import_x509(pkey, xkey, GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE(1<<0)); |
1853 | if (ret < 0) |
1854 | error (EXIT_FAILURE1, 0, "privkey_import_x509: %s", gnutls_strerror (ret)); |
1855 | } |
1856 | |
1857 | pubkey = load_public_key_or_import (1, pkey, cinfo); |
1858 | |
1859 | |
1860 | |
1861 | get_country_crq_set (crq); |
1862 | get_organization_crq_set (crq); |
1863 | get_unit_crq_set (crq); |
1864 | get_locality_crq_set (crq); |
1865 | get_state_crq_set (crq); |
1866 | get_cn_crq_set (crq); |
1867 | get_uid_crq_set (crq); |
1868 | get_oid_crq_set (crq); |
1869 | |
1870 | get_dns_name_set (TYPE_CRQ2, crq); |
1871 | get_ip_addr_set (TYPE_CRQ2, crq); |
1872 | get_email_set (TYPE_CRQ2, crq); |
1873 | |
1874 | pass = get_challenge_pass (); |
1875 | |
1876 | if (pass != NULL((void*)0) && pass[0] != 0) |
1877 | { |
1878 | ret = gnutls_x509_crq_set_challenge_password (crq, pass); |
1879 | if (ret < 0) |
1880 | error (EXIT_FAILURE1, 0, "set_pass: %s", gnutls_strerror (ret)); |
1881 | } |
1882 | |
1883 | if (info.crq_extensions != 0) |
1884 | { |
1885 | ca_status = get_ca_status (); |
1886 | if (ca_status) |
1887 | path_len = get_path_len (); |
1888 | else |
1889 | path_len = -1; |
1890 | |
1891 | ret = gnutls_x509_crq_set_basic_constraints (crq, ca_status, path_len); |
1892 | if (ret < 0) |
1893 | error (EXIT_FAILURE1, 0, "set_basic_constraints: %s", |
1894 | gnutls_strerror (ret)); |
1895 | |
1896 | ret = get_sign_status (1); |
1897 | if (ret) |
1898 | usage |= GNUTLS_KEY_DIGITAL_SIGNATURE128; |
1899 | |
1900 | ret = get_encrypt_status (1); |
1901 | if (ret) |
1902 | usage |= GNUTLS_KEY_KEY_ENCIPHERMENT32; |
1903 | else |
1904 | usage |= GNUTLS_KEY_DIGITAL_SIGNATURE128; |
1905 | |
1906 | if (ca_status) |
1907 | { |
1908 | ret = get_cert_sign_status (); |
1909 | if (ret) |
1910 | usage |= GNUTLS_KEY_KEY_CERT_SIGN4; |
1911 | |
1912 | ret = get_crl_sign_status (); |
1913 | if (ret) |
1914 | usage |= GNUTLS_KEY_CRL_SIGN2; |
1915 | |
1916 | ret = get_code_sign_status (); |
1917 | if (ret) |
1918 | { |
1919 | ret = gnutls_x509_crq_set_key_purpose_oid |
1920 | (crq, GNUTLS_KP_CODE_SIGNING"1.3.6.1.5.5.7.3.3", 0); |
1921 | if (ret < 0) |
1922 | error (EXIT_FAILURE1, 0, "key_kp: %s", gnutls_strerror (ret)); |
1923 | } |
1924 | |
1925 | ret = get_ocsp_sign_status (); |
1926 | if (ret) |
1927 | { |
1928 | ret = gnutls_x509_crq_set_key_purpose_oid |
1929 | (crq, GNUTLS_KP_OCSP_SIGNING"1.3.6.1.5.5.7.3.9", 0); |
1930 | if (ret < 0) |
1931 | error (EXIT_FAILURE1, 0, "key_kp: %s", gnutls_strerror (ret)); |
1932 | } |
1933 | |
1934 | ret = get_time_stamp_status (); |
1935 | if (ret) |
1936 | { |
1937 | ret = gnutls_x509_crq_set_key_purpose_oid |
1938 | (crq, GNUTLS_KP_TIME_STAMPING"1.3.6.1.5.5.7.3.8", 0); |
1939 | if (ret < 0) |
1940 | error (EXIT_FAILURE1, 0, "key_kp: %s", gnutls_strerror (ret)); |
1941 | } |
1942 | |
1943 | ret = get_ipsec_ike_status (); |
1944 | if (ret) |
1945 | { |
1946 | ret = gnutls_x509_crq_set_key_purpose_oid |
1947 | (crq, GNUTLS_KP_IPSEC_IKE"1.3.6.1.5.5.7.3.17", 0); |
1948 | if (ret < 0) |
1949 | error (EXIT_FAILURE1, 0, "key_kp: %s", gnutls_strerror (ret)); |
1950 | } |
1951 | } |
1952 | |
1953 | ret = gnutls_x509_crq_set_key_usage (crq, usage); |
1954 | if (ret < 0) |
1955 | error (EXIT_FAILURE1, 0, "key_usage: %s", gnutls_strerror (ret)); |
1956 | |
1957 | ret = get_tls_client_status (); |
1958 | if (ret != 0) |
1959 | { |
1960 | ret = gnutls_x509_crq_set_key_purpose_oid |
1961 | (crq, GNUTLS_KP_TLS_WWW_CLIENT"1.3.6.1.5.5.7.3.2", 0); |
1962 | if (ret < 0) |
1963 | error (EXIT_FAILURE1, 0, "key_kp: %s", gnutls_strerror (ret)); |
1964 | } |
1965 | |
1966 | ret = get_tls_server_status (); |
1967 | if (ret != 0) |
1968 | { |
1969 | ret = gnutls_x509_crq_set_key_purpose_oid |
1970 | (crq, GNUTLS_KP_TLS_WWW_SERVER"1.3.6.1.5.5.7.3.1", 0); |
1971 | if (ret < 0) |
1972 | error (EXIT_FAILURE1, 0, "key_kp: %s", gnutls_strerror (ret)); |
1973 | } |
1974 | } |
1975 | |
1976 | ret = gnutls_x509_crq_set_pubkey (crq, pubkey); |
1977 | if (ret < 0) |
1978 | error (EXIT_FAILURE1, 0, "set_key: %s", gnutls_strerror (ret)); |
1979 | |
1980 | ret = gnutls_x509_crq_privkey_sign (crq, pkey, SIGN_HASHGNUTLS_DIG_SHA256, 0); |
1981 | if (ret < 0) |
1982 | error (EXIT_FAILURE1, 0, "sign: %s", gnutls_strerror (ret)); |
1983 | |
1984 | print_crq_info (crq, outfile); |
1985 | |
1986 | gnutls_x509_crq_deinit (crq); |
1987 | gnutls_privkey_deinit( pkey); |
1988 | gnutls_pubkey_deinit( pubkey); |
1989 | |
1990 | } |
1991 | |
1992 | static void print_verification_res (FILE* outfile, unsigned int output); |
1993 | |
1994 | static int detailed_verification(gnutls_x509_crt_t cert, |
1995 | gnutls_x509_crt_t issuer, gnutls_x509_crl_t crl, |
1996 | unsigned int verification_output) |
1997 | { |
1998 | char name[512]; |
1999 | char tmp[255]; |
2000 | char issuer_name[512]; |
2001 | size_t name_size; |
2002 | size_t issuer_name_size; |
2003 | int ret; |
2004 | |
2005 | issuer_name_size = sizeof (issuer_name); |
2006 | ret = |
2007 | gnutls_x509_crt_get_issuer_dn (cert, issuer_name, &issuer_name_size); |
2008 | if (ret < 0) |
2009 | error (EXIT_FAILURE1, 0, "gnutls_x509_crt_get_issuer_dn: %s", gnutls_strerror (ret)); |
2010 | |
2011 | name_size = sizeof (name); |
2012 | ret = |
2013 | gnutls_x509_crt_get_dn (cert, name, &name_size); |
2014 | if (ret < 0) |
2015 | error (EXIT_FAILURE1, 0, "gnutls_x509_crt_get_dn: %s", gnutls_strerror (ret)); |
2016 | |
2017 | fprintf (outfile, "\tSubject: %s\n", name); |
2018 | fprintf (outfile, "\tIssuer: %s\n", issuer_name); |
2019 | |
2020 | if (issuer != NULL((void*)0)) |
2021 | { |
2022 | issuer_name_size = sizeof (issuer_name); |
2023 | ret = |
2024 | gnutls_x509_crt_get_dn (issuer, issuer_name, &issuer_name_size); |
2025 | if (ret < 0) |
2026 | error (EXIT_FAILURE1, 0, "gnutls_x509_crt_get_issuer_dn: %s", gnutls_strerror (ret)); |
2027 | |
2028 | fprintf (outfile, "\tChecked against: %s\n", issuer_name); |
2029 | } |
2030 | |
2031 | if (crl != NULL((void*)0)) |
2032 | { |
2033 | gnutls_datum_t data; |
2034 | |
2035 | issuer_name_size = sizeof (issuer_name); |
2036 | ret = |
2037 | gnutls_x509_crl_get_issuer_dn (crl, issuer_name, &issuer_name_size); |
2038 | if (ret < 0) |
2039 | error (EXIT_FAILURE1, 0, "gnutls_x509_crl_get_issuer_dn: %s", gnutls_strerror (ret)); |
2040 | |
2041 | name_size = sizeof(tmp); |
2042 | ret = gnutls_x509_crl_get_number(crl, tmp, &name_size, NULL((void*)0)); |
2043 | if (ret < 0) |
2044 | strcpy(name, "unnumbered"); |
2045 | else |
2046 | { |
2047 | data.data = tmp; |
2048 | data.size = name_size; |
2049 | |
2050 | name_size = sizeof(name); |
2051 | ret = gnutls_hex_encode(&data, name, &name_size); |
2052 | if (ret < 0) |
2053 | error (EXIT_FAILURE1, 0, "gnutls_hex_encode: %s", gnutls_strerror (ret)); |
2054 | } |
2055 | fprintf (outfile, "\tChecked against CRL[%s] of: %s\n", name, issuer_name); |
2056 | } |
2057 | |
2058 | fprintf (outfile, "\tOutput: "); |
2059 | print_verification_res(outfile, verification_output); |
2060 | |
2061 | fputs(".\n\n", outfile); |
2062 | |
2063 | return 0; |
2064 | } |
2065 | |
2066 | |
2067 | |
2068 | |
2069 | |
2070 | static int |
2071 | _verify_x509_mem (const void *cert, int cert_size, const void* ca, int ca_size) |
2072 | { |
2073 | int ret; |
2074 | gnutls_datum_t tmp; |
2075 | gnutls_x509_crt_t *x509_cert_list = NULL((void*)0); |
2076 | gnutls_x509_crt_t *x509_ca_list = NULL((void*)0); |
2077 | gnutls_x509_crl_t *x509_crl_list = NULL((void*)0); |
2078 | unsigned int x509_ncerts, x509_ncrls = 0, x509_ncas = 0; |
2079 | gnutls_x509_trust_list_t list; |
2080 | unsigned int output; |
2081 | |
2082 | ret = gnutls_x509_trust_list_init(&list, 0); |
2083 | if (ret < 0) |
2084 | error (EXIT_FAILURE1, 0, "gnutls_x509_trust_list_init: %s", |
2085 | gnutls_strerror (ret)); |
2086 | |
2087 | if (ca == NULL((void*)0)) |
2088 | { |
2089 | tmp.data = (void*)cert; |
2090 | tmp.size = cert_size; |
2091 | } |
2092 | else |
2093 | { |
2094 | tmp.data = (void*)ca; |
2095 | tmp.size = ca_size; |
2096 | |
2097 | |
2098 | ret = gnutls_x509_crt_list_import2( &x509_ca_list, &x509_ncas, &tmp, |
2099 | GNUTLS_X509_FMT_PEM, 0); |
2100 | if (ret < 0 || x509_ncas < 1) |
2101 | error (EXIT_FAILURE1, 0, "error parsing CAs: %s", |
2102 | gnutls_strerror (ret)); |
2103 | } |
2104 | |
2105 | ret = gnutls_x509_crl_list_import2( &x509_crl_list, &x509_ncrls, &tmp, |
2106 | GNUTLS_X509_FMT_PEM, 0); |
2107 | if (ret < 0) |
2108 | { |
2109 | x509_crl_list = NULL((void*)0); |
2110 | x509_ncrls = 0; |
2111 | } |
2112 | |
2113 | tmp.data = (void*)cert; |
2114 | tmp.size = cert_size; |
2115 | |
2116 | |
2117 | ret = gnutls_x509_crt_list_import2( &x509_cert_list, &x509_ncerts, &tmp, |
2118 | GNUTLS_X509_FMT_PEM, 0); |
2119 | if (ret < 0 || x509_ncerts < 1) |
2120 | error (EXIT_FAILURE1, 0, "error parsing CRTs: %s", |
2121 | gnutls_strerror (ret)); |
2122 | |
2123 | if (ca == NULL((void*)0)) |
2124 | { |
2125 | x509_ca_list = &x509_cert_list[x509_ncerts - 1]; |
2126 | x509_ncas = 1; |
2127 | } |
2128 | |
2129 | fprintf(stdoutstdout, "Loaded %d certificates, %d CAs and %d CRLs\n\n", |
2130 | x509_ncerts, x509_ncas, x509_ncrls); |
2131 | |
2132 | ret = gnutls_x509_trust_list_add_cas(list, x509_ca_list, x509_ncas, 0); |
2133 | if (ret < 0) |
2134 | error (EXIT_FAILURE1, 0, "gnutls_x509_trust_add_cas: %s", |
2135 | gnutls_strerror (ret)); |
2136 | |
2137 | ret = gnutls_x509_trust_list_add_crls(list, x509_crl_list, x509_ncrls, 0, 0); |
2138 | if (ret < 0) |
2139 | error (EXIT_FAILURE1, 0, "gnutls_x509_trust_add_crls: %s", |
2140 | gnutls_strerror (ret)); |
2141 | |
2142 | gnutls_free(x509_crl_list); |
2143 | |
2144 | ret = gnutls_x509_trust_list_verify_crt (list, x509_cert_list, x509_ncerts, |
2145 | GNUTLS_VERIFY_DO_NOT_ALLOW_SAME|GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT, &output, |
2146 | detailed_verification); |
2147 | if (ret < 0) |
2148 | error (EXIT_FAILURE1, 0, "gnutls_x509_trusted_list_verify_crt: %s", |
2149 | gnutls_strerror (ret)); |
2150 | |
2151 | fprintf (outfile, "Chain verification output: "); |
2152 | print_verification_res(outfile, output); |
2153 | |
2154 | fprintf (outfile, ".\n\n"); |
2155 | |
2156 | gnutls_free(x509_cert_list); |
2157 | gnutls_x509_trust_list_deinit(list, 1); |
2158 | |
2159 | if (output != 0) |
2160 | exit(EXIT_FAILURE1); |
2161 | |
2162 | return 0; |
2163 | } |
2164 | |
2165 | static void |
2166 | print_verification_res (FILE* outfile, unsigned int output) |
2167 | { |
2168 | int comma = 0; |
2169 | |
2170 | if (output & GNUTLS_CERT_INVALID) |
2171 | { |
2172 | fprintf (outfile, "Not verified"); |
2173 | comma = 1; |
2174 | } |
2175 | else |
2176 | { |
2177 | fprintf (outfile, "Verified"); |
2178 | comma = 1; |
2179 | } |
2180 | |
2181 | if (output & GNUTLS_CERT_SIGNER_NOT_CA) |
2182 | { |
2183 | if (comma) |
2184 | fprintf (outfile, ", "); |
2185 | fprintf (outfile, "Issuer is not a CA"); |
2186 | comma = 1; |
2187 | } |
2188 | |
2189 | if (output & GNUTLS_CERT_INSECURE_ALGORITHM) |
2190 | { |
2191 | if (comma) |
2192 | fprintf (outfile, ", "); |
2193 | fprintf (outfile, "Insecure algorithm"); |
2194 | comma = 1; |
2195 | } |
2196 | |
2197 | if (output & GNUTLS_CERT_NOT_ACTIVATED) |
2198 | { |
2199 | if (comma) |
2200 | fprintf (outfile, ", "); |
2201 | fprintf (outfile, "Not activated"); |
2202 | comma = 1; |
2203 | } |
2204 | |
2205 | if (output & GNUTLS_CERT_EXPIRED) |
2206 | { |
2207 | if (comma) |
2208 | fprintf (outfile, ", "); |
2209 | fprintf (outfile, "Expired"); |
2210 | comma = 1; |
2211 | } |
2212 | |
2213 | if (output & GNUTLS_CERT_REVOKED) |
2214 | { |
2215 | if (comma) |
2216 | fprintf (outfile, ", "); |
2217 | fprintf (outfile, "Revoked"); |
2218 | comma = 1; |
| Value stored to 'comma' is never read |
2219 | } |
2220 | } |
2221 | |
2222 | static void |
2223 | verify_chain (void) |
2224 | { |
2225 | char *buf; |
2226 | size_t size; |
2227 | |
2228 | buf = fread_file_gnutls_fread_file (infile, &size); |
2229 | if (buf == NULL((void*)0)) |
2230 | error (EXIT_FAILURE1, errno(*__errno_location ()), "reading chain"); |
2231 | |
2232 | buf[size] = 0; |
2233 | |
2234 | _verify_x509_mem (buf, size, NULL((void*)0), 0); |
2235 | |
2236 | } |
2237 | |
2238 | static void |
2239 | verify_certificate (common_info_st * cinfo) |
2240 | { |
2241 | char *cert; |
2242 | char *cas; |
2243 | size_t cert_size, ca_size; |
2244 | FILE * ca_file = fopen(cinfo->ca, "r"); |
2245 | |
2246 | if (ca_file == NULL((void*)0)) |
2247 | error (EXIT_FAILURE1, errno(*__errno_location ()), "opening CA file"); |
2248 | |
2249 | cert = fread_file_gnutls_fread_file (infile, &cert_size); |
2250 | if (cert == NULL((void*)0)) |
2251 | error (EXIT_FAILURE1, errno(*__errno_location ()), "reading certificate chain"); |
2252 | |
2253 | cert[cert_size] = 0; |
2254 | |
2255 | cas = fread_file_gnutls_fread_file (ca_file, &ca_size); |
2256 | if (cas == NULL((void*)0)) |
2257 | error (EXIT_FAILURE1, errno(*__errno_location ()), "reading CA list"); |
2258 | |
2259 | cas[ca_size] = 0; |
2260 | fclose(ca_file); |
2261 | |
2262 | _verify_x509_mem (cert, cert_size, cas, ca_size); |
2263 | |
2264 | |
2265 | } |
2266 | |
2267 | void |
2268 | verify_crl (common_info_st * cinfo) |
2269 | { |
2270 | size_t size, dn_size; |
2271 | char dn[128]; |
2272 | unsigned int output; |
2273 | int comma = 0; |
2274 | int ret; |
2275 | gnutls_datum_t pem; |
2276 | gnutls_x509_crl_t crl; |
2277 | time_t now = time (0); |
2278 | gnutls_x509_crt_t issuer; |
2279 | |
2280 | issuer = load_ca_cert (cinfo); |
2281 | |
2282 | fprintf (outfile, "\nCA certificate:\n"); |
2283 | |
2284 | dn_size = sizeof (dn); |
2285 | ret = gnutls_x509_crt_get_dn (issuer, dn, &dn_size); |
2286 | if (ret < 0) |
2287 | error (EXIT_FAILURE1, 0, "crt_get_dn: %s", gnutls_strerror (ret)); |
2288 | |
2289 | fprintf (outfile, "\tSubject: %s\n\n", dn); |
2290 | |
2291 | ret = gnutls_x509_crl_init (&crl); |
2292 | if (ret < 0) |
2293 | error (EXIT_FAILURE1, 0, "crl_init: %s", gnutls_strerror (ret)); |
2294 | |
2295 | pem.data = fread_file_gnutls_fread_file (infile, &size); |
2296 | pem.size = size; |
2297 | |
2298 | ret = gnutls_x509_crl_import (crl, &pem, info.incert_format); |
2299 | free (pem.data); |
2300 | if (ret < 0) |
2301 | error (EXIT_FAILURE1, 0, "import error: %s", gnutls_strerror (ret)); |
2302 | |
2303 | print_crl_info (crl, outfile); |
2304 | |
2305 | fprintf (outfile, "Verification output: "); |
2306 | ret = gnutls_x509_crl_verify (crl, &issuer, 1, 0, &output); |
2307 | if (ret < 0) |
2308 | error (EXIT_FAILURE1, 0, "verification error: %s", gnutls_strerror (ret)); |
2309 | |
2310 | if (output & GNUTLS_CERT_INVALID) |
2311 | { |
2312 | fprintf (outfile, "Not verified"); |
2313 | comma = 1; |
2314 | } |
2315 | else |
2316 | { |
2317 | fprintf (outfile, "Verified"); |
2318 | comma = 1; |
2319 | } |
2320 | |
2321 | if (output & GNUTLS_CERT_SIGNER_NOT_CA) |
2322 | { |
2323 | if (comma) |
2324 | fprintf (outfile, ", "); |
2325 | fprintf (outfile, "Issuer is not a CA"); |
2326 | comma = 1; |
2327 | } |
2328 | |
2329 | if (output & GNUTLS_CERT_INSECURE_ALGORITHM) |
2330 | { |
2331 | if (comma) |
2332 | fprintf (outfile, ", "); |
2333 | fprintf (outfile, "Insecure algorithm"); |
2334 | comma = 1; |
2335 | } |
2336 | |
2337 | |
2338 | |
2339 | |
2340 | if (gnutls_x509_crl_get_this_update (crl) > now) |
2341 | { |
2342 | if (comma) |
2343 | fprintf (outfile, ", "); |
2344 | comma = 1; |
2345 | fprintf (outfile, "Issued in the future!"); |
2346 | } |
2347 | |
2348 | if (gnutls_x509_crl_get_next_update (crl) < now) |
2349 | { |
2350 | if (comma) |
2351 | fprintf (outfile, ", "); |
2352 | comma = 1; |
2353 | fprintf (outfile, "CRL is not up to date"); |
2354 | } |
2355 | |
2356 | fprintf (outfile, "\n"); |
2357 | } |
2358 | |
2359 | |
2360 | void |
2361 | generate_pkcs8 (common_info_st * cinfo) |
2362 | { |
2363 | gnutls_x509_privkey_t key; |
2364 | int result; |
2365 | size_t size; |
2366 | int flags = 0; |
2367 | const char *password; |
2368 | |
2369 | fprintf (stderrstderr, "Generating a PKCS #8 key structure...\n"); |
2370 | |
2371 | key = load_x509_private_key (1, cinfo); |
2372 | |
2373 | if (info.pass) |
2374 | password = info.pass; |
2375 | else |
2376 | password = get_pass (); |
2377 | |
2378 | if (info.export) |
2379 | flags = GNUTLS_PKCS_USE_PKCS12_RC2_40; |
2380 | else |
2381 | flags = cipher_to_flags (info.pkcs_cipher); |
2382 | |
2383 | if (password == NULL((void*)0) || password[0] == 0) |
2384 | { |
2385 | flags = GNUTLS_PKCS_PLAIN; |
2386 | } |
2387 | |
2388 | size = buffer_size; |
2389 | result = |
2390 | gnutls_x509_privkey_export_pkcs8 (key, info.outcert_format, |
2391 | password, flags, buffer, &size); |
2392 | |
2393 | if (result < 0) |
2394 | error (EXIT_FAILURE1, 0, "key_export: %s", gnutls_strerror (result)); |
2395 | |
2396 | fwrite (buffer, 1, size, outfile); |
2397 | |
2398 | } |
2399 | |
2400 | |
2401 | #include <gnutls/pkcs12.h> |
2402 | #include <unistd.h> |
2403 | |
2404 | void |
2405 | generate_pkcs12 (common_info_st * cinfo) |
2406 | { |
2407 | gnutls_pkcs12_t pkcs12; |
2408 | gnutls_x509_crt_t *crts; |
2409 | gnutls_x509_privkey_t key; |
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 | |
2421 | fprintf (stderrstderr, "Generating a PKCS #12 structure...\n"); |
2422 | |
2423 | key = load_x509_private_key (0, cinfo); |
2424 | crts = load_cert_list (0, &ncrts, cinfo); |
2425 | |
2426 | name = get_pkcs12_key_name (); |
2427 | |
2428 | result = gnutls_pkcs12_init (&pkcs12); |
2429 | if (result < 0) |
2430 | error (EXIT_FAILURE1, 0, "pkcs12_init: %s", gnutls_strerror (result)); |
2431 | |
2432 | if (info.pass) |
2433 | pass = info.pass; |
2434 | else |
2435 | pass = get_pass (); |
2436 | |
2437 | if (pass == NULL((void*)0)) |
2438 | { |
2439 | fprintf(stderrstderr, "No password given for PKCS #12. Assuming null password...\n"); |
2440 | pass = ""; |
2441 | } |
2442 | |
2443 | |
2444 | for (i = 0; i < ncrts; i++) |
2445 | { |
2446 | gnutls_pkcs12_bag_t bag; |
2447 | |
2448 | result = gnutls_pkcs12_bag_init (&bag); |
2449 | if (result < 0) |
2450 | error (EXIT_FAILURE1, 0, "bag_init: %s", gnutls_strerror (result)); |
2451 | |
2452 | result = gnutls_pkcs12_bag_set_crt (bag, crts[i]); |
2453 | if (result < 0) |
2454 | error (EXIT_FAILURE1, 0, "set_crt[%d]: %s", i, |
2455 | gnutls_strerror (result)); |
2456 | |
2457 | indx = result; |
2458 | |
2459 | result = gnutls_pkcs12_bag_set_friendly_name (bag, indx, name); |
2460 | if (result < 0) |
2461 | error (EXIT_FAILURE1, 0, "bag_set_friendly_name: %s", |
2462 | gnutls_strerror (result)); |
2463 | |
2464 | size = sizeof (_key_id); |
2465 | result = gnutls_x509_crt_get_key_id (crts[i], 0, _key_id, &size); |
2466 | if (result < 0) |
2467 | error (EXIT_FAILURE1, 0, "key_id[%d]: %s", i, |
2468 | gnutls_strerror (result)); |
2469 | |
2470 | key_id.data = _key_id; |
2471 | key_id.size = size; |
2472 | |
2473 | result = gnutls_pkcs12_bag_set_key_id (bag, indx, &key_id); |
2474 | if (result < 0) |
2475 | error (EXIT_FAILURE1, 0, "bag_set_key_id: %s", |
2476 | gnutls_strerror (result)); |
2477 | |
2478 | if (info.export) |
2479 | flags = GNUTLS_PKCS_USE_PKCS12_RC2_40; |
2480 | else |
2481 | flags = cipher_to_flags (info.pkcs_cipher); |
2482 | |
2483 | result = gnutls_pkcs12_bag_encrypt (bag, pass, flags); |
2484 | if (result < 0) |
2485 | error (EXIT_FAILURE1, 0, "bag_encrypt: %s", gnutls_strerror (result)); |
2486 | |
2487 | result = gnutls_pkcs12_set_bag (pkcs12, bag); |
2488 | if (result < 0) |
2489 | error (EXIT_FAILURE1, 0, "set_bag: %s", gnutls_strerror (result)); |
2490 | } |
2491 | |
2492 | if (key) |
2493 | { |
2494 | gnutls_pkcs12_bag_t kbag; |
2495 | |
2496 | result = gnutls_pkcs12_bag_init (&kbag); |
2497 | if (result < 0) |
2498 | error (EXIT_FAILURE1, 0, "bag_init: %s", gnutls_strerror (result)); |
2499 | |
2500 | if (info.export) |
2501 | flags = GNUTLS_PKCS_USE_PKCS12_RC2_40; |
2502 | else |
2503 | flags = cipher_to_flags (info.pkcs_cipher); |
2504 | |
2505 | size = buffer_size; |
2506 | result = |
2507 | gnutls_x509_privkey_export_pkcs8 (key, GNUTLS_X509_FMT_DER, |
2508 | pass, flags, buffer, &size); |
2509 | if (result < 0) |
2510 | error (EXIT_FAILURE1, 0, "key_export: %s", gnutls_strerror (result)); |
2511 | |
2512 | data.data = buffer; |
2513 | data.size = size; |
2514 | result = |
2515 | gnutls_pkcs12_bag_set_data (kbag, |
2516 | GNUTLS_BAG_PKCS8_ENCRYPTED_KEY, &data); |
2517 | if (result < 0) |
2518 | error (EXIT_FAILURE1, 0, "bag_set_data: %s", gnutls_strerror (result)); |
2519 | |
2520 | indx = result; |
2521 | |
2522 | result = gnutls_pkcs12_bag_set_friendly_name (kbag, indx, name); |
2523 | if (result < 0) |
2524 | error (EXIT_FAILURE1, 0, "bag_set_friendly_name: %s", |
2525 | gnutls_strerror (result)); |
2526 | |
2527 | size = sizeof (_key_id); |
2528 | result = gnutls_x509_privkey_get_key_id (key, 0, _key_id, &size); |
2529 | if (result < 0) |
2530 | error (EXIT_FAILURE1, 0, "key_id: %s", gnutls_strerror (result)); |
2531 | |
2532 | key_id.data = _key_id; |
2533 | key_id.size = size; |
2534 | |
2535 | result = gnutls_pkcs12_bag_set_key_id (kbag, indx, &key_id); |
2536 | if (result < 0) |
2537 | error (EXIT_FAILURE1, 0, "bag_set_key_id: %s", |
2538 | gnutls_strerror (result)); |
2539 | |
2540 | result = gnutls_pkcs12_set_bag (pkcs12, kbag); |
2541 | if (result < 0) |
2542 | error (EXIT_FAILURE1, 0, "set_bag: %s", gnutls_strerror (result)); |
2543 | } |
2544 | |
2545 | result = gnutls_pkcs12_generate_mac (pkcs12, pass); |
2546 | if (result < 0) |
2547 | error (EXIT_FAILURE1, 0, "generate_mac: %s", gnutls_strerror (result)); |
2548 | |
2549 | size = buffer_size; |
2550 | result = gnutls_pkcs12_export (pkcs12, info.outcert_format, buffer, &size); |
2551 | if (result < 0) |
2552 | error (EXIT_FAILURE1, 0, "pkcs12_export: %s", gnutls_strerror (result)); |
2553 | |
2554 | fwrite (buffer, 1, size, outfile); |
2555 | |
2556 | } |
2557 | |
2558 | static const char * |
2559 | BAGTYPE (gnutls_pkcs12_bag_type_t x) |
2560 | { |
2561 | switch (x) |
2562 | { |
2563 | case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY: |
2564 | return "PKCS #8 Encrypted key"; |
2565 | case GNUTLS_BAG_EMPTY: |
2566 | return "Empty"; |
2567 | case GNUTLS_BAG_PKCS8_KEY: |
2568 | return "PKCS #8 Key"; |
2569 | case GNUTLS_BAG_CERTIFICATE: |
2570 | return "Certificate"; |
2571 | case GNUTLS_BAG_ENCRYPTED: |
2572 | return "Encrypted"; |
2573 | case GNUTLS_BAG_CRL: |
2574 | return "CRL"; |
2575 | case GNUTLS_BAG_SECRET: |
2576 | return "Secret"; |
2577 | default: |
2578 | return "Unknown"; |
2579 | } |
2580 | } |
2581 | |
2582 | static void |
2583 | print_bag_data (gnutls_pkcs12_bag_t bag) |
2584 | { |
2585 | int result; |
2586 | int count, i, type; |
2587 | gnutls_datum_t cdata, id; |
2588 | const char *str, *name; |
2589 | gnutls_datum_t out; |
2590 | |
2591 | count = gnutls_pkcs12_bag_get_count (bag); |
2592 | if (count < 0) |
2593 | error (EXIT_FAILURE1, 0, "get_count: %s", gnutls_strerror (count)); |
2594 | |
2595 | fprintf (outfile, "\tElements: %d\n", count); |
2596 | |
2597 | for (i = 0; i < count; i++) |
2598 | { |
2599 | type = gnutls_pkcs12_bag_get_type (bag, i); |
2600 | if (type < 0) |
2601 | error (EXIT_FAILURE1, 0, "get_type: %s", gnutls_strerror (type)); |
2602 | |
2603 | fprintf (stderrstderr, "\tType: %s\n", BAGTYPE (type)); |
2604 | |
2605 | name = NULL((void*)0); |
2606 | result = gnutls_pkcs12_bag_get_friendly_name (bag, i, (char **) &name); |
2607 | if (result < 0) |
2608 | error (EXIT_FAILURE1, 0, "get_friendly_name: %s", |
2609 | gnutls_strerror (type)); |
2610 | if (name) |
2611 | fprintf (outfile, "\tFriendly name: %s\n", name); |
2612 | |
2613 | id.data = NULL((void*)0); |
2614 | id.size = 0; |
2615 | result = gnutls_pkcs12_bag_get_key_id (bag, i, &id); |
2616 | if (result < 0) |
2617 | error (EXIT_FAILURE1, 0, "get_key_id: %s", gnutls_strerror (type)); |
2618 | fprintf (outfile, "\tKey ID: %s\n", raw_to_string (id.data, id.size)); |
2619 | |
2620 | result = gnutls_pkcs12_bag_get_data (bag, i, &cdata); |
2621 | if (result < 0) |
2622 | error (EXIT_FAILURE1, 0, "get_data: %s", gnutls_strerror (result)); |
2623 | |
2624 | switch (type) |
2625 | { |
2626 | case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY: |
2627 | str = "ENCRYPTED PRIVATE KEY"; |
2628 | break; |
2629 | case GNUTLS_BAG_PKCS8_KEY: |
2630 | str = "PRIVATE KEY"; |
2631 | break; |
2632 | case GNUTLS_BAG_CERTIFICATE: |
2633 | str = "CERTIFICATE"; |
2634 | break; |
2635 | case GNUTLS_BAG_CRL: |
2636 | str = "CRL"; |
2637 | break; |
2638 | case GNUTLS_BAG_ENCRYPTED: |
2639 | case GNUTLS_BAG_EMPTY: |
2640 | default: |
2641 | str = NULL((void*)0); |
2642 | } |
2643 | |
2644 | if (str != NULL((void*)0)) |
2645 | { |
2646 | gnutls_pem_base64_encode_alloc (str, &cdata, &out); |
2647 | fprintf (outfile, "%s\n", out.data); |
2648 | |
2649 | gnutls_free (out.data); |
2650 | } |
2651 | |
2652 | } |
2653 | } |
2654 | |
2655 | void |
2656 | pkcs12_info (void) |
2657 | { |
2658 | gnutls_pkcs12_t pkcs12; |
2659 | gnutls_pkcs12_bag_t bag; |
2660 | int result; |
2661 | size_t size; |
2662 | gnutls_datum_t data; |
2663 | const char *pass; |
2664 | int indx; |
2665 | |
2666 | result = gnutls_pkcs12_init (&pkcs12); |
2667 | if (result < 0) |
2668 | error (EXIT_FAILURE1, 0, "p12_init: %s", gnutls_strerror (result)); |
2669 | |
2670 | data.data = fread_file_gnutls_fread_file (infile, &size); |
2671 | data.size = size; |
2672 | |
2673 | result = gnutls_pkcs12_import (pkcs12, &data, info.incert_format, 0); |
2674 | free (data.data); |
2675 | if (result < 0) |
2676 | error (EXIT_FAILURE1, 0, "p12_import: %s", gnutls_strerror (result)); |
2677 | |
2678 | if (info.pass) |
2679 | pass = info.pass; |
2680 | else |
2681 | pass = get_pass (); |
2682 | |
2683 | result = gnutls_pkcs12_verify_mac (pkcs12, pass); |
2684 | if (result < 0) |
2685 | error (0, 0, "verify_mac: %s", gnutls_strerror (result)); |
2686 | |
2687 | for (indx = 0;; indx++) |
2688 | { |
2689 | result = gnutls_pkcs12_bag_init (&bag); |
2690 | if (result < 0) |
2691 | error (EXIT_FAILURE1, 0, "bag_init: %s", gnutls_strerror (result)); |
2692 | |
2693 | result = gnutls_pkcs12_get_bag (pkcs12, indx, bag); |
2694 | if (result < 0) |
2695 | break; |
2696 | |
2697 | result = gnutls_pkcs12_bag_get_count (bag); |
2698 | if (result < 0) |
2699 | error (EXIT_FAILURE1, 0, "bag_count: %s", gnutls_strerror (result)); |
2700 | |
2701 | fprintf (outfile, "BAG #%d\n", indx); |
2702 | |
2703 | result = gnutls_pkcs12_bag_get_type (bag, 0); |
2704 | if (result < 0) |
2705 | error (EXIT_FAILURE1, 0, "bag_init: %s", gnutls_strerror (result)); |
2706 | |
2707 | if (result == GNUTLS_BAG_ENCRYPTED) |
2708 | { |
2709 | fprintf (stderrstderr, "\tType: %s\n", BAGTYPE (result)); |
2710 | fprintf (stderrstderr, "\n\tDecrypting...\n"); |
2711 | |
2712 | result = gnutls_pkcs12_bag_decrypt (bag, pass); |
2713 | |
2714 | if (result < 0) |
2715 | { |
2716 | error (0, 0, "bag_decrypt: %s", gnutls_strerror (result)); |
2717 | continue; |
2718 | } |
2719 | |
2720 | result = gnutls_pkcs12_bag_get_count (bag); |
2721 | if (result < 0) |
2722 | error (EXIT_FAILURE1, 0, "encrypted bag_count: %s", |
2723 | gnutls_strerror (result)); |
2724 | } |
2725 | |
2726 | print_bag_data (bag); |
2727 | |
2728 | gnutls_pkcs12_bag_deinit (bag); |
2729 | } |
2730 | } |
2731 | |
2732 | void |
2733 | pkcs7_info (void) |
2734 | { |
2735 | gnutls_pkcs7_t pkcs7; |
2736 | int result; |
2737 | size_t size; |
2738 | gnutls_datum_t data, b64; |
2739 | int indx, count; |
2740 | |
2741 | result = gnutls_pkcs7_init (&pkcs7); |
2742 | if (result < 0) |
2743 | error (EXIT_FAILURE1, 0, "p7_init: %s", gnutls_strerror (result)); |
2744 | |
2745 | data.data = fread_file_gnutls_fread_file (infile, &size); |
2746 | data.size = size; |
2747 | |
2748 | result = gnutls_pkcs7_import (pkcs7, &data, info.incert_format); |
2749 | free (data.data); |
2750 | if (result < 0) |
2751 | error (EXIT_FAILURE1, 0, "import error: %s", gnutls_strerror (result)); |
2752 | |
2753 | |
2754 | |
2755 | result = gnutls_pkcs7_get_crt_count (pkcs7); |
2756 | if (result < 0) |
2757 | error (EXIT_FAILURE1, 0, "p7_crt_count: %s", gnutls_strerror (result)); |
2758 | |
2759 | count = result; |
2760 | |
2761 | if (count > 0) |
2762 | fprintf (outfile, "Number of certificates: %u\n", count); |
2763 | |
2764 | for (indx = 0; indx < count; indx++) |
2765 | { |
2766 | fputs ("\n", outfile); |
2767 | |
2768 | size = buffer_size; |
2769 | result = gnutls_pkcs7_get_crt_raw (pkcs7, indx, buffer, &size); |
2770 | if (result < 0) |
2771 | break; |
2772 | |
2773 | data.data = buffer; |
2774 | data.size = size; |
2775 | |
2776 | result = gnutls_pem_base64_encode_alloc ("CERTIFICATE", &data, &b64); |
2777 | if (result < 0) |
2778 | error (EXIT_FAILURE1, 0, "encoding: %s", gnutls_strerror (result)); |
2779 | |
2780 | fputs (b64.data, outfile); |
2781 | gnutls_free (b64.data); |
2782 | } |
2783 | |
2784 | |
2785 | |
2786 | result = gnutls_pkcs7_get_crl_count (pkcs7); |
2787 | if (result < 0) |
2788 | error (EXIT_FAILURE1, 0, "p7_crl_count: %s", gnutls_strerror (result)); |
2789 | |
2790 | count = result; |
2791 | |
2792 | if (count > 0) |
2793 | fprintf (outfile, "\nNumber of CRLs: %u\n", count); |
2794 | |
2795 | for (indx = 0; indx < count; indx++) |
2796 | { |
2797 | fputs ("\n", outfile); |
2798 | |
2799 | size = buffer_size; |
2800 | result = gnutls_pkcs7_get_crl_raw (pkcs7, indx, buffer, &size); |
2801 | if (result < 0) |
2802 | break; |
2803 | |
2804 | data.data = buffer; |
2805 | data.size = size; |
2806 | |
2807 | result = gnutls_pem_base64_encode_alloc ("X509 CRL", &data, &b64); |
2808 | if (result < 0) |
2809 | error (EXIT_FAILURE1, 0, "encoding: %s", gnutls_strerror (result)); |
2810 | |
2811 | fputs (b64.data, outfile); |
2812 | gnutls_free (b64.data); |
2813 | } |
2814 | } |
2815 | |
2816 | void |
2817 | smime_to_pkcs7 (void) |
2818 | { |
2819 | size_t linesize = 0; |
2820 | char *lineptr = NULL((void*)0); |
2821 | ssize_t len; |
2822 | |
2823 | |
2824 | |
2825 | do |
2826 | { |
2827 | len = getline (&lineptr, &linesize, infile); |
2828 | if (len == -1) |
2829 | error (EXIT_FAILURE1, 0, "cannot find RFC 2822 header/body separator"); |
2830 | } |
2831 | while (strcmp (lineptr, "\r\n") != 0 && strcmp (lineptr, "\n") != 0); |
2832 | |
2833 | do |
2834 | { |
2835 | len = getline (&lineptr, &linesize, infile); |
2836 | if (len == -1) |
2837 | error (EXIT_FAILURE1, 0, "message has RFC 2822 header but no body"); |
2838 | } |
2839 | while (strcmp (lineptr, "\r\n") == 0 && strcmp (lineptr, "\n") == 0); |
2840 | |
2841 | fprintf (outfile, "%s", "-----BEGIN PKCS7-----\n"); |
2842 | |
2843 | do |
2844 | { |
2845 | while (len > 0 |
2846 | && (lineptr[len - 1] == '\r' || lineptr[len - 1] == '\n')) |
2847 | lineptr[--len] = '\0'; |
2848 | if (strcmp (lineptr, "") != 0) |
2849 | fprintf (outfile, "%s\n", lineptr); |
2850 | len = getline (&lineptr, &linesize, infile); |
2851 | } |
2852 | while (len != -1); |
2853 | |
2854 | fprintf (outfile, "%s", "-----END PKCS7-----\n"); |
2855 | |
2856 | free (lineptr); |
2857 | } |
2858 | |
2859 | void |
2860 | certtool_version (void) |
2861 | { |
2862 | const char *p = PACKAGE_NAME"GnuTLS"; |
2863 | if (strcmp (gnutls_check_version (NULL((void*)0)), PACKAGE_VERSION"3.0.12") != 0) |
2864 | p = PACKAGE_STRING"GnuTLS 3.0.12"; |
2865 | version_etc (stdoutstdout, program_name, p, gnutls_check_version (NULL((void*)0)), |
2866 | "Nikos Mavrogiannopoulos", "Simon Josefsson", (char *) NULL((void*)0)); |
2867 | } |
2868 | |
2869 | static void |
2870 | print_key_usage (FILE * outfile, unsigned int usage) |
2871 | { |
2872 | if (usage & GNUTLS_KEY_DIGITAL_SIGNATURE128) |
2873 | { |
2874 | fprintf (outfile, "\tDigital signature.\n"); |
2875 | } |
2876 | |
2877 | if (usage & GNUTLS_KEY_NON_REPUDIATION64) |
2878 | { |
2879 | fprintf (outfile, "\tNon repudiation.\n"); |
2880 | } |
2881 | |
2882 | if (usage & GNUTLS_KEY_KEY_ENCIPHERMENT32) |
2883 | { |
2884 | fprintf (outfile, "\tKey encipherment.\n"); |
2885 | } |
2886 | |
2887 | if (usage & GNUTLS_KEY_DATA_ENCIPHERMENT16) |
2888 | { |
2889 | fprintf (outfile, "\tData encipherment.\n"); |
2890 | } |
2891 | |
2892 | if (usage & GNUTLS_KEY_KEY_AGREEMENT8) |
2893 | { |
2894 | fprintf (outfile, "\tKey agreement.\n"); |
2895 | } |
2896 | |
2897 | if (usage & GNUTLS_KEY_KEY_CERT_SIGN4) |
2898 | { |
2899 | fprintf (outfile, "\tCertificate signing.\n"); |
2900 | } |
2901 | |
2902 | if (usage & GNUTLS_KEY_NON_REPUDIATION64) |
2903 | { |
2904 | fprintf (outfile, "\tCRL signing.\n"); |
2905 | } |
2906 | |
2907 | if (usage & GNUTLS_KEY_ENCIPHER_ONLY1) |
2908 | { |
2909 | fprintf (outfile, "\tKey encipher only.\n"); |
2910 | } |
2911 | |
2912 | if (usage & GNUTLS_KEY_DECIPHER_ONLY32768) |
2913 | { |
2914 | fprintf (outfile, "\tKey decipher only.\n"); |
2915 | } |
2916 | } |
2917 | |
2918 | void |
2919 | pubkey_info (gnutls_x509_crt_t crt, common_info_st * cinfo) |
2920 | { |
2921 | gnutls_pubkey_t pubkey; |
2922 | unsigned int bits, usage; |
2923 | int ret; |
2924 | size_t size; |
2925 | const char *cprint; |
2926 | |
2927 | ret = gnutls_pubkey_init (&pubkey); |
2928 | if (ret < 0) |
2929 | { |
2930 | error (EXIT_FAILURE1, 0, "pubkey_init: %s", gnutls_strerror (ret)); |
2931 | } |
2932 | |
2933 | if (crt == NULL((void*)0)) |
2934 | { |
2935 | crt = load_cert (0, cinfo); |
2936 | } |
2937 | |
2938 | if (crt != NULL((void*)0)) |
2939 | { |
2940 | ret = gnutls_pubkey_import_x509 (pubkey, crt, 0); |
2941 | if (ret < 0) |
2942 | { |
2943 | error (EXIT_FAILURE1, 0, "pubkey_import_x509: %s", |
2944 | gnutls_strerror (ret)); |
2945 | } |
2946 | } |
2947 | else |
2948 | { |
2949 | pubkey = load_pubkey (1, cinfo); |
2950 | } |
2951 | |
2952 | if (info.outcert_format == GNUTLS_X509_FMT_DER) |
2953 | { |
2954 | size = buffer_size; |
2955 | ret = gnutls_pubkey_export (pubkey, info.outcert_format, buffer, &size); |
2956 | if (ret < 0) |
2957 | error (EXIT_FAILURE1, 0, "export error: %s", gnutls_strerror (ret)); |
2958 | |
2959 | fwrite (buffer, 1, size, outfile); |
2960 | |
2961 | gnutls_pubkey_deinit (pubkey); |
2962 | |
2963 | return; |
2964 | } |
2965 | |
2966 | |
2967 | |
2968 | fprintf (outfile, "Public Key Info:\n\n"); |
2969 | ret = gnutls_pubkey_get_pk_algorithm (pubkey, &bits); |
2970 | fprintf (outfile, "Public Key Algorithm: "); |
2971 | |
2972 | cprint = gnutls_pk_algorithm_get_name (ret); |
2973 | fprintf (outfile, "%s (%u bits)\n", cprint ? cprint : "Unknown", bits); |
2974 | |
2975 | |
2976 | |
2977 | |
2978 | if (ret == GNUTLS_PK_RSA) |
2979 | { |
2980 | gnutls_datum_t m, e; |
2981 | |
2982 | ret = gnutls_pubkey_get_pk_rsa_raw (pubkey, &m, &e); |
2983 | if (ret < 0) |
2984 | fprintf (stderrstderr, "Error in key RSA data export: %s\n", |
2985 | gnutls_strerror (ret)); |
2986 | else |
2987 | { |
2988 | print_rsa_pkey (&m, &e, NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0)); |
2989 | gnutls_free (m.data); |
2990 | gnutls_free (e.data); |
2991 | } |
2992 | } |
2993 | else if (ret == GNUTLS_PK_DSA) |
2994 | { |
2995 | gnutls_datum_t p, q, g, y; |
2996 | |
2997 | ret = gnutls_pubkey_get_pk_dsa_raw (pubkey, &p, &q, &g, &y); |
2998 | if (ret < 0) |
2999 | fprintf (stderrstderr, "Error in key DSA data export: %s\n", |
3000 | gnutls_strerror (ret)); |
3001 | else |
3002 | { |
3003 | print_dsa_pkey (NULL((void*)0), &y, &p, &q, &g); |
3004 | gnutls_free (y.data); |
3005 | gnutls_free (p.data); |
3006 | gnutls_free (q.data); |
3007 | gnutls_free (g.data); |
3008 | } |
3009 | } |
3010 | else if (ret == GNUTLS_PK_EC) |
3011 | { |
3012 | gnutls_datum_t x, y; |
3013 | gnutls_ecc_curve_t curve; |
3014 | |
3015 | ret = gnutls_pubkey_get_pk_ecc_raw (pubkey, &curve, &x, &y); |
3016 | if (ret < 0) |
3017 | fprintf (stderrstderr, "Error in key ECC data export: %s\n", |
3018 | gnutls_strerror (ret)); |
3019 | else |
3020 | { |
3021 | print_ecc_pkey (curve, NULL((void*)0), &y, &x); |
3022 | gnutls_free (y.data); |
3023 | gnutls_free (x.data); |
3024 | } |
3025 | } |
3026 | |
3027 | ret = gnutls_pubkey_get_key_usage (pubkey, &usage); |
3028 | if (ret < 0) |
3029 | { |
3030 | error (EXIT_FAILURE1, 0, "pubkey_get_key_usage: %s", |
3031 | gnutls_strerror (ret)); |
3032 | } |
3033 | |
3034 | fprintf (outfile, "Public Key Usage:\n"); |
3035 | print_key_usage (outfile, usage); |
3036 | |
3037 | fprintf (outfile, "\n"); |
3038 | |
3039 | size = buffer_size; |
3040 | if ((ret = gnutls_pubkey_get_key_id (pubkey, 0, buffer, &size)) < 0) |
3041 | { |
3042 | fprintf (stderrstderr, "Error in key id calculation: %s\n", |
3043 | gnutls_strerror (ret)); |
3044 | } |
3045 | else |
3046 | { |
3047 | fprintf (outfile, "Public Key ID: %s\n", raw_to_string (buffer, size)); |
3048 | } |
3049 | |
3050 | size = buffer_size; |
3051 | ret = gnutls_pubkey_export (pubkey, GNUTLS_X509_FMT_PEM, buffer, &size); |
3052 | if (ret < 0) |
3053 | error (EXIT_FAILURE1, 0, "export error: %s", gnutls_strerror (ret)); |
3054 | |
3055 | fprintf (outfile, "\n%s\n", buffer); |
3056 | |
3057 | gnutls_pubkey_deinit (pubkey); |
3058 | } |