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