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