Absolute File Name: | /home/opencoverage/opencoverage/guest-scripts/libressl/src/crypto/ocsp/ocsp_ht.c |
Source code | Switch to Preprocessed file |
Line | Source | Count | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | /* $OpenBSD: ocsp_ht.c,v 1.25 2018/05/13 10:42:03 tb Exp $ */ | - | ||||||||||||
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 <openssl/asn1.h> | - | ||||||||||||
64 | #include <openssl/ocsp.h> | - | ||||||||||||
65 | #include <openssl/err.h> | - | ||||||||||||
66 | #include <openssl/buffer.h> | - | ||||||||||||
67 | - | |||||||||||||
68 | /* Stateful OCSP request code, supporting non-blocking I/O */ | - | ||||||||||||
69 | - | |||||||||||||
70 | /* Opaque OCSP request status structure */ | - | ||||||||||||
71 | - | |||||||||||||
72 | struct ocsp_req_ctx_st { | - | ||||||||||||
73 | int state; /* Current I/O state */ | - | ||||||||||||
74 | unsigned char *iobuf; /* Line buffer */ | - | ||||||||||||
75 | int iobuflen; /* Line buffer length */ | - | ||||||||||||
76 | BIO *io; /* BIO to perform I/O with */ | - | ||||||||||||
77 | BIO *mem; /* Memory BIO response is built into */ | - | ||||||||||||
78 | unsigned long asn1_len; /* ASN1 length of response */ | - | ||||||||||||
79 | }; | - | ||||||||||||
80 | - | |||||||||||||
81 | #define OCSP_MAX_REQUEST_LENGTH (100 * 1024) | - | ||||||||||||
82 | #define OCSP_MAX_LINE_LEN 4096; | - | ||||||||||||
83 | - | |||||||||||||
84 | /* OCSP states */ | - | ||||||||||||
85 | - | |||||||||||||
86 | /* If set no reading should be performed */ | - | ||||||||||||
87 | #define OHS_NOREAD 0x1000 | - | ||||||||||||
88 | /* Error condition */ | - | ||||||||||||
89 | #define OHS_ERROR (0 | OHS_NOREAD) | - | ||||||||||||
90 | /* First line being read */ | - | ||||||||||||
91 | #define OHS_FIRSTLINE 1 | - | ||||||||||||
92 | /* MIME headers being read */ | - | ||||||||||||
93 | #define OHS_HEADERS 2 | - | ||||||||||||
94 | /* OCSP initial header (tag + length) being read */ | - | ||||||||||||
95 | #define OHS_ASN1_HEADER 3 | - | ||||||||||||
96 | /* OCSP content octets being read */ | - | ||||||||||||
97 | #define OHS_ASN1_CONTENT 4 | - | ||||||||||||
98 | /* Request being sent */ | - | ||||||||||||
99 | #define OHS_ASN1_WRITE (6 | OHS_NOREAD) | - | ||||||||||||
100 | /* Request being flushed */ | - | ||||||||||||
101 | #define OHS_ASN1_FLUSH (7 | OHS_NOREAD) | - | ||||||||||||
102 | /* Completed */ | - | ||||||||||||
103 | #define OHS_DONE (8 | OHS_NOREAD) | - | ||||||||||||
104 | - | |||||||||||||
105 | - | |||||||||||||
106 | static int parse_http_line1(char *line); | - | ||||||||||||
107 | - | |||||||||||||
108 | void | - | ||||||||||||
109 | OCSP_REQ_CTX_free(OCSP_REQ_CTX *rctx) | - | ||||||||||||
110 | { | - | ||||||||||||
111 | if (rctx == NULL)
| 0-1 | ||||||||||||
112 | return; executed 1 time by 1 test: return; Executed by:
| 1 | ||||||||||||
113 | - | |||||||||||||
114 | BIO_free(rctx->mem); | - | ||||||||||||
115 | free(rctx->iobuf); | - | ||||||||||||
116 | free(rctx); | - | ||||||||||||
117 | } never executed: end of block | 0 | ||||||||||||
118 | - | |||||||||||||
119 | int | - | ||||||||||||
120 | OCSP_REQ_CTX_set1_req(OCSP_REQ_CTX *rctx, OCSP_REQUEST *req) | - | ||||||||||||
121 | { | - | ||||||||||||
122 | if (BIO_printf(rctx->mem, "Content-Type: application/ocsp-request\r\n"
| 0 | ||||||||||||
123 | "Content-Length: %d\r\n\r\n", i2d_OCSP_REQUEST(req, NULL)) <= 0)
| 0 | ||||||||||||
124 | return 0; never executed: return 0; | 0 | ||||||||||||
125 | if (i2d_OCSP_REQUEST_bio(rctx->mem, req) <= 0)
| 0 | ||||||||||||
126 | return 0; never executed: return 0; | 0 | ||||||||||||
127 | rctx->state = OHS_ASN1_WRITE; | - | ||||||||||||
128 | rctx->asn1_len = BIO_get_mem_data(rctx->mem, NULL); | - | ||||||||||||
129 | return 1; never executed: return 1; | 0 | ||||||||||||
130 | } | - | ||||||||||||
131 | - | |||||||||||||
132 | int | - | ||||||||||||
133 | OCSP_REQ_CTX_add1_header(OCSP_REQ_CTX *rctx, const char *name, | - | ||||||||||||
134 | const char *value) | - | ||||||||||||
135 | { | - | ||||||||||||
136 | if (!name)
| 0 | ||||||||||||
137 | return 0; never executed: return 0; | 0 | ||||||||||||
138 | if (BIO_puts(rctx->mem, name) <= 0)
| 0 | ||||||||||||
139 | return 0; never executed: return 0; | 0 | ||||||||||||
140 | if (value) {
| 0 | ||||||||||||
141 | if (BIO_write(rctx->mem, ": ", 2) != 2)
| 0 | ||||||||||||
142 | return 0; never executed: return 0; | 0 | ||||||||||||
143 | if (BIO_puts(rctx->mem, value) <= 0)
| 0 | ||||||||||||
144 | return 0; never executed: return 0; | 0 | ||||||||||||
145 | } never executed: end of block | 0 | ||||||||||||
146 | if (BIO_write(rctx->mem, "\r\n", 2) != 2)
| 0 | ||||||||||||
147 | return 0; never executed: return 0; | 0 | ||||||||||||
148 | return 1; never executed: return 1; | 0 | ||||||||||||
149 | } | - | ||||||||||||
150 | - | |||||||||||||
151 | OCSP_REQ_CTX * | - | ||||||||||||
152 | OCSP_sendreq_new(BIO *io, const char *path, OCSP_REQUEST *req, int maxline) | - | ||||||||||||
153 | { | - | ||||||||||||
154 | OCSP_REQ_CTX *rctx; | - | ||||||||||||
155 | - | |||||||||||||
156 | rctx = malloc(sizeof(OCSP_REQ_CTX)); | - | ||||||||||||
157 | if (rctx == NULL)
| 0 | ||||||||||||
158 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||
159 | rctx->state = OHS_ERROR; | - | ||||||||||||
160 | if ((rctx->mem = BIO_new(BIO_s_mem())) == NULL) {
| 0 | ||||||||||||
161 | free(rctx); | - | ||||||||||||
162 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||
163 | } | - | ||||||||||||
164 | rctx->io = io; | - | ||||||||||||
165 | rctx->asn1_len = 0; | - | ||||||||||||
166 | if (maxline > 0)
| 0 | ||||||||||||
167 | rctx->iobuflen = maxline; never executed: rctx->iobuflen = maxline; | 0 | ||||||||||||
168 | else | - | ||||||||||||
169 | rctx->iobuflen = OCSP_MAX_LINE_LEN; never executed: rctx->iobuflen = 4096; | 0 | ||||||||||||
170 | rctx->iobuf = malloc(rctx->iobuflen); | - | ||||||||||||
171 | if (!rctx->iobuf) {
| 0 | ||||||||||||
172 | BIO_free(rctx->mem); | - | ||||||||||||
173 | free(rctx); | - | ||||||||||||
174 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||
175 | } | - | ||||||||||||
176 | if (!path)
| 0 | ||||||||||||
177 | path = "/"; never executed: path = "/"; | 0 | ||||||||||||
178 | - | |||||||||||||
179 | if (BIO_printf(rctx->mem, "POST %s HTTP/1.0\r\n", path) <= 0) {
| 0 | ||||||||||||
180 | free(rctx->iobuf); | - | ||||||||||||
181 | BIO_free(rctx->mem); | - | ||||||||||||
182 | free(rctx); | - | ||||||||||||
183 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||
184 | } | - | ||||||||||||
185 | - | |||||||||||||
186 | if (req && !OCSP_REQ_CTX_set1_req(rctx, req)) {
| 0 | ||||||||||||
187 | free(rctx->iobuf); | - | ||||||||||||
188 | BIO_free(rctx->mem); | - | ||||||||||||
189 | free(rctx); | - | ||||||||||||
190 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||
191 | } | - | ||||||||||||
192 | - | |||||||||||||
193 | return rctx; never executed: return rctx; | 0 | ||||||||||||
194 | } | - | ||||||||||||
195 | - | |||||||||||||
196 | /* Parse the HTTP response. This will look like this: | - | ||||||||||||
197 | * "HTTP/1.0 200 OK". We need to obtain the numeric code and | - | ||||||||||||
198 | * (optional) informational message. | - | ||||||||||||
199 | */ | - | ||||||||||||
200 | static int | - | ||||||||||||
201 | parse_http_line1(char *line) | - | ||||||||||||
202 | { | - | ||||||||||||
203 | int retcode; | - | ||||||||||||
204 | char *p, *q, *r; | - | ||||||||||||
205 | - | |||||||||||||
206 | /* Skip to first white space (passed protocol info) */ | - | ||||||||||||
207 | for (p = line; *p && !isspace((unsigned char)*p); p++)
| 0 | ||||||||||||
208 | continue; never executed: continue; | 0 | ||||||||||||
209 | if (!*p) {
| 0 | ||||||||||||
210 | OCSPerror(OCSP_R_SERVER_RESPONSE_PARSE_ERROR); | - | ||||||||||||
211 | return 0; never executed: return 0; | 0 | ||||||||||||
212 | } | - | ||||||||||||
213 | - | |||||||||||||
214 | /* Skip past white space to start of response code */ | - | ||||||||||||
215 | while (*p && isspace((unsigned char)*p))
| 0 | ||||||||||||
216 | p++; never executed: p++; | 0 | ||||||||||||
217 | if (!*p) {
| 0 | ||||||||||||
218 | OCSPerror(OCSP_R_SERVER_RESPONSE_PARSE_ERROR); | - | ||||||||||||
219 | return 0; never executed: return 0; | 0 | ||||||||||||
220 | } | - | ||||||||||||
221 | - | |||||||||||||
222 | /* Find end of response code: first whitespace after start of code */ | - | ||||||||||||
223 | for (q = p; *q && !isspace((unsigned char)*q); q++)
| 0 | ||||||||||||
224 | continue; never executed: continue; | 0 | ||||||||||||
225 | if (!*q) {
| 0 | ||||||||||||
226 | OCSPerror(OCSP_R_SERVER_RESPONSE_PARSE_ERROR); | - | ||||||||||||
227 | return 0; never executed: return 0; | 0 | ||||||||||||
228 | } | - | ||||||||||||
229 | - | |||||||||||||
230 | /* Set end of response code and start of message */ | - | ||||||||||||
231 | *q++ = 0; | - | ||||||||||||
232 | - | |||||||||||||
233 | /* Attempt to parse numeric code */ | - | ||||||||||||
234 | retcode = strtoul(p, &r, 10); | - | ||||||||||||
235 | - | |||||||||||||
236 | if (*r)
| 0 | ||||||||||||
237 | return 0; never executed: return 0; | 0 | ||||||||||||
238 | - | |||||||||||||
239 | /* Skip over any leading white space in message */ | - | ||||||||||||
240 | while (*q && isspace((unsigned char)*q))
| 0 | ||||||||||||
241 | q++; never executed: q++; | 0 | ||||||||||||
242 | if (*q) {
| 0 | ||||||||||||
243 | /* Finally zap any trailing white space in message (include | - | ||||||||||||
244 | * CRLF) */ | - | ||||||||||||
245 | - | |||||||||||||
246 | /* We know q has a non white space character so this is OK */ | - | ||||||||||||
247 | for (r = q + strlen(q) - 1; isspace((unsigned char)*r); r--)
| 0 | ||||||||||||
248 | *r = 0; never executed: *r = 0; | 0 | ||||||||||||
249 | } never executed: end of block | 0 | ||||||||||||
250 | if (retcode != 200) {
| 0 | ||||||||||||
251 | OCSPerror(OCSP_R_SERVER_RESPONSE_ERROR); | - | ||||||||||||
252 | if (!*q)
| 0 | ||||||||||||
253 | ERR_asprintf_error_data("Code=%s", p); never executed: ERR_asprintf_error_data("Code=%s", p); | 0 | ||||||||||||
254 | else | - | ||||||||||||
255 | ERR_asprintf_error_data("Code=%s,Reason=%s", p, q); never executed: ERR_asprintf_error_data("Code=%s,Reason=%s", p, q); | 0 | ||||||||||||
256 | return 0; never executed: return 0; | 0 | ||||||||||||
257 | } | - | ||||||||||||
258 | - | |||||||||||||
259 | return 1; never executed: return 1; | 0 | ||||||||||||
260 | } | - | ||||||||||||
261 | - | |||||||||||||
262 | int | - | ||||||||||||
263 | OCSP_sendreq_nbio(OCSP_RESPONSE **presp, OCSP_REQ_CTX *rctx) | - | ||||||||||||
264 | { | - | ||||||||||||
265 | int i, n; | - | ||||||||||||
266 | const unsigned char *p; | - | ||||||||||||
267 | - | |||||||||||||
268 | next_io: code before this statement never executed: next_io: | 0 | ||||||||||||
269 | if (!(rctx->state & OHS_NOREAD)) {
| 0 | ||||||||||||
270 | n = BIO_read(rctx->io, rctx->iobuf, rctx->iobuflen); | - | ||||||||||||
271 | - | |||||||||||||
272 | if (n <= 0) {
| 0 | ||||||||||||
273 | if (BIO_should_retry(rctx->io))
| 0 | ||||||||||||
274 | return -1; never executed: return -1; | 0 | ||||||||||||
275 | return 0; never executed: return 0; | 0 | ||||||||||||
276 | } | - | ||||||||||||
277 | - | |||||||||||||
278 | /* Write data to memory BIO */ | - | ||||||||||||
279 | if (BIO_write(rctx->mem, rctx->iobuf, n) != n)
| 0 | ||||||||||||
280 | return 0; never executed: return 0; | 0 | ||||||||||||
281 | } never executed: end of block | 0 | ||||||||||||
282 | - | |||||||||||||
283 | switch (rctx->state) { | - | ||||||||||||
284 | case OHS_ASN1_WRITE: never executed: case (6 | 0x1000): | 0 | ||||||||||||
285 | n = BIO_get_mem_data(rctx->mem, &p); | - | ||||||||||||
286 | i = BIO_write(rctx->io, | - | ||||||||||||
287 | p + (n - rctx->asn1_len), rctx->asn1_len); | - | ||||||||||||
288 | if (i <= 0) {
| 0 | ||||||||||||
289 | if (BIO_should_retry(rctx->io))
| 0 | ||||||||||||
290 | return -1; never executed: return -1; | 0 | ||||||||||||
291 | rctx->state = OHS_ERROR; | - | ||||||||||||
292 | return 0; never executed: return 0; | 0 | ||||||||||||
293 | } | - | ||||||||||||
294 | - | |||||||||||||
295 | rctx->asn1_len -= i; | - | ||||||||||||
296 | if (rctx->asn1_len > 0)
| 0 | ||||||||||||
297 | goto next_io; never executed: goto next_io; | 0 | ||||||||||||
298 | - | |||||||||||||
299 | rctx->state = OHS_ASN1_FLUSH; | - | ||||||||||||
300 | - | |||||||||||||
301 | (void)BIO_reset(rctx->mem); | - | ||||||||||||
302 | /* FALLTHROUGH */ | - | ||||||||||||
303 | - | |||||||||||||
304 | case OHS_ASN1_FLUSH: code before this statement never executed: case (7 | 0x1000): never executed: case (7 | 0x1000): | 0 | ||||||||||||
305 | i = BIO_flush(rctx->io); | - | ||||||||||||
306 | if (i > 0) {
| 0 | ||||||||||||
307 | rctx->state = OHS_FIRSTLINE; | - | ||||||||||||
308 | goto next_io; never executed: goto next_io; | 0 | ||||||||||||
309 | } | - | ||||||||||||
310 | - | |||||||||||||
311 | if (BIO_should_retry(rctx->io))
| 0 | ||||||||||||
312 | return -1; never executed: return -1; | 0 | ||||||||||||
313 | - | |||||||||||||
314 | rctx->state = OHS_ERROR; | - | ||||||||||||
315 | return 0; never executed: return 0; | 0 | ||||||||||||
316 | - | |||||||||||||
317 | case OHS_ERROR: never executed: case (0 | 0x1000): | 0 | ||||||||||||
318 | return 0; never executed: return 0; | 0 | ||||||||||||
319 | - | |||||||||||||
320 | case OHS_FIRSTLINE: never executed: case 1: | 0 | ||||||||||||
321 | case OHS_HEADERS: never executed: case 2: | 0 | ||||||||||||
322 | /* Attempt to read a line in */ | - | ||||||||||||
323 | next_line: | - | ||||||||||||
324 | /* Due to &%^*$" memory BIO behaviour with BIO_gets we | - | ||||||||||||
325 | * have to check there's a complete line in there before | - | ||||||||||||
326 | * calling BIO_gets or we'll just get a partial read. | - | ||||||||||||
327 | */ | - | ||||||||||||
328 | n = BIO_get_mem_data(rctx->mem, &p); | - | ||||||||||||
329 | if ((n <= 0) || !memchr(p, '\n', n)) {
| 0 | ||||||||||||
330 | if (n >= rctx->iobuflen) {
| 0 | ||||||||||||
331 | rctx->state = OHS_ERROR; | - | ||||||||||||
332 | return 0; never executed: return 0; | 0 | ||||||||||||
333 | } | - | ||||||||||||
334 | goto next_io; never executed: goto next_io; | 0 | ||||||||||||
335 | } | - | ||||||||||||
336 | n = BIO_gets(rctx->mem, (char *)rctx->iobuf, rctx->iobuflen); | - | ||||||||||||
337 | if (n <= 0) {
| 0 | ||||||||||||
338 | if (BIO_should_retry(rctx->mem))
| 0 | ||||||||||||
339 | goto next_io; never executed: goto next_io; | 0 | ||||||||||||
340 | rctx->state = OHS_ERROR; | - | ||||||||||||
341 | return 0; never executed: return 0; | 0 | ||||||||||||
342 | } | - | ||||||||||||
343 | - | |||||||||||||
344 | /* Don't allow excessive lines */ | - | ||||||||||||
345 | if (n == rctx->iobuflen) {
| 0 | ||||||||||||
346 | rctx->state = OHS_ERROR; | - | ||||||||||||
347 | return 0; never executed: return 0; | 0 | ||||||||||||
348 | } | - | ||||||||||||
349 | - | |||||||||||||
350 | /* First line */ | - | ||||||||||||
351 | if (rctx->state == OHS_FIRSTLINE) {
| 0 | ||||||||||||
352 | if (parse_http_line1((char *)rctx->iobuf)) {
| 0 | ||||||||||||
353 | rctx->state = OHS_HEADERS; | - | ||||||||||||
354 | goto next_line; never executed: goto next_line; | 0 | ||||||||||||
355 | } else { | - | ||||||||||||
356 | rctx->state = OHS_ERROR; | - | ||||||||||||
357 | return 0; never executed: return 0; | 0 | ||||||||||||
358 | } | - | ||||||||||||
359 | } else { | - | ||||||||||||
360 | /* Look for blank line: end of headers */ | - | ||||||||||||
361 | for (p = rctx->iobuf; *p; p++) {
| 0 | ||||||||||||
362 | if ((*p != '\r') && (*p != '\n'))
| 0 | ||||||||||||
363 | break; never executed: break; | 0 | ||||||||||||
364 | } never executed: end of block | 0 | ||||||||||||
365 | if (*p)
| 0 | ||||||||||||
366 | goto next_line; never executed: goto next_line; | 0 | ||||||||||||
367 | - | |||||||||||||
368 | rctx->state = OHS_ASN1_HEADER; | - | ||||||||||||
369 | } never executed: end of block | 0 | ||||||||||||
370 | /* FALLTRHOUGH */ | - | ||||||||||||
371 | - | |||||||||||||
372 | case OHS_ASN1_HEADER: code before this statement never executed: case 3: never executed: case 3: | 0 | ||||||||||||
373 | /* Now reading ASN1 header: can read at least 2 bytes which | - | ||||||||||||
374 | * is enough for ASN1 SEQUENCE header and either length field | - | ||||||||||||
375 | * or at least the length of the length field. | - | ||||||||||||
376 | */ | - | ||||||||||||
377 | n = BIO_get_mem_data(rctx->mem, &p); | - | ||||||||||||
378 | if (n < 2)
| 0 | ||||||||||||
379 | goto next_io; never executed: goto next_io; | 0 | ||||||||||||
380 | - | |||||||||||||
381 | /* Check it is an ASN1 SEQUENCE */ | - | ||||||||||||
382 | if (*p++ != (V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED)) {
| 0 | ||||||||||||
383 | rctx->state = OHS_ERROR; | - | ||||||||||||
384 | return 0; never executed: return 0; | 0 | ||||||||||||
385 | } | - | ||||||||||||
386 | - | |||||||||||||
387 | /* Check out length field */ | - | ||||||||||||
388 | if (*p & 0x80) {
| 0 | ||||||||||||
389 | /* If MSB set on initial length octet we can now | - | ||||||||||||
390 | * always read 6 octets: make sure we have them. | - | ||||||||||||
391 | */ | - | ||||||||||||
392 | if (n < 6)
| 0 | ||||||||||||
393 | goto next_io; never executed: goto next_io; | 0 | ||||||||||||
394 | n = *p & 0x7F; | - | ||||||||||||
395 | /* Not NDEF or excessive length */ | - | ||||||||||||
396 | if (!n || (n > 4)) {
| 0 | ||||||||||||
397 | rctx->state = OHS_ERROR; | - | ||||||||||||
398 | return 0; never executed: return 0; | 0 | ||||||||||||
399 | } | - | ||||||||||||
400 | p++; | - | ||||||||||||
401 | rctx->asn1_len = 0; | - | ||||||||||||
402 | for (i = 0; i < n; i++) {
| 0 | ||||||||||||
403 | rctx->asn1_len <<= 8; | - | ||||||||||||
404 | rctx->asn1_len |= *p++; | - | ||||||||||||
405 | } never executed: end of block | 0 | ||||||||||||
406 | - | |||||||||||||
407 | if (rctx->asn1_len > OCSP_MAX_REQUEST_LENGTH) {
| 0 | ||||||||||||
408 | rctx->state = OHS_ERROR; | - | ||||||||||||
409 | return 0; never executed: return 0; | 0 | ||||||||||||
410 | } | - | ||||||||||||
411 | - | |||||||||||||
412 | rctx->asn1_len += n + 2; | - | ||||||||||||
413 | } else never executed: end of block | 0 | ||||||||||||
414 | rctx->asn1_len = *p + 2; never executed: rctx->asn1_len = *p + 2; | 0 | ||||||||||||
415 | - | |||||||||||||
416 | rctx->state = OHS_ASN1_CONTENT; | - | ||||||||||||
417 | - | |||||||||||||
418 | /* FALLTHROUGH */ | - | ||||||||||||
419 | - | |||||||||||||
420 | case OHS_ASN1_CONTENT: code before this statement never executed: case 4: never executed: case 4: | 0 | ||||||||||||
421 | n = BIO_get_mem_data(rctx->mem, &p); | - | ||||||||||||
422 | if (n < (int)rctx->asn1_len)
| 0 | ||||||||||||
423 | goto next_io; never executed: goto next_io; | 0 | ||||||||||||
424 | - | |||||||||||||
425 | *presp = d2i_OCSP_RESPONSE(NULL, &p, rctx->asn1_len); | - | ||||||||||||
426 | if (*presp) {
| 0 | ||||||||||||
427 | rctx->state = OHS_DONE; | - | ||||||||||||
428 | return 1; never executed: return 1; | 0 | ||||||||||||
429 | } | - | ||||||||||||
430 | - | |||||||||||||
431 | rctx->state = OHS_ERROR; | - | ||||||||||||
432 | return 0; never executed: return 0; | 0 | ||||||||||||
433 | - | |||||||||||||
434 | case OHS_DONE: never executed: case (8 | 0x1000): | 0 | ||||||||||||
435 | return 1; never executed: return 1; | 0 | ||||||||||||
436 | } | - | ||||||||||||
437 | - | |||||||||||||
438 | return 0; never executed: return 0; | 0 | ||||||||||||
439 | } | - | ||||||||||||
440 | - | |||||||||||||
441 | /* Blocking OCSP request handler: now a special case of non-blocking I/O */ | - | ||||||||||||
442 | OCSP_RESPONSE * | - | ||||||||||||
443 | OCSP_sendreq_bio(BIO *b, const char *path, OCSP_REQUEST *req) | - | ||||||||||||
444 | { | - | ||||||||||||
445 | OCSP_RESPONSE *resp = NULL; | - | ||||||||||||
446 | OCSP_REQ_CTX *ctx; | - | ||||||||||||
447 | int rv; | - | ||||||||||||
448 | - | |||||||||||||
449 | ctx = OCSP_sendreq_new(b, path, req, -1); | - | ||||||||||||
450 | if (ctx == NULL)
| 0 | ||||||||||||
451 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||
452 | - | |||||||||||||
453 | do { | - | ||||||||||||
454 | rv = OCSP_sendreq_nbio(&resp, ctx); | - | ||||||||||||
455 | } while ((rv == -1) && BIO_should_retry(b)); never executed: end of block
| 0 | ||||||||||||
456 | - | |||||||||||||
457 | OCSP_REQ_CTX_free(ctx); | - | ||||||||||||
458 | - | |||||||||||||
459 | if (rv)
| 0 | ||||||||||||
460 | return resp; never executed: return resp; | 0 | ||||||||||||
461 | - | |||||||||||||
462 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||
463 | } | - | ||||||||||||
Source code | Switch to Preprocessed file |