From 3bb0f989b53c59c6d4527a0b5077dbb7fabe14b7 Mon Sep 17 00:00:00 2001 From: Todd Short Date: Tue, 31 Mar 2015 17:06:21 -0400 Subject: [PATCH] OCSP Updates: error codes and multiple certificates RT3877: Add X509 OCSP error codes and messages Add additional OCSP error codes for X509 verify usage RT3867: Support Multiple CA certs in ocsp app Add the ability to read multiple CA certs from a single file in the ocsp app. Update some missing X509 errors in documentation. Reviewed-by: Richard Levitte Reviewed-by: Rich Salz (Merged from https://github.com/openssl/openssl/pull/941) --- apps/ocsp.c | 32 +++++++++++++++++++---------- crypto/x509/x509_txt.c | 6 ++++++ doc/man1/verify.pod | 41 ++++++++++++++++++++++++++++++++++++++ include/openssl/x509_vfy.h | 4 ++++ 4 files changed, 72 insertions(+), 11 deletions(-) diff --git a/apps/ocsp.c b/apps/ocsp.c index 8f6084214d..c461e76ea3 100644 --- a/apps/ocsp.c +++ b/apps/ocsp.c @@ -64,7 +64,7 @@ static void print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req, STACK_OF(OCSP_CERTID) *ids, long nsec, long maxage); static void make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, - CA_DB *db, X509 *ca, X509 *rcert, + CA_DB *db, STACK_OF(X509) *ca, X509 *rcert, EVP_PKEY *rkey, const EVP_MD *md, STACK_OF(X509) *rother, unsigned long flags, int nmin, int ndays, int badsig); @@ -192,7 +192,8 @@ int ocsp_main(int argc, char **argv) STACK_OF(OPENSSL_STRING) *reqnames = NULL; STACK_OF(X509) *sign_other = NULL, *verify_other = NULL, *rother = NULL; STACK_OF(X509) *issuers = NULL; - X509 *issuer = NULL, *cert = NULL, *rca_cert = NULL; + X509 *issuer = NULL, *cert = NULL; + STACK_OF(X509) *rca_cert = NULL; X509 *signer = NULL, *rsigner = NULL; X509_STORE *store = NULL; X509_VERIFY_PARAM *vpm = NULL; @@ -506,7 +507,9 @@ int ocsp_main(int argc, char **argv) BIO_printf(bio_err, "Error loading responder certificate\n"); goto end; } - rca_cert = load_cert(rca_filename, FORMAT_PEM, "CA certificate"); + if (!load_certs(rca_filename, &rca_cert, FORMAT_PEM, + NULL, "CA certificate")) + goto end; if (rcertfile) { if (!load_certs(rcertfile, &rother, FORMAT_PEM, NULL, "responder other certificates")) @@ -725,7 +728,7 @@ int ocsp_main(int argc, char **argv) X509_free(cert); sk_X509_pop_free(issuers, X509_free); X509_free(rsigner); - X509_free(rca_cert); + sk_X509_pop_free(rca_cert, X509_free); free_index(rdb); BIO_free_all(cbio); BIO_free_all(acbio); @@ -864,13 +867,13 @@ static void print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req, } static void make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, - CA_DB *db, X509 *ca, X509 *rcert, + CA_DB *db, STACK_OF(X509) *ca, X509 *rcert, EVP_PKEY *rkey, const EVP_MD *rmd, STACK_OF(X509) *rother, unsigned long flags, int nmin, int ndays, int badsig) { ASN1_TIME *thisupd = NULL, *nextupd = NULL; - OCSP_CERTID *cid, *ca_id = NULL; + OCSP_CERTID *cid; OCSP_BASICRESP *bs = NULL; int i, id_count; @@ -892,6 +895,8 @@ static void make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, OCSP_ONEREQ *one; ASN1_INTEGER *serial; char **inf; + int jj; + int found = 0; ASN1_OBJECT *cert_id_md_oid; const EVP_MD *cert_id_md; one = OCSP_request_onereq_get0(req, i); @@ -905,11 +910,17 @@ static void make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, NULL); goto end; } - OCSP_CERTID_free(ca_id); - ca_id = OCSP_cert_to_id(cert_id_md, NULL, ca); + for (jj = 0; jj < sk_X509_num(ca) && !found; jj++) { + X509 *ca_cert = sk_X509_value(ca, jj); + OCSP_CERTID *ca_id = OCSP_cert_to_id(cert_id_md, NULL, ca_cert); + + if (OCSP_id_issuer_cmp(ca_id, cid) == 0) + found = 1; + + OCSP_CERTID_free(ca_id); + } - /* Is this request about our CA? */ - if (OCSP_id_issuer_cmp(ca_id, cid)) { + if (!found) { OCSP_basic_add1_status(bs, cid, V_OCSP_CERTSTATUS_UNKNOWN, 0, NULL, thisupd, nextupd); @@ -962,7 +973,6 @@ static void make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, end: ASN1_TIME_free(thisupd); ASN1_TIME_free(nextupd); - OCSP_CERTID_free(ca_id); OCSP_BASICRESP_free(bs); } diff --git a/crypto/x509/x509_txt.c b/crypto/x509/x509_txt.c index 66e5fcd02f..a460bf5474 100644 --- a/crypto/x509/x509_txt.c +++ b/crypto/x509/x509_txt.c @@ -169,6 +169,12 @@ const char *X509_verify_cert_error_string(long n) return ("Certificate Transparency required, but no valid SCTs found"); case X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION: return ("proxy subject name violation"); + case X509_V_ERR_OCSP_VERIFY_NEEDED: + return("OCSP verification needed"); + case X509_V_ERR_OCSP_VERIFY_FAILED: + return("OCSP verification failed"); + case X509_V_ERR_OCSP_CERT_UNKNOWN: + return("OCSP unknown cert"); default: /* Printing an error number into a static buffer is not thread-safe */ diff --git a/doc/man1/verify.pod b/doc/man1/verify.pod index 6db7cd8367..5596e1d8bd 100644 --- a/doc/man1/verify.pod +++ b/doc/man1/verify.pod @@ -696,6 +696,47 @@ DANE TLSA authentication is enabled, but no TLSA records matched the certificate chain. This error is only possible in L. +=item B + +EE certificate key too weak. + +=item B + +CA certificate key too weak. + +=item B + +CA signature digest algorithm too weak. + +=item B + +nvalid certificate verification context. + +=item B + +Issuer certificate lookup error. + +=item B + +Certificate Transparency required, but no valid SCTs found. + +=item B + +Proxy subject name violation. + +=item B + +Returned by the verify callback to indicate an OCSP verification is needed. + +=item B + +Returned by the verify callback to indicate OCSP verification failed. + +=item B + +Returned by the verify callback to indicate that the certificate is not recognized +by the OCSP responder. + =back =head1 BUGS diff --git a/include/openssl/x509_vfy.h b/include/openssl/x509_vfy.h index 1aa0a33b8a..14147815c5 100644 --- a/include/openssl/x509_vfy.h +++ b/include/openssl/x509_vfy.h @@ -180,6 +180,10 @@ void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth); # define X509_V_ERR_NO_VALID_SCTS 71 # define X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION 72 +/* OCSP status errors */ +# define X509_V_ERR_OCSP_VERIFY_NEEDED 73 /* Need OCSP verification */ +# define X509_V_ERR_OCSP_VERIFY_FAILED 74 /* Couldn't verify cert through OCSP */ +# define X509_V_ERR_OCSP_CERT_UNKNOWN 75 /* Certificate wasn't recognized by the OCSP responder */ /* Certificate verify flags */ -- 2.25.1