libksba  1.6.0
About: KSBA is a library to make the tasks of working with X.509 certificates, CMS data and related objects more easy.
  Fossies Dox: libksba-1.6.0.tar.bz2  ("unofficial" and yet experimental doxygen-generated source code documentation)  

ocsp.c
Go to the documentation of this file.
1 /* ocsp.c - OCSP (rfc2560)
2  * Copyright (C) 2003, 2004, 2005, 2006, 2012 g10 Code GmbH
3  *
4  * This file is part of KSBA.
5  *
6  * KSBA is free software; you can redistribute it and/or modify
7  * it under the terms of either
8  *
9  * - the GNU Lesser General Public License as published by the Free
10  * Software Foundation; either version 3 of the License, or (at
11  * your option) any later version.
12  *
13  * or
14  *
15  * - the GNU General Public License as published by the Free
16  * Software Foundation; either version 2 of the License, or (at
17  * your option) any later version.
18  *
19  * or both in parallel, as here.
20  *
21  * KSBA is distributed in the hope that it will be useful, but WITHOUT
22  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
23  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
24  * License for more details.
25  *
26  * You should have received a copies of the GNU General Public License
27  * and the GNU Lesser General Public License along with this program;
28  * if not, see <http://www.gnu.org/licenses/>.
29  */
30 
31 #include <config.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <assert.h>
36 
37 #include "util.h"
38 
39 #include "cert.h"
40 #include "convert.h"
41 #include "keyinfo.h"
42 #include "der-encoder.h"
43 #include "ber-help.h"
44 #include "ocsp.h"
45 
46 
47 static const char oidstr_sha1[] = "1.3.14.3.2.26";
48 static const char oidstr_ocsp_basic[] = "1.3.6.1.5.5.7.48.1.1";
49 static const char oidstr_ocsp_nonce[] = "1.3.6.1.5.5.7.48.1.2";
50 
51 
52 #if 0
53 static void
54 dump_hex (const unsigned char *p, size_t n)
55 {
56  if (!p)
57  fputs ("none", stderr);
58  else
59  {
60  for (; n; n--, p++)
61  fprintf (stderr, " %02X", *p);
62  }
63 }
64 #endif
65 
66 ␌
67 /* Create a new OCSP object and retrun it in R_OCSP. Return 0 on
68  success or an error code.
69  */
70 gpg_error_t
72 {
73  *r_ocsp = xtrycalloc (1, sizeof **r_ocsp);
74  if (!*r_ocsp)
75  return gpg_error_from_syserror ();
76  return 0;
77 }
78 
79 
80 static void
82 {
83  while (cl)
84  {
85  struct ocsp_certlist_s *tmp = cl->next;
86  ksba_cert_release (cl->cert);
87  xfree (cl);
88  cl = tmp;
89  }
90 }
91 
92 
93 static void
95 {
96  while (ex)
97  {
98  struct ocsp_extension_s *tmp = ex->next;
99  xfree (ex);
100  ex = tmp;
101  }
102 }
103 
104 
105 /* Release the OCSP object and all its resources. Passing NULL for
106  OCSP is a valid nop. */
107 void
109 {
110  struct ocsp_reqitem_s *ri;
111 
112  if (!ocsp)
113  return;
114  xfree (ocsp->digest_oid);
115  xfree (ocsp->request_buffer);
116  for (; (ri=ocsp->requestlist); ri = ocsp->requestlist )
117  {
118  ocsp->requestlist = ri->next;
119  ksba_cert_release (ri->cert);
122  xfree (ri->serialno);
123  }
124  xfree (ocsp->sigval);
125  xfree (ocsp->responder_id.name);
126  xfree (ocsp->responder_id.keyid);
129  xfree (ocsp);
130 }
131 
132 
133 
134 /* Set the hash algorithm to be used for signing the request to OID.
135  Using this function will force the creation of a signed
136  request. */
137 gpg_error_t
139 {
140  if (!ocsp || !oid || !*oid)
141  return gpg_error (GPG_ERR_INV_VALUE);
142  if (ocsp->digest_oid)
143  xfree (ocsp->digest_oid);
144  ocsp->digest_oid = xtrystrdup (oid);
145  if (!ocsp->digest_oid)
146  return gpg_error_from_syserror ();
147  return 0;
148 }
149 
150 
151 gpg_error_t
153 {
154  (void)ocsp;
155  (void)cert;
156  return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
157 }
158 
159 
160 /* Add the certificate CERT for which the status is to be requested
161  and it's issuer certificate ISSUER_CERT to the context. This
162  function may be called multiple time to create a list of targets to
163  get combined into one actual request. */
164 gpg_error_t
167 {
168  struct ocsp_reqitem_s *ri;
169 
170  if (!ocsp || !cert || !issuer_cert)
171  return gpg_error (GPG_ERR_INV_VALUE);
172 
173  ri = xtrycalloc (1, sizeof *ri);
174  if (!ri)
175  return gpg_error_from_syserror ();
177  ri->cert = cert;
179  ri->issuer_cert = issuer_cert;
180 
181  ri->next = ocsp->requestlist;
182  ocsp->requestlist = ri;
183 
184  return 0;
185 }
186 
187 
188 /* Set the nonce to be used for the request to the content of the
189  buffer NONCE of size NONCELEN. Libksba may have an upper limit of
190  the allowed size of the nonce; if the supplied nonce is larger it
191  will be truncated and the actual used length of the nonce returned.
192  To detect the implementation limit (which should be considered as a
193  good suggestion), the function may be called with NULL for NONCE,
194  in which case the maximal usable noncelength is returned. The
195  function returns the length of the nonce which will be used. */
196 size_t
197 ksba_ocsp_set_nonce (ksba_ocsp_t ocsp, unsigned char *nonce, size_t noncelen)
198 {
199  if (!ocsp)
200  return 0;
201  if (!nonce)
202  return sizeof ocsp->nonce;
203  if (noncelen > sizeof ocsp->nonce)
204  noncelen = sizeof ocsp->nonce;
205  if (noncelen)
206  {
207  memcpy (ocsp->nonce, nonce, noncelen);
208  }
209  ocsp->noncelen = noncelen;
210  return noncelen;
211 }
212 
213 
214 /* Compute the SHA-1 nameHash for the certificate CERT and put it in
215  the buffer SHA1_BUFFER which must have been allocated to at least
216  20 bytes. */
217 static gpg_error_t
218 issuer_name_hash (ksba_cert_t cert, unsigned char *sha1_buffer)
219 {
220  gpg_error_t err;
221  const unsigned char *ptr;
222  size_t length, dummy;
223 
224  err = _ksba_cert_get_subject_dn_ptr (cert, &ptr, &length);
225  if (!err)
226  {
227  err = _ksba_hash_buffer (NULL, ptr, length, 20, sha1_buffer, &dummy);
228  if (!err && dummy != 20)
229  err = gpg_error (GPG_ERR_BUG);
230  }
231  return err;
232 }
233 
234 /* Compute the SHA-1 hash of the public key of CERT and put it in teh
235  buffer SHA1_BUFFER which must have been allocated with at least 20
236  bytes. */
237 static gpg_error_t
238 issuer_key_hash (ksba_cert_t cert, unsigned char *sha1_buffer)
239 {
240  gpg_error_t err;
241  const unsigned char *ptr;
242  size_t length, dummy;
243 
244  err = _ksba_cert_get_public_key_ptr (cert, &ptr, &length);
245  if (!err)
246  {
247  err = _ksba_hash_buffer (NULL, ptr, length, 20, sha1_buffer, &dummy);
248  if (!err && dummy != 20)
249  err = gpg_error (GPG_ERR_BUG);
250  }
251  return err;
252 }
253 
254 
255 /* Write the extensions for a request to WOUT. */
256 static gpg_error_t
258 {
259  gpg_error_t err;
260  unsigned char *buf;
261  size_t buflen;
262  unsigned char *p;
263  size_t derlen;
264  ksba_writer_t w1 = NULL;
265  ksba_writer_t w2 = NULL;
266 
267  if (!ocsp->noncelen)
268  return 0; /* We do only support the nonce extension. */
269 
270  /* Create writer objects for construction of the extension. */
271  err = ksba_writer_new (&w2);
272  if (!err)
273  err = ksba_writer_set_mem (w2, 256);
274  if (!err)
275  err = ksba_writer_new (&w1);
276  if (!err)
277  err = ksba_writer_set_mem (w1, 256);
278  if (err)
279  goto leave;
280 
281  /* Write OID and and nonce. */
282  err = ksba_oid_from_str (oidstr_ocsp_nonce, &buf, &buflen);
283  if (err)
284  goto leave;
285  err = _ksba_ber_write_tl (w1, TYPE_OBJECT_ID, CLASS_UNIVERSAL, 0, buflen);
286  if (!err)
287  err = ksba_writer_write (w1, buf, buflen);
288  xfree (buf); buf = NULL;
289  /* We known that the nonce is short enough to put the tag into 2 bytes, thus
290  we write the encapsulating octet string directly with a fixed length. */
291  if (!err)
293  2+ocsp->noncelen);
294  if (!err)
296  ocsp->noncelen);
297  if (!err)
298  err = ksba_writer_write (w1, ocsp->nonce, ocsp->noncelen);
299 
300  /* Put a sequence around. */
301  p = ksba_writer_snatch_mem (w1, &derlen);
302  if (!p)
303  {
304  err = ksba_writer_error (w1);
305  goto leave;
306  }
308  if (!err)
309  err = ksba_writer_write (w2, p, derlen);
310  xfree (p); p = NULL;
311 
312  /* Put the sequence around all extensions. */
313  err = ksba_writer_set_mem (w1, 256);
314  if (err)
315  goto leave;
316  p = ksba_writer_snatch_mem (w2, &derlen);
317  if (!p)
318  {
319  err = ksba_writer_error (w2);
320  goto leave;
321  }
323  if (!err)
324  err = ksba_writer_write (w1, p, derlen);
325  xfree (p); p = NULL;
326 
327  /* And put a context tag around everything. */
328  p = ksba_writer_snatch_mem (w1, &derlen);
329  if (!p)
330  {
331  err = ksba_writer_error (w1);
332  goto leave;
333  }
334  err = _ksba_ber_write_tl (wout, 2, CLASS_CONTEXT, 1, derlen);
335  if (!err)
336  err = ksba_writer_write (wout, p, derlen);
337  xfree (p); p = NULL;
338 
339 
340  leave:
341  ksba_writer_release (w2);
342  ksba_writer_release (w1);
343  return err;
344 }
345 
346 
347 /* Build a request from the current context. The function checks that
348  all necessary information have been set and stores the prepared
349  request in the context. A subsequent ksba_ocsp_build_request may
350  then be used to retrieve this request. Optional the requestmay be
351  signed beofre calling ksba_ocsp_build_request.
352  */
353 gpg_error_t
355 {
356  gpg_error_t err;
357  struct ocsp_reqitem_s *ri;
358  unsigned char *p;
359  const unsigned char *der;
360  size_t derlen;
361  ksba_writer_t w1 = NULL;
362  ksba_writer_t w2 = NULL;
363  ksba_writer_t w3 = NULL;
364  ksba_writer_t w4, w5, w6, w7; /* Used as aliases. */
365 
366  if (!ocsp)
367  return gpg_error (GPG_ERR_INV_VALUE);
368 
369  xfree (ocsp->request_buffer);
370  ocsp->request_buffer = NULL;
371  ocsp->request_buflen = 0;
372 
373  if (!ocsp->requestlist)
374  return gpg_error (GPG_ERR_MISSING_ACTION);
375 
376  /* Create three writer objects for construction of the request. */
377  err = ksba_writer_new (&w3);
378  if (!err)
379  err = ksba_writer_set_mem (w3, 2048);
380  if (!err)
381  err = ksba_writer_new (&w2);
382  if (!err)
383  err = ksba_writer_new (&w1);
384  if (err)
385  goto leave;
386 
387 
388  /* Loop over all single requests. */
389  for (ri=ocsp->requestlist; ri; ri = ri->next)
390  {
391  err = ksba_writer_set_mem (w2, 256);
392  if (!err)
393  err = ksba_writer_set_mem (w1, 256);
394  if (err)
395  goto leave;
396 
397  /* Write the AlgorithmIdentifier. */
399  if (err)
400  goto leave;
401 
402  /* Compute the issuerNameHash and write it into the CertID object. */
404  if (!err)
406  if (!err)
407  err = ksba_writer_write (w1, ri->issuer_name_hash, 20);
408  if(err)
409  goto leave;
410 
411  /* Compute the issuerKeyHash and write it. */
413  if (!err)
415  if (!err)
416  err = ksba_writer_write (w1, ri->issuer_key_hash, 20);
417  if (err)
418  goto leave;
419 
420  /* Write the serialNumber of the certificate to be checked. */
421  err = _ksba_cert_get_serial_ptr (ri->cert, &der, &derlen);
422  if (!err)
423  err = ksba_writer_write (w1, der, derlen);
424  if (err)
425  goto leave;
426  xfree (ri->serialno);
427  ri->serialno = xtrymalloc (derlen);
428  if (!ri->serialno)
429  {
430  err = gpg_error_from_syserror ();
431  goto leave;
432  }
433  memcpy (ri->serialno, der, derlen);
434  ri->serialnolen = derlen;
435 
436 
437  /* Now write it out as a sequence to the outer certID object. */
438  p = ksba_writer_snatch_mem (w1, &derlen);
439  if (!p)
440  {
441  err = ksba_writer_error (w1);
442  goto leave;
443  }
445  1, derlen);
446  if (!err)
447  err = ksba_writer_write (w2, p, derlen);
448  xfree (p); p = NULL;
449  if (err)
450  goto leave;
451 
452  /* Here we would write singleRequestExtensions. */
453 
454  /* Now write it out as a sequence to the outer Request object. */
455  p = ksba_writer_snatch_mem (w2, &derlen);
456  if (!p)
457  {
458  err = ksba_writer_error (w2);
459  goto leave;
460  }
462  1, derlen);
463  if (!err)
464  err = ksba_writer_write (w3, p, derlen);
465  xfree (p); p = NULL;
466  if (err)
467  goto leave;
468 
469  } /* End of looping over single requests. */
470 
471  /* Reuse writers; for clarity, use new names. */
472  w4 = w1;
473  w5 = w2;
474  err = ksba_writer_set_mem (w4, 2048);
475  if (!err)
476  err = ksba_writer_set_mem (w5, 2048);
477  if (err)
478  goto leave;
479 
480  /* Put a sequence tag before the requestList. */
481  p = ksba_writer_snatch_mem (w3, &derlen);
482  if (!p)
483  {
484  err = ksba_writer_error (w3);
485  goto leave;
486  }
488  1, derlen);
489  if (!err)
490  err = ksba_writer_write (w4, p, derlen);
491  xfree (p); p = NULL;
492  if (err)
493  goto leave;
494 
495  /* The requestExtensions go here. */
496  err = write_request_extensions (ocsp, w4);
497 
498  /* Write the tbsRequest. */
499 
500  /* The version is default, thus we don't write it. */
501 
502  /* The requesterName would go here. */
503 
504  /* Write the requestList. */
505  p = ksba_writer_snatch_mem (w4, &derlen);
506  if (!p)
507  {
508  err = ksba_writer_error (w4);
509  goto leave;
510  }
512  1, derlen);
513  if (!err)
514  err = ksba_writer_write (w5, p, derlen);
515  xfree (p); p = NULL;
516  if (err)
517  goto leave;
518 
519  /* Reuse writers; for clarity, use new names. */
520  w6 = w3;
521  w7 = w4;
522  err = ksba_writer_set_mem (w6, 2048);
523  if (!err)
524  err = ksba_writer_set_mem (w7, 2048);
525  if (err)
526  goto leave;
527 
528  /* Prepend a sequence tag. */
529  p = ksba_writer_snatch_mem (w5, &derlen);
530  if (!p)
531  {
532  err = ksba_writer_error (w5);
533  goto leave;
534  }
536  1, derlen);
537  if (!err)
538  err = ksba_writer_write (w6, p, derlen);
539  xfree (p); p = NULL;
540  if (err)
541  goto leave;
542 
543  /* Write the ocspRequest. */
544 
545  /* Note that we do not support the optional signature, because this
546  saves us one writer object. */
547 
548  /* Prepend a sequence tag. */
549 /* p = ksba_writer_snatch_mem (w6, &derlen); */
550 /* if (!p) */
551 /* { */
552 /* err = ksba_writer_error (w6); */
553 /* goto leave; */
554 /* } */
555 /* err = _ksba_ber_write_tl (w7, TYPE_SEQUENCE, CLASS_UNIVERSAL, */
556 /* 1, derlen); */
557 /* if (!err) */
558 /* err = ksba_writer_write (w7, p, derlen); */
559 /* xfree (p); p = NULL; */
560 /* if (err) */
561 /* goto leave; */
562 
563 
564  /* Read out the entire request. */
565  p = ksba_writer_snatch_mem (w6, &derlen);
566  if (!p)
567  {
568  err = ksba_writer_error (w6);
569  goto leave;
570  }
571  ocsp->request_buffer = p;
572  ocsp->request_buflen = derlen;
573  /* Ready. */
574 
575  leave:
576  ksba_writer_release (w3);
577  ksba_writer_release (w2);
578  ksba_writer_release (w1);
579  return err;
580 }
581 
582 
583 gpg_error_t
585  void (*hasher)(void *, const void *,
586  size_t length),
587  void *hasher_arg)
588 {
589  (void)ocsp;
590  (void)hasher;
591  (void)hasher_arg;
592  return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
593 }
594 
595 
596 gpg_error_t
598  ksba_const_sexp_t sigval)
599 {
600  (void)ocsp;
601  (void)sigval;
602  return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
603 }
604 
605 
606 gpg_error_t
608 {
609  (void)ocsp;
610  (void)cert;
611  return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
612 }
613 
614 
615 
616 /* Build a request from the current context. The function checks that
617  all necessary information have been set and then returns an
618  allocated buffer with the resulting request.
619  */
620 gpg_error_t
622  unsigned char **r_buffer, size_t *r_buflen)
623 {
624  gpg_error_t err;
625 
626  if (!ocsp || !r_buffer || !r_buflen)
627  return gpg_error (GPG_ERR_INV_VALUE);
628  *r_buffer = NULL;
629  *r_buflen = 0;
630 
631  if (!ocsp->requestlist)
632  return gpg_error (GPG_ERR_MISSING_ACTION);
633  if (!ocsp->request_buffer)
634  {
635  /* No prepare done, do it now. */
636  err = ksba_ocsp_prepare_request (ocsp);
637  if (err)
638  return err;
639  assert (ocsp->request_buffer);
640  }
641  *r_buffer = ocsp->request_buffer;
642  *r_buflen = ocsp->request_buflen;
643  ocsp->request_buffer = NULL;
644  ocsp->request_buflen = 0;
645  return 0;
646 }
647 
648 
649 ␌
650 /*
651  Parse the response extensions and store them aways. While doing
652  this we also check the nonce extension. A typical data ASN.1 blob
653  with only the nonce extension as passed to this function is:
654 
655  SEQUENCE {
656  SEQUENCE {
657  OBJECT IDENTIFIER ocspNonce (1 3 6 1 5 5 7 48 1 2)
658  OCTET STRING, encapsulates {
659  INTEGER
660  41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50
661  }
662  }
663  }
664 */
665 
666 static int
668  const unsigned char *data, size_t datalen)
669 {
670  gpg_error_t err;
671  struct tag_info ti;
672  size_t length;
673  char *oid = NULL;
674 
675  assert (!ocsp->response_extensions);
676  err = parse_sequence (&data, &datalen, &ti);
677  if (err)
678  goto leave;
679  length = ti.length;
680  while (length)
681  {
682  struct ocsp_extension_s *ex;
683  int is_crit;
684 
685  err = parse_sequence (&data, &datalen, &ti);
686  if (err)
687  goto leave;
688  if (length < ti.nhdr + ti.length)
689  {
690  err = gpg_error (GPG_ERR_BAD_BER);
691  goto leave;
692  }
693  length -= ti.nhdr + ti.length;
694 
695  xfree (oid);
696  err = parse_object_id_into_str (&data, &datalen, &oid);
697  if (err)
698  goto leave;
699  is_crit = 0;
700  err = parse_optional_boolean (&data, &datalen, &is_crit);
701  if (err)
702  goto leave;
703  err = parse_octet_string (&data, &datalen, &ti);
704  if (err)
705  goto leave;
706  if (!strcmp (oid, oidstr_ocsp_nonce))
707  {
708  err = parse_octet_string (&data, &datalen, &ti);
709  if (err)
710  goto leave;
711  if (ocsp->noncelen != ti.length
712  || memcmp (ocsp->nonce, data, ti.length))
713  ocsp->bad_nonce = 1;
714  else
715  ocsp->good_nonce = 1;
716  }
717  ex = xtrymalloc (sizeof *ex + strlen (oid) + ti.length);
718  if (!ex)
719  {
720  err = gpg_error_from_syserror ();
721  goto leave;
722  }
723  ex->crit = is_crit;
724  strcpy (ex->data, oid);
725  ex->data[strlen (oid)] = 0;
726  ex->off = strlen (oid) + 1;
727  ex->len = ti.length;
728  memcpy (ex->data + ex->off, data, ti.length);
729  ex->next = ocsp->response_extensions;
730  ocsp->response_extensions = ex;
731 
732  parse_skip (&data, &datalen, &ti); /* Skip the octet string / integer. */
733  }
734 
735  leave:
736  xfree (oid);
737  return err;
738 }
739 
740 
741 /*
742  Parse single extensions and store them away.
743 */
744 static int
746  const unsigned char *data, size_t datalen)
747 {
748  gpg_error_t err;
749  struct tag_info ti;
750  size_t length;
751  char *oid = NULL;
752 
753  assert (ri && !ri->single_extensions);
754  err = parse_sequence (&data, &datalen, &ti);
755  if (err)
756  goto leave;
757  length = ti.length;
758  while (length)
759  {
760  struct ocsp_extension_s *ex;
761  int is_crit;
762 
763  err = parse_sequence (&data, &datalen, &ti);
764  if (err)
765  goto leave;
766  if (length < ti.nhdr + ti.length)
767  {
768  err = gpg_error (GPG_ERR_BAD_BER);
769  goto leave;
770  }
771  length -= ti.nhdr + ti.length;
772 
773  xfree (oid);
774  err = parse_object_id_into_str (&data, &datalen, &oid);
775  if (err)
776  goto leave;
777  is_crit = 0;
778  err = parse_optional_boolean (&data, &datalen, &is_crit);
779  if (err)
780  goto leave;
781  err = parse_octet_string (&data, &datalen, &ti);
782  if (err)
783  goto leave;
784  ex = xtrymalloc (sizeof *ex + strlen (oid) + ti.length);
785  if (!ex)
786  {
787  err = gpg_error_from_syserror ();
788  goto leave;
789  }
790  ex->crit = is_crit;
791  strcpy (ex->data, oid);
792  ex->data[strlen (oid)] = 0;
793  ex->off = strlen (oid) + 1;
794  ex->len = ti.length;
795  memcpy (ex->data + ex->off, data, ti.length);
796  ex->next = ri->single_extensions;
797  ri->single_extensions = ex;
798 
799  parse_skip (&data, &datalen, &ti); /* Skip the octet string / integer. */
800  }
801 
802  leave:
803  xfree (oid);
804  return err;
805 }
806 
807 
808 /* Parse the first part of a response:
809 
810  OCSPResponse ::= SEQUENCE {
811  responseStatus OCSPResponseStatus,
812  responseBytes [0] EXPLICIT ResponseBytes OPTIONAL }
813 
814  OCSPResponseStatus ::= ENUMERATED {
815  successful (0), --Response has valid confirmations
816  malformedRequest (1), --Illegal confirmation request
817  internalError (2), --Internal error in issuer
818  tryLater (3), --Try again later
819  --(4) is not used
820  sigRequired (5), --Must sign the request
821  unauthorized (6) --Request unauthorized
822  }
823 
824  ResponseBytes ::= SEQUENCE {
825  responseType OBJECT IDENTIFIER,
826  response OCTET STRING }
827 
828  On success the RESPONSE_STATUS field of OCSP will be set to the
829  response status and DATA will now point to the first byte in the
830  octet string of the response; RLEN will be set to the length of
831  this octet string. Note thate DATALEN is also updated but might
832  point to a value larger than RLEN points to, if the provided data
833  is a part of a larger image. */
834 static gpg_error_t
836  unsigned char const **data, size_t *datalen,
837  size_t *rlength)
838 {
839  gpg_error_t err;
840  struct tag_info ti;
841  char *oid;
842 
843  *rlength = 0;
844  /* Parse the OCSPResponse sequence. */
845  err = parse_sequence (data, datalen, &ti);
846  if (err)
847  return err;
848  /* Parse the OCSPResponseStatus. */
849  err = parse_enumerated (data, datalen, &ti, 1);
850  if (err)
851  return err;
852  switch (**data)
853  {
854  case 0: ocsp->response_status = KSBA_OCSP_RSPSTATUS_SUCCESS; break;
855  case 1: ocsp->response_status = KSBA_OCSP_RSPSTATUS_MALFORMED; break;
856  case 2: ocsp->response_status = KSBA_OCSP_RSPSTATUS_INTERNAL; break;
857  case 3: ocsp->response_status = KSBA_OCSP_RSPSTATUS_TRYLATER; break;
858  case 5: ocsp->response_status = KSBA_OCSP_RSPSTATUS_SIGREQUIRED; break;
859  case 6: ocsp->response_status = KSBA_OCSP_RSPSTATUS_UNAUTHORIZED; break;
860  default: ocsp->response_status = KSBA_OCSP_RSPSTATUS_OTHER; break;
861  }
862  parse_skip (data, datalen, &ti);
863 
864  if (ocsp->response_status)
865  return 0; /* This is an error reponse; we have to stop here. */
866 
867  /* We have a successful reponse status, thus we check that
868  ResponseBytes are actually available. */
869  err = parse_context_tag (data, datalen, &ti, 0);
870  if (err)
871  return err;
872  err = parse_sequence (data, datalen, &ti);
873  if (err)
874  return err;
875  err = parse_object_id_into_str (data, datalen, &oid);
876  if (err)
877  return err;
878  if (strcmp (oid, oidstr_ocsp_basic))
879  {
880  xfree (oid);
881  return gpg_error (GPG_ERR_UNSUPPORTED_PROTOCOL);
882  }
883  xfree (oid);
884 
885  /* Check that the next field is an octet string. */
886  err = parse_octet_string (data, datalen, &ti);
887  if (err)
888  return err;
889  *rlength = ti.length;
890  return 0;
891 }
892 
893 /* Parse the object:
894 
895  SingleResponse ::= SEQUENCE {
896  certID CertID,
897  certStatus CertStatus,
898  thisUpdate GeneralizedTime,
899  nextUpdate [0] EXPLICIT GeneralizedTime OPTIONAL,
900  singleExtensions [1] EXPLICIT Extensions OPTIONAL }
901 
902  CertStatus ::= CHOICE {
903  good [0] IMPLICIT NULL,
904  revoked [1] IMPLICIT RevokedInfo,
905  unknown [2] IMPLICIT UnknownInfo }
906 
907  RevokedInfo ::= SEQUENCE {
908  revocationTime GeneralizedTime,
909  revocationReason [0] EXPLICIT CRLReason OPTIONAL }
910 
911  UnknownInfo ::= NULL -- this can be replaced with an enumeration
912 
913 */
914 
915 static gpg_error_t
917  unsigned char const **data, size_t *datalen)
918 {
919  gpg_error_t err;
920  struct tag_info ti;
921  const unsigned char *savedata;
922  const unsigned char *endptr;
923  size_t savedatalen;
924  size_t n;
925  char *oid;
926  ksba_isotime_t this_update, next_update, revocation_time;
927  int look_for_request;
928  const unsigned char *name_hash;
929  const unsigned char *key_hash;
930  const unsigned char *serialno;
931  size_t serialnolen;
932  struct ocsp_reqitem_s *request_item = NULL;
933 
934  /* The SingeResponse sequence. */
935  err = parse_sequence (data, datalen, &ti);
936  if (err)
937  return err;
938  endptr = *data + ti.length;
939 
940  /* The CertID is
941  SEQUENCE {
942  hashAlgorithm AlgorithmIdentifier,
943  issuerNameHash OCTET STRING, -- Hash of Issuer's DN
944  issuerKeyHash OCTET STRING, -- Hash of Issuers public key
945  serialNumber CertificateSerialNumber }
946  */
947  err = parse_sequence (data, datalen, &ti);
948  if (err)
949  return err;
950  err = _ksba_parse_algorithm_identifier (*data, *datalen, &n, &oid);
951  if (err)
952  return err;
953  assert (n <= *datalen);
954  *data += n;
955  *datalen -= n;
956  /* fprintf (stderr, "algorithmIdentifier is `%s'\n", oid); */
957  look_for_request = !strcmp (oid, oidstr_sha1);
958  xfree (oid);
959 
960  err = parse_octet_string (data, datalen, &ti);
961  if (err)
962  return err;
963  name_hash = *data;
964 /* fprintf (stderr, "issuerNameHash="); */
965 /* dump_hex (*data, ti.length); */
966 /* putc ('\n', stderr); */
967  if (ti.length != 20)
968  look_for_request = 0; /* Can't be a SHA-1 digest. */
969  parse_skip (data, datalen, &ti);
970 
971  err = parse_octet_string (data, datalen, &ti);
972  if (err)
973  return err;
974  key_hash = *data;
975 /* fprintf (stderr, "issuerKeyHash="); */
976 /* dump_hex (*data, ti.length); */
977 /* putc ('\n', stderr); */
978  if (ti.length != 20)
979  look_for_request = 0; /* Can't be a SHA-1 digest. */
980  parse_skip (data, datalen, &ti);
981 
982  err= parse_integer (data, datalen, &ti);
983  if (err)
984  return err;
985  serialno = *data;
986  serialnolen = ti.length;
987 /* fprintf (stderr, "serialNumber="); */
988 /* dump_hex (*data, ti.length); */
989 /* putc ('\n', stderr); */
990  parse_skip (data, datalen, &ti);
991 
992  if (look_for_request)
993  {
994  for (request_item = ocsp->requestlist;
995  request_item; request_item = request_item->next)
996  if (!memcmp (request_item->issuer_name_hash, name_hash, 20)
997  && !memcmp (request_item->issuer_key_hash, key_hash, 20)
998  && request_item->serialnolen == serialnolen
999  && !memcmp (request_item->serialno, serialno, serialnolen))
1000  break; /* Got it. */
1001  }
1002 
1003 
1004  /*
1005  CertStatus ::= CHOICE {
1006  good [0] IMPLICIT NULL,
1007  revoked [1] IMPLICIT RevokedInfo,
1008  unknown [2] IMPLICIT UnknownInfo }
1009  */
1010  *revocation_time = 0;
1011  err = _ksba_ber_parse_tl (data, datalen, &ti);
1012  if (err)
1013  return err;
1014  if (ti.length > *datalen)
1015  return gpg_error (GPG_ERR_BAD_BER);
1016  else if (ti.class == CLASS_CONTEXT && ti.tag == 0 && !ti.is_constructed)
1017  { /* good */
1018  if (!ti.length)
1019  ; /* Cope with zero length objects. */
1020  else if (*datalen && !**data)
1021  { /* Skip the NULL. */
1022  (*datalen)--;
1023  (*data)++;
1024  }
1025  else
1026  return gpg_error (GPG_ERR_INV_OBJ);
1027 
1028  if (request_item)
1029  request_item->status = KSBA_STATUS_GOOD;
1030  }
1031  else if (ti.class == CLASS_CONTEXT && ti.tag == 1 && ti.is_constructed)
1032  { /* revoked */
1034 
1035  err = parse_asntime_into_isotime (data, datalen, revocation_time);
1036  if (err)
1037  return err;
1038 /* fprintf (stderr, "revocationTime=%s\n", revocation_time); */
1039  savedata = *data;
1040  savedatalen = *datalen;
1041  err = parse_context_tag (data, datalen, &ti, 0);
1042  if (err)
1043  {
1044  *data = savedata;
1045  *datalen = savedatalen;
1046  }
1047  else
1048  { /* Got a revocationReason. */
1049  err = parse_enumerated (data, datalen, &ti, 1);
1050  if (err)
1051  return err;
1052  switch (**data)
1053  {
1054  case 0: reason = KSBA_CRLREASON_UNSPECIFIED; break;
1055  case 1: reason = KSBA_CRLREASON_KEY_COMPROMISE; break;
1056  case 2: reason = KSBA_CRLREASON_CA_COMPROMISE; break;
1057  case 3: reason = KSBA_CRLREASON_AFFILIATION_CHANGED; break;
1058  case 4: reason = KSBA_CRLREASON_SUPERSEDED; break;
1059  case 5: reason = KSBA_CRLREASON_CESSATION_OF_OPERATION; break;
1060  case 6: reason = KSBA_CRLREASON_CERTIFICATE_HOLD; break;
1061  case 8: reason = KSBA_CRLREASON_REMOVE_FROM_CRL; break;
1062  case 9: reason = KSBA_CRLREASON_PRIVILEGE_WITHDRAWN; break;
1063  case 10: reason = KSBA_CRLREASON_AA_COMPROMISE; break;
1064  default: reason = KSBA_CRLREASON_OTHER; break;
1065  }
1066  parse_skip (data, datalen, &ti);
1067  }
1068 /* fprintf (stderr, "revocationReason=%04x\n", reason); */
1069  if (request_item)
1070  {
1071  request_item->status = KSBA_STATUS_REVOKED;
1073  request_item->revocation_reason = reason;
1074  }
1075  }
1076  else if (ti.class == CLASS_CONTEXT && ti.tag == 2 && !ti.is_constructed
1077  && *datalen)
1078  { /* unknown */
1079  if (!ti.length)
1080  ; /* Cope with zero length objects. */
1081  else if (!**data)
1082  { /* Skip the NULL. */
1083  (*datalen)--;
1084  (*data)++;
1085  }
1086  else /* The comment indicates that an enumeration may come here. */
1087  {
1088  err = parse_enumerated (data, datalen, &ti, 0);
1089  if (err)
1090  return err;
1091  fprintf (stderr, "libksba: unknownReason with an enum of "
1092  "length %u detected\n",
1093  (unsigned int)ti.length);
1094  parse_skip (data, datalen, &ti);
1095  }
1096  if (request_item)
1097  request_item->status = KSBA_STATUS_UNKNOWN;
1098  }
1099  else
1100  err = gpg_error (GPG_ERR_INV_OBJ);
1101 
1102  /* thisUpdate. */
1103  err = parse_asntime_into_isotime (data, datalen, this_update);
1104  if (err)
1105  return err;
1106 /* fprintf (stderr, "thisUpdate=%s\n", this_update); */
1107  if (request_item)
1108  _ksba_copy_time (request_item->this_update, this_update);
1109 
1110  /* nextUpdate is optional. */
1111  if (*data >= endptr)
1112  return 0;
1113  *next_update = 0;
1114  err = _ksba_ber_parse_tl (data, datalen, &ti);
1115  if (err)
1116  return err;
1117  if (ti.length > *datalen)
1118  return gpg_error (GPG_ERR_BAD_BER);
1119  else if (ti.class == CLASS_CONTEXT && ti.tag == 0 && ti.is_constructed)
1120  { /* have nextUpdate */
1121  err = parse_asntime_into_isotime (data, datalen, next_update);
1122  if (err)
1123  return err;
1124 /* fprintf (stderr, "nextUpdate=%s\n", next_update); */
1125  if (request_item)
1126  _ksba_copy_time (request_item->next_update, next_update);
1127  }
1128  else if (ti.class == CLASS_CONTEXT && ti.tag == 1 && ti.is_constructed)
1129  { /* Undo that read. */
1130  *data -= ti.nhdr;
1131  *datalen += ti.nhdr;
1132  }
1133  else
1134  err = gpg_error (GPG_ERR_INV_OBJ);
1135 
1136  /* singleExtensions is optional */
1137  if (*data >= endptr)
1138  return 0;
1139  err = _ksba_ber_parse_tl (data, datalen, &ti);
1140  if (err)
1141  return err;
1142  if (ti.length > *datalen)
1143  return gpg_error (GPG_ERR_BAD_BER);
1144  if (ti.class == CLASS_CONTEXT && ti.tag == 1 && ti.is_constructed)
1145  {
1146  if (request_item)
1147  {
1148  err = parse_single_extensions (request_item, *data, ti.length);
1149  if (err)
1150  return err;
1151  }
1152  parse_skip (data, datalen, &ti);
1153  }
1154  else
1155  err = gpg_error (GPG_ERR_INV_OBJ);
1156 
1157  return 0;
1158 }
1159 
1160 /* Parse the object:
1161 
1162  ResponseData ::= SEQUENCE {
1163  version [0] EXPLICIT Version DEFAULT v1,
1164  responderID ResponderID,
1165  producedAt GeneralizedTime,
1166  responses SEQUENCE OF SingleResponse,
1167  responseExtensions [1] EXPLICIT Extensions OPTIONAL }
1168 
1169  ResponderID ::= CHOICE {
1170  byName [1] Name,
1171  byKey [2] KeyHash }
1172 
1173 
1174 */
1175 static gpg_error_t
1177  unsigned char const **data, size_t *datalen)
1178 {
1179  gpg_error_t err;
1180  struct tag_info ti;
1181  const unsigned char *savedata;
1182  size_t savedatalen;
1183  size_t responses_length;
1184 
1185  /* The out er sequence. */
1186  err = parse_sequence (data, datalen, &ti);
1187  if (err)
1188  return err;
1189 
1190  /* The optional version field. */
1191  savedata = *data;
1192  savedatalen = *datalen;
1193  err = parse_context_tag (data, datalen, &ti, 0);
1194  if (err)
1195  {
1196  *data = savedata;
1197  *datalen = savedatalen;
1198  }
1199  else
1200  {
1201  /* FIXME: check that the version matches. */
1202  parse_skip (data, datalen, &ti);
1203  }
1204 
1205  /* The responderID field. */
1206  assert (!ocsp->responder_id.name);
1207  assert (!ocsp->responder_id.keyid);
1208  err = _ksba_ber_parse_tl (data, datalen, &ti);
1209  if (err)
1210  return err;
1211  if (ti.length > *datalen)
1212  return gpg_error (GPG_ERR_BAD_BER);
1213  else if (ti.class == CLASS_CONTEXT && ti.tag == 1 && ti.is_constructed)
1214  { /* byName. */
1215  err = _ksba_derdn_to_str (*data, ti.length, &ocsp->responder_id.name);
1216  if (err)
1217  return err;
1218  parse_skip (data, datalen, &ti);
1219  }
1220  else if (ti.class == CLASS_CONTEXT && ti.tag == 2 && ti.is_constructed)
1221  { /* byKey. */
1222  err = parse_octet_string (data, datalen, &ti);
1223  if (err)
1224  return err;
1225  if (!ti.length)
1226  return gpg_error (GPG_ERR_INV_OBJ); /* Zero length key id. */
1227  ocsp->responder_id.keyid = xtrymalloc (ti.length);
1228  if (!ocsp->responder_id.keyid)
1229  return gpg_error_from_syserror ();
1230  memcpy (ocsp->responder_id.keyid, *data, ti.length);
1231  ocsp->responder_id.keyidlen = ti.length;
1232  parse_skip (data, datalen, &ti);
1233  }
1234  else
1235  err = gpg_error (GPG_ERR_INV_OBJ);
1236 
1237  /* The producedAt field. */
1238  err = parse_asntime_into_isotime (data, datalen, ocsp->produced_at);
1239  if (err)
1240  return err;
1241 
1242  /* The responses field set. */
1243  err = parse_sequence (data, datalen, &ti);
1244  if (err )
1245  return err;
1246  responses_length = ti.length;
1247  while (responses_length)
1248  {
1249  savedatalen = *datalen;
1250  err = parse_single_response (ocsp, data, datalen);
1251  if (err)
1252  return err;
1253  assert (responses_length >= savedatalen - *datalen);
1254  responses_length -= savedatalen - *datalen;
1255  }
1256 
1257  /* The optional responseExtensions set. */
1258  savedata = *data;
1259  savedatalen = *datalen;
1260  err = parse_context_tag (data, datalen, &ti, 1);
1261  if (!err)
1262  {
1263  err = parse_response_extensions (ocsp, *data, ti.length);
1264  if (err)
1265  return err;
1266  parse_skip (data, datalen, &ti);
1267  }
1268  else if (gpg_err_code (err) == GPG_ERR_INV_OBJ)
1269  {
1270  *data = savedata;
1271  *datalen = savedatalen;
1272  }
1273  else
1274  return err;
1275 
1276  return 0;
1277 }
1278 
1279 
1280 /* Parse the entire response message pointed to by MSG of length
1281  MSGLEN. */
1282 static gpg_error_t
1283 parse_response (ksba_ocsp_t ocsp, const unsigned char *msg, size_t msglen)
1284 {
1285  gpg_error_t err;
1286  struct tag_info ti;
1287  const unsigned char *msgstart;
1288  const unsigned char *endptr;
1289  const char *s;
1290  size_t len;
1291 
1292 
1293  msgstart = msg;
1294  err = parse_response_status (ocsp, &msg, &msglen, &len);
1295  if (err)
1296  return err;
1297  msglen = len; /* We don't care about any extra bytes provided to us. */
1298  if (ocsp->response_status)
1299  {
1300 /* fprintf (stderr,"response status found to be %d - stop\n", */
1301 /* ocsp->response_status); */
1302  return 0;
1303  }
1304 
1305  /* Now that we are sure that it is a BasicOCSPResponse, we can parse
1306  the really important things:
1307 
1308  BasicOCSPResponse ::= SEQUENCE {
1309  tbsResponseData ResponseData,
1310  signatureAlgorithm AlgorithmIdentifier,
1311  signature BIT STRING,
1312  certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
1313  */
1314  err = parse_sequence (&msg, &msglen, &ti);
1315  if (err)
1316  return err;
1317  endptr = msg + ti.length;
1318 
1319  ocsp->hash_offset = msg - msgstart;
1320  err = parse_response_data (ocsp, &msg, &msglen);
1321  if (err)
1322  return err;
1323  ocsp->hash_length = msg - msgstart - ocsp->hash_offset;
1324 
1325  /* The signatureAlgorithm and the signature. We only need to get the
1326  length of both objects and let a specialized function do the
1327  actual parsing. */
1328  s = msg;
1329  len = msglen;
1330  err = parse_sequence (&msg, &msglen, &ti);
1331  if (err)
1332  return err;
1333  parse_skip (&msg, &msglen, &ti);
1334  err= _ksba_ber_parse_tl (&msg, &msglen, &ti);
1335  if (err)
1336  return err;
1337  if (!(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_BIT_STRING
1338  && !ti.is_constructed) )
1339  err = gpg_error (GPG_ERR_INV_OBJ);
1340  else if (!ti.length)
1341  err = gpg_error (GPG_ERR_TOO_SHORT);
1342  else if (ti.length > msglen)
1343  err = gpg_error (GPG_ERR_BAD_BER);
1344  parse_skip (&msg, &msglen, &ti);
1345  len = len - msglen;
1346  xfree (ocsp->sigval); ocsp->sigval = NULL;
1347  err = _ksba_sigval_to_sexp (s, len, &ocsp->sigval);
1348  if (err)
1349  return err;
1350 
1351  /* Parse the optional sequence of certificates. */
1352  if (msg >= endptr)
1353  return 0; /* It's optional, so stop now. */
1354  err = parse_context_tag (&msg, &msglen, &ti, 0);
1355  if (gpg_err_code (err) == GPG_ERR_INV_OBJ)
1356  return 0; /* Not the right tag. Stop here. */
1357  if (err)
1358  return err;
1359  err = parse_sequence (&msg, &msglen, &ti);
1360  if (err)
1361  return err;
1362  if (ti.ndef)
1363  return gpg_error (GPG_ERR_UNSUPPORTED_ENCODING);
1364 
1365  {
1366  ksba_cert_t cert;
1367  struct ocsp_certlist_s *cl, **cl_tail;
1368 
1369  assert (!ocsp->received_certs);
1370  cl_tail = &ocsp->received_certs;
1371  endptr = msg + ti.length;
1372  while (msg < endptr)
1373  {
1374  /* Find the length of the certificate. */
1375  s = msg;
1376  err = parse_sequence (&msg, &msglen, &ti);
1377  if (err)
1378  return err;
1379  err = ksba_cert_new (&cert);
1380  if (err)
1381  return err;
1382  err = ksba_cert_init_from_mem (cert, msg - ti.nhdr,
1383  ti.nhdr + ti.length);
1384  if (err)
1385  {
1387  return err;
1388  }
1389  parse_skip (&msg, &msglen, &ti);
1390  cl = xtrycalloc (1, sizeof *cl);
1391  if (!cl)
1392  {
1393  err = gpg_error_from_syserror ();
1395  return err;
1396  }
1397 
1398  cl->cert = cert;
1399 
1400  *cl_tail = cl;
1401  cl_tail = &cl->next;
1402  }
1403  }
1404 
1405  return 0;
1406 }
1407 
1408 
1409 /* Given the OCSP context and a binary reponse message of MSGLEN bytes
1410  in MSG, this fucntion parses the response and prepares it for
1411  signature verification. The status from the server is returned in
1412  RESPONSE_STATUS and must be checked even if the function returns
1413  without an error. */
1414 gpg_error_t
1416  const unsigned char *msg, size_t msglen,
1417  ksba_ocsp_response_status_t *response_status)
1418 {
1419  gpg_error_t err;
1420  struct ocsp_reqitem_s *ri;
1421 
1422  if (!ocsp || !msg || !msglen || !response_status)
1423  return gpg_error (GPG_ERR_INV_VALUE);
1424 
1425  if (!ocsp->requestlist)
1426  return gpg_error (GPG_ERR_MISSING_ACTION);
1427 
1428  /* Reset the fields used to track the response. This is so that we
1429  can use the parse function a second time for the same
1430  request. This is useful in case of a TryLater response status. */
1434  ocsp->received_certs = NULL;
1435  ocsp->hash_length = 0;
1436  ocsp->bad_nonce = 0;
1437  ocsp->good_nonce = 0;
1438  xfree (ocsp->responder_id.name);
1439  ocsp->responder_id.name = NULL;
1440  xfree (ocsp->responder_id.keyid);
1441  ocsp->responder_id.keyid = NULL;
1442  for (ri=ocsp->requestlist; ri; ri = ri->next)
1443  {
1444  ri->status = KSBA_STATUS_NONE;
1445  *ri->this_update = 0;
1446  *ri->next_update = 0;
1447  *ri->revocation_time = 0;
1448  ri->revocation_reason = 0;
1450  }
1451 
1452  /* Run the actual parser. */
1453  err = parse_response (ocsp, msg, msglen);
1454  *response_status = ocsp->response_status;
1455 
1456  /* FIXME: find duplicates in the request list and set them to the
1457  same status. */
1458 
1459  if (*response_status == KSBA_OCSP_RSPSTATUS_SUCCESS)
1460  if (ocsp->bad_nonce || (ocsp->noncelen && !ocsp->good_nonce))
1461  *response_status = KSBA_OCSP_RSPSTATUS_REPLAYED;
1462 
1463  return err;
1464 }
1465 
1466 
1467 /* Return the digest algorithm to be used for the signature or NULL in
1468  case of an error. The returned pointer is valid as long as the
1469  context is valid and no other ksba_ocsp_parse_response or
1470  ksba_ocsp_build_request has been used. */
1471 const char *
1473 {
1474  return ocsp? ocsp->digest_oid : NULL;
1475 }
1476 
1477 
1478 /* Hash the data of the response using the hash function HASHER which
1479  will be passed HASHER_ARG as its first argument and a pointer and a
1480  length of the data to be hashed. This hash function might be called
1481  several times and should update the hash context. The algorithm to
1482  be used for the hashing can be retrieved using
1483  ksba_ocsp_get_digest_algo. Note that MSG and MSGLEN should be
1484  indentical to the values passed to ksba_ocsp_parse_response. */
1485 gpg_error_t
1487  const unsigned char *msg, size_t msglen,
1488  void (*hasher)(void *, const void *, size_t length),
1489  void *hasher_arg)
1490 
1491 {
1492  if (!ocsp || !msg || !hasher)
1493  return gpg_error (GPG_ERR_INV_VALUE);
1494  if (!ocsp->hash_length)
1495  return gpg_error (GPG_ERR_MISSING_ACTION);
1496  if (ocsp->hash_offset + ocsp->hash_length >= msglen)
1497  return gpg_error (GPG_ERR_CONFLICT);
1498 
1499  hasher (hasher_arg, msg + ocsp->hash_offset, ocsp->hash_length);
1500  return 0;
1501 }
1502 
1503 
1504 /* Return the actual signature in a format suitable to be used as
1505  input to Libgcrypt's verification function. The caller must free
1506  the returned string and that function may be called only once after
1507  a successful ksba_ocsp_parse_response. Returns NULL for an invalid
1508  handle or if no signature is available. If PRODUCED_AT is not NULL,
1509  it will receive the time the response was signed. */
1512 {
1513  ksba_sexp_t p;
1514 
1515  if (produced_at)
1516  *produced_at = 0;
1517  if (!ocsp || !ocsp->sigval )
1518  return NULL;
1519 
1520  if (produced_at)
1521  _ksba_copy_time (produced_at, ocsp->produced_at);
1522 
1523  p = ocsp->sigval;
1524  ocsp->sigval = NULL;
1525  return p;
1526 }
1527 
1528 
1529 /* Return the responder ID for the current response into R_NAME or
1530  into R_KEYID. On sucess either R_NAME or R_KEYID will receive an
1531  allocated object. If R_NAME or R_KEYID has been passed as NULL but
1532  a value is available the errorcode GPG_ERR_NO_DATA is returned.
1533  Caller must release the values stored at R_NAME or R_KEYID; the
1534  function stores NULL tehre in case of an error. */
1535 gpg_error_t
1537  char **r_name, ksba_sexp_t *r_keyid)
1538 {
1539  if (r_name)
1540  *r_name = NULL;
1541  if (r_keyid)
1542  *r_keyid = NULL;
1543 
1544  if (!ocsp)
1545  return gpg_error (GPG_ERR_INV_VALUE);
1546 
1547  if (ocsp->responder_id.name && r_name)
1548  {
1549  *r_name = xtrystrdup (ocsp->responder_id.name);
1550  if (!*r_name)
1551  return gpg_error_from_syserror ();
1552  }
1553  else if (ocsp->responder_id.keyid && r_keyid)
1554  {
1555  char numbuf[50];
1556  size_t numbuflen;
1557 
1558  sprintf (numbuf,"(%lu:", (unsigned long)ocsp->responder_id.keyidlen);
1559  numbuflen = strlen (numbuf);
1560  *r_keyid = xtrymalloc (numbuflen + ocsp->responder_id.keyidlen + 2);
1561  if (!*r_keyid)
1562  return gpg_error_from_syserror ();
1563  strcpy (*r_keyid, numbuf);
1564  memcpy (*r_keyid+numbuflen,
1565  ocsp->responder_id.keyid, ocsp->responder_id.keyidlen);
1566  (*r_keyid)[numbuflen + ocsp->responder_id.keyidlen] = ')';
1567  (*r_keyid)[numbuflen + ocsp->responder_id.keyidlen + 1] = 0;
1568  }
1569  else
1570  return gpg_error (GPG_ERR_NO_DATA);
1571 
1572  return 0;
1573 }
1574 
1575 
1576 /* Get optional certificates out of a response. The caller may use
1577  * this in a loop to get all certificates. The returned certificate
1578  * is a shallow copy of the original one; the caller must still use
1579  * ksba_cert_release() to free it. Returns: A certificate object or
1580  * NULL for end of list or error. */
1583 {
1584  struct ocsp_certlist_s *cl;
1585 
1586  if (!ocsp || idx < 0)
1587  return NULL;
1588 
1589  for (cl=ocsp->received_certs; cl && idx; cl = cl->next, idx--)
1590  ;
1591  if (!cl)
1592  return NULL;
1593  ksba_cert_ref (cl->cert);
1594  return cl->cert;
1595 }
1596 
1597 
1598 
1599 
1600 /* Return the status of the certificate CERT for the last response
1601  done on the context OCSP. CERT must be the same certificate as
1602  used for the request; only a shallow compare is done (i.e. the
1603  pointers are compared). R_STATUS returns the status value,
1604  R_THIS_UPDATE and R_NEXT_UPDATE are the corresponding OCSP response
1605  values, R_REVOCATION_TIME is only set to the revocation time if the
1606  indicated status is revoked, R_REASON will be set to the reason
1607  given for a revocation. All the R_* arguments may be given as NULL
1608  if the value is not required. The function return 0 on success,
1609  GPG_ERR_NOT_FOUND if CERT was not used in the request or any other
1610  error code. Note that the caller should have checked the signature
1611  of the entire reponse to be good before using the stati retruned by
1612  this function. */
1613 gpg_error_t
1615  ksba_status_t *r_status,
1616  ksba_isotime_t r_this_update,
1617  ksba_isotime_t r_next_update,
1618  ksba_isotime_t r_revocation_time,
1619  ksba_crl_reason_t *r_reason)
1620 {
1621  struct ocsp_reqitem_s *ri;
1622 
1623  if (!ocsp || !cert || !r_status)
1624  return gpg_error (GPG_ERR_INV_VALUE);
1625  if (!ocsp->requestlist)
1626  return gpg_error (GPG_ERR_MISSING_ACTION);
1627 
1628  /* Find the certificate. We don't care about the issuer certificate
1629  and stop at the first match. The implementation may be optimized
1630  by keeping track of the last certificate found to start with the
1631  next one then. Given that a usual request consists only of a few
1632  certificates, this does not make much sense in reality. */
1633  for (ri=ocsp->requestlist; ri; ri = ri->next)
1634  if (ri->cert == cert)
1635  break;
1636  if (!ri)
1637  return gpg_error (GPG_ERR_NOT_FOUND);
1638  if (r_status)
1639  *r_status = ri->status;
1640  if (r_this_update)
1641  _ksba_copy_time (r_this_update, ri->this_update);
1642  if (r_next_update)
1643  _ksba_copy_time (r_next_update, ri->next_update);
1644  if (r_revocation_time)
1645  _ksba_copy_time (r_revocation_time, ri->revocation_time);
1646  if (r_reason)
1647  *r_reason = ri->revocation_reason;
1648  return 0;
1649 }
1650 
1651 
1652 /* WARNING: The returned values ares only valid as long as no other
1653  ocsp function is called on the same context. */
1654 gpg_error_t
1656  char const **r_oid, int *r_crit,
1657  unsigned char const **r_der, size_t *r_derlen)
1658 {
1659  struct ocsp_extension_s *ex;
1660 
1661  if (!ocsp)
1662  return gpg_error (GPG_ERR_INV_VALUE);
1663  if (!ocsp->requestlist)
1664  return gpg_error (GPG_ERR_MISSING_ACTION);
1665  if (idx < 0)
1666  return gpg_error (GPG_ERR_INV_INDEX);
1667 
1668  if (cert)
1669  {
1670  /* Return extensions for the certificate (singleExtensions). */
1671  struct ocsp_reqitem_s *ri;
1672 
1673  for (ri=ocsp->requestlist; ri; ri = ri->next)
1674  if (ri->cert == cert)
1675  break;
1676  if (!ri)
1677  return gpg_error (GPG_ERR_NOT_FOUND);
1678 
1679  for (ex=ri->single_extensions; ex && idx; ex = ex->next, idx--)
1680  ;
1681  if (!ex)
1682  return gpg_error (GPG_ERR_EOF); /* No more extensions. */
1683  }
1684  else
1685  {
1686  /* Return extensions for the response (responseExtensions). */
1687  for (ex=ocsp->response_extensions; ex && idx; ex = ex->next, idx--)
1688  ;
1689  if (!ex)
1690  return gpg_error (GPG_ERR_EOF); /* No more extensions. */
1691  }
1692 
1693  if (r_oid)
1694  *r_oid = ex->data;
1695  if (r_crit)
1696  *r_crit = ex->crit;
1697  if (r_der)
1698  *r_der = ex->data + ex->off;
1699  if (r_derlen)
1700  *r_derlen = ex->len;
1701 
1702  return 0;
1703 }
@ TYPE_OCTET_STRING
@ TYPE_OBJECT_ID
@ TYPE_SEQUENCE
@ TYPE_BIT_STRING
@ CLASS_CONTEXT
@ CLASS_UNIVERSAL
gpg_error_t _ksba_ber_write_tl(ksba_writer_t writer, unsigned long tag, enum tag_class class, int constructed, unsigned long length)
Definition: ber-help.c:316
gpg_error_t _ksba_ber_parse_tl(unsigned char const **buffer, size_t *size, struct tag_info *ti)
Definition: ber-help.c:200
#define parse_sequence(buf, len, ti)
Definition: ber-help.h:80
#define parse_context_tag(buf, len, ti, tag)
Definition: ber-help.h:85
#define parse_optional_boolean(buf, len, r_bool)
Definition: ber-help.h:105
static void parse_skip(unsigned char const **buf, size_t *len, struct tag_info *ti)
Definition: ber-help.h:68
#define parse_octet_string(buf, len, ti)
Definition: ber-help.h:100
#define parse_integer(buf, len, ti)
Definition: ber-help.h:95
#define parse_asntime_into_isotime(buf, len, isotime)
Definition: ber-help.h:122
#define parse_object_id_into_str(buf, len, r_oid)
Definition: ber-help.h:115
#define parse_enumerated(buf, len, ti, maxlen)
Definition: ber-help.h:90
gpg_error_t _ksba_cert_get_subject_dn_ptr(ksba_cert_t cert, unsigned char const **ptr, size_t *length)
Definition: cert.c:583
gpg_error_t _ksba_cert_get_public_key_ptr(ksba_cert_t cert, unsigned char const **ptr, size_t *length)
Definition: cert.c:882
gpg_error_t _ksba_cert_get_serial_ptr(ksba_cert_t cert, unsigned char const **ptr, size_t *length)
Definition: cert.c:537
const char * oid
Definition: cms.c:71
void _ksba_copy_time(ksba_isotime_t d, const ksba_isotime_t s)
Definition: time.c:127
gpg_error_t _ksba_derdn_to_str(const unsigned char *der, size_t derlen, char **r_string)
Definition: dn.c:622
gpg_error_t _ksba_der_write_algorithm_identifier(ksba_writer_t w, const char *oid, const void *parm, size_t parmlen)
Definition: der-encoder.c:143
#define gpg_error_from_syserror()
Definition: gen-help.h:88
#define GPG_ERR_BUG
Definition: gen-help.h:83
#define GPG_ERR_INV_VALUE
Definition: gen-help.h:82
#define xtrymalloc(a)
Definition: gen-help.h:38
#define gpg_error(a)
Definition: gen-help.h:87
gpg_error_t _ksba_sigval_to_sexp(const unsigned char *der, size_t derlen, ksba_sexp_t *r_string)
Definition: keyinfo.c:1702
const unsigned char * der
Definition: keyinfo.c:367
unsigned int derlen
Definition: keyinfo.c:366
gpg_error_t _ksba_parse_algorithm_identifier(const unsigned char *der, size_t derlen, size_t *r_nread, char **r_oid)
Definition: keyinfo.c:679
gpg_error_t ksba_ocsp_set_requestor(ksba_ocsp_t ocsp, ksba_cert_t cert)
gpg_error_t ksba_writer_set_mem(ksba_writer_t w, size_t initial_size)
gpg_error_t ksba_writer_new(ksba_writer_t *r_w)
gpg_error_t ksba_ocsp_hash_request(ksba_ocsp_t ocsp, void(*hasher)(void *, const void *, size_t length), void *hasher_arg)
gpg_error_t ksba_cert_init_from_mem(ksba_cert_t cert, const void *buffer, size_t length)
const char * ksba_ocsp_get_digest_algo(ksba_ocsp_t ocsp)
gpg_error_t ksba_oid_from_str(const char *string, unsigned char **rbuf, size_t *rlength)
void ksba_cert_ref(ksba_cert_t cert)
ksba_crl_reason_t
Definition: ksba.h:156
@ KSBA_CRLREASON_CESSATION_OF_OPERATION
Definition: ksba.h:162
@ KSBA_CRLREASON_REMOVE_FROM_CRL
Definition: ksba.h:164
@ KSBA_CRLREASON_OTHER
Definition: ksba.h:167
@ KSBA_CRLREASON_SUPERSEDED
Definition: ksba.h:161
@ KSBA_CRLREASON_AA_COMPROMISE
Definition: ksba.h:166
@ KSBA_CRLREASON_CA_COMPROMISE
Definition: ksba.h:159
@ KSBA_CRLREASON_PRIVILEGE_WITHDRAWN
Definition: ksba.h:165
@ KSBA_CRLREASON_UNSPECIFIED
Definition: ksba.h:157
@ KSBA_CRLREASON_AFFILIATION_CHANGED
Definition: ksba.h:160
@ KSBA_CRLREASON_KEY_COMPROMISE
Definition: ksba.h:158
@ KSBA_CRLREASON_CERTIFICATE_HOLD
Definition: ksba.h:163
unsigned char * ksba_sexp_t
Definition: ksba.h:273
gpg_error_t ksba_writer_write(ksba_writer_t w, const void *buffer, size_t length)
int ksba_writer_error(ksba_writer_t w)
gpg_error_t ksba_cert_new(ksba_cert_t *acert)
char ksba_isotime_t[16]
Definition: ksba.h:212
gpg_error_t ksba_ocsp_get_status(ksba_ocsp_t ocsp, ksba_cert_t cert, ksba_status_t *r_status, ksba_isotime_t r_this_update, ksba_isotime_t r_next_update, ksba_isotime_t r_revocation_time, ksba_crl_reason_t *r_reason)
ksba_ocsp_response_status_t
Definition: ksba.h:173
@ KSBA_OCSP_RSPSTATUS_MALFORMED
Definition: ksba.h:175
@ KSBA_OCSP_RSPSTATUS_REPLAYED
Definition: ksba.h:180
@ KSBA_OCSP_RSPSTATUS_TRYLATER
Definition: ksba.h:177
@ KSBA_OCSP_RSPSTATUS_OTHER
Definition: ksba.h:181
@ KSBA_OCSP_RSPSTATUS_SUCCESS
Definition: ksba.h:174
@ KSBA_OCSP_RSPSTATUS_SIGREQUIRED
Definition: ksba.h:178
@ KSBA_OCSP_RSPSTATUS_UNAUTHORIZED
Definition: ksba.h:179
@ KSBA_OCSP_RSPSTATUS_NONE
Definition: ksba.h:182
@ KSBA_OCSP_RSPSTATUS_INTERNAL
Definition: ksba.h:176
gpg_error_t ksba_ocsp_build_request(ksba_ocsp_t ocsp, unsigned char **r_buffer, size_t *r_buflen)
ksba_cert_t ksba_ocsp_get_cert(ksba_ocsp_t ocsp, int idx)
gpg_error_t ksba_ocsp_add_target(ksba_ocsp_t ocsp, ksba_cert_t cert, ksba_cert_t issuer_cert)
gpg_error_t ksba_ocsp_hash_response(ksba_ocsp_t ocsp, const unsigned char *msg, size_t msglen, void(*hasher)(void *, const void *, size_t length), void *hasher_arg)
gpg_error_t ksba_ocsp_add_cert(ksba_ocsp_t ocsp, ksba_cert_t cert)
gpg_error_t ksba_ocsp_get_extension(ksba_ocsp_t ocsp, ksba_cert_t cert, int idx, char const **r_oid, int *r_crit, unsigned char const **r_der, size_t *r_derlen)
ksba_sexp_t ksba_ocsp_get_sig_val(ksba_ocsp_t ocsp, ksba_isotime_t produced_at)
void ksba_writer_release(ksba_writer_t w)
void ksba_ocsp_release(ksba_ocsp_t ocsp)
size_t ksba_ocsp_set_nonce(ksba_ocsp_t ocsp, unsigned char *nonce, size_t noncelen)
const unsigned char * ksba_const_sexp_t
Definition: ksba.h:275
ksba_status_t
Definition: ksba.h:187
@ KSBA_STATUS_REVOKED
Definition: ksba.h:191
@ KSBA_STATUS_GOOD
Definition: ksba.h:190
@ KSBA_STATUS_NONE
Definition: ksba.h:188
@ KSBA_STATUS_UNKNOWN
Definition: ksba.h:189
gpg_error_t ksba_ocsp_set_sig_val(ksba_ocsp_t ocsp, ksba_const_sexp_t sigval)
gpg_error_t ksba_ocsp_parse_response(ksba_ocsp_t ocsp, const unsigned char *msg, size_t msglen, ksba_ocsp_response_status_t *resp_status)
void * ksba_writer_snatch_mem(ksba_writer_t w, size_t *nbytes)
void ksba_cert_release(ksba_cert_t cert)
gpg_error_t ksba_ocsp_get_responder_id(ksba_ocsp_t ocsp, char **r_name, ksba_sexp_t *r_keyid)
gpg_error_t ksba_ocsp_prepare_request(ksba_ocsp_t ocsp)
gpg_error_t ksba_ocsp_set_digest_algo(ksba_ocsp_t ocsp, const char *oid)
gpg_error_t ksba_ocsp_new(ksba_ocsp_t *r_oscp)
static int parse_response_extensions(ksba_ocsp_t ocsp, const unsigned char *data, size_t datalen)
Definition: ocsp.c:667
static gpg_error_t parse_response(ksba_ocsp_t ocsp, const unsigned char *msg, size_t msglen)
Definition: ocsp.c:1283
static const char oidstr_ocsp_basic[]
Definition: ocsp.c:48
static gpg_error_t parse_single_response(ksba_ocsp_t ocsp, unsigned char const **data, size_t *datalen)
Definition: ocsp.c:916
static gpg_error_t issuer_key_hash(ksba_cert_t cert, unsigned char *sha1_buffer)
Definition: ocsp.c:238
static gpg_error_t issuer_name_hash(ksba_cert_t cert, unsigned char *sha1_buffer)
Definition: ocsp.c:218
static gpg_error_t parse_response_data(ksba_ocsp_t ocsp, unsigned char const **data, size_t *datalen)
Definition: ocsp.c:1176
static const char oidstr_sha1[]
Definition: ocsp.c:47
static const char oidstr_ocsp_nonce[]
Definition: ocsp.c:49
static int parse_single_extensions(struct ocsp_reqitem_s *ri, const unsigned char *data, size_t datalen)
Definition: ocsp.c:745
static gpg_error_t parse_response_status(ksba_ocsp_t ocsp, unsigned char const **data, size_t *datalen, size_t *rlength)
Definition: ocsp.c:835
static void release_ocsp_extensions(struct ocsp_extension_s *ex)
Definition: ocsp.c:94
static void release_ocsp_certlist(struct ocsp_certlist_s *cl)
Definition: ocsp.c:81
static gpg_error_t write_request_extensions(ksba_ocsp_t ocsp, ksba_writer_t wout)
Definition: ocsp.c:257
size_t request_buflen
Definition: ocsp.h:93
int bad_nonce
Definition: ocsp.h:104
size_t noncelen
Definition: ocsp.h:85
unsigned char nonce[16]
Definition: ocsp.h:86
ksba_ocsp_response_status_t response_status
Definition: ocsp.h:98
unsigned char * request_buffer
Definition: ocsp.h:92
int good_nonce
Definition: ocsp.h:105
struct ocsp_extension_s * response_extensions
Definition: ocsp.h:103
size_t keyidlen
Definition: ocsp.h:109
char * name
Definition: ocsp.h:107
size_t hash_offset
Definition: ocsp.h:95
char * keyid
Definition: ocsp.h:108
size_t hash_length
Definition: ocsp.h:96
struct ksba_ocsp_s::@29 responder_id
struct ocsp_certlist_s * received_certs
Definition: ocsp.h:101
char * digest_oid
Definition: ocsp.h:80
struct ocsp_reqitem_s * requestlist
Definition: ocsp.h:83
ksba_isotime_t produced_at
Definition: ocsp.h:100
ksba_sexp_t sigval
Definition: ocsp.h:99
struct ocsp_certlist_s * next
Definition: ocsp.h:40
ksba_cert_t cert
Definition: ocsp.h:41
size_t off
Definition: ocsp.h:48
char data[1]
Definition: ocsp.h:51
struct ocsp_extension_s * next
Definition: ocsp.h:47
size_t len
Definition: ocsp.h:49
ksba_cert_t cert
Definition: ocsp.h:60
unsigned char issuer_name_hash[20]
Definition: ocsp.h:64
unsigned char * serialno
Definition: ocsp.h:66
size_t serialnolen
Definition: ocsp.h:67
ksba_crl_reason_t revocation_reason
Definition: ocsp.h:74
struct ocsp_extension_s * single_extensions
Definition: ocsp.h:75
ksba_cert_t issuer_cert
Definition: ocsp.h:61
struct ocsp_reqitem_s * next
Definition: ocsp.h:58
ksba_isotime_t this_update
Definition: ocsp.h:70
unsigned char issuer_key_hash[20]
Definition: ocsp.h:65
ksba_isotime_t revocation_time
Definition: ocsp.h:73
ksba_isotime_t next_update
Definition: ocsp.h:71
ksba_status_t status
Definition: ocsp.h:72
unsigned long tag
Definition: ber-help.h:38
int is_constructed
Definition: ber-help.h:37
unsigned long length
Definition: ber-help.h:39
int ndef
Definition: ber-help.h:40
enum tag_class class
Definition: ber-help.h:36
size_t nhdr
Definition: ber-help.h:41
gpg_error_t _ksba_hash_buffer(const char *oid, const void *buffer, size_t length, size_t resultsize, unsigned char *result, size_t *resultlen)
Definition: util.c:111
#define xfree(a)
Definition: util.h:58
#define xtrystrdup(a)
Definition: util.h:57
#define xtrycalloc(a, b)
Definition: util.h:55