1 /* crlfetch.c - LDAP access
2 * Copyright (C) 2002 Klarälvdalens Datakonsult AB
3 * Copyright (C) 2003, 2004, 2005, 2006, 2007 g10 Code GmbH
5 * This file is part of DirMngr.
7 * DirMngr 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 2 of the License, or
10 * (at your option) any later version.
12 * DirMngr 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/>.
31 #include "ks-engine.h" /* For ks_http_fetch. */
34 # include "ldap-wrapper.h"
37 /* For detecting armored CRLs received via HTTP (yes, such CRLS really
38 exits, e.g. http://grid.fzk.de/ca/gridka-crl.pem at least in June
39 2008) we need a context in the reader callback. */
40 struct reader_cb_context_s
42 estream_t fp; /* The stream used with the ksba reader. */
43 int checked:1; /* PEM/binary detection ahs been done. */
44 int is_pem:1; /* The file stream is PEM encoded. */
45 struct b64state b64state; /* The state used for Base64 decoding. */
49 /* We need to associate a reader object with the reader callback
50 context. This table is used for it. */
51 struct file_reader_map_s
54 struct reader_cb_context_s *cb_ctx;
56 #define MAX_FILE_READER 50
57 static struct file_reader_map_s file_reader_map[MAX_FILE_READER];
59 /* Associate FP with READER. If the table is full wait until another
60 thread has removed an entry. */
62 register_file_reader (ksba_reader_t reader, struct reader_cb_context_s *cb_ctx)
68 for (i=0; i < MAX_FILE_READER; i++)
69 if (!file_reader_map[i].reader)
71 file_reader_map[i].reader = reader;
72 file_reader_map[i].cb_ctx = cb_ctx;
75 log_info (_("reader to file mapping table full - waiting\n"));
80 /* Scan the table for an entry matching READER, remove that entry and
81 return the associated file pointer. */
82 static struct reader_cb_context_s *
83 get_file_reader (ksba_reader_t reader)
85 struct reader_cb_context_s *cb_ctx = NULL;
88 for (i=0; i < MAX_FILE_READER; i++)
89 if (file_reader_map[i].reader == reader)
91 cb_ctx = file_reader_map[i].cb_ctx;
92 file_reader_map[i].reader = NULL;
93 file_reader_map[i].cb_ctx = NULL;
102 my_es_read (void *opaque, char *buffer, size_t nbytes, size_t *nread)
104 struct reader_cb_context_s *cb_ctx = opaque;
107 result = es_read (cb_ctx->fp, buffer, nbytes, nread);
110 /* Fixme we should check whether the semantics of es_read are okay
111 and well defined. I have some doubts. */
112 if (nbytes && !*nread && es_feof (cb_ctx->fp))
113 return gpg_error (GPG_ERR_EOF);
114 if (!nread && es_ferror (cb_ctx->fp))
115 return gpg_error (GPG_ERR_EIO);
117 if (!cb_ctx->checked && *nread)
119 int c = *(unsigned char *)buffer;
122 if ( ((c & 0xc0) >> 6) == 0 /* class: universal */
123 && (c & 0x1f) == 16 /* sequence */
124 && (c & 0x20) /* is constructed */ )
129 b64dec_start (&cb_ctx->b64state, "");
132 if (cb_ctx->is_pem && *nread)
136 if (b64dec_proc (&cb_ctx->b64state, buffer, *nread, &nread2))
138 /* EOF from decoder. */
140 result = gpg_error (GPG_ERR_EOF);
150 /* For now we do not support LDAP over Tor. */
152 no_crl_due_to_tor (ctrl_t ctrl)
154 gpg_error_t err = gpg_error (GPG_ERR_NOT_SUPPORTED);
155 const char *text = _("CRL access not possible due to Tor mode");
157 log_error ("%s", text);
158 dirmngr_status_printf (ctrl, "NOTE", "no_crl_due_to_tor %u %s", err, text);
159 return gpg_error (GPG_ERR_NOT_SUPPORTED);
163 /* Fetch CRL from URL and return the entire CRL using new ksba reader
164 object in READER. Note that this reader object should be closed
165 only using ldap_close_reader. */
167 crl_fetch (ctrl_t ctrl, const char *url, ksba_reader_t *reader)
171 estream_t httpfp = NULL;
176 return gpg_error (GPG_ERR_INV_ARG);
178 err = http_parse_uri (&uri, url, 0);
179 http_release_parsed_uri (uri);
180 if (!err) /* Yes, our HTTP code groks that. */
182 if (opt.disable_http)
184 log_error (_("CRL access not possible due to disabled %s\n"),
186 err = gpg_error (GPG_ERR_NOT_SUPPORTED);
190 /* Note that we also allow root certificates loaded from
191 * "/etc/gnupg/trusted-certs/". We also do not consult the
192 * CRL for the TLS connection - that may lead to a loop.
193 * Due to cacert.org redirecting their https URL to http we
194 * also allow such a downgrade. */
195 err = ks_http_fetch (ctrl, url,
196 (KS_HTTP_FETCH_TRUST_CFG
197 | KS_HTTP_FETCH_NO_CRL
198 | KS_HTTP_FETCH_ALLOW_DOWNGRADE ),
203 log_error (_("error retrieving '%s': %s\n"), url, gpg_strerror (err));
206 struct reader_cb_context_s *cb_ctx;
208 cb_ctx = xtrycalloc (1, sizeof *cb_ctx);
210 err = gpg_error_from_syserror ();
211 else if (!(err = ksba_reader_new (reader)))
214 err = ksba_reader_set_cb (*reader, &my_es_read, cb_ctx);
217 /* The ksba reader misses a user pointer thus we
218 * need to come up with our own way of associating a
219 * file pointer (or well the callback context) with
220 * the reader. It is only required when closing the
221 * reader thus there is no performance issue doing
222 * it this way. FIXME: We now have a close
223 * notification which might be used here. */
224 register_file_reader (*reader, cb_ctx);
231 log_error (_("error initializing reader object: %s\n"),
233 ksba_reader_release (*reader);
239 else /* Let the LDAP code parse other schemes. */
241 if (opt.disable_ldap)
243 log_error (_("CRL access not possible due to disabled %s\n"),
245 err = gpg_error (GPG_ERR_NOT_SUPPORTED);
247 else if (dirmngr_use_tor ())
249 err = no_crl_due_to_tor (ctrl);
254 err = url_fetch_ldap (ctrl, url, reader);
256 err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
257 # endif /*!USE_LDAP*/
266 /* Fetch CRL for ISSUER using a default server. Return the entire CRL
267 as a newly opened stream returned in R_FP. */
269 crl_fetch_default (ctrl_t ctrl, const char *issuer, ksba_reader_t *reader)
271 if (dirmngr_use_tor ())
273 return no_crl_due_to_tor (ctrl);
275 if (opt.disable_ldap)
277 log_error (_("CRL access not possible due to disabled %s\n"),
279 return gpg_error (GPG_ERR_NOT_SUPPORTED);
283 return attr_fetch_ldap (ctrl, issuer, "certificateRevocationList",
289 return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
294 /* Fetch a CA certificate for DN using the default server. This
295 * function only initiates the fetch; fetch_next_cert must be used to
296 * actually read the certificate; end_cert_fetch to end the
299 ca_cert_fetch (ctrl_t ctrl, cert_fetch_context_t *context, const char *dn)
301 if (dirmngr_use_tor ())
303 return no_crl_due_to_tor (ctrl);
305 if (opt.disable_ldap)
307 log_error (_("CRL access not possible due to disabled %s\n"),
309 return gpg_error (GPG_ERR_NOT_SUPPORTED);
312 return start_cacert_fetch_ldap (ctrl, context, dn);
317 return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
323 start_cert_fetch (ctrl_t ctrl, cert_fetch_context_t *context,
324 strlist_t patterns, const ldap_server_t server)
326 if (dirmngr_use_tor ())
328 return no_crl_due_to_tor (ctrl);
330 if (opt.disable_ldap)
332 log_error (_("certificate search not possible due to disabled %s\n"),
334 return gpg_error (GPG_ERR_NOT_SUPPORTED);
337 return start_cert_fetch_ldap (ctrl, context, patterns, server);
343 return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
349 fetch_next_cert (cert_fetch_context_t context,
350 unsigned char **value, size_t * valuelen)
353 return fetch_next_cert_ldap (context, value, valuelen);
358 return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
363 /* Fetch the next data from CONTEXT, assuming it is a certificate and return
364 * it as a cert object in R_CERT. */
366 fetch_next_ksba_cert (cert_fetch_context_t context, ksba_cert_t *r_cert)
369 unsigned char *value = NULL;
376 err = fetch_next_cert_ldap (context, &value, &valuelen);
378 err = gpg_error (GPG_ERR_BUG);
381 err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
386 err = ksba_cert_new (&cert);
393 err = ksba_cert_init_from_mem (cert, value, valuelen);
397 ksba_cert_release (cert);
406 end_cert_fetch (cert_fetch_context_t context)
409 end_cert_fetch_ldap (context);
416 /* Read a certificate from an HTTP URL and return it as an estream
417 * memory buffer at R_FP. */
419 read_cert_via_http (ctrl_t ctrl, const char *url, estream_t *r_fp)
423 estream_t httpfp = NULL;
424 size_t nread, nwritten;
427 if ((err = ks_http_fetch (ctrl, url, KS_HTTP_FETCH_TRUST_CFG, &httpfp)))
430 /* We now read the data from the web server into a memory buffer.
431 * To DOS we limit the certificate length to 32k. */
432 fp = es_fopenmem (32*1024, "rw");
435 err = gpg_error_from_syserror ();
436 log_error ("error allocating memory buffer: %s\n", gpg_strerror (err));
442 if (es_read (httpfp, buffer, sizeof buffer, &nread))
444 err = gpg_error_from_syserror ();
445 log_error ("error reading '%s': %s\n",
446 es_fname_get (httpfp), gpg_strerror (err));
452 if (es_write (fp, buffer, nread, &nwritten))
454 err = gpg_error_from_syserror ();
455 log_error ("error writing '%s': %s\n",
456 es_fname_get (fp), gpg_strerror (err));
459 else if (nread != nwritten)
461 err = gpg_error (GPG_ERR_EIO);
462 log_error ("error writing '%s': %s\n",
463 es_fname_get (fp), "short write");
479 /* Lookup a cert by it's URL. */
481 fetch_cert_by_url (ctrl_t ctrl, const char *url,
482 unsigned char **value, size_t *valuelen)
484 const unsigned char *cert_image = NULL;
486 ksba_reader_t reader = NULL;
487 ksba_cert_t cert = NULL;
493 err = ksba_cert_new (&cert);
497 if (url && (!strncmp (url, "http:", 5) || !strncmp (url, "https:", 6)))
503 err = read_cert_via_http (ctrl, url, &stream);
507 if (es_fclose_snatch (stream, &der, &derlen))
509 err = gpg_error_from_syserror ();
513 err = ksba_cert_init_from_mem (cert, der, derlen);
518 else /* Assume LDAP. */
521 err = url_fetch_ldap (ctrl, url, &reader);
525 err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
530 err = ksba_cert_read_der (cert, reader);
535 cert_image = ksba_cert_get_image (cert, &cert_image_n);
536 if (!cert_image || !cert_image_n)
538 err = gpg_error (GPG_ERR_INV_CERT_OBJ);
542 *value = xtrymalloc (cert_image_n);
545 err = gpg_error_from_syserror ();
549 memcpy (*value, cert_image, cert_image_n);
550 *valuelen = cert_image_n;
553 ksba_cert_release (cert);
555 ldap_wrapper_release_context (reader);
561 /* This function is to be used to close the reader object. In
562 addition to running ksba_reader_release it also releases the LDAP
563 or HTTP contexts associated with that reader. */
565 crl_close_reader (ksba_reader_t reader)
567 struct reader_cb_context_s *cb_ctx;
572 /* Check whether this is a HTTP one. */
573 cb_ctx = get_file_reader (reader);
576 /* This is an HTTP context. */
578 es_fclose (cb_ctx->fp);
579 /* Release the base64 decoder state. */
581 b64dec_finish (&cb_ctx->b64state);
582 /* Release the callback context. */
585 else /* This is an ldap wrapper context (Currently not used). */
588 ldap_wrapper_release_context (reader);
592 /* Now get rid of the reader object. */
593 ksba_reader_release (reader);