Add option --no-autostart.
[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)
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   /* This check has to go after the ecc adjustments. */
507   if (nskey > PUBKEY_MAX_NSKEY)
508     goto bad_seckey;
509
510   /* Parse the key parameters.  */
511   gcry_sexp_release (list);
512   list = gcry_sexp_find_token (top_list, "skey", 0);
513   if (!list)
514     goto bad_seckey;
515   for (idx=0;;)
516     {
517       int is_enc;
518
519       value = gcry_sexp_nth_data (list, ++idx, &valuelen);
520       if (!value && skeyidx >= npkey)
521         break;  /* Ready.  */
522
523       /* Check for too many parameters.  Note that depending on the
524          protection mode and version number we may see less than NSKEY
525          (but at least NPKEY+1) parameters.  */
526       if (idx >= 2*nskey)
527         goto bad_seckey;
528       if (skeyidx >= DIM (skey)-1)
529         goto bad_seckey;
530
531       if (!value || valuelen != 1 || !(value[0] == '_' || value[0] == 'e'))
532         goto bad_seckey;
533       is_enc = (value[0] == 'e');
534       value = gcry_sexp_nth_data (list, ++idx, &valuelen);
535       if (!value || !valuelen)
536         goto bad_seckey;
537       if (is_enc)
538         {
539           void *p = xtrymalloc (valuelen);
540           if (!p)
541             goto outofmem;
542           memcpy (p, value, valuelen);
543           skey[skeyidx] = gcry_mpi_set_opaque (NULL, p, valuelen*8);
544           if (!skey[skeyidx])
545             goto outofmem;
546         }
547       else
548         {
549           if (gcry_mpi_scan (skey + skeyidx, GCRYMPI_FMT_STD,
550                              value, valuelen, NULL))
551             goto bad_seckey;
552         }
553       skeyidx++;
554     }
555   skey[skeyidx++] = NULL;
556
557   gcry_sexp_release (list); list = NULL;
558
559   /* We have no need for the CSUM value thus we don't parse it.  */
560   /* list = gcry_sexp_find_token (top_list, "csum", 0); */
561   /* if (list) */
562   /*   { */
563   /*     string = gcry_sexp_nth_string (list, 1); */
564   /*     if (!string) */
565   /*       goto bad_seckey; */
566   /*     desired_csum = strtoul (string, NULL, 10); */
567   /*     xfree (string); */
568   /*   } */
569   /* else */
570   /*   desired_csum = 0; */
571   /* gcry_sexp_release (list); list = NULL; */
572
573   /* Get the curve name if any,  */
574   list = gcry_sexp_find_token (top_list, "curve", 0);
575   if (list)
576     {
577       curve = gcry_sexp_nth_string (list, 1);
578       gcry_sexp_release (list); list = NULL;
579     }
580
581   gcry_sexp_release (top_list); top_list = NULL;
582
583   /* log_debug ("XXX is_v4=%d\n", is_v4); */
584   /* log_debug ("XXX pubkey_algo=%d\n", pubkey_algo); */
585   /* log_debug ("XXX is_protected=%d\n", is_protected); */
586   /* log_debug ("XXX protect_algo=%d\n", protect_algo); */
587   /* log_printhex ("XXX iv", iv, ivlen); */
588   /* log_debug ("XXX ivlen=%d\n", ivlen); */
589   /* log_debug ("XXX s2k_mode=%d\n", s2k_mode); */
590   /* log_debug ("XXX s2k_algo=%d\n", s2k_algo); */
591   /* log_printhex ("XXX s2k_salt", s2k_salt, sizeof s2k_salt); */
592   /* log_debug ("XXX s2k_count=%lu\n", (unsigned long)s2k_count); */
593   /* for (idx=0; skey[idx]; idx++) */
594   /*   { */
595   /*     int is_enc = gcry_mpi_get_flag (skey[idx], GCRYMPI_FLAG_OPAQUE); */
596   /*     log_info ("XXX skey[%d]%s:", idx, is_enc? " (enc)":""); */
597   /*     if (is_enc) */
598   /*       { */
599   /*         void *p; */
600   /*         unsigned int nbits; */
601   /*         p = gcry_mpi_get_opaque (skey[idx], &nbits); */
602   /*         log_printhex (NULL, p, (nbits+7)/8); */
603   /*       } */
604   /*     else */
605   /*       gcry_mpi_dump (skey[idx]); */
606   /*     log_printf ("\n"); */
607   /*   } */
608
609   if (!is_v4 || is_protected != 2 )
610     {
611       /* We only support the v4 format and a SHA-1 checksum.  */
612       err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
613       goto leave;
614     }
615
616   /* We need to change the received parameters for ECC algorithms.
617      The transfer format has the curve name and the parameters
618      separate.  We put them all into the SKEY array.  */
619   if (canon_pk_algo (pk_algo) == GCRY_PK_ECC)
620     {
621       const char *oidstr;
622
623       /* Assert that all required parameters are available.  We also
624          check that the array does not contain more parameters than
625          needed (this was used by some beta versions of 2.1.  */
626       if (!curve || !skey[0] || !skey[1] || skey[2])
627         {
628           err = gpg_error (GPG_ERR_INTERNAL);
629           goto leave;
630         }
631
632       oidstr = openpgp_curve_to_oid (curve, NULL);
633       if (!oidstr)
634         {
635           log_error ("no OID known for curve '%s'\n", curve);
636           err = gpg_error (GPG_ERR_UNKNOWN_CURVE);
637           goto leave;
638         }
639       /* Put the curve's OID into into the MPI array.  This requires
640          that we shift Q and D.  For ECDH also insert the KDF parms. */
641       if (is_ecdh)
642         {
643           skey[4] = NULL;
644           skey[3] = skey[1];
645           skey[2] = gcry_mpi_copy (pk->pkey[2]);
646         }
647       else
648         {
649           skey[3] = NULL;
650           skey[2] = skey[1];
651         }
652       skey[1] = skey[0];
653       skey[0] = NULL;
654       err = openpgp_oid_from_str (oidstr, skey + 0);
655       if (err)
656         goto leave;
657       /* Fixup the NPKEY and NSKEY to match OpenPGP reality.  */
658       npkey = 2 + is_ecdh;
659       nskey = 3 + is_ecdh;
660
661       /* for (idx=0; skey[idx]; idx++) */
662       /*   { */
663       /*     log_info ("YYY skey[%d]:", idx); */
664       /*     if (gcry_mpi_get_flag (skey[idx], GCRYMPI_FLAG_OPAQUE)) */
665       /*       { */
666       /*         void *p; */
667       /*         unsigned int nbits; */
668       /*         p = gcry_mpi_get_opaque (skey[idx], &nbits); */
669       /*         log_printhex (NULL, p, (nbits+7)/8); */
670       /*       } */
671       /*     else */
672       /*       gcry_mpi_dump (skey[idx]); */
673       /*     log_printf ("\n"); */
674       /*   } */
675     }
676
677   /* Do some sanity checks.  */
678   if (s2k_count > 255)
679     {
680       /* We expect an already encoded S2K count.  */
681       err = gpg_error (GPG_ERR_INV_DATA);
682       goto leave;
683     }
684   err = openpgp_cipher_test_algo (protect_algo);
685   if (err)
686     goto leave;
687   err = openpgp_md_test_algo (s2k_algo);
688   if (err)
689     goto leave;
690
691   /* Check that the public key parameters match.  Note that since
692      Libgcrypt 1.5 gcry_mpi_cmp handles opaque MPI correctly.  */
693   for (idx=0; idx < npkey; idx++)
694     if (gcry_mpi_cmp (pk->pkey[idx], skey[idx]))
695       {
696         err = gpg_error (GPG_ERR_BAD_PUBKEY);
697         goto leave;
698       }
699
700   /* Check that the first secret key parameter in SKEY is encrypted
701      and that there are no more secret key parameters.  The latter is
702      guaranteed by the v4 packet format.  */
703   if (!gcry_mpi_get_flag (skey[npkey], GCRYMPI_FLAG_OPAQUE))
704     goto bad_seckey;
705   if (npkey+1 < DIM (skey) && skey[npkey+1])
706     goto bad_seckey;
707
708   /* Check that the secret key parameters in PK are all set to NULL. */
709   for (idx=npkey; idx < nskey; idx++)
710     if (pk->pkey[idx])
711       goto bad_seckey;
712
713   /* Now build the protection info. */
714   pk->seckey_info = ski = xtrycalloc (1, sizeof *ski);
715   if (!ski)
716     {
717       err = gpg_error_from_syserror ();
718       goto leave;
719     }
720
721   ski->is_protected = 1;
722   ski->sha1chk = 1;
723   ski->algo = protect_algo;
724   ski->s2k.mode = s2k_mode;
725   ski->s2k.hash_algo = s2k_algo;
726   assert (sizeof ski->s2k.salt == sizeof s2k_salt);
727   memcpy (ski->s2k.salt, s2k_salt, sizeof s2k_salt);
728   ski->s2k.count = s2k_count;
729   assert (ivlen <= sizeof ski->iv);
730   memcpy (ski->iv, iv, ivlen);
731   ski->ivlen = ivlen;
732
733   /* Store the protected secret key parameter.  */
734   pk->pkey[npkey] = skey[npkey];
735   skey[npkey] = NULL;
736
737   /* That's it.  */
738
739  leave:
740   gcry_free (curve);
741   gcry_sexp_release (list);
742   gcry_sexp_release (top_list);
743   for (idx=0; idx < skeyidx; idx++)
744     gcry_mpi_release (skey[idx]);
745   return err;
746
747  bad_seckey:
748   err = gpg_error (GPG_ERR_BAD_SECKEY);
749   goto leave;
750
751  outofmem:
752   err = gpg_error (GPG_ERR_ENOMEM);
753   goto leave;
754 }
755
756 /* Export the keys identified by the list of strings in USERS to the
757    stream OUT.  If Secret is false public keys will be exported.  With
758    secret true secret keys will be exported; in this case 1 means the
759    entire secret keyblock and 2 only the subkeys.  OPTIONS are the
760    export options to apply.  If KEYBLOCK_OUT is not NULL, AND the exit
761    code is zero, a pointer to the first keyblock found and exported
762    will be stored at this address; no other keyblocks are exported in
763    this case.  The caller must free it the returned keyblock.  If any
764    key has been exported true is stored at ANY. */
765 static int
766 do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
767                   kbnode_t *keyblock_out, unsigned int options, int *any)
768 {
769   gpg_error_t err = 0;
770   PACKET pkt;
771   KBNODE keyblock = NULL;
772   KBNODE kbctx, node;
773   size_t ndesc, descindex;
774   KEYDB_SEARCH_DESC *desc = NULL;
775   subkey_list_t subkey_list = NULL;  /* Track already processed subkeys. */
776   KEYDB_HANDLE kdbhd;
777   strlist_t sl;
778   int indent = 0;
779   gcry_cipher_hd_t cipherhd = NULL;
780   char *cache_nonce = NULL;
781
782   *any = 0;
783   init_packet (&pkt);
784   kdbhd = keydb_new ();
785
786   if (!users)
787     {
788       ndesc = 1;
789       desc = xcalloc (ndesc, sizeof *desc);
790       desc[0].mode = KEYDB_SEARCH_MODE_FIRST;
791     }
792   else
793     {
794       for (ndesc=0, sl=users; sl; sl = sl->next, ndesc++)
795         ;
796       desc = xmalloc ( ndesc * sizeof *desc);
797
798       for (ndesc=0, sl=users; sl; sl = sl->next)
799         {
800           if (!(err=classify_user_id (sl->d, desc+ndesc, 1)))
801             ndesc++;
802           else
803             log_error (_("key \"%s\" not found: %s\n"),
804                        sl->d, gpg_strerror (err));
805         }
806
807       /* It would be nice to see which of the given users did actually
808          match one in the keyring.  To implement this we need to have
809          a found flag for each entry in desc.  To set this flag we
810          must check all those entries after a match to mark all
811          matched one - currently we stop at the first match.  To do
812          this we need an extra flag to enable this feature.  */
813     }
814
815 #ifdef ENABLE_SELINUX_HACKS
816   if (secret)
817     {
818       log_error (_("exporting secret keys not allowed\n"));
819       err = gpg_error (GPG_ERR_NOT_SUPPORTED);
820       goto leave;
821     }
822 #endif
823
824   /* For secret key export we need to setup a decryption context.  */
825   if (secret)
826     {
827       void *kek = NULL;
828       size_t keklen;
829
830       err = agent_keywrap_key (ctrl, 1, &kek, &keklen);
831       if (err)
832         {
833           log_error ("error getting the KEK: %s\n", gpg_strerror (err));
834           goto leave;
835         }
836
837       /* Prepare a cipher context.  */
838       err = gcry_cipher_open (&cipherhd, GCRY_CIPHER_AES128,
839                               GCRY_CIPHER_MODE_AESWRAP, 0);
840       if (!err)
841         err = gcry_cipher_setkey (cipherhd, kek, keklen);
842       if (err)
843         {
844           log_error ("error setting up an encryption context: %s\n",
845                      gpg_strerror (err));
846           goto leave;
847         }
848       xfree (kek);
849       kek = NULL;
850     }
851
852   while (!(err = keydb_search (kdbhd, desc, ndesc, &descindex)))
853     {
854       int skip_until_subkey = 0;
855       u32 keyid[2];
856       PKT_public_key *pk;
857
858       if (!users)
859         desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
860
861       /* Read the keyblock. */
862       release_kbnode (keyblock);
863       keyblock = NULL;
864       err = keydb_get_keyblock (kdbhd, &keyblock);
865       if (err)
866         {
867           log_error (_("error reading keyblock: %s\n"), gpg_strerror (err));
868           goto leave;
869         }
870
871       node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
872       if (!node)
873         {
874           log_error ("public key packet not found in keyblock - skipped\n");
875           continue;
876         }
877       setup_main_keyids (keyblock);  /* gpg_format_keydesc needs it.  */
878       pk = node->pkt->pkt.public_key;
879       keyid_from_pk (pk, keyid);
880
881       /* If a secret key export is required we need to check whether
882          we have a secret key at all and if so create the seckey_info
883          structure.  */
884       if (secret)
885         {
886           if (agent_probe_any_secret_key (ctrl, keyblock))
887             continue;  /* No secret key (neither primary nor subkey).  */
888
889           /* No v3 keys with GNU mode 1001. */
890           if (secret == 2 && pk->version == 3)
891             {
892               log_info (_("key %s: PGP 2.x style key - skipped\n"),
893                         keystr (keyid));
894               continue;
895             }
896
897           /* The agent does not yet allow to export v3 packets.  It is
898              actually questionable whether we should allow them at
899              all.  */
900           if (pk->version == 3)
901             {
902               log_info ("key %s: PGP 2.x style key (v3) export "
903                         "not yet supported - skipped\n", keystr (keyid));
904               continue;
905             }
906         }
907
908       /* Always do the cleaning on the public key part if requested.
909          Note that we don't yet set this option if we are exporting
910          secret keys.  Note that both export-clean and export-minimal
911          only apply to UID sigs (0x10, 0x11, 0x12, and 0x13).  A
912          designated revocation is never stripped, even with
913          export-minimal set.  */
914       if ((options & EXPORT_CLEAN))
915         clean_key (keyblock, opt.verbose, (options&EXPORT_MINIMAL), NULL, NULL);
916
917       /* And write it. */
918       xfree (cache_nonce);
919       cache_nonce = NULL;
920       for (kbctx=NULL; (node = walk_kbnode (keyblock, &kbctx, 0)); )
921         {
922           if (skip_until_subkey)
923             {
924               if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
925                 skip_until_subkey = 0;
926               else
927                 continue;
928             }
929
930           /* We used to use comment packets, but not any longer.  In
931              case we still have comments on a key, strip them here
932              before we call build_packet(). */
933           if (node->pkt->pkttype == PKT_COMMENT)
934             continue;
935
936           /* Make sure that ring_trust packets never get exported. */
937           if (node->pkt->pkttype == PKT_RING_TRUST)
938             continue;
939
940           /* If exact is set, then we only export what was requested
941              (plus the primary key, if the user didn't specifically
942              request it). */
943           if (desc[descindex].exact
944               && node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
945             {
946               if (!exact_subkey_match_p (desc+descindex, node))
947                 {
948                   /* Before skipping this subkey, check whether any
949                      other description wants an exact match on a
950                      subkey and include that subkey into the output
951                      too.  Need to add this subkey to a list so that
952                      it won't get processed a second time.
953
954                      So the first step here is to check that list and
955                      skip in any case if the key is in that list.
956
957                      We need this whole mess because the import
958                      function of GnuPG < 2.1 is not able to merge
959                      secret keys and thus it is useless to output them
960                      as two separate keys and have import merge them.  */
961                   if (subkey_in_list_p (subkey_list, node))
962                     skip_until_subkey = 1; /* Already processed this one. */
963                   else
964                     {
965                       size_t j;
966
967                       for (j=0; j < ndesc; j++)
968                         if (j != descindex && desc[j].exact
969                             && exact_subkey_match_p (desc+j, node))
970                           break;
971                       if (!(j < ndesc))
972                         skip_until_subkey = 1; /* No other one matching. */
973                     }
974                 }
975
976               if(skip_until_subkey)
977                 continue;
978
979               /* Mark this one as processed. */
980               {
981                 subkey_list_t tmp = new_subkey_list_item (node);
982                 tmp->next = subkey_list;
983                 subkey_list = tmp;
984               }
985             }
986
987           if (node->pkt->pkttype == PKT_SIGNATURE)
988             {
989               /* Do not export packets which are marked as not
990                  exportable.  */
991               if (!(options&EXPORT_LOCAL_SIGS)
992                   && !node->pkt->pkt.signature->flags.exportable)
993                 continue; /* not exportable */
994
995               /* Do not export packets with a "sensitive" revocation
996                  key unless the user wants us to.  Note that we do
997                  export these when issuing the actual revocation
998                  (see revoke.c). */
999               if (!(options&EXPORT_SENSITIVE_REVKEYS)
1000                   && node->pkt->pkt.signature->revkey)
1001                 {
1002                   int i;
1003
1004                   for (i=0;i<node->pkt->pkt.signature->numrevkeys;i++)
1005                     if ( (node->pkt->pkt.signature->revkey[i]->class & 0x40))
1006                       break;
1007
1008                   if (i < node->pkt->pkt.signature->numrevkeys)
1009                     continue;
1010                 }
1011             }
1012
1013           /* Don't export attribs? */
1014           if (!(options&EXPORT_ATTRIBUTES)
1015               && node->pkt->pkttype == PKT_USER_ID
1016               && node->pkt->pkt.user_id->attrib_data )
1017             {
1018               /* Skip until we get to something that is not an attrib
1019                  or a signature on an attrib */
1020               while (kbctx->next && kbctx->next->pkt->pkttype==PKT_SIGNATURE)
1021                 kbctx = kbctx->next;
1022
1023               continue;
1024             }
1025
1026           if (secret && (node->pkt->pkttype == PKT_PUBLIC_KEY
1027                          || node->pkt->pkttype == PKT_PUBLIC_SUBKEY))
1028             {
1029               u32 subkidbuf[2], *subkid;
1030               char *hexgrip, *serialno;
1031
1032               pk = node->pkt->pkt.public_key;
1033               if (node->pkt->pkttype == PKT_PUBLIC_KEY)
1034                 subkid = NULL;
1035               else
1036                 {
1037                   keyid_from_pk (pk, subkidbuf);
1038                   subkid = subkidbuf;
1039                 }
1040
1041               if (pk->seckey_info)
1042                 {
1043                   log_error ("key %s: oops: seckey_info already set"
1044                              " - skipped\n", keystr_with_sub (keyid, subkid));
1045                   skip_until_subkey = 1;
1046                   continue;
1047                 }
1048
1049               err = hexkeygrip_from_pk (pk, &hexgrip);
1050               if (err)
1051                 {
1052                   log_error ("key %s: error computing keygrip: %s"
1053                              " - skipped\n", keystr_with_sub (keyid, subkid),
1054                              gpg_strerror (err));
1055                   skip_until_subkey = 1;
1056                   err = 0;
1057                   continue;
1058                 }
1059
1060               if (secret == 2 && node->pkt->pkttype == PKT_PUBLIC_KEY)
1061                 {
1062                   /* We are asked not to export the secret parts of
1063                      the primary key.  Make up an error code to create
1064                      the stub.  */
1065                   err = GPG_ERR_NOT_FOUND;
1066                   serialno = NULL;
1067                 }
1068               else
1069                 err = agent_get_keyinfo (ctrl, hexgrip, &serialno);
1070
1071               if ((!err && serialno)
1072                   && secret == 2 && node->pkt->pkttype == PKT_PUBLIC_KEY)
1073                 {
1074                   /* It does not make sense to export a key with its
1075                      primary key on card using a non-key stub.  Thus
1076                      we skip those keys when used with
1077                      --export-secret-subkeys. */
1078                   log_info (_("key %s: key material on-card - skipped\n"),
1079                             keystr_with_sub (keyid, subkid));
1080                   skip_until_subkey = 1;
1081                 }
1082               else if (gpg_err_code (err) == GPG_ERR_NOT_FOUND
1083                        || (!err && serialno))
1084                 {
1085                   /* Create a key stub.  */
1086                   struct seckey_info *ski;
1087                   const char *s;
1088
1089                   pk->seckey_info = ski = xtrycalloc (1, sizeof *ski);
1090                   if (!ski)
1091                     {
1092                       err = gpg_error_from_syserror ();
1093                       xfree (hexgrip);
1094                       goto leave;
1095                     }
1096
1097                   ski->is_protected = 1;
1098                   if (err)
1099                     ski->s2k.mode = 1001; /* GNU dummy (no secret key).  */
1100                   else
1101                     {
1102                       ski->s2k.mode = 1002; /* GNU-divert-to-card.  */
1103                       for (s=serialno; sizeof (ski->ivlen) && *s && s[1];
1104                            ski->ivlen++, s += 2)
1105                         ski->iv[ski->ivlen] = xtoi_2 (s);
1106                     }
1107
1108                   if ((options&EXPORT_SEXP_FORMAT))
1109                     err = build_sexp (out, node->pkt, &indent);
1110                   else
1111                     err = build_packet (out, node->pkt);
1112                 }
1113               else if (!err)
1114                 {
1115                   /* FIXME: Move this spaghetti code into a separate
1116                      function.  */
1117                   unsigned char *wrappedkey = NULL;
1118                   size_t wrappedkeylen;
1119                   unsigned char *key = NULL;
1120                   size_t keylen, realkeylen;
1121                   gcry_sexp_t s_skey;
1122
1123                   if (opt.verbose)
1124                     log_info ("key %s: asking agent for the secret parts\n",
1125                               keystr_with_sub (keyid, subkid));
1126
1127                   {
1128                     char *prompt = gpg_format_keydesc (pk,
1129                                                        FORMAT_KEYDESC_EXPORT,1);
1130                     err = agent_export_key (ctrl, hexgrip, prompt, &cache_nonce,
1131                                             &wrappedkey, &wrappedkeylen);
1132                     xfree (prompt);
1133                   }
1134                   if (err)
1135                     goto unwraperror;
1136                   if (wrappedkeylen < 24)
1137                     {
1138                       err = gpg_error (GPG_ERR_INV_LENGTH);
1139                       goto unwraperror;
1140                     }
1141                   keylen = wrappedkeylen - 8;
1142                   key = xtrymalloc_secure (keylen);
1143                   if (!key)
1144                     {
1145                       err = gpg_error_from_syserror ();
1146                       goto unwraperror;
1147                     }
1148                   err = gcry_cipher_decrypt (cipherhd, key, keylen,
1149                                              wrappedkey, wrappedkeylen);
1150                   if (err)
1151                     goto unwraperror;
1152                   realkeylen = gcry_sexp_canon_len (key, keylen, NULL, &err);
1153                   if (!realkeylen)
1154                     goto unwraperror; /* Invalid csexp.  */
1155
1156                   err = gcry_sexp_sscan (&s_skey, NULL, key, realkeylen);
1157                   xfree (key);
1158                   key = NULL;
1159                   if (err)
1160                     goto unwraperror;
1161                   err = transfer_format_to_openpgp (s_skey, pk);
1162                   gcry_sexp_release (s_skey);
1163                   if (err)
1164                     goto unwraperror;
1165
1166                   if ((options&EXPORT_SEXP_FORMAT))
1167                     err = build_sexp (out, node->pkt, &indent);
1168                   else
1169                     err = build_packet (out, node->pkt);
1170                   goto unwraperror_leave;
1171
1172                 unwraperror:
1173                   xfree (wrappedkey);
1174                   xfree (key);
1175                   if (err)
1176                     {
1177                       log_error ("key %s: error receiving key from agent:"
1178                                  " %s%s\n",
1179                                  keystr_with_sub (keyid, subkid),
1180                                  gpg_strerror (err),
1181                                  gpg_err_code (err) == GPG_ERR_FULLY_CANCELED?
1182                                  "":_(" - skipped"));
1183                       if (gpg_err_code (err) == GPG_ERR_FULLY_CANCELED)
1184                         goto leave;
1185                       skip_until_subkey = 1;
1186                       err = 0;
1187                     }
1188                 unwraperror_leave:
1189                   ;
1190                 }
1191               else
1192                 {
1193                   log_error ("key %s: error getting keyinfo from agent: %s"
1194                              " - skipped\n", keystr_with_sub (keyid, subkid),
1195                              gpg_strerror (err));
1196                   skip_until_subkey = 1;
1197                   err = 0;
1198                 }
1199
1200               xfree (pk->seckey_info);
1201               pk->seckey_info = NULL;
1202               xfree (hexgrip);
1203             }
1204           else
1205             {
1206               if ((options&EXPORT_SEXP_FORMAT))
1207                 err = build_sexp (out, node->pkt, &indent);
1208               else
1209                 err = build_packet (out, node->pkt);
1210             }
1211
1212           if (err)
1213             {
1214               log_error ("build_packet(%d) failed: %s\n",
1215                          node->pkt->pkttype, gpg_strerror (err));
1216               goto leave;
1217             }
1218
1219           if (!skip_until_subkey)
1220             *any = 1;
1221         }
1222
1223       if ((options&EXPORT_SEXP_FORMAT) && indent)
1224         {
1225           for (; indent; indent--)
1226             iobuf_put (out, ')');
1227           iobuf_put (out, '\n');
1228         }
1229
1230       if (keyblock_out)
1231         {
1232           *keyblock_out = keyblock;
1233           break;
1234         }
1235     }
1236   if ((options&EXPORT_SEXP_FORMAT) && indent)
1237     {
1238       for (; indent; indent--)
1239         iobuf_put (out, ')');
1240       iobuf_put (out, '\n');
1241     }
1242   if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
1243     err = 0;
1244
1245  leave:
1246   gcry_cipher_close (cipherhd);
1247   release_subkey_list (subkey_list);
1248   xfree(desc);
1249   keydb_release (kdbhd);
1250   if (err || !keyblock_out)
1251     release_kbnode( keyblock );
1252   xfree (cache_nonce);
1253   if( !*any )
1254     log_info(_("WARNING: nothing exported\n"));
1255   return err;
1256 }
1257
1258
1259
1260 /* static int */
1261 /* write_sexp_line (iobuf_t out, int *indent, const char *text) */
1262 /* { */
1263 /*   int i; */
1264
1265 /*   for (i=0; i < *indent; i++) */
1266 /*     iobuf_put (out, ' '); */
1267 /*   iobuf_writestr (out, text); */
1268 /*   return 0; */
1269 /* } */
1270
1271 /* static int */
1272 /* write_sexp_keyparm (iobuf_t out, int *indent, const char *name, gcry_mpi_t a) */
1273 /* { */
1274 /*   int rc; */
1275 /*   unsigned char *buffer; */
1276
1277 /*   write_sexp_line (out, indent, "("); */
1278 /*   iobuf_writestr (out, name); */
1279 /*   iobuf_writestr (out, " #"); */
1280
1281 /*   rc = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buffer, NULL, a); */
1282 /*   assert (!rc); */
1283 /*   iobuf_writestr (out, buffer); */
1284 /*   iobuf_writestr (out, "#)"); */
1285 /*   gcry_free (buffer); */
1286 /*   return 0; */
1287 /* } */
1288
1289 static int
1290 build_sexp_seckey (iobuf_t out, PACKET *pkt, int *indent)
1291 {
1292   (void)out;
1293   (void)pkt;
1294   (void)indent;
1295
1296   /* FIXME: Not yet implemented.  */
1297   return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1298   /* PKT_secret_key *sk = pkt->pkt.secret_key; */
1299   /* char tmpbuf[100]; */
1300
1301   /* if (pkt->pkttype == PKT_SECRET_KEY) */
1302   /*   { */
1303   /*     iobuf_writestr (out, "(openpgp-key\n"); */
1304   /*     (*indent)++; */
1305   /*   } */
1306   /* else */
1307   /*   { */
1308   /*     iobuf_writestr (out, " (subkey\n"); */
1309   /*     (*indent)++; */
1310   /*   } */
1311   /* (*indent)++; */
1312   /* write_sexp_line (out, indent, "(private-key\n"); */
1313   /* (*indent)++; */
1314   /* if (is_RSA (sk->pubkey_algo) && !sk->is_protected) */
1315   /*   { */
1316   /*     write_sexp_line (out, indent, "(rsa\n"); */
1317   /*     (*indent)++; */
1318   /*     write_sexp_keyparm (out, indent, "n", sk->skey[0]); iobuf_put (out,'\n'); */
1319   /*     write_sexp_keyparm (out, indent, "e", sk->skey[1]); iobuf_put (out,'\n'); */
1320   /*     write_sexp_keyparm (out, indent, "d", sk->skey[2]); iobuf_put (out,'\n'); */
1321   /*     write_sexp_keyparm (out, indent, "p", sk->skey[3]); iobuf_put (out,'\n'); */
1322   /*     write_sexp_keyparm (out, indent, "q", sk->skey[4]); iobuf_put (out,'\n'); */
1323   /*     write_sexp_keyparm (out, indent, "u", sk->skey[5]);  */
1324   /*     iobuf_put (out,')'); iobuf_put (out,'\n'); */
1325   /*     (*indent)--; */
1326   /*   } */
1327   /* else if (sk->pubkey_algo == PUBKEY_ALGO_DSA && !sk->is_protected) */
1328   /*   { */
1329   /*     write_sexp_line (out, indent, "(dsa\n"); */
1330   /*     (*indent)++; */
1331   /*     write_sexp_keyparm (out, indent, "p", sk->skey[0]); iobuf_put (out,'\n'); */
1332   /*     write_sexp_keyparm (out, indent, "q", sk->skey[1]); iobuf_put (out,'\n'); */
1333   /*     write_sexp_keyparm (out, indent, "g", sk->skey[2]); iobuf_put (out,'\n'); */
1334   /*     write_sexp_keyparm (out, indent, "y", sk->skey[3]); iobuf_put (out,'\n'); */
1335   /*     write_sexp_keyparm (out, indent, "x", sk->skey[4]); */
1336   /*     iobuf_put (out,')'); iobuf_put (out,'\n'); */
1337   /*     (*indent)--; */
1338   /*   } */
1339   /* else if (sk->pubkey_algo == PUBKEY_ALGO_ECDSA && !sk->is_protected) */
1340   /*   { */
1341   /*     write_sexp_line (out, indent, "(ecdsa\n"); */
1342   /*     (*indent)++;  */
1343   /*     write_sexp_keyparm (out, indent, "c", sk->skey[0]); iobuf_put (out,'\n'); */
1344   /*     write_sexp_keyparm (out, indent, "q", sk->skey[6]); iobuf_put (out,'\n'); */
1345   /*     write_sexp_keyparm (out, indent, "d", sk->skey[7]); */
1346   /*     iobuf_put (out,')'); iobuf_put (out,'\n'); */
1347   /*     (*indent)--; */
1348   /*   } */
1349   /* else if (is_ELGAMAL (sk->pubkey_algo) && !sk->is_protected) */
1350   /*   { */
1351   /*     write_sexp_line (out, indent, "(elg\n"); */
1352   /*     (*indent)++; */
1353   /*     write_sexp_keyparm (out, indent, "p", sk->skey[0]); iobuf_put (out,'\n'); */
1354   /*     write_sexp_keyparm (out, indent, "g", sk->skey[2]); iobuf_put (out,'\n'); */
1355   /*     write_sexp_keyparm (out, indent, "y", sk->skey[3]); iobuf_put (out,'\n'); */
1356   /*     write_sexp_keyparm (out, indent, "x", sk->skey[4]); */
1357   /*     iobuf_put (out,')'); iobuf_put (out,'\n'); */
1358   /*     (*indent)--; */
1359   /*   } */
1360   /* write_sexp_line (out, indent,  "(attrib\n"); (*indent)++; */
1361   /* sprintf (tmpbuf, "(created \"%lu\"", (unsigned long)sk->timestamp); */
1362   /* write_sexp_line (out, indent, tmpbuf); */
1363   /* iobuf_put (out,')'); (*indent)--; /\* close created *\/ */
1364   /* iobuf_put (out,')'); (*indent)--; /\* close attrib *\/ */
1365   /* iobuf_put (out,')'); (*indent)--; /\* close private-key *\/ */
1366   /* if (pkt->pkttype != PKT_SECRET_KEY) */
1367   /*   iobuf_put (out,')'), (*indent)--; /\* close subkey *\/ */
1368   /* iobuf_put (out,'\n'); */
1369
1370   /* return 0; */
1371 }
1372
1373
1374 /* For some packet types we write them in a S-expression format.  This
1375    is still EXPERIMENTAL and subject to change.  */
1376 static int
1377 build_sexp (iobuf_t out, PACKET *pkt, int *indent)
1378 {
1379   int rc;
1380
1381   switch (pkt->pkttype)
1382     {
1383     case PKT_SECRET_KEY:
1384     case PKT_SECRET_SUBKEY:
1385       rc = build_sexp_seckey (out, pkt, indent);
1386       break;
1387     default:
1388       rc = 0;
1389       break;
1390     }
1391   return rc;
1392 }