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