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)  

crl.c
Go to the documentation of this file.
1 /* crl.c - CRL parser
2  * Copyright (C) 2002, 2004, 2005, 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 #include <errno.h>
37 
38 #include "util.h"
39 
40 #include "convert.h"
41 #include "keyinfo.h"
42 #include "der-encoder.h"
43 #include "ber-help.h"
44 #include "ber-decoder.h"
45 #include "crl.h"
46 #include "stringbuf.h"
47 
48 
49 static const char oidstr_crlNumber[] = "2.5.29.20";
50 static const char oidstr_crlReason[] = "2.5.29.21";
51 #if 0
52 static const char oidstr_issuingDistributionPoint[] = "2.5.29.28";
53 #endif
54 static const char oidstr_certificateIssuer[] = "2.5.29.29";
55 static const char oidstr_authorityKeyIdentifier[] = "2.5.29.35";
56 
57 /* We better buffer the hashing. */
58 static inline void
59 do_hash (ksba_crl_t crl, const void *buffer, size_t length)
60 {
61  while (length)
62  {
63  size_t n = length;
64 
65  if (crl->hashbuf.used + n > sizeof crl->hashbuf.buffer)
66  n = sizeof crl->hashbuf.buffer - crl->hashbuf.used;
67  memcpy (crl->hashbuf.buffer+crl->hashbuf.used, buffer, n);
68  crl->hashbuf.used += n;
69  if (crl->hashbuf.used == sizeof crl->hashbuf.buffer)
70  {
71  if (crl->hash_fnc)
72  crl->hash_fnc (crl->hash_fnc_arg,
73  crl->hashbuf.buffer, crl->hashbuf.used);
74  crl->hashbuf.used = 0;
75  }
76  buffer = (const char *)buffer + n;
77  length -= n;
78  }
79 }
80 
81 #define HASH(a,b) do_hash (crl, (a), (b))
82 
83 
84 ␌
85 /**
86  * ksba_crl_new:
87  *
88  * Create a new and empty CRL object
89  *
90  * Return value: A CRL object or an error code.
91  **/
92 gpg_error_t
94 {
95  *r_crl = xtrycalloc (1, sizeof **r_crl);
96  if (!*r_crl)
97  return gpg_error_from_errno (errno);
98  return 0;
99 }
100 
101 
102 /**
103  * ksba_crl_release:
104  * @crl: A CRL object
105  *
106  * Release a CRL object.
107  **/
108 void
110 {
111  if (!crl)
112  return;
113  xfree (crl->algo.oid);
114  xfree (crl->algo.parm);
115 
117  xfree (crl->issuer.image);
118 
119  xfree (crl->item.serial);
120 
121  xfree (crl->sigval);
122  while (crl->extension_list)
123  {
124  crl_extn_t tmp = crl->extension_list->next;
125  xfree (crl->extension_list->oid);
126  xfree (crl->extension_list);
127  crl->extension_list = tmp;
128  }
129 
130  xfree (crl);
131 }
132 
133 
134 gpg_error_t
136 {
137  if (!crl || !r)
138  return gpg_error (GPG_ERR_INV_VALUE);
139 
140  crl->reader = r;
141  return 0;
142 }
143 
144 /* Provide a hash function so that we are able to hash the data */
145 void
147  void (*hash_fnc)(void *, const void *, size_t),
148  void *hash_fnc_arg)
149 {
150  if (crl)
151  {
152  crl->hash_fnc = hash_fnc;
153  crl->hash_fnc_arg = hash_fnc_arg;
154  }
155 }
156 
157 
158 ␌
159 /*
160  access functions
161 */
162 
163 
164 /**
165  * ksba_crl_get_digest_algo:
166  * @cms: CMS object
167  *
168  * Figure out the the digest algorithm used for the signature and return
169  * its OID.
170  *
171  * Return value: NULL if the signature algorithm is not yet available
172  * or there is a mismatched between "tbsCertList.signature" and
173  * "signatureAlgorithm"; on success the OID is returned which is valid
174  * as long as the CRL object is valid.
175  **/
176 const char *
178 {
179  if (!crl)
180  return NULL;
181 
182  /* fixme: implement the described check */
183 
184  return crl->algo.oid;
185 }
186 
187 
188 /**
189  * ksba_crl_get_issuer:
190  * @cms: CMS object
191  * @r_issuer: returns the issuer
192  *
193  * This functions returns the issuer of the CRL. The caller must
194  * release the returned object.
195  *
196  * Return value: 0 on success or an error code
197  **/
198 gpg_error_t
199 ksba_crl_get_issuer (ksba_crl_t crl, char **r_issuer)
200 {
201  gpg_error_t err;
202  AsnNode n;
203  const unsigned char *image;
204 
205  if (!crl || !r_issuer)
206  return gpg_error (GPG_ERR_INV_VALUE);
207  if (!crl->issuer.root)
208  return gpg_error (GPG_ERR_NO_DATA);
209 
210  n = crl->issuer.root;
211  image = crl->issuer.image;
212 
213  if (!n || !n->down)
214  return gpg_error (GPG_ERR_NO_VALUE);
215  n = n->down; /* dereference the choice node */
216 
217  if (n->off == -1)
218  {
219 /* fputs ("get_issuer problem at node:\n", stderr); */
220 /* _ksba_asn_node_dump_all (n, stderr); */
221  return gpg_error (GPG_ERR_GENERAL);
222  }
223  err = _ksba_dn_to_str (image, n, r_issuer);
224 
225  return err;
226 }
227 
228 
229 /* Return the CRL extension in OID, CRITICAL, DER and DERLEN. The
230  caller should iterate IDX from 0 upwards until GPG_ERR_EOF is
231  returned. Note, that the returned values are valid as long as the
232  context is valid and no new parsing has been started. */
233 gpg_error_t
235  char const **oid, int *critical,
236  unsigned char const **der, size_t *derlen)
237 {
238  crl_extn_t e;
239 
240  if (!crl)
241  return gpg_error (GPG_ERR_INV_VALUE);
242  if (idx < 0)
243  return gpg_error (GPG_ERR_INV_INDEX);
244 
245  for (e=crl->extension_list; e && idx; e = e->next, idx-- )
246  ;
247  if (!e)
248  return gpg_error (GPG_ERR_EOF);
249 
250  if (oid)
251  *oid = e->oid;
252  if (critical)
253  *critical = e->critical;
254  if (der)
255  *der = e->der;
256  if (derlen)
257  *derlen = e->derlen;
258 
259  return 0;
260 }
261 
262 
263 /* Return the authorityKeyIdentifier in r_name and r_serial or in
264  r_keyID. GPG_ERR_NO_DATA is returned if no authorityKeyIdentifier
265  or only one using the keyIdentifier method is available and R_KEYID
266  is NULL.
267 
268  FIXME: This function shares a lot of code with the one in cert.c
269 */
270 gpg_error_t
272  ksba_sexp_t *r_keyid,
273  ksba_name_t *r_name,
274  ksba_sexp_t *r_serial)
275 {
276  gpg_error_t err;
277  size_t derlen;
278  const unsigned char *der;
279  const unsigned char *keyid_der = NULL;
280  size_t keyid_derlen = 0;
281  struct tag_info ti;
282  char numbuf[30];
283  size_t numbuflen;
284  crl_extn_t e;
285 
286  if (r_keyid)
287  *r_keyid = NULL;
288  if (!crl || !r_name || !r_serial)
289  return gpg_error (GPG_ERR_INV_VALUE);
290  *r_name = NULL;
291  *r_serial = NULL;
292 
293  for (e=crl->extension_list; e; e = e->next)
294  if (!strcmp (e->oid, oidstr_authorityKeyIdentifier))
295  break;
296  if (!e)
297  return gpg_error (GPG_ERR_NO_DATA); /* not available */
298 
299  /* Check that there is only one */
300  {
301  crl_extn_t e2;
302 
303  for (e2 = e->next; e2; e2 = e2->next)
304  if (!strcmp (e2->oid, oidstr_authorityKeyIdentifier))
305  return gpg_error (GPG_ERR_DUP_VALUE);
306  }
307 
308  der = e->der;
309  derlen = e->derlen;
310 
311  err = _ksba_ber_parse_tl (&der, &derlen, &ti);
312  if (err)
313  return err;
314  if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SEQUENCE
315  && ti.is_constructed) )
316  return gpg_error (GPG_ERR_INV_CRL_OBJ);
317  if (ti.ndef)
318  return gpg_error (GPG_ERR_NOT_DER_ENCODED);
319  if (ti.length > derlen)
320  return gpg_error (GPG_ERR_BAD_BER);
321 
322  err = _ksba_ber_parse_tl (&der, &derlen, &ti);
323  if (err)
324  return err;
325  if (ti.class != CLASS_CONTEXT)
326  return gpg_error (GPG_ERR_INV_CRL_OBJ); /* We expected a tag. */
327  if (ti.ndef)
328  return gpg_error (GPG_ERR_NOT_DER_ENCODED);
329  if (derlen < ti.length)
330  return gpg_error (GPG_ERR_BAD_BER);
331 
332  if (ti.tag == 0)
333  { /* keyIdentifier: Just save it away for later use. */
334  keyid_der = der;
335  keyid_derlen = ti.length;
336 
337  der += ti.length;
338  derlen -= ti.length;
339  /* If the keyid has been requested but no other data follows, we
340  directly jump to the end. */
341  if (r_keyid && !derlen)
342  goto build_keyid;
343  if (!derlen)
344  return gpg_error (GPG_ERR_NO_DATA); /* not available */
345 
346  err = _ksba_ber_parse_tl (&der, &derlen, &ti);
347  if (err)
348  return err;
349  if (ti.class != CLASS_CONTEXT)
350  return gpg_error (GPG_ERR_INV_CRL_OBJ); /* we expected a tag */
351  if (ti.ndef)
352  return gpg_error (GPG_ERR_NOT_DER_ENCODED);
353  if (derlen < ti.length)
354  return gpg_error (GPG_ERR_BAD_BER);
355  }
356 
357  if (ti.tag != 1 || !derlen)
358  return gpg_error (GPG_ERR_INV_CRL_OBJ);
359 
360  err = _ksba_name_new_from_der (r_name, der, ti.length);
361  if (err)
362  return err;
363 
364  der += ti.length;
365  derlen -= ti.length;
366 
367  /* Fixme: we should release r_name before returning on error */
368  err = _ksba_ber_parse_tl (&der, &derlen, &ti);
369  if (err)
370  return err;
371  if (ti.class != CLASS_CONTEXT)
372  return gpg_error (GPG_ERR_INV_CRL_OBJ); /* we expected a tag */
373  if (ti.ndef)
374  return gpg_error (GPG_ERR_NOT_DER_ENCODED);
375  if (derlen < ti.length)
376  return gpg_error (GPG_ERR_BAD_BER);
377 
378  if (ti.tag != 2 || !derlen)
379  return gpg_error (GPG_ERR_INV_CRL_OBJ);
380 
381  sprintf (numbuf,"(%u:", (unsigned int)ti.length);
382  numbuflen = strlen (numbuf);
383  *r_serial = xtrymalloc (numbuflen + ti.length + 2);
384  if (!*r_serial)
385  return gpg_error_from_errno (errno);
386  strcpy (*r_serial, numbuf);
387  memcpy (*r_serial+numbuflen, der, ti.length);
388  (*r_serial)[numbuflen + ti.length] = ')';
389  (*r_serial)[numbuflen + ti.length + 1] = 0;
390 
391  build_keyid:
392  if (r_keyid && keyid_der && keyid_derlen)
393  {
394  sprintf (numbuf,"(%u:", (unsigned int)keyid_derlen);
395  numbuflen = strlen (numbuf);
396  *r_keyid = xtrymalloc (numbuflen + keyid_derlen + 2);
397  if (!*r_keyid)
398  return gpg_error (GPG_ERR_ENOMEM);
399  strcpy (*r_keyid, numbuf);
400  memcpy (*r_keyid+numbuflen, keyid_der, keyid_derlen);
401  (*r_keyid)[numbuflen + keyid_derlen] = ')';
402  (*r_keyid)[numbuflen + keyid_derlen + 1] = 0;
403  }
404  return 0;
405 }
406 
407 
408 /* Return the optional crlNumber in NUMBER or GPG_ERR_NO_DATA if it is
409  not available. Caller must release NUMBER if the fuction retruned
410  with success. */
411 gpg_error_t
413 {
414  gpg_error_t err;
415  size_t derlen;
416  const unsigned char *der;
417  struct tag_info ti;
418  char numbuf[30];
419  size_t numbuflen;
420  crl_extn_t e;
421 
422  if (!crl || !number)
423  return gpg_error (GPG_ERR_INV_VALUE);
424  *number = NULL;
425 
426  for (e=crl->extension_list; e; e = e->next)
427  if (!strcmp (e->oid, oidstr_crlNumber))
428  break;
429  if (!e)
430  return gpg_error (GPG_ERR_NO_DATA); /* not available */
431 
432  /* Check that there is only one. */
433  {
434  crl_extn_t e2;
435 
436  for (e2 = e->next; e2; e2 = e2->next)
437  if (!strcmp (e2->oid, oidstr_crlNumber))
438  return gpg_error (GPG_ERR_DUP_VALUE);
439  }
440 
441  der = e->der;
442  derlen = e->derlen;
443 
444  err = parse_integer (&der, &derlen, &ti);
445  if (err)
446  return err;
447 
448  sprintf (numbuf,"(%u:", (unsigned int)ti.length);
449  numbuflen = strlen (numbuf);
450  *number = xtrymalloc (numbuflen + ti.length + 2);
451  if (!*number)
452  return gpg_error_from_errno (errno);
453  strcpy (*number, numbuf);
454  memcpy (*number+numbuflen, der, ti.length);
455  (*number)[numbuflen + ti.length] = ')';
456  (*number)[numbuflen + ti.length + 1] = 0;
457 
458  return 0;
459 }
460 
461 
462 
463 
464 /**
465  * ksba_crl_get_update_times:
466  * @crl: CRL object
467  * @this: Returns the thisUpdate value
468  * @next: Returns the nextUpdate value.
469  *
470  * THIS and NEXT may be given as NULL if the value is not required.
471  * Return value: 0 on success or an error code
472  **/
473 gpg_error_t
475  ksba_isotime_t this,
476  ksba_isotime_t next)
477 {
478  if (this)
479  *this = 0;
480  if (next)
481  *next = 0;
482  if (!crl)
483  return gpg_error (GPG_ERR_INV_VALUE);
484  if (!*crl->this_update)
485  return gpg_error (GPG_ERR_INV_TIME);
486  if (this)
487  _ksba_copy_time (this, crl->this_update);
488  if (next)
489  _ksba_copy_time (next, crl->next_update);
490  return 0;
491 }
492 
493 /**
494  * ksba_crl_get_item:
495  * @crl: CRL object
496  * @r_serial: Returns a S-exp with the serial number; caller must free.
497  * @r_revocation_date: Returns the recocation date
498  * @r_reason: Return the reason for revocation
499  *
500  * Return the serial number, revocation time and reason of the current
501  * item. Any of these arguments may be passed as %NULL if the value
502  * is not of interest. This function should be used after the parse
503  * function came back with %KSBA_SR_GOT_ITEM. For efficiency reasons
504  * the function should be called only once, the implementation may
505  * return an error for the second call.
506  *
507  * Return value: 0 in success or an error code.
508  **/
509 gpg_error_t
511  ksba_isotime_t r_revocation_date,
512  ksba_crl_reason_t *r_reason)
513 {
514  if (r_revocation_date)
515  *r_revocation_date = 0;
516 
517  if (!crl)
518  return gpg_error (GPG_ERR_INV_VALUE);
519 
520  if (r_serial)
521  {
522  if (!crl->item.serial)
523  return gpg_error (GPG_ERR_NO_DATA);
524  *r_serial = crl->item.serial;
525  crl->item.serial = NULL;
526  }
527  if (r_revocation_date)
528  _ksba_copy_time (r_revocation_date, crl->item.revocation_date);
529  if (r_reason)
530  *r_reason = crl->item.reason;
531  return 0;
532 }
533 
534 
535 
536 /**
537  * ksba_crl_get_sig_val:
538  * @crl: CRL object
539  *
540  * Return the actual signature in a format suitable to be used as
541  * input to Libgcrypt's verification function. The caller must free
542  * the returned string. For a rsaPSS signed CRLs this function may
543  * also be called right after rsaPSS has been detected using
544  * ksba_crl_get_digest_algo and before the the signature value can be
545  * retrieved. In this case an S-expression of the form
546  *
547  * (sig-val (hash-algo OID)(salt-length N))
548  *
549  * is returned. The caller should extract the actual to be used hash
550  * algorithm from that S-expression. Note that after the actual
551  * signature as been seen, a similar S-expression is returned but in
552  * this case also with the (rsa(s XXX)) list.
553  *
554  * Return value: NULL or a string with an S-Exp.
555  **/
558 {
559  ksba_sexp_t p;
560 
561  if (!crl)
562  return NULL;
563 
564  if (!crl->sigval
565  && crl->algo.oid && !strcmp (crl->algo.oid, "1.2.840.113549.1.1.10")
566  && crl->algo.parm && crl->algo.parmlen)
567  {
568  char *pss_hash;
569  unsigned int salt_length;
570  struct stringbuf sb;
571 
573  &pss_hash, &salt_length))
574  return NULL;
575 
576  init_stringbuf (&sb, 100);
577  put_stringbuf (&sb,"(7:sig-val(5:flags3:pss)(9:hash-algo");
578  put_stringbuf_sexp (&sb, pss_hash);
579  put_stringbuf (&sb, ")(11:salt-length");
580  put_stringbuf_uint (&sb, salt_length);
581  put_stringbuf (&sb, "))");
582 
583  return get_stringbuf (&sb);
584  }
585 
586  if (!crl->sigval)
587  return NULL;
588 
589  p = crl->sigval;
590  crl->sigval = NULL;
591  return p;
592 }
593 
594 
595 ␌
596 /*
597  Parser functions
598 */
599 
600 /* read one byte */
601 static int
603 {
604  unsigned char buf;
605  size_t nread;
606  int rc;
607 
608  do
609  rc = ksba_reader_read (reader, &buf, 1, &nread);
610  while (!rc && !nread);
611  return rc? -1: buf;
612 }
613 
614 /* read COUNT bytes into buffer. Return 0 on success */
615 static int
616 read_buffer (ksba_reader_t reader, char *buffer, size_t count)
617 {
618  size_t nread;
619 
620  while (count)
621  {
622  if (ksba_reader_read (reader, buffer, count, &nread))
623  return -1;
624  buffer += nread;
625  count -= nread;
626  }
627  return 0;
628 }
629 
630 /* Create a new decoder and run it for the given element */
631 /* Fixme: this code is duplicated from cms-parser.c */
632 static gpg_error_t
633 create_and_run_decoder (ksba_reader_t reader, const char *elem_name,
634  AsnNode *r_root,
635  unsigned char **r_image, size_t *r_imagelen)
636 {
637  gpg_error_t err;
638  ksba_asn_tree_t crl_tree;
639  BerDecoder decoder;
640 
641  err = ksba_asn_create_tree ("tmttv2", &crl_tree);
642  if (err)
643  return err;
644 
645  decoder = _ksba_ber_decoder_new ();
646  if (!decoder)
647  {
648  ksba_asn_tree_release (crl_tree);
649  return gpg_error (GPG_ERR_ENOMEM);
650  }
651 
652  err = _ksba_ber_decoder_set_reader (decoder, reader);
653  if (err)
654  {
655  ksba_asn_tree_release (crl_tree);
656  _ksba_ber_decoder_release (decoder);
657  return err;
658  }
659 
660  err = _ksba_ber_decoder_set_module (decoder, crl_tree);
661  if (err)
662  {
663  ksba_asn_tree_release (crl_tree);
664  _ksba_ber_decoder_release (decoder);
665  return err;
666  }
667 
668  err = _ksba_ber_decoder_decode (decoder, elem_name, 0,
669  r_root, r_image, r_imagelen);
670 
671  _ksba_ber_decoder_release (decoder);
672  ksba_asn_tree_release (crl_tree);
673  return err;
674 }
675 
676 
677 /* Parse the extension in the buffer DER or length DERLEN and return
678  the result in OID, CRITICAL, OFF and LEN. */
679 static gpg_error_t
680 parse_one_extension (const unsigned char *der, size_t derlen,
681  char **oid, int *critical, size_t *off, size_t *len)
682 {
683  gpg_error_t err;
684  struct tag_info ti;
685  const unsigned char *start = der;
686 
687  *oid = NULL;
688  *critical = 0;
689  *off = *len = 0;
690 
691  /*
692  Extension ::= SEQUENCE {
693  extnID OBJECT IDENTIFIER,
694  critical BOOLEAN DEFAULT FALSE,
695  extnValue OCTET STRING }
696  */
697  err = parse_sequence (&der, &derlen, &ti);
698  if (err)
699  goto failure;
700 
702  if (err)
703  goto failure;
704 
705  err = _ksba_ber_parse_tl (&der, &derlen, &ti);
706  if (err)
707  goto failure;
708  if (ti.length > derlen)
709  return gpg_error (GPG_ERR_BAD_BER);
710  if (ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_BOOLEAN
711  && !ti.is_constructed)
712  {
713  if (ti.length != 1)
714  goto bad_ber;
715  *critical = !!*der;
716  parse_skip (&der, &derlen, &ti);
717  }
718  else
719  { /* Undo that read. */
720  der -= ti.nhdr;
721  derlen += ti.nhdr;
722  }
723 
724  err = parse_octet_string (&der, &derlen, &ti);
725  if (err)
726  goto failure;
727  *off = der - start;
728  *len = ti.length;
729 
730  return 0;
731 
732  bad_ber:
733  err = gpg_error (GPG_ERR_BAD_BER);
734  failure:
735  xfree (*oid);
736  *oid = NULL;
737  return err;
738 }
739 
740 
741 /* Store an extension into the context. */
742 static gpg_error_t
743 store_one_extension (ksba_crl_t crl, const unsigned char *der, size_t derlen)
744 {
745  gpg_error_t err;
746  char *oid;
747  int critical;
748  size_t off, len;
749  crl_extn_t e;
750 
751  err = parse_one_extension (der, derlen, &oid, &critical, &off, &len);
752  if (err)
753  return err;
754  e = xtrymalloc (sizeof *e + len - 1);
755  if (!e)
756  {
757  err = gpg_error_from_errno (errno);
758  xfree (oid);
759  return err;
760  }
761  e->oid = oid;
762  e->critical = critical;
763  e->derlen = len;
764  memcpy (e->der, der + off, len);
765  e->next = crl->extension_list;
766  crl->extension_list = e;
767 
768  return 0;
769 }
770 
771 
772 ␌
773 /* Parse the fixed block at the beginning. We use a custom parser
774  here because our BER decoder is not yet able to stop at certain
775  points */
776 static gpg_error_t
778 {
779  gpg_error_t err;
780  struct tag_info ti;
781  unsigned long outer_len, tbs_len;
782  int outer_ndef, tbs_ndef;
783  int c;
784  unsigned char tmpbuf[500]; /* for OID or algorithmIdentifier */
785  size_t nread;
786 
787  /* read the outer sequence */
788  err = _ksba_ber_read_tl (crl->reader, &ti);
789  if (err)
790  return err;
791  if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SEQUENCE
792  && ti.is_constructed) )
793  return gpg_error (GPG_ERR_INV_CRL_OBJ);
794  outer_len = ti.length;
795  outer_ndef = ti.ndef;
796  if (!outer_ndef && outer_len < 10)
797  return gpg_error (GPG_ERR_TOO_SHORT);
798 
799  /* read the tbs sequence */
800  err = _ksba_ber_read_tl (crl->reader, &ti);
801  if (err)
802  return err;
803  if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SEQUENCE
804  && ti.is_constructed) )
805  return gpg_error (GPG_ERR_INV_CRL_OBJ);
806  HASH (ti.buf, ti.nhdr);
807  if (!outer_ndef)
808  {
809  if (outer_len < ti.nhdr)
810  return gpg_error (GPG_ERR_BAD_BER); /* Triplet header larger
811  than outer sequence */
812  outer_len -= ti.nhdr;
813  if (!ti.ndef && outer_len < ti.length)
814  return gpg_error (GPG_ERR_BAD_BER); /* Triplet larger than
815  outer sequence */
816  outer_len -= ti.length;
817  }
818  tbs_len = ti.length;
819  tbs_ndef = ti.ndef;
820  if (!tbs_ndef && tbs_len < 10)
821  return gpg_error (GPG_ERR_TOO_SHORT);
822 
823  /* read the optional version integer */
824  crl->crl_version = -1;
825  err = _ksba_ber_read_tl (crl->reader, &ti);
826  if (err)
827  return err;
828  if ( ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_INTEGER)
829  {
830  if ( ti.is_constructed || !ti.length )
831  return gpg_error (GPG_ERR_INV_CRL_OBJ);
832  HASH (ti.buf, ti.nhdr);
833  if (!tbs_ndef)
834  {
835  if (tbs_len < ti.nhdr)
836  return gpg_error (GPG_ERR_BAD_BER);
837  tbs_len -= ti.nhdr;
838  if (tbs_len < ti.length)
839  return gpg_error (GPG_ERR_BAD_BER);
840  tbs_len -= ti.length;
841  }
842  /* fixme: we should also check the outer data length here and in
843  the follwing code. It might however be easier to to thsi at
844  the end of this sequence */
845  if (ti.length != 1)
846  return gpg_error (GPG_ERR_UNSUPPORTED_CRL_VERSION);
847  if ( (c=read_byte (crl->reader)) == -1)
848  {
849  err = ksba_reader_error (crl->reader);
850  return err? err : gpg_error (GPG_ERR_GENERAL);
851  }
852  if ( !(c == 0 || c == 1) )
853  return gpg_error (GPG_ERR_UNSUPPORTED_CRL_VERSION);
854  {
855  unsigned char tmp = c;
856  HASH (&tmp, 1);
857  }
858  crl->crl_version = c;
859  err = _ksba_ber_read_tl (crl->reader, &ti);
860  if (err)
861  return err;
862  }
863 
864  /* read the algorithm identifier */
865  if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SEQUENCE
866  && ti.is_constructed) )
867  return gpg_error (GPG_ERR_INV_CRL_OBJ);
868  if (!tbs_ndef)
869  {
870  if (tbs_len < ti.nhdr)
871  return gpg_error (GPG_ERR_BAD_BER);
872  tbs_len -= ti.nhdr;
873  if (!ti.ndef && tbs_len < ti.length)
874  return gpg_error (GPG_ERR_BAD_BER);
875  tbs_len -= ti.length;
876  }
877  if (ti.nhdr + ti.length >= DIM(tmpbuf))
878  return gpg_error (GPG_ERR_TOO_LARGE);
879  memcpy (tmpbuf, ti.buf, ti.nhdr);
880  err = read_buffer (crl->reader, tmpbuf+ti.nhdr, ti.length);
881  if (err)
882  return err;
883  HASH (tmpbuf, ti.nhdr+ti.length);
884 
885  xfree (crl->algo.oid); crl->algo.oid = NULL;
886  xfree (crl->algo.parm); crl->algo.parm = NULL;
887  err = _ksba_parse_algorithm_identifier2 (tmpbuf, ti.nhdr+ti.length, &nread,
888  &crl->algo.oid,
889  &crl->algo.parm,
890  &crl->algo.parmlen);
891  if (err)
892  return err;
893  assert (nread <= ti.nhdr + ti.length);
894  if (nread < ti.nhdr + ti.length)
895  return gpg_error (GPG_ERR_TOO_SHORT);
896 
897 
898  /* read the name */
899  {
900  unsigned long n = ksba_reader_tell (crl->reader);
901  err = create_and_run_decoder (crl->reader,
902  "TMTTv2.CertificateList.tbsCertList.issuer",
903  &crl->issuer.root,
904  &crl->issuer.image,
905  &crl->issuer.imagelen);
906  if (err)
907  return err;
908  /* imagelen might be larger than the valid data (due to read ahead).
909  So we need to get the count from the reader */
910  n = ksba_reader_tell (crl->reader) - n;
911  if (n > crl->issuer.imagelen)
912  return gpg_error (GPG_ERR_BUG);
913  HASH (crl->issuer.image, n);
914 
915  if (!tbs_ndef)
916  {
917  if (tbs_len < n)
918  return gpg_error (GPG_ERR_BAD_BER);
919  tbs_len -= n;
920  }
921  }
922 
923 
924 
925  /* read the thisUpdate time */
926  err = _ksba_ber_read_tl (crl->reader, &ti);
927  if (err)
928  return err;
929  if ( !(ti.class == CLASS_UNIVERSAL
930  && (ti.tag == TYPE_UTC_TIME || ti.tag == TYPE_GENERALIZED_TIME)
931  && !ti.is_constructed) )
932  return gpg_error (GPG_ERR_INV_CRL_OBJ);
933  if (!tbs_ndef)
934  {
935  if (tbs_len < ti.nhdr)
936  return gpg_error (GPG_ERR_BAD_BER);
937  tbs_len -= ti.nhdr;
938  if (!ti.ndef && tbs_len < ti.length)
939  return gpg_error (GPG_ERR_BAD_BER);
940  tbs_len -= ti.length;
941  }
942  if (ti.nhdr + ti.length >= DIM(tmpbuf))
943  return gpg_error (GPG_ERR_TOO_LARGE);
944  memcpy (tmpbuf, ti.buf, ti.nhdr);
945  err = read_buffer (crl->reader, tmpbuf+ti.nhdr, ti.length);
946  if (err)
947  return err;
948  HASH (tmpbuf, ti.nhdr+ti.length);
949  _ksba_asntime_to_iso (tmpbuf+ti.nhdr, ti.length,
950  ti.tag == TYPE_UTC_TIME, crl->this_update);
951 
952  /* Read the optional nextUpdate time. */
953  err = _ksba_ber_read_tl (crl->reader, &ti);
954  if (err)
955  return err;
956  if ( ti.class == CLASS_UNIVERSAL
957  && (ti.tag == TYPE_UTC_TIME || ti.tag == TYPE_GENERALIZED_TIME)
958  && !ti.is_constructed )
959  {
960  if (!tbs_ndef)
961  {
962  if (tbs_len < ti.nhdr)
963  return gpg_error (GPG_ERR_BAD_BER);
964  tbs_len -= ti.nhdr;
965  if (!ti.ndef && tbs_len < ti.length)
966  return gpg_error (GPG_ERR_BAD_BER);
967  tbs_len -= ti.length;
968  }
969  if (ti.nhdr + ti.length >= DIM(tmpbuf))
970  return gpg_error (GPG_ERR_TOO_LARGE);
971  memcpy (tmpbuf, ti.buf, ti.nhdr);
972  err = read_buffer (crl->reader, tmpbuf+ti.nhdr, ti.length);
973  if (err)
974  return err;
975  HASH (tmpbuf, ti.nhdr+ti.length);
976  _ksba_asntime_to_iso (tmpbuf+ti.nhdr, ti.length,
977  ti.tag == TYPE_UTC_TIME, crl->next_update);
978  err = _ksba_ber_read_tl (crl->reader, &ti);
979  if (err)
980  return err;
981  }
982 
983  /* Read the first sequence tag of the optional SEQ of SEQ. */
984  if (tbs_ndef || tbs_len)
985  {
986  if (ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SEQUENCE
987  && ti.is_constructed )
988  { /* yes, there is one */
989  HASH (ti.buf, ti.nhdr);
990  if (!tbs_ndef)
991  {
992  if (tbs_len < ti.nhdr)
993  return gpg_error (GPG_ERR_BAD_BER);
994  tbs_len -= ti.nhdr;
995  if (!ti.ndef && tbs_len < ti.length)
996  return gpg_error (GPG_ERR_BAD_BER);
997  tbs_len -= ti.length;
998  }
999  crl->state.have_seqseq = 1;
1000  crl->state.seqseq_ndef = ti.ndef;
1001  crl->state.seqseq_len = ti.length;
1002  /* and read the next */
1003  err = _ksba_ber_read_tl (crl->reader, &ti);
1004  if (err)
1005  return err;
1006  }
1007  }
1008 
1009  /* We need to save some stuff for the next round. */
1010  crl->state.ti = ti;
1011  crl->state.outer_ndef = outer_ndef;
1012  crl->state.outer_len = outer_len;
1013  crl->state.tbs_ndef = tbs_ndef;
1014  crl->state.tbs_len = tbs_len;
1015 
1016  return 0;
1017 }
1018 
1019 
1020 ␌
1021 /* Store an entry extension into the current item. */
1022 static gpg_error_t
1024  const unsigned char *der, size_t derlen)
1025 {
1026  gpg_error_t err;
1027  char *oid;
1028  int critical;
1029  size_t off, len;
1030 
1031  err = parse_one_extension (der, derlen, &oid, &critical, &off, &len);
1032  if (err)
1033  return err;
1034  if (!strcmp (oid, oidstr_crlReason))
1035  {
1036  struct tag_info ti;
1037  const unsigned char *buf = der+off;
1038  size_t mylen = len;
1039 
1040  err = parse_enumerated (&buf, &mylen, &ti, 1);
1041  if (err)
1042  return err;
1043  /* Note that we OR the values so that in case this extension is
1044  repeated we can track all reason codes. */
1045  switch (*buf)
1046  {
1047  case 0: crl->item.reason |= KSBA_CRLREASON_UNSPECIFIED; break;
1048  case 1: crl->item.reason |= KSBA_CRLREASON_KEY_COMPROMISE; break;
1049  case 2: crl->item.reason |= KSBA_CRLREASON_CA_COMPROMISE; break;
1050  case 3: crl->item.reason |= KSBA_CRLREASON_AFFILIATION_CHANGED; break;
1051  case 4: crl->item.reason |= KSBA_CRLREASON_SUPERSEDED; break;
1053  break;
1054  case 6: crl->item.reason |= KSBA_CRLREASON_CERTIFICATE_HOLD; break;
1055  case 8: crl->item.reason |= KSBA_CRLREASON_REMOVE_FROM_CRL; break;
1056  case 9: crl->item.reason |= KSBA_CRLREASON_PRIVILEGE_WITHDRAWN; break;
1057  case 10: crl->item.reason |= KSBA_CRLREASON_AA_COMPROMISE; break;
1058  default: crl->item.reason |= KSBA_CRLREASON_OTHER; break;
1059  }
1060  }
1061  if (!strcmp (oid, oidstr_certificateIssuer))
1062  {
1063  /* FIXME: We need to implement this. */
1064  }
1065  else if (critical)
1066  err = gpg_error (GPG_ERR_UNKNOWN_CRIT_EXTN);
1067 
1068  xfree (oid);
1069 
1070  return err;
1071 }
1072 
1073 /* Parse the revokedCertificates SEQUENCE of SEQUENCE using a custom
1074  parser for efficiency and return after each entry */
1075 static gpg_error_t
1076 parse_crl_entry (ksba_crl_t crl, int *got_entry)
1077 {
1078  gpg_error_t err;
1079  struct tag_info ti = crl->state.ti;
1080  unsigned long seqseq_len= crl->state.seqseq_len;
1081  int seqseq_ndef = crl->state.seqseq_ndef;
1082  unsigned long len;
1083  int ndef;
1084  unsigned char tmpbuf[4096]; /* for time, serial number and extensions */
1085  char numbuf[22];
1086  int numbuflen;
1087 
1088  /* Check the length to see whether we are at the end of the seq but do
1089  this only when we know that we have this optional seq of seq. */
1090  if (!crl->state.have_seqseq)
1091  return 0; /* ready (no entries at all) */
1092 
1093  if (!seqseq_ndef && !seqseq_len)
1094  return 0; /* ready */
1095 
1096  /* if this is not a SEQUENCE the CRL is invalid */
1097  if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SEQUENCE
1098  && ti.is_constructed) )
1099  return gpg_error (GPG_ERR_INV_CRL_OBJ);
1100  HASH (ti.buf, ti.nhdr);
1101  if (!seqseq_ndef)
1102  {
1103  if (seqseq_len < ti.nhdr)
1104  return gpg_error (GPG_ERR_BAD_BER);
1105  seqseq_len -= ti.nhdr;
1106  if (!ti.ndef && seqseq_len < ti.length)
1107  return gpg_error (GPG_ERR_BAD_BER);
1108  seqseq_len -= ti.length;
1109  }
1110  ndef = ti.ndef;
1111  len = ti.length;
1112 
1113  /* get the serial number */
1114  err = _ksba_ber_read_tl (crl->reader, &ti);
1115  if (err)
1116  return err;
1117  if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_INTEGER
1118  && !ti.is_constructed) )
1119  return gpg_error (GPG_ERR_INV_CRL_OBJ);
1120  if (!ndef)
1121  {
1122  if (len < ti.nhdr)
1123  return gpg_error (GPG_ERR_BAD_BER);
1124  len -= ti.nhdr;
1125  if (!ti.ndef && len < ti.length)
1126  return gpg_error (GPG_ERR_BAD_BER);
1127  len -= ti.length;
1128  }
1129  if (ti.nhdr + ti.length >= DIM(tmpbuf))
1130  return gpg_error (GPG_ERR_TOO_LARGE);
1131  memcpy (tmpbuf, ti.buf, ti.nhdr);
1132  err = read_buffer (crl->reader, tmpbuf+ti.nhdr, ti.length);
1133  if (err)
1134  return err;
1135  HASH (tmpbuf, ti.nhdr+ti.length);
1136 
1137  xfree (crl->item.serial);
1138  sprintf (numbuf,"(%u:", (unsigned int)ti.length);
1139  numbuflen = strlen (numbuf);
1140  crl->item.serial = xtrymalloc (numbuflen + ti.length + 2);
1141  if (!crl->item.serial)
1142  return gpg_error (GPG_ERR_ENOMEM);
1143  strcpy (crl->item.serial, numbuf);
1144  memcpy (crl->item.serial+numbuflen, tmpbuf+ti.nhdr, ti.length);
1145  crl->item.serial[numbuflen + ti.length] = ')';
1146  crl->item.serial[numbuflen + ti.length + 1] = 0;
1147  crl->item.reason = 0;
1148 
1149  /* get the revocation time */
1150  err = _ksba_ber_read_tl (crl->reader, &ti);
1151  if (err)
1152  return err;
1153  if ( !(ti.class == CLASS_UNIVERSAL
1154  && (ti.tag == TYPE_UTC_TIME || ti.tag == TYPE_GENERALIZED_TIME)
1155  && !ti.is_constructed) )
1156  return gpg_error (GPG_ERR_INV_CRL_OBJ);
1157  if (!ndef)
1158  {
1159  if (len < ti.nhdr)
1160  return gpg_error (GPG_ERR_BAD_BER);
1161  len -= ti.nhdr;
1162  if (!ti.ndef && len < ti.length)
1163  return gpg_error (GPG_ERR_BAD_BER);
1164  len -= ti.length;
1165  }
1166  if (ti.nhdr + ti.length >= DIM(tmpbuf))
1167  return gpg_error (GPG_ERR_TOO_LARGE);
1168  memcpy (tmpbuf, ti.buf, ti.nhdr);
1169  err = read_buffer (crl->reader, tmpbuf+ti.nhdr, ti.length);
1170  if (err)
1171  return err;
1172  HASH (tmpbuf, ti.nhdr+ti.length);
1173 
1174  _ksba_asntime_to_iso (tmpbuf+ti.nhdr, ti.length,
1175  ti.tag == TYPE_UTC_TIME, crl->item.revocation_date);
1176 
1177  /* if there is still space we must parse the optional entryExtensions */
1178  if (ndef)
1179  return gpg_error (GPG_ERR_UNSUPPORTED_ENCODING);
1180  else if (len)
1181  {
1182  /* read the outer sequence */
1183  err = _ksba_ber_read_tl (crl->reader, &ti);
1184  if (err)
1185  return err;
1186  if ( !(ti.class == CLASS_UNIVERSAL
1187  && ti.tag == TYPE_SEQUENCE && ti.is_constructed) )
1188  return gpg_error (GPG_ERR_INV_CRL_OBJ);
1189  if (ti.ndef)
1190  return gpg_error (GPG_ERR_UNSUPPORTED_ENCODING);
1191  HASH (ti.buf, ti.nhdr);
1192  if (len < ti.nhdr)
1193  return gpg_error (GPG_ERR_BAD_BER);
1194  len -= ti.nhdr;
1195  if (len < ti.length)
1196  return gpg_error (GPG_ERR_BAD_BER);
1197 
1198  /* now loop over the extensions */
1199  while (len)
1200  {
1201  err = _ksba_ber_read_tl (crl->reader, &ti);
1202  if (err)
1203  return err;
1204  if ( !(ti.class == CLASS_UNIVERSAL
1205  && ti.tag == TYPE_SEQUENCE && ti.is_constructed) )
1206  return gpg_error (GPG_ERR_INV_CRL_OBJ);
1207  if (ti.ndef)
1208  return gpg_error (GPG_ERR_UNSUPPORTED_ENCODING);
1209  if (len < ti.nhdr)
1210  return gpg_error (GPG_ERR_BAD_BER);
1211  len -= ti.nhdr;
1212  if (len < ti.length)
1213  return gpg_error (GPG_ERR_BAD_BER);
1214  len -= ti.length;
1215  if (ti.nhdr + ti.length >= DIM(tmpbuf))
1216  return gpg_error (GPG_ERR_TOO_LARGE);
1217  memcpy (tmpbuf, ti.buf, ti.nhdr);
1218  err = read_buffer (crl->reader, tmpbuf+ti.nhdr, ti.length);
1219  if (err)
1220  return err;
1221  HASH (tmpbuf, ti.nhdr+ti.length);
1222  err = store_one_entry_extension (crl, tmpbuf, ti.nhdr+ti.length);
1223  if (err)
1224  return err;
1225  }
1226  }
1227 
1228  /* read ahead */
1229  err = _ksba_ber_read_tl (crl->reader, &ti);
1230  if (err)
1231  return err;
1232 
1233  *got_entry = 1;
1234 
1235  /* Fixme: the seqseq length is not correct if any element was ndef'd */
1236  crl->state.ti = ti;
1237  crl->state.seqseq_ndef = seqseq_ndef;
1238  crl->state.seqseq_len = seqseq_len;
1239 
1240  return 0;
1241 }
1242 
1243 
1244 /* This function is used when a [0] tag was encountered to read the
1245  crlExtensions */
1246 static gpg_error_t
1248 {
1249  gpg_error_t err;
1250  struct tag_info ti = crl->state.ti;
1251  unsigned long ext_len, len;
1252  unsigned char tmpbuf[4096]; /* for extensions */
1253 
1254  /* if we do not have a tag [0] we are done with this */
1255  if (!(ti.class == CLASS_CONTEXT && ti.tag == 0 && ti.is_constructed))
1256  return 0;
1257  if (ti.ndef)
1258  return gpg_error (GPG_ERR_UNSUPPORTED_ENCODING);
1259  HASH (ti.buf, ti.nhdr);
1260  ext_len = ti.length;
1261 
1262  /* read the outer sequence */
1263  err = _ksba_ber_read_tl (crl->reader, &ti);
1264  if (err)
1265  return err;
1266  if ( !(ti.class == CLASS_UNIVERSAL
1267  && ti.tag == TYPE_SEQUENCE && ti.is_constructed) )
1268  return gpg_error (GPG_ERR_INV_CRL_OBJ);
1269  if (ti.ndef)
1270  return gpg_error (GPG_ERR_UNSUPPORTED_ENCODING);
1271  HASH (ti.buf, ti.nhdr);
1272  if (ext_len < ti.nhdr)
1273  return gpg_error (GPG_ERR_BAD_BER);
1274  ext_len -= ti.nhdr;
1275  if (ext_len < ti.length)
1276  return gpg_error (GPG_ERR_BAD_BER);
1277  len = ti.length;
1278 
1279  /* now loop over the extensions */
1280  while (len)
1281  {
1282  err = _ksba_ber_read_tl (crl->reader, &ti);
1283  if (err)
1284  return err;
1285  if ( !(ti.class == CLASS_UNIVERSAL
1286  && ti.tag == TYPE_SEQUENCE && ti.is_constructed) )
1287  return gpg_error (GPG_ERR_INV_CRL_OBJ);
1288  if (ti.ndef)
1289  return gpg_error (GPG_ERR_UNSUPPORTED_ENCODING);
1290  if (len < ti.nhdr)
1291  return gpg_error (GPG_ERR_BAD_BER);
1292  len -= ti.nhdr;
1293  if (len < ti.length)
1294  return gpg_error (GPG_ERR_BAD_BER);
1295  len -= ti.length;
1296  if (ti.nhdr + ti.length >= DIM(tmpbuf))
1297  return gpg_error (GPG_ERR_TOO_LARGE);
1298  /* fixme use a larger buffer if the extension does not fit into tmpbuf */
1299  memcpy (tmpbuf, ti.buf, ti.nhdr);
1300  err = read_buffer (crl->reader, tmpbuf+ti.nhdr, ti.length);
1301  if (err)
1302  return err;
1303  HASH (tmpbuf, ti.nhdr+ti.length);
1304  err = store_one_extension (crl, tmpbuf, ti.nhdr+ti.length);
1305  if (err)
1306  return err;
1307  }
1308 
1309  /* read ahead */
1310  err = _ksba_ber_read_tl (crl->reader, &ti);
1311  if (err)
1312  return err;
1313 
1314  crl->state.ti = ti;
1315  return 0;
1316 }
1317 
1318 /* Parse the signatureAlgorithm and the signature */
1319 static gpg_error_t
1321 {
1322  gpg_error_t err;
1323  struct tag_info ti = crl->state.ti;
1324  unsigned char tmpbuf[2048]; /* for the sig algo and bitstr */
1325  size_t n, n2;
1326 
1327  /* We do read the stuff into a temporary buffer so that we can apply
1328  our parsing function for this structure */
1329 
1330  /* read the algorithmIdentifier sequence */
1331  if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SEQUENCE
1332  && ti.is_constructed) )
1333  return gpg_error (GPG_ERR_INV_CRL_OBJ);
1334  if (ti.ndef)
1335  return gpg_error (GPG_ERR_UNSUPPORTED_ENCODING);
1336  n = ti.nhdr + ti.length;
1337  if (n >= DIM(tmpbuf))
1338  return gpg_error (GPG_ERR_TOO_LARGE);
1339  memcpy (tmpbuf, ti.buf, ti.nhdr);
1340  err = read_buffer (crl->reader, tmpbuf+ti.nhdr, ti.length);
1341  if (err)
1342  return err;
1343 
1344  /* and append the bit string */
1345  err = _ksba_ber_read_tl (crl->reader, &ti);
1346  if (err)
1347  return err;
1348  if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_BIT_STRING
1349  && !ti.is_constructed) )
1350  return gpg_error (GPG_ERR_INV_CRL_OBJ);
1351  n2 = ti.nhdr + ti.length;
1352  if (n + n2 >= DIM(tmpbuf))
1353  return gpg_error (GPG_ERR_TOO_LARGE);
1354  memcpy (tmpbuf+n, ti.buf, ti.nhdr);
1355  err = read_buffer (crl->reader, tmpbuf+n+ti.nhdr, ti.length);
1356  if (err)
1357  return err;
1358 
1359  /* now parse it */
1360  xfree (crl->sigval); crl->sigval = NULL;
1361  return _ksba_sigval_to_sexp (tmpbuf, n + n2, &crl->sigval);
1362 }
1363 
1364 
1365 /* The actual parser which should be used with a new CRL object and
1366  run in a loop until the the KSBA_SR_READY is encountered */
1367 gpg_error_t
1369 {
1370  enum {
1371  sSTART,
1372  sCRLENTRY,
1373  sCRLEXT,
1374  sERROR
1375  } state = sERROR;
1376  ksba_stop_reason_t stop_reason;
1377  gpg_error_t err = 0;
1378  int got_entry = 0;
1379 
1380  if (!crl || !r_stopreason)
1381  return gpg_error (GPG_ERR_INV_VALUE);
1382 
1383  if (!crl->any_parse_done)
1384  { /* first time initialization of the stop reason */
1385  *r_stopreason = 0;
1386  crl->any_parse_done = 1;
1387  }
1388 
1389  /* Calculate state from last reason */
1390  stop_reason = *r_stopreason;
1391  *r_stopreason = KSBA_SR_RUNNING;
1392  switch (stop_reason)
1393  {
1394  case 0:
1395  state = sSTART;
1396  break;
1397  case KSBA_SR_BEGIN_ITEMS:
1398  case KSBA_SR_GOT_ITEM:
1399  state = sCRLENTRY;
1400  break;
1401  case KSBA_SR_END_ITEMS:
1402  state = sCRLEXT;
1403  break;
1404  case KSBA_SR_RUNNING:
1405  err = gpg_error (GPG_ERR_INV_STATE);
1406  break;
1407  default:
1408  err = gpg_error (GPG_ERR_BUG);
1409  break;
1410  }
1411  if (err)
1412  return err;
1413 
1414  /* Do the action */
1415  switch (state)
1416  {
1417  case sSTART:
1418  err = parse_to_next_update (crl);
1419  break;
1420  case sCRLENTRY:
1421  err = parse_crl_entry (crl, &got_entry);
1422  break;
1423  case sCRLEXT:
1424  err = parse_crl_extensions (crl);
1425  if (!err)
1426  {
1427  if (crl->hash_fnc && crl->hashbuf.used)
1428  crl->hash_fnc (crl->hash_fnc_arg,
1429  crl->hashbuf.buffer, crl->hashbuf.used);
1430  crl->hashbuf.used = 0;
1431  err = parse_signature (crl);
1432  }
1433  break;
1434  default:
1435  err = gpg_error (GPG_ERR_INV_STATE);
1436  break;
1437  }
1438  if (err)
1439  return err;
1440 
1441  /* Calculate new stop reason */
1442  switch (state)
1443  {
1444  case sSTART:
1445  stop_reason = KSBA_SR_BEGIN_ITEMS;
1446  break;
1447  case sCRLENTRY:
1448  stop_reason = got_entry? KSBA_SR_GOT_ITEM : KSBA_SR_END_ITEMS;
1449  break;
1450  case sCRLEXT:
1451  stop_reason = KSBA_SR_READY;
1452  break;
1453  default:
1454  break;
1455  }
1456 
1457  *r_stopreason = stop_reason;
1458  return 0;
1459 }
@ TYPE_GENERALIZED_TIME
@ TYPE_BOOLEAN
@ TYPE_INTEGER
@ TYPE_SEQUENCE
@ TYPE_UTC_TIME
@ TYPE_BIT_STRING
@ CLASS_CONTEXT
@ CLASS_UNIVERSAL
void _ksba_asn_release_nodes(AsnNode node)
Definition: asn1-parse.c:2886
gpg_error_t _ksba_ber_decoder_decode(BerDecoder d, const char *start_name, unsigned int flags, AsnNode *r_root, unsigned char **r_image, size_t *r_imagelen)
Definition: ber-decoder.c:1203
gpg_error_t _ksba_ber_decoder_set_module(BerDecoder d, ksba_asn_tree_t module)
Definition: ber-decoder.c:373
BerDecoder _ksba_ber_decoder_new(void)
Definition: ber-decoder.c:344
void _ksba_ber_decoder_release(BerDecoder d)
Definition: ber-decoder.c:356
gpg_error_t _ksba_ber_decoder_set_reader(BerDecoder d, ksba_reader_t r)
Definition: ber-decoder.c:386
gpg_error_t _ksba_ber_read_tl(ksba_reader_t reader, struct tag_info *ti)
Definition: ber-help.c:93
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
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_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
const char * oid
Definition: cms.c:71
gpg_error_t _ksba_dn_to_str(const unsigned char *image, AsnNode node, char **r_string)
Definition: dn.c:551
gpg_error_t _ksba_name_new_from_der(ksba_name_t *r_name, const unsigned char *image, size_t imagelen)
Definition: name.c:100
void _ksba_copy_time(ksba_isotime_t d, const ksba_isotime_t s)
Definition: time.c:127
gpg_error_t _ksba_asntime_to_iso(const char *buffer, size_t length, int is_utctime, ksba_isotime_t timebuf)
Definition: time.c:52
static const char oidstr_crlReason[]
Definition: crl.c:50
static gpg_error_t store_one_extension(ksba_crl_t crl, const unsigned char *der, size_t derlen)
Definition: crl.c:743
static int read_buffer(ksba_reader_t reader, char *buffer, size_t count)
Definition: crl.c:616
static void do_hash(ksba_crl_t crl, const void *buffer, size_t length)
Definition: crl.c:59
static const char oidstr_crlNumber[]
Definition: crl.c:49
static int read_byte(ksba_reader_t reader)
Definition: crl.c:602
static gpg_error_t parse_to_next_update(ksba_crl_t crl)
Definition: crl.c:777
static gpg_error_t store_one_entry_extension(ksba_crl_t crl, const unsigned char *der, size_t derlen)
Definition: crl.c:1023
static gpg_error_t parse_crl_entry(ksba_crl_t crl, int *got_entry)
Definition: crl.c:1076
#define HASH(a, b)
Definition: crl.c:81
static const char oidstr_authorityKeyIdentifier[]
Definition: crl.c:55
static gpg_error_t create_and_run_decoder(ksba_reader_t reader, const char *elem_name, AsnNode *r_root, unsigned char **r_image, size_t *r_imagelen)
Definition: crl.c:633
static const char oidstr_certificateIssuer[]
Definition: crl.c:54
static gpg_error_t parse_crl_extensions(ksba_crl_t crl)
Definition: crl.c:1247
static gpg_error_t parse_signature(ksba_crl_t crl)
Definition: crl.c:1320
static gpg_error_t parse_one_extension(const unsigned char *der, size_t derlen, char **oid, int *critical, size_t *off, size_t *len)
Definition: crl.c:680
#define DIM(v)
Definition: gen-help.h:46
#define GPG_ERR_GENERAL
Definition: gen-help.h:80
#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_keyinfo_get_pss_info(const unsigned char *der, size_t derlen, char **r_psshash, unsigned int *r_saltlen)
Definition: keyinfo.c:1400
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
gpg_error_t _ksba_parse_algorithm_identifier2(const unsigned char *der, size_t derlen, size_t *r_nread, char **r_oid, char **r_parm, size_t *r_parmlen)
Definition: keyinfo.c:688
unsigned int derlen
Definition: keyinfo.c:366
const char * ksba_crl_get_digest_algo(ksba_crl_t crl)
gpg_error_t ksba_crl_get_update_times(ksba_crl_t crl, ksba_isotime_t this_update, ksba_isotime_t next_update)
gpg_error_t ksba_crl_new(ksba_crl_t *r_crl)
gpg_error_t ksba_crl_parse(ksba_crl_t crl, ksba_stop_reason_t *r_stopreason)
ksba_stop_reason_t
Definition: ksba.h:138
@ KSBA_SR_RUNNING
Definition: ksba.h:140
@ KSBA_SR_BEGIN_ITEMS
Definition: ksba.h:148
@ KSBA_SR_END_ITEMS
Definition: ksba.h:150
@ KSBA_SR_GOT_ITEM
Definition: ksba.h:149
@ KSBA_SR_READY
Definition: ksba.h:145
gpg_error_t ksba_crl_get_item(ksba_crl_t crl, ksba_sexp_t *r_serial, ksba_isotime_t r_revocation_date, ksba_crl_reason_t *r_reason)
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_crl_get_auth_key_id(ksba_crl_t crl, ksba_sexp_t *r_keyid, ksba_name_t *r_name, ksba_sexp_t *r_serial)
gpg_error_t ksba_crl_get_crl_number(ksba_crl_t crl, ksba_sexp_t *number)
void ksba_crl_set_hash_function(ksba_crl_t crl, void(*hash_fnc)(void *, const void *, size_t), void *hash_fnc_arg)
char ksba_isotime_t[16]
Definition: ksba.h:212
unsigned long ksba_reader_tell(ksba_reader_t r)
gpg_error_t ksba_crl_get_extension(ksba_crl_t crl, int idx, char const **oid, int *critical, unsigned char const **der, size_t *derlen)
gpg_error_t ksba_reader_read(ksba_reader_t r, char *buffer, size_t length, size_t *nread)
gpg_error_t ksba_asn_create_tree(const char *mod_name, ksba_asn_tree_t *result)
gpg_error_t ksba_crl_set_reader(ksba_crl_t crl, ksba_reader_t r)
gpg_error_t ksba_reader_error(ksba_reader_t r)
ksba_sexp_t ksba_crl_get_sig_val(ksba_crl_t crl)
void ksba_crl_release(ksba_crl_t crl)
void ksba_asn_tree_release(ksba_asn_tree_t tree)
gpg_error_t ksba_crl_get_issuer(ksba_crl_t crl, char **r_issuer)
static void init_stringbuf(struct stringbuf *sb, int initiallen)
Definition: stringbuf.h:47
static char * get_stringbuf(struct stringbuf *sb)
Definition: stringbuf.h:164
static void put_stringbuf_uint(struct stringbuf *sb, unsigned int value)
Definition: stringbuf.h:155
static void put_stringbuf(struct stringbuf *sb, const char *text)
Definition: stringbuf.h:131
static void put_stringbuf_sexp(struct stringbuf *sb, const char *text)
Definition: stringbuf.h:148
AsnNode down
Definition: asn1-func.h:110
Definition: crl.h:42
int critical
Definition: crl.h:45
size_t derlen
Definition: crl.h:46
struct crl_extn_s * next
Definition: crl.h:43
char * oid
Definition: crl.h:44
unsigned char der[1]
Definition: crl.h:47
Definition: crl.h:51
struct tag_info ti
Definition: crl.h:61
void * hash_fnc_arg
Definition: crl.h:58
AsnNode root
Definition: crl.h:74
ksba_sexp_t serial
Definition: crl.h:82
ksba_isotime_t this_update
Definition: crl.h:78
crl_extn_t extension_list
Definition: crl.h:87
struct ksba_crl_s::@22 algo
void(* hash_fnc)(void *, const void *, size_t)
Definition: crl.h:57
ksba_crl_reason_t reason
Definition: crl.h:83
struct ksba_crl_s::@25 hashbuf
int crl_version
Definition: crl.h:67
unsigned long tbs_len
Definition: crl.h:62
struct ksba_crl_s::@21 state
int any_parse_done
Definition: crl.h:55
int used
Definition: crl.h:91
unsigned long outer_len
Definition: crl.h:62
char buffer[8192]
Definition: crl.h:92
ksba_sexp_t sigval
Definition: crl.h:88
struct ksba_crl_s::@23 issuer
ksba_reader_t reader
Definition: crl.h:54
struct ksba_crl_s::@24 item
unsigned char * image
Definition: crl.h:75
size_t parmlen
Definition: crl.h:71
char * parm
Definition: crl.h:70
int seqseq_ndef
Definition: crl.h:63
int have_seqseq
Definition: crl.h:64
char * oid
Definition: crl.h:69
int tbs_ndef
Definition: crl.h:63
ksba_isotime_t next_update
Definition: crl.h:79
size_t imagelen
Definition: crl.h:76
unsigned long seqseq_len
Definition: crl.h:62
ksba_isotime_t revocation_date
Definition: crl.h:84
int outer_ndef
Definition: crl.h:63
size_t len
Definition: stringbuf.h:39
char * buf
Definition: stringbuf.h:41
unsigned long tag
Definition: ber-help.h:38
int is_constructed
Definition: ber-help.h:37
unsigned char buf[10]
Definition: ber-help.h:42
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
#define xfree(a)
Definition: util.h:58
#define xtrycalloc(a, b)
Definition: util.h:55