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