Port Windows code to NPTH.
[gnupg.git] / agent / cvt-openpgp.c
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.
4  *
5  * This file is part of GnuPG.
6  *
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.
11  *
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.
16  *
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/>.
19  */
20
21 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <assert.h>
26
27 #include "agent.h"
28 #include "i18n.h"
29 #include "cvt-openpgp.h"
30
31
32 /* Helper to pass data via the callback to do_unprotect. */
33 struct try_do_unprotect_arg_s
34 {
35   int  is_v4;
36   int  is_protected;
37   int  pubkey_algo;
38   int  protect_algo;
39   char *iv;
40   int  ivlen;
41   int  s2k_mode;
42   int  s2k_algo;
43   byte *s2k_salt;
44   u32  s2k_count;
45   u16 desired_csum;
46   gcry_mpi_t *skey;
47   size_t skeysize;
48   int skeyidx;
49   gcry_sexp_t *r_key;
50 };
51
52
53
54 /* Compute the keygrip from the public key and store it at GRIP.  */
55 static gpg_error_t
56 get_keygrip (int pubkey_algo, gcry_mpi_t *pkey, unsigned char *grip)
57 {
58   gpg_error_t err;
59   gcry_sexp_t s_pkey = NULL;
60
61   switch (pubkey_algo)
62     {
63     case GCRY_PK_DSA:
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]);
67       break;
68
69     case GCRY_PK_ELG:
70     case GCRY_PK_ELG_E:
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]);
74       break;
75
76     case GCRY_PK_RSA:
77     case GCRY_PK_RSA_E:
78     case GCRY_PK_RSA_S:
79       err = gcry_sexp_build (&s_pkey, NULL,
80                              "(public-key(rsa(n%m)(e%m)))", pkey[0], pkey[1]);
81       break;
82
83     case GCRY_PK_ECDSA:
84     case GCRY_PK_ECDH:
85       err = gcry_sexp_build (&s_pkey, NULL,
86                              "(public-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)(q%m)))",
87                              pkey[0], pkey[1], pkey[2], pkey[3], pkey[4],
88                              pkey[5]);
89       break;
90
91     default:
92       err = gpg_error (GPG_ERR_PUBKEY_ALGO);
93       break;
94     }
95
96   if (!err && !gcry_pk_get_keygrip (s_pkey, grip))
97     err = gpg_error (GPG_ERR_INTERNAL);
98
99   gcry_sexp_release (s_pkey);
100   return err;
101 }
102
103
104 /* Convert a secret key given as algorithm id and an array of key
105    parameters into our s-expression based format.  Note that
106    PUBKEY_ALGO has an gcrypt algorithm number. */
107 static gpg_error_t
108 convert_secret_key (gcry_sexp_t *r_key, int pubkey_algo, gcry_mpi_t *skey)
109 {
110   gpg_error_t err;
111   gcry_sexp_t s_skey = NULL;
112
113   *r_key = NULL;
114
115   switch (pubkey_algo)
116     {
117     case GCRY_PK_DSA:
118       err = gcry_sexp_build (&s_skey, NULL,
119                              "(private-key(dsa(p%m)(q%m)(g%m)(y%m)(x%m)))",
120                              skey[0], skey[1], skey[2], skey[3], skey[4]);
121       break;
122
123     case GCRY_PK_ELG:
124     case GCRY_PK_ELG_E:
125       err = gcry_sexp_build (&s_skey, NULL,
126                              "(private-key(elg(p%m)(g%m)(y%m)(x%m)))",
127                              skey[0], skey[1], skey[2], skey[3]);
128       break;
129
130
131     case GCRY_PK_RSA:
132     case GCRY_PK_RSA_E:
133     case GCRY_PK_RSA_S:
134       err = gcry_sexp_build (&s_skey, NULL,
135                              "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))",
136                              skey[0], skey[1], skey[2], skey[3], skey[4],
137                              skey[5]);
138       break;
139
140     case GCRY_PK_ECDSA:
141     case GCRY_PK_ECDH:
142       /* Although our code would work with "ecc" we explicitly use
143          "ecdh" or "ecdsa" to implicitly set the key capabilities.  */
144       err = gcry_sexp_build (&s_skey, NULL,
145                              "(private-key(%s(p%m)(a%m)(b%m)(g%m)(n%m)(q%m)"
146                              "(d%m)))",
147                              pubkey_algo == GCRY_PK_ECDSA?"ecdsa":"ecdh",
148                              skey[0], skey[1], skey[2], skey[3], skey[4],
149                              skey[5], skey[6]);
150       break;
151
152     default:
153       err = gpg_error (GPG_ERR_PUBKEY_ALGO);
154       break;
155     }
156
157   if (!err)
158     *r_key = s_skey;
159   return err;
160 }
161
162
163
164 /* Hash the passphrase and set the key. */
165 static gpg_error_t
166 hash_passphrase_and_set_key (const char *passphrase,
167                              gcry_cipher_hd_t hd, int protect_algo,
168                              int s2k_mode, int s2k_algo,
169                              byte *s2k_salt, u32 s2k_count)
170 {
171   gpg_error_t err;
172   unsigned char *key;
173   size_t keylen;
174
175   keylen = gcry_cipher_get_algo_keylen (protect_algo);
176   if (!keylen)
177     return gpg_error (GPG_ERR_INTERNAL);
178
179   key = xtrymalloc_secure (keylen);
180   if (!key)
181     return gpg_error_from_syserror ();
182
183   err = s2k_hash_passphrase (passphrase,
184                              s2k_algo, s2k_mode, s2k_salt, s2k_count,
185                              key, keylen);
186   if (!err)
187     err = gcry_cipher_setkey (hd, key, keylen);
188
189   xfree (key);
190   return err;
191 }
192
193
194 static u16
195 checksum (const unsigned char *p, unsigned int n)
196 {
197   u16 a;
198
199   for (a=0; n; n-- )
200     a += *p++;
201   return a;
202 }
203
204
205 /* Note that this function modified SKEY.  SKEYSIZE is the allocated
206    size of the array including the NULL item; this is used for a
207    bounds check.  On success a converted key is stored at R_KEY.  */
208 static int
209 do_unprotect (const char *passphrase,
210               int pkt_version, int pubkey_algo, int is_protected,
211               gcry_mpi_t *skey, size_t skeysize,
212               int protect_algo, void *protect_iv, size_t protect_ivlen,
213               int s2k_mode, int s2k_algo, byte *s2k_salt, u32 s2k_count,
214               u16 desired_csum, gcry_sexp_t *r_key)
215 {
216   gpg_error_t err;
217   size_t npkey, nskey, skeylen;
218   gcry_cipher_hd_t cipher_hd = NULL;
219   u16 actual_csum;
220   size_t nbytes;
221   int i;
222   gcry_mpi_t tmpmpi;
223
224   *r_key = NULL;
225
226  /* Unfortunately, the OpenPGP PK algorithm numbers need to be
227     re-mapped for Libgcrypt.    */
228   pubkey_algo = map_pk_openpgp_to_gcry (pubkey_algo);
229
230   /* Count the actual number of MPIs is in the array and set the
231      remainder to NULL for easier processing later on.  */
232   for (skeylen = 0; skey[skeylen]; skeylen++)
233     ;
234   for (i=skeylen; i < skeysize; i++)
235     skey[i] = NULL;
236
237   /* Check some args.  */
238   if (s2k_mode == 1001)
239     {
240       /* Stub key.  */
241       log_info (_("secret key parts are not available\n"));
242       return gpg_error (GPG_ERR_UNUSABLE_SECKEY);
243     }
244
245   if (gcry_pk_test_algo (pubkey_algo))
246     {
247       log_info (_("public key algorithm %d (%s) is not supported\n"),
248                 pubkey_algo, gcry_pk_algo_name (pubkey_algo));
249       return gpg_error (GPG_ERR_PUBKEY_ALGO);
250     }
251
252   /* Get properties of the public key algorithm and do some
253      consistency checks.  Note that we need at least NPKEY+1 elements
254      in the SKEY array. */
255   if ( (err = gcry_pk_algo_info (pubkey_algo, GCRYCTL_GET_ALGO_NPKEY,
256                                  NULL, &npkey))
257        || (err = gcry_pk_algo_info (pubkey_algo, GCRYCTL_GET_ALGO_NSKEY,
258                                     NULL, &nskey)))
259     return err;
260   if (!npkey || npkey >= nskey)
261     return gpg_error (GPG_ERR_INTERNAL);
262   if (skeylen <= npkey)
263     return gpg_error (GPG_ERR_MISSING_VALUE);
264   if (nskey+1 >= skeysize)
265     return gpg_error (GPG_ERR_BUFFER_TOO_SHORT);
266
267   /* Check whether SKEY is at all protected.  If it is not protected
268      merely verify the checksum.  */
269   if (!is_protected)
270     {
271       unsigned char *buffer;
272
273       actual_csum = 0;
274       for (i=npkey; i < nskey; i++)
275         {
276           if (!skey[i] || gcry_mpi_get_flag (skey[i], GCRYMPI_FLAG_OPAQUE))
277             return gpg_error (GPG_ERR_BAD_SECKEY);
278
279           err = gcry_mpi_print (GCRYMPI_FMT_PGP, NULL, 0, &nbytes, skey[i]);
280           if (!err)
281             {
282               buffer = (gcry_is_secure (skey[i])?
283                         xtrymalloc_secure (nbytes) : xtrymalloc (nbytes));
284               if (!buffer)
285                 return gpg_error_from_syserror ();
286               err = gcry_mpi_print (GCRYMPI_FMT_PGP, buffer, nbytes,
287                                     NULL, skey[i]);
288               if (!err)
289                 actual_csum += checksum (buffer, nbytes);
290               xfree (buffer);
291             }
292           if (err)
293             return err;
294         }
295
296       if (actual_csum != desired_csum)
297         return gpg_error (GPG_ERR_CHECKSUM);
298       return 0;
299     }
300
301
302   if (gcry_cipher_test_algo (protect_algo))
303     {
304       /* The algorithm numbers are Libgcrypt numbers but fortunately
305          the OpenPGP algorithm numbers map one-to-one to the Libgcrypt
306          numbers.  */
307       log_info (_("protection algorithm %d (%s) is not supported\n"),
308                 protect_algo, gnupg_cipher_algo_name (protect_algo));
309       return gpg_error (GPG_ERR_CIPHER_ALGO);
310     }
311
312   if (gcry_md_test_algo (s2k_algo))
313     {
314       log_info (_("protection hash algorithm %d (%s) is not supported\n"),
315                 s2k_algo, gcry_md_algo_name (s2k_algo));
316       return gpg_error (GPG_ERR_DIGEST_ALGO);
317     }
318
319   err = gcry_cipher_open (&cipher_hd, protect_algo,
320                           GCRY_CIPHER_MODE_CFB,
321                           (GCRY_CIPHER_SECURE
322                            | (protect_algo >= 100 ?
323                               0 : GCRY_CIPHER_ENABLE_SYNC)));
324   if (err)
325     {
326       log_error ("failed to open cipher_algo %d: %s\n",
327                  protect_algo, gpg_strerror (err));
328       return err;
329     }
330
331   err = hash_passphrase_and_set_key (passphrase, cipher_hd, protect_algo,
332                                      s2k_mode, s2k_algo, s2k_salt, s2k_count);
333   if (err)
334     {
335       gcry_cipher_close (cipher_hd);
336       return err;
337     }
338
339   gcry_cipher_setiv (cipher_hd, protect_iv, protect_ivlen);
340
341   actual_csum = 0;
342   if (pkt_version >= 4)
343     {
344       int ndata;
345       unsigned int ndatabits;
346       unsigned char *p, *data;
347       u16 csum_pgp7 = 0;
348
349       if (!gcry_mpi_get_flag (skey[npkey], GCRYMPI_FLAG_OPAQUE ))
350         {
351           gcry_cipher_close (cipher_hd);
352           return gpg_error (GPG_ERR_BAD_SECKEY);
353         }
354       p = gcry_mpi_get_opaque (skey[npkey], &ndatabits);
355       ndata = (ndatabits+7)/8;
356
357       if (ndata > 1)
358         csum_pgp7 = p[ndata-2] << 8 | p[ndata-1];
359       data = xtrymalloc_secure (ndata);
360       if (!data)
361         {
362           err = gpg_error_from_syserror ();
363           gcry_cipher_close (cipher_hd);
364           return err;
365         }
366       gcry_cipher_decrypt (cipher_hd, data, ndata, p, ndata);
367
368       p = data;
369       if (is_protected == 2)
370         {
371           /* This is the new SHA1 checksum method to detect tampering
372              with the key as used by the Klima/Rosa attack.  */
373           desired_csum = 0;
374           actual_csum = 1;  /* Default to bad checksum.  */
375
376           if (ndata < 20)
377             log_error ("not enough bytes for SHA-1 checksum\n");
378           else
379             {
380               gcry_md_hd_t h;
381
382               if (gcry_md_open (&h, GCRY_MD_SHA1, 1))
383                 BUG(); /* Algo not available. */
384               gcry_md_write (h, data, ndata - 20);
385               gcry_md_final (h);
386               if (!memcmp (gcry_md_read (h, GCRY_MD_SHA1), data+ndata-20, 20))
387                 actual_csum = 0; /* Digest does match.  */
388               gcry_md_close (h);
389             }
390         }
391       else
392         {
393           /* Old 16 bit checksum method.  */
394           if (ndata < 2)
395             {
396               log_error ("not enough bytes for checksum\n");
397               desired_csum = 0;
398               actual_csum = 1;  /* Mark checksum bad.  */
399             }
400           else
401             {
402               desired_csum = (data[ndata-2] << 8 | data[ndata-1]);
403               actual_csum = checksum (data, ndata-2);
404               if (desired_csum != actual_csum)
405                 {
406                   /* This is a PGP 7.0.0 workaround */
407                   desired_csum = csum_pgp7; /* Take the encrypted one.  */
408                 }
409             }
410         }
411
412       /* Better check it here.  Otherwise the gcry_mpi_scan would fail
413          because the length may have an arbitrary value.  */
414       if (desired_csum == actual_csum)
415         {
416           for (i=npkey; i < nskey; i++ )
417             {
418               if (gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_PGP, p, ndata, &nbytes))
419                 {
420                   /* Checksum was okay, but not correctly decrypted.  */
421                   desired_csum = 0;
422                   actual_csum = 1;   /* Mark checksum bad.  */
423                   break;
424                 }
425               gcry_mpi_release (skey[i]);
426               skey[i] = tmpmpi;
427               ndata -= nbytes;
428               p += nbytes;
429             }
430           skey[i] = NULL;
431           skeylen = i;
432           assert (skeylen <= skeysize);
433
434           /* Note: at this point NDATA should be 2 for a simple
435              checksum or 20 for the sha1 digest.  */
436         }
437       xfree(data);
438     }
439   else /* Packet version <= 3.  */
440     {
441       unsigned char *buffer;
442
443       for (i = npkey; i < nskey; i++)
444         {
445           unsigned char *p;
446           size_t ndata;
447           unsigned int ndatabits;
448
449           if (!skey[i] || !gcry_mpi_get_flag (skey[i], GCRYMPI_FLAG_OPAQUE))
450             {
451               gcry_cipher_close (cipher_hd);
452               return gpg_error (GPG_ERR_BAD_SECKEY);
453             }
454           p = gcry_mpi_get_opaque (skey[i], &ndatabits);
455           ndata = (ndatabits+7)/8;
456
457           if (!(ndata >= 2) || !(ndata == ((p[0] << 8 | p[1]) + 7)/8 + 2))
458             {
459               gcry_cipher_close (cipher_hd);
460               return gpg_error (GPG_ERR_BAD_SECKEY);
461             }
462
463           buffer = xtrymalloc_secure (ndata);
464           if (!buffer)
465             {
466               err = gpg_error_from_syserror ();
467               gcry_cipher_close (cipher_hd);
468               return err;
469             }
470
471           gcry_cipher_sync (cipher_hd);
472           buffer[0] = p[0];
473           buffer[1] = p[1];
474           gcry_cipher_decrypt (cipher_hd, buffer+2, ndata-2, p+2, ndata-2);
475           actual_csum += checksum (buffer, ndata);
476           err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_PGP, buffer, ndata, &ndata);
477           xfree (buffer);
478           if (err)
479             {
480               /* Checksum was okay, but not correctly decrypted.  */
481               desired_csum = 0;
482               actual_csum = 1;   /* Mark checksum bad.  */
483               break;
484             }
485           gcry_mpi_release (skey[i]);
486           skey[i] = tmpmpi;
487         }
488     }
489   gcry_cipher_close (cipher_hd);
490
491   /* Now let's see whether we have used the correct passphrase. */
492   if (actual_csum != desired_csum)
493     return gpg_error (GPG_ERR_BAD_PASSPHRASE);
494
495   if (nskey != skeylen)
496     err = gpg_error (GPG_ERR_BAD_SECKEY);
497   else
498     err = convert_secret_key (r_key, pubkey_algo, skey);
499   if (err)
500     return err;
501
502   /* The checksum may fail, thus we also check the key itself.  */
503   err = gcry_pk_testkey (*r_key);
504   if (err)
505     {
506       gcry_sexp_release (*r_key);
507       *r_key = NULL;
508       return gpg_error (GPG_ERR_BAD_PASSPHRASE);
509     }
510
511   return 0;
512 }
513
514
515 /* Callback function to try the unprotection from the passpharse query
516    code.  */
517 static int
518 try_do_unprotect_cb (struct pin_entry_info_s *pi)
519 {
520   gpg_error_t err;
521   struct try_do_unprotect_arg_s *arg = pi->check_cb_arg;
522
523   err = do_unprotect (pi->pin,
524                       arg->is_v4? 4:3,
525                       arg->pubkey_algo, arg->is_protected,
526                       arg->skey, arg->skeysize,
527                       arg->protect_algo, arg->iv, arg->ivlen,
528                       arg->s2k_mode, arg->s2k_algo,
529                       arg->s2k_salt, arg->s2k_count,
530                       arg->desired_csum, arg->r_key);
531   /* SKEY may be modified now, thus we need to re-compute SKEYIDX.  */
532   for (arg->skeyidx = 0; (arg->skeyidx < arg->skeysize
533                           && arg->skey[arg->skeyidx]); arg->skeyidx++)
534     ;
535   return err;
536 }
537
538
539 /* Convert an OpenPGP transfer key into our internal format.  Before
540    asking for a passphrase we check whether the key already exists in
541    our key storage.  S_PGP is the OpenPGP key in transfer format.  If
542    CACHE_NONCE is given the passphrase will be looked up in the cache.
543    On success R_KEY will receive a canonical encoded S-expression with
544    the unprotected key in our internal format; the caller needs to
545    release that memory.  The passphrase used to decrypt the OpenPGP
546    key will be returned at R_PASSPHRASE; the caller must release this
547    passphrase.  The keygrip will be stored at the 20 byte buffer
548    pointed to by GRIP.  On error NULL is stored at all return
549    arguments.  */
550 gpg_error_t
551 convert_from_openpgp (ctrl_t ctrl, gcry_sexp_t s_pgp,
552                       unsigned char *grip, const char *prompt,
553                       const char *cache_nonce,
554                       unsigned char **r_key, char **r_passphrase)
555 {
556   gpg_error_t err;
557   gcry_sexp_t top_list;
558   gcry_sexp_t list = NULL;
559   const char *value;
560   size_t valuelen;
561   char *string;
562   int  idx;
563   int  is_v4, is_protected;
564   int  pubkey_algo;
565   int  protect_algo = 0;
566   char iv[16];
567   int  ivlen = 0;
568   int  s2k_mode = 0;
569   int  s2k_algo = 0;
570   byte s2k_salt[8];
571   u32  s2k_count = 0;
572   size_t npkey, nskey;
573   gcry_mpi_t skey[10];  /* We support up to 9 parameters.  */
574   u16 desired_csum;
575   int skeyidx = 0;
576   gcry_sexp_t s_skey;
577   struct pin_entry_info_s *pi;
578   struct try_do_unprotect_arg_s pi_arg;
579
580   *r_key = NULL;
581   *r_passphrase = NULL;
582
583   top_list = gcry_sexp_find_token (s_pgp, "openpgp-private-key", 0);
584   if (!top_list)
585     goto bad_seckey;
586
587   list = gcry_sexp_find_token (top_list, "version", 0);
588   if (!list)
589     goto bad_seckey;
590   value = gcry_sexp_nth_data (list, 1, &valuelen);
591   if (!value || valuelen != 1 || !(value[0] == '3' || value[0] == '4'))
592     goto bad_seckey;
593   is_v4 = (value[0] == '4');
594
595   gcry_sexp_release (list);
596   list = gcry_sexp_find_token (top_list, "protection", 0);
597   if (!list)
598     goto bad_seckey;
599   value = gcry_sexp_nth_data (list, 1, &valuelen);
600   if (!value)
601     goto bad_seckey;
602   if (valuelen == 4 && !memcmp (value, "sha1", 4))
603     is_protected = 2;
604   else if (valuelen == 3 && !memcmp (value, "sum", 3))
605     is_protected = 1;
606   else if (valuelen == 4 && !memcmp (value, "none", 4))
607     is_protected = 0;
608   else
609     goto bad_seckey;
610   if (is_protected)
611     {
612       string = gcry_sexp_nth_string (list, 2);
613       if (!string)
614         goto bad_seckey;
615       protect_algo = gcry_cipher_map_name (string);
616       if (!protect_algo && !!strcmp (string, "IDEA"))
617         protect_algo = GCRY_CIPHER_IDEA;
618       xfree (string);
619
620       value = gcry_sexp_nth_data (list, 3, &valuelen);
621       if (!value || !valuelen || valuelen > sizeof iv)
622         goto bad_seckey;
623       memcpy (iv, value, valuelen);
624       ivlen = valuelen;
625
626       string = gcry_sexp_nth_string (list, 4);
627       if (!string)
628         goto bad_seckey;
629       s2k_mode = strtol (string, NULL, 10);
630       xfree (string);
631
632       string = gcry_sexp_nth_string (list, 5);
633       if (!string)
634         goto bad_seckey;
635       s2k_algo = gcry_md_map_name (string);
636       xfree (string);
637
638       value = gcry_sexp_nth_data (list, 6, &valuelen);
639       if (!value || !valuelen || valuelen > sizeof s2k_salt)
640         goto bad_seckey;
641       memcpy (s2k_salt, value, valuelen);
642
643       string = gcry_sexp_nth_string (list, 7);
644       if (!string)
645         goto bad_seckey;
646       s2k_count = strtoul (string, NULL, 10);
647       xfree (string);
648     }
649
650   gcry_sexp_release (list);
651   list = gcry_sexp_find_token (top_list, "algo", 0);
652   if (!list)
653     goto bad_seckey;
654   string = gcry_sexp_nth_string (list, 1);
655   if (!string)
656     goto bad_seckey;
657   pubkey_algo = gcry_pk_map_name (string);
658   xfree (string);
659
660   if (gcry_pk_algo_info (pubkey_algo, GCRYCTL_GET_ALGO_NPKEY, NULL, &npkey)
661       || gcry_pk_algo_info (pubkey_algo, GCRYCTL_GET_ALGO_NSKEY, NULL, &nskey)
662       || !npkey || npkey >= nskey)
663     goto bad_seckey;
664
665   gcry_sexp_release (list);
666   list = gcry_sexp_find_token (top_list, "skey", 0);
667   if (!list)
668     goto bad_seckey;
669   for (idx=0;;)
670     {
671       int is_enc;
672
673       value = gcry_sexp_nth_data (list, ++idx, &valuelen);
674       if (!value && skeyidx >= npkey)
675         break;  /* Ready.  */
676
677       /* Check for too many parameters.  Note that depending on the
678          protection mode and version number we may see less than NSKEY
679          (but at least NPKEY+1) parameters.  */
680       if (idx >= 2*nskey)
681         goto bad_seckey;
682       if (skeyidx >= DIM (skey)-1)
683         goto bad_seckey;
684
685       if (!value || valuelen != 1 || !(value[0] == '_' || value[0] == 'e'))
686         goto bad_seckey;
687       is_enc = (value[0] == 'e');
688       value = gcry_sexp_nth_data (list, ++idx, &valuelen);
689       if (!value || !valuelen)
690         goto bad_seckey;
691       if (is_enc)
692         {
693           void *p = xtrymalloc (valuelen);
694           if (!p)
695             goto outofmem;
696           memcpy (p, value, valuelen);
697           skey[skeyidx] = gcry_mpi_set_opaque (NULL, p, valuelen*8);
698           if (!skey[skeyidx])
699             goto outofmem;
700         }
701       else
702         {
703           if (gcry_mpi_scan (skey + skeyidx, GCRYMPI_FMT_STD,
704                              value, valuelen, NULL))
705             goto bad_seckey;
706         }
707       skeyidx++;
708     }
709   skey[skeyidx++] = NULL;
710
711   gcry_sexp_release (list);
712   list = gcry_sexp_find_token (top_list, "csum", 0);
713   if (list)
714     {
715       string = gcry_sexp_nth_string (list, 1);
716       if (!string)
717         goto bad_seckey;
718       desired_csum = strtoul (string, NULL, 10);
719       xfree (string);
720     }
721   else
722     desired_csum = 0;
723
724
725   gcry_sexp_release (list); list = NULL;
726   gcry_sexp_release (top_list); top_list = NULL;
727
728   /* log_debug ("XXX is_v4=%d\n", is_v4); */
729   /* log_debug ("XXX pubkey_algo=%d\n", pubkey_algo); */
730   /* log_debug ("XXX is_protected=%d\n", is_protected); */
731   /* log_debug ("XXX protect_algo=%d\n", protect_algo); */
732   /* log_printhex ("XXX iv", iv, ivlen); */
733   /* log_debug ("XXX ivlen=%d\n", ivlen); */
734   /* log_debug ("XXX s2k_mode=%d\n", s2k_mode); */
735   /* log_debug ("XXX s2k_algo=%d\n", s2k_algo); */
736   /* log_printhex ("XXX s2k_salt", s2k_salt, sizeof s2k_salt); */
737   /* log_debug ("XXX s2k_count=%lu\n", (unsigned long)s2k_count); */
738   /* for (idx=0; skey[idx]; idx++) */
739   /*   { */
740   /*     int is_enc = gcry_mpi_get_flag (skey[idx], GCRYMPI_FLAG_OPAQUE); */
741   /*     log_info ("XXX skey[%d]%s:", idx, is_enc? " (enc)":""); */
742   /*     if (is_enc) */
743   /*       { */
744   /*         void *p; */
745   /*         unsigned int nbits; */
746   /*         p = gcry_mpi_get_opaque (skey[idx], &nbits); */
747   /*         log_printhex (NULL, p, (nbits+7)/8); */
748   /*       } */
749   /*     else */
750   /*       gcry_mpi_dump (skey[idx]); */
751   /*     log_printf ("\n"); */
752   /*   } */
753
754   err = get_keygrip (pubkey_algo, skey, grip);
755   if (err)
756     goto leave;
757
758   if (!agent_key_available (grip))
759     {
760       err = gpg_error (GPG_ERR_EEXIST);
761       goto leave;
762     }
763
764   pi = xtrycalloc_secure (1, sizeof (*pi) + 100);
765   if (!pi)
766     return gpg_error_from_syserror ();
767   pi->max_length = 100;
768   pi->min_digits = 0;  /* We want a real passphrase.  */
769   pi->max_digits = 16;
770   pi->max_tries = 3;
771   pi->check_cb = try_do_unprotect_cb;
772   pi->check_cb_arg = &pi_arg;
773   pi_arg.is_v4 = is_v4;
774   pi_arg.is_protected = is_protected;
775   pi_arg.pubkey_algo = pubkey_algo;
776   pi_arg.protect_algo = protect_algo;
777   pi_arg.iv = iv;
778   pi_arg.ivlen = ivlen;
779   pi_arg.s2k_mode = s2k_mode;
780   pi_arg.s2k_algo = s2k_algo;
781   pi_arg.s2k_salt = s2k_salt;
782   pi_arg.s2k_count = s2k_count;
783   pi_arg.desired_csum = desired_csum;
784   pi_arg.skey = skey;
785   pi_arg.skeysize = DIM (skey);
786   pi_arg.skeyidx = skeyidx;
787   pi_arg.r_key = &s_skey;
788
789   err = gpg_error (GPG_ERR_BAD_PASSPHRASE);
790   if (cache_nonce)
791     {
792       char *cache_value;
793
794       cache_value = agent_get_cache (cache_nonce, CACHE_MODE_NONCE);
795       if (cache_value)
796         {
797           if (strlen (cache_value) < pi->max_length)
798             strcpy (pi->pin, cache_value);
799           xfree (cache_value);
800         }
801       if (*pi->pin)
802         err = try_do_unprotect_cb (pi);
803     }
804   if (gpg_err_code (err) == GPG_ERR_BAD_PASSPHRASE)
805     err = agent_askpin (ctrl, prompt, NULL, NULL, pi);
806   skeyidx = pi_arg.skeyidx;
807   if (!err)
808     {
809       *r_passphrase = xtrystrdup (pi->pin);
810       if (!*r_passphrase)
811         err = gpg_error_from_syserror ();
812     }
813   xfree (pi);
814   if (err)
815     goto leave;
816
817   /* Save some memory and get rid of the SKEY array now.  */
818   for (idx=0; idx < skeyidx; idx++)
819     gcry_mpi_release (skey[idx]);
820   skeyidx = 0;
821
822   /* Note that the padding is not required - we use it only because
823      that function allows us to created the result in secure memory.  */
824   err = make_canon_sexp_pad (s_skey, 1, r_key, NULL);
825   gcry_sexp_release (s_skey);
826
827  leave:
828   gcry_sexp_release (list);
829   gcry_sexp_release (top_list);
830   for (idx=0; idx < skeyidx; idx++)
831     gcry_mpi_release (skey[idx]);
832   if (err)
833     {
834       xfree (*r_passphrase);
835       *r_passphrase = NULL;
836     }
837   return err;
838
839  bad_seckey:
840   err = gpg_error (GPG_ERR_BAD_SECKEY);
841   goto leave;
842
843  outofmem:
844   err = gpg_error (GPG_ERR_ENOMEM);
845   goto leave;
846
847 }
848
849
850 \f
851 static gpg_error_t
852 key_from_sexp (gcry_sexp_t sexp, const char *elems, gcry_mpi_t *array)
853 {
854   gpg_error_t err = 0;
855   gcry_sexp_t l2;
856   int idx;
857
858   for (idx=0; *elems; elems++, idx++)
859     {
860       l2 = gcry_sexp_find_token (sexp, elems, 1);
861       if (!l2)
862         {
863           err = gpg_error (GPG_ERR_NO_OBJ); /* Required parameter not found.  */
864           goto leave;
865         }
866       array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
867       gcry_sexp_release (l2);
868       if (!array[idx])
869         {
870           err = gpg_error (GPG_ERR_INV_OBJ); /* Required parameter invalid.  */
871           goto leave;
872         }
873     }
874
875  leave:
876   if (err)
877     {
878       int i;
879
880       for (i=0; i < idx; i++)
881         {
882           gcry_mpi_release (array[i]);
883           array[i] = NULL;
884         }
885     }
886   return err;
887 }
888
889
890 /* Given an ARRAY of mpis with the key parameters, protect the secret
891    parameters in that array and replace them by one opaque encoded
892    mpi.  NPKEY is the number of public key parameters and NSKEY is
893    the number of secret key parameters (including the public ones).
894    On success the array will have NPKEY+1 elements.  */
895 static gpg_error_t
896 apply_protection (gcry_mpi_t *array, int npkey, int nskey,
897                   const char *passphrase,
898                   int protect_algo, void *protect_iv, size_t protect_ivlen,
899                   int s2k_mode, int s2k_algo, byte *s2k_salt, u32 s2k_count)
900 {
901   gpg_error_t err;
902   int i, j;
903   gcry_cipher_hd_t cipherhd;
904   unsigned char *bufarr[10];
905   size_t narr[10];
906   unsigned int nbits[10];
907   int ndata;
908   unsigned char *p, *data;
909
910   assert (npkey < nskey);
911   assert (nskey < DIM (bufarr));
912
913   /* Collect only the secret key parameters into BUFARR et al and
914      compute the required size of the data buffer.  */
915   ndata = 20; /* Space for the SHA-1 checksum.  */
916   for (i = npkey, j = 0; i < nskey; i++, j++ )
917     {
918       err = gcry_mpi_aprint (GCRYMPI_FMT_USG, bufarr+j, narr+j, array[i]);
919       if (err)
920         {
921           err = gpg_error_from_syserror ();
922           for (i = 0; i < j; i++)
923             xfree (bufarr[i]);
924           return err;
925         }
926       nbits[j] = gcry_mpi_get_nbits (array[i]);
927       ndata += 2 + narr[j];
928     }
929
930   /* Allocate data buffer and stuff it with the secret key parameters.  */
931   data = xtrymalloc_secure (ndata);
932   if (!data)
933     {
934       err = gpg_error_from_syserror ();
935       for (i = 0; i < (nskey-npkey); i++ )
936         xfree (bufarr[i]);
937       return err;
938     }
939   p = data;
940   for (i = 0; i < (nskey-npkey); i++ )
941     {
942       *p++ = nbits[i] >> 8 ;
943       *p++ = nbits[i];
944       memcpy (p, bufarr[i], narr[i]);
945       p += narr[i];
946       xfree (bufarr[i]);
947       bufarr[i] = NULL;
948     }
949   assert (p == data + ndata - 20);
950
951   /* Append a hash of the secret key parameters.  */
952   gcry_md_hash_buffer (GCRY_MD_SHA1, p, data, ndata - 20);
953
954   /* Encrypt it.  */
955   err = gcry_cipher_open (&cipherhd, protect_algo,
956                           GCRY_CIPHER_MODE_CFB, GCRY_CIPHER_SECURE);
957   if (!err)
958     err = hash_passphrase_and_set_key (passphrase, cipherhd, protect_algo,
959                                        s2k_mode, s2k_algo, s2k_salt, s2k_count);
960   if (!err)
961     err = gcry_cipher_setiv (cipherhd, protect_iv, protect_ivlen);
962   if (!err)
963     err = gcry_cipher_encrypt (cipherhd, data, ndata, NULL, 0);
964   gcry_cipher_close (cipherhd);
965   if (err)
966     {
967       xfree (data);
968       return err;
969     }
970
971   /* Replace the secret key parameters in the array by one opaque value.  */
972   for (i = npkey; i < nskey; i++ )
973     {
974       gcry_mpi_release (array[i]);
975       array[i] = NULL;
976     }
977   array[npkey] = gcry_mpi_set_opaque (NULL, data, ndata*8);
978   return 0;
979 }
980
981
982 /* Convert our key S_KEY into an OpenPGP key transfer format.  On
983    success a canonical encoded S-expression is stored at R_TRANSFERKEY
984    and its length at R_TRANSFERKEYLEN; this S-expression is also
985    padded to a multiple of 64 bits.  */
986 gpg_error_t
987 convert_to_openpgp (ctrl_t ctrl, gcry_sexp_t s_key, const char *passphrase,
988                     unsigned char **r_transferkey, size_t *r_transferkeylen)
989 {
990   gpg_error_t err;
991   gcry_sexp_t list, l2;
992   char *name;
993   int algo;
994   const char *algoname;
995   const char *elems;
996   int npkey, nskey;
997   gcry_mpi_t array[10];
998   char protect_iv[16];
999   char salt[8];
1000   unsigned long s2k_count;
1001   int i, j;
1002
1003   (void)ctrl;
1004
1005   *r_transferkey = NULL;
1006
1007   for (i=0; i < DIM (array); i++)
1008     array[i] = NULL;
1009
1010   list = gcry_sexp_find_token (s_key, "private-key", 0);
1011   if (!list)
1012     return gpg_error (GPG_ERR_NO_OBJ); /* Does not contain a key object.  */
1013   l2 = gcry_sexp_cadr (list);
1014   gcry_sexp_release (list);
1015   list = l2;
1016   name = gcry_sexp_nth_string (list, 0);
1017   if (!name)
1018     {
1019       gcry_sexp_release (list);
1020       return gpg_error (GPG_ERR_INV_OBJ); /* Invalid structure of object. */
1021     }
1022
1023   algo = gcry_pk_map_name (name);
1024   xfree (name);
1025
1026   switch (algo)
1027     {
1028     case GCRY_PK_RSA:   algoname = "rsa";   npkey = 2; elems = "nedpqu";  break;
1029     case GCRY_PK_ELG:   algoname = "elg";   npkey = 3; elems = "pgyx";    break;
1030     case GCRY_PK_ELG_E: algoname = "elg";   npkey = 3; elems = "pgyx";    break;
1031     case GCRY_PK_DSA:   algoname = "dsa";   npkey = 4; elems = "pqgyx";   break;
1032     case GCRY_PK_ECDSA: algoname = "ecdsa"; npkey = 6; elems = "pabgnqd"; break;
1033     case GCRY_PK_ECDH:  algoname = "ecdh";  npkey = 6; elems = "pabgnqd"; break;
1034     default:            algoname = "";      npkey = 0; elems = NULL;      break;
1035     }
1036   assert (!elems || strlen (elems) < DIM (array) );
1037   nskey = elems? strlen (elems) : 0;
1038
1039   if (!elems)
1040     err = gpg_error (GPG_ERR_PUBKEY_ALGO);
1041   else
1042     err = key_from_sexp (list, elems, array);
1043   gcry_sexp_release (list);
1044   if (err)
1045     return err;
1046
1047   gcry_create_nonce (protect_iv, sizeof protect_iv);
1048   gcry_create_nonce (salt, sizeof salt);
1049   /* We need to use the encoded S2k count.  It is not possible to
1050      encode it after it has been used because the encoding procedure
1051      may round the value up.  */
1052   s2k_count = get_standard_s2k_count_rfc4880 ();
1053   err = apply_protection (array, npkey, nskey, passphrase,
1054                           GCRY_CIPHER_AES, protect_iv, sizeof protect_iv,
1055                           3, GCRY_MD_SHA1, salt, s2k_count);
1056   /* Turn it into the transfer key S-expression.  Note that we always
1057      return a protected key.  */
1058   if (!err)
1059     {
1060       char countbuf[35];
1061       membuf_t mbuf;
1062       void *format_args_buf_ptr[1];
1063       int   format_args_buf_int[1];
1064       void *format_args[10+2];
1065       unsigned int n;
1066       gcry_sexp_t tmpkey, tmpsexp = NULL;
1067
1068       snprintf (countbuf, sizeof countbuf, "%lu", s2k_count);
1069
1070       init_membuf (&mbuf, 50);
1071       put_membuf_str (&mbuf, "(skey");
1072       for (i=j=0; i < npkey; i++)
1073         {
1074           put_membuf_str (&mbuf, " _ %m");
1075           format_args[j++] = array + i;
1076         }
1077       put_membuf_str (&mbuf, " e %b");
1078       format_args_buf_ptr[0] = gcry_mpi_get_opaque (array[npkey], &n);
1079       format_args_buf_int[0] = (n+7)/8;
1080       format_args[j++] = format_args_buf_int;
1081       format_args[j++] = format_args_buf_ptr;
1082       put_membuf_str (&mbuf, ")\n");
1083       put_membuf (&mbuf, "", 1);
1084
1085       tmpkey = NULL;
1086       {
1087         char *format = get_membuf (&mbuf, NULL);
1088         if (!format)
1089           err = gpg_error_from_syserror ();
1090         else
1091           err = gcry_sexp_build_array (&tmpkey, NULL, format, format_args);
1092         xfree (format);
1093       }
1094       if (!err)
1095         err = gcry_sexp_build (&tmpsexp, NULL,
1096                                "(openpgp-private-key\n"
1097                                " (version 1:4)\n"
1098                                " (algo %s)\n"
1099                                " %S\n"
1100                                " (protection sha1 aes %b 1:3 sha1 %b %s))\n",
1101                                algoname,
1102                                tmpkey,
1103                                (int)sizeof protect_iv, protect_iv,
1104                                (int)sizeof salt, salt,
1105                                countbuf);
1106       gcry_sexp_release (tmpkey);
1107       if (!err)
1108         err = make_canon_sexp_pad (tmpsexp, 0, r_transferkey, r_transferkeylen);
1109       gcry_sexp_release (tmpsexp);
1110     }
1111
1112   for (i=0; i < DIM (array); i++)
1113     gcry_mpi_release (array[i]);
1114
1115   return err;
1116 }