1 /* call-dirmngr.c - GPG operations to the Dirmngr.
2 * Copyright (C) 2011 Free Software Foundation, Inc.
3 * Copyright (C) 2015 g10 Code GmbH
5 * This file is part of GnuPG.
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.
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.
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/>.
40 #include "keyserver.h"
41 #include "call-dirmngr.h"
44 /* Parameter structure used to gather status info. */
45 struct ks_status_parm_s
51 /* Parameter structure used with the KS_SEARCH command. */
52 struct ks_search_parm_s
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. */
64 /* Parameter structure used with the KS_GET command. */
71 /* Parameter structure used with the KS_PUT command. */
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. */
81 /* Parameter structure used with the DNS_CERT command. */
82 struct dns_cert_parm_s
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
101 /* Link to other contexts which are used simultaneously. */
102 struct dirmngr_local_s *next;
104 /* The active Assuan context. */
105 assuan_context_t ctx;
107 /* Flag set when the keyserver names have been send. */
108 int set_keyservers_done;
110 /* Flag set to true while an operation is running on CTX. */
116 /* Deinitialize all session data of dirmngr pertaining to CTRL. */
118 gpg_dirmngr_deinit_session_data (ctrl_t ctrl)
122 while ((dml = ctrl->dirmngr_local))
124 ctrl->dirmngr_local = dml->next;
126 log_error ("oops: trying to cleanup an active dirmngr context\n");
128 assuan_release (dml->ctx);
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. */
137 create_context (ctrl_t ctrl, assuan_context_t *r_ctx)
140 assuan_context_t ctx;
143 err = start_new_dirmngr (&ctx,
144 GPG_ERR_SOURCE_DEFAULT,
147 opt.autostart, opt.verbose, DBG_IPC,
148 NULL /*gpg_status2*/, ctrl);
149 if (!opt.autostart && gpg_err_code (err) == GPG_ERR_NO_DIRMNGR)
156 log_info (_("no dirmngr running in this session\n"));
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)
168 line = xtryasprintf ("OPTION http-proxy=%s",
169 opt.keyserver_options.http_proxy);
171 err = gpg_error_from_syserror ();
174 err = assuan_transact (ctx, line, NULL, NULL, NULL,
182 assuan_release (ctx);
185 /* audit_log_ok (ctrl->audit, AUDIT_DIRMNGR_READY, err); */
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
199 open_context (ctrl_t ctrl, assuan_context_t *r_ctx)
207 for (dml = ctrl->dirmngr_local; dml && dml->is_active; dml = dml->next)
211 /* Found an inactive local session - return that. */
212 assert (!dml->is_active);
214 /* But first do the per session init if not yet done. */
215 if (!dml->set_keyservers_done)
217 keyserver_spec_t ksi;
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)
230 ksi == opt.keyserver? " --clear":"", ksi->uri);
232 err = gpg_error_from_syserror ();
235 err = assuan_transact (dml->ctx, line, NULL, NULL, NULL,
244 dml->set_keyservers_done = 1;
253 dml = xtrycalloc (1, sizeof *dml);
255 return gpg_error_from_syserror ();
256 err = create_context (ctrl, &dml->ctx);
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;
273 /* Close the assuan context CTX or return it to a pool of unused
274 contexts. If CTX is NULL, the function does nothing. */
276 close_context (ctrl_t ctrl, assuan_context_t ctx)
283 for (dml = ctrl->dirmngr_local; dml; dml = dml->next)
288 log_fatal ("closing inactive dirmngr context %p\n", ctx);
293 log_fatal ("closing unknown dirmngr ctx %p\n", ctx);
297 /* Clear the set_keyservers_done flag on context CTX. */
299 clear_context_flags (ctrl_t ctrl, assuan_context_t ctx)
306 for (dml = ctrl->dirmngr_local; dml; dml = dml->next)
311 log_fatal ("clear_context_flags on inactive dirmngr ctx %p\n", ctx);
312 dml->set_keyservers_done = 0;
316 log_fatal ("clear_context_flags on unknown dirmngr ctx %p\n", ctx);
321 /* Status callback for ks_get and ks_search. */
323 ks_status_cb (void *opaque, const char *line)
325 struct ks_status_parm_s *parm = opaque;
329 if ((s = has_leading_keyword (line, "SOURCE")))
333 parm->source = xtrystrdup (s);
335 err = gpg_error_from_syserror ();
344 /* Data callback for the KS_SEARCH command. */
346 ks_search_data_cb (void *opaque, const void *data, size_t datalen)
349 struct ks_search_parm_s *parm = opaque;
350 const char *line, *s;
351 size_t rawlen, linelen;
357 if (parm->stparm->source)
359 err = parm->data_cb (parm->data_cb_value, 1, parm->stparm->source);
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;
374 return 0; /* Ignore END commands. */
376 put_membuf (&parm->saveddata, data, datalen);
379 line = peek_membuf (&parm->saveddata, &rawlen);
382 parm->lasterr = gpg_error_from_syserror ();
383 return parm->lasterr; /* Tell the server about our problem. */
385 if ((s = memchr (line, '\n', rawlen)))
387 linelen = s - line; /* That is the length excluding the LF. */
388 if (linelen + 1 < sizeof fixedbuf)
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);
399 if (linelen + 1 >= parm->helpbufsize)
401 xfree (parm->helpbuf);
402 parm->helpbufsize = linelen + 1 + 1024;
403 parm->helpbuf = xtrymalloc (parm->helpbufsize);
406 parm->lasterr = gpg_error_from_syserror ();
407 return parm->lasterr;
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);
420 clear_membuf (&parm->saveddata, linelen+1);
421 goto again; /* There might be another complete line. */
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. */
437 gpg_dirmngr_ks_search (ctrl_t ctrl, const char *searchstr,
438 gpg_error_t (*cb)(void*, int, char *), void *cb_value)
441 assuan_context_t ctx;
442 struct ks_status_parm_s stparm;
443 struct ks_search_parm_s parm;
444 char line[ASSUAN_LINELENGTH];
446 err = open_context (ctrl, &ctx);
451 char *escsearchstr = percent_plus_escape (searchstr);
454 err = gpg_error_from_syserror ();
455 close_context (ctrl, ctx);
458 snprintf (line, sizeof line, "KS_SEARCH -- %s", escsearchstr);
459 xfree (escsearchstr);
462 memset (&stparm, 0, sizeof stparm);
463 memset (&parm, 0, sizeof parm);
464 init_membuf (&parm.saveddata, 1024);
466 parm.data_cb_value = cb_value;
467 parm.stparm = &stparm;
469 err = assuan_transact (ctx, line, ks_search_data_cb, &parm,
470 NULL, NULL, ks_status_cb, &stparm);
472 err = cb (cb_value, 0, NULL); /* Send EOF. */
474 xfree (get_membuf (&parm.saveddata, NULL));
475 xfree (parm.helpbuf);
476 xfree (stparm.source);
478 close_context (ctrl, ctx);
484 /* Data callback for the KS_GET and KS_FETCH commands. */
486 ks_get_data_cb (void *opaque, const void *data, size_t datalen)
489 struct ks_get_parm_s *parm = opaque;
493 return 0; /* Ignore END commands. */
495 if (es_write (parm->memfp, data, datalen, &nwritten))
496 err = gpg_error_from_syserror ();
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.
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
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.
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. */
519 gpg_dirmngr_ks_get (ctrl_t ctrl, char **pattern,
520 keyserver_spec_t override_keyserver,
521 estream_t *r_fp, char **r_source)
524 assuan_context_t ctx;
525 struct ks_status_parm_s stparm;
526 struct ks_get_parm_s parm;
532 memset (&stparm, 0, sizeof stparm);
533 memset (&parm, 0, sizeof parm);
539 err = open_context (ctrl, &ctx);
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)
548 clear_context_flags (ctrl, ctx);
549 line = xtryasprintf ("KEYSERVER --clear %s", override_keyserver->uri);
552 err = gpg_error_from_syserror ();
555 err = assuan_transact (ctx, line, NULL, NULL, NULL,
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++)
569 put_membuf (&mb, " ", 1); /* Append Delimiter. */
570 put_membuf_str (&mb, pattern[idx]);
572 put_membuf (&mb, "", 1); /* Append Nul. */
573 line = get_membuf (&mb, &linelen);
576 err = gpg_error_from_syserror ();
579 if (linelen + 2 >= ASSUAN_LINELENGTH)
581 err = gpg_error (GPG_ERR_TOO_MANY);
585 parm.memfp = es_fopenmem (0, "rwb");
588 err = gpg_error_from_syserror ();
591 err = assuan_transact (ctx, line, ks_get_data_cb, &parm,
592 NULL, NULL, ks_status_cb, &stparm);
596 es_rewind (parm.memfp);
602 *r_source = stparm.source;
603 stparm.source = NULL;
607 es_fclose (parm.memfp);
608 xfree (stparm.source);
610 close_context (ctrl, ctx);
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.
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
624 gpg_dirmngr_ks_fetch (ctrl_t ctrl, const char *url, estream_t *r_fp)
627 assuan_context_t ctx;
628 struct ks_get_parm_s parm;
631 memset (&parm, 0, sizeof parm);
635 err = open_context (ctrl, &ctx);
639 line = strconcat ("KS_FETCH -- ", url, NULL);
642 err = gpg_error_from_syserror ();
645 if (strlen (line) + 2 >= ASSUAN_LINELENGTH)
647 err = gpg_error (GPG_ERR_TOO_LARGE);
651 parm.memfp = es_fopenmem (0, "rwb");
654 err = gpg_error_from_syserror ();
657 err = assuan_transact (ctx, line, ks_get_data_cb, &parm,
658 NULL, NULL, NULL, NULL);
662 es_rewind (parm.memfp);
667 es_fclose (parm.memfp);
669 close_context (ctrl, ctx);
676 record_output (estream_t output,
678 const char *validity,
679 /* The public key length or -1. */
681 /* The public key algo or -1. */
683 /* 2 ulongs or NULL. */
685 /* The creation / expiration date or 0. */
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;
703 case PKT_PUBLIC_SUBKEY:
713 assert (! "Unhandled type.");
716 if (pub_key_length > 0)
717 pub_key_length_str = xasprintf ("%d", pub_key_length);
719 if (pub_key_algo != -1)
720 pub_key_algo_str = xasprintf ("%d", pub_key_algo);
723 keyid_str = xasprintf ("%08lX%08lX", (ulong) keyid[0], (ulong) keyid[1]);
726 creation_date_str = xstrdup (colon_strtime (creation_date));
729 expiration_date_str = xstrdup (colon_strtime (expiration_date));
731 /* Quote ':', '%', and any 8-bit characters. */
737 int len = strlen (userid);
738 /* A 100k character limit on the uid should be way more than
740 if (len > 100 * 1024)
743 /* The minimum amount of space that we need. */
744 userid_escaped = xmalloc (len * 3 + 1);
746 for (r = 0; r < len; r++)
748 if (userid[r] == ':' || userid[r]== '%' || (userid[r] & 0x80))
750 sprintf (&userid_escaped[w], "%%%02X", (byte) userid[r]);
754 userid_escaped[w ++] = userid[r];
756 userid_escaped[w] = '\0';
759 es_fprintf (output, "%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s\n",
762 pub_key_length_str ?: "",
763 pub_key_algo_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. */,
776 "" /* Curve name. */);
778 xfree (userid_escaped);
779 xfree (expiration_date_str);
780 xfree (creation_date_str);
782 xfree (pub_key_algo_str);
783 xfree (pub_key_length_str);
786 /* Handle the KS_PUT inquiries. */
788 ks_put_inq_cb (void *opaque, const char *line)
790 struct ks_put_parm_s *parm = opaque;
793 if (has_leading_keyword (line, "KEYBLOCK"))
796 err = assuan_send_data (parm->ctx, parm->data, parm->datalen);
798 else if (has_leading_keyword (line, "KEYBLOCK_INFO"))
803 /* Parse the keyblock and send info lines back to the server. */
804 fp = es_fopenmem (0, "rw,samethread");
806 err = gpg_error_from_syserror ();
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.
814 The fields are (the starred fields are the ones we need):
816 * Field 1 - Type of record
818 * Field 3 - Key length
819 * Field 4 - Public key algorithm
821 * Field 6 - Creation date
822 * Field 7 - Expiration date
823 Field 8 - Certificate S/N, UID hash, trust signature info
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
834 for (node = parm->keyblock; !err && node; node=node->next)
836 switch (node->pkt->pkttype)
839 case PKT_PUBLIC_SUBKEY:
841 PKT_public_key *pk = node->pkt->pkt.public_key;
847 if (pk->flags.revoked)
848 validity[i ++] = 'r';
850 validity[i ++] = 'e';
853 keyid_from_pk (pk, NULL);
855 record_output (fp, node->pkt->pkttype, validity,
856 nbits_from_pk (pk), pk->pubkey_algo,
857 pk->keyid, pk->timestamp, pk->expiredate,
864 PKT_user_id *uid = node->pkt->pkt.user_id;
866 if (!uid->attrib_data)
873 validity[i ++] = 'r';
875 validity[i ++] = 'e';
878 record_output (fp, node->pkt->pkttype, validity,
880 uid->created, uid->expiredate,
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
892 PKT_signature *sig = node->pkt->pkt.signature;
894 if (IS_UID_SIG (sig))
895 record_output (fp, node->pkt->pkttype, NULL,
897 sig->timestamp, sig->expiredate, NULL);
904 /* Given that the last operation was an es_fprintf we should
905 get the correct ERRNO if ferror indicates an error. */
907 err = gpg_error_from_syserror ();
910 /* Without an error and if we have an keyblock at all, send the
912 if (!err && parm->keyblock)
919 while (!(rc=es_read (fp, buffer, sizeof buffer, &nread)) && nread)
921 err = assuan_send_data (parm->ctx, buffer, nread);
926 err = gpg_error_from_syserror ();
931 return gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
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. */
942 gpg_dirmngr_ks_put (ctrl_t ctrl, void *data, size_t datalen, kbnode_t keyblock)
945 assuan_context_t ctx;
946 struct ks_put_parm_s parm;
948 memset (&parm, 0, sizeof parm);
950 /* We are going to parse the keyblock, thus we better make sure the
951 all information is readily available. */
953 merge_keys_and_selfsig (keyblock);
955 err = open_context (ctrl, &ctx);
960 parm.keyblock = keyblock;
962 parm.datalen = datalen;
964 err = assuan_transact (ctx, "KS_PUT", NULL, NULL,
965 ks_put_inq_cb, &parm, NULL, NULL);
967 close_context (ctrl, ctx);
973 /* Data callback for the DNS_CERT command. */
975 dns_cert_data_cb (void *opaque, const void *data, size_t datalen)
977 struct dns_cert_parm_s *parm = opaque;
982 return 0; /* Ignore END commands. */
984 return 0; /* Data is not required. */
986 if (es_write (parm->memfp, data, datalen, &nwritten))
987 err = gpg_error_from_syserror ();
993 /* Status callback for the DNS_CERT command. */
995 dns_cert_status_cb (void *opaque, const char *line)
997 struct dns_cert_parm_s *parm = opaque;
1002 if ((s = has_leading_keyword (line, "FPR")))
1006 if (!(buf = xtrystrdup (s)))
1007 err = gpg_error_from_syserror ();
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);
1016 parm->fpr = xtrymalloc (nbytes);
1018 err = gpg_error_from_syserror ();
1020 memcpy (parm->fpr, buf, (parm->fprlen = nbytes));
1024 else if ((s = has_leading_keyword (line, "URL")) && *s)
1027 err = gpg_error (GPG_ERR_DUP_KEY);
1028 else if (!(parm->fpr = xtrymalloc (nbytes)))
1029 err = gpg_error_from_syserror ();
1031 memcpy (parm->fpr, line, (parm->fprlen = nbytes));
1037 /* Ask the dirmngr for a DNS CERT record. Depending on the found
1038 subtypes different return values are set:
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.
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.
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. */
1053 gpg_dirmngr_dns_cert (ctrl_t ctrl, const char *name, const char *certtype,
1055 unsigned char **r_fpr, size_t *r_fprlen,
1059 assuan_context_t ctx;
1060 struct dns_cert_parm_s parm;
1063 memset (&parm, 0, sizeof parm);
1073 err = open_context (ctrl, &ctx);
1077 line = es_bsprintf ("DNS_CERT %s %s", certtype, name);
1080 err = gpg_error_from_syserror ();
1083 if (strlen (line) + 2 >= ASSUAN_LINELENGTH)
1085 err = gpg_error (GPG_ERR_TOO_LARGE);
1089 parm.memfp = es_fopenmem (0, "rwb");
1092 err = gpg_error_from_syserror ();
1095 err = assuan_transact (ctx, line, dns_cert_data_cb, &parm,
1096 NULL, NULL, dns_cert_status_cb, &parm);
1102 es_rewind (parm.memfp);
1103 *r_key = parm.memfp;
1107 if (r_fpr && parm.fpr)
1113 *r_fprlen = parm.fprlen;
1115 if (r_url && parm.url)
1124 es_fclose (parm.memfp);
1126 close_context (ctrl, ctx);
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. */
1136 gpg_dirmngr_get_pka (ctrl_t ctrl, const char *userid,
1137 unsigned char **r_fpr, size_t *r_fprlen,
1141 assuan_context_t ctx;
1142 struct dns_cert_parm_s parm;
1145 memset (&parm, 0, sizeof parm);
1153 err = open_context (ctrl, &ctx);
1157 line = es_bsprintf ("DNS_CERT --pka -- %s", userid);
1160 err = gpg_error_from_syserror ();
1163 if (strlen (line) + 2 >= ASSUAN_LINELENGTH)
1165 err = gpg_error (GPG_ERR_TOO_LARGE);
1169 err = assuan_transact (ctx, line, dns_cert_data_cb, &parm,
1170 NULL, NULL, dns_cert_status_cb, &parm);
1174 if (r_fpr && parm.fpr)
1180 *r_fprlen = parm.fprlen;
1182 if (r_url && parm.url)
1192 close_context (ctrl, ctx);