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