2 * Copyright (C) 2002, 2003, 2004 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/>.
38 /* A table to store a fingerprint as used in a duplicates table. We
39 don't need to hash here because a fingerprint is alrady a perfect
40 hash value. This we use the most significant bits to index the
41 table and then use a linked list for the overflow. Possible
42 enhancement for very large number of certictates: Add a second
43 level table and then resort to a linked list. */
46 struct duptable_s
*next
;
48 /* Note that we only need to store 19 bytes because the first byte
49 is implictly given by the table index (we require at least 8
51 unsigned char fpr
[19];
53 typedef struct duptable_s
*duptable_t
;
54 #define DUPTABLE_BITS 12
55 #define DUPTABLE_SIZE (1 << DUPTABLE_BITS)
58 static void print_short_info (ksba_cert_t cert
, FILE *fp
, estream_t stream
);
59 static gpg_error_t
export_p12 (ctrl_t ctrl
,
60 const unsigned char *certimg
, size_t certimglen
,
61 const char *prompt
, const char *keygrip
,
65 /* Create a table used to indetify duplicated certificates. */
67 create_duptable (void)
69 return xtrycalloc (DUPTABLE_SIZE
, sizeof (duptable_t
));
73 destroy_duptable (duptable_t
*table
)
80 for (idx
=0; idx
< DUPTABLE_SIZE
; idx
++)
81 for (t
= table
[idx
]; t
; t
= t2
)
90 /* Insert the 20 byte fingerprint FPR into TABLE. Sets EXITS to true
91 if the fingerprint already exists in the table. */
93 insert_duptable (duptable_t
*table
, unsigned char *fpr
, int *exists
)
100 #if DUPTABLE_BITS > 16 || DUPTABLE_BITS < 8
101 #error cannot handle a table larger than 16 bits or smaller than 8 bits
102 #elif DUPTABLE_BITS > 8
103 idx
<<= (DUPTABLE_BITS
- 8);
104 idx
|= (fpr
[1] & ~(~0 << 4));
107 for (t
= table
[idx
]; t
; t
= t
->next
)
108 if (!memcmp (t
->fpr
, fpr
+1, 19))
115 /* Insert that fingerprint. */
116 t
= xtrymalloc (sizeof *t
);
118 return gpg_error_from_syserror ();
119 memcpy (t
->fpr
, fpr
+1, 19);
120 t
->next
= table
[idx
];
128 /* Export all certificates or just those given in NAMES. If STREAM is
129 not NULL the output is send to this extended stream. */
131 gpgsm_export (ctrl_t ctrl
, strlist_t names
, FILE *fp
, estream_t stream
)
133 KEYDB_HANDLE hd
= NULL
;
134 KEYDB_SEARCH_DESC
*desc
= NULL
;
136 Base64Context b64writer
= NULL
;
137 ksba_writer_t writer
;
139 ksba_cert_t cert
= NULL
;
146 dtable
= create_duptable ();
149 log_error ("creating duplicates table failed: %s\n", strerror (errno
));
156 log_error ("keydb_new failed\n");
164 for (sl
=names
, ndesc
=0; sl
; sl
= sl
->next
, ndesc
++)
168 desc
= xtrycalloc (ndesc
, sizeof *desc
);
171 log_error ("allocating memory for export failed: %s\n",
172 gpg_strerror (out_of_core ()));
177 desc
[0].mode
= KEYDB_SEARCH_MODE_FIRST
;
180 for (ndesc
=0, sl
=names
; sl
; sl
= sl
->next
)
182 rc
= keydb_classify_name (sl
->d
, desc
+ndesc
);
185 log_error ("key `%s' not found: %s\n",
186 sl
->d
, gpg_strerror (rc
));
194 /* If all specifications are done by fingerprint, we switch to
195 ephemeral mode so that _all_ currently available and matching
196 certificates are exported.
198 fixme: we should in this case keep a list of certificates to
199 avoid accidential export of duplicate certificates. */
203 && (desc
[i
].mode
== KEYDB_SEARCH_MODE_FPR
204 || desc
[i
].mode
== KEYDB_SEARCH_MODE_FPR20
205 || desc
[i
].mode
== KEYDB_SEARCH_MODE_FPR16
)); i
++)
208 keydb_set_ephemeral (hd
, 1);
211 while (!(rc
= keydb_search (hd
, desc
, ndesc
)))
213 unsigned char fpr
[20];
217 desc
[0].mode
= KEYDB_SEARCH_MODE_NEXT
;
219 rc
= keydb_get_cert (hd
, &cert
);
222 log_error ("keydb_get_cert failed: %s\n", gpg_strerror (rc
));
226 gpgsm_get_fingerprint (cert
, 0, fpr
, NULL
);
227 rc
= insert_duptable (dtable
, fpr
, &exists
);
230 log_error ("inserting into duplicates table fauiled: %s\n",
235 if (!exists
&& count
&& !ctrl
->create_pem
)
237 log_info ("exporting more than one certificate "
238 "is not possible in binary mode\n");
239 log_info ("ignoring other certificates\n");
245 const unsigned char *image
;
248 image
= ksba_cert_get_image (cert
, &imagelen
);
251 log_error ("ksba_cert_get_image failed\n");
256 if (ctrl
->create_pem
)
261 es_putc ('\n', stream
);
265 print_short_info (cert
, fp
, stream
);
267 es_putc ('\n', stream
);
275 ctrl
->pem_name
= "CERTIFICATE";
276 rc
= gpgsm_create_writer (&b64writer
, ctrl
, fp
, stream
, &writer
);
279 log_error ("can't create writer: %s\n", gpg_strerror (rc
));
284 rc
= ksba_writer_write (writer
, image
, imagelen
);
287 log_error ("write error: %s\n", gpg_strerror (rc
));
291 if (ctrl
->create_pem
)
293 /* We want one certificate per PEM block */
294 rc
= gpgsm_finish_writer (b64writer
);
297 log_error ("write failed: %s\n", gpg_strerror (rc
));
300 gpgsm_destroy_writer (b64writer
);
305 ksba_cert_release (cert
);
309 log_error ("keydb_search failed: %s\n", gpg_strerror (rc
));
312 rc
= gpgsm_finish_writer (b64writer
);
315 log_error ("write failed: %s\n", gpg_strerror (rc
));
321 gpgsm_destroy_writer (b64writer
);
322 ksba_cert_release (cert
);
325 destroy_duptable (dtable
);
329 /* Export a certificates and its private key. */
331 gpgsm_p12_export (ctrl_t ctrl
, const char *name
, FILE *fp
)
334 KEYDB_SEARCH_DESC
*desc
= NULL
;
335 Base64Context b64writer
= NULL
;
336 ksba_writer_t writer
;
337 ksba_cert_t cert
= NULL
;
339 const unsigned char *image
;
341 char *keygrip
= NULL
;
351 log_error ("keydb_new failed\n");
355 desc
= xtrycalloc (1, sizeof *desc
);
358 log_error ("allocating memory for export failed: %s\n",
359 gpg_strerror (out_of_core ()));
363 rc
= keydb_classify_name (name
, desc
);
366 log_error ("key `%s' not found: %s\n",
367 name
, gpg_strerror (rc
));
371 /* Lookup the certificate an make sure that it is unique. */
372 rc
= keydb_search (hd
, desc
, 1);
375 rc
= keydb_get_cert (hd
, &cert
);
378 log_error ("keydb_get_cert failed: %s\n", gpg_strerror (rc
));
382 rc
= keydb_search (hd
, desc
, 1);
384 rc
= gpg_error (GPG_ERR_AMBIGUOUS_NAME
);
385 else if (rc
== -1 || gpg_err_code (rc
) == GPG_ERR_EOF
)
389 log_error ("key `%s' not found: %s\n",
390 name
, gpg_strerror (rc
));
395 keygrip
= gpgsm_get_keygrip_hexstring (cert
);
396 if (!keygrip
|| gpgsm_agent_havekey (ctrl
, keygrip
))
398 /* Note, that the !keygrip case indicates a bad certificate. */
399 rc
= gpg_error (GPG_ERR_NO_SECKEY
);
400 log_error ("can't export key `%s': %s\n", name
, gpg_strerror (rc
));
404 image
= ksba_cert_get_image (cert
, &imagelen
);
407 log_error ("ksba_cert_get_image failed\n");
411 if (ctrl
->create_pem
)
413 print_short_info (cert
, fp
, NULL
);
417 if (opt
.p12_charset
&& ctrl
->create_pem
)
419 fprintf (fp
, "The passphrase is %s encoded.\n\n",
423 ctrl
->pem_name
= "PKCS12";
424 rc
= gpgsm_create_writer (&b64writer
, ctrl
, fp
, NULL
, &writer
);
427 log_error ("can't create writer: %s\n", gpg_strerror (rc
));
432 prompt
= gpgsm_format_keydesc (cert
);
433 rc
= export_p12 (ctrl
, image
, imagelen
, prompt
, keygrip
, &datafp
);
438 while ( (nread
= fread (buffer
, 1, sizeof buffer
, datafp
)) > 0 )
439 if ((rc
= ksba_writer_write (writer
, buffer
, nread
)))
441 log_error ("write failed: %s\n", gpg_strerror (rc
));
446 rc
= gpg_error_from_errno (rc
);
447 log_error ("error reading temporary file: %s\n", gpg_strerror (rc
));
451 if (ctrl
->create_pem
)
453 /* We want one certificate per PEM block */
454 rc
= gpgsm_finish_writer (b64writer
);
457 log_error ("write failed: %s\n", gpg_strerror (rc
));
460 gpgsm_destroy_writer (b64writer
);
464 ksba_cert_release (cert
);
470 gpgsm_destroy_writer (b64writer
);
471 ksba_cert_release (cert
);
477 /* Call either es_putc or the plain putc. */
479 do_putc (int value
, FILE *fp
, estream_t stream
)
482 es_putc (value
, stream
);
487 /* Call either es_fputs or the plain fputs. */
489 do_fputs (const char *string
, FILE *fp
, estream_t stream
)
492 es_fputs (string
, stream
);
498 /* Print some info about the certifciate CERT to FP or STREAM */
500 print_short_info (ksba_cert_t cert
, FILE *fp
, estream_t stream
)
506 for (idx
=0; (p
= ksba_cert_get_issuer (cert
, idx
)); idx
++)
510 : "\n aka ...: "), fp
, stream
);
512 gpgsm_es_print_name (stream
, p
);
514 gpgsm_print_name (fp
, p
);
517 do_putc ('\n', fp
, stream
);
519 do_fputs ("Serial ...: ", fp
, stream
);
520 sexp
= ksba_cert_get_serial (cert
);
524 const unsigned char *s
= sexp
;
529 for (len
=0; *s
&& *s
!= ':' && digitp (s
); s
++)
530 len
= len
*10 + atoi_1 (s
);
534 es_write_hexstring (stream
, s
+1, len
, 0, NULL
);
536 print_hexstring (fp
, s
+1, len
, 0);
541 do_putc ('\n', fp
, stream
);
543 for (idx
=0; (p
= ksba_cert_get_subject (cert
, idx
)); idx
++)
547 : "\n aka ..: "), fp
, stream
);
549 gpgsm_es_print_name (stream
, p
);
551 gpgsm_print_name (fp
, p
);
554 do_putc ('\n', fp
, stream
);
559 popen_protect_tool (const char *pgmname
,
560 FILE *infile
, FILE *outfile
, FILE **statusfile
,
561 const char *prompt
, const char *keygrip
,
564 const char *argv
[20];
567 argv
[i
++] = "--homedir";
568 argv
[i
++] = opt
.homedir
;
569 argv
[i
++] = "--p12-export";
570 argv
[i
++] = "--have-cert";
571 argv
[i
++] = "--prompt";
572 argv
[i
++] = prompt
?prompt
:"";
573 argv
[i
++] = "--enable-status-msg";
576 argv
[i
++] = "--p12-charset";
577 argv
[i
++] = opt
.p12_charset
;
582 assert (i
< sizeof argv
);
584 return gnupg_spawn_process (pgmname
, argv
, infile
, outfile
,
591 export_p12 (ctrl_t ctrl
, const unsigned char *certimg
, size_t certimglen
,
592 const char *prompt
, const char *keygrip
,
596 gpg_error_t err
= 0, child_err
= 0;
599 FILE *infp
= NULL
, *outfp
= NULL
, *fp
= NULL
;
604 if (!opt
.protect_tool_program
|| !*opt
.protect_tool_program
)
605 pgmname
= gnupg_module_name (GNUPG_MODULE_NAME_PROTECT_TOOL
);
607 pgmname
= opt
.protect_tool_program
;
612 err
= gpg_error_from_syserror ();
613 log_error (_("error creating temporary file: %s\n"), strerror (errno
));
617 if (fwrite (certimg
, certimglen
, 1, infp
) != 1)
619 err
= gpg_error_from_syserror ();
620 log_error (_("error writing to temporary file: %s\n"),
628 err
= gpg_error_from_syserror ();
629 log_error (_("error creating temporary file: %s\n"), strerror (errno
));
633 err
= popen_protect_tool (pgmname
, infp
, outfp
, &fp
, prompt
, keygrip
, &pid
);
642 /* Read stderr of the protect tool. */
645 while ((c
=getc (fp
)) != EOF
)
647 /* fixme: We could here grep for status information of the
648 protect tool to figure out better error codes for
651 if (pos
>= sizeof buffer
- 5 || c
== '\n')
653 buffer
[pos
- (c
== '\n')] = 0;
655 log_printf ("%s", buffer
);
658 if (!strncmp (buffer
, "gpg-protect-tool: [PROTECT-TOOL:] ",34))
663 pend
= strchr (p
, ' ');
666 if ( !strcmp (p
, "bad-passphrase"))
670 log_info ("%s", buffer
);
673 cont_line
= (c
!= '\n');
681 log_printf ("%s\n", buffer
);
683 log_info ("%s\n", buffer
);
688 /* If we found no error in the output of the child, setup a suitable
689 error code, which will later be reset if the exit status of the
692 child_err
= gpg_error (GPG_ERR_DECRYPT_FAILED
);
701 if (!gnupg_wait_process (pgmname
, pid
))
715 /* During export this is the passphrase used to unprotect the
716 key and not the pkcs#12 thing as in export. Therefore we can
717 issue the regular passphrase status. FIXME: replace the all
718 zero keyid by a regular one. */
719 gpgsm_status (ctrl
, STATUS_BAD_PASSPHRASE
, "0000000000000000");