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