LCOV - code coverage report
Current view: top level - src - crl.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 588 838 70.2 %
Date: 2015-11-05 17:05:02 Functions: 28 30 93.3 %

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

Generated by: LCOV version 1.11