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