1 /* cvt-openpgp.c - Convert an OpenPGP key to our internal format.
2 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2006, 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 <http://www.gnu.org/licenses/>.
29 #include "cvt-openpgp.h"
32 /* Helper to pass data via the callback to do_unprotect. */
33 struct try_do_unprotect_arg_s
54 /* Compute the keygrip from the public key and store it at GRIP. */
56 get_keygrip (int pubkey_algo, gcry_mpi_t *pkey, unsigned char *grip)
59 gcry_sexp_t s_pkey = NULL;
64 err = gcry_sexp_build (&s_pkey, NULL,
65 "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))",
66 pkey[0], pkey[1], pkey[2], pkey[3]);
71 err = gcry_sexp_build (&s_pkey, NULL,
72 "(public-key(elg(p%m)(g%m)(y%m)))",
73 pkey[0], pkey[1], pkey[2]);
79 err = gcry_sexp_build (&s_pkey, NULL,
80 "(public-key(rsa(n%m)(e%m)))", pkey[0], pkey[1]);
84 err = gpg_error (GPG_ERR_PUBKEY_ALGO);
88 if (!err && !gcry_pk_get_keygrip (s_pkey, grip))
89 err = gpg_error (GPG_ERR_INTERNAL);
91 gcry_sexp_release (s_pkey);
96 /* Convert a secret key given as algorithm id and an array of key
97 parameters into our s-expression based format. */
99 convert_secret_key (gcry_sexp_t *r_key, int pubkey_algo, gcry_mpi_t *skey)
102 gcry_sexp_t s_skey = NULL;
109 err = gcry_sexp_build (&s_skey, NULL,
110 "(private-key(dsa(p%m)(q%m)(g%m)(y%m)(x%m)))",
111 skey[0], skey[1], skey[2], skey[3], skey[4]);
116 err = gcry_sexp_build (&s_skey, NULL,
117 "(private-key(elg(p%m)(g%m)(y%m)(x%m)))",
118 skey[0], skey[1], skey[2], skey[3]);
125 err = gcry_sexp_build (&s_skey, NULL,
126 "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))",
127 skey[0], skey[1], skey[2], skey[3], skey[4],
131 err = gpg_error (GPG_ERR_PUBKEY_ALGO);
142 /* Hash the passphrase and set the key. */
144 hash_passphrase_and_set_key (const char *passphrase,
145 gcry_cipher_hd_t hd, int protect_algo,
146 int s2k_mode, int s2k_algo,
147 byte *s2k_salt, u32 s2k_count)
153 keylen = gcry_cipher_get_algo_keylen (protect_algo);
155 return gpg_error (GPG_ERR_INTERNAL);
157 key = xtrymalloc_secure (keylen);
159 return gpg_error_from_syserror ();
161 err = s2k_hash_passphrase (passphrase,
162 s2k_algo, s2k_mode, s2k_salt, s2k_count,
165 err = gcry_cipher_setkey (hd, key, keylen);
173 checksum (const unsigned char *p, unsigned int n)
183 /* Note that this function modified SKEY. SKEYSIZE is the allocated
184 size of the array including the NULL item; this is used for a
185 bounds check. On success a converted key is stored at R_KEY. */
187 do_unprotect (const char *passphrase,
188 int pkt_version, int pubkey_algo, int is_protected,
189 gcry_mpi_t *skey, size_t skeysize,
190 int protect_algo, void *protect_iv, size_t protect_ivlen,
191 int s2k_mode, int s2k_algo, byte *s2k_salt, u32 s2k_count,
192 u16 desired_csum, gcry_sexp_t *r_key)
195 size_t npkey, nskey, skeylen;
196 gcry_cipher_hd_t cipher_hd = NULL;
204 /* Count the actual number of MPIs is in the array and set the
205 remainder to NULL for easier processing later on. */
206 for (skeylen = 0; skey[skeylen]; skeylen++)
208 for (i=skeylen; i < skeysize; i++)
211 /* Check some args. */
212 if (s2k_mode == 1001)
215 log_info (_("secret key parts are not available\n"));
216 return gpg_error (GPG_ERR_UNUSABLE_SECKEY);
219 if (gcry_pk_test_algo (pubkey_algo))
221 /* The algorithm numbers are Libgcrypt numbers but fortunately
222 the OpenPGP algorithm numbers map one-to-one to the Libgcrypt
224 log_info (_("public key algorithm %d (%s) is not supported\n"),
225 pubkey_algo, gcry_pk_algo_name (pubkey_algo));
226 return gpg_error (GPG_ERR_PUBKEY_ALGO);
229 /* Get properties of the public key algorithm and do some
230 consistency checks. Note that we need at least NPKEY+1 elements
231 in the SKEY array. */
232 if ( (err = gcry_pk_algo_info (pubkey_algo, GCRYCTL_GET_ALGO_NPKEY,
234 || (err = gcry_pk_algo_info (pubkey_algo, GCRYCTL_GET_ALGO_NSKEY,
237 if (!npkey || npkey >= nskey)
238 return gpg_error (GPG_ERR_INTERNAL);
239 if (skeylen <= npkey)
240 return gpg_error (GPG_ERR_MISSING_VALUE);
241 if (nskey+1 >= skeysize)
242 return gpg_error (GPG_ERR_BUFFER_TOO_SHORT);
244 /* Check whether SKEY is at all protected. If it is not protected
245 merely verify the checksum. */
248 unsigned char *buffer;
251 for (i=npkey; i < nskey; i++)
253 if (!skey[i] || gcry_mpi_get_flag (skey[i], GCRYMPI_FLAG_OPAQUE))
254 return gpg_error (GPG_ERR_BAD_SECKEY);
256 err = gcry_mpi_print (GCRYMPI_FMT_PGP, NULL, 0, &nbytes, skey[i]);
259 buffer = (gcry_is_secure (skey[i])?
260 xtrymalloc_secure (nbytes) : xtrymalloc (nbytes));
262 return gpg_error_from_syserror ();
263 err = gcry_mpi_print (GCRYMPI_FMT_PGP, buffer, nbytes,
266 actual_csum += checksum (buffer, nbytes);
273 if (actual_csum != desired_csum)
274 return gpg_error (GPG_ERR_CHECKSUM);
279 if (gcry_cipher_test_algo (protect_algo))
281 /* The algorithm numbers are Libgcrypt numbers but fortunately
282 the OpenPGP algorithm numbers map one-to-one to the Libgcrypt
284 log_info (_("protection algorithm %d (%s) is not supported\n"),
285 protect_algo, gcry_cipher_algo_name (protect_algo));
286 return gpg_error (GPG_ERR_CIPHER_ALGO);
289 if (gcry_md_test_algo (s2k_algo))
291 log_info (_("protection hash algorithm %d (%s) is not supported\n"),
292 s2k_algo, gcry_md_algo_name (s2k_algo));
293 return gpg_error (GPG_ERR_DIGEST_ALGO);
296 err = gcry_cipher_open (&cipher_hd, protect_algo,
297 GCRY_CIPHER_MODE_CFB,
299 | (protect_algo >= 100 ?
300 0 : GCRY_CIPHER_ENABLE_SYNC)));
303 log_error ("failed to open cipher_algo %d: %s\n",
304 protect_algo, gpg_strerror (err));
308 err = hash_passphrase_and_set_key (passphrase, cipher_hd, protect_algo,
309 s2k_mode, s2k_algo, s2k_salt, s2k_count);
312 gcry_cipher_close (cipher_hd);
316 gcry_cipher_setiv (cipher_hd, protect_iv, protect_ivlen);
319 if (pkt_version >= 4)
322 unsigned int ndatabits;
323 unsigned char *p, *data;
326 if (!gcry_mpi_get_flag (skey[npkey], GCRYMPI_FLAG_OPAQUE ))
328 gcry_cipher_close (cipher_hd);
329 return gpg_error (GPG_ERR_BAD_SECKEY);
331 p = gcry_mpi_get_opaque (skey[npkey], &ndatabits);
332 ndata = (ndatabits+7)/8;
335 csum_pgp7 = p[ndata-2] << 8 | p[ndata-1];
336 data = xtrymalloc_secure (ndata);
339 err = gpg_error_from_syserror ();
340 gcry_cipher_close (cipher_hd);
343 gcry_cipher_decrypt (cipher_hd, data, ndata, p, ndata);
346 if (is_protected == 2)
348 /* This is the new SHA1 checksum method to detect tampering
349 with the key as used by the Klima/Rosa attack. */
351 actual_csum = 1; /* Default to bad checksum. */
354 log_error ("not enough bytes for SHA-1 checksum\n");
359 if (gcry_md_open (&h, GCRY_MD_SHA1, 1))
360 BUG(); /* Algo not available. */
361 gcry_md_write (h, data, ndata - 20);
363 if (!memcmp (gcry_md_read (h, GCRY_MD_SHA1), data+ndata-20, 20))
364 actual_csum = 0; /* Digest does match. */
370 /* Old 16 bit checksum method. */
373 log_error ("not enough bytes for checksum\n");
375 actual_csum = 1; /* Mark checksum bad. */
379 desired_csum = (data[ndata-2] << 8 | data[ndata-1]);
380 actual_csum = checksum (data, ndata-2);
381 if (desired_csum != actual_csum)
383 /* This is a PGP 7.0.0 workaround */
384 desired_csum = csum_pgp7; /* Take the encrypted one. */
389 /* Better check it here. Otherwise the gcry_mpi_scan would fail
390 because the length may have an arbitrary value. */
391 if (desired_csum == actual_csum)
393 for (i=npkey; i < nskey; i++ )
395 if (gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_PGP, p, ndata, &nbytes))
397 /* Checksum was okay, but not correctly decrypted. */
399 actual_csum = 1; /* Mark checksum bad. */
402 gcry_mpi_release (skey[i]);
409 assert (skeylen <= skeysize);
411 /* Note: at this point NDATA should be 2 for a simple
412 checksum or 20 for the sha1 digest. */
416 else /* Packet version <= 3. */
418 unsigned char *buffer;
420 for (i = npkey; i < nskey; i++)
424 unsigned int ndatabits;
426 if (!skey[i] || !gcry_mpi_get_flag (skey[i], GCRYMPI_FLAG_OPAQUE))
428 gcry_cipher_close (cipher_hd);
429 return gpg_error (GPG_ERR_BAD_SECKEY);
431 p = gcry_mpi_get_opaque (skey[i], &ndatabits);
432 ndata = (ndatabits+7)/8;
434 if (!(ndata >= 2) || !(ndata == ((p[0] << 8 | p[1]) + 7)/8 + 2))
436 gcry_cipher_close (cipher_hd);
437 return gpg_error (GPG_ERR_BAD_SECKEY);
440 buffer = xtrymalloc_secure (ndata);
443 err = gpg_error_from_syserror ();
444 gcry_cipher_close (cipher_hd);
448 gcry_cipher_sync (cipher_hd);
451 gcry_cipher_decrypt (cipher_hd, buffer+2, ndata-2, p+2, ndata-2);
452 actual_csum += checksum (buffer, ndata);
453 err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_PGP, buffer, ndata, &ndata);
457 /* Checksum was okay, but not correctly decrypted. */
459 actual_csum = 1; /* Mark checksum bad. */
462 gcry_mpi_release (skey[i]);
466 gcry_cipher_close (cipher_hd);
468 /* Now let's see whether we have used the correct passphrase. */
469 if (actual_csum != desired_csum)
470 return gpg_error (GPG_ERR_BAD_PASSPHRASE);
472 if (nskey != skeylen)
473 err = gpg_error (GPG_ERR_BAD_SECKEY);
475 err = convert_secret_key (r_key, pubkey_algo, skey);
479 /* The checksum may fail, thus we also check the key itself. */
480 err = gcry_pk_testkey (*r_key);
483 gcry_sexp_release (*r_key);
485 return gpg_error (GPG_ERR_BAD_PASSPHRASE);
492 /* Callback function to try the unprotection from the passpharse query
495 try_do_unprotect_cb (struct pin_entry_info_s *pi)
498 struct try_do_unprotect_arg_s *arg = pi->check_cb_arg;
500 err = do_unprotect (pi->pin,
502 arg->pubkey_algo, arg->is_protected,
503 arg->skey, arg->skeysize,
504 arg->protect_algo, arg->iv, arg->ivlen,
505 arg->s2k_mode, arg->s2k_algo,
506 arg->s2k_salt, arg->s2k_count,
507 arg->desired_csum, arg->r_key);
508 /* SKEY may be modified now, thus we need to re-compute SKEYIDX. */
509 for (arg->skeyidx = 0; (arg->skeyidx < arg->skeysize
510 && arg->skey[arg->skeyidx]); arg->skeyidx++)
516 /* Convert an OpenPGP transfer key into our internal format. Before
517 asking for a passphrase we check whether the key already exists in
518 our key storage. S_PGP is the OpenPGP key in transfer format. If
519 CACHE_NONCE is given the passphrase will be looked up in the cache.
520 On success R_KEY will receive a canonical encoded S-expression with
521 the unprotected key in our internal format; the caller needs to
522 release that memory. The passphrase used to decrypt the OpenPGP
523 key will be returned at R_PASSPHRASE; the caller must release this
524 passphrase. The keygrip will be stored at the 20 byte buffer
525 pointed to by GRIP. On error NULL is stored at all return
528 convert_openpgp (ctrl_t ctrl, gcry_sexp_t s_pgp,
529 unsigned char *grip, const char *prompt,
530 const char *cache_nonce,
531 unsigned char **r_key, char **r_passphrase)
534 gcry_sexp_t top_list;
535 gcry_sexp_t list = NULL;
540 int is_v4, is_protected;
542 int protect_algo = 0;
550 gcry_mpi_t skey[10]; /* We support up to 9 parameters. */
554 struct pin_entry_info_s *pi;
555 struct try_do_unprotect_arg_s pi_arg;
558 *r_passphrase = NULL;
560 top_list = gcry_sexp_find_token (s_pgp, "openpgp-private-key", 0);
564 list = gcry_sexp_find_token (top_list, "version", 0);
567 value = gcry_sexp_nth_data (list, 1, &valuelen);
568 if (!value || valuelen != 1 || !(value[0] == '3' || value[0] == '4'))
570 is_v4 = (value[0] == '4');
572 gcry_sexp_release (list);
573 list = gcry_sexp_find_token (top_list, "protection", 0);
576 value = gcry_sexp_nth_data (list, 1, &valuelen);
579 if (valuelen == 4 && !memcmp (value, "sha1", 4))
581 else if (valuelen == 3 && !memcmp (value, "sum", 3))
583 else if (valuelen == 4 && !memcmp (value, "none", 4))
589 string = gcry_sexp_nth_string (list, 2);
592 protect_algo = gcry_cipher_map_name (string);
593 if (!protect_algo && !!strcmp (string, "IDEA"))
594 protect_algo = GCRY_CIPHER_IDEA;
597 value = gcry_sexp_nth_data (list, 3, &valuelen);
598 if (!value || !valuelen || valuelen > sizeof iv)
600 memcpy (iv, value, valuelen);
603 string = gcry_sexp_nth_string (list, 4);
606 s2k_mode = strtol (string, NULL, 10);
609 string = gcry_sexp_nth_string (list, 5);
612 s2k_algo = gcry_md_map_name (string);
615 value = gcry_sexp_nth_data (list, 6, &valuelen);
616 if (!value || !valuelen || valuelen > sizeof s2k_salt)
618 memcpy (s2k_salt, value, valuelen);
620 string = gcry_sexp_nth_string (list, 7);
623 s2k_count = strtoul (string, NULL, 10);
627 gcry_sexp_release (list);
628 list = gcry_sexp_find_token (top_list, "algo", 0);
631 string = gcry_sexp_nth_string (list, 1);
634 pubkey_algo = gcry_pk_map_name (string);
637 if (gcry_pk_algo_info (pubkey_algo, GCRYCTL_GET_ALGO_NPKEY, NULL, &npkey)
638 || gcry_pk_algo_info (pubkey_algo, GCRYCTL_GET_ALGO_NSKEY, NULL, &nskey)
639 || !npkey || npkey >= nskey)
642 gcry_sexp_release (list);
643 list = gcry_sexp_find_token (top_list, "skey", 0);
650 value = gcry_sexp_nth_data (list, ++idx, &valuelen);
651 if (!value && skeyidx >= npkey)
654 /* Check for too many parameters. Note that depending on the
655 protection mode and version number we may see less than NSKEY
656 (but at least NPKEY+1) parameters. */
659 if (skeyidx >= DIM (skey)-1)
662 if (!value || valuelen != 1 || !(value[0] == '_' || value[0] == 'e'))
664 is_enc = (value[0] == 'e');
665 value = gcry_sexp_nth_data (list, ++idx, &valuelen);
666 if (!value || !valuelen)
670 void *p = xtrymalloc (valuelen);
673 memcpy (p, value, valuelen);
674 skey[skeyidx] = gcry_mpi_set_opaque (NULL, p, valuelen*8);
680 if (gcry_mpi_scan (skey + skeyidx, GCRYMPI_FMT_STD,
681 value, valuelen, NULL))
686 skey[skeyidx++] = NULL;
688 gcry_sexp_release (list);
689 list = gcry_sexp_find_token (top_list, "csum", 0);
692 string = gcry_sexp_nth_string (list, 1);
695 desired_csum = strtoul (string, NULL, 10);
702 gcry_sexp_release (list); list = NULL;
703 gcry_sexp_release (top_list); top_list = NULL;
705 /* log_debug ("XXX is_v4=%d\n", is_v4); */
706 /* log_debug ("XXX pubkey_algo=%d\n", pubkey_algo); */
707 /* log_debug ("XXX is_protected=%d\n", is_protected); */
708 /* log_debug ("XXX protect_algo=%d\n", protect_algo); */
709 /* log_printhex ("XXX iv", iv, ivlen); */
710 /* log_debug ("XXX ivlen=%d\n", ivlen); */
711 /* log_debug ("XXX s2k_mode=%d\n", s2k_mode); */
712 /* log_debug ("XXX s2k_algo=%d\n", s2k_algo); */
713 /* log_printhex ("XXX s2k_salt", s2k_salt, sizeof s2k_salt); */
714 /* log_debug ("XXX s2k_count=%lu\n", (unsigned long)s2k_count); */
715 /* for (idx=0; skey[idx]; idx++) */
717 /* int is_enc = gcry_mpi_get_flag (skey[idx], GCRYMPI_FLAG_OPAQUE); */
718 /* log_info ("XXX skey[%d]%s:", idx, is_enc? " (enc)":""); */
722 /* unsigned int nbits; */
723 /* p = gcry_mpi_get_opaque (skey[idx], &nbits); */
724 /* log_printhex (NULL, p, (nbits+7)/8); */
727 /* gcry_mpi_dump (skey[idx]); */
728 /* log_printf ("\n"); */
731 err = get_keygrip (pubkey_algo, skey, grip);
735 if (!agent_key_available (grip))
737 err = gpg_error (GPG_ERR_EEXIST);
741 pi = xtrycalloc_secure (1, sizeof (*pi) + 100);
743 return gpg_error_from_syserror ();
744 pi->max_length = 100;
745 pi->min_digits = 0; /* We want a real passphrase. */
748 pi->check_cb = try_do_unprotect_cb;
749 pi->check_cb_arg = &pi_arg;
750 pi_arg.is_v4 = is_v4;
751 pi_arg.is_protected = is_protected;
752 pi_arg.pubkey_algo = pubkey_algo;
753 pi_arg.protect_algo = protect_algo;
755 pi_arg.ivlen = ivlen;
756 pi_arg.s2k_mode = s2k_mode;
757 pi_arg.s2k_algo = s2k_algo;
758 pi_arg.s2k_salt = s2k_salt;
759 pi_arg.s2k_count = s2k_count;
760 pi_arg.desired_csum = desired_csum;
762 pi_arg.skeysize = DIM (skey);
763 pi_arg.skeyidx = skeyidx;
764 pi_arg.r_key = &s_skey;
766 err = gpg_error (GPG_ERR_BAD_PASSPHRASE);
769 void *cache_marker = NULL;
770 const char *cache_value;
772 cache_value = agent_get_cache (cache_nonce, CACHE_MODE_IMPGEN,
776 if (strlen (cache_value) < pi->max_length)
777 strcpy (pi->pin, cache_value);
778 agent_unlock_cache_entry (&cache_marker);
781 err = try_do_unprotect_cb (pi);
783 if (gpg_err_code (err) == GPG_ERR_BAD_PASSPHRASE)
784 err = agent_askpin (ctrl, prompt, NULL, NULL, pi);
785 skeyidx = pi_arg.skeyidx;
788 *r_passphrase = xtrystrdup (pi->pin);
790 err = gpg_error_from_syserror ();
796 /* Save some memory and get rid of the SKEY array now. */
797 for (idx=0; idx < skeyidx; idx++)
798 gcry_mpi_release (skey[idx]);
801 /* Note that the padding is not required - we use it only because
802 that function allows us to created the result in secure memory. */
803 err = make_canon_sexp_pad (s_skey, 1, r_key, NULL);
804 gcry_sexp_release (s_skey);
807 gcry_sexp_release (list);
808 gcry_sexp_release (top_list);
809 for (idx=0; idx < skeyidx; idx++)
810 gcry_mpi_release (skey[idx]);
813 xfree (*r_passphrase);
814 *r_passphrase = NULL;
819 err = gpg_error (GPG_ERR_BAD_SECKEY);
823 err = gpg_error (GPG_ERR_ENOMEM);