chiark / gitweb /
asshelp.c: add a lot of debug logging
[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                    ctrl->http_proxy, NULL, NULL, NULL);
179   if (err)
180     {
181       log_error (_("error connecting to '%s': %s\n"), url, gpg_strerror (err));
182       xfree (free_this);
183       return err;
184     }
185
186   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   http_start_data (http);
191   if (es_fwrite (request, requestlen, 1, http_get_write_ptr (http)) != 1)
192     {
193       err = gpg_error_from_errno (errno);
194       log_error ("error sending request to '%s': %s\n", url, strerror (errno));
195       http_close (http, 0);
196       xfree (request);
197       xfree (free_this);
198       return err;
199     }
200   xfree (request);
201   request = NULL;
202
203   err = http_wait_response (http);
204   if (err || http_get_status_code (http) != 200)
205     {
206       if (err)
207         log_error (_("error reading HTTP response for '%s': %s\n"),
208                    url, gpg_strerror (err));
209       else
210         {
211           switch (http_get_status_code (http))
212             {
213             case 301:
214             case 302:
215               {
216                 const char *s = http_get_header (http, "Location");
217
218                 log_info (_("URL '%s' redirected to '%s' (%u)\n"),
219                           url, s?s:"[none]", http_get_status_code (http));
220                 if (s && *s && redirects_left-- )
221                   {
222                     xfree (free_this); url = NULL;
223                     free_this = xtrystrdup (s);
224                     if (!free_this)
225                       err = gpg_error_from_errno (errno);
226                     else
227                       {
228                         url = free_this;
229                         http_close (http, 0);
230                         goto once_more;
231                       }
232                   }
233                 else
234                   err = gpg_error (GPG_ERR_NO_DATA);
235                 log_error (_("too many redirections\n"));
236               }
237               break;
238
239             default:
240               log_error (_("error accessing '%s': http status %u\n"),
241                          url, http_get_status_code (http));
242               err = gpg_error (GPG_ERR_NO_DATA);
243               break;
244             }
245         }
246       http_close (http, 0);
247       xfree (free_this);
248       return err;
249     }
250
251   err = read_response (http_get_read_ptr (http), &response, &responselen);
252   http_close (http, 0);
253   if (err)
254     {
255       log_error (_("error reading HTTP response for '%s': %s\n"),
256                  url, gpg_strerror (err));
257       xfree (free_this);
258       return err;
259     }
260
261   err = ksba_ocsp_parse_response (ocsp, response, responselen,
262                                   &response_status);
263   if (err)
264     {
265       log_error (_("error parsing OCSP response for '%s': %s\n"),
266                  url, gpg_strerror (err));
267       xfree (response);
268       xfree (free_this);
269       return err;
270     }
271
272   switch (response_status)
273     {
274     case KSBA_OCSP_RSPSTATUS_SUCCESS:      t = "success"; break;
275     case KSBA_OCSP_RSPSTATUS_MALFORMED:    t = "malformed"; break;
276     case KSBA_OCSP_RSPSTATUS_INTERNAL:     t = "internal error"; break;
277     case KSBA_OCSP_RSPSTATUS_TRYLATER:     t = "try later"; break;
278     case KSBA_OCSP_RSPSTATUS_SIGREQUIRED:  t = "must sign request"; break;
279     case KSBA_OCSP_RSPSTATUS_UNAUTHORIZED: t = "unauthorized"; break;
280     case KSBA_OCSP_RSPSTATUS_REPLAYED:     t = "replay detected"; break;
281     case KSBA_OCSP_RSPSTATUS_OTHER:        t = "other (unknown)"; break;
282     case KSBA_OCSP_RSPSTATUS_NONE:         t = "no status"; break;
283     default:                               t = "[unknown status]"; break;
284     }
285   if (response_status == KSBA_OCSP_RSPSTATUS_SUCCESS)
286     {
287       if (opt.verbose)
288         log_info (_("OCSP responder at '%s' status: %s\n"), url, t);
289
290       err = ksba_ocsp_hash_response (ocsp, response, responselen,
291                                      HASH_FNC, md);
292       if (err)
293         log_error (_("hashing the OCSP response for '%s' failed: %s\n"),
294                    url, gpg_strerror (err));
295     }
296   else
297     {
298       log_error (_("OCSP responder at '%s' status: %s\n"), url, t);
299       err = gpg_error (GPG_ERR_GENERAL);
300     }
301
302   xfree (response);
303   xfree (free_this);
304   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 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   if (signer_fpr_list)
319     {
320       fpr = get_fingerprint_hexstring (cert);
321       for (; signer_fpr_list && strcmp (signer_fpr_list->hexfpr, fpr);
322            signer_fpr_list = signer_fpr_list->next)
323         ;
324       if (signer_fpr_list)
325         err = 0;
326       else
327         {
328           log_error (_("not signed by a default OCSP signer's certificate"));
329           err = gpg_error (GPG_ERR_BAD_CA_CERT);
330         }
331       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       fpr = get_fingerprint_hexstring (cert);
352       dirmngr_status (ctrl, "ONLY_VALID_IF_CERT_VALID", fpr, NULL);
353       xfree (fpr);
354       err = 0;
355     }
356
357   return err;
358 }
359
360
361 /* Helper for check_signature. */
362 static int
363 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   gcry_sexp_t s_pkey = NULL;
369
370   pubkey = ksba_cert_get_public_key (cert);
371   if (!pubkey)
372     err = gpg_error (GPG_ERR_INV_OBJ);
373   else
374     err = canon_sexp_to_gcry (pubkey, &s_pkey);
375   xfree (pubkey);
376   if (!err)
377     err = gcry_pk_verify (s_sig, s_hash, s_pkey);
378   if (!err)
379     err = validate_responder_cert (ctrl, cert, signer_fpr_list);
380   if (!err)
381     {
382       gcry_sexp_release (s_pkey);
383       return 0; /* Successfully verified the signature. */
384     }
385
386   /* We simply ignore all errors. */
387   gcry_sexp_release (s_pkey);
388   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 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   gcry_md_final (md);
410   algo = gcry_md_get_algo (md);
411   if (algo != GCRY_MD_SHA1 )
412     {
413       log_error (_("only SHA-1 is supported for OCSP responses\n"));
414       return gpg_error (GPG_ERR_DIGEST_ALGO);
415     }
416   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   if (err)
420     {
421       log_error (_("creating S-expression failed: %s\n"), gcry_strerror (err));
422       return err;
423     }
424
425   /* Get rid of old OCSP specific certificate references. */
426   release_ctrl_ocsp_certs (ctrl);
427
428   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       cert = get_cert_byhexfpr (signer_fpr_list->hexfpr);
434       if (!cert)
435         cert = get_cert_local (ctrl, signer_fpr_list->hexfpr);
436       if (cert)
437         {
438           err = check_signature_core (ctrl, cert, s_sig, s_hash,
439                                       signer_fpr_list);
440           ksba_cert_release (cert);
441           cert = NULL;
442           if (!err)
443             {
444               gcry_sexp_release (s_hash);
445               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       for (cert_idx=0; (cert = ksba_ocsp_get_cert (ocsp, cert_idx));
458            cert_idx++)
459         {
460           cert_ref_t cref;
461
462           cref = xtrymalloc (sizeof *cref);
463           if (!cref)
464             log_error (_("allocating list item failed: %s\n"),
465                        gcry_strerror (err));
466           else if (!cache_cert_silent (cert, &cref->fpr))
467             {
468               cref->next = ctrl->ocsp_certs;
469               ctrl->ocsp_certs = cref;
470             }
471           else
472             xfree (cref);
473         }
474
475       /* Get the certificate by means of the responder ID. */
476       err = ksba_ocsp_get_responder_id (ocsp, &name, &keyid);
477       if (err)
478         {
479           log_error (_("error getting responder ID: %s\n"),
480                      gcry_strerror (err));
481           return err;
482         }
483       cert = find_cert_bysubject (ctrl, name, keyid);
484       if (!cert)
485         {
486           log_error ("responder certificate ");
487           if (name)
488             log_printf ("'/%s' ", name);
489           if (keyid)
490             {
491               log_printf ("{");
492               dump_serial (keyid);
493               log_printf ("} ");
494             }
495           log_printf ("not found\n");
496         }
497       ksba_free (name);
498       ksba_free (keyid);
499
500       if (cert)
501         {
502           err = check_signature_core (ctrl, cert, s_sig, s_hash,
503                                       signer_fpr_list);
504           ksba_cert_release (cert);
505           if (!err)
506             {
507               gcry_sexp_release (s_hash);
508               return 0; /* Successfully verified the signature. */
509             }
510         }
511     }
512
513   gcry_sexp_release (s_hash);
514   log_error (_("no suitable certificate found to verify the OCSP response\n"));
515   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 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   ksba_ocsp_t ocsp = NULL;
529   ksba_cert_t issuer_cert = NULL;
530   ksba_sexp_t sigval = NULL;
531   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   char *url_buffer = NULL;
538   const char *url;
539   gcry_md_hd_t md = NULL;
540   int i, idx;
541   char *oid;
542   ksba_name_t name;
543   fingerprint_list_t default_signer = NULL;
544
545   /* Get the certificate.  */
546   if (cert)
547     {
548       ksba_cert_ref (cert);
549
550       err = find_issuing_cert (ctrl, cert, &issuer_cert);
551       if (err)
552         {
553           log_error (_("issuer certificate not found: %s\n"),
554                      gpg_strerror (err));
555           goto leave;
556         }
557     }
558   else
559     {
560       cert = get_cert_local (ctrl, cert_fpr);
561       if (!cert)
562         {
563           log_error (_("caller did not return the target certificate\n"));
564           err = gpg_error (GPG_ERR_GENERAL);
565           goto leave;
566         }
567       issuer_cert = get_issuing_cert_local (ctrl, NULL);
568       if (!issuer_cert)
569         {
570           log_error (_("caller did not return the issuing certificate\n"));
571           err = gpg_error (GPG_ERR_GENERAL);
572           goto leave;
573         }
574     }
575
576   /* Create an OCSP instance.  */
577   err = ksba_ocsp_new (&ocsp);
578   if (err)
579     {
580       log_error (_("failed to allocate OCSP context: %s\n"),
581                  gpg_strerror (err));
582       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   url = NULL;
593   for (idx=0; !url && !opt.ignore_ocsp_service_url && !force_default_responder
594          && !(err=ksba_cert_get_authority_info_access (cert, idx,
595                                                        &oid, &name)); idx++)
596     {
597       if ( !strcmp (oid, oidstr_ocsp) )
598         {
599           for (i=0; !url && ksba_name_enum (name, i); i++)
600             {
601               char *p = ksba_name_get_uri (name, i);
602               if (p && (!ascii_strncasecmp (p, "http:", 5)
603                         || !ascii_strncasecmp (p, "https:", 6)))
604                 url = url_buffer = p;
605               else
606                 xfree (p);
607             }
608         }
609       ksba_name_release (name);
610       ksba_free (oid);
611     }
612   if (err && gpg_err_code (err) != GPG_ERR_EOF)
613     {
614       log_error (_("can't get authorityInfoAccess: %s\n"), gpg_strerror (err));
615       goto leave;
616     }
617   if (!url)
618     {
619       if (!opt.ocsp_responder || !*opt.ocsp_responder)
620         {
621           log_info (_("no default OCSP responder defined\n"));
622           err = gpg_error (GPG_ERR_CONFIGURATION);
623           goto leave;
624         }
625       if (!opt.ocsp_signer)
626         {
627           log_info (_("no default OCSP signer defined\n"));
628           err = gpg_error (GPG_ERR_CONFIGURATION);
629           goto leave;
630         }
631       url = opt.ocsp_responder;
632       default_signer = opt.ocsp_signer;
633       if (opt.verbose)
634         log_info (_("using default OCSP responder '%s'\n"), url);
635     }
636   else
637     {
638       if (opt.verbose)
639         log_info (_("using OCSP responder '%s'\n"), url);
640     }
641
642   /* Ask the OCSP responder. */
643   err = gcry_md_open (&md, GCRY_MD_SHA1, 0);
644   if (err)
645     {
646       log_error (_("failed to establish a hashing context for OCSP: %s\n"),
647                  gpg_strerror (err));
648       goto leave;
649     }
650   err = do_ocsp_request (ctrl, ocsp, md, url, cert, issuer_cert);
651   if (err)
652     goto leave;
653
654   /* We got a useful answer, check that the answer has a valid signature. */
655   sigval = ksba_ocsp_get_sig_val (ocsp, produced_at);
656   if (!sigval || !*produced_at)
657     {
658       err = gpg_error (GPG_ERR_INV_OBJ);
659       goto leave;
660     }
661   if ( (err = canon_sexp_to_gcry (sigval, &s_sig)) )
662     goto leave;
663   xfree (sigval);
664   sigval = NULL;
665   err = check_signature (ctrl, ocsp, s_sig, md, default_signer);
666   if (err)
667     goto leave;
668
669   /* We only support one certificate per request.  Check that the
670      answer matches the right certificate. */
671   err = ksba_ocsp_get_status (ocsp, cert,
672                               &status, this_update, next_update,
673                               revocation_time, &reason);
674   if (err)
675     {
676       log_error (_("error getting OCSP status for target certificate: %s\n"),
677                  gpg_strerror (err));
678       goto leave;
679     }
680
681   /* In case the certificate has been revoked, we better invalidate
682      our cached validation status. */
683   if (status == KSBA_STATUS_REVOKED)
684     {
685       time_t validated_at = 0; /* That is: No cached validation available. */
686       err = ksba_cert_set_user_data (cert, "validated_at",
687                                      &validated_at, sizeof (validated_at));
688       if (err)
689         {
690           log_error ("set_user_data(validated_at) failed: %s\n",
691                      gpg_strerror (err));
692           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   if (opt.verbose)
700     {
701       log_info (_("certificate status is: %s  (this=%s  next=%s)\n"),
702                 status == KSBA_STATUS_GOOD? _("good"):
703                 status == KSBA_STATUS_REVOKED? _("revoked"):
704                 status == KSBA_STATUS_UNKNOWN? _("unknown"):
705                 status == KSBA_STATUS_NONE? _("none"): "?",
706                 this_update, next_update);
707       if (status == KSBA_STATUS_REVOKED)
708         log_info (_("certificate has been revoked at: %s due to: %s\n"),
709                   revocation_time,
710                   reason == KSBA_CRLREASON_UNSPECIFIED?   "unspecified":
711                   reason == KSBA_CRLREASON_KEY_COMPROMISE? "key compromise":
712                   reason == KSBA_CRLREASON_CA_COMPROMISE?   "CA compromise":
713                   reason == KSBA_CRLREASON_AFFILIATION_CHANGED?
714                                                       "affiliation changed":
715                   reason == KSBA_CRLREASON_SUPERSEDED?   "superseded":
716                   reason == KSBA_CRLREASON_CESSATION_OF_OPERATION?
717                                                   "cessation of operation":
718                   reason == KSBA_CRLREASON_CERTIFICATE_HOLD?
719                                                   "certificate on hold":
720                   reason == KSBA_CRLREASON_REMOVE_FROM_CRL?
721                                                   "removed from CRL":
722                   reason == KSBA_CRLREASON_PRIVILEGE_WITHDRAWN?
723                                                   "privilege withdrawn":
724                   reason == KSBA_CRLREASON_AA_COMPROMISE? "AA compromise":
725                   reason == KSBA_CRLREASON_OTHER?   "other":"?");
726
727     }
728
729
730   if (status == KSBA_STATUS_REVOKED)
731     err = gpg_error (GPG_ERR_CERT_REVOKED);
732   else if (status == KSBA_STATUS_UNKNOWN)
733     err = gpg_error (GPG_ERR_NO_DATA);
734   else if (status != KSBA_STATUS_GOOD)
735     err = gpg_error (GPG_ERR_GENERAL);
736
737   /* Allow for some clock skew. */
738   gnupg_get_isotime (current_time);
739   add_seconds_to_isotime (current_time, opt.ocsp_max_clock_skew);
740
741   if (strcmp (this_update, current_time) > 0 )
742     {
743       log_error (_("OCSP responder returned a status in the future\n"));
744       log_info ("used now: %s  this_update: %s\n", current_time, this_update);
745       if (!err)
746         err = gpg_error (GPG_ERR_TIME_CONFLICT);
747     }
748
749   /* Check that THIS_UPDATE is not too far back in the past. */
750   gnupg_copy_time (tmp_time, this_update);
751   add_seconds_to_isotime (tmp_time,
752                           opt.ocsp_max_period+opt.ocsp_max_clock_skew);
753   if (!*tmp_time || strcmp (tmp_time, current_time) < 0 )
754     {
755       log_error (_("OCSP responder returned a non-current status\n"));
756       log_info ("used now: %s  this_update: %s\n",
757                 current_time, this_update);
758       if (!err)
759         err = gpg_error (GPG_ERR_TIME_CONFLICT);
760     }
761
762   /* Check that we are not beyound NEXT_UPDATE  (plus some extra time). */
763   if (*next_update)
764     {
765       gnupg_copy_time (tmp_time, next_update);
766       add_seconds_to_isotime (tmp_time,
767                               opt.ocsp_current_period+opt.ocsp_max_clock_skew);
768       if (!*tmp_time && strcmp (tmp_time, current_time) < 0 )
769         {
770           log_error (_("OCSP responder returned an too old status\n"));
771           log_info ("used now: %s  next_update: %s\n",
772                     current_time, next_update);
773           if (!err)
774             err = gpg_error (GPG_ERR_TIME_CONFLICT);
775         }
776     }
777
778
779  leave:
780   gcry_md_close (md);
781   gcry_sexp_release (s_sig);
782   xfree (sigval);
783   ksba_cert_release (issuer_cert);
784   ksba_cert_release (cert);
785   ksba_ocsp_release (ocsp);
786   xfree (url_buffer);
787   return err;
788 }
789
790
791 /* Release the list of OCSP certificates hold in the CTRL object. */
792 void
793 release_ctrl_ocsp_certs (ctrl_t ctrl)
794 {
795   while (ctrl->ocsp_certs)
796     {
797       cert_ref_t tmp = ctrl->ocsp_certs->next;
798       xfree (ctrl->ocsp_certs);
799       ctrl->ocsp_certs = tmp;
800     }
801 }