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