OLD | NEW |
1 /* ocsp_ht.c */ | 1 /* ocsp_ht.c */ |
2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | 2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL |
3 * project 2006. | 3 * project 2006. |
4 */ | 4 */ |
5 /* ==================================================================== | 5 /* ==================================================================== |
6 * Copyright (c) 2006 The OpenSSL Project. All rights reserved. | 6 * Copyright (c) 2006 The OpenSSL Project. All rights reserved. |
7 * | 7 * |
8 * Redistribution and use in source and binary forms, with or without | 8 * Redistribution and use in source and binary forms, with or without |
9 * modification, are permitted provided that the following conditions | 9 * modification, are permitted provided that the following conditions |
10 * are met: | 10 * are met: |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 | 111 |
112 void OCSP_REQ_CTX_free(OCSP_REQ_CTX *rctx) | 112 void OCSP_REQ_CTX_free(OCSP_REQ_CTX *rctx) |
113 { | 113 { |
114 if (rctx->mem) | 114 if (rctx->mem) |
115 BIO_free(rctx->mem); | 115 BIO_free(rctx->mem); |
116 if (rctx->iobuf) | 116 if (rctx->iobuf) |
117 OPENSSL_free(rctx->iobuf); | 117 OPENSSL_free(rctx->iobuf); |
118 OPENSSL_free(rctx); | 118 OPENSSL_free(rctx); |
119 } | 119 } |
120 | 120 |
| 121 int OCSP_REQ_CTX_set1_req(OCSP_REQ_CTX *rctx, OCSP_REQUEST *req) |
| 122 { |
| 123 static const char req_hdr[] = |
| 124 "Content-Type: application/ocsp-request\r\n" |
| 125 "Content-Length: %d\r\n\r\n"; |
| 126 if (BIO_printf(rctx->mem, req_hdr, i2d_OCSP_REQUEST(req, NULL)) <= 0) |
| 127 return 0; |
| 128 if (i2d_OCSP_REQUEST_bio(rctx->mem, req) <= 0) |
| 129 return 0; |
| 130 rctx->state = OHS_ASN1_WRITE; |
| 131 rctx->asn1_len = BIO_get_mem_data(rctx->mem, NULL); |
| 132 return 1; |
| 133 } |
| 134 |
| 135 int OCSP_REQ_CTX_add1_header(OCSP_REQ_CTX *rctx, |
| 136 const char *name, const char *value) |
| 137 { |
| 138 if (!name) |
| 139 return 0; |
| 140 if (BIO_puts(rctx->mem, name) <= 0) |
| 141 return 0; |
| 142 if (value) |
| 143 { |
| 144 if (BIO_write(rctx->mem, ": ", 2) != 2) |
| 145 return 0; |
| 146 if (BIO_puts(rctx->mem, value) <= 0) |
| 147 return 0; |
| 148 } |
| 149 if (BIO_write(rctx->mem, "\r\n", 2) != 2) |
| 150 return 0; |
| 151 return 1; |
| 152 } |
| 153 |
121 OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, char *path, OCSP_REQUEST *req, | 154 OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, char *path, OCSP_REQUEST *req, |
122 int maxline) | 155 int maxline) |
123 { | 156 { |
124 » static char post_hdr[] = "POST %s HTTP/1.0\r\n" | 157 » static const char post_hdr[] = "POST %s HTTP/1.0\r\n"; |
125 » "Content-Type: application/ocsp-request\r\n" | |
126 » "Content-Length: %d\r\n\r\n"; | |
127 | 158 |
128 OCSP_REQ_CTX *rctx; | 159 OCSP_REQ_CTX *rctx; |
129 rctx = OPENSSL_malloc(sizeof(OCSP_REQ_CTX)); | 160 rctx = OPENSSL_malloc(sizeof(OCSP_REQ_CTX)); |
130 » rctx->state = OHS_FIRSTLINE; | 161 » rctx->state = OHS_ERROR; |
131 rctx->mem = BIO_new(BIO_s_mem()); | 162 rctx->mem = BIO_new(BIO_s_mem()); |
132 rctx->io = io; | 163 rctx->io = io; |
| 164 rctx->asn1_len = 0; |
133 if (maxline > 0) | 165 if (maxline > 0) |
134 rctx->iobuflen = maxline; | 166 rctx->iobuflen = maxline; |
135 else | 167 else |
136 rctx->iobuflen = OCSP_MAX_LINE_LEN; | 168 rctx->iobuflen = OCSP_MAX_LINE_LEN; |
137 rctx->iobuf = OPENSSL_malloc(rctx->iobuflen); | 169 rctx->iobuf = OPENSSL_malloc(rctx->iobuflen); |
| 170 if (!rctx->iobuf) |
| 171 return 0; |
138 if (!path) | 172 if (!path) |
139 path = "/"; | 173 path = "/"; |
140 | 174 |
141 if (BIO_printf(rctx->mem, post_hdr, path, | 175 if (BIO_printf(rctx->mem, post_hdr, path) <= 0) |
142 » » » » i2d_OCSP_REQUEST(req, NULL)) <= 0) | |
143 » » { | |
144 » » rctx->state = OHS_ERROR; | |
145 return 0; | 176 return 0; |
146 » » } | 177 |
147 if (i2d_OCSP_REQUEST_bio(rctx->mem, req) <= 0) | 178 » if (req && !OCSP_REQ_CTX_set1_req(rctx, req)) |
148 » » { | |
149 » » rctx->state = OHS_ERROR; | |
150 return 0; | 179 return 0; |
151 } | |
152 rctx->state = OHS_ASN1_WRITE; | |
153 rctx->asn1_len = BIO_get_mem_data(rctx->mem, NULL); | |
154 | 180 |
155 return rctx; | 181 return rctx; |
156 } | 182 } |
157 | 183 |
158 /* Parse the HTTP response. This will look like this: | 184 /* Parse the HTTP response. This will look like this: |
159 * "HTTP/1.0 200 OK". We need to obtain the numeric code and | 185 * "HTTP/1.0 200 OK". We need to obtain the numeric code and |
160 * (optional) informational message. | 186 * (optional) informational message. |
161 */ | 187 */ |
162 | 188 |
163 static int parse_http_line1(char *line) | 189 static int parse_http_line1(char *line) |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
364 goto next_line; | 390 goto next_line; |
365 | 391 |
366 rctx->state = OHS_ASN1_HEADER; | 392 rctx->state = OHS_ASN1_HEADER; |
367 | 393 |
368 } | 394 } |
369 | 395 |
370 /* Fall thru */ | 396 /* Fall thru */ |
371 | 397 |
372 | 398 |
373 case OHS_ASN1_HEADER: | 399 case OHS_ASN1_HEADER: |
374 » » /* Now reading ASN1 header: can read at least 6 bytes which | 400 » » /* Now reading ASN1 header: can read at least 2 bytes which |
375 » » * is more than enough for any valid ASN1 SEQUENCE header | 401 » » * is enough for ASN1 SEQUENCE header and either length field |
| 402 » » * or at least the length of the length field. |
376 */ | 403 */ |
377 n = BIO_get_mem_data(rctx->mem, &p); | 404 n = BIO_get_mem_data(rctx->mem, &p); |
378 » » if (n < 6) | 405 » » if (n < 2) |
379 goto next_io; | 406 goto next_io; |
380 | 407 |
381 /* Check it is an ASN1 SEQUENCE */ | 408 /* Check it is an ASN1 SEQUENCE */ |
382 if (*p++ != (V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED)) | 409 if (*p++ != (V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED)) |
383 { | 410 { |
384 rctx->state = OHS_ERROR; | 411 rctx->state = OHS_ERROR; |
385 return 0; | 412 return 0; |
386 } | 413 } |
387 | 414 |
388 /* Check out length field */ | 415 /* Check out length field */ |
389 if (*p & 0x80) | 416 if (*p & 0x80) |
390 { | 417 { |
| 418 /* If MSB set on initial length octet we can now |
| 419 * always read 6 octets: make sure we have them. |
| 420 */ |
| 421 if (n < 6) |
| 422 goto next_io; |
391 n = *p & 0x7F; | 423 n = *p & 0x7F; |
392 /* Not NDEF or excessive length */ | 424 /* Not NDEF or excessive length */ |
393 if (!n || (n > 4)) | 425 if (!n || (n > 4)) |
394 { | 426 { |
395 rctx->state = OHS_ERROR; | 427 rctx->state = OHS_ERROR; |
396 return 0; | 428 return 0; |
397 } | 429 } |
398 p++; | 430 p++; |
399 rctx->asn1_len = 0; | 431 rctx->asn1_len = 0; |
400 for (i = 0; i < n; i++) | 432 for (i = 0; i < n; i++) |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
463 rv = OCSP_sendreq_nbio(&resp, ctx); | 495 rv = OCSP_sendreq_nbio(&resp, ctx); |
464 } while ((rv == -1) && BIO_should_retry(b)); | 496 } while ((rv == -1) && BIO_should_retry(b)); |
465 | 497 |
466 OCSP_REQ_CTX_free(ctx); | 498 OCSP_REQ_CTX_free(ctx); |
467 | 499 |
468 if (rv) | 500 if (rv) |
469 return resp; | 501 return resp; |
470 | 502 |
471 return NULL; | 503 return NULL; |
472 } | 504 } |
OLD | NEW |