agent: Add some extra robustness to extract_private_key
[gnupg.git] / agent / cvt-openpgp.c
1 /* cvt-openpgp.c - Convert an OpenPGP key to our internal format.
2  * Copyright (C) 1998-2002, 2006, 2009, 2010 Free Software Foundation, Inc.
3  * Copyright (C) 2013, 2014 Werner Koch
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   const char *curve;
39   int  protect_algo;
40   char *iv;
41   int  ivlen;
42   int  s2k_mode;
43   int  s2k_algo;
44   byte *s2k_salt;
45   u32  s2k_count;
46   u16 desired_csum;
47   gcry_mpi_t *skey;
48   size_t skeysize;
49   int skeyidx;
50   gcry_sexp_t *r_key;
51 };
52
53
54
55 /* Compute the keygrip from the public key and store it at GRIP.  */
56 static gpg_error_t
57 get_keygrip (int pubkey_algo, const char *curve, gcry_mpi_t *pkey,
58              unsigned char *grip)
59 {
60   gpg_error_t err;
61   gcry_sexp_t s_pkey = NULL;
62
63   switch (pubkey_algo)
64     {
65     case GCRY_PK_DSA:
66       err = gcry_sexp_build (&s_pkey, NULL,
67                              "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))",
68                              pkey[0], pkey[1], pkey[2], pkey[3]);
69       break;
70
71     case GCRY_PK_ELG:
72       err = gcry_sexp_build (&s_pkey, NULL,
73                              "(public-key(elg(p%m)(g%m)(y%m)))",
74                              pkey[0], pkey[1], pkey[2]);
75       break;
76
77     case GCRY_PK_RSA:
78       err = gcry_sexp_build (&s_pkey, NULL,
79                              "(public-key(rsa(n%m)(e%m)))", pkey[0], pkey[1]);
80       break;
81
82     case GCRY_PK_ECC:
83       if (!curve)
84         err = gpg_error (GPG_ERR_BAD_SECKEY);
85       else if (!strcmp (curve, openpgp_curve_to_oid ("Ed25519", NULL)))
86         err = gcry_sexp_build (&s_pkey, NULL,
87                                "(public-key(ecc(curve %s)(flags eddsa)(q%m)))",
88                                "Ed25519", pkey[0]);
89       else
90         err = gcry_sexp_build (&s_pkey, NULL,
91                                "(public-key(ecc(curve %s)(q%m)))",
92                                curve, pkey[0]);
93       break;
94
95     default:
96       err = gpg_error (GPG_ERR_PUBKEY_ALGO);
97       break;
98     }
99
100   if (!err && !gcry_pk_get_keygrip (s_pkey, grip))
101     err = gpg_error (GPG_ERR_INTERNAL);
102
103   gcry_sexp_release (s_pkey);
104   return err;
105 }
106
107
108 /* Convert a secret key given as algorithm id and an array of key
109    parameters into our s-expression based format.  Note that
110    PUBKEY_ALGO has an gcrypt algorithm number. */
111 static gpg_error_t
112 convert_secret_key (gcry_sexp_t *r_key, int pubkey_algo, gcry_mpi_t *skey,
113                     const char *curve)
114 {
115   gpg_error_t err;
116   gcry_sexp_t s_skey = NULL;
117
118   *r_key = NULL;
119
120   switch (pubkey_algo)
121     {
122     case GCRY_PK_DSA:
123       err = gcry_sexp_build (&s_skey, NULL,
124                              "(private-key(dsa(p%m)(q%m)(g%m)(y%m)(x%m)))",
125                              skey[0], skey[1], skey[2], skey[3], skey[4]);
126       break;
127
128     case GCRY_PK_ELG:
129     case GCRY_PK_ELG_E:
130       err = gcry_sexp_build (&s_skey, NULL,
131                              "(private-key(elg(p%m)(g%m)(y%m)(x%m)))",
132                              skey[0], skey[1], skey[2], skey[3]);
133       break;
134
135
136     case GCRY_PK_RSA:
137     case GCRY_PK_RSA_E:
138     case GCRY_PK_RSA_S:
139       err = gcry_sexp_build (&s_skey, NULL,
140                              "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))",
141                              skey[0], skey[1], skey[2], skey[3], skey[4],
142                              skey[5]);
143       break;
144
145     case GCRY_PK_ECC:
146       if (!curve)
147         err = gpg_error (GPG_ERR_BAD_SECKEY);
148       else if (!strcmp (curve, openpgp_curve_to_oid ("Ed25519", NULL)))
149         {
150           /* Do not store the OID as name but the real name and the
151              EdDSA flag.  */
152           err = gcry_sexp_build (&s_skey, NULL,
153                                  "(private-key(ecc(curve%s)(flags eddsa)"
154                                  "(q%m)(d%m)))",
155                                  "Ed25519", skey[0], skey[1]);
156         }
157       else
158         err = gcry_sexp_build (&s_skey, NULL,
159                                "(private-key(ecc(curve%s)(q%m)(d%m)))",
160                                curve, skey[0], skey[1]);
161       break;
162
163     default:
164       err = gpg_error (GPG_ERR_PUBKEY_ALGO);
165       break;
166     }
167
168   if (!err)
169     *r_key = s_skey;
170   return err;
171 }
172
173
174 /* Convert a secret key given as algorithm id, an array of key
175    parameters, and an S-expression of the original OpenPGP transfer
176    key into our s-expression based format.  This is a variant of
177    convert_secret_key which is used for the openpgp-native protection
178    mode.  Note that PUBKEY_ALGO has an gcrypt algorithm number. */
179 static gpg_error_t
180 convert_transfer_key (gcry_sexp_t *r_key, int pubkey_algo, gcry_mpi_t *skey,
181                       const char *curve, gcry_sexp_t transfer_key)
182 {
183   gpg_error_t err;
184   gcry_sexp_t s_skey = NULL;
185
186   *r_key = NULL;
187
188   switch (pubkey_algo)
189     {
190     case GCRY_PK_DSA:
191       err = gcry_sexp_build
192         (&s_skey, NULL,
193          "(protected-private-key(dsa(p%m)(q%m)(g%m)(y%m)"
194          "(protected openpgp-native%S)))",
195          skey[0], skey[1], skey[2], skey[3], transfer_key);
196       break;
197
198     case GCRY_PK_ELG:
199       err = gcry_sexp_build
200         (&s_skey, NULL,
201          "(protected-private-key(elg(p%m)(g%m)(y%m)"
202          "(protected openpgp-native%S)))",
203          skey[0], skey[1], skey[2], transfer_key);
204       break;
205
206
207     case GCRY_PK_RSA:
208       err = gcry_sexp_build
209         (&s_skey, NULL,
210          "(protected-private-key(rsa(n%m)(e%m)"
211          "(protected openpgp-native%S)))",
212          skey[0], skey[1], transfer_key );
213       break;
214
215     case GCRY_PK_ECC:
216       if (!curve)
217         err = gpg_error (GPG_ERR_BAD_SECKEY);
218       else if (!strcmp (curve, openpgp_curve_to_oid ("Ed25519", NULL)))
219         {
220           /* Do not store the OID as name but the real name and the
221              EdDSA flag.  */
222           err = gcry_sexp_build
223             (&s_skey, NULL,
224              "(protected-private-key(ecc(curve%s)(flags eddsa)(q%m)"
225              "(protected openpgp-native%S)))",
226              "Ed25519", skey[0], transfer_key);
227         }
228       else
229         err = gcry_sexp_build
230           (&s_skey, NULL,
231            "(protected-private-key(ecc(curve%s)(q%m)"
232            "(protected openpgp-native%S)))",
233            curve, skey[0], transfer_key);
234       break;
235
236     default:
237       err = gpg_error (GPG_ERR_PUBKEY_ALGO);
238       break;
239     }
240
241   if (!err)
242     *r_key = s_skey;
243   return err;
244 }
245
246
247 /* Hash the passphrase and set the key. */
248 static gpg_error_t
249 hash_passphrase_and_set_key (const char *passphrase,
250                              gcry_cipher_hd_t hd, int protect_algo,
251                              int s2k_mode, int s2k_algo,
252                              byte *s2k_salt, u32 s2k_count)
253 {
254   gpg_error_t err;
255   unsigned char *key;
256   size_t keylen;
257
258   keylen = gcry_cipher_get_algo_keylen (protect_algo);
259   if (!keylen)
260     return gpg_error (GPG_ERR_INTERNAL);
261
262   key = xtrymalloc_secure (keylen);
263   if (!key)
264     return gpg_error_from_syserror ();
265
266   err = s2k_hash_passphrase (passphrase,
267                              s2k_algo, s2k_mode, s2k_salt, s2k_count,
268                              key, keylen);
269   if (!err)
270     err = gcry_cipher_setkey (hd, key, keylen);
271
272   xfree (key);
273   return err;
274 }
275
276
277 static u16
278 checksum (const unsigned char *p, unsigned int n)
279 {
280   u16 a;
281
282   for (a=0; n; n-- )
283     a += *p++;
284   return a;
285 }
286
287
288 /* Return the number of expected key parameters.  */
289 static void
290 get_npkey_nskey (int pubkey_algo, size_t *npkey, size_t *nskey)
291 {
292   switch (pubkey_algo)
293     {
294     case GCRY_PK_RSA:   *npkey = 2; *nskey = 6; break;
295     case GCRY_PK_ELG:   *npkey = 3; *nskey = 4; break;
296     case GCRY_PK_ELG_E: *npkey = 3; *nskey = 4; break;
297     case GCRY_PK_DSA:   *npkey = 4; *nskey = 5; break;
298     case GCRY_PK_ECC:   *npkey = 1; *nskey = 2; break;
299     default:            *npkey = 0; *nskey = 0; break;
300     }
301 }
302
303
304 /* Helper for do_unprotect.  PUBKEY_ALOGO is the gcrypt algo number.
305    On success R_NPKEY and R_NSKEY receive the number or parameters for
306    the algorithm PUBKEY_ALGO and R_SKEYLEN the used length of
307    SKEY.  */
308 static int
309 prepare_unprotect (int pubkey_algo, gcry_mpi_t *skey, size_t skeysize,
310                    int s2k_mode,
311                    unsigned int *r_npkey, unsigned int *r_nskey,
312                    unsigned int *r_skeylen)
313 {
314   size_t npkey, nskey, skeylen;
315   int i;
316
317   /* Count the actual number of MPIs is in the array and set the
318      remainder to NULL for easier processing later on.  */
319   for (skeylen = 0; skey[skeylen]; skeylen++)
320     ;
321   for (i=skeylen; i < skeysize; i++)
322     skey[i] = NULL;
323
324   /* Check some args.  */
325   if (s2k_mode == 1001)
326     {
327       /* Stub key.  */
328       log_info (_("secret key parts are not available\n"));
329       return gpg_error (GPG_ERR_UNUSABLE_SECKEY);
330     }
331
332   if (gcry_pk_test_algo (pubkey_algo))
333     {
334       log_info (_("public key algorithm %d (%s) is not supported\n"),
335                 pubkey_algo, gcry_pk_algo_name (pubkey_algo));
336       return gpg_error (GPG_ERR_PUBKEY_ALGO);
337     }
338
339   /* Get properties of the public key algorithm and do some
340      consistency checks.  Note that we need at least NPKEY+1 elements
341      in the SKEY array. */
342   get_npkey_nskey (pubkey_algo, &npkey, &nskey);
343   if (!npkey || !nskey || npkey >= nskey)
344     return gpg_error (GPG_ERR_INTERNAL);
345   if (skeylen <= npkey)
346     return gpg_error (GPG_ERR_MISSING_VALUE);
347   if (nskey+1 >= skeysize)
348     return gpg_error (GPG_ERR_BUFFER_TOO_SHORT);
349
350   /* Check that the public key parameters are all available and not
351      encrypted.  */
352   for (i=0; i < npkey; i++)
353     {
354       if (!skey[i] || gcry_mpi_get_flag (skey[i], GCRYMPI_FLAG_USER1))
355         return gpg_error (GPG_ERR_BAD_SECKEY);
356     }
357
358   if (r_npkey)
359     *r_npkey = npkey;
360   if (r_nskey)
361     *r_nskey = nskey;
362   if (r_skeylen)
363     *r_skeylen = skeylen;
364   return 0;
365 }
366
367
368 /* Note that this function modifies SKEY.  SKEYSIZE is the allocated
369    size of the array including the NULL item; this is used for a
370    bounds check.  On success a converted key is stored at R_KEY.  */
371 static int
372 do_unprotect (const char *passphrase,
373               int pkt_version, int pubkey_algo, int is_protected,
374               const char *curve, gcry_mpi_t *skey, size_t skeysize,
375               int protect_algo, void *protect_iv, size_t protect_ivlen,
376               int s2k_mode, int s2k_algo, byte *s2k_salt, u32 s2k_count,
377               u16 desired_csum, gcry_sexp_t *r_key)
378 {
379   gpg_error_t err;
380   unsigned int npkey, nskey, skeylen;
381   gcry_cipher_hd_t cipher_hd = NULL;
382   u16 actual_csum;
383   size_t nbytes;
384   int i;
385   gcry_mpi_t tmpmpi;
386
387   *r_key = NULL;
388
389   err = prepare_unprotect (pubkey_algo, skey, skeysize, s2k_mode,
390                            &npkey, &nskey, &skeylen);
391   if (err)
392     return err;
393
394   /* Check whether SKEY is at all protected.  If it is not protected
395      merely verify the checksum.  */
396   if (!is_protected)
397     {
398       actual_csum = 0;
399       for (i=npkey; i < nskey; i++)
400         {
401           if (!skey[i] || gcry_mpi_get_flag (skey[i], GCRYMPI_FLAG_USER1))
402             return gpg_error (GPG_ERR_BAD_SECKEY);
403
404           if (gcry_mpi_get_flag (skey[i], GCRYMPI_FLAG_OPAQUE))
405             {
406               unsigned int nbits;
407               const unsigned char *buffer;
408               buffer = gcry_mpi_get_opaque (skey[i], &nbits);
409               nbytes = (nbits+7)/8;
410               actual_csum += checksum (buffer, nbytes);
411             }
412           else
413             {
414               unsigned char *buffer;
415
416               err = gcry_mpi_aprint (GCRYMPI_FMT_PGP, &buffer, &nbytes,
417                                      skey[i]);
418               if (!err)
419                 actual_csum += checksum (buffer, nbytes);
420               xfree (buffer);
421             }
422           if (err)
423             return err;
424         }
425
426       if (actual_csum != desired_csum)
427         return gpg_error (GPG_ERR_CHECKSUM);
428
429       goto do_convert;
430     }
431
432
433   if (gcry_cipher_test_algo (protect_algo))
434     {
435       /* The algorithm numbers are Libgcrypt numbers but fortunately
436          the OpenPGP algorithm numbers map one-to-one to the Libgcrypt
437          numbers.  */
438       log_info (_("protection algorithm %d (%s) is not supported\n"),
439                 protect_algo, gnupg_cipher_algo_name (protect_algo));
440       return gpg_error (GPG_ERR_CIPHER_ALGO);
441     }
442
443   if (gcry_md_test_algo (s2k_algo))
444     {
445       log_info (_("protection hash algorithm %d (%s) is not supported\n"),
446                 s2k_algo, gcry_md_algo_name (s2k_algo));
447       return gpg_error (GPG_ERR_DIGEST_ALGO);
448     }
449
450   err = gcry_cipher_open (&cipher_hd, protect_algo,
451                           GCRY_CIPHER_MODE_CFB,
452                           (GCRY_CIPHER_SECURE
453                            | (protect_algo >= 100 ?
454                               0 : GCRY_CIPHER_ENABLE_SYNC)));
455   if (err)
456     {
457       log_error ("failed to open cipher_algo %d: %s\n",
458                  protect_algo, gpg_strerror (err));
459       return err;
460     }
461
462   err = hash_passphrase_and_set_key (passphrase, cipher_hd, protect_algo,
463                                      s2k_mode, s2k_algo, s2k_salt, s2k_count);
464   if (err)
465     {
466       gcry_cipher_close (cipher_hd);
467       return err;
468     }
469
470   gcry_cipher_setiv (cipher_hd, protect_iv, protect_ivlen);
471
472   actual_csum = 0;
473   if (pkt_version >= 4)
474     {
475       int ndata;
476       unsigned int ndatabits;
477       const unsigned char *p;
478       unsigned char *data;
479       u16 csum_pgp7 = 0;
480
481       if (!gcry_mpi_get_flag (skey[npkey], GCRYMPI_FLAG_OPAQUE ))
482         {
483           gcry_cipher_close (cipher_hd);
484           return gpg_error (GPG_ERR_BAD_SECKEY);
485         }
486       p = gcry_mpi_get_opaque (skey[npkey], &ndatabits);
487       ndata = (ndatabits+7)/8;
488
489       if (ndata > 1)
490         csum_pgp7 = p[ndata-2] << 8 | p[ndata-1];
491       data = xtrymalloc_secure (ndata);
492       if (!data)
493         {
494           err = gpg_error_from_syserror ();
495           gcry_cipher_close (cipher_hd);
496           return err;
497         }
498       gcry_cipher_decrypt (cipher_hd, data, ndata, p, ndata);
499
500       p = data;
501       if (is_protected == 2)
502         {
503           /* This is the new SHA1 checksum method to detect tampering
504              with the key as used by the Klima/Rosa attack.  */
505           desired_csum = 0;
506           actual_csum = 1;  /* Default to bad checksum.  */
507
508           if (ndata < 20)
509             log_error ("not enough bytes for SHA-1 checksum\n");
510           else
511             {
512               gcry_md_hd_t h;
513
514               if (gcry_md_open (&h, GCRY_MD_SHA1, 1))
515                 BUG(); /* Algo not available. */
516               gcry_md_write (h, data, ndata - 20);
517               gcry_md_final (h);
518               if (!memcmp (gcry_md_read (h, GCRY_MD_SHA1), data+ndata-20, 20))
519                 actual_csum = 0; /* Digest does match.  */
520               gcry_md_close (h);
521             }
522         }
523       else
524         {
525           /* Old 16 bit checksum method.  */
526           if (ndata < 2)
527             {
528               log_error ("not enough bytes for checksum\n");
529               desired_csum = 0;
530               actual_csum = 1;  /* Mark checksum bad.  */
531             }
532           else
533             {
534               desired_csum = (data[ndata-2] << 8 | data[ndata-1]);
535               actual_csum = checksum (data, ndata-2);
536               if (desired_csum != actual_csum)
537                 {
538                   /* This is a PGP 7.0.0 workaround */
539                   desired_csum = csum_pgp7; /* Take the encrypted one.  */
540                 }
541             }
542         }
543
544       /* Better check it here.  Otherwise the gcry_mpi_scan would fail
545          because the length may have an arbitrary value.  */
546       if (desired_csum == actual_csum)
547         {
548           for (i=npkey; i < nskey; i++ )
549             {
550               if (gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_PGP, p, ndata, &nbytes))
551                 {
552                   /* Checksum was okay, but not correctly decrypted.  */
553                   desired_csum = 0;
554                   actual_csum = 1;   /* Mark checksum bad.  */
555                   break;
556                 }
557               gcry_mpi_release (skey[i]);
558               skey[i] = tmpmpi;
559               ndata -= nbytes;
560               p += nbytes;
561             }
562           skey[i] = NULL;
563           skeylen = i;
564           assert (skeylen <= skeysize);
565
566           /* Note: at this point NDATA should be 2 for a simple
567              checksum or 20 for the sha1 digest.  */
568         }
569       xfree(data);
570     }
571   else /* Packet version <= 3.  */
572     {
573       unsigned char *buffer;
574
575       for (i = npkey; i < nskey; i++)
576         {
577           const unsigned char *p;
578           size_t ndata;
579           unsigned int ndatabits;
580
581           if (!skey[i] || !gcry_mpi_get_flag (skey[i], GCRYMPI_FLAG_OPAQUE))
582             {
583               gcry_cipher_close (cipher_hd);
584               return gpg_error (GPG_ERR_BAD_SECKEY);
585             }
586           p = gcry_mpi_get_opaque (skey[i], &ndatabits);
587           ndata = (ndatabits+7)/8;
588
589           if (!(ndata >= 2) || !(ndata == ((p[0] << 8 | p[1]) + 7)/8 + 2))
590             {
591               gcry_cipher_close (cipher_hd);
592               return gpg_error (GPG_ERR_BAD_SECKEY);
593             }
594
595           buffer = xtrymalloc_secure (ndata);
596           if (!buffer)
597             {
598               err = gpg_error_from_syserror ();
599               gcry_cipher_close (cipher_hd);
600               return err;
601             }
602
603           gcry_cipher_sync (cipher_hd);
604           buffer[0] = p[0];
605           buffer[1] = p[1];
606           gcry_cipher_decrypt (cipher_hd, buffer+2, ndata-2, p+2, ndata-2);
607           actual_csum += checksum (buffer, ndata);
608           err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_PGP, buffer, ndata, &ndata);
609           xfree (buffer);
610           if (err)
611             {
612               /* Checksum was okay, but not correctly decrypted.  */
613               desired_csum = 0;
614               actual_csum = 1;   /* Mark checksum bad.  */
615               break;
616             }
617           gcry_mpi_release (skey[i]);
618           skey[i] = tmpmpi;
619         }
620     }
621   gcry_cipher_close (cipher_hd);
622
623   /* Now let's see whether we have used the correct passphrase. */
624   if (actual_csum != desired_csum)
625     return gpg_error (GPG_ERR_BAD_PASSPHRASE);
626
627  do_convert:
628   if (nskey != skeylen)
629     err = gpg_error (GPG_ERR_BAD_SECKEY);
630   else
631     err = convert_secret_key (r_key, pubkey_algo, skey, curve);
632   if (err)
633     return err;
634
635   /* The checksum may fail, thus we also check the key itself.  */
636   err = gcry_pk_testkey (*r_key);
637   if (err)
638     {
639       gcry_sexp_release (*r_key);
640       *r_key = NULL;
641       return gpg_error (GPG_ERR_BAD_PASSPHRASE);
642     }
643
644   return 0;
645 }
646
647
648 /* Callback function to try the unprotection from the passphrase query
649    code.  */
650 static int
651 try_do_unprotect_cb (struct pin_entry_info_s *pi)
652 {
653   gpg_error_t err;
654   struct try_do_unprotect_arg_s *arg = pi->check_cb_arg;
655
656   err = do_unprotect (pi->pin,
657                       arg->is_v4? 4:3,
658                       arg->pubkey_algo, arg->is_protected,
659                       arg->curve,
660                       arg->skey, arg->skeysize,
661                       arg->protect_algo, arg->iv, arg->ivlen,
662                       arg->s2k_mode, arg->s2k_algo,
663                       arg->s2k_salt, arg->s2k_count,
664                       arg->desired_csum, arg->r_key);
665   /* SKEY may be modified now, thus we need to re-compute SKEYIDX.  */
666   for (arg->skeyidx = 0; (arg->skeyidx < arg->skeysize
667                           && arg->skey[arg->skeyidx]); arg->skeyidx++)
668     ;
669   return err;
670 }
671
672
673 /* See convert_from_openpgp for the core of the description.  This
674    function adds an optional PASSPHRASE argument and uses this to
675    silently decrypt the key; CACHE_NONCE and R_PASSPHRASE must both be
676    NULL in this mode.  */
677 static gpg_error_t
678 convert_from_openpgp_main (ctrl_t ctrl, gcry_sexp_t s_pgp,
679                            unsigned char *grip, const char *prompt,
680                            const char *cache_nonce, const char *passphrase,
681                            unsigned char **r_key, char **r_passphrase)
682 {
683   gpg_error_t err;
684   int unattended;
685   int from_native;
686   gcry_sexp_t top_list;
687   gcry_sexp_t list = NULL;
688   const char *value;
689   size_t valuelen;
690   char *string;
691   int  idx;
692   int  is_v4, is_protected;
693   int  pubkey_algo;
694   int  protect_algo = 0;
695   char iv[16];
696   int  ivlen = 0;
697   int  s2k_mode = 0;
698   int  s2k_algo = 0;
699   byte s2k_salt[8];
700   u32  s2k_count = 0;
701   size_t npkey, nskey;
702   gcry_mpi_t skey[10];  /* We support up to 9 parameters.  */
703   char *curve = NULL;
704   u16 desired_csum;
705   int skeyidx = 0;
706   gcry_sexp_t s_skey = NULL;
707
708   *r_key = NULL;
709   if (r_passphrase)
710     *r_passphrase = NULL;
711   unattended = !r_passphrase;
712   from_native = (!cache_nonce && passphrase && !r_passphrase);
713
714   top_list = gcry_sexp_find_token (s_pgp, "openpgp-private-key", 0);
715   if (!top_list)
716     goto bad_seckey;
717
718   list = gcry_sexp_find_token (top_list, "version", 0);
719   if (!list)
720     goto bad_seckey;
721   value = gcry_sexp_nth_data (list, 1, &valuelen);
722   if (!value || valuelen != 1 || !(value[0] == '3' || value[0] == '4'))
723     goto bad_seckey;
724   is_v4 = (value[0] == '4');
725
726   gcry_sexp_release (list);
727   list = gcry_sexp_find_token (top_list, "protection", 0);
728   if (!list)
729     goto bad_seckey;
730   value = gcry_sexp_nth_data (list, 1, &valuelen);
731   if (!value)
732     goto bad_seckey;
733   if (valuelen == 4 && !memcmp (value, "sha1", 4))
734     is_protected = 2;
735   else if (valuelen == 3 && !memcmp (value, "sum", 3))
736     is_protected = 1;
737   else if (valuelen == 4 && !memcmp (value, "none", 4))
738     is_protected = 0;
739   else
740     goto bad_seckey;
741
742   if (is_protected)
743     {
744       string = gcry_sexp_nth_string (list, 2);
745       if (!string)
746         goto bad_seckey;
747       protect_algo = gcry_cipher_map_name (string);
748       xfree (string);
749
750       value = gcry_sexp_nth_data (list, 3, &valuelen);
751       if (!value || !valuelen || valuelen > sizeof iv)
752         goto bad_seckey;
753       memcpy (iv, value, valuelen);
754       ivlen = valuelen;
755
756       string = gcry_sexp_nth_string (list, 4);
757       if (!string)
758         goto bad_seckey;
759       s2k_mode = strtol (string, NULL, 10);
760       xfree (string);
761
762       string = gcry_sexp_nth_string (list, 5);
763       if (!string)
764         goto bad_seckey;
765       s2k_algo = gcry_md_map_name (string);
766       xfree (string);
767
768       value = gcry_sexp_nth_data (list, 6, &valuelen);
769       if (!value || !valuelen || valuelen > sizeof s2k_salt)
770         goto bad_seckey;
771       memcpy (s2k_salt, value, valuelen);
772
773       string = gcry_sexp_nth_string (list, 7);
774       if (!string)
775         goto bad_seckey;
776       s2k_count = strtoul (string, NULL, 10);
777       xfree (string);
778     }
779
780   gcry_sexp_release (list);
781   list = gcry_sexp_find_token (top_list, "algo", 0);
782   if (!list)
783     goto bad_seckey;
784   string = gcry_sexp_nth_string (list, 1);
785   if (!string)
786     goto bad_seckey;
787   pubkey_algo = gcry_pk_map_name (string);
788   xfree (string);
789
790   get_npkey_nskey (pubkey_algo, &npkey, &nskey);
791   if (!npkey || !nskey || npkey >= nskey)
792     goto bad_seckey;
793
794   if (npkey == 1) /* This is ECC */
795     {
796       gcry_sexp_release (list);
797       list = gcry_sexp_find_token (top_list, "curve", 0);
798       if (!list)
799         goto bad_seckey;
800       curve = gcry_sexp_nth_string (list, 1);
801       if (!curve)
802         goto bad_seckey;
803     }
804
805   gcry_sexp_release (list);
806   list = gcry_sexp_find_token (top_list, "skey", 0);
807   if (!list)
808     goto bad_seckey;
809   for (idx=0;;)
810     {
811       int is_enc;
812
813       value = gcry_sexp_nth_data (list, ++idx, &valuelen);
814       if (!value && skeyidx >= npkey)
815         break;  /* Ready.  */
816
817       /* Check for too many parameters.  Note that depending on the
818          protection mode and version number we may see less than NSKEY
819          (but at least NPKEY+1) parameters.  */
820       if (idx >= 2*nskey)
821         goto bad_seckey;
822       if (skeyidx >= DIM (skey)-1)
823         goto bad_seckey;
824
825       if (!value || valuelen != 1 || !(value[0] == '_' || value[0] == 'e'))
826         goto bad_seckey;
827       is_enc = (value[0] == 'e');
828       value = gcry_sexp_nth_data (list, ++idx, &valuelen);
829       if (!value || !valuelen)
830         goto bad_seckey;
831       if (is_enc || curve)
832         {
833           /* Encrypted parameters and ECC parameters need or can be
834              stored as opaque.  */
835           skey[skeyidx] = gcry_mpi_set_opaque_copy (NULL, value, valuelen*8);
836           if (!skey[skeyidx])
837             goto outofmem;
838           if (is_enc)
839             gcry_mpi_set_flag (skey[skeyidx], GCRYMPI_FLAG_USER1);
840         }
841       else
842         {
843           if (gcry_mpi_scan (skey + skeyidx, GCRYMPI_FMT_STD,
844                              value, valuelen, NULL))
845             goto bad_seckey;
846         }
847       skeyidx++;
848     }
849   skey[skeyidx++] = NULL;
850
851   gcry_sexp_release (list);
852   list = gcry_sexp_find_token (top_list, "csum", 0);
853   if (list)
854     {
855       string = gcry_sexp_nth_string (list, 1);
856       if (!string)
857         goto bad_seckey;
858       desired_csum = strtoul (string, NULL, 10);
859       xfree (string);
860     }
861   else
862     desired_csum = 0;
863
864
865   gcry_sexp_release (list); list = NULL;
866   gcry_sexp_release (top_list); top_list = NULL;
867
868 #if 0
869   log_debug ("XXX is_v4=%d\n", is_v4);
870   log_debug ("XXX pubkey_algo=%d\n", pubkey_algo);
871   log_debug ("XXX is_protected=%d\n", is_protected);
872   log_debug ("XXX protect_algo=%d\n", protect_algo);
873   log_printhex ("XXX iv", iv, ivlen);
874   log_debug ("XXX ivlen=%d\n", ivlen);
875   log_debug ("XXX s2k_mode=%d\n", s2k_mode);
876   log_debug ("XXX s2k_algo=%d\n", s2k_algo);
877   log_printhex ("XXX s2k_salt", s2k_salt, sizeof s2k_salt);
878   log_debug ("XXX s2k_count=%lu\n", (unsigned long)s2k_count);
879   log_debug ("XXX curve='%s'\n", curve);
880   for (idx=0; skey[idx]; idx++)
881     gcry_log_debugmpi (gcry_mpi_get_flag (skey[idx], GCRYMPI_FLAG_USER1)
882                        ? "skey(e)" : "skey(_)", skey[idx]);
883 #endif /*0*/
884
885   err = get_keygrip (pubkey_algo, curve, skey, grip);
886   if (err)
887     goto leave;
888
889   if (!from_native && !agent_key_available (grip))
890     {
891       err = gpg_error (GPG_ERR_EEXIST);
892       goto leave;
893     }
894
895   if (unattended && !from_native)
896     {
897       err = prepare_unprotect (pubkey_algo, skey, DIM(skey), s2k_mode,
898                                NULL, NULL, NULL);
899       if (err)
900         goto leave;
901
902       err = convert_transfer_key (&s_skey, pubkey_algo, skey, curve, s_pgp);
903       if (err)
904         goto leave;
905     }
906   else
907     {
908       struct pin_entry_info_s *pi;
909       struct try_do_unprotect_arg_s pi_arg;
910
911       pi = xtrycalloc_secure (1, sizeof (*pi) + 100);
912       if (!pi)
913         return gpg_error_from_syserror ();
914       pi->max_length = 100;
915       pi->min_digits = 0;  /* We want a real passphrase.  */
916       pi->max_digits = 16;
917       pi->max_tries = 3;
918       pi->check_cb = try_do_unprotect_cb;
919       pi->check_cb_arg = &pi_arg;
920       pi_arg.is_v4 = is_v4;
921       pi_arg.is_protected = is_protected;
922       pi_arg.pubkey_algo = pubkey_algo;
923       pi_arg.curve = curve;
924       pi_arg.protect_algo = protect_algo;
925       pi_arg.iv = iv;
926       pi_arg.ivlen = ivlen;
927       pi_arg.s2k_mode = s2k_mode;
928       pi_arg.s2k_algo = s2k_algo;
929       pi_arg.s2k_salt = s2k_salt;
930       pi_arg.s2k_count = s2k_count;
931       pi_arg.desired_csum = desired_csum;
932       pi_arg.skey = skey;
933       pi_arg.skeysize = DIM (skey);
934       pi_arg.skeyidx = skeyidx;
935       pi_arg.r_key = &s_skey;
936
937       err = gpg_error (GPG_ERR_BAD_PASSPHRASE);
938       if (!is_protected)
939         {
940           err = try_do_unprotect_cb (pi);
941         }
942       else if (cache_nonce)
943         {
944           char *cache_value;
945
946           cache_value = agent_get_cache (cache_nonce, CACHE_MODE_NONCE);
947           if (cache_value)
948             {
949               if (strlen (cache_value) < pi->max_length)
950                 strcpy (pi->pin, cache_value);
951               xfree (cache_value);
952             }
953           if (*pi->pin)
954             err = try_do_unprotect_cb (pi);
955         }
956       else if (from_native)
957         {
958           if (strlen (passphrase) < pi->max_length)
959             strcpy (pi->pin, passphrase);
960           err = try_do_unprotect_cb (pi);
961         }
962       if (gpg_err_code (err) == GPG_ERR_BAD_PASSPHRASE && !from_native)
963         err = agent_askpin (ctrl, prompt, NULL, NULL, pi);
964       skeyidx = pi_arg.skeyidx;
965       if (!err && r_passphrase && is_protected)
966         {
967           *r_passphrase = xtrystrdup (pi->pin);
968           if (!*r_passphrase)
969             err = gpg_error_from_syserror ();
970         }
971       xfree (pi);
972       if (err)
973         goto leave;
974     }
975
976   /* Save some memory and get rid of the SKEY array now.  */
977   for (idx=0; idx < skeyidx; idx++)
978     gcry_mpi_release (skey[idx]);
979   skeyidx = 0;
980
981   /* Note that the padding is not required - we use it only because
982      that function allows us to create the result in secure memory.  */
983   err = make_canon_sexp_pad (s_skey, 1, r_key, NULL);
984
985  leave:
986   xfree (curve);
987   gcry_sexp_release (s_skey);
988   gcry_sexp_release (list);
989   gcry_sexp_release (top_list);
990   for (idx=0; idx < skeyidx; idx++)
991     gcry_mpi_release (skey[idx]);
992   if (err && r_passphrase)
993     {
994       xfree (*r_passphrase);
995       *r_passphrase = NULL;
996     }
997   return err;
998
999  bad_seckey:
1000   err = gpg_error (GPG_ERR_BAD_SECKEY);
1001   goto leave;
1002
1003  outofmem:
1004   err = gpg_error (GPG_ERR_ENOMEM);
1005   goto leave;
1006
1007 }
1008
1009
1010 /* Convert an OpenPGP transfer key into our internal format.  Before
1011    asking for a passphrase we check whether the key already exists in
1012    our key storage.  S_PGP is the OpenPGP key in transfer format.  If
1013    CACHE_NONCE is given the passphrase will be looked up in the cache.
1014    On success R_KEY will receive a canonical encoded S-expression with
1015    the unprotected key in our internal format; the caller needs to
1016    release that memory.  The passphrase used to decrypt the OpenPGP
1017    key will be returned at R_PASSPHRASE; the caller must release this
1018    passphrase.  If R_PASSPHRASE is NULL the unattended conversion mode
1019    will be used which uses the openpgp-native protection format for
1020    the key.  The keygrip will be stored at the 20 byte buffer pointed
1021    to by GRIP.  On error NULL is stored at all return arguments.  */
1022 gpg_error_t
1023 convert_from_openpgp (ctrl_t ctrl, gcry_sexp_t s_pgp,
1024                       unsigned char *grip, const char *prompt,
1025                       const char *cache_nonce,
1026                       unsigned char **r_key, char **r_passphrase)
1027 {
1028   return convert_from_openpgp_main (ctrl, s_pgp, grip, prompt,
1029                                     cache_nonce, NULL,
1030                                     r_key, r_passphrase);
1031 }
1032
1033 /* This function is called by agent_unprotect to re-protect an
1034    openpgp-native protected private-key into the standard private-key
1035    protection format.  */
1036 gpg_error_t
1037 convert_from_openpgp_native (ctrl_t ctrl,
1038                              gcry_sexp_t s_pgp, const char *passphrase,
1039                              unsigned char **r_key)
1040 {
1041   gpg_error_t err;
1042   unsigned char grip[20];
1043
1044   if (!passphrase)
1045     return gpg_error (GPG_ERR_INTERNAL);
1046
1047   err = convert_from_openpgp_main (ctrl, s_pgp, grip, NULL,
1048                                    NULL, passphrase,
1049                                    r_key, NULL);
1050
1051   /* On success try to re-write the key.  */
1052   if (!err)
1053     {
1054       unsigned char *protectedkey = NULL;
1055       size_t protectedkeylen;
1056
1057       if (!agent_protect (*r_key, passphrase, &protectedkey, &protectedkeylen,
1058                           ctrl->s2k_count))
1059         agent_write_private_key (grip, protectedkey, protectedkeylen, 1);
1060       xfree (protectedkey);
1061     }
1062
1063   return err;
1064 }
1065
1066
1067 /* Given an ARRAY of mpis with the key parameters, protect the secret
1068    parameters in that array and replace them by one opaque encoded
1069    mpi.  NPKEY is the number of public key parameters and NSKEY is
1070    the number of secret key parameters (including the public ones).
1071    On success the array will have NPKEY+1 elements.  */
1072 static gpg_error_t
1073 apply_protection (gcry_mpi_t *array, int npkey, int nskey,
1074                   const char *passphrase,
1075                   int protect_algo, void *protect_iv, size_t protect_ivlen,
1076                   int s2k_mode, int s2k_algo, byte *s2k_salt, u32 s2k_count)
1077 {
1078   gpg_error_t err;
1079   int i, j;
1080   gcry_cipher_hd_t cipherhd;
1081   unsigned char *bufarr[10];
1082   size_t narr[10];
1083   unsigned int nbits[10];
1084   int ndata;
1085   unsigned char *p, *data;
1086
1087   assert (npkey < nskey);
1088   assert (nskey < DIM (bufarr));
1089
1090   /* Collect only the secret key parameters into BUFARR et al and
1091      compute the required size of the data buffer.  */
1092   ndata = 20; /* Space for the SHA-1 checksum.  */
1093   for (i = npkey, j = 0; i < nskey; i++, j++ )
1094     {
1095       if (gcry_mpi_get_flag (array[i], GCRYMPI_FLAG_OPAQUE))
1096         {
1097           const void *s;
1098           unsigned int n;
1099
1100           s = gcry_mpi_get_opaque (array[i], &n);
1101           nbits[j] = n;
1102           n = (n+7)/8;
1103           narr[j] = n;
1104           bufarr[j] = gcry_is_secure (s)? xtrymalloc_secure (n):xtrymalloc (n);
1105           if (!bufarr[j])
1106             {
1107               err = gpg_error_from_syserror ();
1108               for (i = 0; i < j; i++)
1109                 xfree (bufarr[i]);
1110               return err;
1111             }
1112           memcpy (bufarr[j], s, n);
1113         }
1114       else
1115         {
1116           err = gcry_mpi_aprint (GCRYMPI_FMT_USG, bufarr+j, narr+j, array[i]);
1117           if (err)
1118             {
1119               for (i = 0; i < j; i++)
1120                 xfree (bufarr[i]);
1121               return err;
1122             }
1123           nbits[j] = gcry_mpi_get_nbits (array[i]);
1124         }
1125       ndata += 2 + narr[j];
1126     }
1127
1128   /* Allocate data buffer and stuff it with the secret key parameters.  */
1129   data = xtrymalloc_secure (ndata);
1130   if (!data)
1131     {
1132       err = gpg_error_from_syserror ();
1133       for (i = 0; i < (nskey-npkey); i++ )
1134         xfree (bufarr[i]);
1135       return err;
1136     }
1137   p = data;
1138   for (i = 0; i < (nskey-npkey); i++ )
1139     {
1140       *p++ = nbits[i] >> 8 ;
1141       *p++ = nbits[i];
1142       memcpy (p, bufarr[i], narr[i]);
1143       p += narr[i];
1144       xfree (bufarr[i]);
1145       bufarr[i] = NULL;
1146     }
1147   assert (p == data + ndata - 20);
1148
1149   /* Append a hash of the secret key parameters.  */
1150   gcry_md_hash_buffer (GCRY_MD_SHA1, p, data, ndata - 20);
1151
1152   /* Encrypt it.  */
1153   err = gcry_cipher_open (&cipherhd, protect_algo,
1154                           GCRY_CIPHER_MODE_CFB, GCRY_CIPHER_SECURE);
1155   if (!err)
1156     err = hash_passphrase_and_set_key (passphrase, cipherhd, protect_algo,
1157                                        s2k_mode, s2k_algo, s2k_salt, s2k_count);
1158   if (!err)
1159     err = gcry_cipher_setiv (cipherhd, protect_iv, protect_ivlen);
1160   if (!err)
1161     err = gcry_cipher_encrypt (cipherhd, data, ndata, NULL, 0);
1162   gcry_cipher_close (cipherhd);
1163   if (err)
1164     {
1165       xfree (data);
1166       return err;
1167     }
1168
1169   /* Replace the secret key parameters in the array by one opaque value.  */
1170   for (i = npkey; i < nskey; i++ )
1171     {
1172       gcry_mpi_release (array[i]);
1173       array[i] = NULL;
1174     }
1175   array[npkey] = gcry_mpi_set_opaque (NULL, data, ndata*8);
1176   return 0;
1177 }
1178
1179
1180 /*
1181  * Examining S_KEY in S-Expression and extract data.
1182  * When REQ_PRIVATE_KEY_DATA == 1, S_KEY's CAR should be 'private-key',
1183  * but it also allows shadowed or protected versions.
1184  * On success, it returns 0, otherwise error number.
1185  * R_ALGONAME is static string which is no need to free by caller.
1186  * R_NPKEY is pointer to number of public key data.
1187  * R_NSKEY is pointer to number of private key data.
1188  * R_ELEMS is static string which is no need to free by caller.
1189  * ARRAY contains public and private key data.
1190  * ARRAYSIZE is the allocated size of the array for cross-checking.
1191  * R_CURVE is pointer to S-Expression of the curve (can be NULL).
1192  * R_FLAGS is pointer to S-Expression of the flags (can be NULL).
1193  */
1194 gpg_error_t
1195 extract_private_key (gcry_sexp_t s_key, int req_private_key_data,
1196                      const char **r_algoname, int *r_npkey, int *r_nskey,
1197                      const char **r_elems,
1198                      gcry_mpi_t *array, int arraysize,
1199                      gcry_sexp_t *r_curve, gcry_sexp_t *r_flags)
1200 {
1201   gpg_error_t err;
1202   gcry_sexp_t list, l2;
1203   char *name;
1204   const char *algoname, *format;
1205   int npkey, nskey;
1206   gcry_sexp_t curve = NULL;
1207   gcry_sexp_t flags = NULL;
1208
1209   *r_curve = NULL;
1210   *r_flags = NULL;
1211
1212   if (!req_private_key_data)
1213     {
1214       list = gcry_sexp_find_token (s_key, "shadowed-private-key", 0 );
1215       if (!list)
1216         list = gcry_sexp_find_token (s_key, "protected-private-key", 0 );
1217       if (!list)
1218         list = gcry_sexp_find_token (s_key, "private-key", 0 );
1219     }
1220   else
1221     list = gcry_sexp_find_token (s_key, "private-key", 0);
1222
1223   if (!list)
1224     {
1225       log_error ("invalid private key format\n");
1226       return gpg_error (GPG_ERR_BAD_SECKEY);
1227     }
1228
1229   l2 = gcry_sexp_cadr (list);
1230   gcry_sexp_release (list);
1231   list = l2;
1232   name = gcry_sexp_nth_string (list, 0);
1233   if (!name)
1234     {
1235       gcry_sexp_release (list);
1236       return gpg_error (GPG_ERR_INV_OBJ); /* Invalid structure of object. */
1237     }
1238
1239   if (arraysize < 7)
1240     BUG ();
1241
1242   /* Map NAME to a name as used by Libgcrypt.  We do not use the
1243      Libgcrypt function here because we need a lowercase name and
1244      require special treatment for some algorithms.  */
1245   strlwr (name);
1246   if (!strcmp (name, "rsa"))
1247     {
1248       algoname = "rsa";
1249       format = "ned?p?q?u?";
1250       npkey = 2;
1251       nskey = 6;
1252       err = gcry_sexp_extract_param (list, NULL, format,
1253                                      array+0, array+1, array+2, array+3,
1254                                      array+4, array+5, NULL);
1255     }
1256   else if (!strcmp (name, "elg"))
1257     {
1258       algoname = "elg";
1259       format = "pgyx?";
1260       npkey = 3;
1261       nskey = 4;
1262       err = gcry_sexp_extract_param (list, NULL, format,
1263                                      array+0, array+1, array+2, array+3,
1264                                      NULL);
1265     }
1266   else if (!strcmp (name, "dsa"))
1267     {
1268       algoname = "dsa";
1269       format = "pqgyx?";
1270       npkey = 4;
1271       nskey = 5;
1272       err = gcry_sexp_extract_param (list, NULL, format,
1273                                      array+0, array+1, array+2, array+3,
1274                                      array+4, NULL);
1275     }
1276   else if (!strcmp (name, "ecc"))
1277     {
1278       algoname = "ecc";
1279       format = "/qd?";
1280       npkey = 1;
1281       nskey = 2;
1282       curve = gcry_sexp_find_token (list, "curve", 0);
1283       flags = gcry_sexp_find_token (list, "flags", 0);
1284       err = gcry_sexp_extract_param (list, NULL, format,
1285                                      array+0, array+1, NULL);
1286       if (flags)
1287         {
1288           gcry_sexp_t param = gcry_sexp_find_token (flags, "param", 0);
1289           if (param)
1290             {
1291               gcry_sexp_release (param);
1292               array[6] = array[0];
1293               array[7] = array[1];
1294               err = gcry_sexp_extract_param (list, NULL, "pabgnh?",
1295                                              array+0, array+1, array+2, array+3,
1296                                              array+4, array+5, NULL);
1297               if (array[5] == NULL)
1298                 {
1299                   array[5] = GCRYMPI_CONST_ONE;
1300                   npkey += 6;
1301                   nskey += 6;
1302                 }
1303               format = "pabgnhqd?";
1304             }
1305         }
1306     }
1307   else if (!strcmp (name, "ecdsa"))
1308     {
1309       algoname = "ecdsa";
1310       format = "pabgnqd?";
1311       npkey = 6;
1312       nskey = 7;
1313       err = gcry_sexp_extract_param (list, NULL, format,
1314                                      array+0, array+1, array+2, array+3,
1315                                      array+4, array+5, array+6, NULL);
1316     }
1317   else if (!strcmp (name, "ecdh"))
1318     {
1319       algoname = "ecdh";
1320       format = "pabgnqd?";
1321       npkey = 6;
1322       nskey= 7;
1323       err = gcry_sexp_extract_param (list, NULL, format,
1324                                      array+0, array+1, array+2, array+3,
1325                                      array+4, array+5, array+6, NULL);
1326     }
1327   else
1328     {
1329       err = gpg_error (GPG_ERR_PUBKEY_ALGO);
1330     }
1331   xfree (name);
1332   gcry_sexp_release (list);
1333   if (err)
1334     {
1335       gcry_sexp_release (curve);
1336       gcry_sexp_release (flags);
1337       return err;
1338     }
1339   else
1340     {
1341       *r_algoname = algoname;
1342       if (r_elems)
1343         {
1344           if (format[0] == '/') /* It is opaque data qualifier, skip it.  */
1345             *r_elems = format+1;
1346           else
1347             *r_elems = format;
1348         }
1349       *r_npkey = npkey;
1350       if (r_nskey)
1351         *r_nskey = nskey;
1352       *r_curve = curve;
1353       *r_flags = flags;
1354
1355       return 0;
1356     }
1357 }
1358
1359 /* Convert our key S_KEY into an OpenPGP key transfer format.  On
1360    success a canonical encoded S-expression is stored at R_TRANSFERKEY
1361    and its length at R_TRANSFERKEYLEN; this S-expression is also
1362    padded to a multiple of 64 bits.  */
1363 gpg_error_t
1364 convert_to_openpgp (ctrl_t ctrl, gcry_sexp_t s_key, const char *passphrase,
1365                     unsigned char **r_transferkey, size_t *r_transferkeylen)
1366 {
1367   gpg_error_t err;
1368   const char *algoname;
1369   int npkey, nskey;
1370   gcry_mpi_t array[10];
1371   gcry_sexp_t curve = NULL;
1372   gcry_sexp_t flags = NULL;
1373   char protect_iv[16];
1374   char salt[8];
1375   unsigned long s2k_count;
1376   int i, j;
1377
1378   (void)ctrl;
1379
1380   *r_transferkey = NULL;
1381
1382   for (i=0; i < DIM (array); i++)
1383     array[i] = NULL;
1384
1385   err = extract_private_key (s_key, 1, &algoname, &npkey, &nskey, NULL,
1386                              array, DIM (array), &curve, &flags);
1387   if (err)
1388     return err;
1389
1390   gcry_create_nonce (protect_iv, sizeof protect_iv);
1391   gcry_create_nonce (salt, sizeof salt);
1392   /* We need to use the encoded S2k count.  It is not possible to
1393      encode it after it has been used because the encoding procedure
1394      may round the value up.  */
1395   s2k_count = get_standard_s2k_count_rfc4880 ();
1396   err = apply_protection (array, npkey, nskey, passphrase,
1397                           GCRY_CIPHER_AES, protect_iv, sizeof protect_iv,
1398                           3, GCRY_MD_SHA1, salt, s2k_count);
1399   /* Turn it into the transfer key S-expression.  Note that we always
1400      return a protected key.  */
1401   if (!err)
1402     {
1403       char countbuf[35];
1404       membuf_t mbuf;
1405       void *format_args[10+2];
1406       gcry_sexp_t tmpkey;
1407       gcry_sexp_t tmpsexp = NULL;
1408
1409       snprintf (countbuf, sizeof countbuf, "%lu", s2k_count);
1410
1411       init_membuf (&mbuf, 50);
1412       put_membuf_str (&mbuf, "(skey");
1413       for (i=j=0; i < npkey; i++)
1414         {
1415           put_membuf_str (&mbuf, " _ %m");
1416           format_args[j++] = array + i;
1417         }
1418       put_membuf_str (&mbuf, " e %m");
1419       format_args[j++] = array + npkey;
1420       put_membuf_str (&mbuf, ")\n");
1421       put_membuf (&mbuf, "", 1);
1422
1423       tmpkey = NULL;
1424       {
1425         char *format = get_membuf (&mbuf, NULL);
1426         if (!format)
1427           err = gpg_error_from_syserror ();
1428         else
1429           err = gcry_sexp_build_array (&tmpkey, NULL, format, format_args);
1430         xfree (format);
1431       }
1432       if (!err)
1433         err = gcry_sexp_build (&tmpsexp, NULL,
1434                                "(openpgp-private-key\n"
1435                                " (version 1:4)\n"
1436                                " (algo %s)\n"
1437                                " %S%S\n"
1438                                " (protection sha1 aes %b 1:3 sha1 %b %s))\n",
1439                                algoname,
1440                                curve,
1441                                tmpkey,
1442                                (int)sizeof protect_iv, protect_iv,
1443                                (int)sizeof salt, salt,
1444                                countbuf);
1445       gcry_sexp_release (tmpkey);
1446       if (!err)
1447         err = make_canon_sexp_pad (tmpsexp, 0, r_transferkey, r_transferkeylen);
1448       gcry_sexp_release (tmpsexp);
1449     }
1450
1451   for (i=0; i < DIM (array); i++)
1452     gcry_mpi_release (array[i]);
1453   gcry_sexp_release (curve);
1454   gcry_sexp_release (flags);
1455
1456   return err;
1457 }