1 /* call-dirmngr.c - Communication with the dirmngr
2 * Copyright (C) 2002, 2003, 2005, 2007, 2008,
3 * 2010 Free Software Foundation, Inc.
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 <https://www.gnu.org/licenses/>.
35 #include "../common/i18n.h"
37 #include "../common/asshelp.h"
49 /* fixme: We need a context for each thread or serialize the access to
51 static assuan_context_t dirmngr_ctx = NULL;
52 static assuan_context_t dirmngr2_ctx = NULL;
54 static int dirmngr_ctx_locked;
55 static int dirmngr2_ctx_locked;
57 struct inq_certificate_parm_s {
61 ksba_cert_t issuer_cert;
64 struct isvalid_status_parm_s {
67 unsigned char fpr[20];
71 struct lookup_parm_s {
74 void (*cb)(void *, ksba_cert_t);
80 struct run_command_parm_s {
87 static gpg_error_t get_cached_cert (assuan_context_t ctx,
88 const unsigned char *fpr,
93 /* A simple implementation of a dynamic buffer. Use init_membuf() to
94 create a buffer, put_membuf to append bytes and get_membuf to
95 release and return the buffer. Allocation errors are detected but
96 only returned at the final get_membuf(), this helps not to clutter
97 the code with out of core checks. */
100 init_membuf (struct membuf *mb, int initiallen)
103 mb->size = initiallen;
105 mb->buf = xtrymalloc (initiallen);
111 put_membuf (struct membuf *mb, const void *buf, size_t len)
116 if (mb->len + len >= mb->size)
120 mb->size += len + 1024;
121 p = xtryrealloc (mb->buf, mb->size);
129 memcpy (mb->buf + mb->len, buf, len);
134 get_membuf (struct membuf *mb, size_t *len)
148 mb->out_of_core = 1; /* don't allow a reuse */
153 /* Print a warning if the server's version number is less than our
154 version number. Returns an error code on a connection problem. */
156 warn_version_mismatch (ctrl_t ctrl, assuan_context_t ctx,
157 const char *servername, int mode)
161 const char *myversion = strusage (13);
163 err = get_assuan_server_version (ctx, mode, &serverversion);
165 log_error (_("error getting version from '%s': %s\n"),
166 servername, gpg_strerror (err));
167 else if (compare_version_strings (serverversion, myversion) < 0)
171 warn = xtryasprintf (_("server '%s' is older than us (%s < %s)"),
172 servername, serverversion, myversion);
174 err = gpg_error_from_syserror ();
177 log_info (_("WARNING: %s\n"), warn);
180 log_info (_("Note: Outdated servers may lack important"
181 " security fixes.\n"));
182 log_info (_("Note: Use the command \"%s\" to restart them.\n"),
183 "gpgconf --kill all");
185 gpgsm_status2 (ctrl, STATUS_WARNING, "server_version_mismatch 0",
190 xfree (serverversion);
195 /* This function prepares the dirmngr for a new session. The
196 audit-events option is used so that other dirmngr clients won't get
197 disturbed by such events. */
199 prepare_dirmngr (ctrl_t ctrl, assuan_context_t ctx, gpg_error_t err)
201 struct keyserver_spec *server;
204 err = warn_version_mismatch (ctrl, ctx, DIRMNGR_NAME, 0);
208 err = assuan_transact (ctx, "OPTION audit-events=1",
209 NULL, NULL, NULL, NULL, NULL, NULL);
210 if (gpg_err_code (err) == GPG_ERR_UNKNOWN_OPTION)
211 err = 0; /* Allow the use of old dirmngr versions. */
213 audit_log_ok (ctrl->audit, AUDIT_DIRMNGR_READY, err);
218 server = opt.keyserver;
221 char line[ASSUAN_LINELENGTH];
222 char *user = server->user ? server->user : "";
223 char *pass = server->pass ? server->pass : "";
224 char *base = server->base ? server->base : "";
226 snprintf (line, DIM (line), "LDAPSERVER %s:%i:%s:%s:%s",
227 server->host, server->port, user, pass, base);
229 assuan_transact (ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
230 /* The code below is not required because we don't return an error. */
231 /* err = [above call] */
232 /* if (gpg_err_code (err) == GPG_ERR_ASS_UNKNOWN_CMD) */
233 /* err = 0; /\* Allow the use of old dirmngr versions. *\/ */
235 server = server->next;
241 /* Return a new assuan context for a Dirmngr connection. */
243 start_dirmngr_ext (ctrl_t ctrl, assuan_context_t *ctx_r)
246 assuan_context_t ctx;
248 if (opt.disable_dirmngr || ctrl->offline)
249 return gpg_error (GPG_ERR_NO_DIRMNGR);
254 /* Note: if you change this to multiple connections, you also need
255 to take care of the implicit option sending caching. */
257 err = start_new_dirmngr (&ctx, GPG_ERR_SOURCE_DEFAULT,
259 opt.autostart, opt.verbose, DBG_IPC,
260 gpgsm_status2, ctrl);
261 if (!opt.autostart && gpg_err_code (err) == GPG_ERR_NO_DIRMNGR)
268 log_info (_("no dirmngr running in this session\n"));
271 prepare_dirmngr (ctrl, ctx, err);
281 start_dirmngr (ctrl_t ctrl)
285 assert (! dirmngr_ctx_locked);
286 dirmngr_ctx_locked = 1;
288 err = start_dirmngr_ext (ctrl, &dirmngr_ctx);
289 /* We do not check ERR but the existence of a context because the
290 error might come from a failed command send to the dirmngr.
291 Fixme: Why don't we close the drimngr context if we encountered
292 an error in prepare_dirmngr? */
294 dirmngr_ctx_locked = 0;
300 release_dirmngr (ctrl_t ctrl)
304 if (!dirmngr_ctx_locked)
305 log_error ("WARNING: trying to release a non-locked dirmngr ctx\n");
306 dirmngr_ctx_locked = 0;
311 start_dirmngr2 (ctrl_t ctrl)
315 assert (! dirmngr2_ctx_locked);
316 dirmngr2_ctx_locked = 1;
318 err = start_dirmngr_ext (ctrl, &dirmngr2_ctx);
320 dirmngr2_ctx_locked = 0;
326 release_dirmngr2 (ctrl_t ctrl)
330 if (!dirmngr2_ctx_locked)
331 log_error ("WARNING: trying to release a non-locked dirmngr2 ctx\n");
332 dirmngr2_ctx_locked = 0;
337 /* Handle a SENDCERT inquiry. */
339 inq_certificate (void *opaque, const char *line)
341 struct inq_certificate_parm_s *parm = opaque;
345 const unsigned char *der;
348 ksba_sexp_t ski = NULL;
350 if ((s = has_leading_keyword (line, "SENDCERT")))
354 else if ((s = has_leading_keyword (line, "SENDCERT_SKI")))
356 /* Send a certificate where a sourceKeyIdentifier is included. */
358 ski = make_simple_sexp_from_hexstr (line, &n);
363 else if ((s = has_leading_keyword (line, "SENDISSUERCERT")))
368 else if ((s = has_leading_keyword (line, "ISTRUSTED")))
370 /* The server is asking us whether the certificate is a trusted
373 struct rootca_flags_s rootca_flags;
377 for (s=line,n=0; hexdigitp (s); s++, n++)
380 return gpg_error (GPG_ERR_ASS_PARAMETER);
381 for (s=line, n=0; n < 40; s++, n++)
382 fpr[n] = (*s >= 'a')? (*s & 0xdf): *s;
385 if (!gpgsm_agent_istrusted (parm->ctrl, NULL, fpr, &rootca_flags))
386 rc = assuan_send_data (parm->ctx, "1", 1);
393 log_error ("unsupported inquiry '%s'\n", line);
394 return gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
398 { /* Send the current certificate. */
399 der = ksba_cert_get_image (issuer_mode? parm->issuer_cert : parm->cert,
402 rc = gpg_error (GPG_ERR_INV_CERT_OBJ);
404 rc = assuan_send_data (parm->ctx, der, derlen);
406 else if (issuer_mode)
408 log_error ("sending specific issuer certificate back "
409 "is not yet implemented\n");
410 rc = gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
413 { /* Send the given certificate. */
418 err = gpgsm_find_cert (parm->ctrl, line, ski, &cert, 1);
421 log_error ("certificate not found: %s\n", gpg_strerror (err));
422 rc = gpg_error (GPG_ERR_NOT_FOUND);
426 der = ksba_cert_get_image (cert, &derlen);
428 rc = gpg_error (GPG_ERR_INV_CERT_OBJ);
430 rc = assuan_send_data (parm->ctx, der, derlen);
431 ksba_cert_release (cert);
440 /* Take a 20 byte hexencoded string and put it into the provided
441 20 byte buffer FPR in binary format. */
443 unhexify_fpr (const char *hexstr, unsigned char *fpr)
448 for (s=hexstr, n=0; hexdigitp (s); s++, n++)
451 return 0; /* no fingerprint (invalid or wrong length). */
452 for (s=hexstr, n=0; *s; s += 2, n++)
459 isvalid_status_cb (void *opaque, const char *line)
461 struct isvalid_status_parm_s *parm = opaque;
464 if ((s = has_leading_keyword (line, "PROGRESS")))
469 if (gpgsm_status (parm->ctrl, STATUS_PROGRESS, line))
470 return gpg_error (GPG_ERR_ASS_CANCELED);
473 else if ((s = has_leading_keyword (line, "ONLY_VALID_IF_CERT_VALID")))
476 if (!*s || !unhexify_fpr (s, parm->fpr))
477 parm->seen++; /* Bumb it to indicate an error. */
485 /* Call the directory manager to check whether the certificate is valid
486 Returns 0 for valid or usually one of the errors:
488 GPG_ERR_CERTIFICATE_REVOKED
494 1 = Do an OCSP check but fallback to CRL unless CRLS are disabled.
495 2 = Do only an OCSP check using only the default responder.
498 gpgsm_dirmngr_isvalid (ctrl_t ctrl,
499 ksba_cert_t cert, ksba_cert_t issuer_cert, int use_ocsp)
501 static int did_options;
503 char *certid, *certfpr;
504 char line[ASSUAN_LINELENGTH];
505 struct inq_certificate_parm_s parm;
506 struct isvalid_status_parm_s stparm;
508 rc = start_dirmngr (ctrl);
512 certfpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
513 certid = gpgsm_get_certid (cert);
516 log_error ("error getting the certificate ID\n");
517 release_dirmngr (ctrl);
518 return gpg_error (GPG_ERR_GENERAL);
523 char *fpr = gpgsm_get_fingerprint_string (cert, GCRY_MD_SHA1);
524 log_info ("asking dirmngr about %s%s\n", fpr,
525 use_ocsp? " (using OCSP)":"");
529 parm.ctx = dirmngr_ctx;
532 parm.issuer_cert = issuer_cert;
536 memset (stparm.fpr, 0, 20);
538 /* It is sufficient to send the options only once because we have
539 * one connection per process only. */
542 if (opt.force_crl_refresh)
543 assuan_transact (dirmngr_ctx, "OPTION force-crl-refresh=1",
544 NULL, NULL, NULL, NULL, NULL, NULL);
547 snprintf (line, DIM(line), "ISVALID%s%s %s%s%s",
548 use_ocsp == 2 || opt.no_crl_check ? " --only-ocsp":"",
549 use_ocsp == 2? " --force-default-responder":"",
552 use_ocsp? certfpr:"");
556 rc = assuan_transact (dirmngr_ctx, line, NULL, NULL,
557 inq_certificate, &parm,
558 isvalid_status_cb, &stparm);
560 log_info ("response of dirmngr: %s\n", rc? gpg_strerror (rc): "okay");
562 if (!rc && stparm.seen)
564 /* Need to also check the certificate validity. */
565 if (stparm.seen != 1)
567 log_error ("communication problem with dirmngr detected\n");
568 rc = gpg_error (GPG_ERR_INV_CRL);
572 ksba_cert_t rspcert = NULL;
574 if (get_cached_cert (dirmngr_ctx, stparm.fpr, &rspcert))
576 /* Ooops: Something went wrong getting the certificate
577 from the dirmngr. Try our own cert store now. */
582 rc = gpg_error (GPG_ERR_ENOMEM);
584 rc = keydb_search_fpr (ctrl, kh, stparm.fpr);
586 rc = keydb_get_cert (kh, &rspcert);
589 log_error ("unable to find the certificate used "
590 "by the dirmngr: %s\n", gpg_strerror (rc));
591 rc = gpg_error (GPG_ERR_INV_CRL);
598 rc = gpgsm_cert_use_ocsp_p (rspcert);
600 rc = gpg_error (GPG_ERR_INV_CRL);
603 /* Note the no_dirmngr flag: This avoids checking
604 this certificate over and over again. */
605 rc = gpgsm_validate_chain (ctrl, rspcert, "", NULL, 0, NULL,
606 VALIDATE_FLAG_NO_DIRMNGR, NULL);
609 log_error ("invalid certificate used for CRL/OCSP: %s\n",
611 rc = gpg_error (GPG_ERR_INV_CRL);
615 ksba_cert_release (rspcert);
618 release_dirmngr (ctrl);
626 lookup_cb (void *opaque, const void *buffer, size_t length)
628 struct lookup_parm_s *parm = opaque;
639 put_membuf (&parm->data, buffer, length);
642 /* END encountered - process what we have */
643 buf = get_membuf (&parm->data, &len);
646 parm->error = gpg_error (GPG_ERR_ENOMEM);
650 rc = ksba_cert_new (&cert);
656 rc = ksba_cert_init_from_mem (cert, buf, len);
659 log_error ("failed to parse a certificate: %s\n", gpg_strerror (rc));
663 parm->cb (parm->cb_value, cert);
666 ksba_cert_release (cert);
667 init_membuf (&parm->data, 4096);
671 /* Return a properly escaped pattern from NAMES. The only error
672 return is NULL to indicate a malloc failure. */
674 pattern_from_strlist (strlist_t names)
681 for (n=0, sl=names; sl; sl = sl->next)
683 for (s=sl->d; *s; s++, n++)
685 if (*s == '%' || *s == ' ' || *s == '+')
691 p = pattern = xtrymalloc (n+1);
695 for (sl=names; sl; sl = sl->next)
697 for (s=sl->d; *s; s++)
724 *pattern = 0; /* is empty */
726 p[-1] = '\0'; /* remove trailing blank */
732 lookup_status_cb (void *opaque, const char *line)
734 struct lookup_parm_s *parm = opaque;
737 if ((s = has_leading_keyword (line, "PROGRESS")))
742 if (gpgsm_status (parm->ctrl, STATUS_PROGRESS, line))
743 return gpg_error (GPG_ERR_ASS_CANCELED);
746 else if ((s = has_leading_keyword (line, "TRUNCATED")))
751 gpgsm_status (parm->ctrl, STATUS_TRUNCATED, line);
758 /* Run the Directory Manager's lookup command using the pattern
759 compiled from the strings given in NAMES. The caller must provide
760 the callback CB which will be passed cert by cert. Note that CTRL
761 is optional. With CACHE_ONLY the dirmngr will search only its own
764 gpgsm_dirmngr_lookup (ctrl_t ctrl, strlist_t names, int cache_only,
765 void (*cb)(void*, ksba_cert_t), void *cb_value)
769 char line[ASSUAN_LINELENGTH];
770 struct lookup_parm_s parm;
772 assuan_context_t ctx;
774 /* The lookup function can be invoked from the callback of a lookup
775 function, for example to walk the chain. */
776 if (!dirmngr_ctx_locked)
778 rc = start_dirmngr (ctrl);
783 else if (!dirmngr2_ctx_locked)
785 rc = start_dirmngr2 (ctrl);
792 log_fatal ("both dirmngr contexts are in use\n");
795 pattern = pattern_from_strlist (names);
798 if (ctx == dirmngr_ctx)
799 release_dirmngr (ctrl);
801 release_dirmngr2 (ctrl);
803 return out_of_core ();
805 snprintf (line, DIM(line), "LOOKUP%s %s",
806 cache_only? " --cache-only":"", pattern);
812 parm.cb_value = cb_value;
814 init_membuf (&parm.data, 4096);
816 rc = assuan_transact (ctx, line, lookup_cb, &parm,
817 NULL, NULL, lookup_status_cb, &parm);
818 xfree (get_membuf (&parm.data, &len));
820 if (ctx == dirmngr_ctx)
821 release_dirmngr (ctrl);
823 release_dirmngr2 (ctrl);
833 get_cached_cert_data_cb (void *opaque, const void *buffer, size_t length)
835 struct membuf *mb = opaque;
838 put_membuf (mb, buffer, length);
842 /* Return a certificate from the Directory Manager's cache. This
843 function only returns one certificate which must be specified using
844 the fingerprint FPR and will be stored at R_CERT. On error NULL is
845 stored at R_CERT and an error code returned. Note that the caller
846 must provide the locked dirmngr context CTX. */
848 get_cached_cert (assuan_context_t ctx,
849 const unsigned char *fpr, ksba_cert_t *r_cert)
852 char line[ASSUAN_LINELENGTH];
861 bin2hex (fpr, 20, hexfpr);
862 snprintf (line, DIM(line), "LOOKUP --single --cache-only 0x%s", hexfpr);
864 init_membuf (&mb, 4096);
865 err = assuan_transact (ctx, line, get_cached_cert_data_cb, &mb,
866 NULL, NULL, NULL, NULL);
867 buf = get_membuf (&mb, &buflen);
874 return gpg_error (GPG_ERR_ENOMEM);
876 err = ksba_cert_new (&cert);
882 err = ksba_cert_init_from_mem (cert, buf, buflen);
886 log_error ("failed to parse a certificate: %s\n", gpg_strerror (err));
887 ksba_cert_release (cert);
897 /* Run Command helpers*/
899 /* Fairly simple callback to write all output of dirmngr to stdout. */
901 run_command_cb (void *opaque, const void *buffer, size_t length)
907 if ( fwrite (buffer, length, 1, stdout) != 1 )
908 log_error ("error writing to stdout: %s\n", strerror (errno));
913 /* Handle inquiries from the dirmngr COMMAND. */
915 run_command_inq_cb (void *opaque, const char *line)
917 struct run_command_parm_s *parm = opaque;
921 if ((s = has_leading_keyword (line, "SENDCERT")))
922 { /* send the given certificate */
925 const unsigned char *der;
930 return gpg_error (GPG_ERR_ASS_PARAMETER);
932 err = gpgsm_find_cert (parm->ctrl, line, NULL, &cert, 1);
935 log_error ("certificate not found: %s\n", gpg_strerror (err));
936 rc = gpg_error (GPG_ERR_NOT_FOUND);
940 der = ksba_cert_get_image (cert, &derlen);
942 rc = gpg_error (GPG_ERR_INV_CERT_OBJ);
944 rc = assuan_send_data (parm->ctx, der, derlen);
945 ksba_cert_release (cert);
948 else if ((s = has_leading_keyword (line, "PRINTINFO")))
949 { /* Simply show the message given in the argument. */
951 log_info ("dirmngr: %s\n", line);
955 log_error ("unsupported inquiry '%s'\n", line);
956 rc = gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
963 run_command_status_cb (void *opaque, const char *line)
965 ctrl_t ctrl = opaque;
970 log_info ("dirmngr status: %s\n", line);
972 if ((s = has_leading_keyword (line, "PROGRESS")))
977 if (gpgsm_status (ctrl, STATUS_PROGRESS, line))
978 return gpg_error (GPG_ERR_ASS_CANCELED);
986 /* Pass COMMAND to dirmngr and print all output generated by Dirmngr
987 to stdout. A couple of inquiries are defined (see above). ARGC
988 arguments in ARGV are given to the Dirmngr. Spaces, plus and
989 percent characters within the argument strings are percent escaped
990 so that blanks can act as delimiters. */
992 gpgsm_dirmngr_run_command (ctrl_t ctrl, const char *command,
993 int argc, char **argv)
1000 struct run_command_parm_s parm;
1002 rc = start_dirmngr (ctrl);
1007 parm.ctx = dirmngr_ctx;
1009 len = strlen (command) + 1;
1010 for (i=0; i < argc; i++)
1011 len += 1 + 3*strlen (argv[i]); /* enough space for percent escaping */
1012 line = xtrymalloc (len);
1015 release_dirmngr (ctrl);
1016 return out_of_core ();
1019 p = stpcpy (line, command);
1020 for (i=0; i < argc; i++)
1023 for (s=argv[i]; *s; s++)
1029 else if (!isprint (*s) || *s == '+')
1031 sprintf (p, "%%%02X", *(const unsigned char *)s);
1040 rc = assuan_transact (dirmngr_ctx, line,
1041 run_command_cb, NULL,
1042 run_command_inq_cb, &parm,
1043 run_command_status_cb, ctrl);
1045 log_info ("response of dirmngr: %s\n", rc? gpg_strerror (rc): "okay");
1046 release_dirmngr (ctrl);