6ae232055d4d8a97267517c5e50074c2c819941and/* Licensed to the Apache Software Foundation (ASF) under one or more
6ae232055d4d8a97267517c5e50074c2c819941and * contributor license agreements. See the NOTICE file distributed with
fd9abdda70912b99b24e3bf1a38f26fde908a74cnd * this work for additional information regarding copyright ownership.
fd9abdda70912b99b24e3bf1a38f26fde908a74cnd * The ASF licenses this file to You under the Apache License, Version 2.0
fd9abdda70912b99b24e3bf1a38f26fde908a74cnd * (the "License"); you may not use this file except in compliance with
6ae232055d4d8a97267517c5e50074c2c819941and * the License. You may obtain a copy of the License at
96ad5d81ee4a2cc66a4ae19893efc8aa6d06fae7jailletc * Unless required by applicable law or agreed to in writing, software
6ae232055d4d8a97267517c5e50074c2c819941and * distributed under the License is distributed on an "AS IS" BASIS,
6ae232055d4d8a97267517c5e50074c2c819941and * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * See the License for the specific language governing permissions and
2e545ce2450a9953665f701bb05350f0d3f26275nd * limitations under the License.
6ae232055d4d8a97267517c5e50074c2c819941and/* This file implements an OCSP client including a toy HTTP/1.0
6ae232055d4d8a97267517c5e50074c2c819941and * client. Once httpd depends on a real HTTP client library, most of
6ae232055d4d8a97267517c5e50074c2c819941and * this can be thrown away. */
6ae232055d4d8a97267517c5e50074c2c819941and/* Serialize an OCSP request which will be sent to the responder at
b43f840409794ed298e8634f6284741f193b6c4ftakashi * given URI to a memory BIO object, which is returned. */
bc9d4698fce0238d2f6f2682e99423ebb1149976rbowenstatic BIO *serialize_request(OCSP_REQUEST *req, const apr_uri_t *uri)
6ae232055d4d8a97267517c5e50074c2c819941and "Host: %s:%d\r\n"
6ae232055d4d8a97267517c5e50074c2c819941and "Content-Type: application/ocsp-request\r\n"
6ae232055d4d8a97267517c5e50074c2c819941and "Content-Length: %d\r\n"
6ae232055d4d8a97267517c5e50074c2c819941and/* Send the OCSP request serialized into BIO 'request' to the
6ae232055d4d8a97267517c5e50074c2c819941and * responder at given server given by URI. Returns socket object or
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar * NULL on error. */
1f1b6bf13313fdd14a45e52e553d3ff28689b717coarstatic apr_socket_t *send_request(BIO *request, const apr_uri_t *uri,
6ae232055d4d8a97267517c5e50074c2c819941and rv = apr_sockaddr_info_get(&sa, uri->hostname, APR_UNSPEC, uri->port, 0, p);
6ae232055d4d8a97267517c5e50074c2c819941and ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c, APLOGNO(01972)
6ae232055d4d8a97267517c5e50074c2c819941and "could not resolve address of OCSP responder %s",
6ae232055d4d8a97267517c5e50074c2c819941and /* establish a connection to the OCSP responder */
6ae232055d4d8a97267517c5e50074c2c819941and ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(01973)
6ae232055d4d8a97267517c5e50074c2c819941and /* Cycle through address until a connect() succeeds. */
6ae232055d4d8a97267517c5e50074c2c819941and rv = apr_socket_create(&sd, sa->family, SOCK_STREAM, APR_PROTO_TCP, p);
6ae232055d4d8a97267517c5e50074c2c819941and ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c, APLOGNO(01974)
6ae232055d4d8a97267517c5e50074c2c819941and "could not connect to OCSP responder '%s'",
6ae232055d4d8a97267517c5e50074c2c819941and /* send the request and get a response */
6ae232055d4d8a97267517c5e50074c2c819941and ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(01975)
6ae232055d4d8a97267517c5e50074c2c819941and "sending request to OCSP responder");
6ae232055d4d8a97267517c5e50074c2c819941and ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c, APLOGNO(01976)
6ae232055d4d8a97267517c5e50074c2c819941and "failed to send request to OCSP responder '%s'",
6ae232055d4d8a97267517c5e50074c2c819941and/* Return a pool-allocated NUL-terminated line, with CRLF stripped,
6ae232055d4d8a97267517c5e50074c2c819941and * read from brigade 'bbin' using 'bbout' as temporary storage. */
6ae232055d4d8a97267517c5e50074c2c819941andstatic char *get_line(apr_bucket_brigade *bbout, apr_bucket_brigade *bbin,
6ae232055d4d8a97267517c5e50074c2c819941and rv = apr_brigade_split_line(bbout, bbin, APR_BLOCK_READ, 8192);
6ae232055d4d8a97267517c5e50074c2c819941and ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c, APLOGNO(01977)
6ae232055d4d8a97267517c5e50074c2c819941and "failed reading line from OCSP server");
6ae232055d4d8a97267517c5e50074c2c819941and ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c, APLOGNO(01978)
6ae232055d4d8a97267517c5e50074c2c819941and "failed reading line from OCSP server");
6ae232055d4d8a97267517c5e50074c2c819941and if (len == 0) {
6ae232055d4d8a97267517c5e50074c2c819941and ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c, APLOGNO(02321)
6ae232055d4d8a97267517c5e50074c2c819941and "empty response from OCSP server");
6ae232055d4d8a97267517c5e50074c2c819941and ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c, APLOGNO(01979)
6ae232055d4d8a97267517c5e50074c2c819941and "response header line too long from OCSP server");
6ae232055d4d8a97267517c5e50074c2c819941and/* Maximum values to prevent eating RAM forever. */
6ae232055d4d8a97267517c5e50074c2c819941and/* Read the OCSP response from the socket 'sd', using temporary memory
6ae232055d4d8a97267517c5e50074c2c819941and * BIO 'bio', and return the decoded OCSP response object, or NULL on
6ae232055d4d8a97267517c5e50074c2c819941and * error. */
6ae232055d4d8a97267517c5e50074c2c819941andstatic OCSP_RESPONSE *read_response(apr_socket_t *sd, BIO *bio, conn_rec *c,
6ae232055d4d8a97267517c5e50074c2c819941and /* Using brigades for response parsing is much simpler than using
6ae232055d4d8a97267517c5e50074c2c819941and * apr_socket_* directly. */
6ae232055d4d8a97267517c5e50074c2c819941and APR_BRIGADE_INSERT_TAIL(bb, apr_bucket_socket_create(sd, c->bucket_alloc));
6ae232055d4d8a97267517c5e50074c2c819941and ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(01980)
6ae232055d4d8a97267517c5e50074c2c819941and "bad response from OCSP server: %s",
6ae232055d4d8a97267517c5e50074c2c819941and /* Read till end of headers; don't have to even bother parsing the
6ae232055d4d8a97267517c5e50074c2c819941and * Content-Length since the server is obliged to close the
6ae232055d4d8a97267517c5e50074c2c819941and * connection after the response anyway for HTTP/1.0. */
6ae232055d4d8a97267517c5e50074c2c819941and while ((line = get_line(tmpbb, bb, c, p)) != NULL && line[0]
6ae232055d4d8a97267517c5e50074c2c819941and ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(01981)
b43f840409794ed298e8634f6284741f193b6c4ftakashi ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(01982)
bc9d4698fce0238d2f6f2682e99423ebb1149976rbowen "could not read response headers from OCSP server, "
0d0ba3a410038e179b695446bb149cce6264e0abnd else if (!line) {
727872d18412fc021f03969b8641810d8896820bhumbedooh ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(01983)
cc7e1025de9ac63bd4db6fe7f71c158b2cf09fe4humbedooh "could not read response header from OCSP server");
0d0ba3a410038e179b695446bb149cce6264e0abnd /* Read the response body into the memory BIO. */
30471a4650391f57975f60bbb6e4a90be7b284bfhumbedooh ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(01984)
205f749042ed530040a4f0080dbcb47ceae8a374rjung "OCSP response: got EOF");
7fec19672a491661b2fe4b29f685bc7f4efa64d4nd ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c, APLOGNO(01985)
7fec19672a491661b2fe4b29f685bc7f4efa64d4nd "error reading response from OCSP server");
if (len == 0) {
return NULL;
return response;
return NULL;
return NULL;
return response;