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