提交 ee306a13 编写于 作者: D Dr. Stephen Henson

Initial OCSP server support, using index.txt format.

This can process internal requests or behave like a
mini responder.

Todo: documentation, update usage info.
上级 45442167
......@@ -12,6 +12,13 @@
*) applies to 0.9.6a/0.9.6b and 0.9.7
+) applies to 0.9.7 only
+) Add initial OCSP responder support to ocsp application. The
revocation information is handled using the text based index
use by the ca application. The responder can either handle
requests generated internally, supplied in files (for example
via a CGI script) or using an internal minimal server.
[Steve Henson]
+) Add configuration choices to get zlib compression for TLS.
[Richard Levitte]
......
......@@ -68,6 +68,7 @@
#include <openssl/lhash.h>
#include <openssl/conf.h>
#include <openssl/engine.h>
#include <openssl/txt_db.h>
int app_RAND_load_file(const char *file, BIO *bio_e, int dont_warn);
int app_RAND_write_file(const char *file, BIO *bio_e);
......@@ -187,6 +188,11 @@ STACK_OF(X509) *load_certs(BIO *err, const char *file, int format,
X509_STORE *setup_verify(BIO *bp, char *CAfile, char *CApath);
ENGINE *setup_engine(BIO *err, const char *engine, int debug);
/* Functions defined in ca.c and also used in ocsp.c */
int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold,
ASN1_GENERALIZEDTIME **pinvtm, char *str);
int make_serial_index(TXT_DB *db);
#define FORMAT_UNDEF 0
#define FORMAT_ASN1 1
#define FORMAT_TEXT 2
......
......@@ -658,15 +658,8 @@ bad:
db=TXT_DB_read(in,DB_NUMBER);
if (db == NULL) goto err;
if (!TXT_DB_create_index(db, DB_serial, NULL,
LHASH_HASH_FN(index_serial_hash),
LHASH_COMP_FN(index_serial_cmp)))
{
BIO_printf(bio_err,
"error creating serial number index:(%ld,%ld,%ld)\n",
db->error,db->arg1,db->arg2);
if (!make_serial_index(db))
goto err;
}
if (get_certificate_status(ser_status,db) != 1)
BIO_printf(bio_err,"Error verifying serial %s!\n",
......@@ -891,13 +884,8 @@ bad:
BIO_printf(bio_err,"generating index\n");
}
if (!TXT_DB_create_index(db, DB_serial, NULL,
LHASH_HASH_FN(index_serial_hash),
LHASH_COMP_FN(index_serial_cmp)))
{
BIO_printf(bio_err,"error creating serial number index:(%ld,%ld,%ld)\n",db->error,db->arg1,db->arg2);
if (!make_serial_index(db))
goto err;
}
if (!TXT_DB_create_index(db, DB_name, index_name_qual,
LHASH_HASH_FN(index_name_hash),
......@@ -2889,92 +2877,21 @@ char *make_revocation_str(int rev_type, char *rev_arg)
* 2 OK and some extensions added (i.e. V2 CRL)
*/
int make_revoked(X509_REVOKED *rev, char *str)
{
char *tmp = NULL;
char *rtime_str, *reason_str = NULL, *arg_str = NULL, *p;
int reason_code = -1;
int i, ret = 0;
ASN1_OBJECT *hold = NULL;
ASN1_GENERALIZEDTIME *comp_time = NULL;
ASN1_ENUMERATED *rtmp = NULL;
tmp = BUF_strdup(str);
p = strchr(tmp, ',');
rtime_str = tmp;
if (p)
{
*p = '\0';
p++;
reason_str = p;
p = strchr(p, ',');
if (p)
{
*p = '\0';
arg_str = p + 1;
}
}
i = unpack_revinfo(&rev->revocationDate, &reason_code, &hold, &comp_time, str);
if (rev && !ASN1_UTCTIME_set_string(rev->revocationDate, rtime_str))
{
BIO_printf(bio_err, "invalid revocation date %s\n", rtime_str);
if (i == 0)
goto err;
}
if (reason_str)
{
for (i = 0; i < NUM_REASONS; i++)
{
if(!strcasecmp(reason_str, crl_reasons[i]))
{
reason_code = i;
break;
}
}
if (reason_code == OCSP_REVOKED_STATUS_NOSTATUS)
{
BIO_printf(bio_err, "invalid reason code %s\n", reason_str);
goto err;
}
if (reason_code == 7)
reason_code = OCSP_REVOKED_STATUS_REMOVEFROMCRL;
else if (reason_code == 8) /* Hold instruction */
{
if (!arg_str)
{
BIO_printf(bio_err, "missing hold instruction\n");
goto err;
}
reason_code = OCSP_REVOKED_STATUS_CERTIFICATEHOLD;
hold = OBJ_txt2obj(arg_str, 0);
if (!hold)
{
BIO_printf(bio_err, "invalid object identifier %s\n", arg_str);
goto err;
}
}
else if ((reason_code == 9) || (reason_code == 10))
{
if (!arg_str)
{
BIO_printf(bio_err, "missing compromised time\n");
goto err;
}
comp_time = ASN1_GENERALIZEDTIME_new();
if (!ASN1_GENERALIZEDTIME_set_string(comp_time, arg_str))
{
BIO_printf(bio_err, "invalid compromised time %s\n", arg_str);
goto err;
}
if (reason_code == 9)
reason_code = OCSP_REVOKED_STATUS_KEYCOMPROMISE;
else
reason_code = OCSP_REVOKED_STATUS_CACOMPROMISE;
}
}
if (rev && (reason_code != OCSP_REVOKED_STATUS_NOSTATUS))
{
......@@ -3108,3 +3025,121 @@ int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str)
BIO_printf(bp,"'\n");
return 1;
}
int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold, ASN1_GENERALIZEDTIME **pinvtm, char *str)
{
char *tmp = NULL;
char *rtime_str, *reason_str = NULL, *arg_str = NULL, *p;
int reason_code = -1;
int i, ret = 0;
ASN1_OBJECT *hold = NULL;
ASN1_GENERALIZEDTIME *comp_time = NULL;
tmp = BUF_strdup(str);
p = strchr(tmp, ',');
rtime_str = tmp;
if (p)
{
*p = '\0';
p++;
reason_str = p;
p = strchr(p, ',');
if (p)
{
*p = '\0';
arg_str = p + 1;
}
}
if (prevtm)
{
*prevtm = ASN1_UTCTIME_new();
if (!ASN1_UTCTIME_set_string(*prevtm, rtime_str))
{
BIO_printf(bio_err, "invalid revocation date %s\n", rtime_str);
goto err;
}
}
if (reason_str)
{
for (i = 0; i < NUM_REASONS; i++)
{
if(!strcasecmp(reason_str, crl_reasons[i]))
{
reason_code = i;
break;
}
}
if (reason_code == OCSP_REVOKED_STATUS_NOSTATUS)
{
BIO_printf(bio_err, "invalid reason code %s\n", reason_str);
goto err;
}
if (reason_code == 7)
reason_code = OCSP_REVOKED_STATUS_REMOVEFROMCRL;
else if (reason_code == 8) /* Hold instruction */
{
if (!arg_str)
{
BIO_printf(bio_err, "missing hold instruction\n");
goto err;
}
reason_code = OCSP_REVOKED_STATUS_CERTIFICATEHOLD;
hold = OBJ_txt2obj(arg_str, 0);
if (!hold)
{
BIO_printf(bio_err, "invalid object identifier %s\n", arg_str);
goto err;
}
if (phold) *phold = hold;
}
else if ((reason_code == 9) || (reason_code == 10))
{
if (!arg_str)
{
BIO_printf(bio_err, "missing compromised time\n");
goto err;
}
comp_time = ASN1_GENERALIZEDTIME_new();
if (!ASN1_GENERALIZEDTIME_set_string(comp_time, arg_str))
{
BIO_printf(bio_err, "invalid compromised time %s\n", arg_str);
goto err;
}
if (reason_code == 9)
reason_code = OCSP_REVOKED_STATUS_KEYCOMPROMISE;
else
reason_code = OCSP_REVOKED_STATUS_CACOMPROMISE;
}
}
if (preason) *preason = reason_code;
if (pinvtm) *pinvtm = comp_time;
else ASN1_GENERALIZEDTIME_free(comp_time);
err:
if (tmp) OPENSSL_free(tmp);
if (!phold) ASN1_OBJECT_free(hold);
if (!pinvtm) ASN1_GENERALIZEDTIME_free(comp_time);
return ret;
}
int make_serial_index(TXT_DB *db)
{
if (!TXT_DB_create_index(db, DB_serial, NULL,
LHASH_HASH_FN(index_serial_hash),
LHASH_COMP_FN(index_serial_cmp)))
{
BIO_printf(bio_err,
"error creating serial number index:(%ld,%ld,%ld)\n",
db->error,db->arg1,db->arg2);
return 0;
}
return 1;
}
......@@ -67,6 +67,19 @@
/* Maximum leeway in validity period: default 5 minutes */
#define MAX_VALIDITY_PERIOD (5 * 60)
/* CA index.txt definitions */
#define DB_type 0
#define DB_exp_date 1
#define DB_rev_date 2
#define DB_serial 3 /* index - unique */
#define DB_file 4
#define DB_name 5 /* index - unique for active */
#define DB_NUMBER 6
#define DB_TYPE_REV 'R'
#define DB_TYPE_EXP 'E'
#define DB_TYPE_VAL 'V'
static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, X509 *issuer,
STACK_OF(OCSP_CERTID) *ids);
static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, X509 *issuer,
......@@ -75,6 +88,15 @@ static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req,
STACK *names, STACK_OF(OCSP_CERTID) *ids,
long nsec, long maxage);
static int make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, TXT_DB *db,
X509 *ca, X509 *rcert, EVP_PKEY *rkey,
STACK_OF(X509) *rother, unsigned long flags,
int nmin, int ndays);
static char **lookup_serial(TXT_DB *db, ASN1_INTEGER *ser);
static OCSP_REQUEST *do_responder(BIO **cbio, char *port);
static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp);
#undef PROG
#define PROG ocsp_main
......@@ -88,14 +110,15 @@ int MAIN(int argc, char **argv)
char *reqin = NULL, *respin = NULL;
char *reqout = NULL, *respout = NULL;
char *signfile = NULL, *keyfile = NULL;
char *rsignfile = NULL, *rkeyfile = NULL;
char *outfile = NULL;
int add_nonce = 1, noverify = 0, use_ssl = -1;
OCSP_REQUEST *req = NULL;
OCSP_RESPONSE *resp = NULL;
OCSP_BASICRESP *bs = NULL;
X509 *issuer = NULL, *cert = NULL;
X509 *signer = NULL;
EVP_PKEY *key = NULL;
X509 *signer = NULL, *rsigner = NULL;
EVP_PKEY *key = NULL, *rkey = NULL;
BIO *cbio = NULL, *derbio = NULL;
BIO *out = NULL;
int req_text = 0, resp_text = 0;
......@@ -103,14 +126,21 @@ int MAIN(int argc, char **argv)
char *CAfile = NULL, *CApath = NULL;
X509_STORE *store = NULL;
SSL_CTX *ctx = NULL;
STACK_OF(X509) *sign_other = NULL, *verify_other = NULL;
char *sign_certfile = NULL, *verify_certfile = NULL;
unsigned long sign_flags = 0, verify_flags = 0;
STACK_OF(X509) *sign_other = NULL, *verify_other = NULL, *rother = NULL;
char *sign_certfile = NULL, *verify_certfile = NULL, *rcertfile = NULL;
unsigned long sign_flags = 0, verify_flags = 0, rflags = 0;
int ret = 1;
int badarg = 0;
int i;
STACK *reqnames = NULL;
STACK_OF(OCSP_CERTID) *ids = NULL;
X509 *rca_cert = NULL;
char *ridx_filename = NULL;
char *rca_filename = NULL;
TXT_DB *rdb = NULL;
int nmin = 0, ndays = -1;
if (bio_err == NULL) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
SSL_load_error_strings();
args = argv + 1;
......@@ -149,12 +179,27 @@ int MAIN(int argc, char **argv)
}
else badarg = 1;
}
else if (!strcmp(*args, "-port"))
{
if (args[1])
{
args++;
port = *args;
}
else badarg = 1;
}
else if (!strcmp(*args, "-noverify"))
noverify = 1;
else if (!strcmp(*args, "-nonce"))
add_nonce = 2;
else if (!strcmp(*args, "-no_nonce"))
add_nonce = 0;
else if (!strcmp(*args, "-responder_no_certs"))
rflags |= OCSP_NOCERTS;
else if (!strcmp(*args, "-responder_no_time"))
rflags |= OCSP_NOTIME;
else if (!strcmp(*args, "-responder_key_id"))
rflags |= OCSP_RESPID_KEY;
else if (!strcmp(*args, "-no_certs"))
sign_flags |= OCSP_NOCERTS;
else if (!strcmp(*args, "-no_signature_verify"))
......@@ -361,12 +406,91 @@ int MAIN(int argc, char **argv)
}
else badarg = 1;
}
else if (!strcmp(*args, "-index"))
{
if (args[1])
{
args++;
ridx_filename = *args;
}
else badarg = 1;
}
else if (!strcmp(*args, "-CA"))
{
if (args[1])
{
args++;
rca_filename = *args;
}
else badarg = 1;
}
else if (!strcmp (*args, "-nmin"))
{
if (args[1])
{
args++;
nmin = atol(*args);
if (nmin < 0)
{
BIO_printf(bio_err,
"Illegal update period %s\n",
*args);
badarg = 1;
}
}
if (ndays == -1)
ndays = 0;
else badarg = 1;
}
else if (!strcmp (*args, "-ndays"))
{
if (args[1])
{
args++;
ndays = atol(*args);
if (ndays < 0)
{
BIO_printf(bio_err,
"Illegal update period %s\n",
*args);
badarg = 1;
}
}
else badarg = 1;
}
else if (!strcmp(*args, "-rsigner"))
{
if (args[1])
{
args++;
rsignfile = *args;
}
else badarg = 1;
}
else if (!strcmp(*args, "-rkey"))
{
if (args[1])
{
args++;
rkeyfile = *args;
}
else badarg = 1;
}
else if (!strcmp(*args, "-rother"))
{
if (args[1])
{
args++;
rcertfile = *args;
}
else badarg = 1;
}
else badarg = 1;
args++;
}
/* Have we anything to do? */
if (!req && !reqin && !respin) badarg = 1;
if (!req && !reqin && !respin && !(port && ridx_filename)) badarg = 1;
if (badarg)
{
......@@ -437,7 +561,20 @@ int MAIN(int argc, char **argv)
}
}
if (!req && (signfile || reqout || host || add_nonce))
if (!req && port)
{
req = do_responder(&cbio, port);
if (!req && !cbio)
goto end;
if (!req && cbio)
{
resp = OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL);
send_ocsp_response(cbio, resp);
goto done_resp;
}
}
if (!req && (signfile || reqout || host || add_nonce || ridx_filename))
{
BIO_printf(bio_err, "Need an OCSP request for this operation!\n");
goto end;
......@@ -464,12 +601,7 @@ int MAIN(int argc, char **argv)
key = load_key(bio_err, keyfile, FORMAT_PEM, NULL, NULL,
"signer private key");
if (!key)
{
#if 0 /* An appropriate message has already been printed */
BIO_printf(bio_err, "Error loading signer private key\n");
#endif
goto end;
}
if (!OCSP_request_sign(req, signer, key, EVP_sha1(), sign_other, sign_flags))
{
BIO_printf(bio_err, "Error signing OCSP request\n");
......@@ -477,21 +609,61 @@ int MAIN(int argc, char **argv)
}
}
if (reqout)
if (req_text && req) OCSP_REQUEST_print(out, req, 0);
if (rsignfile)
{
derbio = BIO_new_file(reqout, "wb");
if (!derbio)
if (!rkeyfile) rkeyfile = rsignfile;
rsigner = load_cert(bio_err, rsignfile, FORMAT_PEM,
NULL, e, "responder certificate");
if (!rsigner)
{
BIO_printf(bio_err, "Error opening file %s\n", reqout);
BIO_printf(bio_err, "Error loading responder certificate\n");
goto end;
}
i2d_OCSP_REQUEST_bio(derbio, req);
BIO_free(derbio);
rca_cert = load_cert(bio_err, rca_filename, FORMAT_PEM,
NULL, e, "CA certificate");
if (rcertfile)
{
rother = load_certs(bio_err, sign_certfile, FORMAT_PEM,
NULL, e, "responder other certificates");
if (!sign_other) goto end;
}
rkey = load_key(bio_err, rkeyfile, FORMAT_PEM, NULL, NULL,
"responder private key");
if (!rkey)
goto end;
}
if (req_text && req) OCSP_REQUEST_print(out, req, 0);
if (ridx_filename && (!rkey || !rsigner || !rca_cert))
{
BIO_printf(bio_err, "Need a responder certificate, key and CA for this operation!\n");
goto end;
}
if (host)
if (ridx_filename)
{
BIO *db_bio = NULL;
db_bio = BIO_new_file(ridx_filename, "r");
if (!db_bio)
{
BIO_printf(bio_err, "Error opening index file %s\n", ridx_filename);
goto end;
}
rdb = TXT_DB_read(db_bio, DB_NUMBER);
BIO_free(db_bio);
if (!rdb)
{
BIO_printf(bio_err, "Error reading index file %s\n", ridx_filename);
goto end;
}
if (!make_serial_index(rdb))
goto end;
i = make_ocsp_response(&resp, req, rdb, rca_cert, rsigner, rkey, rother, rflags, nmin, ndays);
if (cbio)
send_ocsp_response(cbio, resp);
}
else if (host)
{
cbio = BIO_new_connect(host);
if (!cbio)
......@@ -545,6 +717,8 @@ int MAIN(int argc, char **argv)
goto end;
}
done_resp:
if (respout)
{
derbio = BIO_new_file(respout, "wb");
......@@ -569,6 +743,10 @@ int MAIN(int argc, char **argv)
if (resp_text) OCSP_RESPONSE_print(out, resp, 0);
/* If running as responder don't verify our own response */
if (cbio)
goto end;
store = setup_verify(bio_err, CAfile, CApath);
if(!store) goto end;
if (verify_certfile)
......@@ -622,8 +800,12 @@ end:
X509_free(signer);
X509_STORE_free(store);
EVP_PKEY_free(key);
EVP_PKEY_free(rkey);
X509_free(issuer);
X509_free(cert);
X509_free(rsigner);
X509_free(rca_cert);
TXT_DB_free(rdb);
BIO_free_all(cbio);
BIO_free(out);
OCSP_REQUEST_free(req);
......@@ -763,3 +945,205 @@ static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req,
return 1;
}
static int make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, TXT_DB *db,
X509 *ca, X509 *rcert, EVP_PKEY *rkey,
STACK_OF(X509) *rother, unsigned long flags,
int nmin, int ndays)
{
ASN1_TIME *thisupd = NULL, *nextupd = NULL;
OCSP_CERTID *cid, *ca_id = NULL;
OCSP_BASICRESP *bs = NULL;
int i, id_count, ret = 1;
id_count = OCSP_request_onereq_count(req);
if (id_count <= 0)
{
*resp = OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL);
goto end;
}
ca_id = OCSP_cert_to_id(EVP_sha1(), NULL, ca);
bs = OCSP_BASICRESP_new();
thisupd = X509_gmtime_adj(NULL, 0);
if (ndays != -1)
nextupd = X509_gmtime_adj(NULL, nmin * 60 + ndays * 3600 * 24 );
/* Examine each certificate id in the request */
for (i = 0; i < id_count; i++)
{
OCSP_ONEREQ *one;
ASN1_INTEGER *serial;
char **inf;
one = OCSP_request_onereq_get0(req, i);
cid = OCSP_onereq_get0_id(one);
/* Is this request about our CA? */
if (OCSP_id_issuer_cmp(ca_id, cid))
{
OCSP_basic_add1_status(bs, cid,
V_OCSP_CERTSTATUS_UNKNOWN,
0, NULL,
thisupd, nextupd);
continue;
}
OCSP_id_get0_info(NULL, NULL, NULL, &serial, cid);
inf = lookup_serial(db, serial);
if (!inf)
OCSP_basic_add1_status(bs, cid,
V_OCSP_CERTSTATUS_UNKNOWN,
0, NULL,
thisupd, nextupd);
else if (inf[DB_type][0] == DB_TYPE_VAL)
OCSP_basic_add1_status(bs, cid,
V_OCSP_CERTSTATUS_GOOD,
0, NULL,
thisupd, nextupd);
else if (inf[DB_type][0] == DB_TYPE_REV)
{
ASN1_OBJECT *inst = NULL;
ASN1_TIME *revtm = NULL;
ASN1_GENERALIZEDTIME *invtm = NULL;
OCSP_SINGLERESP *single;
int reason = -1;
unpack_revinfo(&revtm, &reason, &inst, &invtm, inf[DB_rev_date]);
single = OCSP_basic_add1_status(bs, cid,
V_OCSP_CERTSTATUS_REVOKED,
reason, revtm,
thisupd, nextupd);
if (invtm)
OCSP_SINGLERESP_add1_ext_i2d(single, NID_invalidity_date, invtm, 0, 0);
else if (inst)
OCSP_SINGLERESP_add1_ext_i2d(single, NID_hold_instruction_code, inst, 0, 0);
ASN1_OBJECT_free(inst);
ASN1_TIME_free(revtm);
ASN1_GENERALIZEDTIME_free(invtm);
}
}
OCSP_copy_nonce(bs, req);
OCSP_basic_sign(bs, rcert, rkey, EVP_sha1(), rother, flags);
*resp = OCSP_response_create(OCSP_RESPONSE_STATUS_SUCCESSFUL, bs);
end:
ASN1_TIME_free(thisupd);
ASN1_TIME_free(nextupd);
OCSP_CERTID_free(ca_id);
OCSP_BASICRESP_free(bs);
return ret;
}
static char **lookup_serial(TXT_DB *db, ASN1_INTEGER *ser)
{
int i;
BIGNUM *bn = NULL;
char *itmp, *row[DB_NUMBER],**rrow;
for (i = 0; i < DB_NUMBER; i++) row[i] = NULL;
bn = ASN1_INTEGER_to_BN(ser,NULL);
itmp = BN_bn2hex(bn);
row[DB_serial] = itmp;
BN_free(bn);
rrow=TXT_DB_get_by_index(db,DB_serial,row);
OPENSSL_free(itmp);
return rrow;
}
/* Quick and dirty OCSP server: read in and parse input request */
static OCSP_REQUEST *do_responder(BIO **pcbio, char *port)
{
int have_post = 0, len;
OCSP_REQUEST *req = NULL;
char inbuf[1024];
BIO *acbio = NULL, *bufbio = NULL, *cbio = NULL;
bufbio = BIO_new(BIO_f_buffer());
if (!bufbio)
goto err;
acbio = BIO_new_accept(port);
if (!acbio)
goto err;
BIO_set_accept_bios(acbio, bufbio);
bufbio = NULL;
if (BIO_do_accept(acbio) <= 0)
{
BIO_printf(bio_err, "Error setting up accept BIO\n");
ERR_print_errors(bio_err);
goto err;
}
BIO_printf(bio_err, "Waiting for OCSP client connection...\n");
if (BIO_do_accept(acbio) <= 0)
{
BIO_printf(bio_err, "Error accepting connection\n");
ERR_print_errors(bio_err);
goto err;
}
BIO_printf(bio_err, "Connection Established\n");
cbio = BIO_pop(acbio);
BIO_free_all(acbio);
acbio = NULL;
for(;;)
{
len = BIO_gets(cbio, inbuf, 1024);
if (len <= 0) goto err;
/* Look for "POST" signalling start of query */
if (!have_post)
{
if(strncmp(inbuf, "POST", 4))
{
BIO_printf(bio_err, "Invalid request\n");
goto err;
}
have_post = 1;
}
/* Look for end of headers */
if ((inbuf[0] == '\r') || (inbuf[0] == '\n'))
break;
}
/* Try to read OCSP request */
req = d2i_OCSP_REQUEST_bio(cbio, NULL);
*pcbio = cbio;
if (!req)
{
BIO_printf(bio_err, "Error parsing OCSP request\n");
ERR_print_errors(bio_err);
}
return req;
err:
BIO_free_all(acbio);
BIO_free_all(cbio);
BIO_free(bufbio);
OCSP_REQUEST_free(req);
return NULL;
}
static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp)
{
char http_resp[] =
"HTTP/1.0 200 OK\r\nContent-type: application/ocsp-response\r\n"
"Content-Length: %d\r\n\r\n";
if (!cbio)
return 0;
BIO_printf(cbio, http_resp, i2d_OCSP_RESPONSE(resp, NULL));
i2d_OCSP_RESPONSE_bio(cbio, resp);
BIO_flush(cbio);
return 1;
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册