Absolute File Name: | /home/opencoverage/opencoverage/guest-scripts/openssl/src/crypto/ocsp/ocsp_ht.c |
Source code | Switch to Preprocessed file |
Line | Source | Count | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | /* | - | ||||||||||||
2 | * Copyright 2001-2017 The OpenSSL Project Authors. All Rights Reserved. | - | ||||||||||||
3 | * | - | ||||||||||||
4 | * Licensed under the OpenSSL license (the "License"). You may not use | - | ||||||||||||
5 | * this file except in compliance with the License. You can obtain a copy | - | ||||||||||||
6 | * in the file LICENSE in the source distribution or at | - | ||||||||||||
7 | * https://www.openssl.org/source/license.html | - | ||||||||||||
8 | */ | - | ||||||||||||
9 | - | |||||||||||||
10 | #include "e_os.h" | - | ||||||||||||
11 | #include <stdio.h> | - | ||||||||||||
12 | #include <stdlib.h> | - | ||||||||||||
13 | #include "internal/ctype.h" | - | ||||||||||||
14 | #include <string.h> | - | ||||||||||||
15 | #include <openssl/asn1.h> | - | ||||||||||||
16 | #include <openssl/ocsp.h> | - | ||||||||||||
17 | #include <openssl/err.h> | - | ||||||||||||
18 | #include <openssl/buffer.h> | - | ||||||||||||
19 | - | |||||||||||||
20 | /* Stateful OCSP request code, supporting non-blocking I/O */ | - | ||||||||||||
21 | - | |||||||||||||
22 | /* Opaque OCSP request status structure */ | - | ||||||||||||
23 | - | |||||||||||||
24 | struct ocsp_req_ctx_st { | - | ||||||||||||
25 | int state; /* Current I/O state */ | - | ||||||||||||
26 | unsigned char *iobuf; /* Line buffer */ | - | ||||||||||||
27 | int iobuflen; /* Line buffer length */ | - | ||||||||||||
28 | BIO *io; /* BIO to perform I/O with */ | - | ||||||||||||
29 | BIO *mem; /* Memory BIO response is built into */ | - | ||||||||||||
30 | unsigned long asn1_len; /* ASN1 length of response */ | - | ||||||||||||
31 | unsigned long max_resp_len; /* Maximum length of response */ | - | ||||||||||||
32 | }; | - | ||||||||||||
33 | - | |||||||||||||
34 | #define OCSP_MAX_RESP_LENGTH (100 * 1024) | - | ||||||||||||
35 | #define OCSP_MAX_LINE_LEN 4096; | - | ||||||||||||
36 | - | |||||||||||||
37 | /* OCSP states */ | - | ||||||||||||
38 | - | |||||||||||||
39 | /* If set no reading should be performed */ | - | ||||||||||||
40 | #define OHS_NOREAD 0x1000 | - | ||||||||||||
41 | /* Error condition */ | - | ||||||||||||
42 | #define OHS_ERROR (0 | OHS_NOREAD) | - | ||||||||||||
43 | /* First line being read */ | - | ||||||||||||
44 | #define OHS_FIRSTLINE 1 | - | ||||||||||||
45 | /* MIME headers being read */ | - | ||||||||||||
46 | #define OHS_HEADERS 2 | - | ||||||||||||
47 | /* OCSP initial header (tag + length) being read */ | - | ||||||||||||
48 | #define OHS_ASN1_HEADER 3 | - | ||||||||||||
49 | /* OCSP content octets being read */ | - | ||||||||||||
50 | #define OHS_ASN1_CONTENT 4 | - | ||||||||||||
51 | /* First call: ready to start I/O */ | - | ||||||||||||
52 | #define OHS_ASN1_WRITE_INIT (5 | OHS_NOREAD) | - | ||||||||||||
53 | /* Request being sent */ | - | ||||||||||||
54 | #define OHS_ASN1_WRITE (6 | OHS_NOREAD) | - | ||||||||||||
55 | /* Request being flushed */ | - | ||||||||||||
56 | #define OHS_ASN1_FLUSH (7 | OHS_NOREAD) | - | ||||||||||||
57 | /* Completed */ | - | ||||||||||||
58 | #define OHS_DONE (8 | OHS_NOREAD) | - | ||||||||||||
59 | /* Headers set, no final \r\n included */ | - | ||||||||||||
60 | #define OHS_HTTP_HEADER (9 | OHS_NOREAD) | - | ||||||||||||
61 | - | |||||||||||||
62 | static int parse_http_line1(char *line); | - | ||||||||||||
63 | - | |||||||||||||
64 | OCSP_REQ_CTX *OCSP_REQ_CTX_new(BIO *io, int maxline) | - | ||||||||||||
65 | { | - | ||||||||||||
66 | OCSP_REQ_CTX *rctx = OPENSSL_zalloc(sizeof(*rctx)); | - | ||||||||||||
67 | - | |||||||||||||
68 | if (rctx == NULL)
| 0 | ||||||||||||
69 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||
70 | rctx->state = OHS_ERROR; | - | ||||||||||||
71 | rctx->max_resp_len = OCSP_MAX_RESP_LENGTH; | - | ||||||||||||
72 | rctx->mem = BIO_new(BIO_s_mem()); | - | ||||||||||||
73 | rctx->io = io; | - | ||||||||||||
74 | if (maxline > 0)
| 0 | ||||||||||||
75 | rctx->iobuflen = maxline; never executed: rctx->iobuflen = maxline; | 0 | ||||||||||||
76 | else | - | ||||||||||||
77 | rctx->iobuflen = OCSP_MAX_LINE_LEN; never executed: rctx->iobuflen = 4096; | 0 | ||||||||||||
78 | rctx->iobuf = OPENSSL_malloc(rctx->iobuflen); | - | ||||||||||||
79 | if (rctx->iobuf == NULL || rctx->mem == NULL) {
| 0 | ||||||||||||
80 | OCSP_REQ_CTX_free(rctx); | - | ||||||||||||
81 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||
82 | } | - | ||||||||||||
83 | return rctx; never executed: return rctx; | 0 | ||||||||||||
84 | } | - | ||||||||||||
85 | - | |||||||||||||
86 | void OCSP_REQ_CTX_free(OCSP_REQ_CTX *rctx) | - | ||||||||||||
87 | { | - | ||||||||||||
88 | if (!rctx)
| 0 | ||||||||||||
89 | return; never executed: return; | 0 | ||||||||||||
90 | BIO_free(rctx->mem); | - | ||||||||||||
91 | OPENSSL_free(rctx->iobuf); | - | ||||||||||||
92 | OPENSSL_free(rctx); | - | ||||||||||||
93 | } never executed: end of block | 0 | ||||||||||||
94 | - | |||||||||||||
95 | BIO *OCSP_REQ_CTX_get0_mem_bio(OCSP_REQ_CTX *rctx) | - | ||||||||||||
96 | { | - | ||||||||||||
97 | return rctx->mem; never executed: return rctx->mem; | 0 | ||||||||||||
98 | } | - | ||||||||||||
99 | - | |||||||||||||
100 | void OCSP_set_max_response_length(OCSP_REQ_CTX *rctx, unsigned long len) | - | ||||||||||||
101 | { | - | ||||||||||||
102 | if (len == 0)
| 0 | ||||||||||||
103 | rctx->max_resp_len = OCSP_MAX_RESP_LENGTH; never executed: rctx->max_resp_len = (100 * 1024); | 0 | ||||||||||||
104 | else | - | ||||||||||||
105 | rctx->max_resp_len = len; never executed: rctx->max_resp_len = len; | 0 | ||||||||||||
106 | } | - | ||||||||||||
107 | - | |||||||||||||
108 | int OCSP_REQ_CTX_i2d(OCSP_REQ_CTX *rctx, const ASN1_ITEM *it, ASN1_VALUE *val) | - | ||||||||||||
109 | { | - | ||||||||||||
110 | static const char req_hdr[] = | - | ||||||||||||
111 | "Content-Type: application/ocsp-request\r\n" | - | ||||||||||||
112 | "Content-Length: %d\r\n\r\n"; | - | ||||||||||||
113 | int reqlen = ASN1_item_i2d(val, NULL, it); | - | ||||||||||||
114 | if (BIO_printf(rctx->mem, req_hdr, reqlen) <= 0)
| 0 | ||||||||||||
115 | return 0; never executed: return 0; | 0 | ||||||||||||
116 | if (ASN1_item_i2d_bio(it, rctx->mem, val) <= 0)
| 0 | ||||||||||||
117 | return 0; never executed: return 0; | 0 | ||||||||||||
118 | rctx->state = OHS_ASN1_WRITE_INIT; | - | ||||||||||||
119 | return 1; never executed: return 1; | 0 | ||||||||||||
120 | } | - | ||||||||||||
121 | - | |||||||||||||
122 | int OCSP_REQ_CTX_nbio_d2i(OCSP_REQ_CTX *rctx, | - | ||||||||||||
123 | ASN1_VALUE **pval, const ASN1_ITEM *it) | - | ||||||||||||
124 | { | - | ||||||||||||
125 | int rv, len; | - | ||||||||||||
126 | const unsigned char *p; | - | ||||||||||||
127 | - | |||||||||||||
128 | rv = OCSP_REQ_CTX_nbio(rctx); | - | ||||||||||||
129 | if (rv != 1)
| 0 | ||||||||||||
130 | return rv; never executed: return rv; | 0 | ||||||||||||
131 | - | |||||||||||||
132 | len = BIO_get_mem_data(rctx->mem, &p); | - | ||||||||||||
133 | *pval = ASN1_item_d2i(NULL, &p, len, it); | - | ||||||||||||
134 | if (*pval == NULL) {
| 0 | ||||||||||||
135 | rctx->state = OHS_ERROR; | - | ||||||||||||
136 | return 0; never executed: return 0; | 0 | ||||||||||||
137 | } | - | ||||||||||||
138 | return 1; never executed: return 1; | 0 | ||||||||||||
139 | } | - | ||||||||||||
140 | - | |||||||||||||
141 | int OCSP_REQ_CTX_http(OCSP_REQ_CTX *rctx, const char *op, const char *path) | - | ||||||||||||
142 | { | - | ||||||||||||
143 | static const char http_hdr[] = "%s %s HTTP/1.0\r\n"; | - | ||||||||||||
144 | - | |||||||||||||
145 | if (!path)
| 0 | ||||||||||||
146 | path = "/"; never executed: path = "/"; | 0 | ||||||||||||
147 | - | |||||||||||||
148 | if (BIO_printf(rctx->mem, http_hdr, op, path) <= 0)
| 0 | ||||||||||||
149 | return 0; never executed: return 0; | 0 | ||||||||||||
150 | rctx->state = OHS_HTTP_HEADER; | - | ||||||||||||
151 | return 1; never executed: return 1; | 0 | ||||||||||||
152 | } | - | ||||||||||||
153 | - | |||||||||||||
154 | int OCSP_REQ_CTX_set1_req(OCSP_REQ_CTX *rctx, OCSP_REQUEST *req) | - | ||||||||||||
155 | { | - | ||||||||||||
156 | return OCSP_REQ_CTX_i2d(rctx, ASN1_ITEM_rptr(OCSP_REQUEST), never executed: return OCSP_REQ_CTX_i2d(rctx, (&(OCSP_REQUEST_it)), (ASN1_VALUE *)req); | 0 | ||||||||||||
157 | (ASN1_VALUE *)req); never executed: return OCSP_REQ_CTX_i2d(rctx, (&(OCSP_REQUEST_it)), (ASN1_VALUE *)req); | 0 | ||||||||||||
158 | } | - | ||||||||||||
159 | - | |||||||||||||
160 | int OCSP_REQ_CTX_add1_header(OCSP_REQ_CTX *rctx, | - | ||||||||||||
161 | const char *name, const char *value) | - | ||||||||||||
162 | { | - | ||||||||||||
163 | if (!name)
| 0 | ||||||||||||
164 | return 0; never executed: return 0; | 0 | ||||||||||||
165 | if (BIO_puts(rctx->mem, name) <= 0)
| 0 | ||||||||||||
166 | return 0; never executed: return 0; | 0 | ||||||||||||
167 | if (value) {
| 0 | ||||||||||||
168 | if (BIO_write(rctx->mem, ": ", 2) != 2)
| 0 | ||||||||||||
169 | return 0; never executed: return 0; | 0 | ||||||||||||
170 | if (BIO_puts(rctx->mem, value) <= 0)
| 0 | ||||||||||||
171 | return 0; never executed: return 0; | 0 | ||||||||||||
172 | } never executed: end of block | 0 | ||||||||||||
173 | if (BIO_write(rctx->mem, "\r\n", 2) != 2)
| 0 | ||||||||||||
174 | return 0; never executed: return 0; | 0 | ||||||||||||
175 | rctx->state = OHS_HTTP_HEADER; | - | ||||||||||||
176 | return 1; never executed: return 1; | 0 | ||||||||||||
177 | } | - | ||||||||||||
178 | - | |||||||||||||
179 | OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, const char *path, OCSP_REQUEST *req, | - | ||||||||||||
180 | int maxline) | - | ||||||||||||
181 | { | - | ||||||||||||
182 | - | |||||||||||||
183 | OCSP_REQ_CTX *rctx = NULL; | - | ||||||||||||
184 | rctx = OCSP_REQ_CTX_new(io, maxline); | - | ||||||||||||
185 | if (rctx == NULL)
| 0 | ||||||||||||
186 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||
187 | - | |||||||||||||
188 | if (!OCSP_REQ_CTX_http(rctx, "POST", path))
| 0 | ||||||||||||
189 | goto err; never executed: goto err; | 0 | ||||||||||||
190 | - | |||||||||||||
191 | if (req && !OCSP_REQ_CTX_set1_req(rctx, req))
| 0 | ||||||||||||
192 | goto err; never executed: goto err; | 0 | ||||||||||||
193 | - | |||||||||||||
194 | return rctx; never executed: return rctx; | 0 | ||||||||||||
195 | - | |||||||||||||
196 | err: | - | ||||||||||||
197 | OCSP_REQ_CTX_free(rctx); | - | ||||||||||||
198 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||
199 | } | - | ||||||||||||
200 | - | |||||||||||||
201 | /* | - | ||||||||||||
202 | * Parse the HTTP response. This will look like this: "HTTP/1.0 200 OK". We | - | ||||||||||||
203 | * need to obtain the numeric code and (optional) informational message. | - | ||||||||||||
204 | */ | - | ||||||||||||
205 | - | |||||||||||||
206 | static int parse_http_line1(char *line) | - | ||||||||||||
207 | { | - | ||||||||||||
208 | int retcode; | - | ||||||||||||
209 | char *p, *q, *r; | - | ||||||||||||
210 | /* Skip to first white space (passed protocol info) */ | - | ||||||||||||
211 | - | |||||||||||||
212 | for (p = line; *p && !ossl_isspace(*p); p++)
| 0 | ||||||||||||
213 | continue; never executed: continue; | 0 | ||||||||||||
214 | if (!*p) {
| 0 | ||||||||||||
215 | OCSPerr(OCSP_F_PARSE_HTTP_LINE1, OCSP_R_SERVER_RESPONSE_PARSE_ERROR); | - | ||||||||||||
216 | return 0; never executed: return 0; | 0 | ||||||||||||
217 | } | - | ||||||||||||
218 | - | |||||||||||||
219 | /* Skip past white space to start of response code */ | - | ||||||||||||
220 | while (*p && ossl_isspace(*p))
| 0 | ||||||||||||
221 | p++; never executed: p++; | 0 | ||||||||||||
222 | - | |||||||||||||
223 | if (!*p) {
| 0 | ||||||||||||
224 | OCSPerr(OCSP_F_PARSE_HTTP_LINE1, OCSP_R_SERVER_RESPONSE_PARSE_ERROR); | - | ||||||||||||
225 | return 0; never executed: return 0; | 0 | ||||||||||||
226 | } | - | ||||||||||||
227 | - | |||||||||||||
228 | /* Find end of response code: first whitespace after start of code */ | - | ||||||||||||
229 | for (q = p; *q && !ossl_isspace(*q); q++)
| 0 | ||||||||||||
230 | continue; never executed: continue; | 0 | ||||||||||||
231 | - | |||||||||||||
232 | if (!*q) {
| 0 | ||||||||||||
233 | OCSPerr(OCSP_F_PARSE_HTTP_LINE1, OCSP_R_SERVER_RESPONSE_PARSE_ERROR); | - | ||||||||||||
234 | return 0; never executed: return 0; | 0 | ||||||||||||
235 | } | - | ||||||||||||
236 | - | |||||||||||||
237 | /* Set end of response code and start of message */ | - | ||||||||||||
238 | *q++ = 0; | - | ||||||||||||
239 | - | |||||||||||||
240 | /* Attempt to parse numeric code */ | - | ||||||||||||
241 | retcode = strtoul(p, &r, 10); | - | ||||||||||||
242 | - | |||||||||||||
243 | if (*r)
| 0 | ||||||||||||
244 | return 0; never executed: return 0; | 0 | ||||||||||||
245 | - | |||||||||||||
246 | /* Skip over any leading white space in message */ | - | ||||||||||||
247 | while (*q && ossl_isspace(*q))
| 0 | ||||||||||||
248 | q++; never executed: q++; | 0 | ||||||||||||
249 | - | |||||||||||||
250 | if (*q) {
| 0 | ||||||||||||
251 | /* | - | ||||||||||||
252 | * Finally zap any trailing white space in message (include CRLF) | - | ||||||||||||
253 | */ | - | ||||||||||||
254 | - | |||||||||||||
255 | /* We know q has a non white space character so this is OK */ | - | ||||||||||||
256 | for (r = q + strlen(q) - 1; ossl_isspace(*r); r--)
| 0 | ||||||||||||
257 | *r = 0; never executed: *r = 0; | 0 | ||||||||||||
258 | } never executed: end of block | 0 | ||||||||||||
259 | if (retcode != 200) {
| 0 | ||||||||||||
260 | OCSPerr(OCSP_F_PARSE_HTTP_LINE1, OCSP_R_SERVER_RESPONSE_ERROR); | - | ||||||||||||
261 | if (!*q)
| 0 | ||||||||||||
262 | ERR_add_error_data(2, "Code=", p); never executed: ERR_add_error_data(2, "Code=", p); | 0 | ||||||||||||
263 | else | - | ||||||||||||
264 | ERR_add_error_data(4, "Code=", p, ",Reason=", q); never executed: ERR_add_error_data(4, "Code=", p, ",Reason=", q); | 0 | ||||||||||||
265 | return 0; never executed: return 0; | 0 | ||||||||||||
266 | } | - | ||||||||||||
267 | - | |||||||||||||
268 | return 1; never executed: return 1; | 0 | ||||||||||||
269 | - | |||||||||||||
270 | } | - | ||||||||||||
271 | - | |||||||||||||
272 | int OCSP_REQ_CTX_nbio(OCSP_REQ_CTX *rctx) | - | ||||||||||||
273 | { | - | ||||||||||||
274 | int i, n; | - | ||||||||||||
275 | const unsigned char *p; | - | ||||||||||||
276 | next_io: code before this statement never executed: next_io: | 0 | ||||||||||||
277 | if (!(rctx->state & OHS_NOREAD)) {
| 0 | ||||||||||||
278 | n = BIO_read(rctx->io, rctx->iobuf, rctx->iobuflen); | - | ||||||||||||
279 | - | |||||||||||||
280 | if (n <= 0) {
| 0 | ||||||||||||
281 | if (BIO_should_retry(rctx->io))
| 0 | ||||||||||||
282 | return -1; never executed: return -1; | 0 | ||||||||||||
283 | return 0; never executed: return 0; | 0 | ||||||||||||
284 | } | - | ||||||||||||
285 | - | |||||||||||||
286 | /* Write data to memory BIO */ | - | ||||||||||||
287 | - | |||||||||||||
288 | if (BIO_write(rctx->mem, rctx->iobuf, n) != n)
| 0 | ||||||||||||
289 | return 0; never executed: return 0; | 0 | ||||||||||||
290 | } never executed: end of block | 0 | ||||||||||||
291 | - | |||||||||||||
292 | switch (rctx->state) { | - | ||||||||||||
293 | case OHS_HTTP_HEADER: never executed: case (9 | 0x1000): | 0 | ||||||||||||
294 | /* Last operation was adding headers: need a final \r\n */ | - | ||||||||||||
295 | if (BIO_write(rctx->mem, "\r\n", 2) != 2) {
| 0 | ||||||||||||
296 | rctx->state = OHS_ERROR; | - | ||||||||||||
297 | return 0; never executed: return 0; | 0 | ||||||||||||
298 | } | - | ||||||||||||
299 | rctx->state = OHS_ASN1_WRITE_INIT; | - | ||||||||||||
300 | - | |||||||||||||
301 | /* fall thru */ | - | ||||||||||||
302 | case OHS_ASN1_WRITE_INIT: code before this statement never executed: case (5 | 0x1000): never executed: case (5 | 0x1000): | 0 | ||||||||||||
303 | rctx->asn1_len = BIO_get_mem_data(rctx->mem, NULL); | - | ||||||||||||
304 | rctx->state = OHS_ASN1_WRITE; | - | ||||||||||||
305 | - | |||||||||||||
306 | /* fall thru */ | - | ||||||||||||
307 | case OHS_ASN1_WRITE: code before this statement never executed: case (6 | 0x1000): never executed: case (6 | 0x1000): | 0 | ||||||||||||
308 | n = BIO_get_mem_data(rctx->mem, &p); | - | ||||||||||||
309 | - | |||||||||||||
310 | i = BIO_write(rctx->io, p + (n - rctx->asn1_len), rctx->asn1_len); | - | ||||||||||||
311 | - | |||||||||||||
312 | if (i <= 0) {
| 0 | ||||||||||||
313 | if (BIO_should_retry(rctx->io))
| 0 | ||||||||||||
314 | return -1; never executed: return -1; | 0 | ||||||||||||
315 | rctx->state = OHS_ERROR; | - | ||||||||||||
316 | return 0; never executed: return 0; | 0 | ||||||||||||
317 | } | - | ||||||||||||
318 | - | |||||||||||||
319 | rctx->asn1_len -= i; | - | ||||||||||||
320 | - | |||||||||||||
321 | if (rctx->asn1_len > 0)
| 0 | ||||||||||||
322 | goto next_io; never executed: goto next_io; | 0 | ||||||||||||
323 | - | |||||||||||||
324 | rctx->state = OHS_ASN1_FLUSH; | - | ||||||||||||
325 | - | |||||||||||||
326 | (void)BIO_reset(rctx->mem); | - | ||||||||||||
327 | - | |||||||||||||
328 | /* fall thru */ | - | ||||||||||||
329 | case OHS_ASN1_FLUSH: code before this statement never executed: case (7 | 0x1000): never executed: case (7 | 0x1000): | 0 | ||||||||||||
330 | - | |||||||||||||
331 | i = BIO_flush(rctx->io); | - | ||||||||||||
332 | - | |||||||||||||
333 | if (i > 0) {
| 0 | ||||||||||||
334 | rctx->state = OHS_FIRSTLINE; | - | ||||||||||||
335 | goto next_io; never executed: goto next_io; | 0 | ||||||||||||
336 | } | - | ||||||||||||
337 | - | |||||||||||||
338 | if (BIO_should_retry(rctx->io))
| 0 | ||||||||||||
339 | return -1; never executed: return -1; | 0 | ||||||||||||
340 | - | |||||||||||||
341 | rctx->state = OHS_ERROR; | - | ||||||||||||
342 | return 0; never executed: return 0; | 0 | ||||||||||||
343 | - | |||||||||||||
344 | case OHS_ERROR: never executed: case (0 | 0x1000): | 0 | ||||||||||||
345 | return 0; never executed: return 0; | 0 | ||||||||||||
346 | - | |||||||||||||
347 | case OHS_FIRSTLINE: never executed: case 1: | 0 | ||||||||||||
348 | case OHS_HEADERS: never executed: case 2: | 0 | ||||||||||||
349 | - | |||||||||||||
350 | /* Attempt to read a line in */ | - | ||||||||||||
351 | - | |||||||||||||
352 | next_line: | - | ||||||||||||
353 | /* | - | ||||||||||||
354 | * Due to &%^*$" memory BIO behaviour with BIO_gets we have to check | - | ||||||||||||
355 | * there's a complete line in there before calling BIO_gets or we'll | - | ||||||||||||
356 | * just get a partial read. | - | ||||||||||||
357 | */ | - | ||||||||||||
358 | n = BIO_get_mem_data(rctx->mem, &p); | - | ||||||||||||
359 | if ((n <= 0) || !memchr(p, '\n', n)) {
| 0 | ||||||||||||
360 | if (n >= rctx->iobuflen) {
| 0 | ||||||||||||
361 | rctx->state = OHS_ERROR; | - | ||||||||||||
362 | return 0; never executed: return 0; | 0 | ||||||||||||
363 | } | - | ||||||||||||
364 | goto next_io; never executed: goto next_io; | 0 | ||||||||||||
365 | } | - | ||||||||||||
366 | n = BIO_gets(rctx->mem, (char *)rctx->iobuf, rctx->iobuflen); | - | ||||||||||||
367 | - | |||||||||||||
368 | if (n <= 0) {
| 0 | ||||||||||||
369 | if (BIO_should_retry(rctx->mem))
| 0 | ||||||||||||
370 | goto next_io; never executed: goto next_io; | 0 | ||||||||||||
371 | rctx->state = OHS_ERROR; | - | ||||||||||||
372 | return 0; never executed: return 0; | 0 | ||||||||||||
373 | } | - | ||||||||||||
374 | - | |||||||||||||
375 | /* Don't allow excessive lines */ | - | ||||||||||||
376 | if (n == rctx->iobuflen) {
| 0 | ||||||||||||
377 | rctx->state = OHS_ERROR; | - | ||||||||||||
378 | return 0; never executed: return 0; | 0 | ||||||||||||
379 | } | - | ||||||||||||
380 | - | |||||||||||||
381 | /* First line */ | - | ||||||||||||
382 | if (rctx->state == OHS_FIRSTLINE) {
| 0 | ||||||||||||
383 | if (parse_http_line1((char *)rctx->iobuf)) {
| 0 | ||||||||||||
384 | rctx->state = OHS_HEADERS; | - | ||||||||||||
385 | goto next_line; never executed: goto next_line; | 0 | ||||||||||||
386 | } else { | - | ||||||||||||
387 | rctx->state = OHS_ERROR; | - | ||||||||||||
388 | return 0; never executed: return 0; | 0 | ||||||||||||
389 | } | - | ||||||||||||
390 | } else { | - | ||||||||||||
391 | /* Look for blank line: end of headers */ | - | ||||||||||||
392 | for (p = rctx->iobuf; *p; p++) {
| 0 | ||||||||||||
393 | if ((*p != '\r') && (*p != '\n'))
| 0 | ||||||||||||
394 | break; never executed: break; | 0 | ||||||||||||
395 | } never executed: end of block | 0 | ||||||||||||
396 | if (*p)
| 0 | ||||||||||||
397 | goto next_line; never executed: goto next_line; | 0 | ||||||||||||
398 | - | |||||||||||||
399 | rctx->state = OHS_ASN1_HEADER; | - | ||||||||||||
400 | - | |||||||||||||
401 | } never executed: end of block | 0 | ||||||||||||
402 | - | |||||||||||||
403 | /* Fall thru */ | - | ||||||||||||
404 | - | |||||||||||||
405 | case OHS_ASN1_HEADER: code before this statement never executed: case 3: never executed: case 3: | 0 | ||||||||||||
406 | /* | - | ||||||||||||
407 | * Now reading ASN1 header: can read at least 2 bytes which is enough | - | ||||||||||||
408 | * for ASN1 SEQUENCE header and either length field or at least the | - | ||||||||||||
409 | * length of the length field. | - | ||||||||||||
410 | */ | - | ||||||||||||
411 | n = BIO_get_mem_data(rctx->mem, &p); | - | ||||||||||||
412 | if (n < 2)
| 0 | ||||||||||||
413 | goto next_io; never executed: goto next_io; | 0 | ||||||||||||
414 | - | |||||||||||||
415 | /* Check it is an ASN1 SEQUENCE */ | - | ||||||||||||
416 | if (*p++ != (V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED)) {
| 0 | ||||||||||||
417 | rctx->state = OHS_ERROR; | - | ||||||||||||
418 | return 0; never executed: return 0; | 0 | ||||||||||||
419 | } | - | ||||||||||||
420 | - | |||||||||||||
421 | /* Check out length field */ | - | ||||||||||||
422 | if (*p & 0x80) {
| 0 | ||||||||||||
423 | /* | - | ||||||||||||
424 | * If MSB set on initial length octet we can now always read 6 | - | ||||||||||||
425 | * octets: make sure we have them. | - | ||||||||||||
426 | */ | - | ||||||||||||
427 | if (n < 6)
| 0 | ||||||||||||
428 | goto next_io; never executed: goto next_io; | 0 | ||||||||||||
429 | n = *p & 0x7F; | - | ||||||||||||
430 | /* Not NDEF or excessive length */ | - | ||||||||||||
431 | if (!n || (n > 4)) {
| 0 | ||||||||||||
432 | rctx->state = OHS_ERROR; | - | ||||||||||||
433 | return 0; never executed: return 0; | 0 | ||||||||||||
434 | } | - | ||||||||||||
435 | p++; | - | ||||||||||||
436 | rctx->asn1_len = 0; | - | ||||||||||||
437 | for (i = 0; i < n; i++) {
| 0 | ||||||||||||
438 | rctx->asn1_len <<= 8; | - | ||||||||||||
439 | rctx->asn1_len |= *p++; | - | ||||||||||||
440 | } never executed: end of block | 0 | ||||||||||||
441 | - | |||||||||||||
442 | if (rctx->asn1_len > rctx->max_resp_len) {
| 0 | ||||||||||||
443 | rctx->state = OHS_ERROR; | - | ||||||||||||
444 | return 0; never executed: return 0; | 0 | ||||||||||||
445 | } | - | ||||||||||||
446 | - | |||||||||||||
447 | rctx->asn1_len += n + 2; | - | ||||||||||||
448 | } else never executed: end of block | 0 | ||||||||||||
449 | rctx->asn1_len = *p + 2; never executed: rctx->asn1_len = *p + 2; | 0 | ||||||||||||
450 | - | |||||||||||||
451 | rctx->state = OHS_ASN1_CONTENT; | - | ||||||||||||
452 | - | |||||||||||||
453 | /* Fall thru */ | - | ||||||||||||
454 | - | |||||||||||||
455 | case OHS_ASN1_CONTENT: code before this statement never executed: case 4: never executed: case 4: | 0 | ||||||||||||
456 | n = BIO_get_mem_data(rctx->mem, NULL); | - | ||||||||||||
457 | if (n < (int)rctx->asn1_len)
| 0 | ||||||||||||
458 | goto next_io; never executed: goto next_io; | 0 | ||||||||||||
459 | - | |||||||||||||
460 | rctx->state = OHS_DONE; | - | ||||||||||||
461 | return 1; never executed: return 1; | 0 | ||||||||||||
462 | - | |||||||||||||
463 | case OHS_DONE: never executed: case (8 | 0x1000): | 0 | ||||||||||||
464 | return 1; never executed: return 1; | 0 | ||||||||||||
465 | - | |||||||||||||
466 | } | - | ||||||||||||
467 | - | |||||||||||||
468 | return 0; never executed: return 0; | 0 | ||||||||||||
469 | - | |||||||||||||
470 | } | - | ||||||||||||
471 | - | |||||||||||||
472 | int OCSP_sendreq_nbio(OCSP_RESPONSE **presp, OCSP_REQ_CTX *rctx) | - | ||||||||||||
473 | { | - | ||||||||||||
474 | return OCSP_REQ_CTX_nbio_d2i(rctx, never executed: return OCSP_REQ_CTX_nbio_d2i(rctx, (ASN1_VALUE **)presp, (&(OCSP_RESPONSE_it))); | 0 | ||||||||||||
475 | (ASN1_VALUE **)presp, never executed: return OCSP_REQ_CTX_nbio_d2i(rctx, (ASN1_VALUE **)presp, (&(OCSP_RESPONSE_it))); | 0 | ||||||||||||
476 | ASN1_ITEM_rptr(OCSP_RESPONSE)); never executed: return OCSP_REQ_CTX_nbio_d2i(rctx, (ASN1_VALUE **)presp, (&(OCSP_RESPONSE_it))); | 0 | ||||||||||||
477 | } | - | ||||||||||||
478 | - | |||||||||||||
479 | /* Blocking OCSP request handler: now a special case of non-blocking I/O */ | - | ||||||||||||
480 | - | |||||||||||||
481 | OCSP_RESPONSE *OCSP_sendreq_bio(BIO *b, const char *path, OCSP_REQUEST *req) | - | ||||||||||||
482 | { | - | ||||||||||||
483 | OCSP_RESPONSE *resp = NULL; | - | ||||||||||||
484 | OCSP_REQ_CTX *ctx; | - | ||||||||||||
485 | int rv; | - | ||||||||||||
486 | - | |||||||||||||
487 | ctx = OCSP_sendreq_new(b, path, req, -1); | - | ||||||||||||
488 | - | |||||||||||||
489 | if (ctx == NULL)
| 0 | ||||||||||||
490 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||
491 | - | |||||||||||||
492 | do { | - | ||||||||||||
493 | rv = OCSP_sendreq_nbio(&resp, ctx); | - | ||||||||||||
494 | } while ((rv == -1) && BIO_should_retry(b)); never executed: end of block
| 0 | ||||||||||||
495 | - | |||||||||||||
496 | OCSP_REQ_CTX_free(ctx); | - | ||||||||||||
497 | - | |||||||||||||
498 | if (rv)
| 0 | ||||||||||||
499 | return resp; never executed: return resp; | 0 | ||||||||||||
500 | - | |||||||||||||
501 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||
502 | } | - | ||||||||||||
Source code | Switch to Preprocessed file |