Additional functionality in ocsp utility: print summary
of status info. Check nonce values. Option to disable verify. Update usage message. Rename status to string functions and make them global.
This commit is contained in:
parent
90f63e8f83
commit
73758d435b
6 changed files with 165 additions and 25 deletions
8
CHANGES
8
CHANGES
|
@ -3,6 +3,14 @@
|
|||
|
||||
Changes between 0.9.6 and 0.9.7 [xx XXX 2000]
|
||||
|
||||
*) Add summary printout to ocsp utility. The various functions which
|
||||
convert status values to strings have been renamed to:
|
||||
OCSP_response_status_str(), OCSP_cert_status_str() and
|
||||
OCSP_crl_reason_str() and are no longer static. New options
|
||||
to verify nonce values and to disable verification. OCSP response
|
||||
printout format cleaned up.
|
||||
[Steve Henson]
|
||||
|
||||
*) Add additional OCSP certificate checks. These are those specified
|
||||
in RFC2560. This consists of two separate checks: the CA of the
|
||||
certificate being checked must either be the OCSP signer certificate
|
||||
|
|
139
apps/ocsp.c
139
apps/ocsp.c
|
@ -63,8 +63,12 @@
|
|||
#include <openssl/err.h>
|
||||
#include "apps.h"
|
||||
|
||||
static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, X509 *issuer);
|
||||
static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, X509 *issuer);
|
||||
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,
|
||||
STACK_OF(OCSP_CERTID) *ids);
|
||||
static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req,
|
||||
STACK *names, STACK_OF(OCSP_CERTID) *ids);
|
||||
|
||||
#undef PROG
|
||||
#define PROG ocsp_main
|
||||
|
@ -79,7 +83,7 @@ int MAIN(int argc, char **argv)
|
|||
char *reqout = NULL, *respout = NULL;
|
||||
char *signfile = NULL, *keyfile = NULL;
|
||||
char *outfile = NULL;
|
||||
int add_nonce = 1;
|
||||
int add_nonce = 1, noverify = 0;
|
||||
OCSP_REQUEST *req = NULL;
|
||||
OCSP_RESPONSE *resp = NULL;
|
||||
OCSP_BASICRESP *bs = NULL;
|
||||
|
@ -94,9 +98,13 @@ int MAIN(int argc, char **argv)
|
|||
int ret = 1;
|
||||
int badarg = 0;
|
||||
int i;
|
||||
STACK *reqnames = NULL;
|
||||
STACK_OF(OCSP_CERTID) *ids = NULL;
|
||||
if (bio_err == NULL) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
|
||||
ERR_load_crypto_strings();
|
||||
args = argv + 1;
|
||||
reqnames = sk_new_null();
|
||||
ids = sk_OCSP_CERTID_new_null();
|
||||
while (!badarg && *args && *args[0] == '-')
|
||||
{
|
||||
if (!strcmp(*args, "-out"))
|
||||
|
@ -117,6 +125,8 @@ int MAIN(int argc, char **argv)
|
|||
}
|
||||
else badarg = 1;
|
||||
}
|
||||
else if (!strcmp(*args, "-noverify"))
|
||||
noverify = 1;
|
||||
else if (!strcmp(*args, "-nonce"))
|
||||
add_nonce = 2;
|
||||
else if (!strcmp(*args, "-no_nonce"))
|
||||
|
@ -230,7 +240,9 @@ int MAIN(int argc, char **argv)
|
|||
X509_free(cert);
|
||||
cert = load_cert(bio_err, *args, FORMAT_PEM);
|
||||
if(!cert) goto end;
|
||||
if(!add_ocsp_cert(&req, cert, issuer))
|
||||
if(!add_ocsp_cert(&req, cert, issuer, ids))
|
||||
goto end;
|
||||
if(!sk_push(reqnames, *args))
|
||||
goto end;
|
||||
}
|
||||
else badarg = 1;
|
||||
|
@ -240,7 +252,9 @@ int MAIN(int argc, char **argv)
|
|||
if (args[1])
|
||||
{
|
||||
args++;
|
||||
if(!add_ocsp_serial(&req, *args, issuer))
|
||||
if(!add_ocsp_serial(&req, *args, issuer, ids))
|
||||
goto end;
|
||||
if(!sk_push(reqnames, *args))
|
||||
goto end;
|
||||
}
|
||||
else badarg = 1;
|
||||
|
@ -274,6 +288,9 @@ int MAIN(int argc, char **argv)
|
|||
BIO_printf (bio_err, "-no_nonce don't add OCSP nonce to request\n");
|
||||
BIO_printf (bio_err, "-host host:n send OCSP request to host on port n\n");
|
||||
BIO_printf (bio_err, "-path path to use in OCSP request\n");
|
||||
BIO_printf (bio_err, "-CApath dir trusted certificates directory\n");
|
||||
BIO_printf (bio_err, "-CAfile file trusted certificates file\n");
|
||||
BIO_printf (bio_err, "-noverify don't verify response\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
@ -311,7 +328,7 @@ int MAIN(int argc, char **argv)
|
|||
goto end;
|
||||
}
|
||||
|
||||
if (req) OCSP_request_add1_nonce(req, NULL, -1);
|
||||
if (req && add_nonce) OCSP_request_add1_nonce(req, NULL, -1);
|
||||
|
||||
if (signfile)
|
||||
{
|
||||
|
@ -406,6 +423,16 @@ int MAIN(int argc, char **argv)
|
|||
BIO_free(derbio);
|
||||
}
|
||||
|
||||
i = OCSP_response_status(resp);
|
||||
|
||||
if (i != OCSP_RESPONSE_STATUS_SUCCESSFUL)
|
||||
{
|
||||
BIO_printf(out, "Responder Error: %s (%ld)\n",
|
||||
OCSP_response_status_str(i), i);
|
||||
ret = 0;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (resp_text) OCSP_RESPONSE_print(out, resp, 0);
|
||||
|
||||
store = setup_verify(bio_err, CAfile, CApath);
|
||||
|
@ -413,15 +440,34 @@ int MAIN(int argc, char **argv)
|
|||
|
||||
bs = OCSP_response_get1_basic(resp);
|
||||
|
||||
i = OCSP_basic_verify(bs, NULL, store, 0);
|
||||
|
||||
if(i <= 0)
|
||||
if (!bs)
|
||||
{
|
||||
BIO_printf(bio_err, "Response verify error (%d)\n", i);
|
||||
ERR_print_errors(bio_err);
|
||||
BIO_printf(bio_err, "Error parsing response\n");
|
||||
goto end;
|
||||
}
|
||||
else
|
||||
BIO_printf(bio_err, "Response verify OK\n");
|
||||
|
||||
if (!noverify)
|
||||
{
|
||||
if (req && (OCSP_check_nonce(req, bs) <= 0))
|
||||
{
|
||||
BIO_printf(bio_err, "Nonce Verify error\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
i = OCSP_basic_verify(bs, NULL, store, 0);
|
||||
|
||||
if(i <= 0)
|
||||
{
|
||||
BIO_printf(bio_err, "Response Verify Failure\n", i);
|
||||
ERR_print_errors(bio_err);
|
||||
}
|
||||
else
|
||||
BIO_printf(bio_err, "Response verify OK\n");
|
||||
|
||||
}
|
||||
|
||||
if (!print_ocsp_summary(out, bs, req, reqnames, ids))
|
||||
goto end;
|
||||
|
||||
ret = 0;
|
||||
|
||||
|
@ -437,11 +483,14 @@ end:
|
|||
OCSP_REQUEST_free(req);
|
||||
OCSP_RESPONSE_free(resp);
|
||||
OCSP_BASICRESP_free(bs);
|
||||
sk_free(reqnames);
|
||||
sk_OCSP_CERTID_free(ids);
|
||||
|
||||
EXIT(ret);
|
||||
}
|
||||
|
||||
static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, X509 *issuer)
|
||||
static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, X509 *issuer,
|
||||
STACK_OF(OCSP_CERTID) *ids)
|
||||
{
|
||||
OCSP_CERTID *id;
|
||||
if(!issuer)
|
||||
|
@ -452,7 +501,7 @@ static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, X509 *issuer)
|
|||
if(!*req) *req = OCSP_REQUEST_new();
|
||||
if(!*req) goto err;
|
||||
id = OCSP_cert_to_id(NULL, cert, issuer);
|
||||
if(!id) goto err;
|
||||
if(!id || !sk_OCSP_CERTID_push(ids, id)) goto err;
|
||||
if(!OCSP_request_add0_id(*req, id)) goto err;
|
||||
return 1;
|
||||
|
||||
|
@ -461,7 +510,8 @@ static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, X509 *issuer)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, X509 *issuer)
|
||||
static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, X509 *issuer,
|
||||
STACK_OF(OCSP_CERTID) *ids)
|
||||
{
|
||||
OCSP_CERTID *id;
|
||||
X509_NAME *iname;
|
||||
|
@ -484,7 +534,7 @@ static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, X509 *issuer)
|
|||
}
|
||||
id = OCSP_cert_id_new(EVP_sha1(), iname, ikey, sno);
|
||||
ASN1_INTEGER_free(sno);
|
||||
if(!id) goto err;
|
||||
if(!id || !sk_OCSP_CERTID_push(ids, id)) goto err;
|
||||
if(!OCSP_request_add0_id(*req, id)) goto err;
|
||||
return 1;
|
||||
|
||||
|
@ -492,3 +542,58 @@ static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, X509 *issuer)
|
|||
BIO_printf(bio_err, "Error Creating OCSP request\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req,
|
||||
STACK *names, STACK_OF(OCSP_CERTID) *ids)
|
||||
{
|
||||
OCSP_CERTID *id;
|
||||
char *name;
|
||||
int i;
|
||||
|
||||
int status, reason;
|
||||
|
||||
ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
|
||||
|
||||
if (!bs || !req || !sk_num(names) || !sk_OCSP_CERTID_num(ids))
|
||||
return 1;
|
||||
|
||||
for (i = 0; i < sk_OCSP_CERTID_num(ids); i++)
|
||||
{
|
||||
id = sk_OCSP_CERTID_value(ids, i);
|
||||
name = sk_value(names, i);
|
||||
BIO_printf(out, "%s: ", name);
|
||||
|
||||
if(!OCSP_resp_find_status(bs, id, &status, &reason,
|
||||
&rev, &thisupd, &nextupd))
|
||||
{
|
||||
BIO_puts(out, "ERROR: No Status found.\n");
|
||||
continue;
|
||||
}
|
||||
BIO_printf(out, "%s\n", OCSP_cert_status_str(status));
|
||||
|
||||
BIO_puts(out, "\tThis Update: ");
|
||||
ASN1_GENERALIZEDTIME_print(out, thisupd);
|
||||
BIO_puts(out, "\n");
|
||||
|
||||
if(nextupd)
|
||||
{
|
||||
BIO_puts(out, "\tNext Update: ");
|
||||
ASN1_GENERALIZEDTIME_print(out, thisupd);
|
||||
BIO_puts(out, "\n");
|
||||
}
|
||||
|
||||
if (status != V_OCSP_CERTSTATUS_REVOKED)
|
||||
continue;
|
||||
|
||||
if (reason > 0)
|
||||
BIO_printf(out, "\tReason: %s\n",
|
||||
OCSP_crl_reason_str(reason));
|
||||
|
||||
BIO_puts(out, "\tRevocation Time: ");
|
||||
ASN1_GENERALIZEDTIME_print(out, rev);
|
||||
BIO_puts(out, "\n");
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -100,6 +100,8 @@ typedef struct ocsp_cert_id_st
|
|||
ASN1_INTEGER *serialNumber;
|
||||
} OCSP_CERTID;
|
||||
|
||||
DECLARE_STACK_OF(OCSP_CERTID)
|
||||
|
||||
/* Request ::= SEQUENCE {
|
||||
* reqCert CertID,
|
||||
* singleRequestExtensions [0] EXPLICIT Extensions OPTIONAL }
|
||||
|
@ -538,6 +540,10 @@ DECLARE_ASN1_FUNCTIONS(OCSP_REQINFO)
|
|||
DECLARE_ASN1_FUNCTIONS(OCSP_CRLID)
|
||||
DECLARE_ASN1_FUNCTIONS(OCSP_SERVICELOC)
|
||||
|
||||
char *OCSP_response_status_str(long s);
|
||||
char *OCSP_cert_status_str(long s);
|
||||
char *OCSP_crl_reason_str(long s);
|
||||
|
||||
int OCSP_REQUEST_print(BIO *bp, OCSP_REQUEST* a, unsigned long flags);
|
||||
int OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE* o, unsigned long flags);
|
||||
|
||||
|
|
|
@ -97,7 +97,7 @@ static char *table2string(long s, OCSP_TBLSTR *ts, int len)
|
|||
return "(UNKNOWN)";
|
||||
}
|
||||
|
||||
static char* ocspResponseStatus2string(long s)
|
||||
char *OCSP_response_status_str(long s)
|
||||
{
|
||||
static OCSP_TBLSTR rstat_tbl[] = {
|
||||
{ OCSP_RESPONSE_STATUS_SUCCESSFUL, "successful" },
|
||||
|
@ -109,7 +109,7 @@ static char* ocspResponseStatus2string(long s)
|
|||
return table2string(s, rstat_tbl, 6);
|
||||
}
|
||||
|
||||
static char* ocspCertStatus2string(long s)
|
||||
char *OCSP_cert_status_str(long s)
|
||||
{
|
||||
static OCSP_TBLSTR cstat_tbl[] = {
|
||||
{ V_OCSP_CERTSTATUS_GOOD, "good" },
|
||||
|
@ -118,7 +118,7 @@ static char* ocspCertStatus2string(long s)
|
|||
return table2string(s, cstat_tbl, 3);
|
||||
}
|
||||
|
||||
static char * cRLReason2string(long s)
|
||||
char *OCSP_crl_reason_str(long s)
|
||||
{
|
||||
OCSP_TBLSTR reason_tbl[] = {
|
||||
{ OCSP_REVOKED_STATUS_UNSPECIFIED, "unspecified" },
|
||||
|
@ -195,7 +195,7 @@ int OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE* o, unsigned long flags)
|
|||
if (BIO_puts(bp,"OCSP Response Data:\n") <= 0) goto err;
|
||||
l=ASN1_ENUMERATED_get(o->responseStatus);
|
||||
if (BIO_printf(bp," OCSP Response Status: %s (0x%x)\n",
|
||||
ocspResponseStatus2string(l), l) <= 0) goto err;
|
||||
OCSP_response_status_str(l), l) <= 0) goto err;
|
||||
if (rb == NULL) return 1;
|
||||
if (BIO_puts(bp," Response Type: ") <= 0)
|
||||
goto err;
|
||||
|
@ -237,8 +237,8 @@ int OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE* o, unsigned long flags)
|
|||
cid = single->certId;
|
||||
if(ocsp_certid_print(bp, cid, 4) <= 0) goto err;
|
||||
cst = single->certStatus;
|
||||
if (BIO_printf(bp,"\n Cert Status: %s",
|
||||
ocspCertStatus2string(cst->type)) <= 0)
|
||||
if (BIO_printf(bp," Cert Status: %s",
|
||||
OCSP_cert_status_str(cst->type)) <= 0)
|
||||
goto err;
|
||||
if (cst->type == V_OCSP_CERTSTATUS_REVOKED)
|
||||
{
|
||||
|
@ -253,7 +253,7 @@ int OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE* o, unsigned long flags)
|
|||
l=ASN1_ENUMERATED_get(rev->revocationReason);
|
||||
if (BIO_printf(bp,
|
||||
"\n Revocation Reason: %s (0x%x)",
|
||||
cRLReason2string(l), l) <= 0)
|
||||
OCSP_crl_reason_str(l), l) <= 0)
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
@ -271,6 +271,7 @@ int OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE* o, unsigned long flags)
|
|||
"Response Single Extensions",
|
||||
single->singleExtensions, flags, 8))
|
||||
goto err;
|
||||
if (!BIO_write(bp,"\n",1)) goto err;
|
||||
}
|
||||
if (!X509V3_extensions_print(bp, "Response Extensions",
|
||||
rd->responseExtensions, flags, 4))
|
||||
|
|
|
@ -144,7 +144,7 @@ int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
|
|||
|
||||
end:
|
||||
if(chain) sk_X509_pop_free(chain, X509_free);
|
||||
return 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -504,6 +504,26 @@ STACK_OF(type) \
|
|||
#define sk_NAME_FUNCS_pop(st) SKM_sk_pop(NAME_FUNCS, (st))
|
||||
#define sk_NAME_FUNCS_sort(st) SKM_sk_sort(NAME_FUNCS, (st))
|
||||
|
||||
#define sk_OCSP_CERTID_new(st) SKM_sk_new(OCSP_CERTID, (st))
|
||||
#define sk_OCSP_CERTID_new_null() SKM_sk_new_null(OCSP_CERTID)
|
||||
#define sk_OCSP_CERTID_free(st) SKM_sk_free(OCSP_CERTID, (st))
|
||||
#define sk_OCSP_CERTID_num(st) SKM_sk_num(OCSP_CERTID, (st))
|
||||
#define sk_OCSP_CERTID_value(st, i) SKM_sk_value(OCSP_CERTID, (st), (i))
|
||||
#define sk_OCSP_CERTID_set(st, i, val) SKM_sk_set(OCSP_CERTID, (st), (i), (val))
|
||||
#define sk_OCSP_CERTID_zero(st) SKM_sk_zero(OCSP_CERTID, (st))
|
||||
#define sk_OCSP_CERTID_push(st, val) SKM_sk_push(OCSP_CERTID, (st), (val))
|
||||
#define sk_OCSP_CERTID_unshift(st, val) SKM_sk_unshift(OCSP_CERTID, (st), (val))
|
||||
#define sk_OCSP_CERTID_find(st, val) SKM_sk_find(OCSP_CERTID, (st), (val))
|
||||
#define sk_OCSP_CERTID_delete(st, i) SKM_sk_delete(OCSP_CERTID, (st), (i))
|
||||
#define sk_OCSP_CERTID_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_CERTID, (st), (ptr))
|
||||
#define sk_OCSP_CERTID_insert(st, val, i) SKM_sk_insert(OCSP_CERTID, (st), (val), (i))
|
||||
#define sk_OCSP_CERTID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_CERTID, (st), (cmp))
|
||||
#define sk_OCSP_CERTID_dup(st) SKM_sk_dup(OCSP_CERTID, st)
|
||||
#define sk_OCSP_CERTID_pop_free(st, free_func) SKM_sk_pop_free(OCSP_CERTID, (st), (free_func))
|
||||
#define sk_OCSP_CERTID_shift(st) SKM_sk_shift(OCSP_CERTID, (st))
|
||||
#define sk_OCSP_CERTID_pop(st) SKM_sk_pop(OCSP_CERTID, (st))
|
||||
#define sk_OCSP_CERTID_sort(st) SKM_sk_sort(OCSP_CERTID, (st))
|
||||
|
||||
#define sk_OCSP_ONEREQ_new(st) SKM_sk_new(OCSP_ONEREQ, (st))
|
||||
#define sk_OCSP_ONEREQ_new_null() SKM_sk_new_null(OCSP_ONEREQ)
|
||||
#define sk_OCSP_ONEREQ_free(st) SKM_sk_free(OCSP_ONEREQ, (st))
|
||||
|
|
Loading…
Reference in a new issue