1 /* export.c - Export certificates and private keys.
2 * Copyright (C) 2002, 2003, 2004, 2007, 2009,
3 * 2010 Free Software Foundation, Inc.
5 * This file is part of GnuPG.
7 * GnuPG is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
12 * GnuPG is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <https://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, 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,
64 void **r_result, size_t *r_resultlen);
67 /* Create a table used to indetify duplicated certificates. */
69 create_duptable (void)
71 return xtrycalloc (DUPTABLE_SIZE, sizeof (duptable_t));
75 destroy_duptable (duptable_t *table)
82 for (idx=0; idx < DUPTABLE_SIZE; idx++)
83 for (t = table[idx]; t; t = t2)
92 /* Insert the 20 byte fingerprint FPR into TABLE. Sets EXITS to true
93 if the fingerprint already exists in the table. */
95 insert_duptable (duptable_t *table, unsigned char *fpr, int *exists)
102 #if DUPTABLE_BITS > 16 || DUPTABLE_BITS < 8
103 #error cannot handle a table larger than 16 bits or smaller than 8 bits
104 #elif DUPTABLE_BITS > 8
105 idx <<= (DUPTABLE_BITS - 8);
106 idx |= (fpr[1] & ~(~0U << 4));
109 for (t = table[idx]; t; t = t->next)
110 if (!memcmp (t->fpr, fpr+1, 19))
117 /* Insert that fingerprint. */
118 t = xtrymalloc (sizeof *t);
120 return gpg_error_from_syserror ();
121 memcpy (t->fpr, fpr+1, 19);
122 t->next = table[idx];
128 /* Export all certificates or just those given in NAMES. The output
129 is written to STREAM. */
131 gpgsm_export (ctrl_t ctrl, strlist_t names, estream_t stream)
133 KEYDB_HANDLE hd = NULL;
134 KEYDB_SEARCH_DESC *desc = NULL;
136 gnupg_ksba_io_t 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 = classify_user_id (sl->d, desc+ndesc, 0);
185 log_error ("key '%s' not found: %s\n",
186 sl->d, gpg_strerror (rc));
194 /* If all specifications are done by fingerprint or keygrip, we
195 switch to ephemeral mode so that _all_ currently available and
196 matching certificates are exported. */
200 && (desc[i].mode == KEYDB_SEARCH_MODE_FPR
201 || desc[i].mode == KEYDB_SEARCH_MODE_FPR20
202 || desc[i].mode == KEYDB_SEARCH_MODE_FPR16
203 || desc[i].mode == KEYDB_SEARCH_MODE_KEYGRIP)); i++)
206 keydb_set_ephemeral (hd, 1);
209 while (!(rc = keydb_search (ctrl, hd, desc, ndesc)))
211 unsigned char fpr[20];
215 desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
217 rc = keydb_get_cert (hd, &cert);
220 log_error ("keydb_get_cert failed: %s\n", gpg_strerror (rc));
224 gpgsm_get_fingerprint (cert, 0, fpr, NULL);
225 rc = insert_duptable (dtable, fpr, &exists);
228 log_error ("inserting into duplicates table failed: %s\n",
233 if (!exists && count && !ctrl->create_pem)
235 log_info ("exporting more than one certificate "
236 "is not possible in binary mode\n");
237 log_info ("ignoring other certificates\n");
243 const unsigned char *image;
246 image = ksba_cert_get_image (cert, &imagelen);
249 log_error ("ksba_cert_get_image failed\n");
254 if (ctrl->create_pem)
257 es_putc ('\n', stream);
258 print_short_info (cert, stream);
259 es_putc ('\n', stream);
265 ctrl->pem_name = "CERTIFICATE";
266 rc = gnupg_ksba_create_writer
267 (&b64writer, ((ctrl->create_pem? GNUPG_KSBA_IO_PEM : 0)
268 | (ctrl->create_base64? GNUPG_KSBA_IO_BASE64 :0)),
269 ctrl->pem_name, stream, &writer);
272 log_error ("can't create writer: %s\n", gpg_strerror (rc));
277 rc = ksba_writer_write (writer, image, imagelen);
280 log_error ("write error: %s\n", gpg_strerror (rc));
284 if (ctrl->create_pem)
286 /* We want one certificate per PEM block */
287 rc = gnupg_ksba_finish_writer (b64writer);
290 log_error ("write failed: %s\n", gpg_strerror (rc));
293 gnupg_ksba_destroy_writer (b64writer);
298 ksba_cert_release (cert);
302 log_error ("keydb_search failed: %s\n", gpg_strerror (rc));
305 rc = gnupg_ksba_finish_writer (b64writer);
308 log_error ("write failed: %s\n", gpg_strerror (rc));
314 gnupg_ksba_destroy_writer (b64writer);
315 ksba_cert_release (cert);
318 destroy_duptable (dtable);
322 /* Export a certificate and its private key. RAWMODE controls the
324 0 - Private key and certifciate in PKCS#12 format
325 1 - Only unencrypted private key in PKCS#8 format
326 2 - Only unencrypted private key in PKCS#1 format
329 gpgsm_p12_export (ctrl_t ctrl, const char *name, estream_t stream, int rawmode)
333 KEYDB_SEARCH_DESC *desc = NULL;
334 gnupg_ksba_io_t b64writer = NULL;
335 ksba_writer_t writer;
336 ksba_cert_t cert = NULL;
337 const unsigned char *image;
339 char *keygrip = NULL;
347 log_error ("keydb_new failed\n");
351 desc = xtrycalloc (1, sizeof *desc);
354 log_error ("allocating memory for export failed: %s\n",
355 gpg_strerror (out_of_core ()));
359 err = classify_user_id (name, desc, 0);
362 log_error ("key '%s' not found: %s\n",
363 name, gpg_strerror (err));
367 /* Lookup the certificate and make sure that it is unique. */
368 err = keydb_search (ctrl, hd, desc, 1);
371 err = keydb_get_cert (hd, &cert);
374 log_error ("keydb_get_cert failed: %s\n", gpg_strerror (err));
379 err = keydb_search (ctrl, hd, desc, 1);
382 ksba_cert_t cert2 = NULL;
384 if (!keydb_get_cert (hd, &cert2))
386 if (gpgsm_certs_identical_p (cert, cert2))
388 ksba_cert_release (cert2);
391 ksba_cert_release (cert2);
393 err = gpg_error (GPG_ERR_AMBIGUOUS_NAME);
395 else if (err == -1 || gpg_err_code (err) == GPG_ERR_EOF)
399 log_error ("key '%s' not found: %s\n",
400 name, gpg_strerror (err));
405 keygrip = gpgsm_get_keygrip_hexstring (cert);
406 if (!keygrip || gpgsm_agent_havekey (ctrl, keygrip))
408 /* Note, that the !keygrip case indicates a bad certificate. */
409 err = gpg_error (GPG_ERR_NO_SECKEY);
410 log_error ("can't export key '%s': %s\n", name, gpg_strerror (err));
414 image = ksba_cert_get_image (cert, &imagelen);
417 log_error ("ksba_cert_get_image failed\n");
421 if (ctrl->create_pem)
423 print_short_info (cert, stream);
424 es_putc ('\n', stream);
427 if (opt.p12_charset && ctrl->create_pem && !rawmode)
429 es_fprintf (stream, "The passphrase is %s encoded.\n\n",
434 ctrl->pem_name = "PKCS12";
435 else if (rawmode == 1)
436 ctrl->pem_name = "PRIVATE KEY";
438 ctrl->pem_name = "RSA PRIVATE KEY";
439 err = gnupg_ksba_create_writer
440 (&b64writer, ((ctrl->create_pem? GNUPG_KSBA_IO_PEM : 0)
441 | (ctrl->create_base64? GNUPG_KSBA_IO_BASE64 : 0)),
442 ctrl->pem_name, stream, &writer);
445 log_error ("can't create writer: %s\n", gpg_strerror (err));
449 prompt = gpgsm_format_keydesc (cert);
450 err = export_p12 (ctrl, image, imagelen, prompt, keygrip, rawmode,
455 err = ksba_writer_write (writer, data, datalen);
459 log_error ("write failed: %s\n", gpg_strerror (err));
463 if (ctrl->create_pem)
465 /* We want one certificate per PEM block */
466 err = gnupg_ksba_finish_writer (b64writer);
469 log_error ("write failed: %s\n", gpg_strerror (err));
472 gnupg_ksba_destroy_writer (b64writer);
476 ksba_cert_release (cert);
480 gnupg_ksba_destroy_writer (b64writer);
481 ksba_cert_release (cert);
487 /* Print some info about the certifciate CERT to FP or STREAM */
489 print_short_info (ksba_cert_t cert, estream_t stream)
495 for (idx=0; (p = ksba_cert_get_issuer (cert, idx)); idx++)
499 : "\n aka ...: "), stream);
500 gpgsm_es_print_name (stream, p);
503 es_putc ('\n', stream);
505 es_fputs ("Serial ...: ", stream);
506 sexp = ksba_cert_get_serial (cert);
510 const unsigned char *s = sexp;
515 for (len=0; *s && *s != ':' && digitp (s); s++)
516 len = len*10 + atoi_1 (s);
518 es_write_hexstring (stream, s+1, len, 0, NULL);
522 es_putc ('\n', stream);
524 for (idx=0; (p = ksba_cert_get_subject (cert, idx)); idx++)
528 : "\n aka ..: "), stream);
529 gpgsm_es_print_name (stream, p);
532 es_putc ('\n', stream);
534 p = gpgsm_get_keygrip_hexstring (cert);
537 es_fprintf (stream, "Keygrip ..: %s\n", p);
544 /* Parse a private key S-expression and return a malloced array with
545 the RSA parameters in pkcs#12 order. The caller needs to
546 deep-release this array. */
548 sexp_to_kparms (gcry_sexp_t sexp)
550 gcry_sexp_t list, l2;
558 list = gcry_sexp_find_token (sexp, "private-key", 0 );
561 l2 = gcry_sexp_cadr (list);
562 gcry_sexp_release (list);
564 name = gcry_sexp_nth_data (list, 0, &n);
565 if(!name || n != 3 || memcmp (name, "rsa", 3))
567 gcry_sexp_release (list);
571 /* Parameter names used with RSA in the pkcs#12 order. */
573 array = xtrycalloc (strlen(elems) + 1, sizeof *array);
576 gcry_sexp_release (list);
579 for (idx=0, s=elems; *s; s++, idx++ )
582 continue; /* Computed below */
583 l2 = gcry_sexp_find_token (list, s, 1);
586 array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
587 gcry_sexp_release (l2);
589 if (!array[idx]) /* Required parameter not found or invalid. */
591 for (idx=0; array[idx]; idx++)
592 gcry_mpi_release (array[idx]);
594 gcry_sexp_release (list);
598 gcry_sexp_release (list);
600 array[5] = gcry_mpi_snew (0); /* compute d mod (q-1) */
601 gcry_mpi_sub_ui (array[5], array[3], 1);
602 gcry_mpi_mod (array[5], array[2], array[5]);
604 array[6] = gcry_mpi_snew (0); /* compute d mod (p-1) */
605 gcry_mpi_sub_ui (array[6], array[4], 1);
606 gcry_mpi_mod (array[6], array[3], array[6]);
613 export_p12 (ctrl_t ctrl, const unsigned char *certimg, size_t certimglen,
614 const char *prompt, const char *keygrip, int rawmode,
615 void **r_result, size_t *r_resultlen)
620 unsigned char *wrappedkey = NULL;
621 size_t wrappedkeylen;
622 gcry_cipher_hd_t cipherhd = NULL;
623 gcry_sexp_t s_skey = NULL;
624 gcry_mpi_t *kparms = NULL;
625 unsigned char *key = NULL;
627 char *passphrase = NULL;
628 unsigned char *result = NULL;
634 /* Get the current KEK. */
635 err = gpgsm_agent_keywrap_key (ctrl, 1, &kek, &keklen);
638 log_error ("error getting the KEK: %s\n", gpg_strerror (err));
642 /* Receive the wrapped key from the agent. */
643 err = gpgsm_agent_export_key (ctrl, keygrip, prompt,
644 &wrappedkey, &wrappedkeylen);
649 /* Unwrap the key. */
650 err = gcry_cipher_open (&cipherhd, GCRY_CIPHER_AES128,
651 GCRY_CIPHER_MODE_AESWRAP, 0);
654 err = gcry_cipher_setkey (cipherhd, kek, keklen);
660 if (wrappedkeylen < 24)
662 err = gpg_error (GPG_ERR_INV_LENGTH);
665 keylen = wrappedkeylen - 8;
666 key = xtrymalloc_secure (keylen);
669 err = gpg_error_from_syserror ();
672 err = gcry_cipher_decrypt (cipherhd, key, keylen, wrappedkey, wrappedkeylen);
677 gcry_cipher_close (cipherhd);
681 /* Convert to a gcrypt S-expression. */
682 err = gcry_sexp_create (&s_skey, key, keylen, 0, xfree_fnc);
685 key = NULL; /* Key is now owned by S_KEY. */
687 /* Get the parameters from the S-expression. */
688 kparms = sexp_to_kparms (s_skey);
689 gcry_sexp_release (s_skey);
693 log_error ("error converting key parameters\n");
694 err = GPG_ERR_BAD_SECKEY;
700 /* Export in raw mode, that is only the pkcs#1/#8 private key. */
701 result = p12_raw_build (kparms, rawmode, &resultlen);
703 err = gpg_error (GPG_ERR_GENERAL);
707 err = gpgsm_agent_ask_passphrase
709 i18n_utf8 ("Please enter the passphrase to protect the "
710 "new PKCS#12 object."),
715 result = p12_build (kparms, certimg, certimglen, passphrase,
716 opt.p12_charset, &resultlen);
720 err = gpg_error (GPG_ERR_GENERAL);
725 gcry_sexp_release (s_skey);
728 for (i=0; kparms[i]; i++)
729 gcry_mpi_release (kparms[i]);
732 gcry_cipher_close (cipherhd);
736 if (gpg_err_code (err) == GPG_ERR_BAD_PASSPHRASE)
738 /* During export this is the passphrase used to unprotect the
739 key and not the pkcs#12 thing as in export. Therefore we can
740 issue the regular passphrase status. FIXME: replace the all
741 zero keyid by a regular one. */
742 gpgsm_status (ctrl, STATUS_BAD_PASSPHRASE, "0000000000000000");
752 *r_resultlen = resultlen;