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.verbose, DBG_ASSUAN,
213 gpgsm_status2, ctrl);
214 prepare_dirmngr (ctrl, ctx, err);
224 start_dirmngr (ctrl_t ctrl)
228 assert (! dirmngr_ctx_locked);
229 dirmngr_ctx_locked = 1;
231 err = start_dirmngr_ext (ctrl, &dirmngr_ctx);
232 /* We do not check ERR but the existance of a context because the
233 error might come from a failed command send to the dirmngr.
234 Fixme: Why don't we close the drimngr context if we encountered
235 an error in prepare_dirmngr? */
237 dirmngr_ctx_locked = 0;
243 release_dirmngr (ctrl_t ctrl)
247 if (!dirmngr_ctx_locked)
248 log_error ("WARNING: trying to release a non-locked dirmngr ctx\n");
249 dirmngr_ctx_locked = 0;
254 start_dirmngr2 (ctrl_t ctrl)
258 assert (! dirmngr2_ctx_locked);
259 dirmngr2_ctx_locked = 1;
261 err = start_dirmngr_ext (ctrl, &dirmngr2_ctx);
263 dirmngr2_ctx_locked = 0;
269 release_dirmngr2 (ctrl_t ctrl)
273 if (!dirmngr2_ctx_locked)
274 log_error ("WARNING: trying to release a non-locked dirmngr2 ctx\n");
275 dirmngr2_ctx_locked = 0;
280 /* Handle a SENDCERT inquiry. */
282 inq_certificate (void *opaque, const char *line)
284 struct inq_certificate_parm_s *parm = opaque;
286 const unsigned char *der;
289 ksba_sexp_t ski = NULL;
291 if (!strncmp (line, "SENDCERT", 8) && (line[8] == ' ' || !line[8]))
295 else if (!strncmp (line, "SENDCERT_SKI", 12) && (line[12]==' ' || !line[12]))
299 /* Send a certificate where a sourceKeyIdentifier is included. */
303 ski = make_simple_sexp_from_hexstr (line, &n);
308 else if (!strncmp (line, "SENDISSUERCERT", 14)
309 && (line[14] == ' ' || !line[14]))
314 else if (!strncmp (line, "ISTRUSTED", 9) && (line[9]==' ' || !line[9]))
316 /* The server is asking us whether the certificate is a trusted
321 struct rootca_flags_s rootca_flags;
327 for (s=line,n=0; hexdigitp (s); s++, n++)
330 return gpg_error (GPG_ERR_ASS_PARAMETER);
331 for (s=line, n=0; n < 40; s++, n++)
332 fpr[n] = (*s >= 'a')? (*s & 0xdf): *s;
335 if (!gpgsm_agent_istrusted (parm->ctrl, NULL, fpr, &rootca_flags))
336 rc = assuan_send_data (parm->ctx, "1", 1);
343 log_error ("unsupported inquiry `%s'\n", line);
344 return gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
348 { /* Send the current certificate. */
349 der = ksba_cert_get_image (issuer_mode? parm->issuer_cert : parm->cert,
352 rc = gpg_error (GPG_ERR_INV_CERT_OBJ);
354 rc = assuan_send_data (parm->ctx, der, derlen);
356 else if (issuer_mode)
358 log_error ("sending specific issuer certificate back "
359 "is not yet implemented\n");
360 rc = gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
363 { /* Send the given certificate. */
368 err = gpgsm_find_cert (line, ski, &cert);
371 log_error ("certificate not found: %s\n", gpg_strerror (err));
372 rc = gpg_error (GPG_ERR_NOT_FOUND);
376 der = ksba_cert_get_image (cert, &derlen);
378 rc = gpg_error (GPG_ERR_INV_CERT_OBJ);
380 rc = assuan_send_data (parm->ctx, der, derlen);
381 ksba_cert_release (cert);
390 /* Take a 20 byte hexencoded string and put it into the the provided
391 20 byte buffer FPR in binary format. */
393 unhexify_fpr (const char *hexstr, unsigned char *fpr)
398 for (s=hexstr, n=0; hexdigitp (s); s++, n++)
401 return 0; /* no fingerprint (invalid or wrong length). */
403 for (s=hexstr, n=0; *s; s += 2, n++)
410 isvalid_status_cb (void *opaque, const char *line)
412 struct isvalid_status_parm_s *parm = opaque;
414 if (!strncmp (line, "PROGRESS", 8) && (line[8]==' ' || !line[8]))
418 for (line += 8; *line == ' '; line++)
420 if (gpgsm_status (parm->ctrl, STATUS_PROGRESS, line))
421 return gpg_error (GPG_ERR_ASS_CANCELED);
424 else if (!strncmp (line, "ONLY_VALID_IF_CERT_VALID", 24)
425 && (line[24]==' ' || !line[24]))
428 if (!line[24] || !unhexify_fpr (line+25, parm->fpr))
429 parm->seen++; /* Bumb it to indicate an error. */
437 /* Call the directory manager to check whether the certificate is valid
438 Returns 0 for valid or usually one of the errors:
440 GPG_ERR_CERTIFICATE_REVOKED
446 1 = Do an OCSP check.
447 2 = Do an OCSP check using only the default responder.
450 gpgsm_dirmngr_isvalid (ctrl_t ctrl,
451 ksba_cert_t cert, ksba_cert_t issuer_cert, int use_ocsp)
453 static int did_options;
456 char line[ASSUAN_LINELENGTH];
457 struct inq_certificate_parm_s parm;
458 struct isvalid_status_parm_s stparm;
460 rc = start_dirmngr (ctrl);
466 certid = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
470 certid = gpgsm_get_certid (cert);
473 log_error ("error getting the certificate ID\n");
474 release_dirmngr (ctrl);
475 return gpg_error (GPG_ERR_GENERAL);
481 char *fpr = gpgsm_get_fingerprint_string (cert, GCRY_MD_SHA1);
482 log_info ("asking dirmngr about %s%s\n", fpr,
483 use_ocsp? " (using OCSP)":"");
487 parm.ctx = dirmngr_ctx;
490 parm.issuer_cert = issuer_cert;
494 memset (stparm.fpr, 0, 20);
496 /* FIXME: If --disable-crl-checks has been set, we should pass an
497 option to dirmngr, so that no fallback CRL check is done after an
498 ocsp check. It is not a problem right now as dirmngr does not
499 fallback to CRL checking. */
501 /* It is sufficient to send the options only once because we have
502 one connection per process only. */
505 if (opt.force_crl_refresh)
506 assuan_transact (dirmngr_ctx, "OPTION force-crl-refresh=1",
507 NULL, NULL, NULL, NULL, NULL, NULL);
510 snprintf (line, DIM(line)-1, "ISVALID%s %s",
511 use_ocsp == 2? " --only-ocsp --force-default-responder":"",
513 line[DIM(line)-1] = 0;
516 rc = assuan_transact (dirmngr_ctx, line, NULL, NULL,
517 inq_certificate, &parm,
518 isvalid_status_cb, &stparm);
520 log_info ("response of dirmngr: %s\n", rc? gpg_strerror (rc): "okay");
523 if (!rc && stparm.seen)
525 /* Need to also check the certificate validity. */
526 if (stparm.seen != 1)
528 log_error ("communication problem with dirmngr detected\n");
529 rc = gpg_error (GPG_ERR_INV_CRL);
533 ksba_cert_t rspcert = NULL;
535 if (get_cached_cert (dirmngr_ctx, stparm.fpr, &rspcert))
537 /* Ooops: Something went wrong getting the certificate
538 from the dirmngr. Try our own cert store now. */
543 rc = gpg_error (GPG_ERR_ENOMEM);
545 rc = keydb_search_fpr (kh, stparm.fpr);
547 rc = keydb_get_cert (kh, &rspcert);
550 log_error ("unable to find the certificate used "
551 "by the dirmngr: %s\n", gpg_strerror (rc));
552 rc = gpg_error (GPG_ERR_INV_CRL);
559 rc = gpgsm_cert_use_ocsp_p (rspcert);
561 rc = gpg_error (GPG_ERR_INV_CRL);
564 /* Note the no_dirmngr flag: This avoids checking
565 this certificate over and over again. */
566 rc = gpgsm_validate_chain (ctrl, rspcert, "", NULL, 0, NULL,
567 VALIDATE_FLAG_NO_DIRMNGR, NULL);
570 log_error ("invalid certificate used for CRL/OCSP: %s\n",
572 rc = gpg_error (GPG_ERR_INV_CRL);
576 ksba_cert_release (rspcert);
579 release_dirmngr (ctrl);
587 lookup_cb (void *opaque, const void *buffer, size_t length)
589 struct lookup_parm_s *parm = opaque;
600 put_membuf (&parm->data, buffer, length);
603 /* END encountered - process what we have */
604 buf = get_membuf (&parm->data, &len);
607 parm->error = gpg_error (GPG_ERR_ENOMEM);
611 rc = ksba_cert_new (&cert);
617 rc = ksba_cert_init_from_mem (cert, buf, len);
620 log_error ("failed to parse a certificate: %s\n", gpg_strerror (rc));
624 parm->cb (parm->cb_value, cert);
627 ksba_cert_release (cert);
628 init_membuf (&parm->data, 4096);
632 /* Return a properly escaped pattern from NAMES. The only error
633 return is NULL to indicate a malloc failure. */
635 pattern_from_strlist (strlist_t names)
642 for (n=0, sl=names; sl; sl = sl->next)
644 for (s=sl->d; *s; s++, n++)
646 if (*s == '%' || *s == ' ' || *s == '+')
652 p = pattern = xtrymalloc (n+1);
656 for (sl=names; sl; sl = sl->next)
658 for (s=sl->d; *s; s++)
685 *pattern = 0; /* is empty */
687 p[-1] = '\0'; /* remove trailing blank */
693 lookup_status_cb (void *opaque, const char *line)
695 struct lookup_parm_s *parm = opaque;
697 if (!strncmp (line, "PROGRESS", 8) && (line[8]==' ' || !line[8]))
701 for (line += 8; *line == ' '; line++)
703 if (gpgsm_status (parm->ctrl, STATUS_PROGRESS, line))
704 return gpg_error (GPG_ERR_ASS_CANCELED);
707 else if (!strncmp (line, "TRUNCATED", 9) && (line[9]==' ' || !line[9]))
711 for (line +=9; *line == ' '; line++)
713 gpgsm_status (parm->ctrl, STATUS_TRUNCATED, line);
720 /* Run the Directory Manager's lookup command using the pattern
721 compiled from the strings given in NAMES. The caller must provide
722 the callback CB which will be passed cert by cert. Note that CTRL
723 is optional. With CACHE_ONLY the dirmngr will search only its own
726 gpgsm_dirmngr_lookup (ctrl_t ctrl, strlist_t names, int cache_only,
727 void (*cb)(void*, ksba_cert_t), void *cb_value)
731 char line[ASSUAN_LINELENGTH];
732 struct lookup_parm_s parm;
734 assuan_context_t ctx;
736 /* The lookup function can be invoked from the callback of a lookup
737 function, for example to walk the chain. */
738 if (!dirmngr_ctx_locked)
740 rc = start_dirmngr (ctrl);
745 else if (!dirmngr2_ctx_locked)
747 rc = start_dirmngr2 (ctrl);
754 log_fatal ("both dirmngr contexts are in use\n");
757 pattern = pattern_from_strlist (names);
760 if (ctx == dirmngr_ctx)
761 release_dirmngr (ctrl);
763 release_dirmngr2 (ctrl);
765 return out_of_core ();
767 snprintf (line, DIM(line)-1, "LOOKUP%s %s",
768 cache_only? " --cache-only":"", pattern);
769 line[DIM(line)-1] = 0;
775 parm.cb_value = cb_value;
777 init_membuf (&parm.data, 4096);
779 rc = assuan_transact (ctx, line, lookup_cb, &parm,
780 NULL, NULL, lookup_status_cb, &parm);
781 xfree (get_membuf (&parm.data, &len));
783 if (ctx == dirmngr_ctx)
784 release_dirmngr (ctrl);
786 release_dirmngr2 (ctrl);
796 get_cached_cert_data_cb (void *opaque, const void *buffer, size_t length)
798 struct membuf *mb = opaque;
801 put_membuf (mb, buffer, length);
805 /* Return a certificate from the Directory Manager's cache. This
806 function only returns one certificate which must be specified using
807 the fingerprint FPR and will be stored at R_CERT. On error NULL is
808 stored at R_CERT and an error code returned. Note that the caller
809 must provide the locked dirmngr context CTX. */
811 get_cached_cert (assuan_context_t ctx,
812 const unsigned char *fpr, ksba_cert_t *r_cert)
815 char line[ASSUAN_LINELENGTH];
824 bin2hex (fpr, 20, hexfpr);
825 snprintf (line, DIM(line)-1, "LOOKUP --signle --cache-only 0x%s", hexfpr);
827 init_membuf (&mb, 4096);
828 err = assuan_transact (ctx, line, get_cached_cert_data_cb, &mb,
829 NULL, NULL, NULL, NULL);
830 buf = get_membuf (&mb, &buflen);
837 return gpg_error (GPG_ERR_ENOMEM);
839 err = ksba_cert_new (&cert);
845 err = ksba_cert_init_from_mem (cert, buf, buflen);
849 log_error ("failed to parse a certificate: %s\n", gpg_strerror (err));
850 ksba_cert_release (cert);
860 /* Run Command helpers*/
862 /* Fairly simple callback to write all output of dirmngr to stdout. */
864 run_command_cb (void *opaque, const void *buffer, size_t length)
870 if ( fwrite (buffer, length, 1, stdout) != 1 )
871 log_error ("error writing to stdout: %s\n", strerror (errno));
876 /* Handle inquiries from the dirmngr COMMAND. */
878 run_command_inq_cb (void *opaque, const char *line)
880 struct run_command_parm_s *parm = opaque;
883 if ( !strncmp (line, "SENDCERT", 8) && (line[8] == ' ' || !line[8]) )
884 { /* send the given certificate */
887 const unsigned char *der;
892 return gpg_error (GPG_ERR_ASS_PARAMETER);
894 err = gpgsm_find_cert (line, NULL, &cert);
897 log_error ("certificate not found: %s\n", gpg_strerror (err));
898 rc = gpg_error (GPG_ERR_NOT_FOUND);
902 der = ksba_cert_get_image (cert, &derlen);
904 rc = gpg_error (GPG_ERR_INV_CERT_OBJ);
906 rc = assuan_send_data (parm->ctx, der, derlen);
907 ksba_cert_release (cert);
910 else if ( !strncmp (line, "PRINTINFO", 9) && (line[9] == ' ' || !line[9]) )
911 { /* Simply show the message given in the argument. */
913 log_info ("dirmngr: %s\n", line);
917 log_error ("unsupported inquiry `%s'\n", line);
918 rc = gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
925 run_command_status_cb (void *opaque, const char *line)
927 ctrl_t ctrl = opaque;
931 log_info ("dirmngr status: %s\n", line);
933 if (!strncmp (line, "PROGRESS", 8) && (line[8]==' ' || !line[8]))
937 for (line += 8; *line == ' '; line++)
939 if (gpgsm_status (ctrl, STATUS_PROGRESS, line))
940 return gpg_error (GPG_ERR_ASS_CANCELED);
948 /* Pass COMMAND to dirmngr and print all output generated by Dirmngr
949 to stdout. A couple of inquiries are defined (see above). ARGC
950 arguments in ARGV are given to the Dirmngr. Spaces, plus and
951 percent characters within the argument strings are percent escaped
952 so that blanks can act as delimiters. */
954 gpgsm_dirmngr_run_command (ctrl_t ctrl, const char *command,
955 int argc, char **argv)
962 struct run_command_parm_s parm;
964 rc = start_dirmngr (ctrl);
968 parm.ctx = dirmngr_ctx;
970 len = strlen (command) + 1;
971 for (i=0; i < argc; i++)
972 len += 1 + 3*strlen (argv[i]); /* enough space for percent escaping */
973 line = xtrymalloc (len);
976 release_dirmngr (ctrl);
977 return out_of_core ();
980 p = stpcpy (line, command);
981 for (i=0; i < argc; i++)
984 for (s=argv[i]; *s; s++)
990 else if (!isprint (*s) || *s == '+')
992 sprintf (p, "%%%02X", *(const unsigned char *)s);
1001 rc = assuan_transact (dirmngr_ctx, line,
1002 run_command_cb, NULL,
1003 run_command_inq_cb, &parm,
1004 run_command_status_cb, ctrl);
1006 log_info ("response of dirmngr: %s\n", rc? gpg_strerror (rc): "okay");
1007 release_dirmngr (ctrl);