Line data Source code
1 : /* ocsp.c - OCSP management
2 : * Copyright (C) 2004, 2007 g10 Code GmbH
3 : *
4 : * This file is part of DirMngr.
5 : *
6 : * DirMngr is free software; you can redistribute it and/or modify
7 : * it under the terms of the GNU General Public License as published by
8 : * the Free Software Foundation; either version 2 of the License, or
9 : * (at your option) any later version.
10 : *
11 : * DirMngr is distributed in the hope that it will be useful,
12 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : * GNU General Public License for more details.
15 : *
16 : * You should have received a copy of the GNU General Public License
17 : * along with this program; if not, write to the Free Software
18 : * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 : */
20 :
21 : #include <config.h>
22 : #include <stdio.h>
23 : #include <stdlib.h>
24 : #include <errno.h>
25 : #include <assert.h>
26 :
27 : #include "dirmngr.h"
28 : #include "misc.h"
29 : #include "http.h"
30 : #include "validate.h"
31 : #include "certcache.h"
32 : #include "ocsp.h"
33 :
34 : /* The maximum size we allow as a response from an OCSP reponder. */
35 : #define MAX_RESPONSE_SIZE 65536
36 :
37 :
38 : static const char oidstr_ocsp[] = "1.3.6.1.5.5.7.48.1";
39 :
40 :
41 : /* Telesec attribute used to implement a positive confirmation.
42 :
43 : CertHash ::= SEQUENCE {
44 : HashAlgorithm AlgorithmIdentifier,
45 : certificateHash OCTET STRING }
46 : */
47 : static const char oidstr_certHash[] = "1.3.36.8.3.13";
48 :
49 :
50 :
51 :
52 : /* Read from FP and return a newly allocated buffer in R_BUFFER with the
53 : entire data read from FP. */
54 : static gpg_error_t
55 0 : read_response (estream_t fp, unsigned char **r_buffer, size_t *r_buflen)
56 : {
57 : gpg_error_t err;
58 : unsigned char *buffer;
59 : size_t bufsize, nbytes;
60 :
61 0 : *r_buffer = NULL;
62 0 : *r_buflen = 0;
63 :
64 0 : bufsize = 4096;
65 0 : buffer = xtrymalloc (bufsize);
66 0 : if (!buffer)
67 0 : return gpg_error_from_errno (errno);
68 :
69 0 : nbytes = 0;
70 : for (;;)
71 : {
72 : unsigned char *tmp;
73 0 : size_t nread = 0;
74 :
75 0 : assert (nbytes < bufsize);
76 0 : nread = es_fread (buffer+nbytes, 1, bufsize-nbytes, fp);
77 0 : if (nread < bufsize-nbytes && es_ferror (fp))
78 : {
79 0 : err = gpg_error_from_errno (errno);
80 0 : log_error (_("error reading from responder: %s\n"),
81 0 : strerror (errno));
82 0 : xfree (buffer);
83 0 : return err;
84 : }
85 0 : if ( !(nread == bufsize-nbytes && !es_feof (fp)))
86 : { /* Response successfully received. */
87 0 : nbytes += nread;
88 0 : *r_buffer = buffer;
89 0 : *r_buflen = nbytes;
90 0 : return 0;
91 : }
92 :
93 0 : nbytes += nread;
94 :
95 : /* Need to enlarge the buffer. */
96 0 : if (bufsize >= MAX_RESPONSE_SIZE)
97 : {
98 0 : log_error (_("response from server too large; limit is %d bytes\n"),
99 : MAX_RESPONSE_SIZE);
100 0 : xfree (buffer);
101 0 : return gpg_error (GPG_ERR_TOO_LARGE);
102 : }
103 :
104 0 : bufsize += 4096;
105 0 : tmp = xtryrealloc (buffer, bufsize);
106 0 : if (!tmp)
107 : {
108 0 : err = gpg_error_from_errno (errno);
109 0 : xfree (buffer);
110 0 : return err;
111 : }
112 0 : buffer = tmp;
113 0 : }
114 : }
115 :
116 :
117 : /* Construct an OCSP request, send it to the configured OCSP responder
118 : and parse the response. On success the OCSP context may be used to
119 : further process the response. */
120 : static gpg_error_t
121 0 : do_ocsp_request (ctrl_t ctrl, ksba_ocsp_t ocsp, gcry_md_hd_t md,
122 : const char *url, ksba_cert_t cert, ksba_cert_t issuer_cert)
123 : {
124 : gpg_error_t err;
125 : unsigned char *request, *response;
126 : size_t requestlen, responselen;
127 : http_t http;
128 : ksba_ocsp_response_status_t response_status;
129 : const char *t;
130 0 : int redirects_left = 2;
131 0 : char *free_this = NULL;
132 :
133 : (void)ctrl;
134 :
135 0 : if (opt.use_tor)
136 : {
137 : /* For now we do not allow OCSP via Tor due to possible privacy
138 : concerns. Needs further research. */
139 0 : log_error (_("OCSP request not possible due to Tor mode\n"));
140 0 : return gpg_error (GPG_ERR_NOT_SUPPORTED);
141 : }
142 :
143 0 : if (opt.disable_http)
144 : {
145 0 : log_error (_("OCSP request not possible due to disabled HTTP\n"));
146 0 : return gpg_error (GPG_ERR_NOT_SUPPORTED);
147 : }
148 :
149 0 : err = ksba_ocsp_add_target (ocsp, cert, issuer_cert);
150 0 : if (err)
151 : {
152 0 : log_error (_("error setting OCSP target: %s\n"), gpg_strerror (err));
153 0 : return err;
154 : }
155 :
156 : {
157 : size_t n;
158 : unsigned char nonce[32];
159 :
160 0 : n = ksba_ocsp_set_nonce (ocsp, NULL, 0);
161 0 : if (n > sizeof nonce)
162 0 : n = sizeof nonce;
163 0 : gcry_create_nonce (nonce, n);
164 0 : ksba_ocsp_set_nonce (ocsp, nonce, n);
165 : }
166 :
167 0 : err = ksba_ocsp_build_request (ocsp, &request, &requestlen);
168 0 : if (err)
169 : {
170 0 : log_error (_("error building OCSP request: %s\n"), gpg_strerror (err));
171 0 : return err;
172 : }
173 :
174 : once_more:
175 0 : err = http_open (&http, HTTP_REQ_POST, url, NULL, NULL,
176 0 : ((opt.honor_http_proxy? HTTP_FLAG_TRY_PROXY:0)
177 0 : | (opt.use_tor? HTTP_FLAG_FORCE_TOR:0)),
178 0 : ctrl->http_proxy, NULL, NULL, NULL);
179 0 : if (err)
180 : {
181 0 : log_error (_("error connecting to '%s': %s\n"), url, gpg_strerror (err));
182 0 : xfree (free_this);
183 0 : return err;
184 : }
185 :
186 0 : es_fprintf (http_get_write_ptr (http),
187 : "Content-Type: application/ocsp-request\r\n"
188 : "Content-Length: %lu\r\n",
189 : (unsigned long)requestlen );
190 0 : http_start_data (http);
191 0 : if (es_fwrite (request, requestlen, 1, http_get_write_ptr (http)) != 1)
192 : {
193 0 : err = gpg_error_from_errno (errno);
194 0 : log_error ("error sending request to '%s': %s\n", url, strerror (errno));
195 0 : http_close (http, 0);
196 0 : xfree (request);
197 0 : xfree (free_this);
198 0 : return err;
199 : }
200 0 : xfree (request);
201 0 : request = NULL;
202 :
203 0 : err = http_wait_response (http);
204 0 : if (err || http_get_status_code (http) != 200)
205 : {
206 0 : if (err)
207 0 : log_error (_("error reading HTTP response for '%s': %s\n"),
208 : url, gpg_strerror (err));
209 : else
210 : {
211 0 : switch (http_get_status_code (http))
212 : {
213 : case 301:
214 : case 302:
215 : {
216 0 : const char *s = http_get_header (http, "Location");
217 :
218 0 : log_info (_("URL '%s' redirected to '%s' (%u)\n"),
219 : url, s?s:"[none]", http_get_status_code (http));
220 0 : if (s && *s && redirects_left-- )
221 : {
222 0 : xfree (free_this); url = NULL;
223 0 : free_this = xtrystrdup (s);
224 0 : if (!free_this)
225 0 : err = gpg_error_from_errno (errno);
226 : else
227 : {
228 0 : url = free_this;
229 0 : http_close (http, 0);
230 0 : goto once_more;
231 : }
232 : }
233 : else
234 0 : err = gpg_error (GPG_ERR_NO_DATA);
235 0 : log_error (_("too many redirections\n"));
236 : }
237 0 : break;
238 :
239 : default:
240 0 : log_error (_("error accessing '%s': http status %u\n"),
241 : url, http_get_status_code (http));
242 0 : err = gpg_error (GPG_ERR_NO_DATA);
243 0 : break;
244 : }
245 : }
246 0 : http_close (http, 0);
247 0 : xfree (free_this);
248 0 : return err;
249 : }
250 :
251 0 : err = read_response (http_get_read_ptr (http), &response, &responselen);
252 0 : http_close (http, 0);
253 0 : if (err)
254 : {
255 0 : log_error (_("error reading HTTP response for '%s': %s\n"),
256 : url, gpg_strerror (err));
257 0 : xfree (free_this);
258 0 : return err;
259 : }
260 :
261 0 : err = ksba_ocsp_parse_response (ocsp, response, responselen,
262 : &response_status);
263 0 : if (err)
264 : {
265 0 : log_error (_("error parsing OCSP response for '%s': %s\n"),
266 : url, gpg_strerror (err));
267 0 : xfree (response);
268 0 : xfree (free_this);
269 0 : return err;
270 : }
271 :
272 0 : switch (response_status)
273 : {
274 0 : case KSBA_OCSP_RSPSTATUS_SUCCESS: t = "success"; break;
275 0 : case KSBA_OCSP_RSPSTATUS_MALFORMED: t = "malformed"; break;
276 0 : case KSBA_OCSP_RSPSTATUS_INTERNAL: t = "internal error"; break;
277 0 : case KSBA_OCSP_RSPSTATUS_TRYLATER: t = "try later"; break;
278 0 : case KSBA_OCSP_RSPSTATUS_SIGREQUIRED: t = "must sign request"; break;
279 0 : case KSBA_OCSP_RSPSTATUS_UNAUTHORIZED: t = "unauthorized"; break;
280 0 : case KSBA_OCSP_RSPSTATUS_REPLAYED: t = "replay detected"; break;
281 0 : case KSBA_OCSP_RSPSTATUS_OTHER: t = "other (unknown)"; break;
282 0 : case KSBA_OCSP_RSPSTATUS_NONE: t = "no status"; break;
283 0 : default: t = "[unknown status]"; break;
284 : }
285 0 : if (response_status == KSBA_OCSP_RSPSTATUS_SUCCESS)
286 : {
287 0 : if (opt.verbose)
288 0 : log_info (_("OCSP responder at '%s' status: %s\n"), url, t);
289 :
290 0 : err = ksba_ocsp_hash_response (ocsp, response, responselen,
291 : HASH_FNC, md);
292 0 : if (err)
293 0 : log_error (_("hashing the OCSP response for '%s' failed: %s\n"),
294 : url, gpg_strerror (err));
295 : }
296 : else
297 : {
298 0 : log_error (_("OCSP responder at '%s' status: %s\n"), url, t);
299 0 : err = gpg_error (GPG_ERR_GENERAL);
300 : }
301 :
302 0 : xfree (response);
303 0 : xfree (free_this);
304 0 : return err;
305 : }
306 :
307 :
308 : /* Validate that CERT is indeed valid to sign an OCSP response. If
309 : SIGNER_FPR_LIST is not NULL we simply check that CERT matches one
310 : of the fingerprints in this list. */
311 : static gpg_error_t
312 0 : validate_responder_cert (ctrl_t ctrl, ksba_cert_t cert,
313 : fingerprint_list_t signer_fpr_list)
314 : {
315 : gpg_error_t err;
316 : char *fpr;
317 :
318 0 : if (signer_fpr_list)
319 : {
320 0 : fpr = get_fingerprint_hexstring (cert);
321 0 : for (; signer_fpr_list && strcmp (signer_fpr_list->hexfpr, fpr);
322 0 : signer_fpr_list = signer_fpr_list->next)
323 : ;
324 0 : if (signer_fpr_list)
325 0 : err = 0;
326 : else
327 : {
328 0 : log_error (_("not signed by a default OCSP signer's certificate"));
329 0 : err = gpg_error (GPG_ERR_BAD_CA_CERT);
330 : }
331 0 : xfree (fpr);
332 : }
333 : else
334 : {
335 : /* We avoid duplicating the entire certificate validation code
336 : from gpgsm here. Because we have no way calling back to the
337 : client and letting it compute the validity, we use the ugly
338 : hack of telling the client that the response will only be
339 : valid if the certificate given in this status message is
340 : valid.
341 :
342 : Note, that in theory we could simply ask the client via an
343 : inquire to validate a certificate but this might involve
344 : calling DirMngr again recursivly - we can't do that as of now
345 : (neither DirMngr nor gpgsm have the ability for concurrent
346 : access to DirMngr. */
347 :
348 : /* FIXME: We should cache this certificate locally, so that the next
349 : call to dirmngr won't need to look it up - if this works at
350 : all. */
351 0 : fpr = get_fingerprint_hexstring (cert);
352 0 : dirmngr_status (ctrl, "ONLY_VALID_IF_CERT_VALID", fpr, NULL);
353 0 : xfree (fpr);
354 0 : err = 0;
355 : }
356 :
357 0 : return err;
358 : }
359 :
360 :
361 : /* Helper for check_signature. */
362 : static int
363 0 : check_signature_core (ctrl_t ctrl, ksba_cert_t cert, gcry_sexp_t s_sig,
364 : gcry_sexp_t s_hash, fingerprint_list_t signer_fpr_list)
365 : {
366 : gpg_error_t err;
367 : ksba_sexp_t pubkey;
368 0 : gcry_sexp_t s_pkey = NULL;
369 :
370 0 : pubkey = ksba_cert_get_public_key (cert);
371 0 : if (!pubkey)
372 0 : err = gpg_error (GPG_ERR_INV_OBJ);
373 : else
374 0 : err = canon_sexp_to_gcry (pubkey, &s_pkey);
375 0 : xfree (pubkey);
376 0 : if (!err)
377 0 : err = gcry_pk_verify (s_sig, s_hash, s_pkey);
378 0 : if (!err)
379 0 : err = validate_responder_cert (ctrl, cert, signer_fpr_list);
380 0 : if (!err)
381 : {
382 0 : gcry_sexp_release (s_pkey);
383 0 : return 0; /* Successfully verified the signature. */
384 : }
385 :
386 : /* We simply ignore all errors. */
387 0 : gcry_sexp_release (s_pkey);
388 0 : return -1;
389 : }
390 :
391 :
392 : /* Check the signature of an OCSP repsonse. OCSP is the context,
393 : S_SIG the signature value and MD the handle of the hash we used for
394 : the response. This function automagically finds the correct public
395 : key. If SIGNER_FPR_LIST is not NULL, the default OCSP reponder has been
396 : used and thus the certificate is one of those identified by
397 : the fingerprints. */
398 : static gpg_error_t
399 0 : check_signature (ctrl_t ctrl,
400 : ksba_ocsp_t ocsp, gcry_sexp_t s_sig, gcry_md_hd_t md,
401 : fingerprint_list_t signer_fpr_list)
402 : {
403 : gpg_error_t err;
404 : int algo, cert_idx;
405 : gcry_sexp_t s_hash;
406 : ksba_cert_t cert;
407 :
408 : /* Create a suitable S-expression with the hash value of our response. */
409 0 : gcry_md_final (md);
410 0 : algo = gcry_md_get_algo (md);
411 0 : if (algo != GCRY_MD_SHA1 )
412 : {
413 0 : log_error (_("only SHA-1 is supported for OCSP responses\n"));
414 0 : return gpg_error (GPG_ERR_DIGEST_ALGO);
415 : }
416 0 : err = gcry_sexp_build (&s_hash, NULL, "(data(flags pkcs1)(hash sha1 %b))",
417 : gcry_md_get_algo_dlen (algo),
418 : gcry_md_read (md, algo));
419 0 : if (err)
420 : {
421 0 : log_error (_("creating S-expression failed: %s\n"), gcry_strerror (err));
422 0 : return err;
423 : }
424 :
425 : /* Get rid of old OCSP specific certificate references. */
426 0 : release_ctrl_ocsp_certs (ctrl);
427 :
428 0 : if (signer_fpr_list && !signer_fpr_list->next)
429 : {
430 : /* There is exactly one signer fingerprint given. Thus we use
431 : the default OCSP responder's certificate and instantly know
432 : the certificate to use. */
433 0 : cert = get_cert_byhexfpr (signer_fpr_list->hexfpr);
434 0 : if (!cert)
435 0 : cert = get_cert_local (ctrl, signer_fpr_list->hexfpr);
436 0 : if (cert)
437 : {
438 0 : err = check_signature_core (ctrl, cert, s_sig, s_hash,
439 : signer_fpr_list);
440 0 : ksba_cert_release (cert);
441 0 : cert = NULL;
442 0 : if (!err)
443 : {
444 0 : gcry_sexp_release (s_hash);
445 0 : return 0; /* Successfully verified the signature. */
446 : }
447 : }
448 : }
449 : else
450 : {
451 : char *name;
452 : ksba_sexp_t keyid;
453 :
454 : /* Put all certificates included in the response into the cache
455 : and setup a list of those certificate which will later be
456 : preferred used when locating certificates. */
457 0 : for (cert_idx=0; (cert = ksba_ocsp_get_cert (ocsp, cert_idx));
458 0 : cert_idx++)
459 : {
460 : cert_ref_t cref;
461 :
462 0 : cref = xtrymalloc (sizeof *cref);
463 0 : if (!cref)
464 0 : log_error (_("allocating list item failed: %s\n"),
465 : gcry_strerror (err));
466 0 : else if (!cache_cert_silent (cert, &cref->fpr))
467 : {
468 0 : cref->next = ctrl->ocsp_certs;
469 0 : ctrl->ocsp_certs = cref;
470 : }
471 : else
472 0 : xfree (cref);
473 : }
474 :
475 : /* Get the certificate by means of the responder ID. */
476 0 : err = ksba_ocsp_get_responder_id (ocsp, &name, &keyid);
477 0 : if (err)
478 : {
479 0 : log_error (_("error getting responder ID: %s\n"),
480 : gcry_strerror (err));
481 0 : return err;
482 : }
483 0 : cert = find_cert_bysubject (ctrl, name, keyid);
484 0 : if (!cert)
485 : {
486 0 : log_error ("responder certificate ");
487 0 : if (name)
488 0 : log_printf ("'/%s' ", name);
489 0 : if (keyid)
490 : {
491 0 : log_printf ("{");
492 0 : dump_serial (keyid);
493 0 : log_printf ("} ");
494 : }
495 0 : log_printf ("not found\n");
496 : }
497 0 : ksba_free (name);
498 0 : ksba_free (keyid);
499 :
500 0 : if (cert)
501 : {
502 0 : err = check_signature_core (ctrl, cert, s_sig, s_hash,
503 : signer_fpr_list);
504 0 : ksba_cert_release (cert);
505 0 : if (!err)
506 : {
507 0 : gcry_sexp_release (s_hash);
508 0 : return 0; /* Successfully verified the signature. */
509 : }
510 : }
511 : }
512 :
513 0 : gcry_sexp_release (s_hash);
514 0 : log_error (_("no suitable certificate found to verify the OCSP response\n"));
515 0 : return gpg_error (GPG_ERR_NO_PUBKEY);
516 : }
517 :
518 :
519 : /* Check whether the certificate either given by fingerprint CERT_FPR
520 : or directly through the CERT object is valid by running an OCSP
521 : transaction. With FORCE_DEFAULT_RESPONDER set only the configured
522 : default responder is used. */
523 : gpg_error_t
524 0 : ocsp_isvalid (ctrl_t ctrl, ksba_cert_t cert, const char *cert_fpr,
525 : int force_default_responder)
526 : {
527 : gpg_error_t err;
528 0 : ksba_ocsp_t ocsp = NULL;
529 0 : ksba_cert_t issuer_cert = NULL;
530 0 : ksba_sexp_t sigval = NULL;
531 0 : gcry_sexp_t s_sig = NULL;
532 : ksba_isotime_t current_time;
533 : ksba_isotime_t this_update, next_update, revocation_time, produced_at;
534 : ksba_isotime_t tmp_time;
535 : ksba_status_t status;
536 : ksba_crl_reason_t reason;
537 0 : char *url_buffer = NULL;
538 : const char *url;
539 0 : gcry_md_hd_t md = NULL;
540 : int i, idx;
541 : char *oid;
542 : ksba_name_t name;
543 0 : fingerprint_list_t default_signer = NULL;
544 :
545 : /* Get the certificate. */
546 0 : if (cert)
547 : {
548 0 : ksba_cert_ref (cert);
549 :
550 0 : err = find_issuing_cert (ctrl, cert, &issuer_cert);
551 0 : if (err)
552 : {
553 0 : log_error (_("issuer certificate not found: %s\n"),
554 : gpg_strerror (err));
555 0 : goto leave;
556 : }
557 : }
558 : else
559 : {
560 0 : cert = get_cert_local (ctrl, cert_fpr);
561 0 : if (!cert)
562 : {
563 0 : log_error (_("caller did not return the target certificate\n"));
564 0 : err = gpg_error (GPG_ERR_GENERAL);
565 0 : goto leave;
566 : }
567 0 : issuer_cert = get_issuing_cert_local (ctrl, NULL);
568 0 : if (!issuer_cert)
569 : {
570 0 : log_error (_("caller did not return the issuing certificate\n"));
571 0 : err = gpg_error (GPG_ERR_GENERAL);
572 0 : goto leave;
573 : }
574 : }
575 :
576 : /* Create an OCSP instance. */
577 0 : err = ksba_ocsp_new (&ocsp);
578 0 : if (err)
579 : {
580 0 : log_error (_("failed to allocate OCSP context: %s\n"),
581 : gpg_strerror (err));
582 0 : goto leave;
583 : }
584 :
585 :
586 :
587 : /* Figure out the OCSP responder to use.
588 : 1. Try to get the reponder from the certificate.
589 : We do only take http and https style URIs into account.
590 : 2. If this fails use the default responder, if any.
591 : */
592 0 : url = NULL;
593 0 : for (idx=0; !url && !opt.ignore_ocsp_service_url && !force_default_responder
594 0 : && !(err=ksba_cert_get_authority_info_access (cert, idx,
595 0 : &oid, &name)); idx++)
596 : {
597 0 : if ( !strcmp (oid, oidstr_ocsp) )
598 : {
599 0 : for (i=0; !url && ksba_name_enum (name, i); i++)
600 : {
601 0 : char *p = ksba_name_get_uri (name, i);
602 0 : if (p && (!ascii_strncasecmp (p, "http:", 5)
603 0 : || !ascii_strncasecmp (p, "https:", 6)))
604 0 : url = url_buffer = p;
605 : else
606 0 : xfree (p);
607 : }
608 : }
609 0 : ksba_name_release (name);
610 0 : ksba_free (oid);
611 : }
612 0 : if (err && gpg_err_code (err) != GPG_ERR_EOF)
613 : {
614 0 : log_error (_("can't get authorityInfoAccess: %s\n"), gpg_strerror (err));
615 0 : goto leave;
616 : }
617 0 : if (!url)
618 : {
619 0 : if (!opt.ocsp_responder || !*opt.ocsp_responder)
620 : {
621 0 : log_info (_("no default OCSP responder defined\n"));
622 0 : err = gpg_error (GPG_ERR_CONFIGURATION);
623 0 : goto leave;
624 : }
625 0 : if (!opt.ocsp_signer)
626 : {
627 0 : log_info (_("no default OCSP signer defined\n"));
628 0 : err = gpg_error (GPG_ERR_CONFIGURATION);
629 0 : goto leave;
630 : }
631 0 : url = opt.ocsp_responder;
632 0 : default_signer = opt.ocsp_signer;
633 0 : if (opt.verbose)
634 0 : log_info (_("using default OCSP responder '%s'\n"), url);
635 : }
636 : else
637 : {
638 0 : if (opt.verbose)
639 0 : log_info (_("using OCSP responder '%s'\n"), url);
640 : }
641 :
642 : /* Ask the OCSP responder. */
643 0 : err = gcry_md_open (&md, GCRY_MD_SHA1, 0);
644 0 : if (err)
645 : {
646 0 : log_error (_("failed to establish a hashing context for OCSP: %s\n"),
647 : gpg_strerror (err));
648 0 : goto leave;
649 : }
650 0 : err = do_ocsp_request (ctrl, ocsp, md, url, cert, issuer_cert);
651 0 : if (err)
652 0 : goto leave;
653 :
654 : /* We got a useful answer, check that the answer has a valid signature. */
655 0 : sigval = ksba_ocsp_get_sig_val (ocsp, produced_at);
656 0 : if (!sigval || !*produced_at)
657 : {
658 0 : err = gpg_error (GPG_ERR_INV_OBJ);
659 0 : goto leave;
660 : }
661 0 : if ( (err = canon_sexp_to_gcry (sigval, &s_sig)) )
662 0 : goto leave;
663 0 : xfree (sigval);
664 0 : sigval = NULL;
665 0 : err = check_signature (ctrl, ocsp, s_sig, md, default_signer);
666 0 : if (err)
667 0 : goto leave;
668 :
669 : /* We only support one certificate per request. Check that the
670 : answer matches the right certificate. */
671 0 : err = ksba_ocsp_get_status (ocsp, cert,
672 : &status, this_update, next_update,
673 : revocation_time, &reason);
674 0 : if (err)
675 : {
676 0 : log_error (_("error getting OCSP status for target certificate: %s\n"),
677 : gpg_strerror (err));
678 0 : goto leave;
679 : }
680 :
681 : /* In case the certificate has been revoked, we better invalidate
682 : our cached validation status. */
683 0 : if (status == KSBA_STATUS_REVOKED)
684 : {
685 0 : time_t validated_at = 0; /* That is: No cached validation available. */
686 0 : err = ksba_cert_set_user_data (cert, "validated_at",
687 : &validated_at, sizeof (validated_at));
688 0 : if (err)
689 : {
690 0 : log_error ("set_user_data(validated_at) failed: %s\n",
691 : gpg_strerror (err));
692 0 : err = 0; /* The certificate is anyway revoked, and that is a
693 : more important message than the failure of our
694 : cache. */
695 : }
696 : }
697 :
698 :
699 0 : if (opt.verbose)
700 : {
701 0 : log_info (_("certificate status is: %s (this=%s next=%s)\n"),
702 0 : status == KSBA_STATUS_GOOD? _("good"):
703 0 : status == KSBA_STATUS_REVOKED? _("revoked"):
704 0 : status == KSBA_STATUS_UNKNOWN? _("unknown"):
705 0 : status == KSBA_STATUS_NONE? _("none"): "?",
706 : this_update, next_update);
707 0 : if (status == KSBA_STATUS_REVOKED)
708 0 : log_info (_("certificate has been revoked at: %s due to: %s\n"),
709 : revocation_time,
710 0 : reason == KSBA_CRLREASON_UNSPECIFIED? "unspecified":
711 0 : reason == KSBA_CRLREASON_KEY_COMPROMISE? "key compromise":
712 0 : reason == KSBA_CRLREASON_CA_COMPROMISE? "CA compromise":
713 0 : reason == KSBA_CRLREASON_AFFILIATION_CHANGED?
714 0 : "affiliation changed":
715 0 : reason == KSBA_CRLREASON_SUPERSEDED? "superseded":
716 0 : reason == KSBA_CRLREASON_CESSATION_OF_OPERATION?
717 0 : "cessation of operation":
718 0 : reason == KSBA_CRLREASON_CERTIFICATE_HOLD?
719 0 : "certificate on hold":
720 0 : reason == KSBA_CRLREASON_REMOVE_FROM_CRL?
721 0 : "removed from CRL":
722 0 : reason == KSBA_CRLREASON_PRIVILEGE_WITHDRAWN?
723 0 : "privilege withdrawn":
724 0 : reason == KSBA_CRLREASON_AA_COMPROMISE? "AA compromise":
725 0 : reason == KSBA_CRLREASON_OTHER? "other":"?");
726 :
727 : }
728 :
729 :
730 0 : if (status == KSBA_STATUS_REVOKED)
731 0 : err = gpg_error (GPG_ERR_CERT_REVOKED);
732 0 : else if (status == KSBA_STATUS_UNKNOWN)
733 0 : err = gpg_error (GPG_ERR_NO_DATA);
734 0 : else if (status != KSBA_STATUS_GOOD)
735 0 : err = gpg_error (GPG_ERR_GENERAL);
736 :
737 : /* Allow for some clock skew. */
738 0 : gnupg_get_isotime (current_time);
739 0 : add_seconds_to_isotime (current_time, opt.ocsp_max_clock_skew);
740 :
741 0 : if (strcmp (this_update, current_time) > 0 )
742 : {
743 0 : log_error (_("OCSP responder returned a status in the future\n"));
744 0 : log_info ("used now: %s this_update: %s\n", current_time, this_update);
745 0 : if (!err)
746 0 : err = gpg_error (GPG_ERR_TIME_CONFLICT);
747 : }
748 :
749 : /* Check that THIS_UPDATE is not too far back in the past. */
750 0 : gnupg_copy_time (tmp_time, this_update);
751 0 : add_seconds_to_isotime (tmp_time,
752 0 : opt.ocsp_max_period+opt.ocsp_max_clock_skew);
753 0 : if (!*tmp_time || strcmp (tmp_time, current_time) < 0 )
754 : {
755 0 : log_error (_("OCSP responder returned a non-current status\n"));
756 0 : log_info ("used now: %s this_update: %s\n",
757 : current_time, this_update);
758 0 : if (!err)
759 0 : err = gpg_error (GPG_ERR_TIME_CONFLICT);
760 : }
761 :
762 : /* Check that we are not beyound NEXT_UPDATE (plus some extra time). */
763 0 : if (*next_update)
764 : {
765 0 : gnupg_copy_time (tmp_time, next_update);
766 0 : add_seconds_to_isotime (tmp_time,
767 0 : opt.ocsp_current_period+opt.ocsp_max_clock_skew);
768 0 : if (!*tmp_time && strcmp (tmp_time, current_time) < 0 )
769 : {
770 0 : log_error (_("OCSP responder returned an too old status\n"));
771 0 : log_info ("used now: %s next_update: %s\n",
772 : current_time, next_update);
773 0 : if (!err)
774 0 : err = gpg_error (GPG_ERR_TIME_CONFLICT);
775 : }
776 : }
777 :
778 :
779 : leave:
780 0 : gcry_md_close (md);
781 0 : gcry_sexp_release (s_sig);
782 0 : xfree (sigval);
783 0 : ksba_cert_release (issuer_cert);
784 0 : ksba_cert_release (cert);
785 0 : ksba_ocsp_release (ocsp);
786 0 : xfree (url_buffer);
787 0 : return err;
788 : }
789 :
790 :
791 : /* Release the list of OCSP certificates hold in the CTRL object. */
792 : void
793 0 : release_ctrl_ocsp_certs (ctrl_t ctrl)
794 : {
795 0 : while (ctrl->ocsp_certs)
796 : {
797 0 : cert_ref_t tmp = ctrl->ocsp_certs->next;
798 0 : xfree (ctrl->ocsp_certs);
799 0 : ctrl->ocsp_certs = tmp;
800 : }
801 0 : }
|