8105ae6f67677edbda8b10dbc17f69f517450f3e
[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_from_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       char *cache_value;
770
771       cache_value = agent_get_cache (cache_nonce, CACHE_MODE_NONCE);
772       if (cache_value)
773         {
774           if (strlen (cache_value) < pi->max_length)
775             strcpy (pi->pin, cache_value);
776           xfree (cache_value);
777         }
778       if (*pi->pin)
779         err = try_do_unprotect_cb (pi);
780     }
781   if (gpg_err_code (err) == GPG_ERR_BAD_PASSPHRASE)
782     err = agent_askpin (ctrl, prompt, NULL, NULL, pi, NULL);
783   skeyidx = pi_arg.skeyidx;
784   if (!err)
785     {
786       *r_passphrase = xtrystrdup (pi->pin);
787       if (!*r_passphrase)
788         err = gpg_error_from_syserror ();
789     }
790   xfree (pi);
791   if (err)
792     goto leave;
793
794   /* Save some memory and get rid of the SKEY array now.  */
795   for (idx=0; idx < skeyidx; idx++)
796     gcry_mpi_release (skey[idx]);
797   skeyidx = 0;
798
799   /* Note that the padding is not required - we use it only because
800      that function allows us to created the result in secure memory.  */
801   err = make_canon_sexp_pad (s_skey, 1, r_key, NULL);
802   gcry_sexp_release (s_skey);
803
804  leave:
805   gcry_sexp_release (list);
806   gcry_sexp_release (top_list);
807   for (idx=0; idx < skeyidx; idx++)
808     gcry_mpi_release (skey[idx]);
809   if (err)
810     {
811       xfree (*r_passphrase);
812       *r_passphrase = NULL;
813     }
814   return err;
815
816  bad_seckey:
817   err = gpg_error (GPG_ERR_BAD_SECKEY);
818   goto leave;
819   
820  outofmem:
821   err = gpg_error (GPG_ERR_ENOMEM);
822   goto leave;
823
824 }
825
826
827 \f
828 static gpg_error_t
829 key_from_sexp (gcry_sexp_t sexp, const char *elems, gcry_mpi_t *array)
830 {
831   gpg_error_t err = 0;
832   gcry_sexp_t l2;
833   int idx;
834
835   for (idx=0; *elems; elems++, idx++)
836     {
837       l2 = gcry_sexp_find_token (sexp, elems, 1);
838       if (!l2)
839         {
840           err = gpg_error (GPG_ERR_NO_OBJ); /* Required parameter not found.  */
841           goto leave;
842         }
843       array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
844       gcry_sexp_release (l2);
845       if (!array[idx]) 
846         {
847           err = gpg_error (GPG_ERR_INV_OBJ); /* Required parameter invalid.  */
848           goto leave;
849         }
850     }
851   
852  leave:
853   if (err)
854     {
855       int i;
856
857       for (i=0; i < idx; i++)
858         {
859           gcry_mpi_release (array[i]);
860           array[i] = NULL;
861         }
862     }
863   return err;
864 }
865
866
867 /* Given an ARRAY of mpis with the key parameters, protect the secret
868    parameters in that array and replace them by one opaque encoded
869    mpi.  NPKEY is the number of public key parameters and NSKEY is
870    the number of secret key parameters (including the public ones).
871    On success the array will have NPKEY+1 elements.  */
872 static gpg_error_t
873 apply_protection (gcry_mpi_t *array, int npkey, int nskey,
874                   const char *passphrase,
875                   int protect_algo, void *protect_iv, size_t protect_ivlen,
876                   int s2k_mode, int s2k_algo, byte *s2k_salt, u32 s2k_count)
877 {
878   gpg_error_t err;
879   int i, j;
880   gcry_cipher_hd_t cipherhd;
881   unsigned char *bufarr[10];
882   size_t narr[10];
883   unsigned int nbits[10];
884   int ndata;
885   unsigned char *p, *data;
886
887   assert (npkey < nskey);
888   assert (nskey < DIM (bufarr));
889
890   /* Collect only the secret key parameters into BUFARR et al and
891      compute the required size of the data buffer.  */
892   ndata = 20; /* Space for the SHA-1 checksum.  */
893   for (i = npkey, j = 0; i < nskey; i++, j++ )
894     {
895       err = gcry_mpi_aprint (GCRYMPI_FMT_USG, bufarr+j, narr+j, array[i]);
896       if (err)
897         {
898           err = gpg_error_from_syserror ();
899           for (i = 0; i < j; i++)
900             xfree (bufarr[i]);
901           return err;
902         }
903       nbits[j] = gcry_mpi_get_nbits (array[i]);
904       ndata += 2 + narr[j];
905     }
906
907   /* Allocate data buffer and stuff it with the secret key parameters.  */
908   data = xtrymalloc_secure (ndata);
909   if (!data)
910     {
911       err = gpg_error_from_syserror ();
912       for (i = 0; i < (nskey-npkey); i++ )
913         xfree (bufarr[i]);
914       return err;
915     }
916   p = data;
917   for (i = 0; i < (nskey-npkey); i++ )
918     {
919       *p++ = nbits[i] >> 8 ;
920       *p++ = nbits[i];
921       memcpy (p, bufarr[i], narr[i]);
922       p += narr[i];
923       xfree (bufarr[i]);
924       bufarr[i] = NULL;
925     }
926   assert (p == data + ndata - 20);
927
928   /* Append a hash of the secret key parameters.  */
929   gcry_md_hash_buffer (GCRY_MD_SHA1, p, data, ndata - 20);
930
931   /* Encrypt it.  */
932   err = gcry_cipher_open (&cipherhd, protect_algo,
933                           GCRY_CIPHER_MODE_CFB, GCRY_CIPHER_SECURE);
934   if (!err)
935     err = hash_passphrase_and_set_key (passphrase, cipherhd, protect_algo,
936                                        s2k_mode, s2k_algo, s2k_salt, s2k_count);
937   if (!err)
938     err = gcry_cipher_setiv (cipherhd, protect_iv, protect_ivlen);
939   if (!err)
940     err = gcry_cipher_encrypt (cipherhd, data, ndata, NULL, 0);
941   gcry_cipher_close (cipherhd);
942   if (err)
943     {
944       xfree (data);
945       return err;
946     }
947
948   /* Replace the secret key parameters in the array by one opaque value.  */
949   for (i = npkey; i < nskey; i++ )
950     {
951       gcry_mpi_release (array[i]);
952       array[i] = NULL;
953     }
954   array[npkey] = gcry_mpi_set_opaque (NULL, data, ndata*8);
955   return 0;
956 }
957
958
959 /* Convert our key S_KEY into an OpenPGP key transfer format.  On
960    success a canonical encoded S-expression is stored at R_TRANSFERKEY
961    and its length at R_TRANSFERKEYLEN; this S-expression is also
962    padded to a multiple of 64 bits.  */
963 gpg_error_t
964 convert_to_openpgp (ctrl_t ctrl, gcry_sexp_t s_key, const char *passphrase,
965                     unsigned char **r_transferkey, size_t *r_transferkeylen)
966 {
967   gpg_error_t err;
968   gcry_sexp_t list, l2;
969   char *name;
970   int algo;
971   const char *algoname;
972   const char *elems;
973   int npkey, nskey;
974   gcry_mpi_t array[10];
975   char protect_iv[16];
976   char salt[8];
977   unsigned long s2k_count;
978   int i, j;
979
980   (void)ctrl;
981
982   *r_transferkey = NULL;
983
984   for (i=0; i < DIM (array); i++)
985     array[i] = NULL;
986
987   list = gcry_sexp_find_token (s_key, "private-key", 0);
988   if (!list)
989     return gpg_error (GPG_ERR_NO_OBJ); /* Does not contain a key object.  */
990   l2 = gcry_sexp_cadr (list);
991   gcry_sexp_release (list);
992   list = l2;
993   name = gcry_sexp_nth_string (list, 0);
994   if (!name)
995     {
996       gcry_sexp_release (list);
997       return gpg_error (GPG_ERR_INV_OBJ); /* Invalid structure of object. */
998     }
999   
1000   algo = gcry_pk_map_name (name);
1001   xfree (name);
1002
1003   switch (algo)
1004     {
1005     case GCRY_PK_RSA:   algoname = "rsa";   npkey = 2; elems = "nedpqu";  break;
1006     case GCRY_PK_ELG:   algoname = "elg";   npkey = 3; elems = "pgyx";    break;
1007     case GCRY_PK_ELG_E: algoname = "elg";   npkey = 3; elems = "pgyx";    break;
1008     case GCRY_PK_DSA:   algoname = "dsa";   npkey = 4; elems = "pqgyx";   break;
1009     case GCRY_PK_ECDSA: algoname = "ecdsa"; npkey = 6; elems = "pabgnqd"; break;
1010     default:            algoname = "";      npkey = 0; elems = NULL;      break;
1011     }
1012   assert (!elems || strlen (elems) < DIM (array) );
1013   nskey = elems? strlen (elems) : 0;
1014
1015   if (!elems)
1016     err = gpg_error (GPG_ERR_PUBKEY_ALGO);
1017   else
1018     err = key_from_sexp (list, elems, array);
1019   gcry_sexp_release (list);
1020   if (err)
1021     return err;
1022
1023   gcry_create_nonce (protect_iv, sizeof protect_iv);
1024   gcry_create_nonce (salt, sizeof salt);
1025   s2k_count = get_standard_s2k_count ();
1026   err = apply_protection (array, npkey, nskey, passphrase,
1027                           GCRY_CIPHER_AES, protect_iv, sizeof protect_iv,
1028                           3, GCRY_MD_SHA1, salt, s2k_count);
1029   /* Turn it into the transfer key S-expression.  Note that we always
1030      return a protected key.  */
1031   if (!err)
1032     {
1033       char countbuf[35];
1034       membuf_t mbuf;
1035       void *format_args_buf_ptr[1];
1036       int   format_args_buf_int[1];
1037       void *format_args[10+2];
1038       size_t n;
1039       gcry_sexp_t tmpkey, tmpsexp;
1040       
1041       snprintf (countbuf, sizeof countbuf, "%lu", s2k_count);
1042       
1043       init_membuf (&mbuf, 50);
1044       put_membuf_str (&mbuf, "(skey");
1045       for (i=j=0; i < npkey; i++)
1046         {
1047           put_membuf_str (&mbuf, " _ %m");
1048           format_args[j++] = array + i;
1049         }
1050       put_membuf_str (&mbuf, " e %b");
1051       format_args_buf_ptr[0] = gcry_mpi_get_opaque (array[npkey], &n);
1052       format_args_buf_int[0] = (n+7)/8;
1053       format_args[j++] = format_args_buf_int;
1054       format_args[j++] = format_args_buf_ptr;
1055       put_membuf_str (&mbuf, ")\n");
1056       put_membuf (&mbuf, "", 1);
1057
1058       tmpkey = NULL;
1059       {
1060         char *format = get_membuf (&mbuf, NULL);
1061         if (!format)
1062           err = gpg_error_from_syserror ();
1063         else
1064           err = gcry_sexp_build_array (&tmpkey, NULL, format, format_args);
1065         xfree (format);
1066       }
1067       if (!err)
1068         err = gcry_sexp_build (&tmpsexp, NULL,
1069                                "(openpgp-private-key\n"
1070                                " (version 1:4)\n"
1071                                " (algo %s)\n"
1072                                " %S\n"
1073                                " (protection sha1 aes %b 1:3 sha1 %b %s))\n",
1074                                algoname,
1075                                tmpkey, 
1076                                (int)sizeof protect_iv, protect_iv,
1077                                (int)sizeof salt, salt,
1078                                countbuf);
1079       gcry_sexp_release (tmpkey);
1080       if (!err)
1081         err = make_canon_sexp_pad (tmpsexp, 0, r_transferkey, r_transferkeylen);
1082       gcry_sexp_release (tmpsexp);
1083     }
1084
1085   for (i=0; i < DIM (array); i++)
1086     gcry_mpi_release (array[i]);
1087   
1088   return err;
1089 }
1090