SSL_CTX_set_verify.pod: move a typedef in front of its first usage
[openssl.git] / apps / ocsp.c
index cfc06a9c43c27d3d22203fabff18715eac9d8dad..c461e76ea3289e788028e2dc7dd5cd7f1d4b40dc 100644 (file)
@@ -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);
@@ -99,7 +99,7 @@ typedef enum OPTION_choice {
     OPT_MD
 } OPTION_CHOICE;
 
-OPTIONS ocsp_options[] = {
+const OPTIONS ocsp_options[] = {
     {"help", OPT_HELP, '-', "Display this summary"},
     {"out", OPT_OUTFILE, '>', "Output filename"},
     {"timeout", OPT_TIMEOUT, 'p',
@@ -107,7 +107,8 @@ OPTIONS ocsp_options[] = {
     {"url", OPT_URL, 's', "Responder URL"},
     {"host", OPT_HOST, 's', "TCP/IP hostname:port to connect to"},
     {"port", OPT_PORT, 'p', "Port to run responder on"},
-    {"ignore_err", OPT_IGNORE_ERR, '-'},
+    {"ignore_err", OPT_IGNORE_ERR, '-',
+     "Ignore Error response from OCSP responder, and retry "},
     {"noverify", OPT_NOVERIFY, '-', "Don't verify response at all"},
     {"nonce", OPT_NONCE, '-', "Add OCSP nonce to request"},
     {"no_nonce", OPT_NO_NONCE, '-', "Don't add OCSP nonce to request"},
@@ -124,7 +125,8 @@ OPTIONS ocsp_options[] = {
     {"no_chain", OPT_NO_CHAIN, '-', "Don't chain verify response"},
     {"no_cert_checks", OPT_NO_CERT_CHECKS, '-',
      "Don't do additional checks on signing certificate"},
-    {"no_explicit", OPT_NO_EXPLICIT, '-'},
+    {"no_explicit", OPT_NO_EXPLICIT, '-',
+     "Do not explicitly check the chain, just verify the root"},
     {"trust_other", OPT_TRUST_OTHER, '-',
      "Don't verify additional certificates"},
     {"no_intern", OPT_NO_INTERN, '-',
@@ -190,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;
@@ -504,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"))
@@ -723,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);
@@ -862,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;
 
@@ -890,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);
@@ -903,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);
@@ -960,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);
 }