LCOV - code coverage report
Current view: top level - src - ocsp.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 944 0.0 %
Date: 2016-12-09 14:04:45 Functions: 0 39 0.0 %

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

Generated by: LCOV version 1.12