Make it build on W32 again.
[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 #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
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
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
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
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
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
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   gnupg_get_isotime (current_time);
737   add_seconds_to_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   gnupg_copy_time (tmp_time, this_update);
749   add_seconds_to_isotime (tmp_time,
750                           opt.ocsp_max_period+opt.ocsp_max_clock_skew);
751   if (!*tmp_time || strcmp (tmp_time, current_time) < 0 )
752     {
753       log_error (_("OCSP responder returned a non-current status\n"));
754       log_info ("used now: %s  this_update: %s\n", 
755                 current_time, this_update);
756       if (!err)
757         err = gpg_error (GPG_ERR_TIME_CONFLICT);
758     }
759
760   /* Check that we are not beyound NEXT_UPDATE  (plus some extra time). */
761   if (*next_update)
762     {
763       gnupg_copy_time (tmp_time, next_update);
764       add_seconds_to_isotime (tmp_time,
765                               opt.ocsp_current_period+opt.ocsp_max_clock_skew);
766       if (!*tmp_time && strcmp (tmp_time, current_time) < 0 )
767         {
768           log_error (_("OCSP responder returned an too old status\n"));
769           log_info ("used now: %s  next_update: %s\n", 
770                     current_time, next_update);
771           if (!err)
772             err = gpg_error (GPG_ERR_TIME_CONFLICT);
773         }
774     }
775
776
777  leave:
778   gcry_md_close (md);
779   gcry_sexp_release (s_sig);
780   xfree (sigval);
781   ksba_cert_release (issuer_cert);
782   ksba_cert_release (cert);
783   ksba_ocsp_release (ocsp);
784   xfree (url_buffer);
785   return err;
786 }
787
788
789 /* Release the list of OCSP certificates hold in the CTRL object. */
790 void
791 release_ctrl_ocsp_certs (ctrl_t ctrl)
792 {
793   while (ctrl->ocsp_certs)
794     {
795       cert_ref_t tmp = ctrl->ocsp_certs->next;
796       xfree (ctrl->ocsp_certs);
797       ctrl->ocsp_certs = tmp;
798     }
799 }