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

Generated by: LCOV version 1.11