gpg: Copy the correct digest for use by TOFU.
[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) 1998-2016  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
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 "membuf.h"
37 #include "host2net.h"
38 #include "zb32.h"
39 #include "recsel.h"
40 #include "mbox-util.h"
41 #include "init.h"
42 #include "trustdb.h"
43 #include "call-agent.h"
44
45 /* An object to keep track of subkeys. */
46 struct subkey_list_s
47 {
48   struct subkey_list_s *next;
49   u32 kid[2];
50 };
51 typedef struct subkey_list_s *subkey_list_t;
52
53
54 /* An object to track statistics for export operations.  */
55 struct export_stats_s
56 {
57   ulong count;            /* Number of processed keys.        */
58   ulong secret_count;     /* Number of secret keys seen.      */
59   ulong exported;         /* Number of actual exported keys.  */
60 };
61
62
63 /* A global variable to store the selector created from
64  * --export-filter keep-uid=EXPR.
65  *
66  * FIXME: We should put this into the CTRL object but that requires a
67  * lot more changes right now.
68  */
69 static recsel_expr_t export_keep_uid;
70
71
72
73 /* Local prototypes.  */
74 static int do_export (ctrl_t ctrl, strlist_t users, int secret,
75                       unsigned int options, export_stats_t stats);
76 static int do_export_stream (ctrl_t ctrl, iobuf_t out,
77                              strlist_t users, int secret,
78                              kbnode_t *keyblock_out, unsigned int options,
79                              export_stats_t stats, int *any);
80 static gpg_error_t print_pka_or_dane_records
81 /**/                 (iobuf_t out, kbnode_t keyblock, PKT_public_key *pk,
82                       const void *data, size_t datalen,
83                       int print_pka, int print_dane);
84
85 \f
86 static void
87 cleanup_export_globals (void)
88 {
89   recsel_release (export_keep_uid);
90   export_keep_uid = NULL;
91 }
92
93
94 /* Option parser for export options.  See parse_options fro
95    details.  */
96 int
97 parse_export_options(char *str,unsigned int *options,int noisy)
98 {
99   struct parse_options export_opts[]=
100     {
101       {"export-local-sigs",EXPORT_LOCAL_SIGS,NULL,
102        N_("export signatures that are marked as local-only")},
103       {"export-attributes",EXPORT_ATTRIBUTES,NULL,
104        N_("export attribute user IDs (generally photo IDs)")},
105       {"export-sensitive-revkeys",EXPORT_SENSITIVE_REVKEYS,NULL,
106        N_("export revocation keys marked as \"sensitive\"")},
107       {"export-clean",EXPORT_CLEAN,NULL,
108        N_("remove unusable parts from key during export")},
109       {"export-minimal",EXPORT_MINIMAL|EXPORT_CLEAN,NULL,
110        N_("remove as much as possible from key during export")},
111
112       {"export-pka", EXPORT_PKA_FORMAT, NULL, NULL },
113       {"export-dane", EXPORT_DANE_FORMAT, NULL, NULL },
114
115       /* Aliases for backward compatibility */
116       {"include-local-sigs",EXPORT_LOCAL_SIGS,NULL,NULL},
117       {"include-attributes",EXPORT_ATTRIBUTES,NULL,NULL},
118       {"include-sensitive-revkeys",EXPORT_SENSITIVE_REVKEYS,NULL,NULL},
119       /* dummy */
120       {"export-unusable-sigs",0,NULL,NULL},
121       {"export-clean-sigs",0,NULL,NULL},
122       {"export-clean-uids",0,NULL,NULL},
123       {NULL,0,NULL,NULL}
124       /* add tags for include revoked and disabled? */
125     };
126
127   return parse_options(str,options,export_opts,noisy);
128 }
129
130
131 /* Parse and set an export filter from string.  STRING has the format
132  * "NAME=EXPR" with NAME being the name of the filter.  Spaces before
133  * and after NAME are not allowed.  If this function is called several
134  * times all expressions for the same NAME are concatenated.
135  * Supported filter names are:
136  *
137  *  - keep-uid :: If the expression evaluates to true for a certain
138  *                user ID packet, that packet and all it dependencies
139  *                will be exported.  The expression may use these
140  *                variables:
141  *
142  *                - uid  :: The entire user ID.
143  *                - mbox :: The mail box part of the user ID.
144  *                - primary :: Evaluate to true for the primary user ID.
145  */
146 gpg_error_t
147 parse_and_set_export_filter (const char *string)
148 {
149   gpg_error_t err;
150
151   /* Auto register the cleanup function.  */
152   register_mem_cleanup_func (cleanup_export_globals);
153
154   if (!strncmp (string, "keep-uid=", 9))
155     err = recsel_parse_expr (&export_keep_uid, string+9);
156   else
157     err = gpg_error (GPG_ERR_INV_NAME);
158
159   return err;
160 }
161
162
163 /* Create a new export stats object initialized to zero.  On error
164    returns NULL and sets ERRNO.  */
165 export_stats_t
166 export_new_stats (void)
167 {
168   export_stats_t stats;
169
170   return xtrycalloc (1, sizeof *stats);
171 }
172
173
174 /* Release an export stats object.  */
175 void
176 export_release_stats (export_stats_t stats)
177 {
178   xfree (stats);
179 }
180
181
182 /* Print export statistics using the status interface.  */
183 void
184 export_print_stats (export_stats_t stats)
185 {
186   if (!stats)
187     return;
188
189   if (is_status_enabled ())
190     {
191       char buf[15*20];
192
193       snprintf (buf, sizeof buf, "%lu %lu %lu",
194                 stats->count,
195                 stats->secret_count,
196                 stats->exported );
197       write_status_text (STATUS_EXPORT_RES, buf);
198     }
199 }
200
201
202 /*
203  * Export public keys (to stdout or to --output FILE).
204  *
205  * Depending on opt.armor the output is armored.  OPTIONS are defined
206  * in main.h.  If USERS is NULL, all keys will be exported.  STATS is
207  * either an export stats object for update or NULL.
208  *
209  * This function is the core of "gpg --export".
210  */
211 int
212 export_pubkeys (ctrl_t ctrl, strlist_t users, unsigned int options,
213                 export_stats_t stats)
214 {
215   return do_export (ctrl, users, 0, options, stats);
216 }
217
218
219 /*
220  * Export secret keys (to stdout or to --output FILE).
221  *
222  * Depending on opt.armor the output is armored.  If USERS is NULL,
223  * all secret keys will be exported.  STATS is either an export stats
224  * object for update or NULL.
225  *
226  * This function is the core of "gpg --export-secret-keys".
227  */
228 int
229 export_seckeys (ctrl_t ctrl, strlist_t users, export_stats_t stats)
230 {
231   return do_export (ctrl, users, 1, 0, stats);
232 }
233
234
235 /*
236  * Export secret sub keys (to stdout or to --output FILE).
237  *
238  * This is the same as export_seckeys but replaces the primary key by
239  * a stub key.  Depending on opt.armor the output is armored.  If
240  * USERS is NULL, all secret subkeys will be exported.  STATS is
241  * either an export stats object for update or NULL.
242  *
243  * This function is the core of "gpg --export-secret-subkeys".
244  */
245 int
246 export_secsubkeys (ctrl_t ctrl, strlist_t users, export_stats_t stats)
247 {
248   return do_export (ctrl, users, 2, 0, stats);
249 }
250
251
252 /*
253  * Export a single key into a memory buffer.  STATS is either an
254  * export stats object for update or NULL.
255  */
256 gpg_error_t
257 export_pubkey_buffer (ctrl_t ctrl, const char *keyspec, unsigned int options,
258                       export_stats_t stats,
259                       kbnode_t *r_keyblock, void **r_data, size_t *r_datalen)
260 {
261   gpg_error_t err;
262   iobuf_t iobuf;
263   int any;
264   strlist_t helplist;
265
266   *r_keyblock = NULL;
267   *r_data = NULL;
268   *r_datalen = 0;
269
270   helplist = NULL;
271   if (!add_to_strlist_try (&helplist, keyspec))
272     return gpg_error_from_syserror ();
273
274   iobuf = iobuf_temp ();
275   err = do_export_stream (ctrl, iobuf, helplist, 0, r_keyblock, options,
276                           stats, &any);
277   if (!err && !any)
278     err = gpg_error (GPG_ERR_NOT_FOUND);
279   if (!err)
280     {
281       const void *src;
282       size_t datalen;
283
284       iobuf_flush_temp (iobuf);
285       src = iobuf_get_temp_buffer (iobuf);
286       datalen = iobuf_get_temp_length (iobuf);
287       if (!datalen)
288         err = gpg_error (GPG_ERR_NO_PUBKEY);
289       else if (!(*r_data = xtrymalloc (datalen)))
290         err = gpg_error_from_syserror ();
291       else
292         {
293           memcpy (*r_data, src, datalen);
294           *r_datalen = datalen;
295         }
296     }
297   iobuf_close (iobuf);
298   free_strlist (helplist);
299   if (err && *r_keyblock)
300     {
301       release_kbnode (*r_keyblock);
302       *r_keyblock = NULL;
303     }
304   return err;
305 }
306
307
308 /* Export the keys identified by the list of strings in USERS.  If
309    Secret is false public keys will be exported.  With secret true
310    secret keys will be exported; in this case 1 means the entire
311    secret keyblock and 2 only the subkeys.  OPTIONS are the export
312    options to apply.  */
313 static int
314 do_export (ctrl_t ctrl, strlist_t users, int secret, unsigned int options,
315            export_stats_t stats)
316 {
317   IOBUF out = NULL;
318   int any, rc;
319   armor_filter_context_t *afx = NULL;
320   compress_filter_context_t zfx;
321
322   memset( &zfx, 0, sizeof zfx);
323
324   rc = open_outfile (-1, NULL, 0, !!secret, &out );
325   if (rc)
326     return rc;
327
328   if ( opt.armor && !(options & (EXPORT_PKA_FORMAT|EXPORT_DANE_FORMAT)) )
329     {
330       afx = new_armor_context ();
331       afx->what = secret? 5 : 1;
332       push_armor_filter (afx, out);
333     }
334
335   rc = do_export_stream (ctrl, out, users, secret, NULL, options, stats, &any);
336
337   if ( rc || !any )
338     iobuf_cancel (out);
339   else
340     iobuf_close (out);
341   release_armor_context (afx);
342   return rc;
343 }
344
345
346
347 /* Release an entire subkey list. */
348 static void
349 release_subkey_list (subkey_list_t list)
350 {
351   while (list)
352     {
353       subkey_list_t tmp = list->next;;
354       xfree (list);
355       list = tmp;
356     }
357 }
358
359
360 /* Returns true if NODE is a subkey and contained in LIST. */
361 static int
362 subkey_in_list_p (subkey_list_t list, KBNODE node)
363 {
364   if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
365       || node->pkt->pkttype == PKT_SECRET_SUBKEY )
366     {
367       u32 kid[2];
368
369       keyid_from_pk (node->pkt->pkt.public_key, kid);
370
371       for (; list; list = list->next)
372         if (list->kid[0] == kid[0] && list->kid[1] == kid[1])
373           return 1;
374     }
375   return 0;
376 }
377
378 /* Allocate a new subkey list item from NODE. */
379 static subkey_list_t
380 new_subkey_list_item (KBNODE node)
381 {
382   subkey_list_t list = xcalloc (1, sizeof *list);
383
384   if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
385       || node->pkt->pkttype == PKT_SECRET_SUBKEY)
386     keyid_from_pk (node->pkt->pkt.public_key, list->kid);
387
388   return list;
389 }
390
391
392 /* Helper function to check whether the subkey at NODE actually
393    matches the description at DESC.  The function returns true if the
394    key under question has been specified by an exact specification
395    (keyID or fingerprint) and does match the one at NODE.  It is
396    assumed that the packet at NODE is either a public or secret
397    subkey. */
398 static int
399 exact_subkey_match_p (KEYDB_SEARCH_DESC *desc, KBNODE node)
400 {
401   u32 kid[2];
402   byte fpr[MAX_FINGERPRINT_LEN];
403   size_t fprlen;
404   int result = 0;
405
406   switch(desc->mode)
407     {
408     case KEYDB_SEARCH_MODE_SHORT_KID:
409     case KEYDB_SEARCH_MODE_LONG_KID:
410       keyid_from_pk (node->pkt->pkt.public_key, kid);
411       break;
412
413     case KEYDB_SEARCH_MODE_FPR16:
414     case KEYDB_SEARCH_MODE_FPR20:
415     case KEYDB_SEARCH_MODE_FPR:
416       fingerprint_from_pk (node->pkt->pkt.public_key, fpr,&fprlen);
417       break;
418
419     default:
420       break;
421     }
422
423   switch(desc->mode)
424     {
425     case KEYDB_SEARCH_MODE_SHORT_KID:
426       if (desc->u.kid[1] == kid[1])
427         result = 1;
428       break;
429
430     case KEYDB_SEARCH_MODE_LONG_KID:
431       if (desc->u.kid[0] == kid[0] && desc->u.kid[1] == kid[1])
432         result = 1;
433       break;
434
435     case KEYDB_SEARCH_MODE_FPR16:
436       if (!memcmp (desc->u.fpr, fpr, 16))
437         result = 1;
438       break;
439
440     case KEYDB_SEARCH_MODE_FPR20:
441     case KEYDB_SEARCH_MODE_FPR:
442       if (!memcmp (desc->u.fpr, fpr, 20))
443         result = 1;
444       break;
445
446     default:
447       break;
448     }
449
450   return result;
451 }
452
453
454 /* Return an error if the key represented by the S-expression S_KEY
455  * and the OpenPGP key represented by PK do not use the same curve. */
456 static gpg_error_t
457 match_curve_skey_pk (gcry_sexp_t s_key, PKT_public_key *pk)
458 {
459   gcry_sexp_t curve = NULL;
460   gcry_sexp_t flags = NULL;
461   char *curve_str = NULL;
462   char *flag;
463   const char *oidstr = NULL;
464   gcry_mpi_t curve_as_mpi = NULL;
465   gpg_error_t err;
466   int is_eddsa = 0;
467   int idx = 0;
468
469   if (!(pk->pubkey_algo==PUBKEY_ALGO_ECDH
470         || pk->pubkey_algo==PUBKEY_ALGO_ECDSA
471         || pk->pubkey_algo==PUBKEY_ALGO_EDDSA))
472     return gpg_error (GPG_ERR_PUBKEY_ALGO);
473
474   curve = gcry_sexp_find_token (s_key, "curve", 0);
475   if (!curve)
476     {
477       log_error ("no reported curve\n");
478       return gpg_error (GPG_ERR_UNKNOWN_CURVE);
479     }
480   curve_str = gcry_sexp_nth_string (curve, 1);
481   gcry_sexp_release (curve); curve = NULL;
482   if (!curve_str)
483     {
484       log_error ("no curve name\n");
485       return gpg_error (GPG_ERR_UNKNOWN_CURVE);
486     }
487   oidstr = openpgp_curve_to_oid (curve_str, NULL);
488   if (!oidstr)
489     {
490       log_error ("no OID known for curve '%s'\n", curve_str);
491       xfree (curve_str);
492       return gpg_error (GPG_ERR_UNKNOWN_CURVE);
493     }
494   xfree (curve_str);
495   err = openpgp_oid_from_str (oidstr, &curve_as_mpi);
496   if (err)
497     return err;
498   if (gcry_mpi_cmp (pk->pkey[0], curve_as_mpi))
499     {
500       log_error ("curves do not match\n");
501       gcry_mpi_release (curve_as_mpi);
502       return gpg_error (GPG_ERR_INV_CURVE);
503     }
504   gcry_mpi_release (curve_as_mpi);
505   flags = gcry_sexp_find_token (s_key, "flags", 0);
506   if (flags)
507     {
508       for (idx = 1; idx < gcry_sexp_length (flags); idx++)
509         {
510           flag = gcry_sexp_nth_string (flags, idx);
511           if (flag && (strcmp ("eddsa", flag) == 0))
512             is_eddsa = 1;
513           gcry_free (flag);
514         }
515     }
516   if (is_eddsa != (pk->pubkey_algo == PUBKEY_ALGO_EDDSA))
517     {
518       log_error ("disagreement about EdDSA\n");
519       err = gpg_error (GPG_ERR_INV_CURVE);
520     }
521
522   return err;
523 }
524
525
526 /* Return a canonicalized public key algoithms.  This is used to
527    compare different flavors of algorithms (e.g. ELG and ELG_E are
528    considered the same).  */
529 static enum gcry_pk_algos
530 canon_pk_algo (enum gcry_pk_algos algo)
531 {
532   switch (algo)
533     {
534     case GCRY_PK_RSA:
535     case GCRY_PK_RSA_E:
536     case GCRY_PK_RSA_S: return GCRY_PK_RSA;
537     case GCRY_PK_ELG:
538     case GCRY_PK_ELG_E: return GCRY_PK_ELG;
539     case GCRY_PK_ECC:
540     case GCRY_PK_ECDSA:
541     case GCRY_PK_ECDH: return GCRY_PK_ECC;
542     default: return algo;
543     }
544 }
545
546
547 /* Take a cleartext dump of a secret key in PK and change the
548  * parameter array in PK to include the secret parameters.  */
549 static gpg_error_t
550 cleartext_secret_key_to_openpgp (gcry_sexp_t s_key, PKT_public_key *pk)
551 {
552   gpg_error_t err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
553   gcry_sexp_t top_list;
554   gcry_sexp_t key = NULL;
555   char *key_type = NULL;
556   enum gcry_pk_algos pk_algo;
557   struct seckey_info *ski;
558   int idx, sec_start;
559   gcry_mpi_t pub_params[10] = { NULL };
560
561   /* we look for a private-key, then the first element in it tells us
562      the type */
563   top_list = gcry_sexp_find_token (s_key, "private-key", 0);
564   if (!top_list)
565     goto bad_seckey;
566   if (gcry_sexp_length(top_list) != 2)
567     goto bad_seckey;
568   key = gcry_sexp_nth (top_list, 1);
569   if (!key)
570     goto bad_seckey;
571   key_type = gcry_sexp_nth_string(key, 0);
572   pk_algo = gcry_pk_map_name (key_type);
573
574   log_assert (!pk->seckey_info);
575
576   pk->seckey_info = ski = xtrycalloc (1, sizeof *ski);
577   if (!ski)
578     {
579       err = gpg_error_from_syserror ();
580       goto leave;
581     }
582
583   switch (canon_pk_algo (pk_algo))
584     {
585     case GCRY_PK_RSA:
586       if (!is_RSA (pk->pubkey_algo))
587         goto bad_pubkey_algo;
588       err = gcry_sexp_extract_param (key, NULL, "ne",
589                                      &pub_params[0],
590                                      &pub_params[1],
591                                      NULL);
592       for (idx=0; idx < 2 && !err; idx++)
593         if (gcry_mpi_cmp(pk->pkey[idx], pub_params[idx]))
594           err = gpg_error (GPG_ERR_BAD_PUBKEY);
595       if (!err)
596         {
597           for (idx = 2; idx < 6 && !err; idx++)
598             {
599               gcry_mpi_release (pk->pkey[idx]);
600               pk->pkey[idx] = NULL;
601             }
602           err = gcry_sexp_extract_param (key, NULL, "dpqu",
603                                          &pk->pkey[2],
604                                          &pk->pkey[3],
605                                          &pk->pkey[4],
606                                          &pk->pkey[5],
607                                          NULL);
608         }
609       if (!err)
610         {
611           for (idx = 2; idx < 6; idx++)
612             ski->csum += checksum_mpi (pk->pkey[idx]);
613         }
614       break;
615
616     case GCRY_PK_DSA:
617       if (!is_DSA (pk->pubkey_algo))
618         goto bad_pubkey_algo;
619       err = gcry_sexp_extract_param (key, NULL, "pqgy",
620                                      &pub_params[0],
621                                      &pub_params[1],
622                                      &pub_params[2],
623                                      &pub_params[3],
624                                      NULL);
625       for (idx=0; idx < 4 && !err; idx++)
626         if (gcry_mpi_cmp(pk->pkey[idx], pub_params[idx]))
627           err = gpg_error (GPG_ERR_BAD_PUBKEY);
628       if (!err)
629         {
630           gcry_mpi_release (pk->pkey[4]);
631           pk->pkey[4] = NULL;
632           err = gcry_sexp_extract_param (key, NULL, "x",
633                                          &pk->pkey[4],
634                                          NULL);
635         }
636       if (!err)
637         ski->csum += checksum_mpi (pk->pkey[4]);
638       break;
639
640     case GCRY_PK_ELG:
641       if (!is_ELGAMAL (pk->pubkey_algo))
642         goto bad_pubkey_algo;
643       err = gcry_sexp_extract_param (key, NULL, "pgy",
644                                      &pub_params[0],
645                                      &pub_params[1],
646                                      &pub_params[2],
647                                      NULL);
648       for (idx=0; idx < 3 && !err; idx++)
649         if (gcry_mpi_cmp(pk->pkey[idx], pub_params[idx]))
650           err = gpg_error (GPG_ERR_BAD_PUBKEY);
651       if (!err)
652         {
653           gcry_mpi_release (pk->pkey[3]);
654           pk->pkey[3] = NULL;
655           err = gcry_sexp_extract_param (key, NULL, "x",
656                                          &pk->pkey[3],
657                                          NULL);
658         }
659       if (!err)
660         ski->csum += checksum_mpi (pk->pkey[3]);
661       break;
662
663     case GCRY_PK_ECC:
664       err = match_curve_skey_pk (key, pk);
665       if (err)
666         goto leave;
667       if (!err)
668         err = gcry_sexp_extract_param (key, NULL, "q",
669                                        &pub_params[0],
670                                        NULL);
671       if (!err && (gcry_mpi_cmp(pk->pkey[1], pub_params[0])))
672         err = gpg_error (GPG_ERR_BAD_PUBKEY);
673
674       sec_start = 2;
675       if (pk->pubkey_algo == PUBKEY_ALGO_ECDH)
676         sec_start += 1;
677       if (!err)
678         {
679           gcry_mpi_release (pk->pkey[sec_start]);
680           pk->pkey[sec_start] = NULL;
681           err = gcry_sexp_extract_param (key, NULL, "d",
682                                          &pk->pkey[sec_start],
683                                          NULL);
684         }
685
686       if (!err)
687         ski->csum += checksum_mpi (pk->pkey[sec_start]);
688       break;
689
690     default:
691       pk->seckey_info = NULL;
692       xfree (ski);
693       err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
694       break;
695     }
696
697  leave:
698   gcry_sexp_release (top_list);
699   gcry_sexp_release (key);
700   gcry_free (key_type);
701
702   for (idx=0; idx < DIM(pub_params); idx++)
703     gcry_mpi_release (pub_params[idx]);
704   return err;
705
706  bad_pubkey_algo:
707   err = gpg_error (GPG_ERR_PUBKEY_ALGO);
708   goto leave;
709
710  bad_seckey:
711   err = gpg_error (GPG_ERR_BAD_SECKEY);
712   goto leave;
713 }
714
715
716 /* Use the key transfer format given in S_PGP to create the secinfo
717    structure in PK and change the parameter array in PK to include the
718    secret parameters.  */
719 static gpg_error_t
720 transfer_format_to_openpgp (gcry_sexp_t s_pgp, PKT_public_key *pk)
721 {
722   gpg_error_t err;
723   gcry_sexp_t top_list;
724   gcry_sexp_t list = NULL;
725   char *curve = NULL;
726   const char *value;
727   size_t valuelen;
728   char *string;
729   int  idx;
730   int  is_v4, is_protected;
731   enum gcry_pk_algos pk_algo;
732   int  protect_algo = 0;
733   char iv[16];
734   int  ivlen = 0;
735   int  s2k_mode = 0;
736   int  s2k_algo = 0;
737   byte s2k_salt[8];
738   u32  s2k_count = 0;
739   int  is_ecdh = 0;
740   size_t npkey, nskey;
741   gcry_mpi_t skey[10];  /* We support up to 9 parameters.  */
742   int skeyidx = 0;
743   struct seckey_info *ski;
744
745   /* gcry_log_debugsxp ("transferkey", s_pgp); */
746   top_list = gcry_sexp_find_token (s_pgp, "openpgp-private-key", 0);
747   if (!top_list)
748     goto bad_seckey;
749
750   list = gcry_sexp_find_token (top_list, "version", 0);
751   if (!list)
752     goto bad_seckey;
753   value = gcry_sexp_nth_data (list, 1, &valuelen);
754   if (!value || valuelen != 1 || !(value[0] == '3' || value[0] == '4'))
755     goto bad_seckey;
756   is_v4 = (value[0] == '4');
757
758   gcry_sexp_release (list);
759   list = gcry_sexp_find_token (top_list, "protection", 0);
760   if (!list)
761     goto bad_seckey;
762   value = gcry_sexp_nth_data (list, 1, &valuelen);
763   if (!value)
764     goto bad_seckey;
765   if (valuelen == 4 && !memcmp (value, "sha1", 4))
766     is_protected = 2;
767   else if (valuelen == 3 && !memcmp (value, "sum", 3))
768     is_protected = 1;
769   else if (valuelen == 4 && !memcmp (value, "none", 4))
770     is_protected = 0;
771   else
772     goto bad_seckey;
773   if (is_protected)
774     {
775       string = gcry_sexp_nth_string (list, 2);
776       if (!string)
777         goto bad_seckey;
778       protect_algo = gcry_cipher_map_name (string);
779       xfree (string);
780
781       value = gcry_sexp_nth_data (list, 3, &valuelen);
782       if (!value || !valuelen || valuelen > sizeof iv)
783         goto bad_seckey;
784       memcpy (iv, value, valuelen);
785       ivlen = valuelen;
786
787       string = gcry_sexp_nth_string (list, 4);
788       if (!string)
789         goto bad_seckey;
790       s2k_mode = strtol (string, NULL, 10);
791       xfree (string);
792
793       string = gcry_sexp_nth_string (list, 5);
794       if (!string)
795         goto bad_seckey;
796       s2k_algo = gcry_md_map_name (string);
797       xfree (string);
798
799       value = gcry_sexp_nth_data (list, 6, &valuelen);
800       if (!value || !valuelen || valuelen > sizeof s2k_salt)
801         goto bad_seckey;
802       memcpy (s2k_salt, value, valuelen);
803
804       string = gcry_sexp_nth_string (list, 7);
805       if (!string)
806         goto bad_seckey;
807       s2k_count = strtoul (string, NULL, 10);
808       xfree (string);
809     }
810
811   /* Parse the gcrypt PK algo and check that it is okay.  */
812   gcry_sexp_release (list);
813   list = gcry_sexp_find_token (top_list, "algo", 0);
814   if (!list)
815     goto bad_seckey;
816   string = gcry_sexp_nth_string (list, 1);
817   if (!string)
818     goto bad_seckey;
819   pk_algo = gcry_pk_map_name (string);
820   xfree (string); string = NULL;
821   if (gcry_pk_algo_info (pk_algo, GCRYCTL_GET_ALGO_NPKEY, NULL, &npkey)
822       || gcry_pk_algo_info (pk_algo, GCRYCTL_GET_ALGO_NSKEY, NULL, &nskey)
823       || !npkey || npkey >= nskey)
824     goto bad_seckey;
825
826   /* Check that the pubkey algo matches the one from the public key.  */
827   switch (canon_pk_algo (pk_algo))
828     {
829     case GCRY_PK_RSA:
830       if (!is_RSA (pk->pubkey_algo))
831         pk_algo = 0;  /* Does not match.  */
832       break;
833     case GCRY_PK_DSA:
834       if (!is_DSA (pk->pubkey_algo))
835         pk_algo = 0;  /* Does not match.  */
836       break;
837     case GCRY_PK_ELG:
838       if (!is_ELGAMAL (pk->pubkey_algo))
839         pk_algo = 0;  /* Does not match.  */
840       break;
841     case GCRY_PK_ECC:
842       if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA)
843         ;
844       else if (pk->pubkey_algo == PUBKEY_ALGO_ECDH)
845         is_ecdh = 1;
846       else if (pk->pubkey_algo == PUBKEY_ALGO_EDDSA)
847         ;
848       else
849         pk_algo = 0;  /* Does not match.  */
850       /* For ECC we do not have the domain parameters thus fix our info.  */
851       npkey = 1;
852       nskey = 2;
853       break;
854     default:
855       pk_algo = 0;   /* Oops.  */
856       break;
857     }
858   if (!pk_algo)
859     {
860       err = gpg_error (GPG_ERR_PUBKEY_ALGO);
861       goto leave;
862     }
863
864   /* This check has to go after the ecc adjustments. */
865   if (nskey > PUBKEY_MAX_NSKEY)
866     goto bad_seckey;
867
868   /* Parse the key parameters.  */
869   gcry_sexp_release (list);
870   list = gcry_sexp_find_token (top_list, "skey", 0);
871   if (!list)
872     goto bad_seckey;
873   for (idx=0;;)
874     {
875       int is_enc;
876
877       value = gcry_sexp_nth_data (list, ++idx, &valuelen);
878       if (!value && skeyidx >= npkey)
879         break;  /* Ready.  */
880
881       /* Check for too many parameters.  Note that depending on the
882          protection mode and version number we may see less than NSKEY
883          (but at least NPKEY+1) parameters.  */
884       if (idx >= 2*nskey)
885         goto bad_seckey;
886       if (skeyidx >= DIM (skey)-1)
887         goto bad_seckey;
888
889       if (!value || valuelen != 1 || !(value[0] == '_' || value[0] == 'e'))
890         goto bad_seckey;
891       is_enc = (value[0] == 'e');
892       value = gcry_sexp_nth_data (list, ++idx, &valuelen);
893       if (!value || !valuelen)
894         goto bad_seckey;
895       if (is_enc)
896         {
897           void *p = xtrymalloc (valuelen);
898           if (!p)
899             goto outofmem;
900           memcpy (p, value, valuelen);
901           skey[skeyidx] = gcry_mpi_set_opaque (NULL, p, valuelen*8);
902           if (!skey[skeyidx])
903             goto outofmem;
904         }
905       else
906         {
907           if (gcry_mpi_scan (skey + skeyidx, GCRYMPI_FMT_STD,
908                              value, valuelen, NULL))
909             goto bad_seckey;
910         }
911       skeyidx++;
912     }
913   skey[skeyidx++] = NULL;
914
915   gcry_sexp_release (list); list = NULL;
916
917   /* We have no need for the CSUM value thus we don't parse it.  */
918   /* list = gcry_sexp_find_token (top_list, "csum", 0); */
919   /* if (list) */
920   /*   { */
921   /*     string = gcry_sexp_nth_string (list, 1); */
922   /*     if (!string) */
923   /*       goto bad_seckey; */
924   /*     desired_csum = strtoul (string, NULL, 10); */
925   /*     xfree (string); */
926   /*   } */
927   /* else */
928   /*   desired_csum = 0; */
929   /* gcry_sexp_release (list); list = NULL; */
930
931   /* Get the curve name if any,  */
932   list = gcry_sexp_find_token (top_list, "curve", 0);
933   if (list)
934     {
935       curve = gcry_sexp_nth_string (list, 1);
936       gcry_sexp_release (list); list = NULL;
937     }
938
939   gcry_sexp_release (top_list); top_list = NULL;
940
941   /* log_debug ("XXX is_v4=%d\n", is_v4); */
942   /* log_debug ("XXX pubkey_algo=%d\n", pubkey_algo); */
943   /* log_debug ("XXX is_protected=%d\n", is_protected); */
944   /* log_debug ("XXX protect_algo=%d\n", protect_algo); */
945   /* log_printhex ("XXX iv", iv, ivlen); */
946   /* log_debug ("XXX ivlen=%d\n", ivlen); */
947   /* log_debug ("XXX s2k_mode=%d\n", s2k_mode); */
948   /* log_debug ("XXX s2k_algo=%d\n", s2k_algo); */
949   /* log_printhex ("XXX s2k_salt", s2k_salt, sizeof s2k_salt); */
950   /* log_debug ("XXX s2k_count=%lu\n", (unsigned long)s2k_count); */
951   /* for (idx=0; skey[idx]; idx++) */
952   /*   { */
953   /*     int is_enc = gcry_mpi_get_flag (skey[idx], GCRYMPI_FLAG_OPAQUE); */
954   /*     log_info ("XXX skey[%d]%s:", idx, is_enc? " (enc)":""); */
955   /*     if (is_enc) */
956   /*       { */
957   /*         void *p; */
958   /*         unsigned int nbits; */
959   /*         p = gcry_mpi_get_opaque (skey[idx], &nbits); */
960   /*         log_printhex (NULL, p, (nbits+7)/8); */
961   /*       } */
962   /*     else */
963   /*       gcry_mpi_dump (skey[idx]); */
964   /*     log_printf ("\n"); */
965   /*   } */
966
967   if (!is_v4 || is_protected != 2 )
968     {
969       /* We only support the v4 format and a SHA-1 checksum.  */
970       err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
971       goto leave;
972     }
973
974   /* We need to change the received parameters for ECC algorithms.
975      The transfer format has the curve name and the parameters
976      separate.  We put them all into the SKEY array.  */
977   if (canon_pk_algo (pk_algo) == GCRY_PK_ECC)
978     {
979       const char *oidstr;
980
981       /* Assert that all required parameters are available.  We also
982          check that the array does not contain more parameters than
983          needed (this was used by some beta versions of 2.1.  */
984       if (!curve || !skey[0] || !skey[1] || skey[2])
985         {
986           err = gpg_error (GPG_ERR_INTERNAL);
987           goto leave;
988         }
989
990       oidstr = openpgp_curve_to_oid (curve, NULL);
991       if (!oidstr)
992         {
993           log_error ("no OID known for curve '%s'\n", curve);
994           err = gpg_error (GPG_ERR_UNKNOWN_CURVE);
995           goto leave;
996         }
997       /* Put the curve's OID into into the MPI array.  This requires
998          that we shift Q and D.  For ECDH also insert the KDF parms. */
999       if (is_ecdh)
1000         {
1001           skey[4] = NULL;
1002           skey[3] = skey[1];
1003           skey[2] = gcry_mpi_copy (pk->pkey[2]);
1004         }
1005       else
1006         {
1007           skey[3] = NULL;
1008           skey[2] = skey[1];
1009         }
1010       skey[1] = skey[0];
1011       skey[0] = NULL;
1012       err = openpgp_oid_from_str (oidstr, skey + 0);
1013       if (err)
1014         goto leave;
1015       /* Fixup the NPKEY and NSKEY to match OpenPGP reality.  */
1016       npkey = 2 + is_ecdh;
1017       nskey = 3 + is_ecdh;
1018
1019       /* for (idx=0; skey[idx]; idx++) */
1020       /*   { */
1021       /*     log_info ("YYY skey[%d]:", idx); */
1022       /*     if (gcry_mpi_get_flag (skey[idx], GCRYMPI_FLAG_OPAQUE)) */
1023       /*       { */
1024       /*         void *p; */
1025       /*         unsigned int nbits; */
1026       /*         p = gcry_mpi_get_opaque (skey[idx], &nbits); */
1027       /*         log_printhex (NULL, p, (nbits+7)/8); */
1028       /*       } */
1029       /*     else */
1030       /*       gcry_mpi_dump (skey[idx]); */
1031       /*     log_printf ("\n"); */
1032       /*   } */
1033     }
1034
1035   /* Do some sanity checks.  */
1036   if (s2k_count > 255)
1037     {
1038       /* We expect an already encoded S2K count.  */
1039       err = gpg_error (GPG_ERR_INV_DATA);
1040       goto leave;
1041     }
1042   err = openpgp_cipher_test_algo (protect_algo);
1043   if (err)
1044     goto leave;
1045   err = openpgp_md_test_algo (s2k_algo);
1046   if (err)
1047     goto leave;
1048
1049   /* Check that the public key parameters match.  Note that since
1050      Libgcrypt 1.5 gcry_mpi_cmp handles opaque MPI correctly.  */
1051   for (idx=0; idx < npkey; idx++)
1052     if (gcry_mpi_cmp (pk->pkey[idx], skey[idx]))
1053       {
1054         err = gpg_error (GPG_ERR_BAD_PUBKEY);
1055         goto leave;
1056       }
1057
1058   /* Check that the first secret key parameter in SKEY is encrypted
1059      and that there are no more secret key parameters.  The latter is
1060      guaranteed by the v4 packet format.  */
1061   if (!gcry_mpi_get_flag (skey[npkey], GCRYMPI_FLAG_OPAQUE))
1062     goto bad_seckey;
1063   if (npkey+1 < DIM (skey) && skey[npkey+1])
1064     goto bad_seckey;
1065
1066   /* Check that the secret key parameters in PK are all set to NULL. */
1067   for (idx=npkey; idx < nskey; idx++)
1068     if (pk->pkey[idx])
1069       goto bad_seckey;
1070
1071   /* Now build the protection info. */
1072   pk->seckey_info = ski = xtrycalloc (1, sizeof *ski);
1073   if (!ski)
1074     {
1075       err = gpg_error_from_syserror ();
1076       goto leave;
1077     }
1078
1079   ski->is_protected = 1;
1080   ski->sha1chk = 1;
1081   ski->algo = protect_algo;
1082   ski->s2k.mode = s2k_mode;
1083   ski->s2k.hash_algo = s2k_algo;
1084   log_assert (sizeof ski->s2k.salt == sizeof s2k_salt);
1085   memcpy (ski->s2k.salt, s2k_salt, sizeof s2k_salt);
1086   ski->s2k.count = s2k_count;
1087   log_assert (ivlen <= sizeof ski->iv);
1088   memcpy (ski->iv, iv, ivlen);
1089   ski->ivlen = ivlen;
1090
1091   /* Store the protected secret key parameter.  */
1092   pk->pkey[npkey] = skey[npkey];
1093   skey[npkey] = NULL;
1094
1095   /* That's it.  */
1096
1097  leave:
1098   gcry_free (curve);
1099   gcry_sexp_release (list);
1100   gcry_sexp_release (top_list);
1101   for (idx=0; idx < skeyidx; idx++)
1102     gcry_mpi_release (skey[idx]);
1103   return err;
1104
1105  bad_seckey:
1106   err = gpg_error (GPG_ERR_BAD_SECKEY);
1107   goto leave;
1108
1109  outofmem:
1110   err = gpg_error (GPG_ERR_ENOMEM);
1111   goto leave;
1112 }
1113
1114
1115 /* Print an "EXPORTED" status line.  PK is the primary public key.  */
1116 static void
1117 print_status_exported (PKT_public_key *pk)
1118 {
1119   char *hexfpr;
1120
1121   if (!is_status_enabled ())
1122     return;
1123
1124   hexfpr = hexfingerprint (pk, NULL, 0);
1125   write_status_text (STATUS_EXPORTED, hexfpr? hexfpr : "[?]");
1126   xfree (hexfpr);
1127 }
1128
1129
1130 /*
1131  * Receive a secret key from agent specified by HEXGRIP.
1132  *
1133  * Since the key data from agant is encrypted, decrypt it by CIPHERHD.
1134  * Then, parse the decrypted key data in transfer format, and put
1135  * secret parameters into PK.
1136  *
1137  * If CLEARTEXT is 0, store the secret key material
1138  * passphrase-protected.  Otherwise, store secret key material in the
1139  * clear.
1140  *
1141  * CACHE_NONCE_ADDR is used to share nonce for multple key retrievals.
1142  */
1143 gpg_error_t
1144 receive_seckey_from_agent (ctrl_t ctrl, gcry_cipher_hd_t cipherhd,
1145                            int cleartext,
1146                            char **cache_nonce_addr, const char *hexgrip,
1147                            PKT_public_key *pk)
1148 {
1149   gpg_error_t err = 0;
1150   unsigned char *wrappedkey = NULL;
1151   size_t wrappedkeylen;
1152   unsigned char *key = NULL;
1153   size_t keylen, realkeylen;
1154   gcry_sexp_t s_skey;
1155   char *prompt;
1156
1157   if (opt.verbose)
1158     log_info ("key %s: asking agent for the secret parts\n", hexgrip);
1159
1160   prompt = gpg_format_keydesc (pk, FORMAT_KEYDESC_EXPORT,1);
1161   err = agent_export_key (ctrl, hexgrip, prompt, !cleartext, cache_nonce_addr,
1162                           &wrappedkey, &wrappedkeylen);
1163   xfree (prompt);
1164
1165   if (err)
1166     goto unwraperror;
1167   if (wrappedkeylen < 24)
1168     {
1169       err = gpg_error (GPG_ERR_INV_LENGTH);
1170       goto unwraperror;
1171     }
1172   keylen = wrappedkeylen - 8;
1173   key = xtrymalloc_secure (keylen);
1174   if (!key)
1175     {
1176       err = gpg_error_from_syserror ();
1177       goto unwraperror;
1178     }
1179   err = gcry_cipher_decrypt (cipherhd, key, keylen, wrappedkey, wrappedkeylen);
1180   if (err)
1181     goto unwraperror;
1182   realkeylen = gcry_sexp_canon_len (key, keylen, NULL, &err);
1183   if (!realkeylen)
1184     goto unwraperror; /* Invalid csexp.  */
1185
1186   err = gcry_sexp_sscan (&s_skey, NULL, key, realkeylen);
1187   if (!err)
1188     {
1189       if (cleartext)
1190         err = cleartext_secret_key_to_openpgp (s_skey, pk);
1191       else
1192         err = transfer_format_to_openpgp (s_skey, pk);
1193       gcry_sexp_release (s_skey);
1194     }
1195
1196  unwraperror:
1197   xfree (key);
1198   xfree (wrappedkey);
1199   if (err)
1200     {
1201       log_error ("key %s: error receiving key from agent:"
1202                  " %s%s\n", hexgrip, gpg_strerror (err),
1203                  gpg_err_code (err) == GPG_ERR_FULLY_CANCELED?
1204                  "":_(" - skipped"));
1205     }
1206   return err;
1207 }
1208
1209
1210 /* Write KEYBLOCK either to stdout or to the file set with the
1211  * --output option.  This is a simplified version of do_export_stream
1212  * which supports only a few export options.  */
1213 gpg_error_t
1214 write_keyblock_to_output (kbnode_t keyblock, int with_armor,
1215                           unsigned int options)
1216 {
1217   gpg_error_t err;
1218   const char *fname;
1219   iobuf_t out;
1220   kbnode_t node;
1221   armor_filter_context_t *afx = NULL;
1222   iobuf_t out_help = NULL;
1223   PKT_public_key *pk = NULL;
1224
1225   fname = opt.outfile? opt.outfile : "-";
1226   if (is_secured_filename (fname) )
1227     return gpg_error (GPG_ERR_EPERM);
1228
1229   out = iobuf_create (fname, 0);
1230   if (!out)
1231     {
1232       err = gpg_error_from_syserror ();
1233       log_error(_("can't create '%s': %s\n"), fname, gpg_strerror (err));
1234       return err;
1235     }
1236   if (opt.verbose)
1237     log_info (_("writing to '%s'\n"), iobuf_get_fname_nonnull (out));
1238
1239   if ((options & (EXPORT_PKA_FORMAT|EXPORT_DANE_FORMAT)))
1240     {
1241       with_armor = 0;
1242       out_help = iobuf_temp ();
1243     }
1244
1245   if (with_armor)
1246     {
1247       afx = new_armor_context ();
1248       afx->what = 1;
1249       push_armor_filter (afx, out);
1250     }
1251
1252   for (node = keyblock; node; node = node->next)
1253     {
1254       if (is_deleted_kbnode (node) || node->pkt->pkttype == PKT_RING_TRUST)
1255         continue;
1256       if (!pk && (node->pkt->pkttype == PKT_PUBLIC_KEY
1257                   || node->pkt->pkttype == PKT_SECRET_KEY))
1258         pk = node->pkt->pkt.public_key;
1259
1260       err = build_packet (out_help? out_help : out, node->pkt);
1261       if (err)
1262         {
1263           log_error ("build_packet(%d) failed: %s\n",
1264                      node->pkt->pkttype, gpg_strerror (err) );
1265           goto leave;
1266         }
1267     }
1268   err = 0;
1269
1270   if (out_help && pk)
1271     {
1272       const void *data;
1273       size_t datalen;
1274
1275       iobuf_flush_temp (out_help);
1276       data = iobuf_get_temp_buffer (out_help);
1277       datalen = iobuf_get_temp_length (out_help);
1278
1279       err = print_pka_or_dane_records (out,
1280                                        keyblock, pk, data, datalen,
1281                                        (options & EXPORT_PKA_FORMAT),
1282                                        (options & EXPORT_DANE_FORMAT));
1283     }
1284
1285  leave:
1286   if (err)
1287     iobuf_cancel (out);
1288   else
1289     iobuf_close (out);
1290   iobuf_cancel (out_help);
1291   release_armor_context (afx);
1292   return err;
1293 }
1294
1295
1296 /* Helper for apply_keep_uid_filter.  */
1297 static const char *
1298 filter_getval (void *cookie, const char *propname)
1299 {
1300   kbnode_t node = cookie;
1301   const char *result;
1302
1303   if (node->pkt->pkttype == PKT_USER_ID)
1304     {
1305       if (!strcmp (propname, "uid"))
1306         result = node->pkt->pkt.user_id->name;
1307       else if (!strcmp (propname, "mbox"))
1308         {
1309           if (!node->pkt->pkt.user_id->mbox)
1310             {
1311               node->pkt->pkt.user_id->mbox
1312                 = mailbox_from_userid (node->pkt->pkt.user_id->name);
1313             }
1314           return node->pkt->pkt.user_id->mbox;
1315         }
1316       else if (!strcmp (propname, "primary"))
1317         result = node->pkt->pkt.user_id->is_primary? "1":"0";
1318       else
1319         result = NULL;
1320     }
1321   else
1322     result = NULL;
1323
1324   return result;
1325 }
1326
1327 /*
1328  * Apply the keep-uid filter to the keyblock.  The deleted nodes are
1329  * marked and thus the caller should call commit_kbnode afterwards.
1330  * KEYBLOCK must not have any blocks marked as deleted.
1331  */
1332 static void
1333 apply_keep_uid_filter (kbnode_t keyblock, recsel_expr_t selector)
1334 {
1335   kbnode_t node;
1336
1337   for (node = keyblock->next; node; node = node->next )
1338     {
1339       if (node->pkt->pkttype == PKT_USER_ID)
1340         {
1341           if (!recsel_select (selector, filter_getval, node))
1342             {
1343               /* log_debug ("keep-uid: deleting '%s'\n", */
1344               /*            node->pkt->pkt.user_id->name); */
1345               /* The UID packet and all following packets up to the
1346                * next UID or a subkey.  */
1347               delete_kbnode (node);
1348               for (; node->next
1349                      && node->next->pkt->pkttype != PKT_USER_ID
1350                      && node->next->pkt->pkttype != PKT_PUBLIC_SUBKEY
1351                      && node->next->pkt->pkttype != PKT_SECRET_SUBKEY ;
1352                    node = node->next)
1353                 delete_kbnode (node->next);
1354             }
1355           /* else */
1356           /*   log_debug ("keep-uid: keeping '%s'\n", */
1357           /*              node->pkt->pkt.user_id->name); */
1358         }
1359     }
1360 }
1361
1362
1363 /* Print DANE or PKA records for all user IDs in KEYBLOCK to OUT.  The
1364  * data for the record is taken from (DATA,DATELEN).  PK is the public
1365  * key packet with the primary key. */
1366 static gpg_error_t
1367 print_pka_or_dane_records (iobuf_t out, kbnode_t keyblock, PKT_public_key *pk,
1368                            const void *data, size_t datalen,
1369                            int print_pka, int print_dane)
1370 {
1371   gpg_error_t err = 0;
1372   kbnode_t kbctx, node;
1373   PKT_user_id *uid;
1374   char *mbox = NULL;
1375   char hashbuf[32];
1376   char *hash = NULL;
1377   char *domain;
1378   const char *s;
1379   unsigned int len;
1380   estream_t fp = NULL;
1381   char *hexdata = NULL;
1382   char *hexfpr;
1383
1384   hexfpr = hexfingerprint (pk, NULL, 0);
1385   hexdata = bin2hex (data, datalen, NULL);
1386   if (!hexdata)
1387     {
1388       err = gpg_error_from_syserror ();
1389       goto leave;
1390     }
1391   ascii_strlwr (hexdata);
1392   fp = es_fopenmem (0, "rw,samethread");
1393   if (!fp)
1394     {
1395       err = gpg_error_from_syserror ();
1396       goto leave;
1397     }
1398
1399   for (kbctx = NULL; (node = walk_kbnode (keyblock, &kbctx, 0));)
1400     {
1401       if (node->pkt->pkttype != PKT_USER_ID)
1402         continue;
1403       uid = node->pkt->pkt.user_id;
1404
1405       if (uid->is_expired || uid->is_revoked)
1406         continue;
1407
1408       xfree (mbox);
1409       mbox = mailbox_from_userid (uid->name);
1410       if (!mbox)
1411         continue;
1412
1413       domain = strchr (mbox, '@');
1414       *domain++ = 0;
1415
1416       if (print_pka)
1417         {
1418           es_fprintf (fp, "$ORIGIN _pka.%s.\n; %s\n; ", domain, hexfpr);
1419           print_utf8_buffer (fp, uid->name, uid->len);
1420           es_putc ('\n', fp);
1421           gcry_md_hash_buffer (GCRY_MD_SHA1, hashbuf, mbox, strlen (mbox));
1422           xfree (hash);
1423           hash = zb32_encode (hashbuf, 8*20);
1424           if (!hash)
1425             {
1426               err = gpg_error_from_syserror ();
1427               goto leave;
1428             }
1429           len = strlen (hexfpr)/2;
1430           es_fprintf (fp, "%s TYPE37 \\# %u 0006 0000 00 %02X %s\n\n",
1431                       hash, 6 + len, len, hexfpr);
1432         }
1433
1434       if (print_dane && hexdata)
1435         {
1436           es_fprintf (fp, "$ORIGIN _openpgpkey.%s.\n; %s\n; ", domain, hexfpr);
1437           print_utf8_buffer (fp, uid->name, uid->len);
1438           es_putc ('\n', fp);
1439           gcry_md_hash_buffer (GCRY_MD_SHA256, hashbuf, mbox, strlen (mbox));
1440           xfree (hash);
1441           hash = bin2hex (hashbuf, 28, NULL);
1442           if (!hash)
1443             {
1444               err = gpg_error_from_syserror ();
1445               goto leave;
1446             }
1447           ascii_strlwr (hash);
1448           len = strlen (hexdata)/2;
1449           es_fprintf (fp, "%s TYPE61 \\# %u (\n", hash, len);
1450           for (s = hexdata; ;)
1451             {
1452               es_fprintf (fp, "\t%.64s\n", s);
1453               if (strlen (s) < 64)
1454                 break;
1455               s += 64;
1456             }
1457           es_fputs ("\t)\n\n", fp);
1458         }
1459     }
1460
1461   /* Make sure it is a string and write it.  */
1462   es_fputc (0, fp);
1463   {
1464     void *vp;
1465
1466     if (es_fclose_snatch (fp, &vp, NULL))
1467       {
1468         err = gpg_error_from_syserror ();
1469         goto leave;
1470       }
1471     fp = NULL;
1472     iobuf_writestr (out, vp);
1473     es_free (vp);
1474   }
1475   err = 0;
1476
1477  leave:
1478   xfree (hash);
1479   xfree (mbox);
1480   es_fclose (fp);
1481   xfree (hexdata);
1482   xfree (hexfpr);
1483   return err;
1484 }
1485
1486
1487 /* Helper for do_export_stream which writes one keyblock to OUT.  */
1488 static gpg_error_t
1489 do_export_one_keyblock (ctrl_t ctrl, kbnode_t keyblock, u32 *keyid,
1490                         iobuf_t out, int secret, unsigned int options,
1491                         export_stats_t stats, int *any,
1492                         KEYDB_SEARCH_DESC *desc, size_t ndesc,
1493                         size_t descindex, gcry_cipher_hd_t cipherhd)
1494 {
1495   gpg_error_t err;
1496   char *cache_nonce = NULL;
1497   subkey_list_t subkey_list = NULL;  /* Track already processed subkeys. */
1498   int skip_until_subkey = 0;
1499   int cleartext = 0;
1500   char *hexgrip = NULL;
1501   char *serialno = NULL;
1502   PKT_public_key *pk;
1503   u32 subkidbuf[2], *subkid;
1504   kbnode_t kbctx, node;
1505
1506   for (kbctx=NULL; (node = walk_kbnode (keyblock, &kbctx, 0)); )
1507     {
1508       if (skip_until_subkey)
1509         {
1510           if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
1511             skip_until_subkey = 0;
1512           else
1513             continue;
1514         }
1515
1516       /* We used to use comment packets, but not any longer.  In
1517        * case we still have comments on a key, strip them here
1518        * before we call build_packet(). */
1519       if (node->pkt->pkttype == PKT_COMMENT)
1520         continue;
1521
1522       /* Make sure that ring_trust packets never get exported. */
1523       if (node->pkt->pkttype == PKT_RING_TRUST)
1524         continue;
1525
1526       /* If exact is set, then we only export what was requested
1527        * (plus the primary key, if the user didn't specifically
1528        * request it). */
1529       if (desc[descindex].exact && node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
1530         {
1531           if (!exact_subkey_match_p (desc+descindex, node))
1532             {
1533               /* Before skipping this subkey, check whether any
1534                * other description wants an exact match on a
1535                * subkey and include that subkey into the output
1536                * too.  Need to add this subkey to a list so that
1537                * it won't get processed a second time.
1538                *
1539                * So the first step here is to check that list and
1540                * skip in any case if the key is in that list.
1541                *
1542                * We need this whole mess because the import
1543                * function of GnuPG < 2.1 is not able to merge
1544                * secret keys and thus it is useless to output them
1545                * as two separate keys and have import merge them.
1546                */
1547               if (subkey_in_list_p (subkey_list, node))
1548                 skip_until_subkey = 1; /* Already processed this one. */
1549               else
1550                 {
1551                   size_t j;
1552
1553                   for (j=0; j < ndesc; j++)
1554                     if (j != descindex && desc[j].exact
1555                         && exact_subkey_match_p (desc+j, node))
1556                       break;
1557                   if (!(j < ndesc))
1558                     skip_until_subkey = 1; /* No other one matching. */
1559                 }
1560             }
1561
1562           if (skip_until_subkey)
1563             continue;
1564
1565           /* Mark this one as processed. */
1566           {
1567             subkey_list_t tmp = new_subkey_list_item (node);
1568             tmp->next = subkey_list;
1569             subkey_list = tmp;
1570           }
1571         }
1572
1573       if (node->pkt->pkttype == PKT_SIGNATURE)
1574         {
1575           /* Do not export packets which are marked as not
1576            * exportable.  */
1577           if (!(options & EXPORT_LOCAL_SIGS)
1578               && !node->pkt->pkt.signature->flags.exportable)
1579             continue; /* not exportable */
1580
1581           /* Do not export packets with a "sensitive" revocation key
1582            * unless the user wants us to.  Note that we do export
1583            * these when issuing the actual revocation (see revoke.c). */
1584           if (!(options & EXPORT_SENSITIVE_REVKEYS)
1585               && node->pkt->pkt.signature->revkey)
1586             {
1587               int i;
1588
1589               for (i = 0; i < node->pkt->pkt.signature->numrevkeys; i++)
1590                 if ((node->pkt->pkt.signature->revkey[i].class & 0x40))
1591                   break;
1592               if (i < node->pkt->pkt.signature->numrevkeys)
1593                 continue;
1594             }
1595         }
1596
1597       /* Don't export attribs? */
1598       if (!(options & EXPORT_ATTRIBUTES)
1599           && node->pkt->pkttype == PKT_USER_ID
1600           && node->pkt->pkt.user_id->attrib_data)
1601         {
1602           /* Skip until we get to something that is not an attrib or a
1603            * signature on an attrib.  */
1604           while (kbctx->next && kbctx->next->pkt->pkttype == PKT_SIGNATURE)
1605             kbctx = kbctx->next;
1606
1607           continue;
1608         }
1609
1610       if (secret && (node->pkt->pkttype == PKT_PUBLIC_KEY
1611                      || node->pkt->pkttype == PKT_PUBLIC_SUBKEY))
1612         {
1613           pk = node->pkt->pkt.public_key;
1614           if (node->pkt->pkttype == PKT_PUBLIC_KEY)
1615             subkid = NULL;
1616           else
1617             {
1618               keyid_from_pk (pk, subkidbuf);
1619               subkid = subkidbuf;
1620             }
1621
1622           if (pk->seckey_info)
1623             {
1624               log_error ("key %s: oops: seckey_info already set"
1625                          " - skipped\n", keystr_with_sub (keyid, subkid));
1626               skip_until_subkey = 1;
1627               continue;
1628             }
1629
1630           xfree (hexgrip);
1631           err = hexkeygrip_from_pk (pk, &hexgrip);
1632           if (err)
1633             {
1634               log_error ("key %s: error computing keygrip: %s"
1635                          " - skipped\n", keystr_with_sub (keyid, subkid),
1636                          gpg_strerror (err));
1637               skip_until_subkey = 1;
1638               err = 0;
1639               continue;
1640             }
1641
1642           xfree (serialno);
1643           serialno = NULL;
1644           if (secret == 2 && node->pkt->pkttype == PKT_PUBLIC_KEY)
1645             {
1646               /* We are asked not to export the secret parts of the
1647                * primary key.  Make up an error code to create the
1648                * stub.  */
1649               err = GPG_ERR_NOT_FOUND;
1650             }
1651           else
1652             err = agent_get_keyinfo (ctrl, hexgrip, &serialno, &cleartext);
1653
1654           if ((!err && serialno)
1655               && secret == 2 && node->pkt->pkttype == PKT_PUBLIC_KEY)
1656             {
1657               /* It does not make sense to export a key with its
1658                * primary key on card using a non-key stub.  Thus we
1659                * skip those keys when used with --export-secret-subkeys. */
1660               log_info (_("key %s: key material on-card - skipped\n"),
1661                         keystr_with_sub (keyid, subkid));
1662               skip_until_subkey = 1;
1663             }
1664           else if (gpg_err_code (err) == GPG_ERR_NOT_FOUND
1665                    || (!err && serialno))
1666             {
1667               /* Create a key stub.  */
1668               struct seckey_info *ski;
1669               const char *s;
1670
1671               pk->seckey_info = ski = xtrycalloc (1, sizeof *ski);
1672               if (!ski)
1673                 {
1674                   err = gpg_error_from_syserror ();
1675                   goto leave;
1676                 }
1677
1678               ski->is_protected = 1;
1679               if (err)
1680                 ski->s2k.mode = 1001; /* GNU dummy (no secret key).  */
1681               else
1682                 {
1683                   ski->s2k.mode = 1002; /* GNU-divert-to-card.  */
1684                   for (s=serialno; sizeof (ski->ivlen) && *s && s[1];
1685                        ski->ivlen++, s += 2)
1686                     ski->iv[ski->ivlen] = xtoi_2 (s);
1687                 }
1688
1689               err = build_packet (out, node->pkt);
1690               if (!err && node->pkt->pkttype == PKT_PUBLIC_KEY)
1691                 {
1692                   stats->exported++;
1693                   print_status_exported (node->pkt->pkt.public_key);
1694                 }
1695             }
1696           else if (!err)
1697             {
1698               err = receive_seckey_from_agent (ctrl, cipherhd,
1699                                                cleartext, &cache_nonce,
1700                                                hexgrip, pk);
1701               if (err)
1702                 {
1703                   if (gpg_err_code (err) == GPG_ERR_FULLY_CANCELED)
1704                     goto leave;
1705                   skip_until_subkey = 1;
1706                   err = 0;
1707                 }
1708               else
1709                 {
1710                   err = build_packet (out, node->pkt);
1711                   if (node->pkt->pkttype == PKT_PUBLIC_KEY)
1712                     {
1713                       stats->exported++;
1714                       print_status_exported (node->pkt->pkt.public_key);
1715                     }
1716                 }
1717             }
1718           else
1719             {
1720               log_error ("key %s: error getting keyinfo from agent: %s"
1721                          " - skipped\n", keystr_with_sub (keyid, subkid),
1722                              gpg_strerror (err));
1723               skip_until_subkey = 1;
1724               err = 0;
1725             }
1726
1727           xfree (pk->seckey_info);
1728           pk->seckey_info = NULL;
1729           {
1730             int i;
1731             for (i = pubkey_get_npkey (pk->pubkey_algo);
1732                  i < pubkey_get_nskey (pk->pubkey_algo); i++)
1733               {
1734                 gcry_mpi_release (pk->pkey[i]);
1735                 pk->pkey[i] = NULL;
1736               }
1737           }
1738         }
1739       else /* Not secret or common packets.  */
1740         {
1741           err = build_packet (out, node->pkt);
1742           if (!err && node->pkt->pkttype == PKT_PUBLIC_KEY)
1743             {
1744               stats->exported++;
1745               print_status_exported (node->pkt->pkt.public_key);
1746             }
1747         }
1748
1749       if (err)
1750         {
1751           log_error ("build_packet(%d) failed: %s\n",
1752                      node->pkt->pkttype, gpg_strerror (err));
1753           goto leave;
1754         }
1755
1756       if (!skip_until_subkey)
1757         *any = 1;
1758     }
1759
1760  leave:
1761   release_subkey_list (subkey_list);
1762   xfree (serialno);
1763   xfree (hexgrip);
1764   xfree (cache_nonce);
1765   return err;
1766 }
1767
1768
1769 /* Export the keys identified by the list of strings in USERS to the
1770    stream OUT.  If SECRET is false public keys will be exported.  With
1771    secret true secret keys will be exported; in this case 1 means the
1772    entire secret keyblock and 2 only the subkeys.  OPTIONS are the
1773    export options to apply.  If KEYBLOCK_OUT is not NULL, AND the exit
1774    code is zero, a pointer to the first keyblock found and exported
1775    will be stored at this address; no other keyblocks are exported in
1776    this case.  The caller must free the returned keyblock.  If any
1777    key has been exported true is stored at ANY. */
1778 static int
1779 do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
1780                   kbnode_t *keyblock_out, unsigned int options,
1781                   export_stats_t stats, int *any)
1782 {
1783   gpg_error_t err = 0;
1784   PACKET pkt;
1785   kbnode_t keyblock = NULL;
1786   kbnode_t node;
1787   size_t ndesc, descindex;
1788   KEYDB_SEARCH_DESC *desc = NULL;
1789   KEYDB_HANDLE kdbhd;
1790   strlist_t sl;
1791   gcry_cipher_hd_t cipherhd = NULL;
1792   struct export_stats_s dummystats;
1793   iobuf_t out_help = NULL;
1794
1795   if (!stats)
1796     stats = &dummystats;
1797   *any = 0;
1798   init_packet (&pkt);
1799   kdbhd = keydb_new ();
1800   if (!kdbhd)
1801     return gpg_error_from_syserror ();
1802
1803   /* For the PKA and DANE format open a helper iobuf and for DANE
1804    * enforce some options.  */
1805   if ((options & (EXPORT_PKA_FORMAT | EXPORT_DANE_FORMAT)))
1806     {
1807       out_help = iobuf_temp ();
1808       if ((options & EXPORT_DANE_FORMAT))
1809         options |= EXPORT_MINIMAL | EXPORT_CLEAN;
1810     }
1811
1812   if (!users)
1813     {
1814       ndesc = 1;
1815       desc = xcalloc (ndesc, sizeof *desc);
1816       desc[0].mode = KEYDB_SEARCH_MODE_FIRST;
1817     }
1818   else
1819     {
1820       for (ndesc=0, sl=users; sl; sl = sl->next, ndesc++)
1821         ;
1822       desc = xmalloc ( ndesc * sizeof *desc);
1823
1824       for (ndesc=0, sl=users; sl; sl = sl->next)
1825         {
1826           if (!(err=classify_user_id (sl->d, desc+ndesc, 1)))
1827             ndesc++;
1828           else
1829             log_error (_("key \"%s\" not found: %s\n"),
1830                        sl->d, gpg_strerror (err));
1831         }
1832
1833       keydb_disable_caching (kdbhd);  /* We are looping the search.  */
1834
1835       /* It would be nice to see which of the given users did actually
1836          match one in the keyring.  To implement this we need to have
1837          a found flag for each entry in desc.  To set this flag we
1838          must check all those entries after a match to mark all
1839          matched one - currently we stop at the first match.  To do
1840          this we need an extra flag to enable this feature.  */
1841     }
1842
1843 #ifdef ENABLE_SELINUX_HACKS
1844   if (secret)
1845     {
1846       log_error (_("exporting secret keys not allowed\n"));
1847       err = gpg_error (GPG_ERR_NOT_SUPPORTED);
1848       goto leave;
1849     }
1850 #endif
1851
1852   /* For secret key export we need to setup a decryption context.  */
1853   if (secret)
1854     {
1855       void *kek = NULL;
1856       size_t keklen;
1857
1858       err = agent_keywrap_key (ctrl, 1, &kek, &keklen);
1859       if (err)
1860         {
1861           log_error ("error getting the KEK: %s\n", gpg_strerror (err));
1862           goto leave;
1863         }
1864
1865       /* Prepare a cipher context.  */
1866       err = gcry_cipher_open (&cipherhd, GCRY_CIPHER_AES128,
1867                               GCRY_CIPHER_MODE_AESWRAP, 0);
1868       if (!err)
1869         err = gcry_cipher_setkey (cipherhd, kek, keklen);
1870       if (err)
1871         {
1872           log_error ("error setting up an encryption context: %s\n",
1873                      gpg_strerror (err));
1874           goto leave;
1875         }
1876       xfree (kek);
1877       kek = NULL;
1878     }
1879
1880   for (;;)
1881     {
1882       u32 keyid[2];
1883       PKT_public_key *pk;
1884
1885       err = keydb_search (kdbhd, desc, ndesc, &descindex);
1886       if (!users)
1887         desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
1888       if (err)
1889         break;
1890
1891       /* Read the keyblock. */
1892       release_kbnode (keyblock);
1893       keyblock = NULL;
1894       err = keydb_get_keyblock (kdbhd, &keyblock);
1895       if (err)
1896         {
1897           log_error (_("error reading keyblock: %s\n"), gpg_strerror (err));
1898           goto leave;
1899         }
1900
1901       node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
1902       if (!node)
1903         {
1904           log_error ("public key packet not found in keyblock - skipped\n");
1905           continue;
1906         }
1907       stats->count++;
1908       setup_main_keyids (keyblock);  /* gpg_format_keydesc needs it.  */
1909       pk = node->pkt->pkt.public_key;
1910       keyid_from_pk (pk, keyid);
1911
1912       /* If a secret key export is required we need to check whether
1913          we have a secret key at all and if so create the seckey_info
1914          structure.  */
1915       if (secret)
1916         {
1917           if (agent_probe_any_secret_key (ctrl, keyblock))
1918             continue;  /* No secret key (neither primary nor subkey).  */
1919
1920           /* No v3 keys with GNU mode 1001. */
1921           if (secret == 2 && pk->version == 3)
1922             {
1923               log_info (_("key %s: PGP 2.x style key - skipped\n"),
1924                         keystr (keyid));
1925               continue;
1926             }
1927
1928           /* The agent does not yet allow export of v3 packets.  It is
1929              actually questionable whether we should allow them at
1930              all.  */
1931           if (pk->version == 3)
1932             {
1933               log_info ("key %s: PGP 2.x style key (v3) export "
1934                         "not yet supported - skipped\n", keystr (keyid));
1935               continue;
1936             }
1937           stats->secret_count++;
1938         }
1939
1940       /* Always do the cleaning on the public key part if requested.
1941          Note that we don't yet set this option if we are exporting
1942          secret keys.  Note that both export-clean and export-minimal
1943          only apply to UID sigs (0x10, 0x11, 0x12, and 0x13).  A
1944          designated revocation is never stripped, even with
1945          export-minimal set.  */
1946       if ((options & EXPORT_CLEAN))
1947         clean_key (keyblock, opt.verbose, (options&EXPORT_MINIMAL), NULL, NULL);
1948
1949       if (export_keep_uid)
1950         {
1951           commit_kbnode (&keyblock);
1952           apply_keep_uid_filter (keyblock, export_keep_uid);
1953           commit_kbnode (&keyblock);
1954         }
1955
1956       /* And write it. */
1957       err = do_export_one_keyblock (ctrl, keyblock, keyid,
1958                                     out_help? out_help : out,
1959                                     secret, options, stats, any,
1960                                     desc, ndesc, descindex, cipherhd);
1961       if (err)
1962         break;
1963
1964       if (keyblock_out)
1965         {
1966           *keyblock_out = keyblock;
1967           break;
1968         }
1969
1970       if (out_help)
1971         {
1972           /* We want to write PKA or DANE records.  OUT_HELP has the
1973            * keyblock and we print a record for each uid to OUT. */
1974           const void *data;
1975           size_t datalen;
1976
1977           iobuf_flush_temp (out_help);
1978           data = iobuf_get_temp_buffer (out_help);
1979           datalen = iobuf_get_temp_length (out_help);
1980
1981           err = print_pka_or_dane_records (out,
1982                                            keyblock, pk, data, datalen,
1983                                            (options & EXPORT_PKA_FORMAT),
1984                                            (options & EXPORT_DANE_FORMAT));
1985           if (err)
1986             goto leave;
1987
1988           iobuf_close (out_help);
1989           out_help = iobuf_temp ();
1990         }
1991
1992     }
1993   if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
1994     err = 0;
1995
1996  leave:
1997   iobuf_cancel (out_help);
1998   gcry_cipher_close (cipherhd);
1999   xfree(desc);
2000   keydb_release (kdbhd);
2001   if (err || !keyblock_out)
2002     release_kbnode( keyblock );
2003   if( !*any )
2004     log_info(_("WARNING: nothing exported\n"));
2005   return err;
2006 }
2007
2008
2009
2010 \f
2011 static gpg_error_t
2012 key_to_sshblob (membuf_t *mb, const char *identifier, ...)
2013 {
2014   va_list arg_ptr;
2015   gpg_error_t err = 0;
2016   unsigned char nbuf[4];
2017   unsigned char *buf;
2018   size_t buflen;
2019   gcry_mpi_t a;
2020
2021   ulongtobuf (nbuf, (ulong)strlen (identifier));
2022   put_membuf (mb, nbuf, 4);
2023   put_membuf_str (mb, identifier);
2024   if (!strncmp (identifier, "ecdsa-sha2-", 11))
2025     {
2026       ulongtobuf (nbuf, (ulong)strlen (identifier+11));
2027       put_membuf (mb, nbuf, 4);
2028       put_membuf_str (mb, identifier+11);
2029     }
2030   va_start (arg_ptr, identifier);
2031   while ((a = va_arg (arg_ptr, gcry_mpi_t)))
2032     {
2033       err = gcry_mpi_aprint (GCRYMPI_FMT_SSH, &buf, &buflen, a);
2034       if (err)
2035         break;
2036       if (!strcmp (identifier, "ssh-ed25519")
2037           && buflen > 5 && buf[4] == 0x40)
2038         {
2039           /* We need to strip our 0x40 prefix.  */
2040           put_membuf (mb, "\x00\x00\x00\x20", 4);
2041           put_membuf (mb, buf+5, buflen-5);
2042         }
2043       else
2044         put_membuf (mb, buf, buflen);
2045       gcry_free (buf);
2046     }
2047   va_end (arg_ptr);
2048   return err;
2049 }
2050
2051 /* Export the key identified by USERID in the SSH public key format.
2052    The function exports the latest subkey with Authentication
2053    capability unless the '!' suffix is used to export a specific
2054    key.  */
2055 gpg_error_t
2056 export_ssh_key (ctrl_t ctrl, const char *userid)
2057 {
2058   gpg_error_t err;
2059   kbnode_t keyblock = NULL;
2060   KEYDB_SEARCH_DESC desc;
2061   u32 latest_date;
2062   u32 curtime = make_timestamp ();
2063   kbnode_t latest_key, node;
2064   PKT_public_key *pk;
2065   const char *identifier;
2066   membuf_t mb;
2067   estream_t fp = NULL;
2068   struct b64state b64_state;
2069   const char *fname = "-";
2070
2071   init_membuf (&mb, 4096);
2072
2073   /* We need to know whether the key has been specified using the
2074      exact syntax ('!' suffix).  Thus we need to run a
2075      classify_user_id on our own.  */
2076   err = classify_user_id (userid, &desc, 1);
2077
2078   /* Get the public key.  */
2079   if (!err)
2080     {
2081       getkey_ctx_t getkeyctx;
2082
2083       err = get_pubkey_byname (ctrl, &getkeyctx, NULL, userid, &keyblock,
2084                                NULL,
2085                                0  /* Only usable keys or given exact. */,
2086                                1  /* No AKL lookup.  */);
2087       if (!err)
2088         {
2089           err = getkey_next (getkeyctx, NULL, NULL);
2090           if (!err)
2091             err = gpg_error (GPG_ERR_AMBIGUOUS_NAME);
2092           else if (gpg_err_code (err) == GPG_ERR_NO_PUBKEY)
2093             err = 0;
2094         }
2095       getkey_end (getkeyctx);
2096     }
2097   if (err)
2098     {
2099       log_error (_("key \"%s\" not found: %s\n"), userid, gpg_strerror (err));
2100       return err;
2101     }
2102
2103   /* The finish_lookup code in getkey.c does not handle auth keys,
2104      thus we have to duplicate the code here to find the latest
2105      subkey.  However, if the key has been found using an exact match
2106      ('!' notation) we use that key without any further checks and
2107      even allow the use of the primary key. */
2108   latest_date = 0;
2109   latest_key = NULL;
2110   for (node = keyblock; node; node = node->next)
2111     {
2112       if ((node->pkt->pkttype == PKT_PUBLIC_SUBKEY
2113            || node->pkt->pkttype == PKT_PUBLIC_KEY)
2114           && node->pkt->pkt.public_key->flags.exact)
2115         {
2116           latest_key = node;
2117           break;
2118         }
2119     }
2120   if (!latest_key)
2121     {
2122       for (node = keyblock; node; node = node->next)
2123         {
2124           if (node->pkt->pkttype != PKT_PUBLIC_SUBKEY)
2125             continue;
2126
2127           pk = node->pkt->pkt.public_key;
2128           if (DBG_LOOKUP)
2129             log_debug ("\tchecking subkey %08lX\n",
2130                        (ulong) keyid_from_pk (pk, NULL));
2131           if (!(pk->pubkey_usage & PUBKEY_USAGE_AUTH))
2132             {
2133               if (DBG_LOOKUP)
2134                 log_debug ("\tsubkey not usable for authentication\n");
2135               continue;
2136             }
2137           if (!pk->flags.valid)
2138             {
2139               if (DBG_LOOKUP)
2140                 log_debug ("\tsubkey not valid\n");
2141               continue;
2142             }
2143           if (pk->flags.revoked)
2144             {
2145               if (DBG_LOOKUP)
2146                 log_debug ("\tsubkey has been revoked\n");
2147               continue;
2148             }
2149           if (pk->has_expired)
2150             {
2151               if (DBG_LOOKUP)
2152                 log_debug ("\tsubkey has expired\n");
2153               continue;
2154             }
2155           if (pk->timestamp > curtime && !opt.ignore_valid_from)
2156             {
2157               if (DBG_LOOKUP)
2158                 log_debug ("\tsubkey not yet valid\n");
2159               continue;
2160             }
2161           if (DBG_LOOKUP)
2162             log_debug ("\tsubkey might be fine\n");
2163           /* In case a key has a timestamp of 0 set, we make sure that it
2164              is used.  A better change would be to compare ">=" but that
2165              might also change the selected keys and is as such a more
2166              intrusive change.  */
2167           if (pk->timestamp > latest_date || (!pk->timestamp && !latest_date))
2168             {
2169               latest_date = pk->timestamp;
2170               latest_key = node;
2171             }
2172         }
2173     }
2174
2175   if (!latest_key)
2176     {
2177       err = gpg_error (GPG_ERR_UNUSABLE_PUBKEY);
2178       log_error (_("key \"%s\" not found: %s\n"), userid, gpg_strerror (err));
2179       goto leave;
2180     }
2181
2182   pk = latest_key->pkt->pkt.public_key;
2183   if (DBG_LOOKUP)
2184     log_debug ("\tusing key %08lX\n", (ulong) keyid_from_pk (pk, NULL));
2185
2186   switch (pk->pubkey_algo)
2187     {
2188     case PUBKEY_ALGO_DSA:
2189       identifier = "ssh-dss";
2190       err = key_to_sshblob (&mb, identifier,
2191                             pk->pkey[0], pk->pkey[1], pk->pkey[2], pk->pkey[3],
2192                             NULL);
2193       break;
2194
2195     case PUBKEY_ALGO_RSA:
2196     case PUBKEY_ALGO_RSA_S:
2197       identifier = "ssh-rsa";
2198       err = key_to_sshblob (&mb, identifier, pk->pkey[1], pk->pkey[0], NULL);
2199       break;
2200
2201     case PUBKEY_ALGO_ECDSA:
2202       {
2203         char *curveoid;
2204         const char *curve;
2205
2206         curveoid = openpgp_oid_to_str (pk->pkey[0]);
2207         if (!curveoid)
2208           err = gpg_error_from_syserror ();
2209         else if (!(curve = openpgp_oid_to_curve (curveoid, 0)))
2210           err = gpg_error (GPG_ERR_UNKNOWN_CURVE);
2211         else
2212           {
2213             if (!strcmp (curve, "nistp256"))
2214               identifier = "ecdsa-sha2-nistp256";
2215             else if (!strcmp (curve, "nistp384"))
2216               identifier = "ecdsa-sha2-nistp384";
2217             else if (!strcmp (curve, "nistp521"))
2218               identifier = "ecdsa-sha2-nistp521";
2219             else
2220               identifier = NULL;
2221
2222             if (!identifier)
2223               err = gpg_error (GPG_ERR_UNKNOWN_CURVE);
2224             else
2225               err = key_to_sshblob (&mb, identifier, pk->pkey[1], NULL);
2226           }
2227         xfree (curveoid);
2228       }
2229       break;
2230
2231     case PUBKEY_ALGO_EDDSA:
2232       if (!openpgp_oid_is_ed25519 (pk->pkey[0]))
2233         err = gpg_error (GPG_ERR_UNKNOWN_CURVE);
2234       else
2235         {
2236           identifier = "ssh-ed25519";
2237           err = key_to_sshblob (&mb, identifier, pk->pkey[1], NULL);
2238         }
2239       break;
2240
2241     case PUBKEY_ALGO_ELGAMAL_E:
2242     case PUBKEY_ALGO_ELGAMAL:
2243       err = gpg_error (GPG_ERR_UNUSABLE_PUBKEY);
2244       break;
2245
2246     default:
2247       err = GPG_ERR_PUBKEY_ALGO;
2248       break;
2249     }
2250
2251   if (err)
2252     goto leave;
2253
2254   if (opt.outfile && *opt.outfile && strcmp (opt.outfile, "-"))
2255     fp = es_fopen ((fname = opt.outfile), "w");
2256   else
2257     fp = es_stdout;
2258   if (!fp)
2259     {
2260       err = gpg_error_from_syserror ();
2261       log_error (_("error creating '%s': %s\n"), fname, gpg_strerror (err));
2262       goto leave;
2263     }
2264
2265   es_fprintf (fp, "%s ", identifier);
2266   err = b64enc_start_es (&b64_state, fp, "");
2267   if (err)
2268     goto leave;
2269   {
2270     void *blob;
2271     size_t bloblen;
2272
2273     blob = get_membuf (&mb, &bloblen);
2274     if (!blob)
2275       err = gpg_error_from_syserror ();
2276     else
2277       err = b64enc_write (&b64_state, blob, bloblen);
2278     xfree (blob);
2279     if (err)
2280       goto leave;
2281   }
2282   err = b64enc_finish (&b64_state);
2283   if (err)
2284     goto leave;
2285   es_fprintf (fp, " openpgp:0x%08lX\n", (ulong)keyid_from_pk (pk, NULL));
2286
2287   if (es_ferror (fp))
2288     err = gpg_error_from_syserror ();
2289   else
2290     {
2291       if (es_fclose (fp))
2292         err = gpg_error_from_syserror ();
2293       fp = NULL;
2294     }
2295
2296   if (err)
2297     log_error (_("error writing '%s': %s\n"), fname, gpg_strerror (err));
2298
2299  leave:
2300   es_fclose (fp);
2301   xfree (get_membuf (&mb, NULL));
2302   release_kbnode (keyblock);
2303   return err;
2304 }