version 1.18, 2020/09/09 13:08:38 |
version 1.19, 2020/09/09 13:57:36 |
|
|
/* Maximum leeway in validity period: default 5 minutes */ |
/* Maximum leeway in validity period: default 5 minutes */ |
#define MAX_VALIDITY_PERIOD (5 * 60) |
#define MAX_VALIDITY_PERIOD (5 * 60) |
|
|
static int |
static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, |
add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, const EVP_MD *cert_id_md, X509 *issuer, |
const EVP_MD *cert_id_md, X509 *issuer, STACK_OF(OCSP_CERTID) *ids); |
STACK_OF(OCSP_CERTID) *ids); |
static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, |
static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, const EVP_MD *cert_id_md, X509 *issuer, |
const EVP_MD *cert_id_md, X509 *issuer, STACK_OF(OCSP_CERTID) *ids); |
STACK_OF(OCSP_CERTID) *ids); |
|
static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req, |
static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req, |
STACK_OF(OPENSSL_STRING) *names, |
STACK_OF(OPENSSL_STRING) *names, STACK_OF(OCSP_CERTID) *ids, long nsec, |
STACK_OF(OCSP_CERTID) *ids, long nsec, |
|
long maxage); |
long maxage); |
|
|
static int make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, CA_DB *db, |
static int make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, |
X509 *ca, X509 *rcert, EVP_PKEY *rkey, |
CA_DB *db, X509 *ca, X509 *rcert, EVP_PKEY *rkey, STACK_OF(X509) *rother, |
STACK_OF(X509) *rother, unsigned long flags, |
unsigned long flags, int nmin, int ndays); |
int nmin, int ndays); |
|
|
|
static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser); |
static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser); |
static BIO *init_responder(char *port); |
static BIO *init_responder(char *port); |
static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, char *port); |
static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, |
|
char *port); |
static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp); |
static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp); |
static OCSP_RESPONSE *query_responder(BIO *err, BIO *cbio, char *path, |
static OCSP_RESPONSE *query_responder(BIO *err, BIO *cbio, char *path, |
STACK_OF(CONF_VALUE) *headers, |
STACK_OF(CONF_VALUE) *headers, OCSP_REQUEST *req, int req_timeout); |
OCSP_REQUEST *req, int req_timeout); |
|
|
|
static struct { |
static struct { |
int accept_count; |
int accept_count; |
|
|
} |
} |
|
|
/* Have we anything to do? */ |
/* Have we anything to do? */ |
if (!ocsp_config.req && !ocsp_config.reqin && !ocsp_config.respin && !(ocsp_config.port && ocsp_config.ridx_filename)) |
if (!ocsp_config.req && !ocsp_config.reqin && !ocsp_config.respin && |
|
!(ocsp_config.port && ocsp_config.ridx_filename)) |
badarg = 1; |
badarg = 1; |
|
|
if (badarg) { |
if (badarg) { |
|
|
if (!ocsp_config.req && ocsp_config.reqin) { |
if (!ocsp_config.req && ocsp_config.reqin) { |
derbio = BIO_new_file(ocsp_config.reqin, "rb"); |
derbio = BIO_new_file(ocsp_config.reqin, "rb"); |
if (!derbio) { |
if (!derbio) { |
BIO_printf(bio_err, "Error Opening OCSP request file\n"); |
BIO_printf(bio_err, |
|
"Error Opening OCSP request file\n"); |
goto end; |
goto end; |
} |
} |
ocsp_config.req = d2i_OCSP_REQUEST_bio(derbio, NULL); |
ocsp_config.req = d2i_OCSP_REQUEST_bio(derbio, NULL); |
|
|
rsigner = load_cert(bio_err, ocsp_config.rsignfile, FORMAT_PEM, |
rsigner = load_cert(bio_err, ocsp_config.rsignfile, FORMAT_PEM, |
NULL, "responder certificate"); |
NULL, "responder certificate"); |
if (!rsigner) { |
if (!rsigner) { |
BIO_printf(bio_err, "Error loading responder certificate\n"); |
BIO_printf(bio_err, |
|
"Error loading responder certificate\n"); |
goto end; |
goto end; |
} |
} |
rca_cert = load_cert(bio_err, ocsp_config.rca_filename, FORMAT_PEM, |
rca_cert = load_cert(bio_err, ocsp_config.rca_filename, |
NULL, "CA certificate"); |
FORMAT_PEM, NULL, "CA certificate"); |
if (ocsp_config.rcertfile) { |
if (ocsp_config.rcertfile) { |
rother = load_certs(bio_err, ocsp_config.rcertfile, FORMAT_PEM, |
rother = load_certs(bio_err, ocsp_config.rcertfile, |
NULL, "responder other certificates"); |
FORMAT_PEM, NULL, "responder other certificates"); |
if (!rother) |
if (!rother) |
goto end; |
goto end; |
} |
} |
rkey = load_key(bio_err, ocsp_config.rkeyfile, FORMAT_PEM, 0, NULL, |
rkey = load_key(bio_err, ocsp_config.rkeyfile, FORMAT_PEM, 0, |
"responder private key"); |
NULL, "responder private key"); |
if (!rkey) |
if (!rkey) |
goto end; |
goto end; |
} |
} |
if (acbio) |
if (acbio) |
BIO_printf(bio_err, "Waiting for OCSP client connections...\n"); |
BIO_printf(bio_err, "Waiting for OCSP client connections...\n"); |
|
|
redo_accept: |
redo_accept: |
|
|
if (acbio) { |
if (acbio) { |
if (!do_responder(&ocsp_config.req, &cbio, acbio, ocsp_config.port)) |
if (!do_responder(&ocsp_config.req, &cbio, acbio, |
|
ocsp_config.port)) |
goto end; |
goto end; |
if (!ocsp_config.req) { |
if (!ocsp_config.req) { |
resp = OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL); |
resp = OCSP_response_create( |
|
OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL); |
send_ocsp_response(cbio, resp); |
send_ocsp_response(cbio, resp); |
goto done_resp; |
goto done_resp; |
} |
} |
} |
} |
if (!ocsp_config.req && (ocsp_config.signfile || ocsp_config.reqout || ocsp_config.host || ocsp_config.add_nonce || ocsp_config.ridx_filename)) { |
if (!ocsp_config.req && |
BIO_printf(bio_err, "Need an OCSP request for this operation!\n"); |
(ocsp_config.signfile || ocsp_config.reqout || ocsp_config.host || |
|
ocsp_config.add_nonce || ocsp_config.ridx_filename)) { |
|
BIO_printf(bio_err, |
|
"Need an OCSP request for this operation!\n"); |
goto end; |
goto end; |
} |
} |
if (ocsp_config.req && ocsp_config.add_nonce) |
if (ocsp_config.req && ocsp_config.add_nonce) |
|
|
signer = load_cert(bio_err, ocsp_config.signfile, FORMAT_PEM, |
signer = load_cert(bio_err, ocsp_config.signfile, FORMAT_PEM, |
NULL, "signer certificate"); |
NULL, "signer certificate"); |
if (!signer) { |
if (!signer) { |
BIO_printf(bio_err, "Error loading signer certificate\n"); |
BIO_printf(bio_err, |
|
"Error loading signer certificate\n"); |
goto end; |
goto end; |
} |
} |
if (ocsp_config.sign_certfile) { |
if (ocsp_config.sign_certfile) { |
sign_other = load_certs(bio_err, ocsp_config.sign_certfile, FORMAT_PEM, |
sign_other = load_certs(bio_err, |
NULL, "signer certificates"); |
ocsp_config.sign_certfile, FORMAT_PEM, NULL, |
|
"signer certificates"); |
if (!sign_other) |
if (!sign_other) |
goto end; |
goto end; |
} |
} |
key = load_key(bio_err, ocsp_config.keyfile, FORMAT_PEM, 0, NULL, |
key = load_key(bio_err, ocsp_config.keyfile, FORMAT_PEM, 0, |
"signer private key"); |
NULL, "signer private key"); |
if (!key) |
if (!key) |
goto end; |
goto end; |
|
|
if (!OCSP_request_sign(ocsp_config.req, signer, key, NULL, sign_other, ocsp_config.sign_flags)) { |
if (!OCSP_request_sign(ocsp_config.req, signer, key, NULL, |
|
sign_other, ocsp_config.sign_flags)) { |
BIO_printf(bio_err, "Error signing OCSP request\n"); |
BIO_printf(bio_err, "Error signing OCSP request\n"); |
goto end; |
goto end; |
} |
} |
|
|
if (ocsp_config.reqout) { |
if (ocsp_config.reqout) { |
derbio = BIO_new_file(ocsp_config.reqout, "wb"); |
derbio = BIO_new_file(ocsp_config.reqout, "wb"); |
if (!derbio) { |
if (!derbio) { |
BIO_printf(bio_err, "Error opening file %s\n", ocsp_config.reqout); |
BIO_printf(bio_err, "Error opening file %s\n", |
|
ocsp_config.reqout); |
goto end; |
goto end; |
} |
} |
i2d_OCSP_REQUEST_bio(derbio, ocsp_config.req); |
i2d_OCSP_REQUEST_bio(derbio, ocsp_config.req); |
BIO_free(derbio); |
BIO_free(derbio); |
} |
} |
if (ocsp_config.ridx_filename && (!rkey || !rsigner || !rca_cert)) { |
if (ocsp_config.ridx_filename && (!rkey || !rsigner || !rca_cert)) { |
BIO_printf(bio_err, "Need a responder certificate, key and CA for this operation!\n"); |
BIO_printf(bio_err, |
|
"Need a responder certificate, key and CA for this operation!\n"); |
goto end; |
goto end; |
} |
} |
if (ocsp_config.ridx_filename && !rdb) { |
if (ocsp_config.ridx_filename && !rdb) { |
|
|
goto end; |
goto end; |
} |
} |
if (rdb) { |
if (rdb) { |
i = make_ocsp_response(&resp, ocsp_config.req, rdb, rca_cert, rsigner, rkey, rother, ocsp_config.rflags, ocsp_config.nmin, ocsp_config.ndays); |
i = make_ocsp_response(&resp, ocsp_config.req, rdb, rca_cert, |
|
rsigner, rkey, rother, ocsp_config.rflags, |
|
ocsp_config.nmin, ocsp_config.ndays); |
if (cbio) |
if (cbio) |
send_ocsp_response(cbio, resp); |
send_ocsp_response(cbio, resp); |
} else if (ocsp_config.host) { |
} else if (ocsp_config.host) { |
resp = process_responder(bio_err, ocsp_config.req, ocsp_config.host, ocsp_config.path ? ocsp_config.path : "/", |
resp = process_responder(bio_err, ocsp_config.req, |
ocsp_config.port, ocsp_config.use_ssl, ocsp_config.headers, ocsp_config.req_timeout); |
ocsp_config.host, |
|
ocsp_config.path ? ocsp_config.path : "/", |
|
ocsp_config.port, ocsp_config.use_ssl, ocsp_config.headers, |
|
ocsp_config.req_timeout); |
if (!resp) |
if (!resp) |
goto end; |
goto end; |
} else if (ocsp_config.respin) { |
} else if (ocsp_config.respin) { |
derbio = BIO_new_file(ocsp_config.respin, "rb"); |
derbio = BIO_new_file(ocsp_config.respin, "rb"); |
if (!derbio) { |
if (!derbio) { |
BIO_printf(bio_err, "Error Opening OCSP response file\n"); |
BIO_printf(bio_err, |
|
"Error Opening OCSP response file\n"); |
goto end; |
goto end; |
} |
} |
resp = d2i_OCSP_RESPONSE_bio(derbio, NULL); |
resp = d2i_OCSP_RESPONSE_bio(derbio, NULL); |
|
|
goto end; |
goto end; |
} |
} |
|
|
done_resp: |
done_resp: |
|
|
if (ocsp_config.respout) { |
if (ocsp_config.respout) { |
derbio = BIO_new_file(ocsp_config.respout, "wb"); |
derbio = BIO_new_file(ocsp_config.respout, "wb"); |
if (!derbio) { |
if (!derbio) { |
BIO_printf(bio_err, "Error opening file %s\n", ocsp_config.respout); |
BIO_printf(bio_err, "Error opening file %s\n", |
|
ocsp_config.respout); |
goto end; |
goto end; |
} |
} |
i2d_OCSP_RESPONSE_bio(derbio, resp); |
i2d_OCSP_RESPONSE_bio(derbio, resp); |
|
|
goto end; |
goto end; |
} |
} |
if (!store) |
if (!store) |
store = setup_verify(bio_err, ocsp_config.CAfile, ocsp_config.CApath); |
store = setup_verify(bio_err, ocsp_config.CAfile, |
|
ocsp_config.CApath); |
if (!store) |
if (!store) |
goto end; |
goto end; |
if (ocsp_config.verify_certfile) { |
if (ocsp_config.verify_certfile) { |
verify_other = load_certs(bio_err, ocsp_config.verify_certfile, FORMAT_PEM, |
verify_other = load_certs(bio_err, ocsp_config.verify_certfile, |
NULL, "validator certificate"); |
FORMAT_PEM, NULL, "validator certificate"); |
if (!verify_other) |
if (!verify_other) |
goto end; |
goto end; |
} |
} |
|
|
goto end; |
goto end; |
} |
} |
if (!ocsp_config.noverify) { |
if (!ocsp_config.noverify) { |
if (ocsp_config.req && ((i = OCSP_check_nonce(ocsp_config.req, bs)) <= 0)) { |
if (ocsp_config.req && |
if (i == -1) |
((i = OCSP_check_nonce(ocsp_config.req, bs)) <= 0)) { |
BIO_printf(bio_err, "WARNING: no nonce in response\n"); |
if (i == -1) { |
else { |
BIO_printf(bio_err, |
|
"WARNING: no nonce in response\n"); |
|
} else { |
BIO_printf(bio_err, "Nonce Verify error\n"); |
BIO_printf(bio_err, "Nonce Verify error\n"); |
goto end; |
goto end; |
} |
} |
} |
} |
i = OCSP_basic_verify(bs, verify_other, store, ocsp_config.verify_flags); |
i = OCSP_basic_verify(bs, verify_other, store, |
|
ocsp_config.verify_flags); |
if (i < 0) |
if (i < 0) |
i = OCSP_basic_verify(bs, NULL, store, 0); |
i = OCSP_basic_verify(bs, NULL, store, 0); |
|
|
if (i <= 0) { |
if (i <= 0) { |
BIO_printf(bio_err, "Response Verify Failure\n"); |
BIO_printf(bio_err, "Response Verify Failure\n"); |
ERR_print_errors(bio_err); |
ERR_print_errors(bio_err); |
} else |
} else { |
BIO_printf(bio_err, "Response verify OK\n"); |
BIO_printf(bio_err, "Response verify OK\n"); |
|
} |
} |
} |
if (!print_ocsp_summary(out, bs, ocsp_config.req, ocsp_config.reqnames, ocsp_config.ids, ocsp_config.nsec, ocsp_config.maxage)) |
if (!print_ocsp_summary(out, bs, ocsp_config.req, ocsp_config.reqnames, |
|
ocsp_config.ids, ocsp_config.nsec, ocsp_config.maxage)) |
goto end; |
goto end; |
|
|
ret = 0; |
ret = 0; |
|
|
} |
} |
|
|
static int |
static int |
add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, const EVP_MD *cert_id_md, X509 *issuer, |
add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, const EVP_MD *cert_id_md, |
STACK_OF(OCSP_CERTID) *ids) |
X509 *issuer, STACK_OF(OCSP_CERTID) *ids) |
{ |
{ |
OCSP_CERTID *id; |
OCSP_CERTID *id; |
|
|
if (!issuer) { |
if (!issuer) { |
BIO_printf(bio_err, "No issuer certificate specified\n"); |
BIO_printf(bio_err, "No issuer certificate specified\n"); |
return 0; |
return 0; |
|
|
} |
} |
|
|
static int |
static int |
add_ocsp_serial(OCSP_REQUEST **req, char *serial, const EVP_MD *cert_id_md, X509 *issuer, |
add_ocsp_serial(OCSP_REQUEST **req, char *serial, const EVP_MD *cert_id_md, |
STACK_OF(OCSP_CERTID) *ids) |
X509 *issuer, STACK_OF(OCSP_CERTID) *ids) |
{ |
{ |
OCSP_CERTID *id; |
OCSP_CERTID *id; |
X509_NAME *iname; |
X509_NAME *iname; |
ASN1_BIT_STRING *ikey; |
ASN1_BIT_STRING *ikey; |
ASN1_INTEGER *sno; |
ASN1_INTEGER *sno; |
|
|
if (!issuer) { |
if (!issuer) { |
BIO_printf(bio_err, "No issuer certificate specified\n"); |
BIO_printf(bio_err, "No issuer certificate specified\n"); |
return 0; |
return 0; |
|
|
ikey = X509_get0_pubkey_bitstr(issuer); |
ikey = X509_get0_pubkey_bitstr(issuer); |
sno = s2i_ASN1_INTEGER(NULL, serial); |
sno = s2i_ASN1_INTEGER(NULL, serial); |
if (!sno) { |
if (!sno) { |
BIO_printf(bio_err, "Error converting serial number %s\n", serial); |
BIO_printf(bio_err, "Error converting serial number %s\n", |
|
serial); |
return 0; |
return 0; |
} |
} |
id = OCSP_cert_id_new(cert_id_md, iname, ikey, sno); |
id = OCSP_cert_id_new(cert_id_md, iname, ikey, sno); |
|
|
|
|
static int |
static int |
print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req, |
print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req, |
STACK_OF(OPENSSL_STRING) *names, |
STACK_OF(OPENSSL_STRING) *names, STACK_OF(OCSP_CERTID) *ids, long nsec, |
STACK_OF(OCSP_CERTID) *ids, long nsec, |
|
long maxage) |
long maxage) |
{ |
{ |
OCSP_CERTID *id; |
OCSP_CERTID *id; |
char *name; |
char *name; |
int i; |
int i; |
|
|
int status, reason; |
int status, reason; |
|
|
ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd; |
ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd; |
|
|
if (!bs || !req || !sk_OPENSSL_STRING_num(names) || !sk_OCSP_CERTID_num(ids)) |
if (!bs || !req || !sk_OPENSSL_STRING_num(names) || |
|
!sk_OCSP_CERTID_num(ids)) |
return 1; |
return 1; |
|
|
for (i = 0; i < sk_OCSP_CERTID_num(ids); i++) { |
for (i = 0; i < sk_OCSP_CERTID_num(ids); i++) { |
|
|
|
|
static int |
static int |
make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, CA_DB *db, |
make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, CA_DB *db, |
X509 *ca, X509 *rcert, EVP_PKEY *rkey, |
X509 *ca, X509 *rcert, EVP_PKEY *rkey, STACK_OF(X509) *rother, |
STACK_OF(X509) *rother, unsigned long flags, |
unsigned long flags, int nmin, int ndays) |
int nmin, int ndays) |
|
{ |
{ |
ASN1_TIME *thisupd = NULL, *nextupd = NULL; |
ASN1_TIME *thisupd = NULL, *nextupd = NULL; |
OCSP_CERTID *cid, *ca_id = NULL; |
OCSP_CERTID *cid, *ca_id = NULL; |
|
|
id_count = OCSP_request_onereq_count(req); |
id_count = OCSP_request_onereq_count(req); |
|
|
if (id_count <= 0) { |
if (id_count <= 0) { |
*resp = OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL); |
*resp = OCSP_response_create( |
|
OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL); |
goto end; |
goto end; |
} |
} |
bs = OCSP_BASICRESP_new(); |
bs = OCSP_BASICRESP_new(); |
|
|
|
|
cert_id_md = EVP_get_digestbyobj(cert_id_md_oid); |
cert_id_md = EVP_get_digestbyobj(cert_id_md_oid); |
if (!cert_id_md) { |
if (!cert_id_md) { |
*resp = OCSP_response_create(OCSP_RESPONSE_STATUS_INTERNALERROR, |
*resp = OCSP_response_create( |
NULL); |
OCSP_RESPONSE_STATUS_INTERNALERROR, NULL); |
goto end; |
goto end; |
} |
} |
OCSP_CERTID_free(ca_id); |
OCSP_CERTID_free(ca_id); |
|
|
/* Is this request about our CA? */ |
/* Is this request about our CA? */ |
if (OCSP_id_issuer_cmp(ca_id, cid)) { |
if (OCSP_id_issuer_cmp(ca_id, cid)) { |
OCSP_basic_add1_status(bs, cid, |
OCSP_basic_add1_status(bs, cid, |
V_OCSP_CERTSTATUS_UNKNOWN, |
V_OCSP_CERTSTATUS_UNKNOWN, 0, NULL, |
0, NULL, |
|
thisupd, nextupd); |
thisupd, nextupd); |
continue; |
continue; |
} |
} |
OCSP_id_get0_info(NULL, NULL, NULL, &serial, cid); |
OCSP_id_get0_info(NULL, NULL, NULL, &serial, cid); |
inf = lookup_serial(db, serial); |
inf = lookup_serial(db, serial); |
if (!inf) |
if (!inf) { |
OCSP_basic_add1_status(bs, cid, |
OCSP_basic_add1_status(bs, cid, |
V_OCSP_CERTSTATUS_UNKNOWN, |
V_OCSP_CERTSTATUS_UNKNOWN, 0, NULL, |
0, NULL, |
|
thisupd, nextupd); |
thisupd, nextupd); |
else if (inf[DB_type][0] == DB_TYPE_VAL) |
} else if (inf[DB_type][0] == DB_TYPE_VAL) { |
OCSP_basic_add1_status(bs, cid, |
OCSP_basic_add1_status(bs, cid, |
V_OCSP_CERTSTATUS_GOOD, |
V_OCSP_CERTSTATUS_GOOD, 0, NULL, |
0, NULL, |
|
thisupd, nextupd); |
thisupd, nextupd); |
else if (inf[DB_type][0] == DB_TYPE_REV) { |
} else if (inf[DB_type][0] == DB_TYPE_REV) { |
ASN1_OBJECT *inst = NULL; |
ASN1_OBJECT *inst = NULL; |
ASN1_TIME *revtm = NULL; |
ASN1_TIME *revtm = NULL; |
ASN1_GENERALIZEDTIME *invtm = NULL; |
ASN1_GENERALIZEDTIME *invtm = NULL; |
OCSP_SINGLERESP *single; |
OCSP_SINGLERESP *single; |
int reason = -1; |
int reason = -1; |
unpack_revinfo(&revtm, &reason, &inst, &invtm, inf[DB_rev_date]); |
|
|
unpack_revinfo(&revtm, &reason, &inst, &invtm, |
|
inf[DB_rev_date]); |
single = OCSP_basic_add1_status(bs, cid, |
single = OCSP_basic_add1_status(bs, cid, |
V_OCSP_CERTSTATUS_REVOKED, |
V_OCSP_CERTSTATUS_REVOKED, |
reason, revtm, |
reason, revtm, |
thisupd, nextupd); |
thisupd, nextupd); |
if (invtm) |
if (invtm) |
OCSP_SINGLERESP_add1_ext_i2d(single, NID_invalidity_date, invtm, 0, 0); |
OCSP_SINGLERESP_add1_ext_i2d(single, |
|
NID_invalidity_date, invtm, 0, 0); |
else if (inst) |
else if (inst) |
OCSP_SINGLERESP_add1_ext_i2d(single, NID_hold_instruction_code, inst, 0, 0); |
OCSP_SINGLERESP_add1_ext_i2d(single, |
|
NID_hold_instruction_code, inst, 0, 0); |
ASN1_OBJECT_free(inst); |
ASN1_OBJECT_free(inst); |
ASN1_TIME_free(revtm); |
ASN1_TIME_free(revtm); |
ASN1_GENERALIZEDTIME_free(invtm); |
ASN1_GENERALIZEDTIME_free(invtm); |
|
|
OCSP_CERTID_free(ca_id); |
OCSP_CERTID_free(ca_id); |
OCSP_BASICRESP_free(bs); |
OCSP_BASICRESP_free(bs); |
return ret; |
return ret; |
|
|
} |
} |
|
|
static char ** |
static char ** |
|
|
int i; |
int i; |
BIGNUM *bn = NULL; |
BIGNUM *bn = NULL; |
char *itmp, *row[DB_NUMBER], **rrow; |
char *itmp, *row[DB_NUMBER], **rrow; |
|
|
for (i = 0; i < DB_NUMBER; i++) |
for (i = 0; i < DB_NUMBER; i++) |
row[i] = NULL; |
row[i] = NULL; |
bn = ASN1_INTEGER_to_BN(ser, NULL); |
bn = ASN1_INTEGER_to_BN(ser, NULL); |
|
|
init_responder(char *port) |
init_responder(char *port) |
{ |
{ |
BIO *acbio = NULL, *bufbio = NULL; |
BIO *acbio = NULL, *bufbio = NULL; |
|
|
bufbio = BIO_new(BIO_f_buffer()); |
bufbio = BIO_new(BIO_f_buffer()); |
if (!bufbio) |
if (!bufbio) |
goto err; |
goto err; |
|
|
*preq = req; |
*preq = req; |
|
|
return 1; |
return 1; |
|
|
} |
} |
|
|
static int |
static int |
|
|
static const char http_resp[] = |
static const char http_resp[] = |
"HTTP/1.0 200 OK\r\nContent-type: application/ocsp-response\r\n" |
"HTTP/1.0 200 OK\r\nContent-type: application/ocsp-response\r\n" |
"Content-Length: %d\r\n\r\n"; |
"Content-Length: %d\r\n\r\n"; |
|
|
if (!cbio) |
if (!cbio) |
return 0; |
return 0; |
BIO_printf(cbio, http_resp, i2d_OCSP_RESPONSE(resp, NULL)); |
BIO_printf(cbio, http_resp, i2d_OCSP_RESPONSE(resp, NULL)); |
|
|
} |
} |
|
|
static OCSP_RESPONSE * |
static OCSP_RESPONSE * |
query_responder(BIO *err, BIO *cbio, char *path, |
query_responder(BIO *err, BIO *cbio, char *path, STACK_OF(CONF_VALUE) *headers, |
STACK_OF(CONF_VALUE) *headers, |
|
OCSP_REQUEST *req, int req_timeout) |
OCSP_REQUEST *req, int req_timeout) |
{ |
{ |
int fd; |
int fd; |
|
|
if (req_timeout == -1) |
if (req_timeout == -1) |
continue; |
continue; |
pfd[0].fd = fd; |
pfd[0].fd = fd; |
if (BIO_should_read(cbio)) |
if (BIO_should_read(cbio)) { |
pfd[0].events = POLLIN; |
pfd[0].events = POLLIN; |
else if (BIO_should_write(cbio)) |
} else if (BIO_should_write(cbio)) { |
pfd[0].events = POLLOUT; |
pfd[0].events = POLLOUT; |
else { |
} else { |
BIO_puts(err, "Unexpected retry condition\n"); |
BIO_puts(err, "Unexpected retry condition\n"); |
goto err; |
goto err; |
} |
} |
|
|
break; |
break; |
} |
} |
} |
} |
|
|
err: |
err: |
OCSP_REQ_CTX_free(ctx); |
OCSP_REQ_CTX_free(ctx); |
|
|
return rsp; |
return rsp; |
} |
} |
|
|
OCSP_RESPONSE * |
OCSP_RESPONSE * |
process_responder(BIO *err, OCSP_REQUEST *req, |
process_responder(BIO *err, OCSP_REQUEST *req, char *host, char *path, |
char *host, char *path, char *port, int use_ssl, |
char *port, int use_ssl, STACK_OF(CONF_VALUE) *headers, int req_timeout) |
STACK_OF(CONF_VALUE) *headers, |
|
int req_timeout) |
|
{ |
{ |
BIO *cbio = NULL; |
BIO *cbio = NULL; |
SSL_CTX *ctx = NULL; |
SSL_CTX *ctx = NULL; |
OCSP_RESPONSE *resp = NULL; |
OCSP_RESPONSE *resp = NULL; |
|
|
cbio = BIO_new_connect(host); |
cbio = BIO_new_connect(host); |
if (!cbio) { |
if (!cbio) { |
BIO_printf(err, "Error creating connect BIO\n"); |
BIO_printf(err, "Error creating connect BIO\n"); |
|
|
resp = query_responder(err, cbio, path, headers, req, req_timeout); |
resp = query_responder(err, cbio, path, headers, req, req_timeout); |
if (!resp) |
if (!resp) |
BIO_printf(bio_err, "Error querying OCSP responder\n"); |
BIO_printf(bio_err, "Error querying OCSP responder\n"); |
|
|
end: |
end: |
BIO_free_all(cbio); |
BIO_free_all(cbio); |
SSL_CTX_free(ctx); |
SSL_CTX_free(ctx); |