Import OpenPGP keys into the agent.
[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     default:
84       err = gpg_error (GPG_ERR_PUBKEY_ALGO);
85       break;
86     }
87
88   if (!err && !gcry_pk_get_keygrip (s_pkey, grip))
89     err = gpg_error (GPG_ERR_INTERNAL);
90
91   gcry_sexp_release (s_pkey);
92   return err;
93 }
94
95
96 /* Convert a secret key given as algorithm id and an array of key
97    parameters into our s-expression based format.  */
98 static gpg_error_t
99 convert_secret_key (gcry_sexp_t *r_key, int pubkey_algo, gcry_mpi_t *skey)
100 {
101   gpg_error_t err;
102   gcry_sexp_t s_skey = NULL;
103
104   *r_key = NULL;
105
106   switch (pubkey_algo)
107     {
108     case GCRY_PK_DSA:
109       err = gcry_sexp_build (&s_skey, NULL,
110                              "(private-key(dsa(p%m)(q%m)(g%m)(y%m)(x%m)))",
111                              skey[0], skey[1], skey[2], skey[3], skey[4]);
112       break;
113
114     case GCRY_PK_ELG:
115     case GCRY_PK_ELG_E:
116       err = gcry_sexp_build (&s_skey, NULL,
117                              "(private-key(elg(p%m)(g%m)(y%m)(x%m)))",
118                              skey[0], skey[1], skey[2], skey[3]);
119       break;
120
121
122     case GCRY_PK_RSA:
123     case GCRY_PK_RSA_E:
124     case GCRY_PK_RSA_S:
125       err = gcry_sexp_build (&s_skey, NULL,
126                              "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))",
127                              skey[0], skey[1], skey[2], skey[3], skey[4],
128                              skey[5]);
129
130     default:
131       err = gpg_error (GPG_ERR_PUBKEY_ALGO);
132       break;
133     }
134
135   if (!err)
136     *r_key = s_skey;
137   return err;
138 }
139
140
141
142 /* Hash the passphrase and set the key. */
143 static gpg_error_t
144 hash_passphrase_and_set_key (const char *passphrase,
145                              gcry_cipher_hd_t hd, int protect_algo,
146                              int s2k_mode, int s2k_algo,
147                              byte *s2k_salt, u32 s2k_count)
148 {
149   gpg_error_t err;
150   unsigned char *key;
151   size_t keylen;
152
153   keylen = gcry_cipher_get_algo_keylen (protect_algo);
154   if (!keylen)
155     return gpg_error (GPG_ERR_INTERNAL);
156   
157   key = xtrymalloc_secure (keylen);
158   if (!key)
159     return gpg_error_from_syserror ();
160
161   err = s2k_hash_passphrase (passphrase,
162                              s2k_algo, s2k_mode, s2k_salt, s2k_count,
163                              key, keylen);
164   if (!err)
165     err = gcry_cipher_setkey (hd, key, keylen);
166
167   xfree (key);
168   return err;
169 }
170
171
172 static u16
173 checksum (const unsigned char *p, unsigned int n)
174 {
175   u16 a;
176   
177   for (a=0; n; n-- )
178     a += *p++;
179   return a;
180 }
181
182
183 /* Note that this function modified SKEY.  SKEYSIZE is the allocated
184    size of the array including the NULL item; this is used for a
185    bounds check.  On success a converted key is stored at R_KEY.  */
186 static int
187 do_unprotect (const char *passphrase,
188               int pkt_version, int pubkey_algo, int is_protected,
189               gcry_mpi_t *skey, size_t skeysize,
190               int protect_algo, void *protect_iv, size_t protect_ivlen,
191               int s2k_mode, int s2k_algo, byte *s2k_salt, u32 s2k_count,
192               u16 desired_csum, gcry_sexp_t *r_key)
193 {
194   gpg_error_t err;
195   size_t npkey, nskey, skeylen;
196   gcry_cipher_hd_t cipher_hd = NULL;
197   u16 actual_csum;
198   size_t nbytes;
199   int i;
200   gcry_mpi_t tmpmpi;
201
202   *r_key = NULL;
203
204   /* Count the actual number of MPIs is in the array and set the
205      remainder to NULL for easier processing later on.  */
206   for (skeylen = 0; skey[skeylen]; skeylen++)
207     ;
208   for (i=skeylen; i < skeysize; i++)
209     skey[i] = NULL;
210
211   /* Check some args.  */
212   if (s2k_mode == 1001)
213     {
214       /* Stub key.  */
215       log_info (_("secret key parts are not available\n"));
216       return gpg_error (GPG_ERR_UNUSABLE_SECKEY);
217     }
218
219   if (gcry_pk_test_algo (pubkey_algo))
220     {
221       /* The algorithm numbers are Libgcrypt numbers but fortunately
222          the OpenPGP algorithm numbers map one-to-one to the Libgcrypt
223          numbers.  */
224       log_info (_("public key algorithm %d (%s) is not supported\n"),
225                 pubkey_algo, gcry_pk_algo_name (pubkey_algo));
226       return gpg_error (GPG_ERR_PUBKEY_ALGO);
227     }
228
229   /* Get properties of the public key algorithm and do some
230      consistency checks.  Note that we need at least NPKEY+1 elements
231      in the SKEY array. */
232   if ( (err = gcry_pk_algo_info (pubkey_algo, GCRYCTL_GET_ALGO_NPKEY,
233                                  NULL, &npkey))
234        || (err = gcry_pk_algo_info (pubkey_algo, GCRYCTL_GET_ALGO_NSKEY,
235                                     NULL, &nskey)))
236     return err;
237   if (!npkey || npkey >= nskey)
238     return gpg_error (GPG_ERR_INTERNAL);
239   if (skeylen <= npkey)
240     return gpg_error (GPG_ERR_MISSING_VALUE);
241   if (nskey+1 >= skeysize)
242     return gpg_error (GPG_ERR_BUFFER_TOO_SHORT);
243   
244   /* Check whether SKEY is at all protected.  If it is not protected
245      merely verify the checksum.  */
246   if (!is_protected)
247     {
248       unsigned char *buffer;
249
250       actual_csum = 0;
251       for (i=npkey; i < nskey; i++)
252         {
253           if (!skey[i] || gcry_mpi_get_flag (skey[i], GCRYMPI_FLAG_OPAQUE))
254             return gpg_error (GPG_ERR_BAD_SECKEY);
255           
256           err = gcry_mpi_print (GCRYMPI_FMT_PGP, NULL, 0, &nbytes, skey[i]);
257           if (!err)
258             {
259               buffer = (gcry_is_secure (skey[i])?
260                         xtrymalloc_secure (nbytes) : xtrymalloc (nbytes));
261               if (!buffer)
262                 return gpg_error_from_syserror ();
263               err = gcry_mpi_print (GCRYMPI_FMT_PGP, buffer, nbytes,
264                                     NULL, skey[i]);
265               if (!err)
266                 actual_csum += checksum (buffer, nbytes);
267               xfree (buffer);
268             }
269           if (err)
270             return err;
271         }
272       
273       if (actual_csum != desired_csum)
274         return gpg_error (GPG_ERR_CHECKSUM);
275       return 0;
276     }
277
278
279   if (gcry_cipher_test_algo (protect_algo))
280     {
281       /* The algorithm numbers are Libgcrypt numbers but fortunately
282          the OpenPGP algorithm numbers map one-to-one to the Libgcrypt
283          numbers.  */
284       log_info (_("protection algorithm %d (%s) is not supported\n"),
285                 protect_algo, gcry_cipher_algo_name (protect_algo));
286       return gpg_error (GPG_ERR_CIPHER_ALGO);
287     }
288
289   if (gcry_md_test_algo (s2k_algo))
290     {
291       log_info (_("protection hash algorithm %d (%s) is not supported\n"),
292                 s2k_algo, gcry_md_algo_name (s2k_algo));
293       return gpg_error (GPG_ERR_DIGEST_ALGO);
294     }
295   
296   err = gcry_cipher_open (&cipher_hd, protect_algo,
297                           GCRY_CIPHER_MODE_CFB,
298                           (GCRY_CIPHER_SECURE
299                            | (protect_algo >= 100 ?
300                               0 : GCRY_CIPHER_ENABLE_SYNC)));
301   if (err)
302     {
303       log_error ("failed to open cipher_algo %d: %s\n",
304                  protect_algo, gpg_strerror (err));
305       return err;
306     }
307
308   err = hash_passphrase_and_set_key (passphrase, cipher_hd, protect_algo,
309                                      s2k_mode, s2k_algo, s2k_salt, s2k_count);
310   if (err)
311     {
312       gcry_cipher_close (cipher_hd);
313       return err;
314     }  
315
316   gcry_cipher_setiv (cipher_hd, protect_iv, protect_ivlen);
317   
318   actual_csum = 0;
319   if (pkt_version >= 4)
320     {
321       int ndata;
322       unsigned int ndatabits;
323       unsigned char *p, *data;
324       u16 csum_pgp7 = 0;
325
326       if (!gcry_mpi_get_flag (skey[npkey], GCRYMPI_FLAG_OPAQUE ))
327         {
328           gcry_cipher_close (cipher_hd);
329           return gpg_error (GPG_ERR_BAD_SECKEY);
330         }
331       p = gcry_mpi_get_opaque (skey[npkey], &ndatabits);
332       ndata = (ndatabits+7)/8;
333
334       if (ndata > 1)
335         csum_pgp7 = p[ndata-2] << 8 | p[ndata-1];
336       data = xtrymalloc_secure (ndata);
337       if (!data)
338         {
339           err = gpg_error_from_syserror ();
340           gcry_cipher_close (cipher_hd);
341           return err;
342         }
343       gcry_cipher_decrypt (cipher_hd, data, ndata, p, ndata);
344
345       p = data;
346       if (is_protected == 2)
347         {
348           /* This is the new SHA1 checksum method to detect tampering
349              with the key as used by the Klima/Rosa attack.  */
350           desired_csum = 0; 
351           actual_csum = 1;  /* Default to bad checksum.  */
352
353           if (ndata < 20) 
354             log_error ("not enough bytes for SHA-1 checksum\n");
355           else 
356             {
357               gcry_md_hd_t h;
358               
359               if (gcry_md_open (&h, GCRY_MD_SHA1, 1))
360                 BUG(); /* Algo not available. */
361               gcry_md_write (h, data, ndata - 20);
362               gcry_md_final (h);
363               if (!memcmp (gcry_md_read (h, GCRY_MD_SHA1), data+ndata-20, 20))
364                 actual_csum = 0; /* Digest does match.  */
365               gcry_md_close (h);
366             }
367         }
368       else 
369         {
370           /* Old 16 bit checksum method.  */
371           if (ndata < 2)
372             {
373               log_error ("not enough bytes for checksum\n");
374               desired_csum = 0; 
375               actual_csum = 1;  /* Mark checksum bad.  */
376             }
377           else
378             {
379               desired_csum = (data[ndata-2] << 8 | data[ndata-1]);
380               actual_csum = checksum (data, ndata-2);
381               if (desired_csum != actual_csum)
382                 {
383                   /* This is a PGP 7.0.0 workaround */
384                   desired_csum = csum_pgp7; /* Take the encrypted one.  */
385                 }
386             }
387         }
388       
389       /* Better check it here.  Otherwise the gcry_mpi_scan would fail
390          because the length may have an arbitrary value.  */
391       if (desired_csum == actual_csum)
392         {
393           for (i=npkey; i < nskey; i++ )
394             {
395               if (gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_PGP, p, ndata, &nbytes))
396                 {
397                   /* Checksum was okay, but not correctly decrypted.  */
398                   desired_csum = 0;
399                   actual_csum = 1;   /* Mark checksum bad.  */
400                   break;
401                 }
402               gcry_mpi_release (skey[i]);
403               skey[i] = tmpmpi;
404               ndata -= nbytes;
405               p += nbytes;
406             }
407           skey[i] = NULL;
408           skeylen = i;
409           assert (skeylen <= skeysize);
410
411           /* Note: at this point NDATA should be 2 for a simple
412              checksum or 20 for the sha1 digest.  */
413         }
414       xfree(data);
415     }
416   else /* Packet version <= 3.  */
417     {
418       unsigned char *buffer;
419
420       for (i = npkey; i < nskey; i++)
421         {
422           unsigned char *p;
423           size_t ndata;
424           unsigned int ndatabits;
425
426           if (!skey[i] || !gcry_mpi_get_flag (skey[i], GCRYMPI_FLAG_OPAQUE))
427             {
428               gcry_cipher_close (cipher_hd);
429               return gpg_error (GPG_ERR_BAD_SECKEY);
430             }
431           p = gcry_mpi_get_opaque (skey[i], &ndatabits);
432           ndata = (ndatabits+7)/8;
433
434           if (!(ndata >= 2) || !(ndata == ((p[0] << 8 | p[1]) + 7)/8 + 2))
435             {
436               gcry_cipher_close (cipher_hd);
437               return gpg_error (GPG_ERR_BAD_SECKEY);
438             }
439           
440           buffer = xtrymalloc_secure (ndata);
441           if (!buffer)
442             {
443               err = gpg_error_from_syserror ();
444               gcry_cipher_close (cipher_hd);
445               return err;
446             }
447               
448           gcry_cipher_sync (cipher_hd);
449           buffer[0] = p[0];
450           buffer[1] = p[1];
451           gcry_cipher_decrypt (cipher_hd, buffer+2, ndata-2, p+2, ndata-2);
452           actual_csum += checksum (buffer, ndata);
453           err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_PGP, buffer, ndata, &ndata);
454           xfree (buffer);
455           if (err)
456             {
457               /* Checksum was okay, but not correctly decrypted.  */
458               desired_csum = 0;
459               actual_csum = 1;   /* Mark checksum bad.  */
460               break;
461             }
462           gcry_mpi_release (skey[i]);
463           skey[i] = tmpmpi;
464         }
465     }
466   gcry_cipher_close (cipher_hd);
467
468   /* Now let's see whether we have used the correct passphrase. */
469   if (actual_csum != desired_csum)
470     return gpg_error (GPG_ERR_BAD_PASSPHRASE);
471
472   if (nskey != skeylen)
473     err = gpg_error (GPG_ERR_BAD_SECKEY);
474   else
475     err = convert_secret_key (r_key, pubkey_algo, skey);
476   if (err)
477     return err;
478
479   /* The checksum may fail, thus we also check the key itself.  */
480   err = gcry_pk_testkey (*r_key);
481   if (err)
482     {
483       gcry_sexp_release (*r_key);
484       *r_key = NULL;
485       return gpg_error (GPG_ERR_BAD_PASSPHRASE);
486     }
487
488   return 0;
489 }
490
491
492 /* Callback function to try the unprotection from the passpharse query
493    code.  */
494 static int
495 try_do_unprotect_cb (struct pin_entry_info_s *pi)
496 {
497   gpg_error_t err;
498   struct try_do_unprotect_arg_s *arg = pi->check_cb_arg;
499
500   err = do_unprotect (pi->pin, arg->is_v4? 4:3,
501                       arg->pubkey_algo, arg->is_protected,
502                       arg->skey, arg->skeysize,
503                       arg->protect_algo, arg->iv, arg->ivlen,
504                       arg->s2k_mode, arg->s2k_algo,
505                       arg->s2k_salt, arg->s2k_count,
506                       arg->desired_csum, arg->r_key);
507   /* SKEY may be modified now, thus we need to re-compute SKEYIDX.  */
508   for (arg->skeyidx = 0; (arg->skeyidx < arg->skeysize
509                           && arg->skey[arg->skeyidx]); arg->skeyidx++)
510          ;
511   return err;
512 }
513
514
515 /* Convert an OpenPGP transfer key into our internal format.  Before
516    asking for a passphrase we check whether the key already exists in
517    our key storage.  S_PGP is the OpenPGP key in transfer format.  On
518    success R_KEY will receive a canonical encoded S-expression with
519    the unprotected key in our internal format; the caller needs to
520    release that memory.  The passphrase used to decrypt the OpenPGP
521    key will be returned at R_PASSPHRASE; the caller must release this
522    passphrase.  The keygrip will be stored at the 20 byte buffer
523    pointed to by GRIP.  On error NULL is stored at all return
524    arguments.  */
525 gpg_error_t
526 convert_openpgp (ctrl_t ctrl, gcry_sexp_t s_pgp, 
527                  unsigned char *grip, const char *prompt,
528                  unsigned char **r_key, char **r_passphrase)
529 {
530   gpg_error_t err;
531   gcry_sexp_t top_list;
532   gcry_sexp_t list = NULL;
533   const char *value;
534   size_t valuelen;
535   char *string;
536   int  idx;
537   int  is_v4, is_protected;
538   int  pubkey_algo;
539   int  protect_algo = 0;
540   char iv[16];
541   int  ivlen = 0;
542   int  s2k_mode = 0;
543   int  s2k_algo = 0;
544   byte s2k_salt[8];
545   u32  s2k_count = 0;
546   size_t npkey, nskey;
547   gcry_mpi_t skey[10];  /* We support up to 9 parameters.  */
548   u16 desired_csum;
549   int skeyidx = 0;
550   gcry_sexp_t s_skey;
551   struct pin_entry_info_s *pi;
552   struct try_do_unprotect_arg_s pi_arg;
553
554   *r_key = NULL;
555   *r_passphrase = NULL;
556
557   top_list = gcry_sexp_find_token (s_pgp, "openpgp-private-key", 0);
558   if (!top_list)
559     goto bad_seckey;
560
561   list = gcry_sexp_find_token (top_list, "version", 0);
562   if (!list)
563     goto bad_seckey;
564   value = gcry_sexp_nth_data (list, 1, &valuelen);
565   if (!value || valuelen != 1 || !(value[0] == '3' || value[0] == '4'))
566     goto bad_seckey;
567   is_v4 = (value[0] == '4');
568
569   gcry_sexp_release (list);
570   list = gcry_sexp_find_token (top_list, "protection", 0);
571   if (!list)
572     goto bad_seckey;
573   value = gcry_sexp_nth_data (list, 1, &valuelen);
574   if (!value)
575     goto bad_seckey;
576   if (valuelen == 4 && !memcmp (value, "sha1", 4))
577     is_protected = 2;
578   else if (valuelen == 3 && !memcmp (value, "sum", 3))
579     is_protected = 1;
580   else if (valuelen == 4 && !memcmp (value, "none", 4))
581     is_protected = 0;
582   else
583     goto bad_seckey;
584   if (is_protected)
585     {
586       string = gcry_sexp_nth_string (list, 2);
587       if (!string)
588         goto bad_seckey;
589       protect_algo = gcry_cipher_map_name (string);
590       if (!protect_algo && !!strcmp (string, "IDEA"))
591         protect_algo = GCRY_CIPHER_IDEA;
592       xfree (string);
593       
594       value = gcry_sexp_nth_data (list, 3, &valuelen);
595       if (!value || !valuelen || valuelen > sizeof iv)
596         goto bad_seckey;
597       memcpy (iv, value, valuelen);
598       ivlen = valuelen;
599
600       string = gcry_sexp_nth_string (list, 4);
601       if (!string)
602         goto bad_seckey;
603       s2k_mode = strtol (string, NULL, 10);
604       xfree (string);
605
606       string = gcry_sexp_nth_string (list, 5);
607       if (!string)
608         goto bad_seckey;
609       s2k_algo = gcry_md_map_name (string);
610       xfree (string);
611
612       value = gcry_sexp_nth_data (list, 6, &valuelen);
613       if (!value || !valuelen || valuelen > sizeof s2k_salt)
614         goto bad_seckey;
615       memcpy (s2k_salt, value, valuelen);
616
617       string = gcry_sexp_nth_string (list, 7);
618       if (!string)
619         goto bad_seckey;
620       s2k_count = strtoul (string, NULL, 10);
621       xfree (string);
622     }
623
624   gcry_sexp_release (list);
625   list = gcry_sexp_find_token (top_list, "algo", 0);
626   if (!list)
627     goto bad_seckey;
628   string = gcry_sexp_nth_string (list, 1);
629   if (!string)
630     goto bad_seckey;
631   pubkey_algo = gcry_pk_map_name (string);
632   xfree (string);
633
634   if (gcry_pk_algo_info (pubkey_algo, GCRYCTL_GET_ALGO_NPKEY, NULL, &npkey)
635       || gcry_pk_algo_info (pubkey_algo, GCRYCTL_GET_ALGO_NSKEY, NULL, &nskey)
636       || !npkey || npkey >= nskey)
637     goto bad_seckey;
638
639   gcry_sexp_release (list);
640   list = gcry_sexp_find_token (top_list, "skey", 0);
641   if (!list)
642     goto bad_seckey;
643   for (idx=0;;)
644     {
645       int is_enc;
646
647       value = gcry_sexp_nth_data (list, ++idx, &valuelen);
648       if (!value && skeyidx >= npkey)
649         break;  /* Ready.  */
650
651       /* Check for too many parameters.  Note that depending on the
652          protection mode and version number we may see less than NSKEY
653          (but at least NPKEY+1) parameters.  */
654       if (idx >= 2*nskey)
655         goto bad_seckey;
656       if (skeyidx >= DIM (skey)-1)
657         goto bad_seckey;
658
659       if (!value || valuelen != 1 || !(value[0] == '_' || value[0] == 'e'))
660         goto bad_seckey;
661       is_enc = (value[0] == 'e');
662       value = gcry_sexp_nth_data (list, ++idx, &valuelen);
663       if (!value || !valuelen)
664         goto bad_seckey;
665       if (is_enc)
666         {
667           void *p = xtrymalloc (valuelen);
668           if (!p)
669             goto outofmem;
670           memcpy (p, value, valuelen);
671           skey[skeyidx] = gcry_mpi_set_opaque (NULL, p, valuelen*8);
672           if (!skey[skeyidx])
673             goto outofmem;
674         }
675       else
676         {
677           if (gcry_mpi_scan (skey + skeyidx, GCRYMPI_FMT_STD,
678                              value, valuelen, NULL))
679             goto bad_seckey;
680         }
681       skeyidx++;
682     }
683   skey[skeyidx++] = NULL;
684
685   gcry_sexp_release (list);
686   list = gcry_sexp_find_token (top_list, "csum", 0);
687   if (list)
688     {
689       string = gcry_sexp_nth_string (list, 1);
690       if (!string)
691         goto bad_seckey;
692       desired_csum = strtoul (string, NULL, 10);
693       xfree (string);
694     }
695   else
696     desired_csum = 0;
697
698
699   gcry_sexp_release (list); list = NULL;
700   gcry_sexp_release (top_list); top_list = NULL;
701
702   /* log_debug ("XXX is_v4=%d\n", is_v4); */
703   /* log_debug ("XXX pubkey_algo=%d\n", pubkey_algo); */
704   /* log_debug ("XXX is_protected=%d\n", is_protected); */
705   /* log_debug ("XXX protect_algo=%d\n", protect_algo); */
706   /* log_printhex ("XXX iv", iv, ivlen); */
707   /* log_debug ("XXX ivlen=%d\n", ivlen); */
708   /* log_debug ("XXX s2k_mode=%d\n", s2k_mode); */
709   /* log_debug ("XXX s2k_algo=%d\n", s2k_algo); */
710   /* log_printhex ("XXX s2k_salt", s2k_salt, sizeof s2k_salt); */
711   /* log_debug ("XXX s2k_count=%lu\n", (unsigned long)s2k_count); */
712   /* for (idx=0; skey[idx]; idx++) */
713   /*   { */
714   /*     int is_enc = gcry_mpi_get_flag (skey[idx], GCRYMPI_FLAG_OPAQUE); */
715   /*     log_info ("XXX skey[%d]%s:", idx, is_enc? " (enc)":""); */
716   /*     if (is_enc) */
717   /*       { */
718   /*         void *p; */
719   /*         unsigned int nbits; */
720   /*         p = gcry_mpi_get_opaque (skey[idx], &nbits); */
721   /*         log_printhex (NULL, p, (nbits+7)/8); */
722   /*       } */
723   /*     else */
724   /*       gcry_mpi_dump (skey[idx]); */
725   /*     log_printf ("\n"); */
726   /*   } */
727
728   err = get_keygrip (pubkey_algo, skey, grip);
729   if (err)
730     goto leave;
731
732   if (!agent_key_available (grip))
733     {
734       err = gpg_error (GPG_ERR_EEXIST);
735       goto leave;
736     }
737
738   pi = xtrycalloc_secure (1, sizeof (*pi) + 100);
739   if (!pi)
740     return gpg_error_from_syserror ();
741   pi->max_length = 100;
742   pi->min_digits = 0;  /* We want a real passphrase.  */
743   pi->max_digits = 16;
744   pi->max_tries = 3;
745   pi->check_cb = try_do_unprotect_cb;
746   pi->check_cb_arg = &pi_arg;
747   pi_arg.is_v4 = is_v4;
748   pi_arg.is_protected = is_protected;
749   pi_arg.pubkey_algo = pubkey_algo;
750   pi_arg.protect_algo = protect_algo;
751   pi_arg.iv = iv;
752   pi_arg.ivlen = ivlen;
753   pi_arg.s2k_mode = s2k_mode;
754   pi_arg.s2k_algo = s2k_algo;
755   pi_arg.s2k_salt = s2k_salt;
756   pi_arg.s2k_count = s2k_count;
757   pi_arg.desired_csum = desired_csum;
758   pi_arg.skey = skey;
759   pi_arg.skeysize = DIM (skey);
760   pi_arg.skeyidx = skeyidx;
761   pi_arg.r_key = &s_skey;
762   err = agent_askpin (ctrl, prompt, NULL, NULL, pi);
763   skeyidx = pi_arg.skeyidx;
764   if (!err)
765     {
766       *r_passphrase = xtrystrdup (pi->pin);
767       if (!*r_passphrase)
768         err = gpg_error_from_syserror ();
769     }
770   xfree (pi);
771   if (err)
772     goto leave;
773
774   /* Save some memory and get rid of the SKEY array now.  */
775   for (idx=0; idx < skeyidx; idx++)
776     gcry_mpi_release (skey[idx]);
777   skeyidx = 0;
778
779   /* Note that the padding is not required - we use it only because
780      that function allows us to created the result in secure memory.  */
781   err = make_canon_sexp_pad (s_skey, 1, r_key, NULL);
782   gcry_sexp_release (s_skey);
783
784  leave:
785   gcry_sexp_release (list);
786   gcry_sexp_release (top_list);
787   for (idx=0; idx < skeyidx; idx++)
788     gcry_mpi_release (skey[idx]);
789   if (err)
790     {
791       xfree (*r_passphrase);
792       *r_passphrase = NULL;
793     }
794   return err;
795
796  bad_seckey:
797   err = gpg_error (GPG_ERR_BAD_SECKEY);
798   goto leave;
799   
800  outofmem:
801   err = gpg_error (GPG_ERR_ENOMEM);
802   goto leave;
803
804 }
805
806
807