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)  

ber-help.c
Go to the documentation of this file.
1 /* ber-help.c - BER herlper functions
2  * Copyright (C) 2001, 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 "util.h"
37 
38 #include "asn1-func.h" /* need some constants */
39 #include "convert.h"
40 #include "ber-help.h"
41 
42 /* Fixme: The parser functions should check that primitive types don't
43  have the constructed bit set (which is not allowed). This saves us
44  some work when using these parsers */
45 
46 static int
48 {
49  unsigned char buf;
50  size_t nread;
51  int rc;
52 
53  do
54  rc = ksba_reader_read (reader, &buf, 1, &nread);
55  while (!rc && !nread);
56  return rc? -1: buf;
57 }
58 
59 
60 static int
61 premature_eof (struct tag_info *ti)
62 {
63  /* Note: We do an strcmp on this string at other places. */
64  ti->err_string = "premature EOF";
65  return gpg_error (GPG_ERR_BAD_BER);
66 }
67 
68 
69 
70 static gpg_error_t
71 eof_or_error (ksba_reader_t reader, struct tag_info *ti, int premature)
72 {
73  gpg_error_t err;
74 
75  err = ksba_reader_error (reader);
76  if (err)
77  {
78  ti->err_string = "read error";
79  return err;
80  }
81  if (premature)
82  return premature_eof (ti);
83 
84  return gpg_error (GPG_ERR_EOF);
85 }
86 
87 
88 
89 /*
90  Read the tag and the length part from the TLV triplet.
91  */
92 gpg_error_t
94 {
95  int c;
96  unsigned long tag;
97 
98  ti->length = 0;
99  ti->ndef = 0;
100  ti->nhdr = 0;
101  ti->err_string = NULL;
102  ti->non_der = 0;
103 
104  /* Get the tag */
105  c = read_byte (reader);
106  if (c==-1)
107  return eof_or_error (reader, ti, 0);
108 
109  ti->buf[ti->nhdr++] = c;
110  ti->class = (c & 0xc0) >> 6;
111  ti->is_constructed = !!(c & 0x20);
112  tag = c & 0x1f;
113 
114  if (tag == 0x1f)
115  {
116  tag = 0;
117  do
118  {
119  /* We silently ignore an overflow in the tag value. It is
120  not worth checking for it. */
121  tag <<= 7;
122  c = read_byte (reader);
123  if (c == -1)
124  return eof_or_error (reader, ti, 1);
125  if (ti->nhdr >= DIM (ti->buf))
126  {
127  ti->err_string = "tag+length header too large";
128  return gpg_error (GPG_ERR_BAD_BER);
129  }
130  ti->buf[ti->nhdr++] = c;
131  tag |= c & 0x7f;
132  }
133  while (c & 0x80);
134  }
135  ti->tag = tag;
136 
137  /* Get the length */
138  c = read_byte (reader);
139  if (c == -1)
140  return eof_or_error (reader, ti, 1);
141  if (ti->nhdr >= DIM (ti->buf))
142  {
143  ti->err_string = "tag+length header too large";
144  return gpg_error (GPG_ERR_BAD_BER);
145  }
146  ti->buf[ti->nhdr++] = c;
147 
148  if ( !(c & 0x80) )
149  ti->length = c;
150  else if (c == 0x80)
151  {
152  ti->ndef = 1;
153  ti->non_der = 1;
154  }
155  else if (c == 0xff)
156  {
157  ti->err_string = "forbidden length value";
158  return gpg_error (GPG_ERR_BAD_BER);
159  }
160  else
161  {
162  unsigned long len = 0;
163  int count = c & 0x7f;
164 
165  if (count > sizeof (len) || count > sizeof (size_t))
166  return gpg_error (GPG_ERR_BAD_BER);
167 
168  for (; count; count--)
169  {
170  len <<= 8;
171  c = read_byte (reader);
172  if (c == -1)
173  return eof_or_error (reader, ti, 1);
174  if (ti->nhdr >= DIM (ti->buf))
175  {
176  ti->err_string = "tag+length header too large";
177  return gpg_error (GPG_ERR_BAD_BER);
178  }
179  ti->buf[ti->nhdr++] = c;
180  len |= c & 0xff;
181  }
182  ti->length = len;
183  }
184 
185  /* Without this kludge some example certs can't be parsed */
186  if (ti->class == CLASS_UNIVERSAL && !ti->tag)
187  ti->length = 0;
188 
189  return 0;
190 }
191 
192 
193 /* Parse the buffer at the address BUFFER which of SIZE and return the
194  * tag and the length part from the TLV triplet. Update BUFFER and
195  * SIZE on success. Note that this function will never return
196  * GPG_ERR_INV_OBJ so that this error code can be used by the parse_foo
197  * functions below to return an error for unexpected tags and the
198  * caller is able to backoff in that case. */
199 gpg_error_t
200 _ksba_ber_parse_tl (unsigned char const **buffer, size_t *size,
201  struct tag_info *ti)
202 {
203  int c;
204  unsigned long tag;
205  const unsigned char *buf = *buffer;
206  size_t length = *size;
207 
208  ti->length = 0;
209  ti->ndef = 0;
210  ti->nhdr = 0;
211  ti->err_string = NULL;
212  ti->non_der = 0;
213 
214  /* Get the tag */
215  if (!length)
216  return premature_eof (ti);
217  c = *buf++; length--;
218 
219  ti->buf[ti->nhdr++] = c;
220  ti->class = (c & 0xc0) >> 6;
221  ti->is_constructed = !!(c & 0x20);
222  tag = c & 0x1f;
223 
224  if (tag == 0x1f)
225  {
226  tag = 0;
227  do
228  {
229  /* We silently ignore an overflow in the tag value. It is
230  not worth checking for it. */
231  tag <<= 7;
232  if (!length)
233  return premature_eof (ti);
234  c = *buf++; length--;
235  if (ti->nhdr >= DIM (ti->buf))
236  {
237  ti->err_string = "tag+length header too large";
238  return gpg_error (GPG_ERR_BAD_BER);
239  }
240  ti->buf[ti->nhdr++] = c;
241  tag |= c & 0x7f;
242  }
243  while (c & 0x80);
244  }
245  ti->tag = tag;
246 
247  /* Get the length */
248  if (!length)
249  return premature_eof (ti);
250  c = *buf++; length--;
251  if (ti->nhdr >= DIM (ti->buf))
252  {
253  ti->err_string = "tag+length header too large";
254  return gpg_error (GPG_ERR_BAD_BER);
255  }
256  ti->buf[ti->nhdr++] = c;
257 
258  if ( !(c & 0x80) )
259  ti->length = c;
260  else if (c == 0x80)
261  {
262  ti->ndef = 1;
263  ti->non_der = 1;
264  }
265  else if (c == 0xff)
266  {
267  ti->err_string = "forbidden length value";
268  return gpg_error (GPG_ERR_BAD_BER);
269  }
270  else
271  {
272  unsigned long len = 0;
273  int count = c & 0x7f;
274 
275  if (count > sizeof (len) || count > sizeof (size_t))
276  return gpg_error (GPG_ERR_BAD_BER);
277 
278  for (; count; count--)
279  {
280  len <<= 8;
281  if (!length)
282  return premature_eof (ti);
283  c = *buf++; length--;
284  if (ti->nhdr >= DIM (ti->buf))
285  {
286  ti->err_string = "tag+length header too large";
287  return gpg_error (GPG_ERR_BAD_BER);
288  }
289  ti->buf[ti->nhdr++] = c;
290  len |= c & 0xff;
291  }
292  /* Sanity check for the length: This is done so that we can take
293  * the value for malloc plus some additional bytes without
294  * risking an overflow. */
295  if (len > (1 << 30))
296  return gpg_error (GPG_ERR_BAD_BER);
297  ti->length = len;
298  }
299 
300 
301  /* Without this kludge some example certs can't be parsed */
302  if (ti->class == CLASS_UNIVERSAL && !ti->tag)
303  ti->length = 0;
304 
305  *buffer = buf;
306  *size = length;
307  return 0;
308 }
309 
310 
311 /* Write TAG of CLASS to WRITER. constructed is a flag telling
312  whether the value is a constructed one. length gives the length of
313  the value, if it is 0 undefinite length is assumed. length is
314  ignored for the NULL tag. */
315 gpg_error_t
317  unsigned long tag,
318  enum tag_class class,
319  int constructed,
320  unsigned long length)
321 {
322  unsigned char buf[50];
323  int buflen = 0;
324 
325  if (tag < 0x1f)
326  {
327  *buf = (class << 6) | tag;
328  if (constructed)
329  *buf |= 0x20;
330  buflen++;
331  }
332  else
333  {
334  return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
335  }
336 
337  if (!tag && !class)
338  buf[buflen++] = 0; /* end tag */
339  else if (tag == TYPE_NULL && !class)
340  buf[buflen++] = 0; /* NULL tag */
341  else if (!length)
342  buf[buflen++] = 0x80; /* indefinite length */
343  else if (length < 128)
344  buf[buflen++] = length;
345  else
346  {
347  int i;
348 
349  /* fixme: if we know the sizeof an ulong we could support larger
350  objects - however this is pretty ridiculous */
351  i = (length <= 0xff ? 1:
352  length <= 0xffff ? 2:
353  length <= 0xffffff ? 3: 4);
354 
355  buf[buflen++] = (0x80 | i);
356  if (i > 3)
357  buf[buflen++] = length >> 24;
358  if (i > 2)
359  buf[buflen++] = length >> 16;
360  if (i > 1)
361  buf[buflen++] = length >> 8;
362  buf[buflen++] = length;
363  }
364 
365  return ksba_writer_write (writer, buf, buflen);
366 }
367 
368 /* Encode TAG of CLASS in BUFFER. CONSTRUCTED is a flag telling
369  whether the value is a constructed one. LENGTH gives the length of
370  the value, if it is 0 undefinite length is assumed. LENGTH is
371  ignored for the NULL tag. It is assumed that the provide buffer is
372  large enough for storing the result - this is usually achieved by
373  using _ksba_ber_count_tl() in advance. Returns 0 in case of an
374  error or the length of the encoding.*/
375 size_t
376 _ksba_ber_encode_tl (unsigned char *buffer,
377  unsigned long tag,
378  enum tag_class class,
379  int constructed,
380  unsigned long length)
381 {
382  unsigned char *buf = buffer;
383 
384  if (tag < 0x1f)
385  {
386  *buf = (class << 6) | tag;
387  if (constructed)
388  *buf |= 0x20;
389  buf++;
390  }
391  else
392  {
393  return 0; /*Not implemented*/
394  }
395 
396  if (!tag && !class)
397  *buf++ = 0; /* end tag */
398  else if (tag == TYPE_NULL && !class)
399  *buf++ = 0; /* NULL tag */
400  else if (!length)
401  *buf++ = 0x80; /* indefinite length */
402  else if (length < 128)
403  *buf++ = length;
404  else
405  {
406  int i;
407 
408  /* fixme: if we know the sizeof an ulong we could support larger
409  objetcs - however this is pretty ridiculous */
410  i = (length <= 0xff ? 1:
411  length <= 0xffff ? 2:
412  length <= 0xffffff ? 3: 4);
413 
414  *buf++ = (0x80 | i);
415  if (i > 3)
416  *buf++ = length >> 24;
417  if (i > 2)
418  *buf++ = length >> 16;
419  if (i > 1)
420  *buf++ = length >> 8;
421  *buf++ = length;
422  }
423 
424  return buf - buffer;
425 }
426 
427 
428 /* Calculate the length of the TL needed to encode a TAG of CLASS.
429  CONSTRUCTED is a flag telling whether the value is a constructed
430  one. LENGTH gives the length of the value; if it is 0 an
431  indefinite length is assumed. LENGTH is ignored for the NULL
432  tag. */
433 size_t
434 _ksba_ber_count_tl (unsigned long tag,
435  enum tag_class class,
436  int constructed,
437  unsigned long length)
438 {
439  int buflen = 0;
440 
441  (void)constructed; /* Not used, but passed for uniformity of such calls. */
442 
443  /* coverity[identical_branches] */
444  if (tag < 0x1f)
445  {
446  buflen++;
447  }
448  else
449  {
450  buflen++; /* assume one and let the actual write function bail out */
451  }
452 
453  if (!tag && !class)
454  buflen++; /* end tag */
455  else if (tag == TYPE_NULL && !class)
456  buflen++; /* NULL tag */
457  else if (!length)
458  buflen++; /* indefinite length */
459  else if (length < 128)
460  buflen++;
461  else
462  {
463  int i;
464 
465  /* fixme: if we know the sizeof an ulong we could support larger
466  objetcs - however this is pretty ridiculous */
467  i = (length <= 0xff ? 1:
468  length <= 0xffff ? 2:
469  length <= 0xffffff ? 3: 4);
470 
471  buflen++;
472  if (i > 3)
473  buflen++;
474  if (i > 2)
475  buflen++;
476  if (i > 1)
477  buflen++;
478  buflen++;
479  }
480 
481  return buflen;
482 }
483 
484 
485 gpg_error_t
486 _ksba_parse_sequence (unsigned char const **buf, size_t *len,
487  struct tag_info *ti)
488 {
489  gpg_error_t err;
490 
491  err = _ksba_ber_parse_tl (buf, len, ti);
492  if (err)
493  ;
494  else if (!(ti->class == CLASS_UNIVERSAL && ti->tag == TYPE_SEQUENCE
495  && ti->is_constructed) )
496  err = gpg_error (GPG_ERR_INV_OBJ);
497  else if (ti->length > *len)
498  err = gpg_error (GPG_ERR_BAD_BER);
499  return err;
500 }
501 
502 
503 /* Note that this function returns GPG_ERR_FALSE if the TLV is valid
504  * but the tag does not match. The caller may thus check for this
505  * error code and compare against other tag values. */
506 gpg_error_t
507 _ksba_parse_context_tag (unsigned char const **buf, size_t *len,
508  struct tag_info *ti, int tag)
509 {
510  gpg_error_t err;
511 
512  err = _ksba_ber_parse_tl (buf, len, ti);
513  if (err)
514  ;
515  else if (!(ti->class == CLASS_CONTEXT && ti->is_constructed))
516  err = gpg_error (GPG_ERR_INV_OBJ);
517  else if (ti->length > *len)
518  err = gpg_error (GPG_ERR_BAD_BER);
519  else if (ti->tag != tag)
520  err = gpg_error (GPG_ERR_FALSE);
521 
522  return err;
523 }
524 
525 
526 gpg_error_t
527 _ksba_parse_enumerated (unsigned char const **buf, size_t *len,
528  struct tag_info *ti, size_t maxlen)
529 {
530  gpg_error_t err;
531 
532  err = _ksba_ber_parse_tl (buf, len, ti);
533  if (err)
534  ;
535  else if (!(ti->class == CLASS_UNIVERSAL && ti->tag == TYPE_ENUMERATED
536  && !ti->is_constructed) )
537  err = gpg_error (GPG_ERR_INV_OBJ);
538  else if (!ti->length)
539  err = gpg_error (GPG_ERR_TOO_SHORT);
540  else if (maxlen && ti->length > maxlen)
541  err = gpg_error (GPG_ERR_TOO_LARGE);
542  else if (ti->length > *len)
543  err = gpg_error (GPG_ERR_BAD_BER);
544 
545  return err;
546 }
547 
548 
549 gpg_error_t
550 _ksba_parse_integer (unsigned char const **buf, size_t *len,
551  struct tag_info *ti)
552 {
553  gpg_error_t err;
554 
555  err = _ksba_ber_parse_tl (buf, len, ti);
556  if (err)
557  ;
558  else if (!(ti->class == CLASS_UNIVERSAL && ti->tag == TYPE_INTEGER
559  && !ti->is_constructed) )
560  err = gpg_error (GPG_ERR_INV_OBJ);
561  else if (!ti->length)
562  err = gpg_error (GPG_ERR_TOO_SHORT);
563  else if (ti->length > *len)
564  err = gpg_error (GPG_ERR_BAD_BER);
565 
566  return err;
567 }
568 
569 
570 gpg_error_t
571 _ksba_parse_octet_string (unsigned char const **buf, size_t *len,
572  struct tag_info *ti)
573 {
574  gpg_error_t err;
575 
576  err= _ksba_ber_parse_tl (buf, len, ti);
577  if (err)
578  ;
579  else if (!(ti->class == CLASS_UNIVERSAL && ti->tag == TYPE_OCTET_STRING
580  && !ti->is_constructed) )
581  err = gpg_error (GPG_ERR_INV_OBJ);
582  else if (!ti->length)
583  err = gpg_error (GPG_ERR_TOO_SHORT);
584  else if (ti->length > *len)
585  err = gpg_error (GPG_ERR_BAD_BER);
586 
587  return err;
588 }
589 
590 
591 /* Note that R_BOOL will only be set if a value has been given. Thus
592  the caller should set it to the default value prior to calling this
593  function. Obviously no call to parse_skip is required after
594  calling this function. */
595 gpg_error_t
596 _ksba_parse_optional_boolean (unsigned char const **buf, size_t *len,
597  int *r_bool)
598 {
599  gpg_error_t err;
600  struct tag_info ti;
601 
602  err = _ksba_ber_parse_tl (buf, len, &ti);
603  if (err)
604  ;
605  else if (!ti.length)
606  err = gpg_error (GPG_ERR_TOO_SHORT);
607  else if (ti.length > *len)
608  err = gpg_error (GPG_ERR_BAD_BER);
609  else if (ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_BOOLEAN
610  && !ti.is_constructed)
611  {
612  if (ti.length != 1)
613  err = gpg_error (GPG_ERR_BAD_BER);
614  *r_bool = !!**buf;
615  parse_skip (buf, len, &ti);
616  }
617  else
618  { /* Undo the read. */
619  *buf -= ti.nhdr;
620  *len += ti.nhdr;
621  }
622 
623  return err;
624 }
625 
626 
627 /* Parse an optional Null tag. Ir R_SEEN is not NULL it is set to
628  * true if a NULL tag was encountered. */
629 gpg_error_t
630 _ksba_parse_optional_null (unsigned char const **buf, size_t *len,
631  int *r_seen)
632 {
633  gpg_error_t err;
634  struct tag_info ti;
635 
636  if (r_seen)
637  *r_seen = 0;
638  err = _ksba_ber_parse_tl (buf, len, &ti);
639  if (err)
640  ;
641  else if (ti.length > *len)
642  err = gpg_error (GPG_ERR_BAD_BER);
643  else if (ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_NULL
644  && !ti.is_constructed)
645  {
646  if (ti.length)
647  err = gpg_error (GPG_ERR_BAD_BER);
648  if (r_seen)
649  *r_seen = 1;
650  parse_skip (buf, len, &ti);
651  }
652  else
653  { /* Undo the read. */
654  *buf -= ti.nhdr;
655  *len += ti.nhdr;
656  }
657 
658  return err;
659 }
660 
661 
662 
663 gpg_error_t
664 _ksba_parse_object_id_into_str (unsigned char const **buf, size_t *len,
665  char **oid)
666 {
667  struct tag_info ti;
668  gpg_error_t err;
669 
670  *oid = NULL;
671  err = _ksba_ber_parse_tl (buf, len, &ti);
672  if (err)
673  ;
674  else if (!(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_OBJECT_ID
675  && !ti.is_constructed) )
676  err = gpg_error (GPG_ERR_INV_OBJ);
677  else if (!ti.length)
678  err = gpg_error (GPG_ERR_TOO_SHORT);
679  else if (ti.length > *len)
680  err = gpg_error (GPG_ERR_BAD_BER);
681  else if (!(*oid = ksba_oid_to_str (*buf, ti.length)))
682  err = gpg_error_from_syserror ();
683  else
684  {
685  *buf += ti.length;
686  *len -= ti.length;
687  }
688  return err;
689 }
690 
691 
692 gpg_error_t
693 _ksba_parse_asntime_into_isotime (unsigned char const **buf, size_t *len,
694  ksba_isotime_t isotime)
695 {
696  struct tag_info ti;
697  gpg_error_t err;
698 
699  err = _ksba_ber_parse_tl (buf, len, &ti);
700  if (err)
701  ;
702  else if ( !(ti.class == CLASS_UNIVERSAL
703  && (ti.tag == TYPE_UTC_TIME || ti.tag == TYPE_GENERALIZED_TIME)
704  && !ti.is_constructed) )
705  err = gpg_error (GPG_ERR_INV_OBJ);
706  else if (ti.length > *len)
707  err = gpg_error (GPG_ERR_INV_BER);
708  else if (!(err = _ksba_asntime_to_iso (*buf, ti.length,
709  ti.tag == TYPE_UTC_TIME, isotime)))
710  parse_skip (buf, len, &ti);
711 
712  return err;
713 }
@ TYPE_OCTET_STRING
@ TYPE_NULL
@ TYPE_GENERALIZED_TIME
@ TYPE_OBJECT_ID
@ TYPE_BOOLEAN
@ TYPE_INTEGER
@ TYPE_ENUMERATED
@ TYPE_SEQUENCE
@ TYPE_UTC_TIME
tag_class
@ CLASS_CONTEXT
@ CLASS_UNIVERSAL
gpg_error_t _ksba_parse_object_id_into_str(unsigned char const **buf, size_t *len, char **oid)
Definition: ber-help.c:664
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_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
gpg_error_t _ksba_parse_optional_boolean(unsigned char const **buf, size_t *len, int *r_bool)
Definition: ber-help.c:596
static int read_byte(ksba_reader_t reader)
Definition: ber-help.c:47
gpg_error_t _ksba_parse_enumerated(unsigned char const **buf, size_t *len, struct tag_info *ti, size_t maxlen)
Definition: ber-help.c:527
gpg_error_t _ksba_parse_sequence(unsigned char const **buf, size_t *len, struct tag_info *ti)
Definition: ber-help.c:486
size_t _ksba_ber_encode_tl(unsigned char *buffer, unsigned long tag, enum tag_class class, int constructed, unsigned long length)
Definition: ber-help.c:376
size_t _ksba_ber_count_tl(unsigned long tag, enum tag_class class, int constructed, unsigned long length)
Definition: ber-help.c:434
static gpg_error_t eof_or_error(ksba_reader_t reader, struct tag_info *ti, int premature)
Definition: ber-help.c:71
gpg_error_t _ksba_parse_octet_string(unsigned char const **buf, size_t *len, struct tag_info *ti)
Definition: ber-help.c:571
gpg_error_t _ksba_parse_context_tag(unsigned char const **buf, size_t *len, struct tag_info *ti, int tag)
Definition: ber-help.c:507
static int premature_eof(struct tag_info *ti)
Definition: ber-help.c:61
gpg_error_t _ksba_parse_optional_null(unsigned char const **buf, size_t *len, int *r_seen)
Definition: ber-help.c:630
gpg_error_t _ksba_parse_integer(unsigned char const **buf, size_t *len, struct tag_info *ti)
Definition: ber-help.c:550
gpg_error_t _ksba_parse_asntime_into_isotime(unsigned char const **buf, size_t *len, ksba_isotime_t isotime)
Definition: ber-help.c:693
static void parse_skip(unsigned char const **buf, size_t *len, struct tag_info *ti)
Definition: ber-help.h:68
const char * oid
Definition: cms.c:71
gpg_error_t _ksba_asntime_to_iso(const char *buffer, size_t length, int is_utctime, ksba_isotime_t timebuf)
Definition: time.c:52
#define DIM(v)
Definition: gen-help.h:46
#define gpg_error_from_syserror()
Definition: gen-help.h:88
#define gpg_error(a)
Definition: gen-help.h:87
gpg_error_t ksba_writer_write(ksba_writer_t w, const void *buffer, size_t length)
char ksba_isotime_t[16]
Definition: ksba.h:212
char * ksba_oid_to_str(const char *buffer, size_t length)
gpg_error_t ksba_reader_read(ksba_reader_t r, char *buffer, size_t length, size_t *nread)
gpg_error_t ksba_reader_error(ksba_reader_t r)
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
const char * err_string
Definition: ber-help.h:43
unsigned long length
Definition: ber-help.h:39
int non_der
Definition: ber-help.h:44
int ndef
Definition: ber-help.h:40
enum tag_class class
Definition: ber-help.h:36
size_t nhdr
Definition: ber-help.h:41