s/CACHE_MODE_IMPGEN/CACHE_MODE_NONCE/.
[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,
501                       arg->is_v4? 4:3,
502                       arg->pubkey_algo, arg->is_protected,
503                       arg->skey, arg->skeysize,
504                       arg->protect_algo, arg->iv, arg->ivlen,
505                       arg->s2k_mode, arg->s2k_algo,
506                       arg->s2k_salt, arg->s2k_count,
507                       arg->desired_csum, arg->r_key);
508   /* SKEY may be modified now, thus we need to re-compute SKEYIDX.  */
509   for (arg->skeyidx = 0; (arg->skeyidx < arg->skeysize
510                           && arg->skey[arg->skeyidx]); arg->skeyidx++)
511     ;
512   return err;
513 }
514
515
516 /* Convert an OpenPGP transfer key into our internal format.  Before
517    asking for a passphrase we check whether the key already exists in
518    our key storage.  S_PGP is the OpenPGP key in transfer format.  If
519    CACHE_NONCE is given the passphrase will be looked up in the cache.
520    On success R_KEY will receive a canonical encoded S-expression with
521    the unprotected key in our internal format; the caller needs to
522    release that memory.  The passphrase used to decrypt the OpenPGP
523    key will be returned at R_PASSPHRASE; the caller must release this
524    passphrase.  The keygrip will be stored at the 20 byte buffer
525    pointed to by GRIP.  On error NULL is stored at all return
526    arguments.  */
527 gpg_error_t
528 convert_openpgp (ctrl_t ctrl, gcry_sexp_t s_pgp, 
529                  unsigned char *grip, const char *prompt,
530                  const char *cache_nonce,
531                  unsigned char **r_key, char **r_passphrase)
532 {
533   gpg_error_t err;
534   gcry_sexp_t top_list;
535   gcry_sexp_t list = NULL;
536   const char *value;
537   size_t valuelen;
538   char *string;
539   int  idx;
540   int  is_v4, is_protected;
541   int  pubkey_algo;
542   int  protect_algo = 0;
543   char iv[16];
544   int  ivlen = 0;
545   int  s2k_mode = 0;
546   int  s2k_algo = 0;
547   byte s2k_salt[8];
548   u32  s2k_count = 0;
549   size_t npkey, nskey;
550   gcry_mpi_t skey[10];  /* We support up to 9 parameters.  */
551   u16 desired_csum;
552   int skeyidx = 0;
553   gcry_sexp_t s_skey;
554   struct pin_entry_info_s *pi;
555   struct try_do_unprotect_arg_s pi_arg;
556
557   *r_key = NULL;
558   *r_passphrase = NULL;
559
560   top_list = gcry_sexp_find_token (s_pgp, "openpgp-private-key", 0);
561   if (!top_list)
562     goto bad_seckey;
563
564   list = gcry_sexp_find_token (top_list, "version", 0);
565   if (!list)
566     goto bad_seckey;
567   value = gcry_sexp_nth_data (list, 1, &valuelen);
568   if (!value || valuelen != 1 || !(value[0] == '3' || value[0] == '4'))
569     goto bad_seckey;
570   is_v4 = (value[0] == '4');
571
572   gcry_sexp_release (list);
573   list = gcry_sexp_find_token (top_list, "protection", 0);
574   if (!list)
575     goto bad_seckey;
576   value = gcry_sexp_nth_data (list, 1, &valuelen);
577   if (!value)
578     goto bad_seckey;
579   if (valuelen == 4 && !memcmp (value, "sha1", 4))
580     is_protected = 2;
581   else if (valuelen == 3 && !memcmp (value, "sum", 3))
582     is_protected = 1;
583   else if (valuelen == 4 && !memcmp (value, "none", 4))
584     is_protected = 0;
585   else
586     goto bad_seckey;
587   if (is_protected)
588     {
589       string = gcry_sexp_nth_string (list, 2);
590       if (!string)
591         goto bad_seckey;
592       protect_algo = gcry_cipher_map_name (string);
593       if (!protect_algo && !!strcmp (string, "IDEA"))
594         protect_algo = GCRY_CIPHER_IDEA;
595       xfree (string);
596       
597       value = gcry_sexp_nth_data (list, 3, &valuelen);
598       if (!value || !valuelen || valuelen > sizeof iv)
599         goto bad_seckey;
600       memcpy (iv, value, valuelen);
601       ivlen = valuelen;
602
603       string = gcry_sexp_nth_string (list, 4);
604       if (!string)
605         goto bad_seckey;
606       s2k_mode = strtol (string, NULL, 10);
607       xfree (string);
608
609       string = gcry_sexp_nth_string (list, 5);
610       if (!string)
611         goto bad_seckey;
612       s2k_algo = gcry_md_map_name (string);
613       xfree (string);
614
615       value = gcry_sexp_nth_data (list, 6, &valuelen);
616       if (!value || !valuelen || valuelen > sizeof s2k_salt)
617         goto bad_seckey;
618       memcpy (s2k_salt, value, valuelen);
619
620       string = gcry_sexp_nth_string (list, 7);
621       if (!string)
622         goto bad_seckey;
623       s2k_count = strtoul (string, NULL, 10);
624       xfree (string);
625     }
626
627   gcry_sexp_release (list);
628   list = gcry_sexp_find_token (top_list, "algo", 0);
629   if (!list)
630     goto bad_seckey;
631   string = gcry_sexp_nth_string (list, 1);
632   if (!string)
633     goto bad_seckey;
634   pubkey_algo = gcry_pk_map_name (string);
635   xfree (string);
636
637   if (gcry_pk_algo_info (pubkey_algo, GCRYCTL_GET_ALGO_NPKEY, NULL, &npkey)
638       || gcry_pk_algo_info (pubkey_algo, GCRYCTL_GET_ALGO_NSKEY, NULL, &nskey)
639       || !npkey || npkey >= nskey)
640     goto bad_seckey;
641
642   gcry_sexp_release (list);
643   list = gcry_sexp_find_token (top_list, "skey", 0);
644   if (!list)
645     goto bad_seckey;
646   for (idx=0;;)
647     {
648       int is_enc;
649
650       value = gcry_sexp_nth_data (list, ++idx, &valuelen);
651       if (!value && skeyidx >= npkey)
652         break;  /* Ready.  */
653
654       /* Check for too many parameters.  Note that depending on the
655          protection mode and version number we may see less than NSKEY
656          (but at least NPKEY+1) parameters.  */
657       if (idx >= 2*nskey)
658         goto bad_seckey;
659       if (skeyidx >= DIM (skey)-1)
660         goto bad_seckey;
661
662       if (!value || valuelen != 1 || !(value[0] == '_' || value[0] == 'e'))
663         goto bad_seckey;
664       is_enc = (value[0] == 'e');
665       value = gcry_sexp_nth_data (list, ++idx, &valuelen);
666       if (!value || !valuelen)
667         goto bad_seckey;
668       if (is_enc)
669         {
670           void *p = xtrymalloc (valuelen);
671           if (!p)
672             goto outofmem;
673           memcpy (p, value, valuelen);
674           skey[skeyidx] = gcry_mpi_set_opaque (NULL, p, valuelen*8);
675           if (!skey[skeyidx])
676             goto outofmem;
677         }
678       else
679         {
680           if (gcry_mpi_scan (skey + skeyidx, GCRYMPI_FMT_STD,
681                              value, valuelen, NULL))
682             goto bad_seckey;
683         }
684       skeyidx++;
685     }
686   skey[skeyidx++] = NULL;
687
688   gcry_sexp_release (list);
689   list = gcry_sexp_find_token (top_list, "csum", 0);
690   if (list)
691     {
692       string = gcry_sexp_nth_string (list, 1);
693       if (!string)
694         goto bad_seckey;
695       desired_csum = strtoul (string, NULL, 10);
696       xfree (string);
697     }
698   else
699     desired_csum = 0;
700
701
702   gcry_sexp_release (list); list = NULL;
703   gcry_sexp_release (top_list); top_list = NULL;
704
705   /* log_debug ("XXX is_v4=%d\n", is_v4); */
706   /* log_debug ("XXX pubkey_algo=%d\n", pubkey_algo); */
707   /* log_debug ("XXX is_protected=%d\n", is_protected); */
708   /* log_debug ("XXX protect_algo=%d\n", protect_algo); */
709   /* log_printhex ("XXX iv", iv, ivlen); */
710   /* log_debug ("XXX ivlen=%d\n", ivlen); */
711   /* log_debug ("XXX s2k_mode=%d\n", s2k_mode); */
712   /* log_debug ("XXX s2k_algo=%d\n", s2k_algo); */
713   /* log_printhex ("XXX s2k_salt", s2k_salt, sizeof s2k_salt); */
714   /* log_debug ("XXX s2k_count=%lu\n", (unsigned long)s2k_count); */
715   /* for (idx=0; skey[idx]; idx++) */
716   /*   { */
717   /*     int is_enc = gcry_mpi_get_flag (skey[idx], GCRYMPI_FLAG_OPAQUE); */
718   /*     log_info ("XXX skey[%d]%s:", idx, is_enc? " (enc)":""); */
719   /*     if (is_enc) */
720   /*       { */
721   /*         void *p; */
722   /*         unsigned int nbits; */
723   /*         p = gcry_mpi_get_opaque (skey[idx], &nbits); */
724   /*         log_printhex (NULL, p, (nbits+7)/8); */
725   /*       } */
726   /*     else */
727   /*       gcry_mpi_dump (skey[idx]); */
728   /*     log_printf ("\n"); */
729   /*   } */
730
731   err = get_keygrip (pubkey_algo, skey, grip);
732   if (err)
733     goto leave;
734
735   if (!agent_key_available (grip))
736     {
737       err = gpg_error (GPG_ERR_EEXIST);
738       goto leave;
739     }
740
741   pi = xtrycalloc_secure (1, sizeof (*pi) + 100);
742   if (!pi)
743     return gpg_error_from_syserror ();
744   pi->max_length = 100;
745   pi->min_digits = 0;  /* We want a real passphrase.  */
746   pi->max_digits = 16;
747   pi->max_tries = 3;
748   pi->check_cb = try_do_unprotect_cb;
749   pi->check_cb_arg = &pi_arg;
750   pi_arg.is_v4 = is_v4;
751   pi_arg.is_protected = is_protected;
752   pi_arg.pubkey_algo = pubkey_algo;
753   pi_arg.protect_algo = protect_algo;
754   pi_arg.iv = iv;
755   pi_arg.ivlen = ivlen;
756   pi_arg.s2k_mode = s2k_mode;
757   pi_arg.s2k_algo = s2k_algo;
758   pi_arg.s2k_salt = s2k_salt;
759   pi_arg.s2k_count = s2k_count;
760   pi_arg.desired_csum = desired_csum;
761   pi_arg.skey = skey;
762   pi_arg.skeysize = DIM (skey);
763   pi_arg.skeyidx = skeyidx;
764   pi_arg.r_key = &s_skey;
765
766   err = gpg_error (GPG_ERR_BAD_PASSPHRASE);
767   if (cache_nonce)
768     {
769       void *cache_marker = NULL;
770       const char *cache_value;
771
772       cache_value = agent_get_cache (cache_nonce, CACHE_MODE_NONCE,
773                                      &cache_marker);
774       if (cache_value)
775         {
776           if (strlen (cache_value) < pi->max_length)
777             strcpy (pi->pin, cache_value);
778           agent_unlock_cache_entry (&cache_marker);
779         }
780       if (*pi->pin)
781         err = try_do_unprotect_cb (pi);
782     }
783   if (gpg_err_code (err) == GPG_ERR_BAD_PASSPHRASE)
784     err = agent_askpin (ctrl, prompt, NULL, NULL, pi);
785   skeyidx = pi_arg.skeyidx;
786   if (!err)
787     {
788       *r_passphrase = xtrystrdup (pi->pin);
789       if (!*r_passphrase)
790         err = gpg_error_from_syserror ();
791     }
792   xfree (pi);
793   if (err)
794     goto leave;
795
796   /* Save some memory and get rid of the SKEY array now.  */
797   for (idx=0; idx < skeyidx; idx++)
798     gcry_mpi_release (skey[idx]);
799   skeyidx = 0;
800
801   /* Note that the padding is not required - we use it only because
802      that function allows us to created the result in secure memory.  */
803   err = make_canon_sexp_pad (s_skey, 1, r_key, NULL);
804   gcry_sexp_release (s_skey);
805
806  leave:
807   gcry_sexp_release (list);
808   gcry_sexp_release (top_list);
809   for (idx=0; idx < skeyidx; idx++)
810     gcry_mpi_release (skey[idx]);
811   if (err)
812     {
813       xfree (*r_passphrase);
814       *r_passphrase = NULL;
815     }
816   return err;
817
818  bad_seckey:
819   err = gpg_error (GPG_ERR_BAD_SECKEY);
820   goto leave;
821   
822  outofmem:
823   err = gpg_error (GPG_ERR_ENOMEM);
824   goto leave;
825
826 }
827
828
829