Imported Upstream version 1.3.4
[platform/upstream/libksba.git] / src / cert.c
1 /* cert.c - main function for the certificate handling
2  *      Copyright (C) 2001, 2002, 2003, 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 #include "ber-decoder.h"
40 #include "ber-help.h"
41 #include "convert.h"
42 #include "keyinfo.h"
43 #include "sexp-parse.h"
44 #include "cert.h"
45
46
47 static const char oidstr_subjectKeyIdentifier[] = "2.5.29.14";
48 static const char oidstr_keyUsage[]         = "2.5.29.15";
49 static const char oidstr_subjectAltName[]   = "2.5.29.17";
50 static const char oidstr_issuerAltName[]    = "2.5.29.18";
51 static const char oidstr_basicConstraints[] = "2.5.29.19";
52 static const char oidstr_crlDistributionPoints[] = "2.5.29.31";
53 static const char oidstr_certificatePolicies[] = "2.5.29.32";
54 static const char oidstr_authorityKeyIdentifier[] = "2.5.29.35";
55 static const char oidstr_extKeyUsage[] = "2.5.29.37";
56 static const char oidstr_authorityInfoAccess[] = "1.3.6.1.5.5.7.1.1";
57 static const char oidstr_subjectInfoAccess[]   = "1.3.6.1.5.5.7.1.11";
58
59
60 /**
61  * ksba_cert_new:
62  *
63  * Create a new and empty certificate object
64  *
65  * Return value: 0 on success or error code.  For a successful
66  * operation, ACERT is set to the new certifixate obbject, otherwise
67  * it is set to NULL.
68  **/
69 gpg_error_t
70 ksba_cert_new (ksba_cert_t *acert)
71 {
72   *acert = xtrycalloc (1, sizeof **acert);
73   if (!*acert)
74     return gpg_error_from_errno (errno);
75   (*acert)->ref_count++;
76
77   return 0;
78 }
79
80 void
81 ksba_cert_ref (ksba_cert_t cert)
82 {
83   if (!cert)
84     fprintf (stderr, "BUG: ksba_cert_ref for NULL\n");
85   else
86     ++cert->ref_count;
87 }
88
89 /**
90  * ksba_cert_release:
91  * @cert: A certificate object
92  *
93  * Release a certificate object.
94  **/
95 void
96 ksba_cert_release (ksba_cert_t cert)
97 {
98   int i;
99
100   if (!cert)
101     return;
102   if (cert->ref_count < 1)
103     {
104       fprintf (stderr, "BUG: trying to release an already released cert\n");
105       return;
106     }
107   if (--cert->ref_count)
108     return;
109
110   if (cert->udata)
111     {
112       struct cert_user_data *ud = cert->udata;
113       cert->udata = NULL;
114       do
115         {
116           struct cert_user_data *ud2 = ud->next;
117           if (ud->data && ud->data != ud->databuf)
118             xfree (ud->data);
119           xfree (ud);
120           ud = ud2;
121         }
122       while (ud);
123     }
124
125   xfree (cert->cache.digest_algo);
126   if (cert->cache.extns_valid)
127     {
128       for (i=0; i < cert->cache.n_extns; i++)
129         xfree (cert->cache.extns[i].oid);
130       xfree (cert->cache.extns);
131     }
132
133   _ksba_asn_release_nodes (cert->root);
134   ksba_asn_tree_release (cert->asn_tree);
135
136   xfree (cert->image);
137
138   xfree (cert);
139 }
140
141
142 /* Store arbitrary data along with a certificate.  The DATA of length
143    DATALEN will be stored under the string KEY.  If some data is
144    already stored under this key it will be replaced by the new data.
145    Using NULL for DATA will effectivly delete the data.
146
147    On error (i.e. out or memory) an already existing data object
148    stored under KEY may get deleted.
149
150    This function is not thread safe because we don't employ any
151    locking. */
152 gpg_error_t
153 ksba_cert_set_user_data (ksba_cert_t cert,
154                          const char *key, const void *data, size_t datalen)
155 {
156   struct cert_user_data *ud;
157
158   if (!cert || !key || !*key)
159     return gpg_error (GPG_ERR_INV_VALUE);
160
161   for (ud=cert->udata; ud; ud = ud->next)
162     if (!strcmp (ud->key, key))
163       break;
164   if (ud)  /* Update the data stored under this key or reuse this item. */
165     {
166       if (ud->data && ud->data != ud->databuf)
167         xfree (ud->data);
168       ud->data = NULL;
169       if (data && datalen <= sizeof ud->databuf)
170         {
171           memcpy (ud->databuf, data, datalen);
172           ud->data = ud->databuf;
173           ud->datalen = datalen;
174         }
175       else if (data)
176         {
177           ud->data = xtrymalloc (datalen);
178           if (!ud->data)
179             return gpg_error_from_errno (errno);
180           memcpy (ud->data, data, datalen);
181           ud->datalen = datalen;
182         }
183     }
184   else if (data) /* Insert as a new item. */
185     {
186       ud = xtrycalloc (1, sizeof *ud + strlen (key));
187       if (!ud)
188         return gpg_error_from_errno (errno);
189       strcpy (ud->key, key);
190       if (datalen <= sizeof ud->databuf)
191         {
192           memcpy (ud->databuf, data, datalen);
193           ud->data = ud->databuf;
194           ud->datalen = datalen;
195         }
196       else
197         {
198           ud->data = xtrymalloc (datalen);
199           if (!ud->data)
200             {
201               xfree (ud);
202               return gpg_error_from_errno (errno);
203             }
204           memcpy (ud->data, data, datalen);
205           ud->datalen = datalen;
206         }
207       ud->next = cert->udata;
208       cert->udata = ud;
209     }
210
211   return 0;
212 }
213
214
215
216 /* Return user data for certificate CERT stored under the string
217    KEY. The caller needs to provide a suitable large BUFFER and pass
218    the usable length of the buffer in BUFFERLEN.  If DATALEN is not
219    NULL, the length of the data stored at BUFFER will be stored there.
220
221    If BUFFER is NULL, BUFFERLEN will be ignored and the required
222    length of the buffer will be returned at DATALEN.
223
224    On success 0 is returned.  If no data is stored under KEY
225    GPG_ERR_NOT_FOUND is returned.  If the provided buffer is too
226    short, GPG_ERR_BUFFER_TOO_SHORT will be returned (note, that this
227    is not the case if BUFFER is NULL).
228 */
229 gpg_error_t
230 ksba_cert_get_user_data (ksba_cert_t cert, const char *key,
231                          void *buffer, size_t bufferlen, size_t *datalen)
232 {
233   struct cert_user_data *ud;
234
235   if (!cert || !key || !*key)
236     return gpg_error (GPG_ERR_INV_VALUE);
237
238   for (ud=cert->udata; ud; ud = ud->next)
239     if (!strcmp (ud->key, key))
240       break;
241   if (!ud || !ud->data)
242     return gpg_error (GPG_ERR_NOT_FOUND);
243   if (datalen)
244     *datalen = ud->datalen;
245   if (buffer)
246     {
247       if (ud->datalen > bufferlen)
248         return gpg_error (GPG_ERR_BUFFER_TOO_SHORT);
249       memcpy (buffer, ud->data, ud->datalen);
250     }
251   return 0;
252 }
253
254
255 /**
256  * ksba_cert_read_der:
257  * @cert: An unitialized certificate object
258  * @reader: A KSBA Reader object
259  *
260  * Read the next certificate from the reader and store it in the
261  * certificate object for future access.  The certificate is parsed
262  * and rejected if it has any syntactical or semantical error
263  * (i.e. does not match the ASN.1 description).
264  *
265  * Return value: 0 on success or an error value
266  **/
267 gpg_error_t
268 ksba_cert_read_der (ksba_cert_t cert, ksba_reader_t reader)
269 {
270   gpg_error_t err = 0;
271   BerDecoder decoder = NULL;
272
273   if (!cert || !reader)
274     return gpg_error (GPG_ERR_INV_VALUE);
275   if (cert->initialized)
276     return gpg_error (GPG_ERR_CONFLICT); /* Fixme: should remove the old one */
277
278   _ksba_asn_release_nodes (cert->root);
279   ksba_asn_tree_release (cert->asn_tree);
280   cert->root = NULL;
281   cert->asn_tree = NULL;
282
283   err = ksba_asn_create_tree ("tmttv2", &cert->asn_tree);
284   if (err)
285     goto leave;
286
287   decoder = _ksba_ber_decoder_new ();
288   if (!decoder)
289     {
290       err = gpg_error (GPG_ERR_ENOMEM);
291       goto leave;
292     }
293
294   err = _ksba_ber_decoder_set_reader (decoder, reader);
295   if (err)
296     goto leave;
297
298   err = _ksba_ber_decoder_set_module (decoder, cert->asn_tree);
299   if (err)
300      goto leave;
301
302   err = _ksba_ber_decoder_decode (decoder, "TMTTv2.Certificate", 0,
303                                   &cert->root, &cert->image, &cert->imagelen);
304   if (!err)
305       cert->initialized = 1;
306
307  leave:
308   _ksba_ber_decoder_release (decoder);
309
310   return err;
311 }
312
313
314 gpg_error_t
315 ksba_cert_init_from_mem (ksba_cert_t cert, const void *buffer, size_t length)
316 {
317   gpg_error_t err;
318   ksba_reader_t reader;
319
320   err = ksba_reader_new (&reader);
321   if (err)
322     return err;
323   err = ksba_reader_set_mem (reader, buffer, length);
324   if (err)
325     {
326       ksba_reader_release (reader);
327       return err;
328     }
329   err = ksba_cert_read_der (cert, reader);
330   ksba_reader_release (reader);
331   return err;
332 }
333
334
335
336 const unsigned char *
337 ksba_cert_get_image (ksba_cert_t cert, size_t *r_length )
338 {
339   AsnNode n;
340
341   if (!cert)
342     return NULL;
343   if (!cert->initialized)
344     return NULL;
345
346   n = _ksba_asn_find_node (cert->root, "Certificate");
347   if (!n)
348     return NULL;
349
350   if (n->off == -1)
351     {
352 /*        fputs ("ksba_cert_get_image problem at node:\n", stderr); */
353 /*        _ksba_asn_node_dump_all (n, stderr); */
354       return NULL;
355     }
356
357   /* Due to minor problems in our parser we might hit the assertion
358      below.  Thus we better return a error, proper. */
359   if ( !(n->nhdr + n->len + n->off <= cert->imagelen) )
360     {
361       fprintf (stderr,"\nOops, ksba_cert_get_image failed: "
362                "imagelen=%lu  hdr=%d len=%d off=%d\n",
363                (unsigned long)cert->imagelen, n->nhdr, (int)n->len, n->off);
364       return NULL;
365     }
366   /*assert (n->nhdr + n->len + n->off <= cert->imagelen);*/
367
368   if (r_length)
369     *r_length = n->nhdr + n->len;
370   return cert->image + n->off;
371 }
372
373 /* Check whether certificates A and B are identical and return o in
374    this case. */
375 int
376 _ksba_cert_cmp (ksba_cert_t a, ksba_cert_t b)
377 {
378   const unsigned char *img_a, *img_b;
379   size_t len_a, len_b;
380
381   img_a = ksba_cert_get_image (a, &len_a);
382   if (!img_a)
383     return 1;
384   img_b = ksba_cert_get_image (b, &len_b);
385   if (!img_b)
386     return 1;
387   return !(len_a == len_b && !memcmp (img_a, img_b, len_a));
388 }
389
390
391
392
393 gpg_error_t
394 ksba_cert_hash (ksba_cert_t cert, int what,
395                 void (*hasher)(void *, const void *, size_t length),
396                 void *hasher_arg)
397 {
398   AsnNode n;
399
400   if (!cert /*|| !hasher*/)
401     return gpg_error (GPG_ERR_INV_VALUE);
402   if (!cert->initialized)
403     return gpg_error (GPG_ERR_NO_DATA);
404
405   n = _ksba_asn_find_node (cert->root,
406                            what == 1? "Certificate.tbsCertificate"
407                                     : "Certificate");
408   if (!n)
409     return gpg_error (GPG_ERR_NO_VALUE); /* oops - should be there */
410   if (n->off == -1)
411     {
412 /*        fputs ("ksba_cert_hash problem at node:\n", stderr); */
413 /*        _ksba_asn_node_dump_all (n, stderr); */
414       return gpg_error (GPG_ERR_NO_VALUE);
415     }
416
417   hasher (hasher_arg, cert->image + n->off,  n->nhdr + n->len);
418
419
420   return 0;
421 }
422
423
424
425 /**
426  * ksba_cert_get_digest_algo:
427  * @cert: Initialized certificate object
428  *
429  * Figure out the the digest algorithm used for the signature and
430  * return its OID
431  *
432  * This function is intended as a helper for the ksba_cert_hash().
433  *
434  * Return value: NULL for error otherwise a constant string with the OID.
435  * This string is valid as long the certificate object is valid.
436  **/
437 const char *
438 ksba_cert_get_digest_algo (ksba_cert_t cert)
439 {
440   gpg_error_t err;
441   AsnNode n;
442   char *algo;
443   size_t nread;
444
445   if (!cert)
446     return NULL;  /* Ooops (can't set cert->last_error :-().  */
447
448   if (!cert->initialized)
449     {
450        cert->last_error = gpg_error (GPG_ERR_NO_DATA);
451        return NULL;
452     }
453
454   if (cert->cache.digest_algo)
455     return cert->cache.digest_algo;
456
457 /*   n = _ksba_asn_find_node (cert->root, */
458 /*                            "Certificate.signatureAlgorithm.algorithm"); */
459 /*   algo = _ksba_oid_node_to_str (cert->image, n); */
460 /*   if (!algo) */
461 /*     cert->last_error = gpg_error (GPG_ERR_UNKNOWN_ALGORITHM); */
462 /*   else  */
463 /*     cert->cache.digest_algo = algo; */
464
465   n = _ksba_asn_find_node (cert->root, "Certificate.signatureAlgorithm");
466   if (!n || n->off == -1)
467     {
468       algo = NULL;
469       err = gpg_error (GPG_ERR_UNKNOWN_ALGORITHM);
470     }
471   else
472     err = _ksba_parse_algorithm_identifier (cert->image + n->off,
473                                             n->nhdr + n->len, &nread, &algo);
474   if (err)
475     cert->last_error = err;
476   else
477     cert->cache.digest_algo = algo;
478
479   return algo;
480 }
481
482
483
484
485 /**
486  * ksba_cert_get_serial:
487  * @cert: certificate object
488  *
489  * This function returnes the serial number of the certificate.  The
490  * serial number is an integer returned as an canonical encoded
491  * S-expression with just one element.
492  *
493  * Return value: An allocated S-Exp or NULL for no value.
494  **/
495 ksba_sexp_t
496 ksba_cert_get_serial (ksba_cert_t cert)
497 {
498   AsnNode n;
499   char *p;
500   char numbuf[22];
501   int numbuflen;
502
503   if (!cert || !cert->initialized)
504     return NULL;
505
506   n = _ksba_asn_find_node (cert->root,
507                            "Certificate.tbsCertificate.serialNumber");
508   if (!n)
509     return NULL; /* oops - should be there */
510
511   if (n->off == -1)
512     {
513 /*        fputs ("get_serial problem at node:\n", stderr); */
514 /*        _ksba_asn_node_dump_all (n, stderr); */
515       return NULL;
516     }
517
518   sprintf (numbuf,"(%u:", (unsigned int)n->len);
519   numbuflen = strlen (numbuf);
520   p = xtrymalloc (numbuflen + n->len + 2);
521   if (!p)
522     return NULL;
523   strcpy (p, numbuf);
524   memcpy (p+numbuflen, cert->image + n->off + n->nhdr, n->len);
525   p[numbuflen + n->len] = ')';
526   p[numbuflen + n->len + 1] = 0;
527   return p;
528 }
529
530
531 /* Return a pointer to the DER encoding of the serial number in CERT in
532    PTR and the length of that field in LENGTH.  */
533 gpg_error_t
534 _ksba_cert_get_serial_ptr (ksba_cert_t cert,
535                            unsigned char const **ptr, size_t *length)
536 {
537   asn_node_t n;
538
539   if (!cert || !cert->initialized || !ptr || !length)
540     return gpg_error (GPG_ERR_INV_VALUE);
541   n = _ksba_asn_find_node (cert->root,
542                            "Certificate.tbsCertificate.serialNumber");
543   if (!n || n->off == -1)
544     return gpg_error (GPG_ERR_NO_VALUE);
545
546   *ptr = cert->image + n->off + n->nhdr;
547   *length = n->len;
548   return 0;
549 }
550
551
552
553 /* Return a pointer to the DER encoding of the subject's DN in CERT in
554    PTR and the length of that object in LENGTH.  */
555 gpg_error_t
556 _ksba_cert_get_subject_dn_ptr (ksba_cert_t cert,
557                                unsigned char const **ptr, size_t *length)
558 {
559   asn_node_t n;
560
561   if (!cert || !cert->initialized || !ptr || !length)
562     return gpg_error (GPG_ERR_INV_VALUE);
563
564   n = _ksba_asn_find_node (cert->root, "Certificate.tbsCertificate.subject");
565   if (!n || !n->down)
566     return gpg_error (GPG_ERR_NO_VALUE); /* oops - should be there */
567   n = n->down; /* dereference the choice node */
568   if (n->off == -1)
569     return gpg_error (GPG_ERR_NO_VALUE);
570   *ptr = cert->image + n->off;
571   *length = n->nhdr + n->len;
572   return 0;
573 }
574
575
576
577 /* Worker function for get_isssuer and get_subject. */
578 static gpg_error_t
579 get_name (ksba_cert_t cert, int idx, int use_subject, char **result)
580 {
581   gpg_error_t err;
582   char *p;
583   int i;
584   const char *oid;
585   struct tag_info ti;
586   const unsigned char *der;
587   size_t off, derlen, seqlen;
588
589   if (!cert || !cert->initialized || !result)
590     return gpg_error (GPG_ERR_INV_VALUE);
591   if (idx < 0)
592     return gpg_error (GPG_ERR_INV_INDEX);
593
594   *result = NULL;
595   if (!idx)
596     { /* Get the required DN */
597       AsnNode n;
598
599       n = _ksba_asn_find_node (cert->root,
600                                (use_subject?
601                                 "Certificate.tbsCertificate.subject":
602                                 "Certificate.tbsCertificate.issuer") );
603       if (!n || !n->down)
604         return gpg_error (GPG_ERR_NO_VALUE); /* oops - should be there */
605       n = n->down; /* dereference the choice node */
606       if (n->off == -1)
607         return gpg_error (GPG_ERR_NO_VALUE);
608
609       err = _ksba_dn_to_str (cert->image, n, &p);
610       if (err)
611         return err;
612       *result = p;
613       return 0;
614     }
615
616   /* get {issuer,subject}AltName */
617   for (i=0; !(err=ksba_cert_get_extension (cert, i, &oid, NULL,
618                                            &off, &derlen)); i++)
619     {
620       if (!strcmp (oid, (use_subject?
621                          oidstr_subjectAltName:oidstr_issuerAltName)))
622         break;
623     }
624   if (err)
625       return err; /* no alt name or error*/
626
627   der = cert->image + off;
628
629
630   /* FIXME: We should use _ksba_name_new_from_der and ksba_name_enum here */
631
632   err = _ksba_ber_parse_tl (&der, &derlen, &ti);
633   if (err)
634     return err;
635   if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SEQUENCE
636          && ti.is_constructed) )
637     return gpg_error (GPG_ERR_INV_CERT_OBJ);
638   if (ti.ndef)
639     return gpg_error (GPG_ERR_NOT_DER_ENCODED);
640   seqlen = ti.length;
641   if (seqlen > derlen)
642     return gpg_error (GPG_ERR_BAD_BER);
643   if (!seqlen)
644     return gpg_error (GPG_ERR_INV_CERT_OBJ); /* empty sequence is not allowed */
645
646   while (seqlen)
647     {
648       err = _ksba_ber_parse_tl (&der, &derlen, &ti);
649       if (err)
650         return err;
651       if (ti.class != CLASS_CONTEXT)
652         return gpg_error (GPG_ERR_INV_CERT_OBJ); /* we expected a tag */
653       if (ti.ndef)
654         return gpg_error (GPG_ERR_NOT_DER_ENCODED);
655       if (seqlen < ti.nhdr)
656         return gpg_error (GPG_ERR_BAD_BER);
657       seqlen -= ti.nhdr;
658       if (seqlen < ti.length)
659         return gpg_error (GPG_ERR_BAD_BER);
660       seqlen -= ti.length;
661       if (derlen < ti.length)
662         return gpg_error (GPG_ERR_BAD_BER);
663       if (!(ti.tag == 1 || ti.tag == 2 || ti.tag == 6))
664         ; /* Not a supported tag: Do not change IDX. */
665       else if (--idx)
666         ; /* not yet at the desired index */
667       else if (ti.tag == 1)
668         { /* rfc822Name - this is an implicit IA5_STRING */
669           p = xtrymalloc (ti.length+3);
670           if (!p)
671             return gpg_error (GPG_ERR_ENOMEM);
672           *p = '<';
673           memcpy (p+1, der, ti.length);
674           p[ti.length+1] = '>';
675           p[ti.length+2] = 0;
676           *result = p;
677           return 0;
678         }
679       else if (ti.tag == 2 || ti.tag == 6)
680         { /* dNSName or URI - this are implicit IA5_STRINGs */
681           char numbuf[20], *numbufp;
682           size_t numbuflen;
683
684           numbufp = smklen (numbuf, DIM(numbuf), ti.length, &numbuflen);
685           p = xtrymalloc (11 + numbuflen + ti.length + 3);
686           if (!p)
687             return gpg_error (GPG_ERR_ENOMEM);
688           *result = p;
689           p = stpcpy (p, ti.tag == 2? "(8:dns-name" : "(3:uri");
690           p = stpcpy (p, numbufp);
691           memcpy (p, der, ti.length);
692           p += ti.length;
693           *p++ = ')';
694           *p = 0;
695           return 0;
696         }
697
698       /* advance pointer */
699       der += ti.length;
700       derlen -= ti.length;
701     }
702
703   return gpg_error (GPG_ERR_EOF);
704 }
705
706
707
708 /**
709  * ksba_cert_get_issuer:
710  * @cert: certificate object
711  *
712  * With @idx == 0 this function returns the Distinguished Name (DN) of
713  * the certificate issuer which in most cases is a CA.  The format of
714  * the returned string is in accordance with RFC-2253.  NULL is
715  * returned if the DN is not available which is an error and should
716  * have been catched by the certificate reading function.
717  *
718  * With @idx > 0 the function may be used to enumerate alternate
719  * issuer names. The function returns NULL if there are no more
720  * alternate names.  The function does only return alternate names
721  * which are recognized by libksba and ignores others.  The format of
722  * the returned name is either a RFC-2253 formated one which can be
723  * detected by checking whether the first character is letter or
724  * digit.  rfc-2822 conform email addresses are returned enclosed in
725  * angle brackets, the opening angle bracket should be used to
726  * indicate this.  Other formats are returned as an S-Expression in
727  * canonical format, so a opening parenthesis may be used to detect
728  * this encoding, the name may include binary null characters, so
729  * strlen may return a length shorther than actually used, the real
730  * length is implictly given by the structure of the S-Exp, an extra
731  * null is appended for safety reasons.
732  *
733  * The caller must free the returned string using ksba_free() or the
734  * function he has registered as a replacement.
735  *
736  * Return value: An allocated string or NULL for error.
737  **/
738 char *
739 ksba_cert_get_issuer (ksba_cert_t cert, int idx)
740 {
741   gpg_error_t err;
742   char *name;
743
744   err = get_name (cert, idx, 0, &name);
745   if (err)
746     {
747       cert->last_error = err;
748       return NULL;
749     }
750   return name;
751 }
752
753 /* See ..get_issuer */
754 char *
755 ksba_cert_get_subject (ksba_cert_t cert, int idx)
756 {
757   gpg_error_t err;
758   char *name;
759
760   err = get_name (cert, idx, 1, &name);
761   if (err)
762     {
763       cert->last_error = err;
764       return NULL;
765     }
766   return name;
767 }
768
769
770
771 /**
772  * ksba_cert_get_valididy:
773  * @cert: certificate object
774  * @what: 0 for notBefore, 1 for notAfter
775  * @timebuf: Returns the time.
776  *
777  * Return the validity object from the certificate.  If no value is
778  * available 0 is returned because we can safely assume that this is
779  * not a valid date.
780  *
781  * Return value: The time value an 0 or an error code.
782  **/
783 gpg_error_t
784 ksba_cert_get_validity (ksba_cert_t cert, int what, ksba_isotime_t timebuf)
785 {
786   AsnNode n, n2;
787
788   if (!cert || what < 0 || what > 1)
789     return gpg_error (GPG_ERR_INV_VALUE);
790   *timebuf = 0;
791   if (!cert->initialized)
792     return gpg_error (GPG_ERR_NO_DATA);
793
794   n = _ksba_asn_find_node (cert->root,
795         what == 0? "Certificate.tbsCertificate.validity.notBefore"
796                  : "Certificate.tbsCertificate.validity.notAfter");
797   if (!n)
798     return 0; /* no value available */
799
800   /* Fixme: We should remove the choice node and don't use this ugly hack */
801   for (n2=n->down; n2; n2 = n2->right)
802     {
803       if ((n2->type == TYPE_UTC_TIME || n2->type == TYPE_GENERALIZED_TIME)
804           && n2->off != -1)
805         break;
806     }
807   n = n2;
808   if (!n)
809     return 0; /* no value available */
810
811   return_val_if_fail (n->off != -1, gpg_error (GPG_ERR_BUG));
812
813   return _ksba_asntime_to_iso (cert->image + n->off + n->nhdr, n->len,
814                                n->type == TYPE_UTC_TIME, timebuf);
815 }
816
817
818
819 ksba_sexp_t
820 ksba_cert_get_public_key (ksba_cert_t cert)
821 {
822   AsnNode n;
823   gpg_error_t err;
824   ksba_sexp_t string;
825
826   if (!cert)
827     return NULL;
828   if (!cert->initialized)
829     return NULL;
830
831   n = _ksba_asn_find_node (cert->root,
832                            "Certificate"
833                            ".tbsCertificate.subjectPublicKeyInfo");
834   if (!n)
835     {
836       cert->last_error = gpg_error (GPG_ERR_NO_VALUE);
837       return NULL;
838     }
839
840   err = _ksba_keyinfo_to_sexp (cert->image + n->off, n->nhdr + n->len,
841                                &string);
842   if (err)
843     {
844       cert->last_error = err;
845       return NULL;
846     }
847
848   return string;
849 }
850
851 /* Return a pointer to the DER encoding of the actual public key
852    (i.e. the bit string) in PTR and the length of that object in
853    LENGTH.  */
854 gpg_error_t
855 _ksba_cert_get_public_key_ptr (ksba_cert_t cert,
856                                unsigned char const **ptr, size_t *length)
857 {
858   asn_node_t n;
859
860   if (!cert || !cert->initialized || !ptr || !length)
861     return gpg_error (GPG_ERR_INV_VALUE);
862
863   n = _ksba_asn_find_node (cert->root,
864                            "Certificate.tbsCertificate.subjectPublicKeyInfo");
865   if (!n || !n->down || !n->down->right)
866     return gpg_error (GPG_ERR_NO_VALUE); /* oops - should be there */
867   n = n->down->right;
868   if (n->off == -1)
869     return gpg_error (GPG_ERR_NO_VALUE);
870   *ptr = cert->image + n->off + n->nhdr;
871   *length = n->len;
872   /* Somehow we end up at the preceding NULL value, and not at a
873      sequence, we hack it way here. */
874   if (*length && !**ptr)
875     {
876       (*length)--;
877       (*ptr)++;
878     }
879
880   return 0;
881 }
882
883
884
885 ksba_sexp_t
886 ksba_cert_get_sig_val (ksba_cert_t cert)
887 {
888   AsnNode n, n2;
889   gpg_error_t err;
890   ksba_sexp_t string;
891
892   if (!cert)
893     return NULL;
894   if (!cert->initialized)
895     return NULL;
896
897   n = _ksba_asn_find_node (cert->root,
898                            "Certificate.signatureAlgorithm");
899   if (!n)
900     {
901       cert->last_error = gpg_error (GPG_ERR_NO_VALUE);
902       return NULL;
903     }
904   if (n->off == -1)
905     {
906 /*        fputs ("ksba_cert_get_sig_val problem at node:\n", stderr); */
907 /*        _ksba_asn_node_dump_all (n, stderr); */
908       cert->last_error = gpg_error (GPG_ERR_NO_VALUE);
909       return NULL;
910     }
911
912   n2 = n->right;
913   err = _ksba_sigval_to_sexp (cert->image + n->off,
914                               n->nhdr + n->len
915                               + ((!n2||n2->off == -1)? 0:(n2->nhdr+n2->len)),
916                               &string);
917   if (err)
918     {
919       cert->last_error = err;
920       return NULL;
921     }
922
923   return string;
924 }
925
926 \f
927 /* Read all extensions into the cache */
928 static gpg_error_t
929 read_extensions (ksba_cert_t cert)
930 {
931   AsnNode start, n;
932   int count;
933
934   assert (!cert->cache.extns_valid);
935   assert (!cert->cache.extns);
936
937   start = _ksba_asn_find_node (cert->root,
938                                "Certificate.tbsCertificate.extensions..");
939   for (count=0, n=start; n; n = n->right)
940     count++;
941   if (!count)
942     {
943       cert->cache.n_extns = 0;
944       cert->cache.extns_valid = 1;
945       return 0; /* no extensions at all */
946     }
947   cert->cache.extns = xtrycalloc (count, sizeof *cert->cache.extns);
948   if (!cert->cache.extns)
949     return gpg_error (GPG_ERR_ENOMEM);
950   cert->cache.n_extns = count;
951
952   {
953     for (count=0; start; start = start->right, count++)
954       {
955         n = start->down;
956         if (!n || n->type != TYPE_OBJECT_ID)
957           goto no_value;
958
959         cert->cache.extns[count].oid = _ksba_oid_node_to_str (cert->image, n);
960         if (!cert->cache.extns[count].oid)
961           goto no_value;
962
963         n = n->right;
964         if (n && n->type == TYPE_BOOLEAN)
965           {
966             if (n->off != -1 && n->len && cert->image[n->off + n->nhdr])
967               cert->cache.extns[count].crit = 1;
968             n = n->right;
969           }
970
971         if (!n || n->type != TYPE_OCTET_STRING || n->off == -1)
972           goto no_value;
973
974         cert->cache.extns[count].off = n->off + n->nhdr;
975         cert->cache.extns[count].len = n->len;
976       }
977
978     assert (count == cert->cache.n_extns);
979     cert->cache.extns_valid = 1;
980     return 0;
981
982   no_value:
983     for (count=0; count < cert->cache.n_extns; count++)
984       xfree (cert->cache.extns[count].oid);
985     xfree (cert->cache.extns);
986     cert->cache.extns = NULL;
987     return gpg_error (GPG_ERR_NO_VALUE);
988   }
989 }
990
991
992 /* Return information about the IDX nth extension */
993 gpg_error_t
994 ksba_cert_get_extension (ksba_cert_t cert, int idx,
995                          char const **r_oid, int *r_crit,
996                          size_t *r_deroff, size_t *r_derlen)
997 {
998   gpg_error_t err;
999
1000   if (!cert)
1001     return gpg_error (GPG_ERR_INV_VALUE);
1002   if (!cert->initialized)
1003     return gpg_error (GPG_ERR_NO_DATA);
1004
1005   if (!cert->cache.extns_valid)
1006     {
1007       err = read_extensions (cert);
1008       if (err)
1009         return err;
1010       assert (cert->cache.extns_valid);
1011     }
1012
1013   if (idx == cert->cache.n_extns)
1014     return gpg_error (GPG_ERR_EOF); /* No more extensions. */
1015
1016   if (idx < 0 || idx >= cert->cache.n_extns)
1017     return gpg_error (GPG_ERR_INV_INDEX);
1018
1019   if (r_oid)
1020     *r_oid = cert->cache.extns[idx].oid;
1021   if (r_crit)
1022     *r_crit = cert->cache.extns[idx].crit;
1023   if (r_deroff)
1024     *r_deroff = cert->cache.extns[idx].off;
1025   if (r_derlen)
1026     *r_derlen = cert->cache.extns[idx].len;
1027   return 0;
1028 }
1029
1030
1031 \f
1032 /* Return information on the basicConstraint (2.5.19.19) of CERT.
1033    R_CA receives true if this is a CA and only in that case R_PATHLEN
1034    is set to the maximim certification path length or -1 if there is
1035    nosuch limitation */
1036 gpg_error_t
1037 ksba_cert_is_ca (ksba_cert_t cert, int *r_ca, int *r_pathlen)
1038 {
1039   gpg_error_t err;
1040   const char *oid;
1041   int idx, crit;
1042   size_t off, derlen, seqlen;
1043   const unsigned char *der;
1044   struct tag_info ti;
1045   unsigned long value;
1046
1047   /* set default values */
1048   if (r_ca)
1049     *r_ca = 0;
1050   if (r_pathlen)
1051     *r_pathlen = -1;
1052   for (idx=0; !(err=ksba_cert_get_extension (cert, idx, &oid, &crit,
1053                                              &off, &derlen)); idx++)
1054     {
1055       if (!strcmp (oid, oidstr_basicConstraints))
1056         break;
1057     }
1058   if (gpg_err_code (err) == GPG_ERR_EOF)
1059       return 0; /* no such constraint */
1060   if (err)
1061     return err;
1062
1063   /* check that there is only one */
1064   for (idx++; !(err=ksba_cert_get_extension (cert, idx, &oid, NULL,
1065                                              NULL, NULL)); idx++)
1066     {
1067       if (!strcmp (oid, oidstr_basicConstraints))
1068         return gpg_error (GPG_ERR_DUP_VALUE);
1069     }
1070
1071   der = cert->image + off;
1072
1073   err = _ksba_ber_parse_tl (&der, &derlen, &ti);
1074   if (err)
1075     return err;
1076   if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SEQUENCE
1077          && ti.is_constructed) )
1078     return gpg_error (GPG_ERR_INV_CERT_OBJ);
1079   if (ti.ndef)
1080     return gpg_error (GPG_ERR_NOT_DER_ENCODED);
1081   seqlen = ti.length;
1082   if (seqlen > derlen)
1083     return gpg_error (GPG_ERR_BAD_BER);
1084   if (!seqlen)
1085     return 0; /* an empty sequence is allowed because both elements
1086                  are optional */
1087
1088   err = _ksba_ber_parse_tl (&der, &derlen, &ti);
1089   if (err)
1090     return err;
1091   if (seqlen < ti.nhdr)
1092     return gpg_error (GPG_ERR_BAD_BER);
1093   seqlen -= ti.nhdr;
1094   if (seqlen < ti.length)
1095     return gpg_error (GPG_ERR_BAD_BER);
1096   seqlen -= ti.length;
1097
1098   if (ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_BOOLEAN)
1099     {
1100       if (ti.length != 1)
1101         return gpg_error (GPG_ERR_ENCODING_PROBLEM);
1102       if (r_ca)
1103         *r_ca = !!*der;
1104       der++; derlen--;
1105       if (!seqlen)
1106         return 0; /* ready (no pathlength) */
1107
1108       err = _ksba_ber_parse_tl (&der, &derlen, &ti);
1109       if (err)
1110         return err;
1111       if (seqlen < ti.nhdr)
1112         return gpg_error (GPG_ERR_BAD_BER);
1113       seqlen -= ti.nhdr;
1114       if (seqlen < ti.length)
1115         return gpg_error (GPG_ERR_BAD_BER);
1116       seqlen -= ti.length;
1117     }
1118
1119   if (!(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_INTEGER))
1120     return gpg_error (GPG_ERR_INV_CERT_OBJ);
1121
1122   for (value=0; ti.length; ti.length--)
1123     {
1124       value <<= 8;
1125       value |= (*der++) & 0xff;
1126       derlen--;
1127     }
1128   if (r_pathlen)
1129     *r_pathlen = value;
1130
1131   /* if the extension is marked as critical and any stuff is still
1132      left we better return an error */
1133   if (crit && seqlen)
1134     return gpg_error (GPG_ERR_INV_CERT_OBJ);
1135
1136   return 0;
1137 }
1138
1139
1140 \f
1141 /* Get the key usage flags. The function returns Ksba_No_Data if no
1142    key usage is specified. */
1143 gpg_error_t
1144 ksba_cert_get_key_usage (ksba_cert_t cert, unsigned int *r_flags)
1145 {
1146   gpg_error_t err;
1147   const char *oid;
1148   int idx, crit;
1149   size_t off, derlen;
1150   const unsigned char *der;
1151   struct tag_info ti;
1152   unsigned int bits, mask;
1153   int i, unused, full;
1154
1155   if (!r_flags)
1156     return gpg_error (GPG_ERR_INV_VALUE);
1157   *r_flags = 0;
1158   for (idx=0; !(err=ksba_cert_get_extension (cert, idx, &oid, &crit,
1159                                              &off, &derlen)); idx++)
1160     {
1161       if (!strcmp (oid, oidstr_keyUsage))
1162         break;
1163     }
1164   if (gpg_err_code (err) == GPG_ERR_EOF
1165       || gpg_err_code (err) == GPG_ERR_NO_VALUE)
1166       return gpg_error (GPG_ERR_NO_DATA); /* no key usage */
1167   if (err)
1168     return err;
1169
1170   /* check that there is only one */
1171   for (idx++; !(err=ksba_cert_get_extension (cert, idx, &oid, NULL,
1172                                              NULL, NULL)); idx++)
1173     {
1174       if (!strcmp (oid, oidstr_keyUsage))
1175         return gpg_error (GPG_ERR_DUP_VALUE);
1176     }
1177
1178   der = cert->image + off;
1179
1180   err = _ksba_ber_parse_tl (&der, &derlen, &ti);
1181   if (err)
1182     return err;
1183   if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_BIT_STRING
1184          && !ti.is_constructed) )
1185     return gpg_error (GPG_ERR_INV_CERT_OBJ);
1186   if (ti.ndef)
1187     return gpg_error (GPG_ERR_NOT_DER_ENCODED);
1188   if (!ti.length || ti.length > derlen)
1189     return gpg_error (GPG_ERR_ENCODING_PROBLEM); /* number of unused bits missing */
1190   unused = *der++; derlen--;
1191   ti.length--;
1192   if ((!ti.length && unused) || unused/8 > ti.length)
1193     return gpg_error (GPG_ERR_ENCODING_PROBLEM);
1194
1195   full = ti.length - (unused+7)/8;
1196   unused %= 8;
1197   mask = 0;
1198   for (i=1; unused; i <<= 1, unused--)
1199     mask |= i;
1200
1201   /* the first octet */
1202   if (!ti.length)
1203     return 0; /* no bits set */
1204   bits = *der++; derlen--; ti.length--;
1205   if (full)
1206     full--;
1207   else {
1208     bits &= ~mask;
1209     mask = 0;
1210   }
1211   if (bits & 0x80)
1212     *r_flags |= KSBA_KEYUSAGE_DIGITAL_SIGNATURE;
1213   if (bits & 0x40)
1214     *r_flags |= KSBA_KEYUSAGE_NON_REPUDIATION;
1215   if (bits & 0x20)
1216     *r_flags |= KSBA_KEYUSAGE_KEY_ENCIPHERMENT;
1217   if (bits & 0x10)
1218     *r_flags |= KSBA_KEYUSAGE_DATA_ENCIPHERMENT;
1219   if (bits & 0x08)
1220     *r_flags |= KSBA_KEYUSAGE_KEY_AGREEMENT;
1221   if (bits & 0x04)
1222     *r_flags |= KSBA_KEYUSAGE_KEY_CERT_SIGN;
1223   if (bits & 0x02)
1224     *r_flags |= KSBA_KEYUSAGE_CRL_SIGN;
1225   if (bits & 0x01)
1226     *r_flags |= KSBA_KEYUSAGE_ENCIPHER_ONLY;
1227
1228   /* the second octet */
1229   if (!ti.length)
1230     return 0; /* no bits set */
1231   bits = *der++; derlen--; ti.length--;
1232   if (full)
1233     full--;
1234   else {
1235     bits &= mask;
1236     mask = ~0;
1237   }
1238   if (bits & 0x80)
1239     *r_flags |= KSBA_KEYUSAGE_DECIPHER_ONLY;
1240
1241   return 0;
1242 }
1243
1244
1245 \f
1246 /* Note, that this helper is also used for ext_key_usage. */
1247 static gpg_error_t
1248 append_cert_policy (char **policies, const char *oid, int crit)
1249 {
1250   char *p;
1251
1252   if (!*policies)
1253     {
1254       *policies = xtrymalloc (strlen (oid) + 4);
1255       if (!*policies)
1256         return gpg_error (GPG_ERR_ENOMEM);
1257       p = *policies;
1258     }
1259   else
1260     {
1261       char *tmp = xtryrealloc (*policies,
1262                                strlen(*policies) + 1 + strlen (oid) + 4);
1263       if (!tmp)
1264         return gpg_error (GPG_ERR_ENOMEM);
1265       *policies = tmp;
1266       p = stpcpy (tmp+strlen (tmp), "\n");;
1267     }
1268
1269   strcpy (stpcpy (p, oid), crit? ":C:": ":N:");
1270   return 0;
1271 }
1272
1273
1274 /* Return a string with the certificatePolicies delimited by
1275    linefeeds.  The return values may be extended to carry more
1276    information er line, so the caller should only use the first
1277    white-space delimited token per line.  The function returns
1278    GPG_ERR_NO_DATA when this extension is not used.  Caller must free
1279    the returned value.  */
1280 gpg_error_t
1281 ksba_cert_get_cert_policies (ksba_cert_t cert, char **r_policies)
1282 {
1283   gpg_error_t err;
1284   const char *oid;
1285   int idx, crit;
1286   size_t off, derlen, seqlen;
1287   const unsigned char *der;
1288   struct tag_info ti;
1289
1290   if (!cert || !r_policies)
1291     return gpg_error (GPG_ERR_INV_VALUE);
1292   *r_policies = NULL;
1293
1294   for (idx=0; !(err=ksba_cert_get_extension (cert, idx, &oid, &crit,
1295                                              &off, &derlen)); idx++)
1296     {
1297       if (!strcmp (oid, oidstr_certificatePolicies))
1298         {
1299           char *suboid;
1300
1301           der = cert->image + off;
1302
1303           err = _ksba_ber_parse_tl (&der, &derlen, &ti);
1304           if (err)
1305             goto leave;
1306           if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SEQUENCE
1307                  && ti.is_constructed) )
1308             {
1309               err = gpg_error (GPG_ERR_INV_CERT_OBJ);
1310               goto leave;
1311             }
1312           if (ti.ndef)
1313             {
1314               err = gpg_error (GPG_ERR_NOT_DER_ENCODED);
1315               goto leave;
1316             }
1317           seqlen = ti.length;
1318           if (seqlen > derlen)
1319             {
1320               err = gpg_error (GPG_ERR_BAD_BER);
1321               goto leave;
1322             }
1323           while (seqlen)
1324             {
1325               size_t seqseqlen;
1326
1327               err = _ksba_ber_parse_tl (&der, &derlen, &ti);
1328               if (err)
1329                 goto leave;
1330               if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SEQUENCE
1331                      && ti.is_constructed) )
1332                 {
1333                   err = gpg_error (GPG_ERR_INV_CERT_OBJ);
1334                   goto leave;
1335                 }
1336               if (ti.ndef)
1337                 {
1338                   err = gpg_error (GPG_ERR_NOT_DER_ENCODED);
1339                   goto leave;
1340                 }
1341               if (ti.length > derlen)
1342                 {
1343                   err = gpg_error (GPG_ERR_BAD_BER);
1344                   goto leave;
1345                 }
1346               if (!ti.length)
1347                 {
1348                   /* We do not accept an empty inner SEQ */
1349                   err = gpg_error (GPG_ERR_INV_CERT_OBJ);
1350                   goto leave;
1351                 }
1352               if (ti.nhdr+ti.length > seqlen)
1353                 {
1354                   err = gpg_error (GPG_ERR_BAD_BER);
1355                   goto leave;
1356                 }
1357               seqlen -= ti.nhdr + ti.length;
1358               seqseqlen = ti.length;
1359
1360               err = _ksba_ber_parse_tl (&der, &derlen, &ti);
1361               if (err)
1362                 goto leave;
1363               if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_OBJECT_ID))
1364                 {
1365                   err = gpg_error (GPG_ERR_INV_CERT_OBJ);
1366                   goto leave;
1367                 }
1368               if (ti.length > derlen)
1369                 {
1370                   err = gpg_error (GPG_ERR_BAD_BER);
1371                   goto leave;
1372                 }
1373               if (ti.nhdr+ti.length > seqseqlen)
1374                 {
1375                   err = gpg_error (GPG_ERR_BAD_BER);
1376                   goto leave;
1377                 }
1378               seqseqlen -= ti.nhdr;
1379
1380               suboid = ksba_oid_to_str (der, ti.length);
1381               if (!suboid)
1382                 {
1383                   err = gpg_error (GPG_ERR_ENOMEM);
1384                   goto leave;
1385                 }
1386               der       += ti.length;
1387               derlen    -= ti.length;
1388               seqseqlen -= ti.length;
1389
1390               err = append_cert_policy (r_policies, suboid, crit);
1391               xfree (suboid);
1392               if (err)
1393                 goto leave;
1394
1395               /* skip the rest of the seq which is more or less optional */
1396               der    += seqseqlen;
1397               derlen -= seqseqlen;
1398             }
1399         }
1400     }
1401
1402   if (gpg_err_code (err) == GPG_ERR_EOF)
1403     err = 0;
1404   if (!*r_policies || gpg_err_code (err) == GPG_ERR_NO_VALUE)
1405     err = gpg_error (GPG_ERR_NO_DATA);
1406
1407  leave:
1408   if (err)
1409     {
1410       xfree (*r_policies);
1411       *r_policies = NULL;
1412     }
1413   return err;
1414 }
1415
1416
1417 /* Return a string with the extendedKeyUsageOIDs delimited by
1418    linefeeds.  The return values may be extended to carry more
1419    information per line, so the caller should only use the first
1420    white-space delimited token per line.  The function returns
1421    GPG_ERR_NO_DATA when this extension is not used.  Caller must free
1422    the returned value.  */
1423 gpg_error_t
1424 ksba_cert_get_ext_key_usages (ksba_cert_t cert, char **result)
1425 {
1426   gpg_error_t err;
1427   const char *oid;
1428   int idx, crit;
1429   size_t off, derlen;
1430   const unsigned char *der;
1431   struct tag_info ti;
1432
1433   if (!cert || !result)
1434     return gpg_error (GPG_ERR_INV_VALUE);
1435   *result = NULL;
1436
1437   for (idx=0; !(err=ksba_cert_get_extension (cert, idx, &oid, &crit,
1438                                              &off, &derlen)); idx++)
1439     {
1440       if (!strcmp (oid, oidstr_extKeyUsage))
1441         {
1442           char *suboid;
1443
1444           der = cert->image + off;
1445
1446           err = _ksba_ber_parse_tl (&der, &derlen, &ti);
1447           if (err)
1448             goto leave;
1449           if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SEQUENCE
1450                  && ti.is_constructed) )
1451             {
1452               err = gpg_error (GPG_ERR_INV_CERT_OBJ);
1453               goto leave;
1454             }
1455           if (ti.ndef)
1456             {
1457               err = gpg_error (GPG_ERR_NOT_DER_ENCODED);
1458               goto leave;
1459             }
1460           if (ti.length > derlen)
1461             {
1462               err = gpg_error (GPG_ERR_BAD_BER);
1463               goto leave;
1464             }
1465           while (derlen)
1466             {
1467               err = _ksba_ber_parse_tl (&der, &derlen, &ti);
1468               if (err)
1469                 goto leave;
1470               if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_OBJECT_ID))
1471                 {
1472                   err = gpg_error (GPG_ERR_INV_CERT_OBJ);
1473                   goto leave;
1474                 }
1475               if (ti.ndef)
1476                 {
1477                   err = gpg_error (GPG_ERR_NOT_DER_ENCODED);
1478                   goto leave;
1479                 }
1480               if (ti.length > derlen)
1481                 {
1482                   err = gpg_error (GPG_ERR_BAD_BER);
1483                   goto leave;
1484                 }
1485
1486               suboid = ksba_oid_to_str (der, ti.length);
1487               if (!suboid)
1488                 {
1489                   err = gpg_error (GPG_ERR_ENOMEM);
1490                   goto leave;
1491                 }
1492               der       += ti.length;
1493               derlen    -= ti.length;
1494
1495               err = append_cert_policy (result, suboid, crit);
1496               xfree (suboid);
1497               if (err)
1498                 goto leave;
1499             }
1500         }
1501     }
1502
1503   if (gpg_err_code (err) == GPG_ERR_EOF)
1504     err = 0;
1505   if (!*result || gpg_err_code (err) == GPG_ERR_NO_VALUE)
1506     err = gpg_error (GPG_ERR_NO_DATA);
1507
1508  leave:
1509   if (err)
1510     {
1511       xfree (*result);
1512       *result = NULL;
1513     }
1514   return err;
1515 }
1516
1517
1518
1519 \f
1520 /* Helper function for ksba_cert_get_crl_dist_point */
1521 static gpg_error_t
1522 parse_distribution_point (const unsigned char *der, size_t derlen,
1523                           ksba_name_t *distpoint, ksba_name_t *issuer,
1524                           ksba_crl_reason_t *reason)
1525 {
1526   gpg_error_t err;
1527   struct tag_info ti;
1528
1529   err = _ksba_ber_parse_tl (&der, &derlen, &ti);
1530   if (err)
1531     return err;
1532   if (ti.class != CLASS_CONTEXT)
1533     return gpg_error (GPG_ERR_INV_CERT_OBJ); /* we expected a tag */
1534   if (ti.ndef)
1535     return gpg_error (GPG_ERR_NOT_DER_ENCODED);
1536   if (derlen < ti.length)
1537     return gpg_error (GPG_ERR_BAD_BER);
1538
1539   if (ti.tag == 0 && derlen)
1540     { /* distributionPointName */
1541       err = _ksba_ber_parse_tl (&der, &derlen, &ti);
1542       if (err)
1543         return err;
1544       if (ti.class != CLASS_CONTEXT)
1545         return gpg_error (GPG_ERR_INV_CERT_OBJ); /* we expected a tag */
1546       if (ti.ndef)
1547         return gpg_error (GPG_ERR_NOT_DER_ENCODED);
1548       if (derlen < ti.nhdr)
1549         return gpg_error (GPG_ERR_BAD_BER);
1550       if (derlen < ti.length)
1551         return gpg_error (GPG_ERR_BAD_BER);
1552
1553       if (ti.tag == 0)
1554         {
1555           if (distpoint)
1556             {
1557               err = _ksba_name_new_from_der (distpoint, der, ti.length);
1558               if (err)
1559                 return err;
1560             }
1561         }
1562       else
1563         {
1564           /* We don't support nameRelativeToCRLIssuer yet*/
1565         }
1566       der += ti.length;
1567       derlen -= ti.length;
1568
1569       if (!derlen)
1570         return 0;
1571
1572       /* read the next optional element */
1573       err = _ksba_ber_parse_tl (&der, &derlen, &ti);
1574       if (err)
1575         return err;
1576       if (ti.class != CLASS_CONTEXT)
1577         return gpg_error (GPG_ERR_INV_CERT_OBJ); /* we expected a tag */
1578       if (ti.ndef)
1579         return gpg_error (GPG_ERR_NOT_DER_ENCODED);
1580       if (derlen < ti.length)
1581         return gpg_error (GPG_ERR_BAD_BER);
1582     }
1583
1584   if (ti.tag == 1 && derlen)
1585     { /* reasonFlags */
1586       unsigned int bits, mask;
1587       int i, unused, full;
1588
1589       unused = *der++; derlen--;
1590       ti.length--;
1591       if ((!ti.length && unused) || unused/8 > ti.length)
1592         return gpg_error (GPG_ERR_ENCODING_PROBLEM);
1593
1594       full = ti.length - (unused+7)/8;
1595       unused %= 8;
1596       mask = 0;
1597       for (i=1; unused; i <<= 1, unused--)
1598         mask |= i;
1599
1600       /* we are only required to look at the first octect */
1601       if (ti.length && reason)
1602         {
1603           bits = *der;
1604           if (full)
1605             full--;
1606           else {
1607             bits &= ~mask;
1608             mask = 0;
1609           }
1610
1611           if (bits & 0x80)
1612             *reason |= KSBA_CRLREASON_UNSPECIFIED;
1613           if (bits & 0x40)
1614             *reason |= KSBA_CRLREASON_KEY_COMPROMISE;
1615           if (bits & 0x20)
1616             *reason |= KSBA_CRLREASON_CA_COMPROMISE;
1617           if (bits & 0x10)
1618             *reason |= KSBA_CRLREASON_AFFILIATION_CHANGED;
1619           if (bits & 0x08)
1620             *reason |= KSBA_CRLREASON_SUPERSEDED;
1621           if (bits & 0x04)
1622             *reason |= KSBA_CRLREASON_CESSATION_OF_OPERATION;
1623           if (bits & 0x02)
1624             *reason |= KSBA_CRLREASON_CERTIFICATE_HOLD;
1625         }
1626
1627       der += ti.length;
1628       derlen -= ti.length;
1629
1630       if (!derlen)
1631         return 0;
1632
1633       /* read the next optional element */
1634       err = _ksba_ber_parse_tl (&der, &derlen, &ti);
1635       if (err)
1636         return err;
1637       if (ti.class != CLASS_CONTEXT)
1638         return gpg_error (GPG_ERR_INV_CERT_OBJ); /* we expected a tag */
1639       if (ti.ndef)
1640         return gpg_error (GPG_ERR_NOT_DER_ENCODED);
1641       if (derlen < ti.length)
1642         return gpg_error (GPG_ERR_BAD_BER);
1643     }
1644
1645   if (ti.tag == 2 && derlen)
1646     { /* crlIssuer */
1647       if (issuer)
1648         {
1649           err = _ksba_name_new_from_der (issuer, der, ti.length);
1650           if (err)
1651             return err;
1652         }
1653
1654       der += ti.length;
1655       derlen -= ti.length;
1656     }
1657
1658   if (derlen)
1659     return gpg_error (GPG_ERR_INV_CERT_OBJ);
1660
1661   return 0;
1662 }
1663
1664 /* Return the CRLDistPoints given in the cert extension.  IDX should
1665    be iterated started from 0 until the function returns -1.
1666    R_DISTPOINT returns a ksba_name_t object with the distribution point
1667    name(s) the return value may be NULL to indicate that this name is
1668    not available.  R_ISSUER returns the CRL issuer; if the returned
1669    value is NULL the caller should assume that the CRL issuer is the
1670    same as the certificate issuer.  R_REASON returns the reason for
1671    the CRL.  This is a bit encoded value with no bit set if this has
1672    not been specified in the cert.
1673
1674    The caller may pass NULL to any of the pointer arguments if he is
1675    not interested in this value.  The return values for R_DISTPOINT
1676    and R_ISSUER must be released by the caller using
1677    ksba_name_release(). */
1678
1679 gpg_error_t
1680 ksba_cert_get_crl_dist_point (ksba_cert_t cert, int idx,
1681                               ksba_name_t *r_distpoint,
1682                               ksba_name_t *r_issuer,
1683                               ksba_crl_reason_t *r_reason)
1684 {
1685   gpg_error_t err;
1686   const char *oid;
1687   size_t off, derlen;
1688   int myidx, crit;
1689
1690   if (r_distpoint)
1691     *r_distpoint = NULL;
1692   if (r_issuer)
1693     *r_issuer = NULL;
1694   if (r_reason)
1695     *r_reason = 0;
1696
1697   for (myidx=0; !(err=ksba_cert_get_extension (cert, myidx, &oid, &crit,
1698                                                &off, &derlen)); myidx++)
1699     {
1700       if (!strcmp (oid, oidstr_crlDistributionPoints))
1701         {
1702           const unsigned char *der;
1703           struct tag_info ti;
1704            size_t seqlen;
1705
1706           der = cert->image + off;
1707
1708           err = _ksba_ber_parse_tl (&der, &derlen, &ti);
1709           if (err)
1710             return err;
1711           if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SEQUENCE
1712                  && ti.is_constructed) )
1713             return gpg_error (GPG_ERR_INV_CERT_OBJ);
1714           if (ti.ndef)
1715             return gpg_error (GPG_ERR_NOT_DER_ENCODED);
1716           seqlen = ti.length;
1717           if (seqlen > derlen)
1718             return gpg_error (GPG_ERR_BAD_BER);
1719
1720           /* Note: an empty sequence is actually not allowed but we
1721              better don't care */
1722
1723           while (seqlen)
1724             {
1725               err = _ksba_ber_parse_tl (&der, &derlen, &ti);
1726               if (err)
1727                 return err;
1728               if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SEQUENCE
1729                      && ti.is_constructed) )
1730                 return gpg_error (GPG_ERR_INV_CERT_OBJ);
1731               if (derlen < ti.length)
1732                 return gpg_error (GPG_ERR_BAD_BER);
1733               if (seqlen < ti.nhdr)
1734                 return gpg_error (GPG_ERR_BAD_BER);
1735               seqlen -= ti.nhdr;
1736               if (seqlen < ti.length)
1737                 return gpg_error (GPG_ERR_BAD_BER);
1738
1739               if (idx)
1740                 { /* skip because we are not yet at the desired index */
1741                   der    += ti.length;
1742                   derlen -= ti.length;
1743                   seqlen -= ti.length;
1744                   idx--;
1745                   continue;
1746                 }
1747
1748               if (!ti.length)
1749                 return 0;
1750
1751               err = parse_distribution_point (der, ti.length,
1752                                               r_distpoint, r_issuer, r_reason);
1753               if (err && r_distpoint)
1754                 {
1755                   ksba_name_release (*r_distpoint);
1756                   *r_distpoint = NULL;
1757                 }
1758               if (err && r_issuer)
1759                 {
1760                   ksba_name_release (*r_issuer);
1761                   *r_issuer = NULL;
1762                 }
1763               if (err && r_reason)
1764                 *r_reason = 0;
1765
1766               return err;
1767             }
1768         }
1769     }
1770
1771   return err;
1772 }
1773
1774 \f
1775 /* Return the authorityKeyIdentifier in R_NAME and R_SERIAL or/and in
1776    R_KEYID.  GPG_ERR_NO_DATA is returned if no authorityKeyIdentifier
1777    or only one using the keyIdentifier method is available and R_KEYID
1778    is NULL. */
1779 gpg_error_t
1780 ksba_cert_get_auth_key_id (ksba_cert_t cert,
1781                            ksba_sexp_t *r_keyid,
1782                            ksba_name_t *r_name,
1783                            ksba_sexp_t *r_serial)
1784 {
1785   gpg_error_t err;
1786   const char *oid;
1787   size_t off, derlen;
1788   const unsigned char *der;
1789   const unsigned char *keyid_der = NULL;
1790   size_t keyid_derlen = 0;
1791   int idx, crit;
1792   struct tag_info ti;
1793   char numbuf[30];
1794   size_t numbuflen;
1795
1796   if (r_keyid)
1797     *r_keyid = NULL;
1798   if (!r_name || !r_serial)
1799     return gpg_error (GPG_ERR_INV_VALUE);
1800   *r_name = NULL;
1801   *r_serial = NULL;
1802
1803   for (idx=0; !(err=ksba_cert_get_extension (cert, idx, &oid, &crit,
1804                                              &off, &derlen)); idx++)
1805     {
1806       if (!strcmp (oid, oidstr_authorityKeyIdentifier))
1807         break;
1808     }
1809   if (gpg_err_code (err) == GPG_ERR_EOF
1810       || gpg_err_code (err) == GPG_ERR_NO_VALUE)
1811     return gpg_error (GPG_ERR_NO_DATA); /* not available */
1812   if (err)
1813     return err;
1814
1815   /* check that there is only one */
1816   for (idx++; !(err=ksba_cert_get_extension (cert, idx, &oid, NULL,
1817                                              NULL, NULL)); idx++)
1818     {
1819       if (!strcmp (oid, oidstr_authorityKeyIdentifier))
1820         return gpg_error (GPG_ERR_DUP_VALUE);
1821     }
1822
1823   der = cert->image + off;
1824
1825   err = _ksba_ber_parse_tl (&der, &derlen, &ti);
1826   if (err)
1827     return err;
1828   if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SEQUENCE
1829          && ti.is_constructed) )
1830     return gpg_error (GPG_ERR_INV_CERT_OBJ);
1831   if (ti.ndef)
1832     return gpg_error (GPG_ERR_NOT_DER_ENCODED);
1833   if (ti.length > derlen)
1834     return gpg_error (GPG_ERR_BAD_BER);
1835
1836   err = _ksba_ber_parse_tl (&der, &derlen, &ti);
1837   if (err)
1838     return err;
1839   if (ti.class != CLASS_CONTEXT)
1840     return gpg_error (GPG_ERR_INV_CERT_OBJ); /* we expected a tag */
1841   if (ti.ndef)
1842     return gpg_error (GPG_ERR_NOT_DER_ENCODED);
1843   if (derlen < ti.length)
1844     return gpg_error (GPG_ERR_BAD_BER);
1845
1846   if (ti.tag == 0)
1847     { /* keyIdentifier:  Save it away and skip over it. */
1848       keyid_der = der;
1849       keyid_derlen = ti.length;
1850
1851       der += ti.length;
1852       derlen -= ti.length;
1853       /* If the keyid has been requested but no other data follows, we
1854          directly jump to the end. */
1855       if (r_keyid && !derlen)
1856         goto build_keyid;
1857       if (!derlen)
1858         return gpg_error (GPG_ERR_NO_DATA); /* not available */
1859       err = _ksba_ber_parse_tl (&der, &derlen, &ti);
1860       if (err)
1861         return err;
1862       if (ti.class != CLASS_CONTEXT)
1863         return gpg_error (GPG_ERR_INV_CERT_OBJ); /* we expected a tag */
1864       if (ti.ndef)
1865         return gpg_error (GPG_ERR_NOT_DER_ENCODED);
1866       if (derlen < ti.length)
1867         return gpg_error (GPG_ERR_BAD_BER);
1868     }
1869
1870   if (ti.tag != 1 || !derlen)
1871     return gpg_error (GPG_ERR_INV_CERT_OBJ);
1872
1873   err = _ksba_name_new_from_der (r_name, der, ti.length);
1874   if (err)
1875     return err;
1876
1877   der += ti.length;
1878   derlen -= ti.length;
1879
1880   /* fixme: we should release r_name before returning on error */
1881   err = _ksba_ber_parse_tl (&der, &derlen, &ti);
1882   if (err)
1883     return err;
1884   if (ti.class != CLASS_CONTEXT)
1885     return gpg_error (GPG_ERR_INV_CERT_OBJ); /* we expected a tag */
1886   if (ti.ndef)
1887     return gpg_error (GPG_ERR_NOT_DER_ENCODED);
1888   if (derlen < ti.length)
1889     return gpg_error (GPG_ERR_BAD_BER);
1890
1891   if (ti.tag != 2 || !derlen)
1892     return gpg_error (GPG_ERR_INV_CERT_OBJ);
1893
1894   sprintf (numbuf,"(%u:", (unsigned int)ti.length);
1895   numbuflen = strlen (numbuf);
1896   *r_serial = xtrymalloc (numbuflen + ti.length + 2);
1897   if (!*r_serial)
1898     return gpg_error (GPG_ERR_ENOMEM);
1899   strcpy (*r_serial, numbuf);
1900   memcpy (*r_serial+numbuflen, der, ti.length);
1901   (*r_serial)[numbuflen + ti.length] = ')';
1902   (*r_serial)[numbuflen + ti.length + 1] = 0;
1903
1904  build_keyid:
1905   if (r_keyid && keyid_der && keyid_derlen)
1906     {
1907       sprintf (numbuf,"(%u:", (unsigned int)keyid_derlen);
1908       numbuflen = strlen (numbuf);
1909       *r_keyid = xtrymalloc (numbuflen + keyid_derlen + 2);
1910       if (!*r_keyid)
1911         return gpg_error (GPG_ERR_ENOMEM);
1912       strcpy (*r_keyid, numbuf);
1913       memcpy (*r_keyid+numbuflen, keyid_der, keyid_derlen);
1914       (*r_keyid)[numbuflen + keyid_derlen] = ')';
1915       (*r_keyid)[numbuflen + keyid_derlen + 1] = 0;
1916     }
1917   return 0;
1918 }
1919
1920
1921 /* Return a simple octet string extension at the object identifier OID
1922    from certificate CERT.  The data is return as a simple S-expression
1923    and stored at R_DATA.  Returns 0 on success or an error code.
1924    common error codes are: GPG_ERR_NO_DATA if no such extension is
1925    available, GPG_ERR_DUP_VALUE if more than one is available.  If
1926    R_CRIT is not NULL, the critical extension flag will be stored at
1927    that address. */
1928 static gpg_error_t
1929 get_simple_octet_string_ext (ksba_cert_t cert, const char *oid,
1930                              int *r_crit, ksba_sexp_t *r_data)
1931 {
1932   gpg_error_t err;
1933   const char *tmpoid;
1934   size_t off, derlen;
1935   const unsigned char *der;
1936   int idx, crit;
1937   struct tag_info ti;
1938   char numbuf[30];
1939   size_t numbuflen;
1940
1941   if (!r_data)
1942     return gpg_error (GPG_ERR_INV_VALUE);
1943   *r_data = NULL;
1944
1945   for (idx=0; !(err=ksba_cert_get_extension (cert, idx, &tmpoid, &crit,
1946                                              &off, &derlen)); idx++)
1947     {
1948       if (!strcmp (tmpoid, oid))
1949         break;
1950     }
1951   if (err)
1952     {
1953       if (gpg_err_code (err) == GPG_ERR_EOF
1954           || gpg_err_code (err) == GPG_ERR_NO_VALUE)
1955         return gpg_error (GPG_ERR_NO_DATA);
1956       return err;
1957     }
1958
1959   /* Check that there is only one */
1960   for (idx++; !(err=ksba_cert_get_extension (cert, idx, &tmpoid, NULL,
1961                                              NULL, NULL)); idx++)
1962     {
1963       if (!strcmp (tmpoid, oid))
1964         return gpg_error (GPG_ERR_DUP_VALUE);
1965     }
1966
1967   der = cert->image + off;
1968
1969   err = _ksba_ber_parse_tl (&der, &derlen, &ti);
1970   if (err)
1971     return err;
1972   if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_OCTET_STRING
1973          && !ti.is_constructed) )
1974     return gpg_error (GPG_ERR_INV_CERT_OBJ);
1975   if (ti.ndef)
1976     return gpg_error (GPG_ERR_NOT_DER_ENCODED);
1977   if (ti.length > derlen)
1978     return gpg_error (GPG_ERR_BAD_BER);
1979   if (ti.length != derlen)
1980     return gpg_error (GPG_ERR_INV_CERT_OBJ); /* Garbage follows. */
1981
1982   sprintf (numbuf,"(%u:", (unsigned int)ti.length);
1983   numbuflen = strlen (numbuf);
1984   *r_data = xtrymalloc (numbuflen + ti.length + 2);
1985   if (!*r_data)
1986     return gpg_error (GPG_ERR_ENOMEM);
1987   strcpy (*r_data, numbuf);
1988   memcpy (*r_data+numbuflen, der, ti.length);
1989   (*r_data)[numbuflen + ti.length] = ')';
1990   (*r_data)[numbuflen + ti.length + 1] = 0;
1991   if (r_crit)
1992     *r_crit = crit;
1993   return 0;
1994 }
1995
1996
1997 /* Return the subjectKeyIdentifier extension as a simple allocated
1998    S-expression at the address of R_KEYID. 0 is returned on success,
1999    GPG_ERR_NO_DATA if no such extension is available or any other
2000    error code.  If R_CRIT is not passed as NULL, the criticla flag of
2001    this is extension is stored there. */
2002 gpg_error_t
2003 ksba_cert_get_subj_key_id (ksba_cert_t cert, int *r_crit, ksba_sexp_t *r_keyid)
2004 {
2005   return get_simple_octet_string_ext (cert, oidstr_subjectKeyIdentifier,
2006                                       r_crit, r_keyid);
2007 }
2008
2009
2010 \f
2011 /* MODE 0 := authorityInfoAccess
2012         1 := subjectInfoAccess
2013
2014    Caller must release METHOD and LOCATION if the function returned
2015    with success; on error both variables will point to NULL.
2016  */
2017 static gpg_error_t
2018 get_info_access (ksba_cert_t cert, int idx, int mode,
2019                  char **method, ksba_name_t *location)
2020 {
2021   gpg_error_t err;
2022   const char *oid;
2023   size_t off, derlen;
2024   int myidx, crit;
2025
2026   *method = NULL;
2027   *location = NULL;
2028
2029   if (!cert || !cert->initialized)
2030     return gpg_error (GPG_ERR_INV_VALUE);
2031   if (idx < 0)
2032     return gpg_error (GPG_ERR_INV_INDEX);
2033
2034   for (myidx=0; !(err=ksba_cert_get_extension (cert, myidx, &oid, &crit,
2035                                                &off, &derlen)); myidx++)
2036     {
2037       if (!strcmp (oid,(mode == 0)? oidstr_authorityInfoAccess
2038                                   : oidstr_subjectInfoAccess) )
2039         {
2040           const unsigned char *der;
2041           struct tag_info ti;
2042           size_t seqlen;
2043
2044           der = cert->image + off;
2045
2046           /* What we are going to parse is:
2047            *
2048            *    AuthorityInfoAccessSyntax  ::=
2049            *            SEQUENCE SIZE (1..MAX) OF AccessDescription
2050            *
2051            *    AccessDescription  ::=  SEQUENCE {
2052            *            accessMethod          OBJECT IDENTIFIER,
2053            *            accessLocation        GeneralName  }
2054            */
2055           err = _ksba_ber_parse_tl (&der, &derlen, &ti);
2056           if (err)
2057             return err;
2058           if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SEQUENCE
2059                  && ti.is_constructed) )
2060             return gpg_error (GPG_ERR_INV_CERT_OBJ);
2061           if (ti.ndef)
2062             return gpg_error (GPG_ERR_NOT_DER_ENCODED);
2063           seqlen = ti.length;
2064           if (seqlen > derlen)
2065             return gpg_error (GPG_ERR_BAD_BER);
2066
2067           /* Note: an empty sequence is actually not allowed but we
2068              better don't care. */
2069
2070           while (seqlen)
2071             {
2072               err = _ksba_ber_parse_tl (&der, &derlen, &ti);
2073               if (err)
2074                 return err;
2075               if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SEQUENCE
2076                      && ti.is_constructed) )
2077                 return gpg_error (GPG_ERR_INV_CERT_OBJ);
2078               if (derlen < ti.length)
2079                 return gpg_error (GPG_ERR_BAD_BER);
2080               if (seqlen < ti.nhdr)
2081                 return gpg_error (GPG_ERR_BAD_BER);
2082               seqlen -= ti.nhdr;
2083               if (seqlen < ti.length)
2084                 return gpg_error (GPG_ERR_BAD_BER);
2085
2086               if (idx)
2087                 { /* Skip because we are not yet at the desired index. */
2088                   der    += ti.length;
2089                   derlen -= ti.length;
2090                   seqlen -= ti.length;
2091                   idx--;
2092                   continue;
2093                 }
2094               /* We only need the next object, thus we can (and
2095                  actually need to) limit the DERLEN to the length of
2096                  the current sequence. */
2097               derlen = ti.length;
2098               if (!derlen)
2099                 return gpg_error (GPG_ERR_INV_CERT_OBJ);
2100
2101               err = _ksba_ber_parse_tl (&der, &derlen, &ti);
2102               if (err)
2103                 return err;
2104
2105               if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_OBJECT_ID
2106                      && !ti.is_constructed))
2107                 return gpg_error (GPG_ERR_INV_CERT_OBJ);
2108               if (ti.ndef)
2109                 return gpg_error (GPG_ERR_NOT_DER_ENCODED);
2110               if (derlen < ti.length)
2111                 return gpg_error (GPG_ERR_BAD_BER);
2112
2113               *method = ksba_oid_to_str (der, ti.length);
2114               if (!*method)
2115                 return gpg_error (GPG_ERR_ENOMEM);
2116               der       += ti.length;
2117               derlen    -= ti.length;
2118
2119               err = _ksba_name_new_from_der (location, der, derlen);
2120               if (err)
2121                 {
2122                   ksba_free (*method);
2123                   *method = NULL;
2124                   return err;
2125                 }
2126               return 0;
2127             }
2128         }
2129     }
2130
2131   return err;
2132 }
2133
2134
2135 /* Return the authorityInfoAccess attributes. IDX should be iterated
2136    starting from 0 until the function returns GPG_ERR_EOF.  R_METHOD
2137    returns an allocated string with the OID of one item and R_LOCATION
2138    return the GeneralName for that OID.  The return values for
2139    R_METHOD and R_LOCATION must be released by the caller unless the
2140    function returned an error; the function will however make sure
2141    that R_METHOD and R_LOCATION will point to NULL if the function
2142    returns an error.  See RFC 2459, section 4.2.2.1 */
2143 gpg_error_t
2144 ksba_cert_get_authority_info_access (ksba_cert_t cert, int idx,
2145                                      char **r_method, ksba_name_t *r_location)
2146 {
2147   if (!r_method || !r_location)
2148     return gpg_error (GPG_ERR_INV_VALUE);
2149   return get_info_access (cert, idx, 0, r_method, r_location);
2150 }
2151
2152 /* Return the subjectInfoAccess attributes. IDX should be iterated
2153    starting from 0 until the function returns GPG_ERR_EOF.  R_METHOD
2154    returns an allocated string with the OID of one item and R_LOCATION
2155    return the GeneralName for that OID.  The return values for
2156    R_METHOD and R_LOCATION must be released by the caller unless the
2157    function returned an error; the function will however make sure
2158    that R_METHOD and R_LOCATION will point to NULL if the function
2159    returns an error.  See RFC 2459, section 4.2.2.2 */
2160 gpg_error_t
2161 ksba_cert_get_subject_info_access (ksba_cert_t cert, int idx,
2162                                    char **r_method, ksba_name_t *r_location)
2163 {
2164   if (!r_method || !r_location)
2165     return gpg_error (GPG_ERR_INV_VALUE);
2166   return get_info_access (cert, idx, 1, r_method, r_location);
2167 }