1 /* export.c - Export certificates and private keys.
2 * Copyright (C) 2002, 2003, 2004, 2007, 2009 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
6 * GnuPG is free software; you can redistribute it and/or modify
7 * it 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 * GnuPG is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU 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 <http://www.gnu.org/licenses/>.
39 /* A table to store a fingerprint as used in a duplicates table. We
40 don't need to hash here because a fingerprint is already a perfect
41 hash value. This we use the most significant bits to index the
42 table and then use a linked list for the overflow. Possible
43 enhancement for very large number of certificates: Add a second
44 level table and then resort to a linked list. */
47 struct duptable_s
*next
;
49 /* Note that we only need to store 19 bytes because the first byte
50 is implictly given by the table index (we require at least 8
52 unsigned char fpr
[19];
54 typedef struct duptable_s
*duptable_t
;
55 #define DUPTABLE_BITS 12
56 #define DUPTABLE_SIZE (1 << DUPTABLE_BITS)
59 static void print_short_info (ksba_cert_t cert
, FILE *fp
, estream_t stream
);
60 static gpg_error_t
export_p12 (ctrl_t ctrl
,
61 const unsigned char *certimg
, size_t certimglen
,
62 const char *prompt
, const char *keygrip
,
66 /* Create a table used to indetify duplicated certificates. */
68 create_duptable (void)
70 return xtrycalloc (DUPTABLE_SIZE
, sizeof (duptable_t
));
74 destroy_duptable (duptable_t
*table
)
81 for (idx
=0; idx
< DUPTABLE_SIZE
; idx
++)
82 for (t
= table
[idx
]; t
; t
= t2
)
91 /* Insert the 20 byte fingerprint FPR into TABLE. Sets EXITS to true
92 if the fingerprint already exists in the table. */
94 insert_duptable (duptable_t
*table
, unsigned char *fpr
, int *exists
)
101 #if DUPTABLE_BITS > 16 || DUPTABLE_BITS < 8
102 #error cannot handle a table larger than 16 bits or smaller than 8 bits
103 #elif DUPTABLE_BITS > 8
104 idx
<<= (DUPTABLE_BITS
- 8);
105 idx
|= (fpr
[1] & ~(~0 << 4));
108 for (t
= table
[idx
]; t
; t
= t
->next
)
109 if (!memcmp (t
->fpr
, fpr
+1, 19))
116 /* Insert that fingerprint. */
117 t
= xtrymalloc (sizeof *t
);
119 return gpg_error_from_syserror ();
120 memcpy (t
->fpr
, fpr
+1, 19);
121 t
->next
= table
[idx
];
129 /* Export all certificates or just those given in NAMES. If STREAM is
130 not NULL the output is send to this extended stream. */
132 gpgsm_export (ctrl_t ctrl
, strlist_t names
, FILE *fp
, estream_t stream
)
134 KEYDB_HANDLE hd
= NULL
;
135 KEYDB_SEARCH_DESC
*desc
= NULL
;
137 Base64Context b64writer
= NULL
;
138 ksba_writer_t writer
;
140 ksba_cert_t cert
= NULL
;
147 dtable
= create_duptable ();
150 log_error ("creating duplicates table failed: %s\n", strerror (errno
));
157 log_error ("keydb_new failed\n");
165 for (sl
=names
, ndesc
=0; sl
; sl
= sl
->next
, ndesc
++)
169 desc
= xtrycalloc (ndesc
, sizeof *desc
);
172 log_error ("allocating memory for export failed: %s\n",
173 gpg_strerror (out_of_core ()));
178 desc
[0].mode
= KEYDB_SEARCH_MODE_FIRST
;
181 for (ndesc
=0, sl
=names
; sl
; sl
= sl
->next
)
183 rc
= keydb_classify_name (sl
->d
, desc
+ndesc
);
186 log_error ("key `%s' not found: %s\n",
187 sl
->d
, gpg_strerror (rc
));
195 /* If all specifications are done by fingerprint or keygrip, we
196 switch to ephemeral mode so that _all_ currently available and
197 matching certificates are exported. */
201 && (desc
[i
].mode
== KEYDB_SEARCH_MODE_FPR
202 || desc
[i
].mode
== KEYDB_SEARCH_MODE_FPR20
203 || desc
[i
].mode
== KEYDB_SEARCH_MODE_FPR16
204 || desc
[i
].mode
== KEYDB_SEARCH_MODE_KEYGRIP
)); i
++)
207 keydb_set_ephemeral (hd
, 1);
210 while (!(rc
= keydb_search (hd
, desc
, ndesc
)))
212 unsigned char fpr
[20];
216 desc
[0].mode
= KEYDB_SEARCH_MODE_NEXT
;
218 rc
= keydb_get_cert (hd
, &cert
);
221 log_error ("keydb_get_cert failed: %s\n", gpg_strerror (rc
));
225 gpgsm_get_fingerprint (cert
, 0, fpr
, NULL
);
226 rc
= insert_duptable (dtable
, fpr
, &exists
);
229 log_error ("inserting into duplicates table failed: %s\n",
234 if (!exists
&& count
&& !ctrl
->create_pem
)
236 log_info ("exporting more than one certificate "
237 "is not possible in binary mode\n");
238 log_info ("ignoring other certificates\n");
244 const unsigned char *image
;
247 image
= ksba_cert_get_image (cert
, &imagelen
);
250 log_error ("ksba_cert_get_image failed\n");
255 if (ctrl
->create_pem
)
260 es_putc ('\n', stream
);
264 print_short_info (cert
, fp
, stream
);
266 es_putc ('\n', stream
);
274 ctrl
->pem_name
= "CERTIFICATE";
275 rc
= gpgsm_create_writer (&b64writer
, ctrl
, fp
, stream
, &writer
);
278 log_error ("can't create writer: %s\n", gpg_strerror (rc
));
283 rc
= ksba_writer_write (writer
, image
, imagelen
);
286 log_error ("write error: %s\n", gpg_strerror (rc
));
290 if (ctrl
->create_pem
)
292 /* We want one certificate per PEM block */
293 rc
= gpgsm_finish_writer (b64writer
);
296 log_error ("write failed: %s\n", gpg_strerror (rc
));
299 gpgsm_destroy_writer (b64writer
);
304 ksba_cert_release (cert
);
308 log_error ("keydb_search failed: %s\n", gpg_strerror (rc
));
311 rc
= gpgsm_finish_writer (b64writer
);
314 log_error ("write failed: %s\n", gpg_strerror (rc
));
320 gpgsm_destroy_writer (b64writer
);
321 ksba_cert_release (cert
);
324 destroy_duptable (dtable
);
328 /* Export a certificates and its private key. */
330 gpgsm_p12_export (ctrl_t ctrl
, const char *name
, FILE *fp
)
333 KEYDB_SEARCH_DESC
*desc
= NULL
;
334 Base64Context b64writer
= NULL
;
335 ksba_writer_t writer
;
336 ksba_cert_t cert
= NULL
;
338 const unsigned char *image
;
340 char *keygrip
= NULL
;
350 log_error ("keydb_new failed\n");
354 desc
= xtrycalloc (1, sizeof *desc
);
357 log_error ("allocating memory for export failed: %s\n",
358 gpg_strerror (out_of_core ()));
362 rc
= keydb_classify_name (name
, desc
);
365 log_error ("key `%s' not found: %s\n",
366 name
, gpg_strerror (rc
));
370 /* Lookup the certificate and make sure that it is unique. */
371 rc
= keydb_search (hd
, desc
, 1);
374 rc
= keydb_get_cert (hd
, &cert
);
377 log_error ("keydb_get_cert failed: %s\n", gpg_strerror (rc
));
382 rc
= keydb_search (hd
, desc
, 1);
385 ksba_cert_t cert2
= NULL
;
387 if (!keydb_get_cert (hd
, &cert2
))
389 if (gpgsm_certs_identical_p (cert
, cert2
))
391 ksba_cert_release (cert2
);
394 ksba_cert_release (cert2
);
396 rc
= gpg_error (GPG_ERR_AMBIGUOUS_NAME
);
398 else if (rc
== -1 || gpg_err_code (rc
) == GPG_ERR_EOF
)
402 log_error ("key `%s' not found: %s\n",
403 name
, gpg_strerror (rc
));
408 keygrip
= gpgsm_get_keygrip_hexstring (cert
);
409 if (!keygrip
|| gpgsm_agent_havekey (ctrl
, keygrip
))
411 /* Note, that the !keygrip case indicates a bad certificate. */
412 rc
= gpg_error (GPG_ERR_NO_SECKEY
);
413 log_error ("can't export key `%s': %s\n", name
, gpg_strerror (rc
));
417 image
= ksba_cert_get_image (cert
, &imagelen
);
420 log_error ("ksba_cert_get_image failed\n");
424 if (ctrl
->create_pem
)
426 print_short_info (cert
, fp
, NULL
);
430 if (opt
.p12_charset
&& ctrl
->create_pem
)
432 fprintf (fp
, "The passphrase is %s encoded.\n\n",
436 ctrl
->pem_name
= "PKCS12";
437 rc
= gpgsm_create_writer (&b64writer
, ctrl
, fp
, NULL
, &writer
);
440 log_error ("can't create writer: %s\n", gpg_strerror (rc
));
445 prompt
= gpgsm_format_keydesc (cert
);
446 rc
= export_p12 (ctrl
, image
, imagelen
, prompt
, keygrip
, &datafp
);
451 while ( (nread
= fread (buffer
, 1, sizeof buffer
, datafp
)) > 0 )
452 if ((rc
= ksba_writer_write (writer
, buffer
, nread
)))
454 log_error ("write failed: %s\n", gpg_strerror (rc
));
459 rc
= gpg_error_from_errno (rc
);
460 log_error ("error reading temporary file: %s\n", gpg_strerror (rc
));
464 if (ctrl
->create_pem
)
466 /* We want one certificate per PEM block */
467 rc
= gpgsm_finish_writer (b64writer
);
470 log_error ("write failed: %s\n", gpg_strerror (rc
));
473 gpgsm_destroy_writer (b64writer
);
477 ksba_cert_release (cert
);
483 gpgsm_destroy_writer (b64writer
);
484 ksba_cert_release (cert
);
490 /* Call either es_putc or the plain putc. */
492 do_putc (int value
, FILE *fp
, estream_t stream
)
495 es_putc (value
, stream
);
500 /* Call either es_fputs or the plain fputs. */
502 do_fputs (const char *string
, FILE *fp
, estream_t stream
)
505 es_fputs (string
, stream
);
511 /* Print some info about the certifciate CERT to FP or STREAM */
513 print_short_info (ksba_cert_t cert
, FILE *fp
, estream_t stream
)
519 for (idx
=0; (p
= ksba_cert_get_issuer (cert
, idx
)); idx
++)
523 : "\n aka ...: "), fp
, stream
);
525 gpgsm_es_print_name (stream
, p
);
527 gpgsm_print_name (fp
, p
);
530 do_putc ('\n', fp
, stream
);
532 do_fputs ("Serial ...: ", fp
, stream
);
533 sexp
= ksba_cert_get_serial (cert
);
537 const unsigned char *s
= sexp
;
542 for (len
=0; *s
&& *s
!= ':' && digitp (s
); s
++)
543 len
= len
*10 + atoi_1 (s
);
547 es_write_hexstring (stream
, s
+1, len
, 0, NULL
);
549 print_hexstring (fp
, s
+1, len
, 0);
554 do_putc ('\n', fp
, stream
);
556 for (idx
=0; (p
= ksba_cert_get_subject (cert
, idx
)); idx
++)
560 : "\n aka ..: "), fp
, stream
);
562 gpgsm_es_print_name (stream
, p
);
564 gpgsm_print_name (fp
, p
);
567 do_putc ('\n', fp
, stream
);
572 popen_protect_tool (ctrl_t ctrl
, const char *pgmname
,
573 FILE *infile
, FILE *outfile
, FILE **statusfile
,
574 const char *prompt
, const char *keygrip
,
577 const char *argv
[22];
580 /* Make sure that the agent is running so that the protect tool is
581 able to ask for a passphrase. This has only an effect under W32
582 where the agent is started on demand; sending a NOP does not harm
583 on other platforms. This is not really necessary anymore because
584 the protect tool does this now by itself; it does not harm either.*/
585 gpgsm_agent_send_nop (ctrl
);
587 argv
[i
++] = "--homedir";
588 argv
[i
++] = opt
.homedir
;
589 argv
[i
++] = "--p12-export";
590 argv
[i
++] = "--have-cert";
591 argv
[i
++] = "--prompt";
592 argv
[i
++] = prompt
?prompt
:"";
593 argv
[i
++] = "--enable-status-msg";
596 argv
[i
++] = "--p12-charset";
597 argv
[i
++] = opt
.p12_charset
;
599 if (opt
.agent_program
)
601 argv
[i
++] = "--agent-program";
602 argv
[i
++] = opt
.agent_program
;
607 assert (i
< sizeof argv
);
609 return gnupg_spawn_process (pgmname
, argv
, infile
, outfile
,
610 setup_pinentry_env
, (128|64),
616 export_p12 (ctrl_t ctrl
, const unsigned char *certimg
, size_t certimglen
,
617 const char *prompt
, const char *keygrip
,
621 gpg_error_t err
= 0, child_err
= 0;
624 FILE *infp
= NULL
, *outfp
= NULL
, *fp
= NULL
;
629 if (!opt
.protect_tool_program
|| !*opt
.protect_tool_program
)
630 pgmname
= gnupg_module_name (GNUPG_MODULE_NAME_PROTECT_TOOL
);
632 pgmname
= opt
.protect_tool_program
;
634 infp
= gnupg_tmpfile ();
637 err
= gpg_error_from_syserror ();
638 log_error (_("error creating temporary file: %s\n"), strerror (errno
));
642 if (fwrite (certimg
, certimglen
, 1, infp
) != 1)
644 err
= gpg_error_from_syserror ();
645 log_error (_("error writing to temporary file: %s\n"),
650 outfp
= gnupg_tmpfile ();
653 err
= gpg_error_from_syserror ();
654 log_error (_("error creating temporary file: %s\n"), strerror (errno
));
658 err
= popen_protect_tool (ctrl
,
659 pgmname
, infp
, outfp
, &fp
, prompt
, keygrip
, &pid
);
668 /* Read stderr of the protect tool. */
671 while ((c
=getc (fp
)) != EOF
)
673 /* fixme: We could here grep for status information of the
674 protect tool to figure out better error codes for
677 if (pos
>= sizeof buffer
- 5 || c
== '\n')
679 buffer
[pos
- (c
== '\n')] = 0;
681 log_printf ("%s", buffer
);
684 if (!strncmp (buffer
, "gpg-protect-tool: [PROTECT-TOOL:] ",34))
689 pend
= strchr (p
, ' ');
692 if ( !strcmp (p
, "bad-passphrase"))
696 log_info ("%s", buffer
);
699 cont_line
= (c
!= '\n');
707 log_printf ("%s\n", buffer
);
709 log_info ("%s\n", buffer
);
714 /* If we found no error in the output of the child, setup a suitable
715 error code, which will later be reset if the exit status of the
718 child_err
= gpg_error (GPG_ERR_DECRYPT_FAILED
);
727 if (!gnupg_wait_process (pgmname
, pid
, NULL
))
741 /* During export this is the passphrase used to unprotect the
742 key and not the pkcs#12 thing as in export. Therefore we can
743 issue the regular passphrase status. FIXME: replace the all
744 zero keyid by a regular one. */
745 gpgsm_status (ctrl
, STATUS_BAD_PASSPHRASE
, "0000000000000000");