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 <http://www.gnu.org/licenses/>.
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 {
86 static gpg_error_t get_cached_cert (assuan_context_t ctx,
87 const unsigned char *fpr,
92 /* A simple implementation of a dynamic buffer. Use init_membuf() to
93 create a buffer, put_membuf to append bytes and get_membuf to
94 release and return the buffer. Allocation errors are detected but
95 only returned at the final get_membuf(), this helps not to clutter
96 the code with out of core checks. */
99 init_membuf (struct membuf *mb, int initiallen)
102 mb->size = initiallen;
104 mb->buf = xtrymalloc (initiallen);
110 put_membuf (struct membuf *mb, const void *buf, size_t len)
115 if (mb->len + len >= mb->size)
119 mb->size += len + 1024;
120 p = xtryrealloc (mb->buf, mb->size);
128 memcpy (mb->buf + mb->len, buf, len);
133 get_membuf (struct membuf *mb, size_t *len)
147 mb->out_of_core = 1; /* don't allow a reuse */
152 /* This function prepares the dirmngr for a new session. The
153 audit-events option is used so that other dirmngr clients won't get
154 disturbed by such events. */
156 prepare_dirmngr (ctrl_t ctrl, assuan_context_t ctx, gpg_error_t err)
158 struct keyserver_spec *server;
162 err = assuan_transact (ctx, "OPTION audit-events=1",
163 NULL, NULL, NULL, NULL, NULL, NULL);
164 if (gpg_err_code (err) == GPG_ERR_UNKNOWN_OPTION)
165 err = 0; /* Allow the use of old dirmngr versions. */
167 audit_log_ok (ctrl->audit, AUDIT_DIRMNGR_READY, err);
172 server = opt.keyserver;
175 char line[ASSUAN_LINELENGTH];
176 char *user = server->user ? server->user : "";
177 char *pass = server->pass ? server->pass : "";
178 char *base = server->base ? server->base : "";
180 snprintf (line, DIM (line) - 1, "LDAPSERVER %s:%i:%s:%s:%s",
181 server->host, server->port, user, pass, base);
182 line[DIM (line) - 1] = 0;
184 err = assuan_transact (ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
185 if (gpg_err_code (err) == GPG_ERR_ASS_UNKNOWN_CMD)
186 err = 0; /* Allow the use of old dirmngr versions. */
188 server = server->next;
194 /* Return a new assuan context for a Dirmngr connection. */
196 start_dirmngr_ext (ctrl_t ctrl, assuan_context_t *ctx_r)
199 assuan_context_t ctx;
201 if (opt.disable_dirmngr)
202 return gpg_error (GPG_ERR_NO_DIRMNGR);
207 /* Note: if you change this to multiple connections, you also need
208 to take care of the implicit option sending caching. */
210 err = start_new_dirmngr (&ctx, GPG_ERR_SOURCE_DEFAULT,
211 opt.homedir, opt.dirmngr_program,
212 opt.autostart, opt.verbose, DBG_IPC,
213 gpgsm_status2, ctrl);
214 if (!opt.autostart && gpg_err_code (err) == GPG_ERR_NO_DIRMNGR)
221 log_info (_("no dirmngr running in this session\n"));
224 prepare_dirmngr (ctrl, ctx, err);
234 start_dirmngr (ctrl_t ctrl)
238 assert (! dirmngr_ctx_locked);
239 dirmngr_ctx_locked = 1;
241 err = start_dirmngr_ext (ctrl, &dirmngr_ctx);
242 /* We do not check ERR but the existance of a context because the
243 error might come from a failed command send to the dirmngr.
244 Fixme: Why don't we close the drimngr context if we encountered
245 an error in prepare_dirmngr? */
247 dirmngr_ctx_locked = 0;
253 release_dirmngr (ctrl_t ctrl)
257 if (!dirmngr_ctx_locked)
258 log_error ("WARNING: trying to release a non-locked dirmngr ctx\n");
259 dirmngr_ctx_locked = 0;
264 start_dirmngr2 (ctrl_t ctrl)
268 assert (! dirmngr2_ctx_locked);
269 dirmngr2_ctx_locked = 1;
271 err = start_dirmngr_ext (ctrl, &dirmngr2_ctx);
273 dirmngr2_ctx_locked = 0;
279 release_dirmngr2 (ctrl_t ctrl)
283 if (!dirmngr2_ctx_locked)
284 log_error ("WARNING: trying to release a non-locked dirmngr2 ctx\n");
285 dirmngr2_ctx_locked = 0;
290 /* Handle a SENDCERT inquiry. */
292 inq_certificate (void *opaque, const char *line)
294 struct inq_certificate_parm_s *parm = opaque;
298 const unsigned char *der;
301 ksba_sexp_t ski = NULL;
303 if ((s = has_leading_keyword (line, "SENDCERT")))
307 else if ((s = has_leading_keyword (line, "SENDCERT_SKI")))
309 /* Send a certificate where a sourceKeyIdentifier is included. */
311 ski = make_simple_sexp_from_hexstr (line, &n);
316 else if ((s = has_leading_keyword (line, "SENDISSUERCERT")))
321 else if ((s = has_leading_keyword (line, "ISTRUSTED")))
323 /* The server is asking us whether the certificate is a trusted
326 struct rootca_flags_s rootca_flags;
330 for (s=line,n=0; hexdigitp (s); s++, n++)
333 return gpg_error (GPG_ERR_ASS_PARAMETER);
334 for (s=line, n=0; n < 40; s++, n++)
335 fpr[n] = (*s >= 'a')? (*s & 0xdf): *s;
338 if (!gpgsm_agent_istrusted (parm->ctrl, NULL, fpr, &rootca_flags))
339 rc = assuan_send_data (parm->ctx, "1", 1);
346 log_error ("unsupported inquiry '%s'\n", line);
347 return gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
351 { /* Send the current certificate. */
352 der = ksba_cert_get_image (issuer_mode? parm->issuer_cert : parm->cert,
355 rc = gpg_error (GPG_ERR_INV_CERT_OBJ);
357 rc = assuan_send_data (parm->ctx, der, derlen);
359 else if (issuer_mode)
361 log_error ("sending specific issuer certificate back "
362 "is not yet implemented\n");
363 rc = gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
366 { /* Send the given certificate. */
371 err = gpgsm_find_cert (line, ski, &cert);
374 log_error ("certificate not found: %s\n", gpg_strerror (err));
375 rc = gpg_error (GPG_ERR_NOT_FOUND);
379 der = ksba_cert_get_image (cert, &derlen);
381 rc = gpg_error (GPG_ERR_INV_CERT_OBJ);
383 rc = assuan_send_data (parm->ctx, der, derlen);
384 ksba_cert_release (cert);
393 /* Take a 20 byte hexencoded string and put it into the the provided
394 20 byte buffer FPR in binary format. */
396 unhexify_fpr (const char *hexstr, unsigned char *fpr)
401 for (s=hexstr, n=0; hexdigitp (s); s++, n++)
404 return 0; /* no fingerprint (invalid or wrong length). */
406 for (s=hexstr, n=0; *s; s += 2, n++)
413 isvalid_status_cb (void *opaque, const char *line)
415 struct isvalid_status_parm_s *parm = opaque;
418 if ((s = has_leading_keyword (line, "PROGRESS")))
423 if (gpgsm_status (parm->ctrl, STATUS_PROGRESS, line))
424 return gpg_error (GPG_ERR_ASS_CANCELED);
427 else if ((s = has_leading_keyword (line, "ONLY_VALID_IF_CERT_VALID")))
430 if (!*s || !unhexify_fpr (s, parm->fpr))
431 parm->seen++; /* Bumb it to indicate an error. */
439 /* Call the directory manager to check whether the certificate is valid
440 Returns 0 for valid or usually one of the errors:
442 GPG_ERR_CERTIFICATE_REVOKED
448 1 = Do an OCSP check.
449 2 = Do an OCSP check using only the default responder.
452 gpgsm_dirmngr_isvalid (ctrl_t ctrl,
453 ksba_cert_t cert, ksba_cert_t issuer_cert, int use_ocsp)
455 static int did_options;
458 char line[ASSUAN_LINELENGTH];
459 struct inq_certificate_parm_s parm;
460 struct isvalid_status_parm_s stparm;
462 rc = start_dirmngr (ctrl);
468 certid = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
472 certid = gpgsm_get_certid (cert);
475 log_error ("error getting the certificate ID\n");
476 release_dirmngr (ctrl);
477 return gpg_error (GPG_ERR_GENERAL);
483 char *fpr = gpgsm_get_fingerprint_string (cert, GCRY_MD_SHA1);
484 log_info ("asking dirmngr about %s%s\n", fpr,
485 use_ocsp? " (using OCSP)":"");
489 parm.ctx = dirmngr_ctx;
492 parm.issuer_cert = issuer_cert;
496 memset (stparm.fpr, 0, 20);
498 /* FIXME: If --disable-crl-checks has been set, we should pass an
499 option to dirmngr, so that no fallback CRL check is done after an
500 ocsp check. It is not a problem right now as dirmngr does not
501 fallback to CRL checking. */
503 /* It is sufficient to send the options only once because we have
504 one connection per process only. */
507 if (opt.force_crl_refresh)
508 assuan_transact (dirmngr_ctx, "OPTION force-crl-refresh=1",
509 NULL, NULL, NULL, NULL, NULL, NULL);
512 snprintf (line, DIM(line)-1, "ISVALID%s %s",
513 use_ocsp == 2? " --only-ocsp --force-default-responder":"",
515 line[DIM(line)-1] = 0;
518 rc = assuan_transact (dirmngr_ctx, line, NULL, NULL,
519 inq_certificate, &parm,
520 isvalid_status_cb, &stparm);
522 log_info ("response of dirmngr: %s\n", rc? gpg_strerror (rc): "okay");
525 if (!rc && stparm.seen)
527 /* Need to also check the certificate validity. */
528 if (stparm.seen != 1)
530 log_error ("communication problem with dirmngr detected\n");
531 rc = gpg_error (GPG_ERR_INV_CRL);
535 ksba_cert_t rspcert = NULL;
537 if (get_cached_cert (dirmngr_ctx, stparm.fpr, &rspcert))
539 /* Ooops: Something went wrong getting the certificate
540 from the dirmngr. Try our own cert store now. */
545 rc = gpg_error (GPG_ERR_ENOMEM);
547 rc = keydb_search_fpr (kh, stparm.fpr);
549 rc = keydb_get_cert (kh, &rspcert);
552 log_error ("unable to find the certificate used "
553 "by the dirmngr: %s\n", gpg_strerror (rc));
554 rc = gpg_error (GPG_ERR_INV_CRL);
561 rc = gpgsm_cert_use_ocsp_p (rspcert);
563 rc = gpg_error (GPG_ERR_INV_CRL);
566 /* Note the no_dirmngr flag: This avoids checking
567 this certificate over and over again. */
568 rc = gpgsm_validate_chain (ctrl, rspcert, "", NULL, 0, NULL,
569 VALIDATE_FLAG_NO_DIRMNGR, NULL);
572 log_error ("invalid certificate used for CRL/OCSP: %s\n",
574 rc = gpg_error (GPG_ERR_INV_CRL);
578 ksba_cert_release (rspcert);
581 release_dirmngr (ctrl);
589 lookup_cb (void *opaque, const void *buffer, size_t length)
591 struct lookup_parm_s *parm = opaque;
602 put_membuf (&parm->data, buffer, length);
605 /* END encountered - process what we have */
606 buf = get_membuf (&parm->data, &len);
609 parm->error = gpg_error (GPG_ERR_ENOMEM);
613 rc = ksba_cert_new (&cert);
619 rc = ksba_cert_init_from_mem (cert, buf, len);
622 log_error ("failed to parse a certificate: %s\n", gpg_strerror (rc));
626 parm->cb (parm->cb_value, cert);
629 ksba_cert_release (cert);
630 init_membuf (&parm->data, 4096);
634 /* Return a properly escaped pattern from NAMES. The only error
635 return is NULL to indicate a malloc failure. */
637 pattern_from_strlist (strlist_t names)
644 for (n=0, sl=names; sl; sl = sl->next)
646 for (s=sl->d; *s; s++, n++)
648 if (*s == '%' || *s == ' ' || *s == '+')
654 p = pattern = xtrymalloc (n+1);
658 for (sl=names; sl; sl = sl->next)
660 for (s=sl->d; *s; s++)
687 *pattern = 0; /* is empty */
689 p[-1] = '\0'; /* remove trailing blank */
695 lookup_status_cb (void *opaque, const char *line)
697 struct lookup_parm_s *parm = opaque;
700 if ((s = has_leading_keyword (line, "PROGRESS")))
705 if (gpgsm_status (parm->ctrl, STATUS_PROGRESS, line))
706 return gpg_error (GPG_ERR_ASS_CANCELED);
709 else if ((s = has_leading_keyword (line, "TRUNCATED")))
714 gpgsm_status (parm->ctrl, STATUS_TRUNCATED, line);
721 /* Run the Directory Manager's lookup command using the pattern
722 compiled from the strings given in NAMES. The caller must provide
723 the callback CB which will be passed cert by cert. Note that CTRL
724 is optional. With CACHE_ONLY the dirmngr will search only its own
727 gpgsm_dirmngr_lookup (ctrl_t ctrl, strlist_t names, int cache_only,
728 void (*cb)(void*, ksba_cert_t), void *cb_value)
732 char line[ASSUAN_LINELENGTH];
733 struct lookup_parm_s parm;
735 assuan_context_t ctx;
737 /* The lookup function can be invoked from the callback of a lookup
738 function, for example to walk the chain. */
739 if (!dirmngr_ctx_locked)
741 rc = start_dirmngr (ctrl);
746 else if (!dirmngr2_ctx_locked)
748 rc = start_dirmngr2 (ctrl);
755 log_fatal ("both dirmngr contexts are in use\n");
758 pattern = pattern_from_strlist (names);
761 if (ctx == dirmngr_ctx)
762 release_dirmngr (ctrl);
764 release_dirmngr2 (ctrl);
766 return out_of_core ();
768 snprintf (line, DIM(line)-1, "LOOKUP%s %s",
769 cache_only? " --cache-only":"", pattern);
770 line[DIM(line)-1] = 0;
776 parm.cb_value = cb_value;
778 init_membuf (&parm.data, 4096);
780 rc = assuan_transact (ctx, line, lookup_cb, &parm,
781 NULL, NULL, lookup_status_cb, &parm);
782 xfree (get_membuf (&parm.data, &len));
784 if (ctx == dirmngr_ctx)
785 release_dirmngr (ctrl);
787 release_dirmngr2 (ctrl);
797 get_cached_cert_data_cb (void *opaque, const void *buffer, size_t length)
799 struct membuf *mb = opaque;
802 put_membuf (mb, buffer, length);
806 /* Return a certificate from the Directory Manager's cache. This
807 function only returns one certificate which must be specified using
808 the fingerprint FPR and will be stored at R_CERT. On error NULL is
809 stored at R_CERT and an error code returned. Note that the caller
810 must provide the locked dirmngr context CTX. */
812 get_cached_cert (assuan_context_t ctx,
813 const unsigned char *fpr, ksba_cert_t *r_cert)
816 char line[ASSUAN_LINELENGTH];
825 bin2hex (fpr, 20, hexfpr);
826 snprintf (line, DIM(line)-1, "LOOKUP --single --cache-only 0x%s", hexfpr);
828 init_membuf (&mb, 4096);
829 err = assuan_transact (ctx, line, get_cached_cert_data_cb, &mb,
830 NULL, NULL, NULL, NULL);
831 buf = get_membuf (&mb, &buflen);
838 return gpg_error (GPG_ERR_ENOMEM);
840 err = ksba_cert_new (&cert);
846 err = ksba_cert_init_from_mem (cert, buf, buflen);
850 log_error ("failed to parse a certificate: %s\n", gpg_strerror (err));
851 ksba_cert_release (cert);
861 /* Run Command helpers*/
863 /* Fairly simple callback to write all output of dirmngr to stdout. */
865 run_command_cb (void *opaque, const void *buffer, size_t length)
871 if ( fwrite (buffer, length, 1, stdout) != 1 )
872 log_error ("error writing to stdout: %s\n", strerror (errno));
877 /* Handle inquiries from the dirmngr COMMAND. */
879 run_command_inq_cb (void *opaque, const char *line)
881 struct run_command_parm_s *parm = opaque;
885 if ((s = has_leading_keyword (line, "SENDCERT")))
886 { /* send the given certificate */
889 const unsigned char *der;
894 return gpg_error (GPG_ERR_ASS_PARAMETER);
896 err = gpgsm_find_cert (line, NULL, &cert);
899 log_error ("certificate not found: %s\n", gpg_strerror (err));
900 rc = gpg_error (GPG_ERR_NOT_FOUND);
904 der = ksba_cert_get_image (cert, &derlen);
906 rc = gpg_error (GPG_ERR_INV_CERT_OBJ);
908 rc = assuan_send_data (parm->ctx, der, derlen);
909 ksba_cert_release (cert);
912 else if ((s = has_leading_keyword (line, "PRINTINFO")))
913 { /* Simply show the message given in the argument. */
915 log_info ("dirmngr: %s\n", line);
919 log_error ("unsupported inquiry '%s'\n", line);
920 rc = gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
927 run_command_status_cb (void *opaque, const char *line)
929 ctrl_t ctrl = opaque;
934 log_info ("dirmngr status: %s\n", line);
936 if ((s = has_leading_keyword (line, "PROGRESS")))
941 if (gpgsm_status (ctrl, STATUS_PROGRESS, line))
942 return gpg_error (GPG_ERR_ASS_CANCELED);
950 /* Pass COMMAND to dirmngr and print all output generated by Dirmngr
951 to stdout. A couple of inquiries are defined (see above). ARGC
952 arguments in ARGV are given to the Dirmngr. Spaces, plus and
953 percent characters within the argument strings are percent escaped
954 so that blanks can act as delimiters. */
956 gpgsm_dirmngr_run_command (ctrl_t ctrl, const char *command,
957 int argc, char **argv)
964 struct run_command_parm_s parm;
966 rc = start_dirmngr (ctrl);
970 parm.ctx = dirmngr_ctx;
972 len = strlen (command) + 1;
973 for (i=0; i < argc; i++)
974 len += 1 + 3*strlen (argv[i]); /* enough space for percent escaping */
975 line = xtrymalloc (len);
978 release_dirmngr (ctrl);
979 return out_of_core ();
982 p = stpcpy (line, command);
983 for (i=0; i < argc; i++)
986 for (s=argv[i]; *s; s++)
992 else if (!isprint (*s) || *s == '+')
994 sprintf (p, "%%%02X", *(const unsigned char *)s);
1003 rc = assuan_transact (dirmngr_ctx, line,
1004 run_command_cb, NULL,
1005 run_command_inq_cb, &parm,
1006 run_command_status_cb, ctrl);
1008 log_info ("response of dirmngr: %s\n", rc? gpg_strerror (rc): "okay");
1009 release_dirmngr (ctrl);