LCOV - code coverage report
Current view: top level - ocsp - ocsp_ht.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 0 191 0.0 %
Date: 2014-08-02 Functions: 0 14 0.0 %
Branches: 0 153 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* ocsp_ht.c */
       2                 :            : /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
       3                 :            :  * project 2006.
       4                 :            :  */
       5                 :            : /* ====================================================================
       6                 :            :  * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
       7                 :            :  *
       8                 :            :  * Redistribution and use in source and binary forms, with or without
       9                 :            :  * modification, are permitted provided that the following conditions
      10                 :            :  * are met:
      11                 :            :  *
      12                 :            :  * 1. Redistributions of source code must retain the above copyright
      13                 :            :  *    notice, this list of conditions and the following disclaimer. 
      14                 :            :  *
      15                 :            :  * 2. Redistributions in binary form must reproduce the above copyright
      16                 :            :  *    notice, this list of conditions and the following disclaimer in
      17                 :            :  *    the documentation and/or other materials provided with the
      18                 :            :  *    distribution.
      19                 :            :  *
      20                 :            :  * 3. All advertising materials mentioning features or use of this
      21                 :            :  *    software must display the following acknowledgment:
      22                 :            :  *    "This product includes software developed by the OpenSSL Project
      23                 :            :  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
      24                 :            :  *
      25                 :            :  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
      26                 :            :  *    endorse or promote products derived from this software without
      27                 :            :  *    prior written permission. For written permission, please contact
      28                 :            :  *    licensing@OpenSSL.org.
      29                 :            :  *
      30                 :            :  * 5. Products derived from this software may not be called "OpenSSL"
      31                 :            :  *    nor may "OpenSSL" appear in their names without prior written
      32                 :            :  *    permission of the OpenSSL Project.
      33                 :            :  *
      34                 :            :  * 6. Redistributions of any form whatsoever must retain the following
      35                 :            :  *    acknowledgment:
      36                 :            :  *    "This product includes software developed by the OpenSSL Project
      37                 :            :  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
      38                 :            :  *
      39                 :            :  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
      40                 :            :  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      41                 :            :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
      42                 :            :  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
      43                 :            :  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      44                 :            :  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      45                 :            :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
      46                 :            :  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      47                 :            :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
      48                 :            :  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      49                 :            :  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
      50                 :            :  * OF THE POSSIBILITY OF SUCH DAMAGE.
      51                 :            :  * ====================================================================
      52                 :            :  *
      53                 :            :  * This product includes cryptographic software written by Eric Young
      54                 :            :  * (eay@cryptsoft.com).  This product includes software written by Tim
      55                 :            :  * Hudson (tjh@cryptsoft.com).
      56                 :            :  *
      57                 :            :  */
      58                 :            : 
      59                 :            : #include <stdio.h>
      60                 :            : #include <stdlib.h>
      61                 :            : #include <ctype.h>
      62                 :            : #include <string.h>
      63                 :            : #include "e_os.h"
      64                 :            : #include <openssl/asn1.h>
      65                 :            : #include <openssl/ocsp.h>
      66                 :            : #include <openssl/err.h>
      67                 :            : #include <openssl/buffer.h>
      68                 :            : #ifdef OPENSSL_SYS_SUNOS
      69                 :            : #define strtoul (unsigned long)strtol
      70                 :            : #endif /* OPENSSL_SYS_SUNOS */
      71                 :            : 
      72                 :            : /* Stateful OCSP request code, supporting non-blocking I/O */
      73                 :            : 
      74                 :            : /* Opaque OCSP request status structure */
      75                 :            : 
      76                 :            : struct ocsp_req_ctx_st {
      77                 :            :         int state;              /* Current I/O state */
      78                 :            :         unsigned char *iobuf;   /* Line buffer */
      79                 :            :         int iobuflen;           /* Line buffer length */
      80                 :            :         BIO *io;                /* BIO to perform I/O with */
      81                 :            :         BIO *mem;               /* Memory BIO response is built into */
      82                 :            :         unsigned long asn1_len; /* ASN1 length of response */
      83                 :            :         unsigned long max_resp_len; /* Maximum length of response */
      84                 :            :         };
      85                 :            : 
      86                 :            : #define OCSP_MAX_RESP_LENGTH    (100 * 1024)
      87                 :            : #define OCSP_MAX_LINE_LEN       4096;
      88                 :            : 
      89                 :            : /* OCSP states */
      90                 :            : 
      91                 :            : /* If set no reading should be performed */
      92                 :            : #define OHS_NOREAD              0x1000
      93                 :            : /* Error condition */
      94                 :            : #define OHS_ERROR               (0 | OHS_NOREAD)
      95                 :            : /* First line being read */
      96                 :            : #define OHS_FIRSTLINE           1
      97                 :            : /* MIME headers being read */
      98                 :            : #define OHS_HEADERS             2
      99                 :            : /* OCSP initial header (tag + length) being read */
     100                 :            : #define OHS_ASN1_HEADER         3
     101                 :            : /* OCSP content octets being read */
     102                 :            : #define OHS_ASN1_CONTENT        4
     103                 :            : /* First call: ready to start I/O */
     104                 :            : #define OHS_ASN1_WRITE_INIT     (5 | OHS_NOREAD)
     105                 :            : /* Request being sent */
     106                 :            : #define OHS_ASN1_WRITE          (6 | OHS_NOREAD)
     107                 :            : /* Request being flushed */
     108                 :            : #define OHS_ASN1_FLUSH          (7 | OHS_NOREAD)
     109                 :            : /* Completed */
     110                 :            : #define OHS_DONE                (8 | OHS_NOREAD)
     111                 :            : /* Headers set, no final \r\n included */
     112                 :            : #define OHS_HTTP_HEADER         (9 | OHS_NOREAD)
     113                 :            : 
     114                 :            : 
     115                 :            : static int parse_http_line1(char *line);
     116                 :            : 
     117                 :          0 : OCSP_REQ_CTX *OCSP_REQ_CTX_new(BIO *io, int maxline)
     118                 :            :         {
     119                 :            :         OCSP_REQ_CTX *rctx;
     120                 :          0 :         rctx = OPENSSL_malloc(sizeof(OCSP_REQ_CTX));
     121         [ #  # ]:          0 :         if (!rctx)
     122                 :            :                 return NULL;
     123                 :          0 :         rctx->state = OHS_ERROR;
     124                 :          0 :         rctx->max_resp_len = OCSP_MAX_RESP_LENGTH;
     125                 :          0 :         rctx->mem = BIO_new(BIO_s_mem());
     126                 :          0 :         rctx->io = io;
     127                 :          0 :         rctx->asn1_len = 0;
     128         [ #  # ]:          0 :         if (maxline > 0)
     129                 :          0 :                 rctx->iobuflen = maxline;
     130                 :            :         else
     131                 :          0 :                 rctx->iobuflen = OCSP_MAX_LINE_LEN;
     132                 :          0 :         rctx->iobuf = OPENSSL_malloc(rctx->iobuflen);
     133 [ #  # ][ #  # ]:          0 :         if (!rctx->iobuf || !rctx->mem)
     134                 :            :                 {
     135                 :          0 :                 OCSP_REQ_CTX_free(rctx);
     136                 :          0 :                 return NULL;
     137                 :            :                 }
     138                 :            :         return rctx;
     139                 :            :         }
     140                 :            : 
     141                 :          0 : void OCSP_REQ_CTX_free(OCSP_REQ_CTX *rctx)
     142                 :            :         {
     143         [ #  # ]:          0 :         if (rctx->mem)
     144                 :          0 :                 BIO_free(rctx->mem);
     145         [ #  # ]:          0 :         if (rctx->iobuf)
     146                 :          0 :                 OPENSSL_free(rctx->iobuf);
     147                 :          0 :         OPENSSL_free(rctx);
     148                 :          0 :         }
     149                 :            : 
     150                 :          0 : BIO *OCSP_REQ_CTX_get0_mem_bio(OCSP_REQ_CTX *rctx)
     151                 :            :         {
     152                 :          0 :         return rctx->mem;
     153                 :            :         }
     154                 :            : 
     155                 :          0 : void OCSP_set_max_response_length(OCSP_REQ_CTX *rctx, unsigned long len)
     156                 :            :         {
     157         [ #  # ]:          0 :         if (len == 0)
     158                 :          0 :                 rctx->max_resp_len = OCSP_MAX_RESP_LENGTH;
     159                 :            :         else
     160                 :          0 :                 rctx->max_resp_len = len;
     161                 :          0 :         }
     162                 :            : 
     163                 :          0 : int OCSP_REQ_CTX_i2d(OCSP_REQ_CTX *rctx, const ASN1_ITEM *it, ASN1_VALUE *val)
     164                 :            :         {
     165                 :            :         static const char req_hdr[] =
     166                 :            :                         "Content-Type: application/ocsp-request\r\n"
     167                 :            :                         "Content-Length: %d\r\n\r\n";
     168                 :          0 :         int reqlen = ASN1_item_i2d(val, NULL, it);
     169         [ #  # ]:          0 :         if (BIO_printf(rctx->mem, req_hdr, reqlen) <= 0)
     170                 :            :                 return 0;
     171         [ #  # ]:          0 :         if (ASN1_item_i2d_bio(it, rctx->mem, val) <= 0)
     172                 :            :                 return 0;
     173                 :          0 :         rctx->state = OHS_ASN1_WRITE_INIT;
     174                 :          0 :         return 1;
     175                 :            :         }
     176                 :            : 
     177                 :          0 : int OCSP_REQ_CTX_nbio_d2i(OCSP_REQ_CTX *rctx,
     178                 :            :                                         ASN1_VALUE **pval, const ASN1_ITEM *it)
     179                 :            :         {
     180                 :            :         int rv, len;
     181                 :            :         const unsigned char *p;
     182                 :            : 
     183                 :          0 :         rv = OCSP_REQ_CTX_nbio(rctx);
     184         [ #  # ]:          0 :         if (rv != 1)
     185                 :            :                 return rv;
     186                 :            : 
     187                 :          0 :         len = BIO_get_mem_data(rctx->mem, &p);
     188                 :          0 :         *pval = ASN1_item_d2i(NULL, &p, len, it);
     189         [ #  # ]:          0 :         if (*pval == NULL)
     190                 :            :                 {
     191                 :          0 :                 rctx->state = OHS_ERROR;
     192                 :          0 :                 return 0;
     193                 :            :                 }
     194                 :            :         return 1;
     195                 :            :         }
     196                 :            : 
     197                 :          0 : int OCSP_REQ_CTX_http(OCSP_REQ_CTX *rctx, const char *op, const char *path)
     198                 :            :         {
     199                 :            :         static const char http_hdr[] = "%s %s HTTP/1.0\r\n";
     200                 :            : 
     201         [ #  # ]:          0 :         if (!path)
     202                 :          0 :                 path = "/";
     203                 :            : 
     204         [ #  # ]:          0 :         if (BIO_printf(rctx->mem, http_hdr, op, path) <= 0)
     205                 :            :                 return 0;
     206                 :          0 :         rctx->state = OHS_HTTP_HEADER;
     207                 :          0 :         return 1;
     208                 :            :         }
     209                 :            : 
     210                 :          0 : int OCSP_REQ_CTX_set1_req(OCSP_REQ_CTX *rctx, OCSP_REQUEST *req)
     211                 :            :         {
     212                 :          0 :         return OCSP_REQ_CTX_i2d(rctx, ASN1_ITEM_rptr(OCSP_REQUEST),
     213                 :            :                                                         (ASN1_VALUE *)req);
     214                 :            :         }
     215                 :            : 
     216                 :          0 : int OCSP_REQ_CTX_add1_header(OCSP_REQ_CTX *rctx,
     217                 :            :                 const char *name, const char *value)
     218                 :            :         {
     219         [ #  # ]:          0 :         if (!name)
     220                 :            :                 return 0;
     221         [ #  # ]:          0 :         if (BIO_puts(rctx->mem, name) <= 0)
     222                 :            :                 return 0;
     223         [ #  # ]:          0 :         if (value)
     224                 :            :                 {
     225         [ #  # ]:          0 :                 if (BIO_write(rctx->mem, ": ", 2) != 2)
     226                 :            :                         return 0;
     227         [ #  # ]:          0 :                 if (BIO_puts(rctx->mem, value) <= 0)
     228                 :            :                         return 0;
     229                 :            :                 }
     230         [ #  # ]:          0 :         if (BIO_write(rctx->mem, "\r\n", 2) != 2)
     231                 :            :                 return 0;
     232                 :          0 :         rctx->state = OHS_HTTP_HEADER;
     233                 :          0 :         return 1;
     234                 :            :         }
     235                 :            : 
     236                 :          0 : OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, const char *path, OCSP_REQUEST *req,
     237                 :            :                                int maxline)
     238                 :            :         {
     239                 :            : 
     240                 :          0 :         OCSP_REQ_CTX *rctx = NULL;
     241                 :          0 :         rctx = OCSP_REQ_CTX_new(io, maxline);
     242         [ #  # ]:          0 :         if (!rctx)
     243                 :            :                 return NULL;
     244                 :            : 
     245         [ #  # ]:          0 :         if (!OCSP_REQ_CTX_http(rctx, "POST", path))
     246                 :            :                 goto err;
     247                 :            : 
     248 [ #  # ][ #  # ]:          0 :         if (req && !OCSP_REQ_CTX_set1_req(rctx, req))
     249                 :            :                 goto err;
     250                 :            : 
     251                 :          0 :         return rctx;
     252                 :            :         
     253                 :            :         err:
     254                 :          0 :         OCSP_REQ_CTX_free(rctx);
     255                 :          0 :         return NULL;
     256                 :            :         }
     257                 :            : 
     258                 :            : /* Parse the HTTP response. This will look like this:
     259                 :            :  * "HTTP/1.0 200 OK". We need to obtain the numeric code and
     260                 :            :  * (optional) informational message.
     261                 :            :  */
     262                 :            : 
     263                 :          0 : static int parse_http_line1(char *line)
     264                 :            :         {
     265                 :            :         int retcode;
     266                 :            :         char *p, *q, *r;
     267                 :            :         /* Skip to first white space (passed protocol info) */
     268                 :            : 
     269 [ #  # ][ #  # ]:          0 :         for(p = line; *p && !isspace((unsigned char)*p); p++)
     270                 :          0 :                 continue;
     271         [ #  # ]:          0 :         if(!*p)
     272                 :            :                 {
     273                 :          0 :                 OCSPerr(OCSP_F_PARSE_HTTP_LINE1,
     274                 :            :                                         OCSP_R_SERVER_RESPONSE_PARSE_ERROR);
     275                 :          0 :                 return 0;
     276                 :            :                 }
     277                 :            : 
     278                 :            :         /* Skip past white space to start of response code */
     279 [ #  # ][ #  # ]:          0 :         while(*p && isspace((unsigned char)*p))
     280                 :          0 :                 p++;
     281                 :            : 
     282         [ #  # ]:          0 :         if(!*p)
     283                 :            :                 {
     284                 :          0 :                 OCSPerr(OCSP_F_PARSE_HTTP_LINE1,
     285                 :            :                                         OCSP_R_SERVER_RESPONSE_PARSE_ERROR);
     286                 :          0 :                 return 0;
     287                 :            :                 }
     288                 :            : 
     289                 :            :         /* Find end of response code: first whitespace after start of code */
     290 [ #  # ][ #  # ]:          0 :         for(q = p; *q && !isspace((unsigned char)*q); q++)
     291                 :          0 :                 continue;
     292                 :            : 
     293         [ #  # ]:          0 :         if(!*q)
     294                 :            :                 {
     295                 :          0 :                 OCSPerr(OCSP_F_PARSE_HTTP_LINE1,
     296                 :            :                                         OCSP_R_SERVER_RESPONSE_PARSE_ERROR);
     297                 :          0 :                 return 0;
     298                 :            :                 }
     299                 :            : 
     300                 :            :         /* Set end of response code and start of message */ 
     301                 :          0 :         *q++ = 0;
     302                 :            : 
     303                 :            :         /* Attempt to parse numeric code */
     304                 :          0 :         retcode = strtoul(p, &r, 10);
     305                 :            : 
     306         [ #  # ]:          0 :         if(*r)
     307                 :            :                 return 0;
     308                 :            : 
     309                 :            :         /* Skip over any leading white space in message */
     310 [ #  # ][ #  # ]:          0 :         while(*q && isspace((unsigned char)*q))
     311                 :          0 :                 q++;
     312                 :            : 
     313         [ #  # ]:          0 :         if(*q)
     314                 :            :                 {
     315                 :            :                 /* Finally zap any trailing white space in message (include
     316                 :            :                  * CRLF) */
     317                 :            : 
     318                 :            :                 /* We know q has a non white space character so this is OK */
     319         [ #  # ]:          0 :                 for(r = q + strlen(q) - 1; isspace((unsigned char)*r); r--)
     320                 :          0 :                         *r = 0;
     321                 :            :                 }
     322         [ #  # ]:          0 :         if(retcode != 200)
     323                 :            :                 {
     324                 :          0 :                 OCSPerr(OCSP_F_PARSE_HTTP_LINE1, OCSP_R_SERVER_RESPONSE_ERROR);
     325         [ #  # ]:          0 :                 if(!*q)
     326                 :          0 :                         ERR_add_error_data(2, "Code=", p);
     327                 :            :                 else
     328                 :          0 :                         ERR_add_error_data(4, "Code=", p, ",Reason=", q);
     329                 :            :                 return 0;
     330                 :            :                 }
     331                 :            : 
     332                 :            : 
     333                 :            :         return 1;
     334                 :            : 
     335                 :            :         }
     336                 :            : 
     337                 :          0 : int OCSP_REQ_CTX_nbio(OCSP_REQ_CTX *rctx)
     338                 :            :         {
     339                 :            :         int i, n;
     340                 :            :         const unsigned char *p;
     341                 :            :         next_io:
     342         [ #  # ]:          0 :         if (!(rctx->state & OHS_NOREAD))
     343                 :            :                 {
     344                 :          0 :                 n = BIO_read(rctx->io, rctx->iobuf, rctx->iobuflen);
     345                 :            : 
     346         [ #  # ]:          0 :                 if (n <= 0)
     347                 :            :                         {
     348         [ #  # ]:          0 :                         if (BIO_should_retry(rctx->io))
     349                 :            :                                 return -1;
     350                 :          0 :                         return 0;
     351                 :            :                         }
     352                 :            : 
     353                 :            :                 /* Write data to memory BIO */
     354                 :            : 
     355         [ #  # ]:          0 :                 if (BIO_write(rctx->mem, rctx->iobuf, n) != n)
     356                 :            :                         return 0;
     357                 :            :                 }
     358                 :            : 
     359   [ #  #  #  #  :          0 :         switch(rctx->state)
             #  #  #  #  
                      # ]
     360                 :            :                 {
     361                 :            :                 case OHS_HTTP_HEADER:
     362                 :            :                 /* Last operation was adding headers: need a final \r\n */
     363         [ #  # ]:          0 :                 if (BIO_write(rctx->mem, "\r\n", 2) != 2)
     364                 :            :                         {
     365                 :          0 :                         rctx->state = OHS_ERROR;
     366                 :          0 :                         return 0;
     367                 :            :                         }
     368                 :          0 :                 rctx->state = OHS_ASN1_WRITE_INIT;
     369                 :            : 
     370                 :            :                 case OHS_ASN1_WRITE_INIT:
     371                 :          0 :                 rctx->asn1_len = BIO_get_mem_data(rctx->mem, NULL);
     372                 :          0 :                 rctx->state = OHS_ASN1_WRITE;
     373                 :            : 
     374                 :            :                 case OHS_ASN1_WRITE:
     375                 :          0 :                 n = BIO_get_mem_data(rctx->mem, &p);
     376                 :            : 
     377                 :          0 :                 i = BIO_write(rctx->io,
     378                 :          0 :                         p + (n - rctx->asn1_len), rctx->asn1_len);
     379                 :            : 
     380         [ #  # ]:          0 :                 if (i <= 0)
     381                 :            :                         {
     382         [ #  # ]:          0 :                         if (BIO_should_retry(rctx->io))
     383                 :            :                                 return -1;
     384                 :          0 :                         rctx->state = OHS_ERROR;
     385                 :          0 :                         return 0;
     386                 :            :                         }
     387                 :            : 
     388                 :          0 :                 rctx->asn1_len -= i;
     389                 :            : 
     390         [ #  # ]:          0 :                 if (rctx->asn1_len > 0)
     391                 :            :                         goto next_io;
     392                 :            : 
     393                 :          0 :                 rctx->state = OHS_ASN1_FLUSH;
     394                 :            : 
     395                 :          0 :                 (void)BIO_reset(rctx->mem);
     396                 :            : 
     397                 :            :                 case OHS_ASN1_FLUSH:
     398                 :            : 
     399                 :          0 :                 i = BIO_flush(rctx->io);
     400                 :            : 
     401         [ #  # ]:          0 :                 if (i > 0)
     402                 :            :                         {
     403                 :          0 :                         rctx->state = OHS_FIRSTLINE;
     404                 :          0 :                         goto next_io;
     405                 :            :                         }
     406                 :            : 
     407         [ #  # ]:          0 :                 if (BIO_should_retry(rctx->io))
     408                 :            :                         return -1;
     409                 :            : 
     410                 :          0 :                 rctx->state = OHS_ERROR;
     411                 :          0 :                 return 0;
     412                 :            : 
     413                 :            :                 case OHS_ERROR:
     414                 :            :                 return 0;
     415                 :            : 
     416                 :            :                 case OHS_FIRSTLINE:
     417                 :            :                 case OHS_HEADERS:
     418                 :            : 
     419                 :            :                 /* Attempt to read a line in */
     420                 :            : 
     421                 :            :                 next_line:
     422                 :            :                 /* Due to &%^*$" memory BIO behaviour with BIO_gets we
     423                 :            :                  * have to check there's a complete line in there before
     424                 :            :                  * calling BIO_gets or we'll just get a partial read.
     425                 :            :                  */
     426                 :          0 :                 n = BIO_get_mem_data(rctx->mem, &p);
     427 [ #  # ][ #  # ]:          0 :                 if ((n <= 0) || !memchr(p, '\n', n))
     428                 :            :                         {
     429         [ #  # ]:          0 :                         if (n >= rctx->iobuflen)
     430                 :            :                                 {
     431                 :          0 :                                 rctx->state = OHS_ERROR;
     432                 :          0 :                                 return 0;
     433                 :            :                                 }
     434                 :            :                         goto next_io;
     435                 :            :                         }
     436                 :          0 :                 n = BIO_gets(rctx->mem, (char *)rctx->iobuf, rctx->iobuflen);
     437                 :            : 
     438         [ #  # ]:          0 :                 if (n <= 0)
     439                 :            :                         {
     440         [ #  # ]:          0 :                         if (BIO_should_retry(rctx->mem))
     441                 :            :                                 goto next_io;
     442                 :          0 :                         rctx->state = OHS_ERROR;
     443                 :          0 :                         return 0;
     444                 :            :                         }
     445                 :            : 
     446                 :            :                 /* Don't allow excessive lines */
     447         [ #  # ]:          0 :                 if (n == rctx->iobuflen)
     448                 :            :                         {
     449                 :          0 :                         rctx->state = OHS_ERROR;
     450                 :          0 :                         return 0;
     451                 :            :                         }
     452                 :            : 
     453                 :            :                 /* First line */
     454         [ #  # ]:          0 :                 if (rctx->state == OHS_FIRSTLINE)
     455                 :            :                         {
     456         [ #  # ]:          0 :                         if (parse_http_line1((char *)rctx->iobuf))
     457                 :            :                                 {
     458                 :          0 :                                 rctx->state = OHS_HEADERS;
     459                 :          0 :                                 goto next_line;
     460                 :            :                                 }
     461                 :            :                         else
     462                 :            :                                 {
     463                 :          0 :                                 rctx->state = OHS_ERROR;
     464                 :          0 :                                 return 0;
     465                 :            :                                 }
     466                 :            :                         }
     467                 :            :                 else
     468                 :            :                         {
     469                 :            :                         /* Look for blank line: end of headers */
     470         [ #  # ]:          0 :                         for (p = rctx->iobuf; *p; p++)
     471                 :            :                                 {
     472         [ #  # ]:          0 :                                 if ((*p != '\r') && (*p != '\n'))
     473                 :            :                                         break;
     474                 :            :                                 }
     475         [ #  # ]:          0 :                         if (*p)
     476                 :            :                                 goto next_line;
     477                 :            : 
     478                 :          0 :                         rctx->state = OHS_ASN1_HEADER;
     479                 :            : 
     480                 :            :                         }
     481                 :            :  
     482                 :            :                 /* Fall thru */
     483                 :            : 
     484                 :            : 
     485                 :            :                 case OHS_ASN1_HEADER:
     486                 :            :                 /* Now reading ASN1 header: can read at least 2 bytes which
     487                 :            :                  * is enough for ASN1 SEQUENCE header and either length field
     488                 :            :                  * or at least the length of the length field.
     489                 :            :                  */
     490                 :          0 :                 n = BIO_get_mem_data(rctx->mem, &p);
     491         [ #  # ]:          0 :                 if (n < 2)
     492                 :            :                         goto next_io;
     493                 :            : 
     494                 :            :                 /* Check it is an ASN1 SEQUENCE */
     495         [ #  # ]:          0 :                 if (*p++ != (V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED))
     496                 :            :                         {
     497                 :          0 :                         rctx->state = OHS_ERROR;
     498                 :          0 :                         return 0;
     499                 :            :                         }
     500                 :            : 
     501                 :            :                 /* Check out length field */
     502         [ #  # ]:          0 :                 if (*p & 0x80)
     503                 :            :                         {
     504                 :            :                         /* If MSB set on initial length octet we can now
     505                 :            :                          * always read 6 octets: make sure we have them.
     506                 :            :                          */
     507         [ #  # ]:          0 :                         if (n < 6)
     508                 :            :                                 goto next_io;
     509                 :          0 :                         n = *p & 0x7F;
     510                 :            :                         /* Not NDEF or excessive length */
     511         [ #  # ]:          0 :                         if (!n || (n > 4))
     512                 :            :                                 {
     513                 :          0 :                                 rctx->state = OHS_ERROR;
     514                 :          0 :                                 return 0;
     515                 :            :                                 }
     516                 :          0 :                         p++;
     517                 :          0 :                         rctx->asn1_len = 0;
     518         [ #  # ]:          0 :                         for (i = 0; i < n; i++)
     519                 :            :                                 {
     520                 :          0 :                                 rctx->asn1_len <<= 8;
     521                 :          0 :                                 rctx->asn1_len |= *p++;
     522                 :            :                                 }
     523                 :            : 
     524         [ #  # ]:          0 :                         if (rctx->asn1_len > rctx->max_resp_len)
     525                 :            :                                 {
     526                 :          0 :                                 rctx->state = OHS_ERROR;
     527                 :          0 :                                 return 0;
     528                 :            :                                 }
     529                 :            : 
     530                 :          0 :                         rctx->asn1_len += n + 2;
     531                 :            :                         }
     532                 :            :                 else
     533                 :          0 :                         rctx->asn1_len = *p + 2;
     534                 :            : 
     535                 :          0 :                 rctx->state = OHS_ASN1_CONTENT;
     536                 :            : 
     537                 :            :                 /* Fall thru */
     538                 :            :                 
     539                 :            :                 case OHS_ASN1_CONTENT:
     540                 :          0 :                 n = BIO_get_mem_data(rctx->mem, NULL);
     541         [ #  # ]:          0 :                 if (n < (int)rctx->asn1_len)
     542                 :            :                         goto next_io;
     543                 :            : 
     544                 :          0 :                 rctx->state = OHS_DONE;
     545                 :          0 :                 return 1;
     546                 :            : 
     547                 :            :                 break;
     548                 :            : 
     549                 :            :                 case OHS_DONE:
     550                 :          0 :                 return 1;
     551                 :            : 
     552                 :            :                 }
     553                 :            : 
     554                 :            :         return 0;
     555                 :            : 
     556                 :            :         }
     557                 :            : 
     558                 :          0 : int OCSP_sendreq_nbio(OCSP_RESPONSE **presp, OCSP_REQ_CTX *rctx)
     559                 :            :         {
     560                 :          0 :         return OCSP_REQ_CTX_nbio_d2i(rctx,
     561                 :            :                         (ASN1_VALUE **)presp, ASN1_ITEM_rptr(OCSP_RESPONSE));
     562                 :            :         }
     563                 :            : 
     564                 :            : /* Blocking OCSP request handler: now a special case of non-blocking I/O */
     565                 :            : 
     566                 :          0 : OCSP_RESPONSE *OCSP_sendreq_bio(BIO *b, const char *path, OCSP_REQUEST *req)
     567                 :            :         {
     568                 :          0 :         OCSP_RESPONSE *resp = NULL;
     569                 :            :         OCSP_REQ_CTX *ctx;
     570                 :            :         int rv;
     571                 :            : 
     572                 :          0 :         ctx = OCSP_sendreq_new(b, path, req, -1);
     573                 :            : 
     574         [ #  # ]:          0 :         if (!ctx)
     575                 :            :                 return NULL;
     576                 :            : 
     577                 :            :         do
     578                 :            :                 {
     579                 :          0 :                 rv = OCSP_sendreq_nbio(&resp, ctx);
     580 [ #  # ][ #  # ]:          0 :                 } while ((rv == -1) && BIO_should_retry(b));
     581                 :            : 
     582                 :          0 :         OCSP_REQ_CTX_free(ctx);
     583                 :            : 
     584         [ #  # ]:          0 :         if (rv)
     585                 :          0 :                 return resp;
     586                 :            : 
     587                 :            :         return NULL;
     588                 :            :         }

Generated by: LCOV version 1.9