gpg: Install the current release signing pubkey.
[gnupg.git] / g10 / export.c
1 /* export.c - Export keys in the OpenPGP defined format.
2  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
3  *               2005, 2010 Free Software Foundation, Inc.
4  * Copyright (C) 2014  Werner Koch
5  *
6  * This file is part of GnuPG.
7  *
8  * GnuPG is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * GnuPG is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, see <http://www.gnu.org/licenses/>.
20  */
21
22 #include <config.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <errno.h>
27 #include <assert.h>
28
29 #include "gpg.h"
30 #include "options.h"
31 #include "packet.h"
32 #include "status.h"
33 #include "keydb.h"
34 #include "util.h"
35 #include "main.h"
36 #include "i18n.h"
37 #include "trustdb.h"
38 #include "call-agent.h"
39
40 /* An object to keep track of subkeys. */
41 struct subkey_list_s
42 {
43   struct subkey_list_s *next;
44   u32 kid[2];
45 };
46 typedef struct subkey_list_s *subkey_list_t;
47
48
49 static int do_export (ctrl_t ctrl,
50                       strlist_t users, int secret, unsigned int options );
51 static int do_export_stream (ctrl_t ctrl, iobuf_t out,
52                              strlist_t users, int secret,
53                              kbnode_t *keyblock_out, unsigned int options,
54                              int *any);
55 static int build_sexp (iobuf_t out, PACKET *pkt, int *indent);
56
57
58 int
59 parse_export_options(char *str,unsigned int *options,int noisy)
60 {
61   struct parse_options export_opts[]=
62     {
63       {"export-local-sigs",EXPORT_LOCAL_SIGS,NULL,
64        N_("export signatures that are marked as local-only")},
65       {"export-attributes",EXPORT_ATTRIBUTES,NULL,
66        N_("export attribute user IDs (generally photo IDs)")},
67       {"export-sensitive-revkeys",EXPORT_SENSITIVE_REVKEYS,NULL,
68        N_("export revocation keys marked as \"sensitive\"")},
69       {"export-clean",EXPORT_CLEAN,NULL,
70        N_("remove unusable parts from key during export")},
71       {"export-minimal",EXPORT_MINIMAL|EXPORT_CLEAN,NULL,
72        N_("remove as much as possible from key during export")},
73       {"export-sexp-format",EXPORT_SEXP_FORMAT, NULL,
74        N_("export keys in an S-expression based format")},
75       /* Aliases for backward compatibility */
76       {"include-local-sigs",EXPORT_LOCAL_SIGS,NULL,NULL},
77       {"include-attributes",EXPORT_ATTRIBUTES,NULL,NULL},
78       {"include-sensitive-revkeys",EXPORT_SENSITIVE_REVKEYS,NULL,NULL},
79       /* dummy */
80       {"export-unusable-sigs",0,NULL,NULL},
81       {"export-clean-sigs",0,NULL,NULL},
82       {"export-clean-uids",0,NULL,NULL},
83       {NULL,0,NULL,NULL}
84       /* add tags for include revoked and disabled? */
85     };
86
87   return parse_options(str,options,export_opts,noisy);
88 }
89
90
91 /****************
92  * Export the public keys (to standard out or --output).
93  * Depending on opt.armor the output is armored.
94  * options are defined in main.h.
95  * If USERS is NULL, the complete ring will be exported.  */
96 int
97 export_pubkeys (ctrl_t ctrl, strlist_t users, unsigned int options )
98 {
99   return do_export (ctrl, users, 0, options );
100 }
101
102 /****************
103  * Export to an already opened stream; return -1 if no keys have
104  * been exported
105  */
106 int
107 export_pubkeys_stream (ctrl_t ctrl, iobuf_t out, strlist_t users,
108                        kbnode_t *keyblock_out, unsigned int options )
109 {
110   int any, rc;
111
112   rc = do_export_stream (ctrl, out, users, 0, keyblock_out, options, &any);
113   if (!rc && !any)
114     rc = -1;
115   return rc;
116 }
117
118
119 /*
120  * Export a single key into a memory buffer.
121  */
122 gpg_error_t
123 export_pubkey_buffer (ctrl_t ctrl, const char *keyspec, unsigned int options,
124                       kbnode_t *r_keyblock, void **r_data, size_t *r_datalen)
125 {
126   gpg_error_t err;
127   iobuf_t iobuf;
128   int any;
129   strlist_t helplist;
130
131   *r_keyblock = NULL;
132   *r_data = NULL;
133   *r_datalen = 0;
134
135   helplist = NULL;
136   if (!add_to_strlist_try (&helplist, keyspec))
137     return gpg_error_from_syserror ();
138
139   iobuf = iobuf_temp ();
140   err = do_export_stream (ctrl, iobuf, helplist, 0, r_keyblock, options, &any);
141   if (!err && !any)
142     err = gpg_error (GPG_ERR_NOT_FOUND);
143   if (!err)
144     {
145       const void *src;
146       size_t datalen;
147
148       iobuf_flush_temp (iobuf);
149       src = iobuf_get_temp_buffer (iobuf);
150       datalen = iobuf_get_temp_length (iobuf);
151       if (!datalen)
152         err = gpg_error (GPG_ERR_NO_PUBKEY);
153       else if (!(*r_data = xtrymalloc (datalen)))
154         err = gpg_error_from_syserror ();
155       else
156         {
157           memcpy (*r_data, src, datalen);
158           *r_datalen = datalen;
159         }
160     }
161   iobuf_close (iobuf);
162   free_strlist (helplist);
163   if (err && *r_keyblock)
164     {
165       release_kbnode (*r_keyblock);
166       *r_keyblock = NULL;
167     }
168   return err;
169 }
170
171
172 int
173 export_seckeys (ctrl_t ctrl, strlist_t users )
174 {
175   /* Use only relevant options for the secret key. */
176   unsigned int options = (opt.export_options & EXPORT_SEXP_FORMAT);
177   return do_export (ctrl, users, 1, options);
178 }
179
180 int
181 export_secsubkeys (ctrl_t ctrl, strlist_t users )
182 {
183   /* Use only relevant options for the secret key. */
184   unsigned int options = (opt.export_options & EXPORT_SEXP_FORMAT);
185   return do_export (ctrl, users, 2, options);
186 }
187
188
189 /* Export the keys identified by the list of strings in USERS.  If
190    Secret is false public keys will be exported.  With secret true
191    secret keys will be exported; in this case 1 means the entire
192    secret keyblock and 2 only the subkeys.  OPTIONS are the export
193    options to apply.  */
194 static int
195 do_export (ctrl_t ctrl, strlist_t users, int secret, unsigned int options )
196 {
197   IOBUF out = NULL;
198   int any, rc;
199   armor_filter_context_t *afx = NULL;
200   compress_filter_context_t zfx;
201
202   memset( &zfx, 0, sizeof zfx);
203
204   rc = open_outfile (-1, NULL, 0, !!secret, &out );
205   if (rc)
206     return rc;
207
208   if (!(options & EXPORT_SEXP_FORMAT))
209     {
210       if ( opt.armor )
211         {
212           afx = new_armor_context ();
213           afx->what = secret? 5 : 1;
214           push_armor_filter (afx, out);
215         }
216     }
217
218   rc = do_export_stream (ctrl, out, users, secret, NULL, options, &any );
219
220   if ( rc || !any )
221     iobuf_cancel (out);
222   else
223     iobuf_close (out);
224   release_armor_context (afx);
225   return rc;
226 }
227
228
229
230 /* Release an entire subkey list. */
231 static void
232 release_subkey_list (subkey_list_t list)
233 {
234   while (list)
235     {
236       subkey_list_t tmp = list->next;;
237       xfree (list);
238       list = tmp;
239     }
240 }
241
242
243 /* Returns true if NODE is a subkey and contained in LIST. */
244 static int
245 subkey_in_list_p (subkey_list_t list, KBNODE node)
246 {
247   if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
248       || node->pkt->pkttype == PKT_SECRET_SUBKEY )
249     {
250       u32 kid[2];
251
252       keyid_from_pk (node->pkt->pkt.public_key, kid);
253
254       for (; list; list = list->next)
255         if (list->kid[0] == kid[0] && list->kid[1] == kid[1])
256           return 1;
257     }
258   return 0;
259 }
260
261 /* Allocate a new subkey list item from NODE. */
262 static subkey_list_t
263 new_subkey_list_item (KBNODE node)
264 {
265   subkey_list_t list = xcalloc (1, sizeof *list);
266
267   if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
268       || node->pkt->pkttype == PKT_SECRET_SUBKEY)
269     keyid_from_pk (node->pkt->pkt.public_key, list->kid);
270
271   return list;
272 }
273
274
275 /* Helper function to check whether the subkey at NODE actually
276    matches the description at DESC.  The function returns true if the
277    key under question has been specified by an exact specification
278    (keyID or fingerprint) and does match the one at NODE.  It is
279    assumed that the packet at NODE is either a public or secret
280    subkey. */
281 static int
282 exact_subkey_match_p (KEYDB_SEARCH_DESC *desc, KBNODE node)
283 {
284   u32 kid[2];
285   byte fpr[MAX_FINGERPRINT_LEN];
286   size_t fprlen;
287   int result = 0;
288
289   switch(desc->mode)
290     {
291     case KEYDB_SEARCH_MODE_SHORT_KID:
292     case KEYDB_SEARCH_MODE_LONG_KID:
293       keyid_from_pk (node->pkt->pkt.public_key, kid);
294       break;
295
296     case KEYDB_SEARCH_MODE_FPR16:
297     case KEYDB_SEARCH_MODE_FPR20:
298     case KEYDB_SEARCH_MODE_FPR:
299       fingerprint_from_pk (node->pkt->pkt.public_key, fpr,&fprlen);
300       break;
301
302     default:
303       break;
304     }
305
306   switch(desc->mode)
307     {
308     case KEYDB_SEARCH_MODE_SHORT_KID:
309       if (desc->u.kid[1] == kid[1])
310         result = 1;
311       break;
312
313     case KEYDB_SEARCH_MODE_LONG_KID:
314       if (desc->u.kid[0] == kid[0] && desc->u.kid[1] == kid[1])
315         result = 1;
316       break;
317
318     case KEYDB_SEARCH_MODE_FPR16:
319       if (!memcmp (desc->u.fpr, fpr, 16))
320         result = 1;
321       break;
322
323     case KEYDB_SEARCH_MODE_FPR20:
324     case KEYDB_SEARCH_MODE_FPR:
325       if (!memcmp (desc->u.fpr, fpr, 20))
326         result = 1;
327       break;
328
329     default:
330       break;
331     }
332
333   return result;
334 }
335
336
337 /* Return a canonicalized public key algoithms.  This is used to
338    compare different flavors of algorithms (e.g. ELG and ELG_E are
339    considered the same).  */
340 static enum gcry_pk_algos
341 canon_pk_algo (enum gcry_pk_algos algo)
342 {
343   switch (algo)
344     {
345     case GCRY_PK_RSA:
346     case GCRY_PK_RSA_E:
347     case GCRY_PK_RSA_S: return GCRY_PK_RSA;
348     case GCRY_PK_ELG:
349     case GCRY_PK_ELG_E: return GCRY_PK_ELG;
350     case GCRY_PK_ECC:
351     case GCRY_PK_ECDSA:
352     case GCRY_PK_ECDH: return GCRY_PK_ECC;
353     default: return algo;
354     }
355 }
356
357
358 /* Use the key transfer format given in S_PGP to create the secinfo
359    structure in PK and change the parameter array in PK to include the
360    secret parameters.  */
361 static gpg_error_t
362 transfer_format_to_openpgp (gcry_sexp_t s_pgp, PKT_public_key *pk)
363 {
364   gpg_error_t err;
365   gcry_sexp_t top_list;
366   gcry_sexp_t list = NULL;
367   char *curve = NULL;
368   const char *value;
369   size_t valuelen;
370   char *string;
371   int  idx;
372   int  is_v4, is_protected;
373   enum gcry_pk_algos pk_algo;
374   int  protect_algo = 0;
375   char iv[16];
376   int  ivlen = 0;
377   int  s2k_mode = 0;
378   int  s2k_algo = 0;
379   byte s2k_salt[8];
380   u32  s2k_count = 0;
381   int  is_ecdh = 0;
382   size_t npkey, nskey;
383   gcry_mpi_t skey[10];  /* We support up to 9 parameters.  */
384   int skeyidx = 0;
385   struct seckey_info *ski;
386
387   /* gcry_log_debugsxp ("transferkey", s_pgp); */
388   top_list = gcry_sexp_find_token (s_pgp, "openpgp-private-key", 0);
389   if (!top_list)
390     goto bad_seckey;
391
392   list = gcry_sexp_find_token (top_list, "version", 0);
393   if (!list)
394     goto bad_seckey;
395   value = gcry_sexp_nth_data (list, 1, &valuelen);
396   if (!value || valuelen != 1 || !(value[0] == '3' || value[0] == '4'))
397     goto bad_seckey;
398   is_v4 = (value[0] == '4');
399
400   gcry_sexp_release (list);
401   list = gcry_sexp_find_token (top_list, "protection", 0);
402   if (!list)
403     goto bad_seckey;
404   value = gcry_sexp_nth_data (list, 1, &valuelen);
405   if (!value)
406     goto bad_seckey;
407   if (valuelen == 4 && !memcmp (value, "sha1", 4))
408     is_protected = 2;
409   else if (valuelen == 3 && !memcmp (value, "sum", 3))
410     is_protected = 1;
411   else if (valuelen == 4 && !memcmp (value, "none", 4))
412     is_protected = 0;
413   else
414     goto bad_seckey;
415   if (is_protected)
416     {
417       string = gcry_sexp_nth_string (list, 2);
418       if (!string)
419         goto bad_seckey;
420       protect_algo = gcry_cipher_map_name (string);
421       xfree (string);
422
423       value = gcry_sexp_nth_data (list, 3, &valuelen);
424       if (!value || !valuelen || valuelen > sizeof iv)
425         goto bad_seckey;
426       memcpy (iv, value, valuelen);
427       ivlen = valuelen;
428
429       string = gcry_sexp_nth_string (list, 4);
430       if (!string)
431         goto bad_seckey;
432       s2k_mode = strtol (string, NULL, 10);
433       xfree (string);
434
435       string = gcry_sexp_nth_string (list, 5);
436       if (!string)
437         goto bad_seckey;
438       s2k_algo = gcry_md_map_name (string);
439       xfree (string);
440
441       value = gcry_sexp_nth_data (list, 6, &valuelen);
442       if (!value || !valuelen || valuelen > sizeof s2k_salt)
443         goto bad_seckey;
444       memcpy (s2k_salt, value, valuelen);
445
446       string = gcry_sexp_nth_string (list, 7);
447       if (!string)
448         goto bad_seckey;
449       s2k_count = strtoul (string, NULL, 10);
450       xfree (string);
451     }
452
453   /* Parse the gcrypt PK algo and check that it is okay.  */
454   gcry_sexp_release (list);
455   list = gcry_sexp_find_token (top_list, "algo", 0);
456   if (!list)
457     goto bad_seckey;
458   string = gcry_sexp_nth_string (list, 1);
459   if (!string)
460     goto bad_seckey;
461   pk_algo = gcry_pk_map_name (string);
462   xfree (string); string = NULL;
463   if (gcry_pk_algo_info (pk_algo, GCRYCTL_GET_ALGO_NPKEY, NULL, &npkey)
464       || gcry_pk_algo_info (pk_algo, GCRYCTL_GET_ALGO_NSKEY, NULL, &nskey)
465       || !npkey || npkey >= nskey || nskey > PUBKEY_MAX_NSKEY)
466     goto bad_seckey;
467
468   /* Check that the pubkey algo matches the one from the public key.  */
469   switch (canon_pk_algo (pk_algo))
470     {
471     case GCRY_PK_RSA:
472       if (!is_RSA (pk->pubkey_algo))
473         pk_algo = 0;  /* Does not match.  */
474       break;
475     case GCRY_PK_DSA:
476       if (!is_DSA (pk->pubkey_algo))
477         pk_algo = 0;  /* Does not match.  */
478       break;
479     case GCRY_PK_ELG:
480       if (!is_ELGAMAL (pk->pubkey_algo))
481         pk_algo = 0;  /* Does not match.  */
482       break;
483     case GCRY_PK_ECC:
484       if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA)
485         ;
486       else if (pk->pubkey_algo == PUBKEY_ALGO_ECDH)
487         is_ecdh = 1;
488       else if (pk->pubkey_algo == PUBKEY_ALGO_EDDSA)
489         ;
490       else
491         pk_algo = 0;  /* Does not match.  */
492       /* For ECC we do not have the domain parameters thus fix our info.  */
493       npkey = 1;
494       nskey = 2;
495       break;
496     default:
497       pk_algo = 0;   /* Oops.  */
498       break;
499     }
500   if (!pk_algo)
501     {
502       err = gpg_error (GPG_ERR_PUBKEY_ALGO);
503       goto leave;
504     }
505
506   /* Parse the key parameters.  */
507   gcry_sexp_release (list);
508   list = gcry_sexp_find_token (top_list, "skey", 0);
509   if (!list)
510     goto bad_seckey;
511   for (idx=0;;)
512     {
513       int is_enc;
514
515       value = gcry_sexp_nth_data (list, ++idx, &valuelen);
516       if (!value && skeyidx >= npkey)
517         break;  /* Ready.  */
518
519       /* Check for too many parameters.  Note that depending on the
520          protection mode and version number we may see less than NSKEY
521          (but at least NPKEY+1) parameters.  */
522       if (idx >= 2*nskey)
523         goto bad_seckey;
524       if (skeyidx >= DIM (skey)-1)
525         goto bad_seckey;
526
527       if (!value || valuelen != 1 || !(value[0] == '_' || value[0] == 'e'))
528         goto bad_seckey;
529       is_enc = (value[0] == 'e');
530       value = gcry_sexp_nth_data (list, ++idx, &valuelen);
531       if (!value || !valuelen)
532         goto bad_seckey;
533       if (is_enc)
534         {
535           void *p = xtrymalloc (valuelen);
536           if (!p)
537             goto outofmem;
538           memcpy (p, value, valuelen);
539           skey[skeyidx] = gcry_mpi_set_opaque (NULL, p, valuelen*8);
540           if (!skey[skeyidx])
541             goto outofmem;
542         }
543       else
544         {
545           if (gcry_mpi_scan (skey + skeyidx, GCRYMPI_FMT_STD,
546                              value, valuelen, NULL))
547             goto bad_seckey;
548         }
549       skeyidx++;
550     }
551   skey[skeyidx++] = NULL;
552
553   gcry_sexp_release (list); list = NULL;
554
555   /* We have no need for the CSUM value thus we don't parse it.  */
556   /* list = gcry_sexp_find_token (top_list, "csum", 0); */
557   /* if (list) */
558   /*   { */
559   /*     string = gcry_sexp_nth_string (list, 1); */
560   /*     if (!string) */
561   /*       goto bad_seckey; */
562   /*     desired_csum = strtoul (string, NULL, 10); */
563   /*     xfree (string); */
564   /*   } */
565   /* else */
566   /*   desired_csum = 0; */
567   /* gcry_sexp_release (list); list = NULL; */
568
569   /* Get the curve name if any,  */
570   list = gcry_sexp_find_token (top_list, "curve", 0);
571   if (list)
572     {
573       curve = gcry_sexp_nth_string (list, 1);
574       gcry_sexp_release (list); list = NULL;
575     }
576
577   gcry_sexp_release (top_list); top_list = NULL;
578
579   /* log_debug ("XXX is_v4=%d\n", is_v4); */
580   /* log_debug ("XXX pubkey_algo=%d\n", pubkey_algo); */
581   /* log_debug ("XXX is_protected=%d\n", is_protected); */
582   /* log_debug ("XXX protect_algo=%d\n", protect_algo); */
583   /* log_printhex ("XXX iv", iv, ivlen); */
584   /* log_debug ("XXX ivlen=%d\n", ivlen); */
585   /* log_debug ("XXX s2k_mode=%d\n", s2k_mode); */
586   /* log_debug ("XXX s2k_algo=%d\n", s2k_algo); */
587   /* log_printhex ("XXX s2k_salt", s2k_salt, sizeof s2k_salt); */
588   /* log_debug ("XXX s2k_count=%lu\n", (unsigned long)s2k_count); */
589   /* for (idx=0; skey[idx]; idx++) */
590   /*   { */
591   /*     int is_enc = gcry_mpi_get_flag (skey[idx], GCRYMPI_FLAG_OPAQUE); */
592   /*     log_info ("XXX skey[%d]%s:", idx, is_enc? " (enc)":""); */
593   /*     if (is_enc) */
594   /*       { */
595   /*         void *p; */
596   /*         unsigned int nbits; */
597   /*         p = gcry_mpi_get_opaque (skey[idx], &nbits); */
598   /*         log_printhex (NULL, p, (nbits+7)/8); */
599   /*       } */
600   /*     else */
601   /*       gcry_mpi_dump (skey[idx]); */
602   /*     log_printf ("\n"); */
603   /*   } */
604
605   if (!is_v4 || is_protected != 2 )
606     {
607       /* We only support the v4 format and a SHA-1 checksum.  */
608       err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
609       goto leave;
610     }
611
612   /* We need to change the received parameters for ECC algorithms.
613      The transfer format has the curve name and the parameters
614      separate.  We put them all into the SKEY array.  */
615   if (canon_pk_algo (pk_algo) == GCRY_PK_ECC)
616     {
617       const char *oidstr;
618
619       /* Assert that all required parameters are available.  We also
620          check that the array does not contain more parameters than
621          needed (this was used by some beta versions of 2.1.  */
622       if (!curve || !skey[0] || !skey[1] || skey[2])
623         {
624           err = gpg_error (GPG_ERR_INTERNAL);
625           goto leave;
626         }
627
628       oidstr = openpgp_curve_to_oid (curve, NULL);
629       if (!oidstr)
630         {
631           log_error ("no OID known for curve '%s'\n", curve);
632           err = gpg_error (GPG_ERR_UNKNOWN_CURVE);
633           goto leave;
634         }
635       /* Put the curve's OID into into the MPI array.  This requires
636          that we shift Q and D.  For ECDH also insert the KDF parms. */
637       if (is_ecdh)
638         {
639           skey[4] = NULL;
640           skey[3] = skey[1];
641           skey[2] = gcry_mpi_copy (pk->pkey[2]);
642         }
643       else
644         {
645           skey[3] = NULL;
646           skey[2] = skey[1];
647         }
648       skey[1] = skey[0];
649       skey[0] = NULL;
650       err = openpgp_oid_from_str (oidstr, skey + 0);
651       if (err)
652         goto leave;
653       /* Fixup the NPKEY and NSKEY to match OpenPGP reality.  */
654       npkey = 2 + is_ecdh;
655       nskey = 3 + is_ecdh;
656
657       /* for (idx=0; skey[idx]; idx++) */
658       /*   { */
659       /*     log_info ("YYY skey[%d]:", idx); */
660       /*     if (gcry_mpi_get_flag (skey[idx], GCRYMPI_FLAG_OPAQUE)) */
661       /*       { */
662       /*         void *p; */
663       /*         unsigned int nbits; */
664       /*         p = gcry_mpi_get_opaque (skey[idx], &nbits); */
665       /*         log_printhex (NULL, p, (nbits+7)/8); */
666       /*       } */
667       /*     else */
668       /*       gcry_mpi_dump (skey[idx]); */
669       /*     log_printf ("\n"); */
670       /*   } */
671     }
672
673   /* Do some sanity checks.  */
674   if (s2k_count > 255)
675     {
676       /* We expect an already encoded S2K count.  */
677       err = gpg_error (GPG_ERR_INV_DATA);
678       goto leave;
679     }
680   err = openpgp_cipher_test_algo (protect_algo);
681   if (err)
682     goto leave;
683   err = openpgp_md_test_algo (s2k_algo);
684   if (err)
685     goto leave;
686
687   /* Check that the public key parameters match.  Note that since
688      Libgcrypt 1.5 gcry_mpi_cmp handles opaque MPI correctly.  */
689   for (idx=0; idx < npkey; idx++)
690     if (gcry_mpi_cmp (pk->pkey[idx], skey[idx]))
691       {
692         err = gpg_error (GPG_ERR_BAD_PUBKEY);
693         goto leave;
694       }
695
696   /* Check that the first secret key parameter in SKEY is encrypted
697      and that there are no more secret key parameters.  The latter is
698      guaranteed by the v4 packet format.  */
699   if (!gcry_mpi_get_flag (skey[npkey], GCRYMPI_FLAG_OPAQUE))
700     goto bad_seckey;
701   if (npkey+1 < DIM (skey) && skey[npkey+1])
702     goto bad_seckey;
703
704   /* Check that the secret key parameters in PK are all set to NULL. */
705   for (idx=npkey; idx < nskey; idx++)
706     if (pk->pkey[idx])
707       goto bad_seckey;
708
709   /* Now build the protection info. */
710   pk->seckey_info = ski = xtrycalloc (1, sizeof *ski);
711   if (!ski)
712     {
713       err = gpg_error_from_syserror ();
714       goto leave;
715     }
716
717   ski->is_protected = 1;
718   ski->sha1chk = 1;
719   ski->algo = protect_algo;
720   ski->s2k.mode = s2k_mode;
721   ski->s2k.hash_algo = s2k_algo;
722   assert (sizeof ski->s2k.salt == sizeof s2k_salt);
723   memcpy (ski->s2k.salt, s2k_salt, sizeof s2k_salt);
724   ski->s2k.count = s2k_count;
725   assert (ivlen <= sizeof ski->iv);
726   memcpy (ski->iv, iv, ivlen);
727   ski->ivlen = ivlen;
728
729   /* Store the protected secret key parameter.  */
730   pk->pkey[npkey] = skey[npkey];
731   skey[npkey] = NULL;
732
733   /* That's it.  */
734
735  leave:
736   gcry_free (curve);
737   gcry_sexp_release (list);
738   gcry_sexp_release (top_list);
739   for (idx=0; idx < skeyidx; idx++)
740     gcry_mpi_release (skey[idx]);
741   return err;
742
743  bad_seckey:
744   err = gpg_error (GPG_ERR_BAD_SECKEY);
745   goto leave;
746
747  outofmem:
748   err = gpg_error (GPG_ERR_ENOMEM);
749   goto leave;
750 }
751
752 /* Export the keys identified by the list of strings in USERS to the
753    stream OUT.  If Secret is false public keys will be exported.  With
754    secret true secret keys will be exported; in this case 1 means the
755    entire secret keyblock and 2 only the subkeys.  OPTIONS are the
756    export options to apply.  If KEYBLOCK_OUT is not NULL, AND the exit
757    code is zero, a pointer to the first keyblock found and exported
758    will be stored at this address; no other keyblocks are exported in
759    this case.  The caller must free it the returned keyblock.  If any
760    key has been exported true is stored at ANY. */
761 static int
762 do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
763                   kbnode_t *keyblock_out, unsigned int options, int *any)
764 {
765   gpg_error_t err = 0;
766   PACKET pkt;
767   KBNODE keyblock = NULL;
768   KBNODE kbctx, node;
769   size_t ndesc, descindex;
770   KEYDB_SEARCH_DESC *desc = NULL;
771   subkey_list_t subkey_list = NULL;  /* Track already processed subkeys. */
772   KEYDB_HANDLE kdbhd;
773   strlist_t sl;
774   int indent = 0;
775   gcry_cipher_hd_t cipherhd = NULL;
776
777   *any = 0;
778   init_packet (&pkt);
779   kdbhd = keydb_new ();
780
781   if (!users)
782     {
783       ndesc = 1;
784       desc = xcalloc (ndesc, sizeof *desc);
785       desc[0].mode = KEYDB_SEARCH_MODE_FIRST;
786     }
787   else
788     {
789       for (ndesc=0, sl=users; sl; sl = sl->next, ndesc++)
790         ;
791       desc = xmalloc ( ndesc * sizeof *desc);
792
793       for (ndesc=0, sl=users; sl; sl = sl->next)
794         {
795           if (!(err=classify_user_id (sl->d, desc+ndesc, 1)))
796             ndesc++;
797           else
798             log_error (_("key \"%s\" not found: %s\n"),
799                        sl->d, gpg_strerror (err));
800         }
801
802       /* It would be nice to see which of the given users did actually
803          match one in the keyring.  To implement this we need to have
804          a found flag for each entry in desc.  To set this flag we
805          must check all those entries after a match to mark all
806          matched one - currently we stop at the first match.  To do
807          this we need an extra flag to enable this feature.  */
808     }
809
810 #ifdef ENABLE_SELINUX_HACKS
811   if (secret)
812     {
813       log_error (_("exporting secret keys not allowed\n"));
814       err = gpg_error (GPG_ERR_NOT_SUPPORTED);
815       goto leave;
816     }
817 #endif
818
819   /* For secret key export we need to setup a decryption context.  */
820   if (secret)
821     {
822       void *kek = NULL;
823       size_t keklen;
824
825       err = agent_keywrap_key (ctrl, 1, &kek, &keklen);
826       if (err)
827         {
828           log_error ("error getting the KEK: %s\n", gpg_strerror (err));
829           goto leave;
830         }
831
832       /* Prepare a cipher context.  */
833       err = gcry_cipher_open (&cipherhd, GCRY_CIPHER_AES128,
834                               GCRY_CIPHER_MODE_AESWRAP, 0);
835       if (!err)
836         err = gcry_cipher_setkey (cipherhd, kek, keklen);
837       if (err)
838         {
839           log_error ("error setting up an encryption context: %s\n",
840                      gpg_strerror (err));
841           goto leave;
842         }
843       xfree (kek);
844       kek = NULL;
845     }
846
847   while (!(err = keydb_search (kdbhd, desc, ndesc, &descindex)))
848     {
849       int skip_until_subkey = 0;
850       u32 keyid[2];
851       PKT_public_key *pk;
852
853       if (!users)
854         desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
855
856       /* Read the keyblock. */
857       release_kbnode (keyblock);
858       keyblock = NULL;
859       err = keydb_get_keyblock (kdbhd, &keyblock);
860       if (err)
861         {
862           log_error (_("error reading keyblock: %s\n"), gpg_strerror (err));
863           goto leave;
864         }
865
866       node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
867       if (!node)
868         {
869           log_error ("public key packet not found in keyblock - skipped\n");
870           continue;
871         }
872       setup_main_keyids (keyblock);  /* gpg_format_keydesc needs it.  */
873       pk = node->pkt->pkt.public_key;
874       keyid_from_pk (pk, keyid);
875
876       /* If a secret key export is required we need to check whether
877          we have a secret key at all and if so create the seckey_info
878          structure.  */
879       if (secret)
880         {
881           if (agent_probe_any_secret_key (ctrl, keyblock))
882             continue;  /* No secret key (neither primary nor subkey).  */
883
884           /* No v3 keys with GNU mode 1001. */
885           if (secret == 2 && pk->version == 3)
886             {
887               log_info (_("key %s: PGP 2.x style key - skipped\n"),
888                         keystr (keyid));
889               continue;
890             }
891
892           /* The agent does not yet allow to export v3 packets.  It is
893              actually questionable whether we should allow them at
894              all.  */
895           if (pk->version == 3)
896             {
897               log_info ("key %s: PGP 2.x style key (v3) export "
898                         "not yet supported - skipped\n", keystr (keyid));
899               continue;
900             }
901         }
902
903       /* Always do the cleaning on the public key part if requested.
904          Note that we don't yet set this option if we are exporting
905          secret keys.  Note that both export-clean and export-minimal
906          only apply to UID sigs (0x10, 0x11, 0x12, and 0x13).  A
907          designated revocation is never stripped, even with
908          export-minimal set.  */
909       if ((options & EXPORT_CLEAN))
910         clean_key (keyblock, opt.verbose, (options&EXPORT_MINIMAL), NULL, NULL);
911
912       /* And write it. */
913       for (kbctx=NULL; (node = walk_kbnode (keyblock, &kbctx, 0)); )
914         {
915           if (skip_until_subkey)
916             {
917               if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
918                 skip_until_subkey = 0;
919               else
920                 continue;
921             }
922
923           /* We used to use comment packets, but not any longer.  In
924              case we still have comments on a key, strip them here
925              before we call build_packet(). */
926           if (node->pkt->pkttype == PKT_COMMENT)
927             continue;
928
929           /* Make sure that ring_trust packets never get exported. */
930           if (node->pkt->pkttype == PKT_RING_TRUST)
931             continue;
932
933           /* If exact is set, then we only export what was requested
934              (plus the primary key, if the user didn't specifically
935              request it). */
936           if (desc[descindex].exact
937               && node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
938             {
939               if (!exact_subkey_match_p (desc+descindex, node))
940                 {
941                   /* Before skipping this subkey, check whether any
942                      other description wants an exact match on a
943                      subkey and include that subkey into the output
944                      too.  Need to add this subkey to a list so that
945                      it won't get processed a second time.
946
947                      So the first step here is to check that list and
948                      skip in any case if the key is in that list.
949
950                      We need this whole mess because the import
951                      function of GnuPG < 2.1 is not able to merge
952                      secret keys and thus it is useless to output them
953                      as two separate keys and have import merge them.  */
954                   if (subkey_in_list_p (subkey_list, node))
955                     skip_until_subkey = 1; /* Already processed this one. */
956                   else
957                     {
958                       size_t j;
959
960                       for (j=0; j < ndesc; j++)
961                         if (j != descindex && desc[j].exact
962                             && exact_subkey_match_p (desc+j, node))
963                           break;
964                       if (!(j < ndesc))
965                         skip_until_subkey = 1; /* No other one matching. */
966                     }
967                 }
968
969               if(skip_until_subkey)
970                 continue;
971
972               /* Mark this one as processed. */
973               {
974                 subkey_list_t tmp = new_subkey_list_item (node);
975                 tmp->next = subkey_list;
976                 subkey_list = tmp;
977               }
978             }
979
980           if (node->pkt->pkttype == PKT_SIGNATURE)
981             {
982               /* Do not export packets which are marked as not
983                  exportable.  */
984               if (!(options&EXPORT_LOCAL_SIGS)
985                   && !node->pkt->pkt.signature->flags.exportable)
986                 continue; /* not exportable */
987
988               /* Do not export packets with a "sensitive" revocation
989                  key unless the user wants us to.  Note that we do
990                  export these when issuing the actual revocation
991                  (see revoke.c). */
992               if (!(options&EXPORT_SENSITIVE_REVKEYS)
993                   && node->pkt->pkt.signature->revkey)
994                 {
995                   int i;
996
997                   for (i=0;i<node->pkt->pkt.signature->numrevkeys;i++)
998                     if ( (node->pkt->pkt.signature->revkey[i]->class & 0x40))
999                       break;
1000
1001                   if (i < node->pkt->pkt.signature->numrevkeys)
1002                     continue;
1003                 }
1004             }
1005
1006           /* Don't export attribs? */
1007           if (!(options&EXPORT_ATTRIBUTES)
1008               && node->pkt->pkttype == PKT_USER_ID
1009               && node->pkt->pkt.user_id->attrib_data )
1010             {
1011               /* Skip until we get to something that is not an attrib
1012                  or a signature on an attrib */
1013               while (kbctx->next && kbctx->next->pkt->pkttype==PKT_SIGNATURE)
1014                 kbctx = kbctx->next;
1015
1016               continue;
1017             }
1018
1019           if (secret && (node->pkt->pkttype == PKT_PUBLIC_KEY
1020                          || node->pkt->pkttype == PKT_PUBLIC_SUBKEY))
1021             {
1022               u32 subkidbuf[2], *subkid;
1023               char *hexgrip, *serialno;
1024
1025               pk = node->pkt->pkt.public_key;
1026               if (node->pkt->pkttype == PKT_PUBLIC_KEY)
1027                 subkid = NULL;
1028               else
1029                 {
1030                   keyid_from_pk (pk, subkidbuf);
1031                   subkid = subkidbuf;
1032                 }
1033
1034               if (pk->seckey_info)
1035                 {
1036                   log_error ("key %s: oops: seckey_info already set"
1037                              " - skipped\n", keystr_with_sub (keyid, subkid));
1038                   skip_until_subkey = 1;
1039                   continue;
1040                 }
1041
1042               err = hexkeygrip_from_pk (pk, &hexgrip);
1043               if (err)
1044                 {
1045                   log_error ("key %s: error computing keygrip: %s"
1046                              " - skipped\n", keystr_with_sub (keyid, subkid),
1047                              gpg_strerror (err));
1048                   skip_until_subkey = 1;
1049                   err = 0;
1050                   continue;
1051                 }
1052
1053               if (secret == 2 && node->pkt->pkttype == PKT_PUBLIC_KEY)
1054                 {
1055                   /* We are asked not to export the secret parts of
1056                      the primary key.  Make up an error code to create
1057                      the stub.  */
1058                   err = GPG_ERR_NOT_FOUND;
1059                   serialno = NULL;
1060                 }
1061               else
1062                 err = agent_get_keyinfo (ctrl, hexgrip, &serialno);
1063
1064               if ((!err && serialno)
1065                   && secret == 2 && node->pkt->pkttype == PKT_PUBLIC_KEY)
1066                 {
1067                   /* It does not make sense to export a key with its
1068                      primary key on card using a non-key stub.  Thus
1069                      we skip those keys when used with
1070                      --export-secret-subkeys. */
1071                   log_info (_("key %s: key material on-card - skipped\n"),
1072                             keystr_with_sub (keyid, subkid));
1073                   skip_until_subkey = 1;
1074                 }
1075               else if (gpg_err_code (err) == GPG_ERR_NOT_FOUND
1076                        || (!err && serialno))
1077                 {
1078                   /* Create a key stub.  */
1079                   struct seckey_info *ski;
1080                   const char *s;
1081
1082                   pk->seckey_info = ski = xtrycalloc (1, sizeof *ski);
1083                   if (!ski)
1084                     {
1085                       err = gpg_error_from_syserror ();
1086                       xfree (hexgrip);
1087                       goto leave;
1088                     }
1089
1090                   ski->is_protected = 1;
1091                   if (err)
1092                     ski->s2k.mode = 1001; /* GNU dummy (no secret key).  */
1093                   else
1094                     {
1095                       ski->s2k.mode = 1002; /* GNU-divert-to-card.  */
1096                       for (s=serialno; sizeof (ski->ivlen) && *s && s[1];
1097                            ski->ivlen++, s += 2)
1098                         ski->iv[ski->ivlen] = xtoi_2 (s);
1099                     }
1100
1101                   if ((options&EXPORT_SEXP_FORMAT))
1102                     err = build_sexp (out, node->pkt, &indent);
1103                   else
1104                     err = build_packet (out, node->pkt);
1105                 }
1106               else if (!err)
1107                 {
1108                   /* FIXME: Move this spaghetti code into a separate
1109                      function.  */
1110                   unsigned char *wrappedkey = NULL;
1111                   size_t wrappedkeylen;
1112                   unsigned char *key = NULL;
1113                   size_t keylen, realkeylen;
1114                   gcry_sexp_t s_skey;
1115
1116                   if (opt.verbose)
1117                     log_info ("key %s: asking agent for the secret parts\n",
1118                               keystr_with_sub (keyid, subkid));
1119
1120                   {
1121                     char *prompt = gpg_format_keydesc (pk,
1122                                                        FORMAT_KEYDESC_EXPORT,1);
1123                     err = agent_export_key (ctrl, hexgrip, prompt, NULL,
1124                                             &wrappedkey, &wrappedkeylen);
1125                     xfree (prompt);
1126                   }
1127                   if (err)
1128                     goto unwraperror;
1129                   if (wrappedkeylen < 24)
1130                     {
1131                       err = gpg_error (GPG_ERR_INV_LENGTH);
1132                       goto unwraperror;
1133                     }
1134                   keylen = wrappedkeylen - 8;
1135                   key = xtrymalloc_secure (keylen);
1136                   if (!key)
1137                     {
1138                       err = gpg_error_from_syserror ();
1139                       goto unwraperror;
1140                     }
1141                   err = gcry_cipher_decrypt (cipherhd, key, keylen,
1142                                              wrappedkey, wrappedkeylen);
1143                   if (err)
1144                     goto unwraperror;
1145                   realkeylen = gcry_sexp_canon_len (key, keylen, NULL, &err);
1146                   if (!realkeylen)
1147                     goto unwraperror; /* Invalid csexp.  */
1148
1149                   err = gcry_sexp_sscan (&s_skey, NULL, key, realkeylen);
1150                   xfree (key);
1151                   key = NULL;
1152                   if (err)
1153                     goto unwraperror;
1154                   err = transfer_format_to_openpgp (s_skey, pk);
1155                   gcry_sexp_release (s_skey);
1156                   if (err)
1157                     goto unwraperror;
1158
1159                   if ((options&EXPORT_SEXP_FORMAT))
1160                     err = build_sexp (out, node->pkt, &indent);
1161                   else
1162                     err = build_packet (out, node->pkt);
1163                   goto unwraperror_leave;
1164
1165                 unwraperror:
1166                   xfree (wrappedkey);
1167                   xfree (key);
1168                   if (err)
1169                     {
1170                       log_error ("key %s: error receiving key from agent:"
1171                                  " %s%s\n",
1172                                  keystr_with_sub (keyid, subkid),
1173                                  gpg_strerror (err),
1174                                  gpg_err_code (err) == GPG_ERR_FULLY_CANCELED?
1175                                  "":_(" - skipped"));
1176                       if (gpg_err_code (err) == GPG_ERR_FULLY_CANCELED)
1177                         goto leave;
1178                       skip_until_subkey = 1;
1179                       err = 0;
1180                     }
1181                 unwraperror_leave:
1182                   ;
1183                 }
1184               else
1185                 {
1186                   log_error ("key %s: error getting keyinfo from agent: %s"
1187                              " - skipped\n", keystr_with_sub (keyid, subkid),
1188                              gpg_strerror (err));
1189                   skip_until_subkey = 1;
1190                   err = 0;
1191                 }
1192
1193               xfree (pk->seckey_info);
1194               pk->seckey_info = NULL;
1195               xfree (hexgrip);
1196             }
1197           else
1198             {
1199               if ((options&EXPORT_SEXP_FORMAT))
1200                 err = build_sexp (out, node->pkt, &indent);
1201               else
1202                 err = build_packet (out, node->pkt);
1203             }
1204
1205           if (err)
1206             {
1207               log_error ("build_packet(%d) failed: %s\n",
1208                          node->pkt->pkttype, gpg_strerror (err));
1209               goto leave;
1210             }
1211
1212           if (!skip_until_subkey)
1213             *any = 1;
1214         }
1215
1216       if ((options&EXPORT_SEXP_FORMAT) && indent)
1217         {
1218           for (; indent; indent--)
1219             iobuf_put (out, ')');
1220           iobuf_put (out, '\n');
1221         }
1222
1223       if (keyblock_out)
1224         {
1225           *keyblock_out = keyblock;
1226           break;
1227         }
1228     }
1229   if ((options&EXPORT_SEXP_FORMAT) && indent)
1230     {
1231       for (; indent; indent--)
1232         iobuf_put (out, ')');
1233       iobuf_put (out, '\n');
1234     }
1235   if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
1236     err = 0;
1237
1238  leave:
1239   gcry_cipher_close (cipherhd);
1240   release_subkey_list (subkey_list);
1241   xfree(desc);
1242   keydb_release (kdbhd);
1243   if (err || !keyblock_out)
1244     release_kbnode( keyblock );
1245   if( !*any )
1246     log_info(_("WARNING: nothing exported\n"));
1247   return err;
1248 }
1249
1250
1251
1252 /* static int */
1253 /* write_sexp_line (iobuf_t out, int *indent, const char *text) */
1254 /* { */
1255 /*   int i; */
1256
1257 /*   for (i=0; i < *indent; i++) */
1258 /*     iobuf_put (out, ' '); */
1259 /*   iobuf_writestr (out, text); */
1260 /*   return 0; */
1261 /* } */
1262
1263 /* static int */
1264 /* write_sexp_keyparm (iobuf_t out, int *indent, const char *name, gcry_mpi_t a) */
1265 /* { */
1266 /*   int rc; */
1267 /*   unsigned char *buffer; */
1268
1269 /*   write_sexp_line (out, indent, "("); */
1270 /*   iobuf_writestr (out, name); */
1271 /*   iobuf_writestr (out, " #"); */
1272
1273 /*   rc = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buffer, NULL, a); */
1274 /*   assert (!rc); */
1275 /*   iobuf_writestr (out, buffer); */
1276 /*   iobuf_writestr (out, "#)"); */
1277 /*   gcry_free (buffer); */
1278 /*   return 0; */
1279 /* } */
1280
1281 static int
1282 build_sexp_seckey (iobuf_t out, PACKET *pkt, int *indent)
1283 {
1284   (void)out;
1285   (void)pkt;
1286   (void)indent;
1287
1288   /* FIXME: Not yet implemented.  */
1289   return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1290   /* PKT_secret_key *sk = pkt->pkt.secret_key; */
1291   /* char tmpbuf[100]; */
1292
1293   /* if (pkt->pkttype == PKT_SECRET_KEY) */
1294   /*   { */
1295   /*     iobuf_writestr (out, "(openpgp-key\n"); */
1296   /*     (*indent)++; */
1297   /*   } */
1298   /* else */
1299   /*   { */
1300   /*     iobuf_writestr (out, " (subkey\n"); */
1301   /*     (*indent)++; */
1302   /*   } */
1303   /* (*indent)++; */
1304   /* write_sexp_line (out, indent, "(private-key\n"); */
1305   /* (*indent)++; */
1306   /* if (is_RSA (sk->pubkey_algo) && !sk->is_protected) */
1307   /*   { */
1308   /*     write_sexp_line (out, indent, "(rsa\n"); */
1309   /*     (*indent)++; */
1310   /*     write_sexp_keyparm (out, indent, "n", sk->skey[0]); iobuf_put (out,'\n'); */
1311   /*     write_sexp_keyparm (out, indent, "e", sk->skey[1]); iobuf_put (out,'\n'); */
1312   /*     write_sexp_keyparm (out, indent, "d", sk->skey[2]); iobuf_put (out,'\n'); */
1313   /*     write_sexp_keyparm (out, indent, "p", sk->skey[3]); iobuf_put (out,'\n'); */
1314   /*     write_sexp_keyparm (out, indent, "q", sk->skey[4]); iobuf_put (out,'\n'); */
1315   /*     write_sexp_keyparm (out, indent, "u", sk->skey[5]);  */
1316   /*     iobuf_put (out,')'); iobuf_put (out,'\n'); */
1317   /*     (*indent)--; */
1318   /*   } */
1319   /* else if (sk->pubkey_algo == PUBKEY_ALGO_DSA && !sk->is_protected) */
1320   /*   { */
1321   /*     write_sexp_line (out, indent, "(dsa\n"); */
1322   /*     (*indent)++; */
1323   /*     write_sexp_keyparm (out, indent, "p", sk->skey[0]); iobuf_put (out,'\n'); */
1324   /*     write_sexp_keyparm (out, indent, "q", sk->skey[1]); iobuf_put (out,'\n'); */
1325   /*     write_sexp_keyparm (out, indent, "g", sk->skey[2]); iobuf_put (out,'\n'); */
1326   /*     write_sexp_keyparm (out, indent, "y", sk->skey[3]); iobuf_put (out,'\n'); */
1327   /*     write_sexp_keyparm (out, indent, "x", sk->skey[4]); */
1328   /*     iobuf_put (out,')'); iobuf_put (out,'\n'); */
1329   /*     (*indent)--; */
1330   /*   } */
1331   /* else if (sk->pubkey_algo == PUBKEY_ALGO_ECDSA && !sk->is_protected) */
1332   /*   { */
1333   /*     write_sexp_line (out, indent, "(ecdsa\n"); */
1334   /*     (*indent)++;  */
1335   /*     write_sexp_keyparm (out, indent, "c", sk->skey[0]); iobuf_put (out,'\n'); */
1336   /*     write_sexp_keyparm (out, indent, "q", sk->skey[6]); iobuf_put (out,'\n'); */
1337   /*     write_sexp_keyparm (out, indent, "d", sk->skey[7]); */
1338   /*     iobuf_put (out,')'); iobuf_put (out,'\n'); */
1339   /*     (*indent)--; */
1340   /*   } */
1341   /* else if (is_ELGAMAL (sk->pubkey_algo) && !sk->is_protected) */
1342   /*   { */
1343   /*     write_sexp_line (out, indent, "(elg\n"); */
1344   /*     (*indent)++; */
1345   /*     write_sexp_keyparm (out, indent, "p", sk->skey[0]); iobuf_put (out,'\n'); */
1346   /*     write_sexp_keyparm (out, indent, "g", sk->skey[2]); iobuf_put (out,'\n'); */
1347   /*     write_sexp_keyparm (out, indent, "y", sk->skey[3]); iobuf_put (out,'\n'); */
1348   /*     write_sexp_keyparm (out, indent, "x", sk->skey[4]); */
1349   /*     iobuf_put (out,')'); iobuf_put (out,'\n'); */
1350   /*     (*indent)--; */
1351   /*   } */
1352   /* write_sexp_line (out, indent,  "(attrib\n"); (*indent)++; */
1353   /* sprintf (tmpbuf, "(created \"%lu\"", (unsigned long)sk->timestamp); */
1354   /* write_sexp_line (out, indent, tmpbuf); */
1355   /* iobuf_put (out,')'); (*indent)--; /\* close created *\/ */
1356   /* iobuf_put (out,')'); (*indent)--; /\* close attrib *\/ */
1357   /* iobuf_put (out,')'); (*indent)--; /\* close private-key *\/ */
1358   /* if (pkt->pkttype != PKT_SECRET_KEY) */
1359   /*   iobuf_put (out,')'), (*indent)--; /\* close subkey *\/ */
1360   /* iobuf_put (out,'\n'); */
1361
1362   /* return 0; */
1363 }
1364
1365
1366 /* For some packet types we write them in a S-expression format.  This
1367    is still EXPERIMENTAL and subject to change.  */
1368 static int
1369 build_sexp (iobuf_t out, PACKET *pkt, int *indent)
1370 {
1371   int rc;
1372
1373   switch (pkt->pkttype)
1374     {
1375     case PKT_SECRET_KEY:
1376     case PKT_SECRET_SUBKEY:
1377       rc = build_sexp_seckey (out, pkt, indent);
1378       break;
1379     default:
1380       rc = 0;
1381       break;
1382     }
1383   return rc;
1384 }