g10: fix cmp_public_key.
[gnupg.git] / g10 / call-dirmngr.c
1 /* call-dirmngr.c - GPG operations to the Dirmngr.
2  * Copyright (C) 2011 Free Software Foundation, Inc.
3  * Copyright (C) 2015  g10 Code GmbH
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 <unistd.h>
27 #include <time.h>
28 #include <assert.h>
29 #ifdef HAVE_LOCALE_H
30 # include <locale.h>
31 #endif
32
33 #include "gpg.h"
34 #include <assuan.h>
35 #include "util.h"
36 #include "membuf.h"
37 #include "options.h"
38 #include "i18n.h"
39 #include "asshelp.h"
40 #include "keyserver.h"
41 #include "call-dirmngr.h"
42
43
44 /* Parameter structure used to gather status info.  */
45 struct ks_status_parm_s
46 {
47   char *source;
48 };
49
50
51 /* Parameter structure used with the KS_SEARCH command.  */
52 struct ks_search_parm_s
53 {
54   gpg_error_t lasterr;  /* Last error code.  */
55   membuf_t saveddata;   /* Buffer to build complete lines.  */
56   char *helpbuf;        /* NULL or malloced buffer.  */
57   size_t helpbufsize;   /* Allocated size of HELPBUF.  */
58   gpg_error_t (*data_cb)(void*, int, char*);  /* Callback.  */
59   void *data_cb_value;  /* First argument for DATA_CB.  */
60   struct ks_status_parm_s *stparm; /* Link to the status parameter.  */
61 };
62
63
64 /* Parameter structure used with the KS_GET command.  */
65 struct ks_get_parm_s
66 {
67   estream_t memfp;
68 };
69
70
71 /* Parameter structure used with the KS_PUT command.  */
72 struct ks_put_parm_s
73 {
74   assuan_context_t ctx;
75   kbnode_t keyblock;  /* The optional keyblock.  */
76   const void *data;   /* The key in OpenPGP binary format.  */
77   size_t datalen;     /* The length of DATA.  */
78 };
79
80
81 /* Parameter structure used with the DNS_CERT command.  */
82 struct dns_cert_parm_s
83 {
84   estream_t memfp;
85   unsigned char *fpr;
86   size_t fprlen;
87   char *url;
88 };
89
90
91 /* Data used to associate an session with dirmngr contexts.  We can't
92    use a simple one to one mapping because we sometimes need two
93    connections to the dirmngr; for example while doing a listing and
94    being in a data callback we may want to retrieve a key.  The local
95    dirmngr data takes care of this.  At the end of the session the
96    function dirmngr_deinit_session_data is called by gpg.c to cleanup
97    these resources.  Note that gpg.h defines a typedef dirmngr_local_t
98    for this structure. */
99 struct dirmngr_local_s
100 {
101   /* Link to other contexts which are used simultaneously.  */
102   struct dirmngr_local_s *next;
103
104   /* The active Assuan context. */
105   assuan_context_t ctx;
106
107   /* Flag set when the keyserver names have been send.  */
108   int set_keyservers_done;
109
110   /* Flag set to true while an operation is running on CTX.  */
111   int is_active;
112 };
113
114
115 \f
116 /* Deinitialize all session data of dirmngr pertaining to CTRL.  */
117 void
118 gpg_dirmngr_deinit_session_data (ctrl_t ctrl)
119 {
120   dirmngr_local_t dml;
121
122   while ((dml = ctrl->dirmngr_local))
123     {
124       ctrl->dirmngr_local = dml->next;
125       if (dml->is_active)
126         log_error ("oops: trying to cleanup an active dirmngr context\n");
127       else
128         assuan_release (dml->ctx);
129       xfree (dml);
130     }
131 }
132
133
134 /* Try to connect to the Dirmngr via a socket or spawn it if possible.
135    Handle the server's initial greeting and set global options.  */
136 static gpg_error_t
137 create_context (ctrl_t ctrl, assuan_context_t *r_ctx)
138 {
139   gpg_error_t err;
140   assuan_context_t ctx;
141
142   *r_ctx = NULL;
143   err = start_new_dirmngr (&ctx,
144                            GPG_ERR_SOURCE_DEFAULT,
145                            opt.homedir,
146                            opt.dirmngr_program,
147                            opt.autostart, opt.verbose, DBG_IPC,
148                            NULL /*gpg_status2*/, ctrl);
149   if (!opt.autostart && gpg_err_code (err) == GPG_ERR_NO_DIRMNGR)
150     {
151       static int shown;
152
153       if (!shown)
154         {
155           shown = 1;
156           log_info (_("no dirmngr running in this session\n"));
157         }
158     }
159   else if (!err)
160     {
161       char *line;
162
163       /* Tell the dirmngr that we want to collect audit event. */
164       /* err = assuan_transact (agent_ctx, "OPTION audit-events=1", */
165       /*                        NULL, NULL, NULL, NULL, NULL, NULL); */
166       if (opt.keyserver_options.http_proxy)
167         {
168           line = xtryasprintf ("OPTION http-proxy=%s",
169                                opt.keyserver_options.http_proxy);
170           if (!line)
171             err = gpg_error_from_syserror ();
172           else
173             {
174               err = assuan_transact (ctx, line, NULL, NULL, NULL,
175                                      NULL, NULL, NULL);
176               xfree (line);
177             }
178         }
179     }
180
181   if (err)
182     assuan_release (ctx);
183   else
184     {
185       /* audit_log_ok (ctrl->audit, AUDIT_DIRMNGR_READY, err); */
186       *r_ctx = ctx;
187     }
188
189   return err;
190 }
191
192
193 /* Get a context for accessing dirmngr.  If no context is available a
194    new one is created and - if required - dirmngr started.  On success
195    an assuan context is stored at R_CTX.  This context may only be
196    released by means of close_context.  Note that NULL is stored at
197    R_CTX on error.  */
198 static gpg_error_t
199 open_context (ctrl_t ctrl, assuan_context_t *r_ctx)
200 {
201   gpg_error_t err;
202   dirmngr_local_t dml;
203
204   *r_ctx = NULL;
205   for (;;)
206     {
207       for (dml = ctrl->dirmngr_local; dml && dml->is_active; dml = dml->next)
208         ;
209       if (dml)
210         {
211           /* Found an inactive local session - return that.  */
212           assert (!dml->is_active);
213
214           /* But first do the per session init if not yet done.  */
215           if (!dml->set_keyservers_done)
216             {
217               keyserver_spec_t ksi;
218
219               /* Set all configured keyservers.  We clear existing
220                  keyservers so that any keyserver configured in GPG
221                  overrides keyservers possibly still configured in Dirmngr
222                  for the session (Note that the keyserver list of a
223                  session in Dirmngr survives a RESET. */
224               for (ksi = opt.keyserver; ksi; ksi = ksi->next)
225                 {
226                   char *line;
227
228                   line = xtryasprintf
229                     ("KEYSERVER%s %s",
230                      ksi == opt.keyserver? " --clear":"", ksi->uri);
231                   if (!line)
232                     err = gpg_error_from_syserror ();
233                   else
234                     {
235                       err = assuan_transact (dml->ctx, line, NULL, NULL, NULL,
236                                              NULL, NULL, NULL);
237                       xfree (line);
238                     }
239
240                   if (err)
241                     return err;
242                 }
243
244               dml->set_keyservers_done = 1;
245             }
246
247           dml->is_active = 1;
248
249           *r_ctx = dml->ctx;
250           return 0;
251         }
252
253       dml = xtrycalloc (1, sizeof *dml);
254       if (!dml)
255         return gpg_error_from_syserror ();
256       err = create_context (ctrl, &dml->ctx);
257       if (err)
258         {
259           xfree (dml);
260           return err;
261         }
262
263       /* To be on the nPth thread safe site we need to add it to a
264          list; this is far easier than to have a lock for this
265          function.  It should not happen anyway but the code is free
266          because we need it for the is_active check above.  */
267       dml->next = ctrl->dirmngr_local;
268       ctrl->dirmngr_local = dml;
269     }
270 }
271
272
273 /* Close the assuan context CTX or return it to a pool of unused
274    contexts.  If CTX is NULL, the function does nothing.  */
275 static void
276 close_context (ctrl_t ctrl, assuan_context_t ctx)
277 {
278   dirmngr_local_t dml;
279
280   if (!ctx)
281     return;
282
283   for (dml = ctrl->dirmngr_local; dml; dml = dml->next)
284     {
285       if (dml->ctx == ctx)
286         {
287           if (!dml->is_active)
288             log_fatal ("closing inactive dirmngr context %p\n", ctx);
289           dml->is_active = 0;
290           return;
291         }
292     }
293   log_fatal ("closing unknown dirmngr ctx %p\n", ctx);
294 }
295
296
297 /* Clear the set_keyservers_done flag on context CTX.  */
298 static void
299 clear_context_flags (ctrl_t ctrl, assuan_context_t ctx)
300 {
301   dirmngr_local_t dml;
302
303   if (!ctx)
304     return;
305
306   for (dml = ctrl->dirmngr_local; dml; dml = dml->next)
307     {
308       if (dml->ctx == ctx)
309         {
310           if (!dml->is_active)
311             log_fatal ("clear_context_flags on inactive dirmngr ctx %p\n", ctx);
312           dml->set_keyservers_done = 0;
313           return;
314         }
315     }
316   log_fatal ("clear_context_flags on unknown dirmngr ctx %p\n", ctx);
317 }
318
319
320 \f
321 /* Status callback for ks_get and ks_search.  */
322 static gpg_error_t
323 ks_status_cb (void *opaque, const char *line)
324 {
325   struct ks_status_parm_s *parm = opaque;
326   gpg_error_t err = 0;
327   const char *s;
328
329   if ((s = has_leading_keyword (line, "SOURCE")))
330     {
331       if (!parm->source)
332         {
333           parm->source = xtrystrdup (s);
334           if (!parm->source)
335             err = gpg_error_from_syserror ();
336         }
337     }
338
339   return err;
340 }
341
342
343 \f
344 /* Data callback for the KS_SEARCH command. */
345 static gpg_error_t
346 ks_search_data_cb (void *opaque, const void *data, size_t datalen)
347 {
348   gpg_error_t err = 0;
349   struct ks_search_parm_s *parm = opaque;
350   const char *line, *s;
351   size_t rawlen, linelen;
352   char fixedbuf[256];
353
354   if (parm->lasterr)
355     return 0;
356
357   if (parm->stparm->source)
358     {
359       err = parm->data_cb (parm->data_cb_value, 1, parm->stparm->source);
360       if (err)
361         {
362           parm->lasterr = err;
363           return err;
364         }
365       /* Clear it so that we won't get back here unless the server
366          accidentally sends a second source status line.  Note that
367          will not see all accidentally sent source lines because it
368          depends on whether data lines have been send in between.  */
369       xfree (parm->stparm->source);
370       parm->stparm->source = NULL;
371     }
372
373   if (!data)
374     return 0;  /* Ignore END commands.  */
375
376   put_membuf (&parm->saveddata, data, datalen);
377
378  again:
379   line = peek_membuf (&parm->saveddata, &rawlen);
380   if (!line)
381     {
382       parm->lasterr = gpg_error_from_syserror ();
383       return parm->lasterr; /* Tell the server about our problem.  */
384     }
385   if ((s = memchr (line, '\n', rawlen)))
386     {
387       linelen = s - line;  /* That is the length excluding the LF.  */
388       if (linelen + 1 < sizeof fixedbuf)
389         {
390           /* We can use the static buffer.  */
391           memcpy (fixedbuf, line, linelen);
392           fixedbuf[linelen] = 0;
393           if (linelen && fixedbuf[linelen-1] == '\r')
394             fixedbuf[linelen-1] = 0;
395           err = parm->data_cb (parm->data_cb_value, 0, fixedbuf);
396         }
397       else
398         {
399           if (linelen + 1 >= parm->helpbufsize)
400             {
401               xfree (parm->helpbuf);
402               parm->helpbufsize = linelen + 1 + 1024;
403               parm->helpbuf = xtrymalloc (parm->helpbufsize);
404               if (!parm->helpbuf)
405                 {
406                   parm->lasterr = gpg_error_from_syserror ();
407                   return parm->lasterr;
408                 }
409             }
410           memcpy (parm->helpbuf, line, linelen);
411           parm->helpbuf[linelen] = 0;
412           if (linelen && parm->helpbuf[linelen-1] == '\r')
413             parm->helpbuf[linelen-1] = 0;
414           err = parm->data_cb (parm->data_cb_value, 0, parm->helpbuf);
415         }
416       if (err)
417         parm->lasterr = err;
418       else
419         {
420           clear_membuf (&parm->saveddata, linelen+1);
421           goto again;  /* There might be another complete line.  */
422         }
423     }
424
425   return err;
426 }
427
428
429 /* Run the KS_SEARCH command using the search string SEARCHSTR.  All
430    data lines are passed to the CB function.  That function is called
431    with CB_VALUE as its first argument, a 0 as second argument, and
432    the decoded data line as third argument.  The callback function may
433    modify the data line and it is guaranteed that this data line is a
434    complete line with a terminating 0 character but without the
435    linefeed.  NULL is passed to the callback to indicate EOF.  */
436 gpg_error_t
437 gpg_dirmngr_ks_search (ctrl_t ctrl, const char *searchstr,
438                        gpg_error_t (*cb)(void*, int, char *), void *cb_value)
439 {
440   gpg_error_t err;
441   assuan_context_t ctx;
442   struct ks_status_parm_s stparm;
443   struct ks_search_parm_s parm;
444   char line[ASSUAN_LINELENGTH];
445
446   err = open_context (ctrl, &ctx);
447   if (err)
448     return err;
449
450   {
451     char *escsearchstr = percent_plus_escape (searchstr);
452     if (!escsearchstr)
453       {
454         err = gpg_error_from_syserror ();
455         close_context (ctrl, ctx);
456         return err;
457       }
458     snprintf (line, sizeof line, "KS_SEARCH -- %s", escsearchstr);
459     xfree (escsearchstr);
460   }
461
462   memset (&stparm, 0, sizeof stparm);
463   memset (&parm, 0, sizeof parm);
464   init_membuf (&parm.saveddata, 1024);
465   parm.data_cb = cb;
466   parm.data_cb_value = cb_value;
467   parm.stparm = &stparm;
468
469   err = assuan_transact (ctx, line, ks_search_data_cb, &parm,
470                         NULL, NULL, ks_status_cb, &stparm);
471   if (!err)
472     err = cb (cb_value, 0, NULL);  /* Send EOF.  */
473
474   xfree (get_membuf (&parm.saveddata, NULL));
475   xfree (parm.helpbuf);
476   xfree (stparm.source);
477
478   close_context (ctrl, ctx);
479   return err;
480 }
481
482
483 \f
484 /* Data callback for the KS_GET and KS_FETCH commands. */
485 static gpg_error_t
486 ks_get_data_cb (void *opaque, const void *data, size_t datalen)
487 {
488   gpg_error_t err = 0;
489   struct ks_get_parm_s *parm = opaque;
490   size_t nwritten;
491
492   if (!data)
493     return 0;  /* Ignore END commands.  */
494
495   if (es_write (parm->memfp, data, datalen, &nwritten))
496     err = gpg_error_from_syserror ();
497
498   return err;
499 }
500
501
502 /* Run the KS_GET command using the patterns in the array PATTERN.  On
503    success an estream object is returned to retrieve the keys.  On
504    error an error code is returned and NULL stored at R_FP.
505
506    The pattern may only use search specification which a keyserver can
507    use to retrieve keys.  Because we know the format of the pattern we
508    don't need to escape the patterns before sending them to the
509    server.
510
511    If R_SOURCE is not NULL the source of the data is stored as a
512    malloced string there.  If a source is not known NULL is stored.
513
514    If there are too many patterns the function returns an error.  That
515    could be fixed by issuing several search commands or by
516    implementing a different interface.  However with long keyids we
517    are able to ask for (1000-10-1)/(2+8+1) = 90 keys at once.  */
518 gpg_error_t
519 gpg_dirmngr_ks_get (ctrl_t ctrl, char **pattern,
520                     keyserver_spec_t override_keyserver,
521                     estream_t *r_fp, char **r_source)
522 {
523   gpg_error_t err;
524   assuan_context_t ctx;
525   struct ks_status_parm_s stparm;
526   struct ks_get_parm_s parm;
527   char *line = NULL;
528   size_t linelen;
529   membuf_t mb;
530   int idx;
531
532   memset (&stparm, 0, sizeof stparm);
533   memset (&parm, 0, sizeof parm);
534
535   *r_fp = NULL;
536   if (r_source)
537     *r_source = NULL;
538
539   err = open_context (ctrl, &ctx);
540   if (err)
541     return err;
542
543   /* If we have an override keyserver we first indicate that the next
544      user of the context needs to again setup the global keyservers and
545      them we send the override keyserver.  */
546   if (override_keyserver)
547     {
548       clear_context_flags (ctrl, ctx);
549       line = xtryasprintf ("KEYSERVER --clear %s", override_keyserver->uri);
550       if (!line)
551         {
552           err = gpg_error_from_syserror ();
553           goto leave;
554         }
555       err = assuan_transact (ctx, line, NULL, NULL, NULL,
556                              NULL, NULL, NULL);
557       if (err)
558         goto leave;
559
560       xfree (line);
561       line = NULL;
562     }
563
564   /* Lump all patterns into one string.  */
565   init_membuf (&mb, 1024);
566   put_membuf_str (&mb, "KS_GET --");
567   for (idx=0; pattern[idx]; idx++)
568     {
569       put_membuf (&mb, " ", 1); /* Append Delimiter.  */
570       put_membuf_str (&mb, pattern[idx]);
571     }
572   put_membuf (&mb, "", 1); /* Append Nul.  */
573   line = get_membuf (&mb, &linelen);
574   if (!line)
575     {
576       err = gpg_error_from_syserror ();
577       goto leave;
578     }
579   if (linelen + 2 >= ASSUAN_LINELENGTH)
580     {
581       err = gpg_error (GPG_ERR_TOO_MANY);
582       goto leave;
583     }
584
585   parm.memfp = es_fopenmem (0, "rwb");
586   if (!parm.memfp)
587     {
588       err = gpg_error_from_syserror ();
589       goto leave;
590     }
591   err = assuan_transact (ctx, line, ks_get_data_cb, &parm,
592                          NULL, NULL, ks_status_cb, &stparm);
593   if (err)
594     goto leave;
595
596   es_rewind (parm.memfp);
597   *r_fp = parm.memfp;
598   parm.memfp = NULL;
599
600   if (r_source)
601     {
602       *r_source = stparm.source;
603       stparm.source = NULL;
604     }
605
606  leave:
607   es_fclose (parm.memfp);
608   xfree (stparm.source);
609   xfree (line);
610   close_context (ctrl, ctx);
611   return err;
612 }
613
614
615 /* Run the KS_FETCH and pass URL as argument.  On success an estream
616    object is returned to retrieve the keys.  On error an error code is
617    returned and NULL stored at R_FP.
618
619    The url is expected to point to a small set of keys; in many cases
620    only to one key.  However, schemes like finger may return several
621    keys.  Note that the configured keyservers are ignored by the
622    KS_FETCH command.  */
623 gpg_error_t
624 gpg_dirmngr_ks_fetch (ctrl_t ctrl, const char *url, estream_t *r_fp)
625 {
626   gpg_error_t err;
627   assuan_context_t ctx;
628   struct ks_get_parm_s parm;
629   char *line = NULL;
630
631   memset (&parm, 0, sizeof parm);
632
633   *r_fp = NULL;
634
635   err = open_context (ctrl, &ctx);
636   if (err)
637     return err;
638
639   line = strconcat ("KS_FETCH -- ", url, NULL);
640   if (!line)
641     {
642       err = gpg_error_from_syserror ();
643       goto leave;
644     }
645   if (strlen (line) + 2 >= ASSUAN_LINELENGTH)
646     {
647       err = gpg_error (GPG_ERR_TOO_LARGE);
648       goto leave;
649     }
650
651   parm.memfp = es_fopenmem (0, "rwb");
652   if (!parm.memfp)
653     {
654       err = gpg_error_from_syserror ();
655       goto leave;
656     }
657   err = assuan_transact (ctx, line, ks_get_data_cb, &parm,
658                          NULL, NULL, NULL, NULL);
659   if (err)
660     goto leave;
661
662   es_rewind (parm.memfp);
663   *r_fp = parm.memfp;
664   parm.memfp = NULL;
665
666  leave:
667   es_fclose (parm.memfp);
668   xfree (line);
669   close_context (ctrl, ctx);
670   return err;
671 }
672
673
674 \f
675 static void
676 record_output (estream_t output,
677                pkttype_t type,
678                const char *validity,
679                /* The public key length or -1.  */
680                int pub_key_length,
681                /* The public key algo or -1.  */
682                int pub_key_algo,
683                /* 2 ulongs or NULL.  */
684                const u32 *keyid,
685                /* The creation / expiration date or 0.  */
686                u32 creation_date,
687                u32 expiration_date,
688                const char *userid)
689 {
690   const char *type_str = NULL;
691   char *pub_key_length_str = NULL;
692   char *pub_key_algo_str = NULL;
693   char *keyid_str = NULL;
694   char *creation_date_str = NULL;
695   char *expiration_date_str = NULL;
696   char *userid_escaped = NULL;
697
698   switch (type)
699     {
700     case PKT_PUBLIC_KEY:
701       type_str = "pub";
702       break;
703     case PKT_PUBLIC_SUBKEY:
704       type_str = "sub";
705       break;
706     case PKT_USER_ID:
707       type_str = "uid";
708       break;
709     case PKT_SIGNATURE:
710       type_str = "sig";
711       break;
712     default:
713       assert (! "Unhandled type.");
714     }
715
716   if (pub_key_length > 0)
717     pub_key_length_str = xasprintf ("%d", pub_key_length);
718
719   if (pub_key_algo != -1)
720     pub_key_algo_str = xasprintf ("%d", pub_key_algo);
721
722   if (keyid)
723     keyid_str = xasprintf ("%08lX%08lX", (ulong) keyid[0], (ulong) keyid[1]);
724
725   if (creation_date)
726     creation_date_str = xstrdup (colon_strtime (creation_date));
727
728   if (expiration_date)
729     expiration_date_str = xstrdup (colon_strtime (expiration_date));
730
731   /* Quote ':', '%', and any 8-bit characters.  */
732   if (userid)
733     {
734       int r;
735       int w = 0;
736
737       int len = strlen (userid);
738       /* A 100k character limit on the uid should be way more than
739          enough.  */
740       if (len > 100 * 1024)
741         len = 100 * 1024;
742
743       /* The minimum amount of space that we need.  */
744       userid_escaped = xmalloc (len * 3 + 1);
745
746       for (r = 0; r < len; r++)
747         {
748           if (userid[r] == ':' || userid[r]== '%' || (userid[r] & 0x80))
749             {
750               sprintf (&userid_escaped[w], "%%%02X", (byte) userid[r]);
751               w += 3;
752             }
753           else
754             userid_escaped[w ++] = userid[r];
755         }
756       userid_escaped[w] = '\0';
757     }
758
759   es_fprintf (output, "%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s\n",
760               type_str,
761               validity ?: "",
762               pub_key_length_str ?: "",
763               pub_key_algo_str ?: "",
764               keyid_str ?: "",
765               creation_date_str ?: "",
766               expiration_date_str ?: "",
767               "" /* Certificate S/N */,
768               "" /* Ownertrust.  */,
769               userid_escaped ?: "",
770               "" /* Signature class.  */,
771               "" /* Key capabilities.  */,
772               "" /* Issuer certificate fingerprint.  */,
773               "" /* Flag field.  */,
774               "" /* S/N of a token.  */,
775               "" /* Hash algo.  */,
776               "" /* Curve name.  */);
777
778   xfree (userid_escaped);
779   xfree (expiration_date_str);
780   xfree (creation_date_str);
781   xfree (keyid_str);
782   xfree (pub_key_algo_str);
783   xfree (pub_key_length_str);
784 }
785
786 /* Handle the KS_PUT inquiries. */
787 static gpg_error_t
788 ks_put_inq_cb (void *opaque, const char *line)
789 {
790   struct ks_put_parm_s *parm = opaque;
791   gpg_error_t err = 0;
792
793   if (has_leading_keyword (line, "KEYBLOCK"))
794     {
795       if (parm->data)
796         err = assuan_send_data (parm->ctx, parm->data, parm->datalen);
797     }
798   else if (has_leading_keyword (line, "KEYBLOCK_INFO"))
799     {
800       kbnode_t node;
801       estream_t fp;
802
803       /* Parse the keyblock and send info lines back to the server.  */
804       fp = es_fopenmem (0, "rw,samethread");
805       if (!fp)
806         err = gpg_error_from_syserror ();
807
808       /* Note: the output format for the INFO block follows the colon
809          format as described in doc/DETAILS.  We don't actually reuse
810          the functionality from g10/keylist.c to produce the output,
811          because we don't need all of it and some of it is quite
812          expensive to generate.
813
814          The fields are (the starred fields are the ones we need):
815
816            * Field 1 - Type of record
817            * Field 2 - Validity
818            * Field 3 - Key length
819            * Field 4 - Public key algorithm
820            * Field 5 - KeyID
821            * Field 6 - Creation date
822            * Field 7 - Expiration date
823              Field 8 - Certificate S/N, UID hash, trust signature info
824              Field 9 -  Ownertrust
825            * Field 10 - User-ID
826              Field 11 - Signature class
827              Field 12 - Key capabilities
828              Field 13 - Issuer certificate fingerprint or other info
829              Field 14 - Flag field
830              Field 15 - S/N of a token
831              Field 16 - Hash algorithm
832              Field 17 - Curve name
833        */
834       for (node = parm->keyblock; !err && node; node=node->next)
835         {
836           switch (node->pkt->pkttype)
837             {
838             case PKT_PUBLIC_KEY:
839             case PKT_PUBLIC_SUBKEY:
840               {
841                 PKT_public_key *pk = node->pkt->pkt.public_key;
842
843                 char validity[3];
844                 int i;
845
846                 i = 0;
847                 if (pk->flags.revoked)
848                   validity[i ++] = 'r';
849                 if (pk->has_expired)
850                   validity[i ++] = 'e';
851                 validity[i] = '\0';
852
853                 keyid_from_pk (pk, NULL);
854
855                 record_output (fp, node->pkt->pkttype, validity,
856                                nbits_from_pk (pk), pk->pubkey_algo,
857                                pk->keyid, pk->timestamp, pk->expiredate,
858                                NULL);
859               }
860               break;
861
862             case PKT_USER_ID:
863               {
864                 PKT_user_id *uid = node->pkt->pkt.user_id;
865
866                 if (!uid->attrib_data)
867                   {
868                     char validity[3];
869                     int i;
870
871                     i = 0;
872                     if (uid->is_revoked)
873                       validity[i ++] = 'r';
874                     if (uid->is_expired)
875                       validity[i ++] = 'e';
876                     validity[i] = '\0';
877
878                     record_output (fp, node->pkt->pkttype, validity,
879                                    -1, -1, NULL,
880                                    uid->created, uid->expiredate,
881                                    uid->name);
882                   }
883               }
884               break;
885
886               /* This bit is really for the benefit of people who
887                  store their keys in LDAP servers.  It makes it easy
888                  to do queries for things like "all keys signed by
889                  Isabella".  */
890             case PKT_SIGNATURE:
891               {
892                 PKT_signature *sig = node->pkt->pkt.signature;
893
894                 if (IS_UID_SIG (sig))
895                   record_output (fp, node->pkt->pkttype, NULL,
896                                  -1, -1, sig->keyid,
897                                  sig->timestamp, sig->expiredate, NULL);
898               }
899               break;
900
901             default:
902               continue;
903             }
904           /* Given that the last operation was an es_fprintf we should
905              get the correct ERRNO if ferror indicates an error.  */
906           if (es_ferror (fp))
907             err = gpg_error_from_syserror ();
908         }
909
910       /* Without an error and if we have an keyblock at all, send the
911          data back.  */
912       if (!err && parm->keyblock)
913         {
914           int rc;
915           char buffer[512];
916           size_t nread;
917
918           es_rewind (fp);
919           while (!(rc=es_read (fp, buffer, sizeof buffer, &nread)) && nread)
920             {
921               err = assuan_send_data (parm->ctx, buffer, nread);
922               if (err)
923                 break;
924             }
925           if (!err && rc)
926             err = gpg_error_from_syserror ();
927         }
928       es_fclose (fp);
929     }
930   else
931     return gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
932
933   return err;
934 }
935
936
937 /* Send a key to the configured server.  {DATA,DATLEN} contains the
938    key in OpenPGP binary transport format.  If KEYBLOCK is not NULL it
939    has the internal representaion of that key; this is for example
940    used to convey meta data to LDAP keyservers.  */
941 gpg_error_t
942 gpg_dirmngr_ks_put (ctrl_t ctrl, void *data, size_t datalen, kbnode_t keyblock)
943 {
944   gpg_error_t err;
945   assuan_context_t ctx;
946   struct ks_put_parm_s parm;
947
948   memset (&parm, 0, sizeof parm);
949
950   /* We are going to parse the keyblock, thus we better make sure the
951      all information is readily available.  */
952   if (keyblock)
953     merge_keys_and_selfsig (keyblock);
954
955   err = open_context (ctrl, &ctx);
956   if (err)
957     return err;
958
959   parm.ctx = ctx;
960   parm.keyblock = keyblock;
961   parm.data = data;
962   parm.datalen = datalen;
963
964   err = assuan_transact (ctx, "KS_PUT", NULL, NULL,
965                          ks_put_inq_cb, &parm, NULL, NULL);
966
967   close_context (ctrl, ctx);
968   return err;
969 }
970
971
972 \f
973 /* Data callback for the DNS_CERT command. */
974 static gpg_error_t
975 dns_cert_data_cb (void *opaque, const void *data, size_t datalen)
976 {
977   struct dns_cert_parm_s *parm = opaque;
978   gpg_error_t err = 0;
979   size_t nwritten;
980
981   if (!data)
982     return 0;  /* Ignore END commands.  */
983   if (!parm->memfp)
984     return 0;  /* Data is not required.  */
985
986   if (es_write (parm->memfp, data, datalen, &nwritten))
987     err = gpg_error_from_syserror ();
988
989   return err;
990 }
991
992
993 /* Status callback for the DNS_CERT command.  */
994 static gpg_error_t
995 dns_cert_status_cb (void *opaque, const char *line)
996 {
997   struct dns_cert_parm_s *parm = opaque;
998   gpg_error_t err = 0;
999   const char *s;
1000   size_t nbytes;
1001
1002   if ((s = has_leading_keyword (line, "FPR")))
1003     {
1004       char *buf;
1005
1006       if (!(buf = xtrystrdup (s)))
1007         err = gpg_error_from_syserror ();
1008       else if (parm->fpr)
1009         err = gpg_error (GPG_ERR_DUP_KEY);
1010       else if (!hex2str (buf, buf, strlen (buf)+1, &nbytes))
1011         err = gpg_error_from_syserror ();
1012       else if (nbytes < 20)
1013         err = gpg_error (GPG_ERR_TOO_SHORT);
1014       else
1015         {
1016           parm->fpr = xtrymalloc (nbytes);
1017           if (!parm->fpr)
1018             err = gpg_error_from_syserror ();
1019           else
1020             memcpy (parm->fpr, buf, (parm->fprlen = nbytes));
1021         }
1022       xfree (buf);
1023     }
1024   else if ((s = has_leading_keyword (line, "URL")) && *s)
1025     {
1026       if (parm->url)
1027         err = gpg_error (GPG_ERR_DUP_KEY);
1028       else if (!(parm->fpr = xtrymalloc (nbytes)))
1029         err = gpg_error_from_syserror ();
1030       else
1031         memcpy (parm->fpr, line, (parm->fprlen = nbytes));
1032     }
1033
1034   return err;
1035 }
1036
1037 /* Ask the dirmngr for a DNS CERT record.  Depending on the found
1038    subtypes different return values are set:
1039
1040    - For a PGP subtype a new estream with that key will be returned at
1041      R_KEY and the other return parameters are set to NULL/0.
1042
1043    - For an IPGP subtype the fingerprint is stored as a malloced block
1044      at (R_FPR,R_FPRLEN).  If an URL is available it is stored as a
1045      malloced string at R_URL; NULL is stored if there is no URL.
1046
1047    If CERTTYPE is DNS_CERTTYPE_ANY this function returns the first
1048    CERT record found with a supported type; it is expected that only
1049    one CERT record is used.  If CERTTYPE is one of the supported
1050    certtypes, only records with this certtype are considered and the
1051    first one found is returned.  All R_* args are optional. */
1052 gpg_error_t
1053 gpg_dirmngr_dns_cert (ctrl_t ctrl, const char *name, const char *certtype,
1054                       estream_t *r_key,
1055                       unsigned char **r_fpr, size_t *r_fprlen,
1056                       char **r_url)
1057 {
1058   gpg_error_t err;
1059   assuan_context_t ctx;
1060   struct dns_cert_parm_s parm;
1061   char *line = NULL;
1062
1063   memset (&parm, 0, sizeof parm);
1064   if (r_key)
1065     *r_key = NULL;
1066   if (r_fpr)
1067     *r_fpr = NULL;
1068   if (r_fprlen)
1069     *r_fprlen = 0;
1070   if (r_url)
1071     *r_url = NULL;
1072
1073   err = open_context (ctrl, &ctx);
1074   if (err)
1075     return err;
1076
1077   line = es_bsprintf ("DNS_CERT %s %s", certtype, name);
1078   if (!line)
1079     {
1080       err = gpg_error_from_syserror ();
1081       goto leave;
1082     }
1083   if (strlen (line) + 2 >= ASSUAN_LINELENGTH)
1084     {
1085       err = gpg_error (GPG_ERR_TOO_LARGE);
1086       goto leave;
1087     }
1088
1089   parm.memfp = es_fopenmem (0, "rwb");
1090   if (!parm.memfp)
1091     {
1092       err = gpg_error_from_syserror ();
1093       goto leave;
1094     }
1095   err = assuan_transact (ctx, line, dns_cert_data_cb, &parm,
1096                          NULL, NULL, dns_cert_status_cb, &parm);
1097   if (err)
1098     goto leave;
1099
1100   if (r_key)
1101     {
1102       es_rewind (parm.memfp);
1103       *r_key = parm.memfp;
1104       parm.memfp = NULL;
1105     }
1106
1107   if (r_fpr && parm.fpr)
1108     {
1109       *r_fpr = parm.fpr;
1110       parm.fpr = NULL;
1111     }
1112   if (r_fprlen)
1113     *r_fprlen = parm.fprlen;
1114
1115   if (r_url && parm.url)
1116     {
1117       *r_url = parm.url;
1118       parm.url = NULL;
1119     }
1120
1121  leave:
1122   xfree (parm.fpr);
1123   xfree (parm.url);
1124   es_fclose (parm.memfp);
1125   xfree (line);
1126   close_context (ctrl, ctx);
1127   return err;
1128 }
1129
1130
1131 /* Ask the dirmngr for PKA info.  On success the retrieved fingerprint
1132    is returned in a malloced buffer at R_FPR and its length is stored
1133    at R_FPRLEN.  If an URL is available it is stored as a malloced
1134    string at R_URL.  On error all return values are set to NULL/0.  */
1135 gpg_error_t
1136 gpg_dirmngr_get_pka (ctrl_t ctrl, const char *userid,
1137                      unsigned char **r_fpr, size_t *r_fprlen,
1138                      char **r_url)
1139 {
1140   gpg_error_t err;
1141   assuan_context_t ctx;
1142   struct dns_cert_parm_s parm;
1143   char *line = NULL;
1144
1145   memset (&parm, 0, sizeof parm);
1146   if (r_fpr)
1147     *r_fpr = NULL;
1148   if (r_fprlen)
1149     *r_fprlen = 0;
1150   if (r_url)
1151     *r_url = NULL;
1152
1153   err = open_context (ctrl, &ctx);
1154   if (err)
1155     return err;
1156
1157   line = es_bsprintf ("DNS_CERT --pka -- %s", userid);
1158   if (!line)
1159     {
1160       err = gpg_error_from_syserror ();
1161       goto leave;
1162     }
1163   if (strlen (line) + 2 >= ASSUAN_LINELENGTH)
1164     {
1165       err = gpg_error (GPG_ERR_TOO_LARGE);
1166       goto leave;
1167     }
1168
1169   err = assuan_transact (ctx, line, dns_cert_data_cb, &parm,
1170                          NULL, NULL, dns_cert_status_cb, &parm);
1171   if (err)
1172     goto leave;
1173
1174   if (r_fpr && parm.fpr)
1175     {
1176       *r_fpr = parm.fpr;
1177       parm.fpr = NULL;
1178     }
1179   if (r_fprlen)
1180     *r_fprlen = parm.fprlen;
1181
1182   if (r_url && parm.url)
1183     {
1184       *r_url = parm.url;
1185       parm.url = NULL;
1186     }
1187
1188  leave:
1189   xfree (parm.fpr);
1190   xfree (parm.url);
1191   xfree (line);
1192   close_context (ctrl, ctx);
1193   return err;
1194 }