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 succesfully 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 reponse. */
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 0 : else if (opt.system_daemon)
334 : {
335 0 : err = validate_cert_chain (ctrl, cert, NULL, VALIDATE_MODE_OCSP, NULL);
336 : }
337 : else
338 : {
339 : /* We avoid duplicating the entire certificate validation code
340 : from gpgsm here. Because we have no way calling back to the
341 : client and letting it compute the validity, we use the ugly
342 : hack of telling the client that the response will only be
343 : valid if the certificate given in this status message is
344 : valid.
345 :
346 : Note, that in theory we could simply ask the client via an
347 : inquire to validate a certificate but this might involve
348 : calling DirMngr again recursivly - we can't do that as of now
349 : (neither DirMngr nor gpgsm have the ability for concurrent
350 : access to DirMngr. */
351 :
352 : /* FIXME: We should cache this certificate locally, so that the next
353 : call to dirmngr won't need to look it up - if this works at
354 : all. */
355 0 : fpr = get_fingerprint_hexstring (cert);
356 0 : dirmngr_status (ctrl, "ONLY_VALID_IF_CERT_VALID", fpr, NULL);
357 0 : xfree (fpr);
358 0 : err = 0;
359 : }
360 :
361 0 : return err;
362 : }
363 :
364 :
365 : /* Helper for check_signature. */
366 : static int
367 0 : check_signature_core (ctrl_t ctrl, ksba_cert_t cert, gcry_sexp_t s_sig,
368 : gcry_sexp_t s_hash, fingerprint_list_t signer_fpr_list)
369 : {
370 : gpg_error_t err;
371 : ksba_sexp_t pubkey;
372 0 : gcry_sexp_t s_pkey = NULL;
373 :
374 0 : pubkey = ksba_cert_get_public_key (cert);
375 0 : if (!pubkey)
376 0 : err = gpg_error (GPG_ERR_INV_OBJ);
377 : else
378 0 : err = canon_sexp_to_gcry (pubkey, &s_pkey);
379 0 : xfree (pubkey);
380 0 : if (!err)
381 0 : err = gcry_pk_verify (s_sig, s_hash, s_pkey);
382 0 : if (!err)
383 0 : err = validate_responder_cert (ctrl, cert, signer_fpr_list);
384 0 : if (!err)
385 : {
386 0 : gcry_sexp_release (s_pkey);
387 0 : return 0; /* Successfully verified the signature. */
388 : }
389 :
390 : /* We simply ignore all errors. */
391 0 : gcry_sexp_release (s_pkey);
392 0 : return -1;
393 : }
394 :
395 :
396 : /* Check the signature of an OCSP repsonse. OCSP is the context,
397 : S_SIG the signature value and MD the handle of the hash we used for
398 : the response. This function automagically finds the correct public
399 : key. If SIGNER_FPR_LIST is not NULL, the default OCSP reponder has been
400 : used and thus the certificate is one of those identified by
401 : the fingerprints. */
402 : static gpg_error_t
403 0 : check_signature (ctrl_t ctrl,
404 : ksba_ocsp_t ocsp, gcry_sexp_t s_sig, gcry_md_hd_t md,
405 : fingerprint_list_t signer_fpr_list)
406 : {
407 : gpg_error_t err;
408 : int algo, cert_idx;
409 : gcry_sexp_t s_hash;
410 : ksba_cert_t cert;
411 :
412 : /* Create a suitable S-expression with the hash value of our response. */
413 0 : gcry_md_final (md);
414 0 : algo = gcry_md_get_algo (md);
415 0 : if (algo != GCRY_MD_SHA1 )
416 : {
417 0 : log_error (_("only SHA-1 is supported for OCSP responses\n"));
418 0 : return gpg_error (GPG_ERR_DIGEST_ALGO);
419 : }
420 0 : err = gcry_sexp_build (&s_hash, NULL, "(data(flags pkcs1)(hash sha1 %b))",
421 : gcry_md_get_algo_dlen (algo),
422 : gcry_md_read (md, algo));
423 0 : if (err)
424 : {
425 0 : log_error (_("creating S-expression failed: %s\n"), gcry_strerror (err));
426 0 : return err;
427 : }
428 :
429 : /* Get rid of old OCSP specific certificate references. */
430 0 : release_ctrl_ocsp_certs (ctrl);
431 :
432 0 : if (signer_fpr_list && !signer_fpr_list->next)
433 : {
434 : /* There is exactly one signer fingerprint given. Thus we use
435 : the default OCSP responder's certificate and instantly know
436 : the certificate to use. */
437 0 : cert = get_cert_byhexfpr (signer_fpr_list->hexfpr);
438 0 : if (!cert)
439 0 : cert = get_cert_local (ctrl, signer_fpr_list->hexfpr);
440 0 : if (cert)
441 : {
442 0 : err = check_signature_core (ctrl, cert, s_sig, s_hash,
443 : signer_fpr_list);
444 0 : ksba_cert_release (cert);
445 0 : cert = NULL;
446 0 : if (!err)
447 : {
448 0 : gcry_sexp_release (s_hash);
449 0 : return 0; /* Successfully verified the signature. */
450 : }
451 : }
452 : }
453 : else
454 : {
455 : char *name;
456 : ksba_sexp_t keyid;
457 :
458 : /* Put all certificates included in the response into the cache
459 : and setup a list of those certificate which will later be
460 : preferred used when locating certificates. */
461 0 : for (cert_idx=0; (cert = ksba_ocsp_get_cert (ocsp, cert_idx));
462 0 : cert_idx++)
463 : {
464 : cert_ref_t cref;
465 :
466 0 : cref = xtrymalloc (sizeof *cref);
467 0 : if (!cref)
468 0 : log_error (_("allocating list item failed: %s\n"),
469 : gcry_strerror (err));
470 0 : else if (!cache_cert_silent (cert, &cref->fpr))
471 : {
472 0 : cref->next = ctrl->ocsp_certs;
473 0 : ctrl->ocsp_certs = cref;
474 : }
475 : else
476 0 : xfree (cref);
477 : }
478 :
479 : /* Get the certificate by means of the responder ID. */
480 0 : err = ksba_ocsp_get_responder_id (ocsp, &name, &keyid);
481 0 : if (err)
482 : {
483 0 : log_error (_("error getting responder ID: %s\n"),
484 : gcry_strerror (err));
485 0 : return err;
486 : }
487 0 : cert = find_cert_bysubject (ctrl, name, keyid);
488 0 : if (!cert)
489 : {
490 0 : log_error ("responder certificate ");
491 0 : if (name)
492 0 : log_printf ("'/%s' ", name);
493 0 : if (keyid)
494 : {
495 0 : log_printf ("{");
496 0 : dump_serial (keyid);
497 0 : log_printf ("} ");
498 : }
499 0 : log_printf ("not found\n");
500 : }
501 0 : ksba_free (name);
502 0 : ksba_free (keyid);
503 :
504 0 : if (cert)
505 : {
506 0 : err = check_signature_core (ctrl, cert, s_sig, s_hash,
507 : signer_fpr_list);
508 0 : ksba_cert_release (cert);
509 0 : if (!err)
510 : {
511 0 : gcry_sexp_release (s_hash);
512 0 : return 0; /* Successfully verified the signature. */
513 : }
514 : }
515 : }
516 :
517 0 : gcry_sexp_release (s_hash);
518 0 : log_error (_("no suitable certificate found to verify the OCSP response\n"));
519 0 : return gpg_error (GPG_ERR_NO_PUBKEY);
520 : }
521 :
522 :
523 : /* Check whether the certificate either given by fingerprint CERT_FPR
524 : or directly through the CERT object is valid by running an OCSP
525 : transaction. With FORCE_DEFAULT_RESPONDER set only the configured
526 : default responder is used. */
527 : gpg_error_t
528 0 : ocsp_isvalid (ctrl_t ctrl, ksba_cert_t cert, const char *cert_fpr,
529 : int force_default_responder)
530 : {
531 : gpg_error_t err;
532 0 : ksba_ocsp_t ocsp = NULL;
533 0 : ksba_cert_t issuer_cert = NULL;
534 0 : ksba_sexp_t sigval = NULL;
535 0 : gcry_sexp_t s_sig = NULL;
536 : ksba_isotime_t current_time;
537 : ksba_isotime_t this_update, next_update, revocation_time, produced_at;
538 : ksba_isotime_t tmp_time;
539 : ksba_status_t status;
540 : ksba_crl_reason_t reason;
541 0 : char *url_buffer = NULL;
542 : const char *url;
543 0 : gcry_md_hd_t md = NULL;
544 : int i, idx;
545 : char *oid;
546 : ksba_name_t name;
547 0 : fingerprint_list_t default_signer = NULL;
548 :
549 : /* Get the certificate. */
550 0 : if (cert)
551 : {
552 0 : ksba_cert_ref (cert);
553 :
554 0 : err = find_issuing_cert (ctrl, cert, &issuer_cert);
555 0 : if (err)
556 : {
557 0 : log_error (_("issuer certificate not found: %s\n"),
558 : gpg_strerror (err));
559 0 : goto leave;
560 : }
561 : }
562 : else
563 : {
564 0 : cert = get_cert_local (ctrl, cert_fpr);
565 0 : if (!cert)
566 : {
567 0 : log_error (_("caller did not return the target certificate\n"));
568 0 : err = gpg_error (GPG_ERR_GENERAL);
569 0 : goto leave;
570 : }
571 0 : issuer_cert = get_issuing_cert_local (ctrl, NULL);
572 0 : if (!issuer_cert)
573 : {
574 0 : log_error (_("caller did not return the issuing certificate\n"));
575 0 : err = gpg_error (GPG_ERR_GENERAL);
576 0 : goto leave;
577 : }
578 : }
579 :
580 : /* Create an OCSP instance. */
581 0 : err = ksba_ocsp_new (&ocsp);
582 0 : if (err)
583 : {
584 0 : log_error (_("failed to allocate OCSP context: %s\n"),
585 : gpg_strerror (err));
586 0 : goto leave;
587 : }
588 :
589 :
590 :
591 : /* Figure out the OCSP responder to use.
592 : 1. Try to get the reponder from the certificate.
593 : We do only take http and https style URIs into account.
594 : 2. If this fails use the default responder, if any.
595 : */
596 0 : url = NULL;
597 0 : for (idx=0; !url && !opt.ignore_ocsp_service_url && !force_default_responder
598 0 : && !(err=ksba_cert_get_authority_info_access (cert, idx,
599 0 : &oid, &name)); idx++)
600 : {
601 0 : if ( !strcmp (oid, oidstr_ocsp) )
602 : {
603 0 : for (i=0; !url && ksba_name_enum (name, i); i++)
604 : {
605 0 : char *p = ksba_name_get_uri (name, i);
606 0 : if (p && (!ascii_strncasecmp (p, "http:", 5)
607 0 : || !ascii_strncasecmp (p, "https:", 6)))
608 0 : url = url_buffer = p;
609 : else
610 0 : xfree (p);
611 : }
612 : }
613 0 : ksba_name_release (name);
614 0 : ksba_free (oid);
615 : }
616 0 : if (err && gpg_err_code (err) != GPG_ERR_EOF)
617 : {
618 0 : log_error (_("can't get authorityInfoAccess: %s\n"), gpg_strerror (err));
619 0 : goto leave;
620 : }
621 0 : if (!url)
622 : {
623 0 : if (!opt.ocsp_responder || !*opt.ocsp_responder)
624 : {
625 0 : log_info (_("no default OCSP responder defined\n"));
626 0 : err = gpg_error (GPG_ERR_CONFIGURATION);
627 0 : goto leave;
628 : }
629 0 : if (!opt.ocsp_signer)
630 : {
631 0 : log_info (_("no default OCSP signer defined\n"));
632 0 : err = gpg_error (GPG_ERR_CONFIGURATION);
633 0 : goto leave;
634 : }
635 0 : url = opt.ocsp_responder;
636 0 : default_signer = opt.ocsp_signer;
637 0 : if (opt.verbose)
638 0 : log_info (_("using default OCSP responder '%s'\n"), url);
639 : }
640 : else
641 : {
642 0 : if (opt.verbose)
643 0 : log_info (_("using OCSP responder '%s'\n"), url);
644 : }
645 :
646 : /* Ask the OCSP responder. */
647 0 : err = gcry_md_open (&md, GCRY_MD_SHA1, 0);
648 0 : if (err)
649 : {
650 0 : log_error (_("failed to establish a hashing context for OCSP: %s\n"),
651 : gpg_strerror (err));
652 0 : goto leave;
653 : }
654 0 : err = do_ocsp_request (ctrl, ocsp, md, url, cert, issuer_cert);
655 0 : if (err)
656 0 : goto leave;
657 :
658 : /* We got a useful answer, check that the answer has a valid signature. */
659 0 : sigval = ksba_ocsp_get_sig_val (ocsp, produced_at);
660 0 : if (!sigval || !*produced_at)
661 : {
662 0 : err = gpg_error (GPG_ERR_INV_OBJ);
663 0 : goto leave;
664 : }
665 0 : if ( (err = canon_sexp_to_gcry (sigval, &s_sig)) )
666 0 : goto leave;
667 0 : xfree (sigval);
668 0 : sigval = NULL;
669 0 : err = check_signature (ctrl, ocsp, s_sig, md, default_signer);
670 0 : if (err)
671 0 : goto leave;
672 :
673 : /* We only support one certificate per request. Check that the
674 : answer matches the right certificate. */
675 0 : err = ksba_ocsp_get_status (ocsp, cert,
676 : &status, this_update, next_update,
677 : revocation_time, &reason);
678 0 : if (err)
679 : {
680 0 : log_error (_("error getting OCSP status for target certificate: %s\n"),
681 : gpg_strerror (err));
682 0 : goto leave;
683 : }
684 :
685 : /* In case the certificate has been revoked, we better invalidate
686 : our cached validation status. */
687 0 : if (status == KSBA_STATUS_REVOKED)
688 : {
689 0 : time_t validated_at = 0; /* That is: No cached validation available. */
690 0 : err = ksba_cert_set_user_data (cert, "validated_at",
691 : &validated_at, sizeof (validated_at));
692 0 : if (err)
693 : {
694 0 : log_error ("set_user_data(validated_at) failed: %s\n",
695 : gpg_strerror (err));
696 0 : err = 0; /* The certificate is anyway revoked, and that is a
697 : more important message than the failure of our
698 : cache. */
699 : }
700 : }
701 :
702 :
703 0 : if (opt.verbose)
704 : {
705 0 : log_info (_("certificate status is: %s (this=%s next=%s)\n"),
706 0 : status == KSBA_STATUS_GOOD? _("good"):
707 0 : status == KSBA_STATUS_REVOKED? _("revoked"):
708 0 : status == KSBA_STATUS_UNKNOWN? _("unknown"):
709 0 : status == KSBA_STATUS_NONE? _("none"): "?",
710 : this_update, next_update);
711 0 : if (status == KSBA_STATUS_REVOKED)
712 0 : log_info (_("certificate has been revoked at: %s due to: %s\n"),
713 : revocation_time,
714 0 : reason == KSBA_CRLREASON_UNSPECIFIED? "unspecified":
715 0 : reason == KSBA_CRLREASON_KEY_COMPROMISE? "key compromise":
716 0 : reason == KSBA_CRLREASON_CA_COMPROMISE? "CA compromise":
717 0 : reason == KSBA_CRLREASON_AFFILIATION_CHANGED?
718 0 : "affiliation changed":
719 0 : reason == KSBA_CRLREASON_SUPERSEDED? "superseeded":
720 0 : reason == KSBA_CRLREASON_CESSATION_OF_OPERATION?
721 0 : "cessation of operation":
722 0 : reason == KSBA_CRLREASON_CERTIFICATE_HOLD?
723 0 : "certificate on hold":
724 0 : reason == KSBA_CRLREASON_REMOVE_FROM_CRL?
725 0 : "removed from CRL":
726 0 : reason == KSBA_CRLREASON_PRIVILEGE_WITHDRAWN?
727 0 : "privilege withdrawn":
728 0 : reason == KSBA_CRLREASON_AA_COMPROMISE? "AA compromise":
729 0 : reason == KSBA_CRLREASON_OTHER? "other":"?");
730 :
731 : }
732 :
733 :
734 0 : if (status == KSBA_STATUS_REVOKED)
735 0 : err = gpg_error (GPG_ERR_CERT_REVOKED);
736 0 : else if (status == KSBA_STATUS_UNKNOWN)
737 0 : err = gpg_error (GPG_ERR_NO_DATA);
738 0 : else if (status != KSBA_STATUS_GOOD)
739 0 : err = gpg_error (GPG_ERR_GENERAL);
740 :
741 : /* Allow for some clock skew. */
742 0 : gnupg_get_isotime (current_time);
743 0 : add_seconds_to_isotime (current_time, opt.ocsp_max_clock_skew);
744 :
745 0 : if (strcmp (this_update, current_time) > 0 )
746 : {
747 0 : log_error (_("OCSP responder returned a status in the future\n"));
748 0 : log_info ("used now: %s this_update: %s\n", current_time, this_update);
749 0 : if (!err)
750 0 : err = gpg_error (GPG_ERR_TIME_CONFLICT);
751 : }
752 :
753 : /* Check that THIS_UPDATE is not too far back in the past. */
754 0 : gnupg_copy_time (tmp_time, this_update);
755 0 : add_seconds_to_isotime (tmp_time,
756 0 : opt.ocsp_max_period+opt.ocsp_max_clock_skew);
757 0 : if (!*tmp_time || strcmp (tmp_time, current_time) < 0 )
758 : {
759 0 : log_error (_("OCSP responder returned a non-current status\n"));
760 0 : log_info ("used now: %s this_update: %s\n",
761 : current_time, this_update);
762 0 : if (!err)
763 0 : err = gpg_error (GPG_ERR_TIME_CONFLICT);
764 : }
765 :
766 : /* Check that we are not beyound NEXT_UPDATE (plus some extra time). */
767 0 : if (*next_update)
768 : {
769 0 : gnupg_copy_time (tmp_time, next_update);
770 0 : add_seconds_to_isotime (tmp_time,
771 0 : opt.ocsp_current_period+opt.ocsp_max_clock_skew);
772 0 : if (!*tmp_time && strcmp (tmp_time, current_time) < 0 )
773 : {
774 0 : log_error (_("OCSP responder returned an too old status\n"));
775 0 : log_info ("used now: %s next_update: %s\n",
776 : current_time, next_update);
777 0 : if (!err)
778 0 : err = gpg_error (GPG_ERR_TIME_CONFLICT);
779 : }
780 : }
781 :
782 :
783 : leave:
784 0 : gcry_md_close (md);
785 0 : gcry_sexp_release (s_sig);
786 0 : xfree (sigval);
787 0 : ksba_cert_release (issuer_cert);
788 0 : ksba_cert_release (cert);
789 0 : ksba_ocsp_release (ocsp);
790 0 : xfree (url_buffer);
791 0 : return err;
792 : }
793 :
794 :
795 : /* Release the list of OCSP certificates hold in the CTRL object. */
796 : void
797 0 : release_ctrl_ocsp_certs (ctrl_t ctrl)
798 : {
799 0 : while (ctrl->ocsp_certs)
800 : {
801 0 : cert_ref_t tmp = ctrl->ocsp_certs->next;
802 0 : xfree (ctrl->ocsp_certs);
803 0 : ctrl->ocsp_certs = tmp;
804 : }
805 0 : }
|