Add -CAstore and similar to all openssl commands that have -CApath
authorRichard Levitte <levitte@openssl.org>
Thu, 7 Mar 2019 14:26:34 +0000 (15:26 +0100)
committerRichard Levitte <levitte@openssl.org>
Sun, 3 Nov 2019 17:38:23 +0000 (18:38 +0100)
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/8442)

27 files changed:
apps/cms.c
apps/crl.c
apps/include/apps.h
apps/include/s_apps.h
apps/lib/apps.c
apps/lib/opt.c
apps/lib/s_cb.c
apps/ocsp.c
apps/pkcs12.c
apps/s_client.c
apps/s_server.c
apps/s_time.c
apps/smime.c
apps/ts.c
apps/verify.c
doc/man1/openssl-cms.pod.in
doc/man1/openssl-crl.pod.in
doc/man1/openssl-ocsp.pod.in
doc/man1/openssl-pkcs12.pod.in
doc/man1/openssl-s_client.pod.in
doc/man1/openssl-s_server.pod.in
doc/man1/openssl-s_time.pod.in
doc/man1/openssl-smime.pod.in
doc/man1/openssl-ts.pod.in
doc/man1/openssl-verify.pod.in
doc/man1/openssl.pod
doc/perlvars.pm

index 0e0df5e..468820f 100644 (file)
@@ -75,7 +75,8 @@ typedef enum OPTION_choice {
     OPT_NOSIGS, OPT_NO_CONTENT_VERIFY, OPT_NO_ATTR_VERIFY, OPT_INDEF,
     OPT_NOINDEF, OPT_CRLFEOL, OPT_NOOUT, OPT_RR_PRINT,
     OPT_RR_ALL, OPT_RR_FIRST, OPT_RCTFORM, OPT_CERTFILE, OPT_CAFILE,
-    OPT_CAPATH, OPT_NOCAPATH, OPT_NOCAFILE,OPT_CONTENT, OPT_PRINT,
+    OPT_CAPATH, OPT_CASTORE, OPT_NOCAPATH, OPT_NOCAFILE, OPT_NOCASTORE,
+    OPT_CONTENT, OPT_PRINT,
     OPT_SECRETKEY, OPT_SECRETKEYID, OPT_PWRI_PASSWORD, OPT_ECONTENT_TYPE,
     OPT_PASSIN, OPT_TO, OPT_FROM, OPT_SUBJECT, OPT_SIGNER, OPT_RECIP,
     OPT_CERTSOUT, OPT_MD, OPT_INKEY, OPT_KEYFORM, OPT_KEYOPT, OPT_RR_FROM,
@@ -156,10 +157,13 @@ const OPTIONS cms_options[] = {
     {"certfile", OPT_CERTFILE, '<', "Other certificates file"},
     {"CAfile", OPT_CAFILE, '<', "Trusted certificates file"},
     {"CApath", OPT_CAPATH, '/', "trusted certificates directory"},
+    {"CAstore", OPT_CASTORE, ':', "trusted certificates store URI"},
     {"no-CAfile", OPT_NOCAFILE, '-',
      "Do not load the default certificates file"},
     {"no-CApath", OPT_NOCAPATH, '-',
      "Do not load certificates from the default certificates directory"},
+    {"no-CAstore", OPT_NOCASTORE, '-',
+     "Do not load certificates from the default certificates store"},
     {"content", OPT_CONTENT, '<',
      "Supply or override content for detached signature"},
     {"print", OPT_PRINT, '-',
@@ -219,9 +223,9 @@ int cms_main(int argc, char **argv)
     X509_STORE *store = NULL;
     X509_VERIFY_PARAM *vpm = NULL;
     char *certfile = NULL, *keyfile = NULL, *contfile = NULL;
-    const char *CAfile = NULL, *CApath = NULL;
+    const char *CAfile = NULL, *CApath = NULL, *CAstore = NULL;
     char *certsoutfile = NULL;
-    int noCAfile = 0, noCApath = 0;
+    int noCAfile = 0, noCApath = 0, noCAstore = 0;
     char *infile = NULL, *outfile = NULL, *rctfile = NULL;
     char *passinarg = NULL, *passin = NULL, *signerfile = NULL, *recipfile = NULL;
     char *to = NULL, *from = NULL, *subject = NULL, *prog;
@@ -401,12 +405,18 @@ int cms_main(int argc, char **argv)
         case OPT_CAPATH:
             CApath = opt_arg();
             break;
+        case OPT_CASTORE:
+            CAstore = opt_arg();
+            break;
         case OPT_NOCAFILE:
             noCAfile = 1;
             break;
         case OPT_NOCAPATH:
             noCApath = 1;
             break;
+        case OPT_NOCASTORE:
+            noCAstore = 1;
+            break;
         case OPT_IN:
             infile = opt_arg();
             break;
@@ -825,7 +835,8 @@ int cms_main(int argc, char **argv)
         goto end;
 
     if ((operation == SMIME_VERIFY) || (operation == SMIME_VERIFY_RECEIPT)) {
-        if ((store = setup_verify(CAfile, CApath, noCAfile, noCApath)) == NULL)
+        if ((store = setup_verify(CAfile, noCAfile, CApath, noCApath,
+                                  CAstore, noCAstore)) == NULL)
             goto end;
         X509_STORE_set_verify_cb(store, cms_cb);
         if (vpmtouched)
index d36b93b..f7f4fb7 100644 (file)
@@ -22,9 +22,9 @@ typedef enum OPTION_choice {
     OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
     OPT_INFORM, OPT_IN, OPT_OUTFORM, OPT_OUT, OPT_KEYFORM, OPT_KEY,
     OPT_ISSUER, OPT_LASTUPDATE, OPT_NEXTUPDATE, OPT_FINGERPRINT,
-    OPT_CRLNUMBER, OPT_BADSIG, OPT_GENDELTA, OPT_CAPATH, OPT_CAFILE,
-    OPT_NOCAPATH, OPT_NOCAFILE, OPT_VERIFY, OPT_TEXT, OPT_HASH, OPT_HASH_OLD,
-    OPT_NOOUT, OPT_NAMEOPT, OPT_MD
+    OPT_CRLNUMBER, OPT_BADSIG, OPT_GENDELTA, OPT_CAPATH, OPT_CAFILE, OPT_CASTORE,
+    OPT_NOCAPATH, OPT_NOCAFILE, OPT_NOCASTORE, OPT_VERIFY, OPT_TEXT, OPT_HASH,
+    OPT_HASH_OLD, OPT_NOOUT, OPT_NAMEOPT, OPT_MD
 } OPTION_CHOICE;
 
 const OPTIONS crl_options[] = {
@@ -45,10 +45,13 @@ const OPTIONS crl_options[] = {
     {"gendelta", OPT_GENDELTA, '<', "Other CRL to compare/diff to the Input one"},
     {"CApath", OPT_CAPATH, '/', "Verify CRL using certificates in dir"},
     {"CAfile", OPT_CAFILE, '<', "Verify CRL using certificates in file name"},
+    {"CAstore", OPT_CASTORE, ':', "Verify CRL using certificates in store URI"},
     {"no-CAfile", OPT_NOCAFILE, '-',
      "Do not load the default certificates file"},
     {"no-CApath", OPT_NOCAPATH, '-',
      "Do not load certificates from the default certificates directory"},
+    {"no-CAstore", OPT_NOCASTORE, '-',
+     "Do not load certificates from the default certificates store"},
     {"verify", OPT_VERIFY, '-', "Verify CRL signature"},
     {"text", OPT_TEXT, '-', "Print out a text format version"},
     {"hash", OPT_HASH, '-', "Print hash value"},
@@ -71,12 +74,12 @@ int crl_main(int argc, char **argv)
     EVP_PKEY *pkey;
     const EVP_MD *digest = EVP_sha1();
     char *infile = NULL, *outfile = NULL, *crldiff = NULL, *keyfile = NULL;
-    const char *CAfile = NULL, *CApath = NULL, *prog;
+    const char *CAfile = NULL, *CApath = NULL, *CAstore = NULL, *prog;
     OPTION_CHOICE o;
     int hash = 0, issuer = 0, lastupdate = 0, nextupdate = 0, noout = 0;
     int informat = FORMAT_PEM, outformat = FORMAT_PEM, keyformat = FORMAT_PEM;
     int ret = 1, num = 0, badsig = 0, fingerprint = 0, crlnumber = 0;
-    int text = 0, do_ver = 0, noCAfile = 0, noCApath = 0;
+    int text = 0, do_ver = 0, noCAfile = 0, noCApath = 0, noCAstore = 0;
     int i;
 #ifndef OPENSSL_NO_MD5
     int hash_old = 0;
@@ -126,12 +129,19 @@ int crl_main(int argc, char **argv)
             CAfile = opt_arg();
             do_ver = 1;
             break;
+        case OPT_CASTORE:
+            CAstore = opt_arg();
+            do_ver = 1;
+            break;
         case OPT_NOCAPATH:
             noCApath =  1;
             break;
         case OPT_NOCAFILE:
             noCAfile =  1;
             break;
+        case OPT_NOCASTORE:
+            noCAstore =  1;
+            break;
         case OPT_HASH_OLD:
 #ifndef OPENSSL_NO_MD5
             hash_old = ++num;
@@ -185,7 +195,8 @@ int crl_main(int argc, char **argv)
         goto end;
 
     if (do_ver) {
-        if ((store = setup_verify(CAfile, CApath, noCAfile, noCApath)) == NULL)
+        if ((store = setup_verify(CAfile, noCAfile, CApath, noCApath,
+                                  CAstore, noCAstore)) == NULL)
             goto end;
         lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
         if (lookup == NULL)
index 41db807..21a2a90 100644 (file)
@@ -126,11 +126,13 @@ int load_certs(const char *file, STACK_OF(X509) **certs, int format,
                const char *pass, const char *cert_descrip);
 int load_crls(const char *file, STACK_OF(X509_CRL) **crls, int format,
               const char *pass, const char *cert_descrip);
-X509_STORE *setup_verify(const char *CAfile, const char *CApath,
-                         int noCAfile, int noCApath);
-__owur int ctx_set_verify_locations(SSL_CTX *ctx, const char *CAfile,
-                                    const char *CApath, int noCAfile,
-                                    int noCApath);
+X509_STORE *setup_verify(const char *CAfile, int noCAfile,
+                         const char *CApath, int noCApath,
+                         const char *CAstore, int noCAstore);
+__owur int ctx_set_verify_locations(SSL_CTX *ctx,
+                                    const char *CAfile, int noCAfile,
+                                    const char *CApath, int noCApath,
+                                    const char *CAstore, int noCAstore);
 
 #ifndef OPENSSL_NO_CT
 
index 4f976da..1bbe5fe 100644 (file)
@@ -69,8 +69,9 @@ int config_ctx(SSL_CONF_CTX *cctx, STACK_OF(OPENSSL_STRING) *str, SSL_CTX *ctx);
 int ssl_ctx_add_crls(SSL_CTX *ctx, STACK_OF(X509_CRL) *crls,
                      int crl_download);
 int ssl_load_stores(SSL_CTX *ctx, const char *vfyCApath,
-                    const char *vfyCAfile, const char *chCApath,
-                    const char *chCAfile, STACK_OF(X509_CRL) *crls,
+                    const char *vfyCAfile, const char *vfyCAstore,
+                    const char *chCApath, const char *chCAfile,
+                    const char *chCAstore, STACK_OF(X509_CRL) *crls,
                     int crl_download);
 void ssl_ctx_security_debug(SSL_CTX *ctx, int verbose);
 int set_keylog_file(SSL_CTX *ctx, const char *keylog_file);
index 73483d9..8b840bb 100644 (file)
@@ -125,18 +125,29 @@ int app_init(long mesgwin)
 }
 #endif
 
-int ctx_set_verify_locations(SSL_CTX *ctx, const char *CAfile,
-                             const char *CApath, int noCAfile, int noCApath)
+int ctx_set_verify_locations(SSL_CTX *ctx,
+                             const char *CAfile, int noCAfile,
+                             const char *CApath, int noCApath,
+                             const char *CAstore, int noCAstore)
 {
-    if (CAfile == NULL && CApath == NULL) {
+    if (CAfile == NULL && CApath == NULL && CAstore == NULL) {
         if (!noCAfile && SSL_CTX_set_default_verify_file(ctx) <= 0)
             return 0;
         if (!noCApath && SSL_CTX_set_default_verify_dir(ctx) <= 0)
             return 0;
+        if (!noCAstore && SSL_CTX_set_default_verify_store(ctx) <= 0)
+            return 0;
 
         return 1;
     }
-    return SSL_CTX_load_verify_locations(ctx, CAfile, CApath);
+
+    if (CAfile != NULL && !SSL_CTX_load_verify_file(ctx, CAfile))
+        return 0;
+    if (CApath != NULL && !SSL_CTX_load_verify_dir(ctx, CApath))
+        return 0;
+    if (CAstore != NULL && !SSL_CTX_load_verify_store(ctx, CAstore))
+        return 0;
+    return 1;
 }
 
 #ifndef OPENSSL_NO_CT
@@ -1068,7 +1079,9 @@ void print_array(BIO *out, const char* title, int len, const unsigned char* d)
     BIO_printf(out, "\n};\n");
 }
 
-X509_STORE *setup_verify(const char *CAfile, const char *CApath, int noCAfile, int noCApath)
+X509_STORE *setup_verify(const char *CAfile, int noCAfile,
+                         const char *CApath, int noCApath,
+                         const char *CAstore, int noCAstore)
 {
     X509_STORE *store = X509_STORE_new();
     X509_LOOKUP *lookup;
@@ -1080,7 +1093,7 @@ X509_STORE *setup_verify(const char *CAfile, const char *CApath, int noCAfile, i
         lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
         if (lookup == NULL)
             goto end;
-        if (CAfile) {
+        if (CAfile != NULL) {
             if (!X509_LOOKUP_load_file(lookup, CAfile, X509_FILETYPE_PEM)) {
                 BIO_printf(bio_err, "Error loading file %s\n", CAfile);
                 goto end;
@@ -1094,7 +1107,7 @@ X509_STORE *setup_verify(const char *CAfile, const char *CApath, int noCAfile, i
         lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
         if (lookup == NULL)
             goto end;
-        if (CApath) {
+        if (CApath != NULL) {
             if (!X509_LOOKUP_add_dir(lookup, CApath, X509_FILETYPE_PEM)) {
                 BIO_printf(bio_err, "Error loading directory %s\n", CApath);
                 goto end;
@@ -1104,6 +1117,17 @@ X509_STORE *setup_verify(const char *CAfile, const char *CApath, int noCAfile, i
         }
     }
 
+    if (CAstore != NULL || !noCAstore) {
+        lookup = X509_STORE_add_lookup(store, X509_LOOKUP_store());
+        if (lookup == NULL)
+            goto end;
+        if (!X509_LOOKUP_add_store(lookup, CAstore)) {
+            if (CAstore != NULL)
+                BIO_printf(bio_err, "Error loading store URI %s\n", CAstore);
+            goto end;
+        }
+    }
+
     ERR_clear_error();
     return store;
  end:
index 44d2570..98979fc 100644 (file)
@@ -146,7 +146,7 @@ char *opt_init(int ac, char **av, const OPTIONS *o)
         switch (i) {
         case   0: case '-': case '/': case '<': case '>': case 'E': case 'F':
         case 'M': case 'U': case 'f': case 'l': case 'n': case 'p': case 's':
-        case 'u': case 'c':
+        case 'u': case 'c': case ':':
             break;
         default:
             OPENSSL_assert(0);
@@ -686,6 +686,7 @@ int opt_next(void)
         switch (o->valtype) {
         default:
         case 's':
+        case ':':
             /* Just a string. */
             break;
         case '/':
@@ -804,6 +805,8 @@ static const char *valtype2param(const OPTIONS *o)
     case 0:
     case '-':
         return "";
+    case ':':
+        return "uri";
     case 's':
         return "val";
     case '/':
index 47b8afe..7b81d60 100644 (file)
@@ -1262,27 +1262,37 @@ int ssl_ctx_add_crls(SSL_CTX *ctx, STACK_OF(X509_CRL) *crls, int crl_download)
 
 int ssl_load_stores(SSL_CTX *ctx,
                     const char *vfyCApath, const char *vfyCAfile,
+                    const char *vfyCAstore,
                     const char *chCApath, const char *chCAfile,
+                    const char *chCAstore,
                     STACK_OF(X509_CRL) *crls, int crl_download)
 {
     X509_STORE *vfy = NULL, *ch = NULL;
     int rv = 0;
-    if (vfyCApath != NULL || vfyCAfile != NULL) {
+    if (vfyCApath != NULL || vfyCAfile != NULL || vfyCAstore != NULL) {
         vfy = X509_STORE_new();
         if (vfy == NULL)
             goto err;
-        if (!X509_STORE_load_locations(vfy, vfyCAfile, vfyCApath))
+        if (vfyCAfile != NULL && !X509_STORE_load_file(vfy, vfyCAfile))
+            goto err;
+        if (vfyCApath != NULL && !X509_STORE_load_path(vfy, vfyCApath))
+            goto err;
+        if (vfyCAstore != NULL && !X509_STORE_load_store(vfy, vfyCAstore))
             goto err;
         add_crls_store(vfy, crls);
         SSL_CTX_set1_verify_cert_store(ctx, vfy);
         if (crl_download)
             store_setup_crl_download(vfy);
     }
-    if (chCApath != NULL || chCAfile != NULL) {
+    if (chCApath != NULL || chCAfile != NULL || chCAstore != NULL) {
         ch = X509_STORE_new();
         if (ch == NULL)
             goto err;
-        if (!X509_STORE_load_locations(ch, chCAfile, chCApath))
+        if (chCAfile != NULL && !X509_STORE_load_file(ch, chCAfile))
+            goto err;
+        if (chCApath != NULL && !X509_STORE_load_path(ch, chCApath))
+            goto err;
+        if (chCAstore != NULL && !X509_STORE_load_store(ch, chCAstore))
             goto err;
         SSL_CTX_set1_chain_cert_store(ctx, ch);
     }
index 71c6a56..458c808 100644 (file)
@@ -134,7 +134,8 @@ typedef enum OPTION_choice {
     OPT_NO_CERT_CHECKS, OPT_NO_EXPLICIT, OPT_TRUST_OTHER,
     OPT_NO_INTERN, OPT_BADSIG, OPT_TEXT, OPT_REQ_TEXT, OPT_RESP_TEXT,
     OPT_REQIN, OPT_RESPIN, OPT_SIGNER, OPT_VAFILE, OPT_SIGN_OTHER,
-    OPT_VERIFY_OTHER, OPT_CAFILE, OPT_CAPATH, OPT_NOCAFILE, OPT_NOCAPATH,
+    OPT_VERIFY_OTHER, OPT_CAFILE, OPT_CAPATH, OPT_CASTORE, OPT_NOCAFILE,
+    OPT_NOCAPATH, OPT_NOCASTORE,
     OPT_VALIDITY_PERIOD, OPT_STATUS_AGE, OPT_SIGNKEY, OPT_REQOUT,
     OPT_RESPOUT, OPT_PATH, OPT_ISSUER, OPT_CERT, OPT_SERIAL,
     OPT_INDEX, OPT_CA, OPT_NMIN, OPT_REQUEST, OPT_NDAYS, OPT_RSIGNER,
@@ -195,10 +196,13 @@ const OPTIONS ocsp_options[] = {
      "Additional certificates to search for signer"},
     {"CAfile", OPT_CAFILE, '<', "Trusted certificates file"},
     {"CApath", OPT_CAPATH, '<', "Trusted certificates directory"},
+    {"CAstore", OPT_CASTORE, ':', "Trusted certificates store URI"},
     {"no-CAfile", OPT_NOCAFILE, '-',
      "Do not load the default certificates file"},
     {"no-CApath", OPT_NOCAPATH, '-',
      "Do not load certificates from the default certificates directory"},
+    {"no-CAstore", OPT_NOCAPATH, '-',
+     "Do not load certificates from the default certificates store"},
     {"validity_period", OPT_VALIDITY_PERIOD, 'u',
      "Maximum validity discrepancy in seconds"},
     {"status_age", OPT_STATUS_AGE, 'p', "Maximum status age in seconds"},
@@ -250,7 +254,7 @@ int ocsp_main(int argc, char **argv)
     X509 *signer = NULL, *rsigner = NULL;
     X509_STORE *store = NULL;
     X509_VERIFY_PARAM *vpm = NULL;
-    const char *CAfile = NULL, *CApath = NULL;
+    const char *CAfile = NULL, *CApath = NULL, *CAstore = NULL;
     char *header, *value;
     char *host = NULL, *port = NULL, *path = "/", *outfile = NULL;
     char *rca_filename = NULL, *reqin = NULL, *respin = NULL;
@@ -259,7 +263,7 @@ int ocsp_main(int argc, char **argv)
     char *sign_certfile = NULL, *verify_certfile = NULL, *rcertfile = NULL;
     char *signfile = NULL, *keyfile = NULL;
     char *thost = NULL, *tport = NULL, *tpath = NULL;
-    int noCAfile = 0, noCApath = 0;
+    int noCAfile = 0, noCApath = 0, noCAstore = 0;
     int accept_count = -1, add_nonce = 1, noverify = 0, use_ssl = -1;
     int vpmtouched = 0, badsig = 0, i, ignore_err = 0, nmin = 0, ndays = -1;
     int req_text = 0, resp_text = 0, ret = 1;
@@ -395,12 +399,18 @@ int ocsp_main(int argc, char **argv)
         case OPT_CAPATH:
             CApath = opt_arg();
             break;
+        case OPT_CASTORE:
+            CAstore = opt_arg();
+            break;
         case OPT_NOCAFILE:
             noCAfile = 1;
             break;
         case OPT_NOCAPATH:
             noCApath = 1;
             break;
+        case OPT_NOCASTORE:
+            noCAstore = 1;
+            break;
         case OPT_V_CASES:
             if (!opt_verify(o, vpm))
                 goto end;
@@ -765,7 +775,8 @@ redo_accept:
     }
 
     if (store == NULL) {
-        store = setup_verify(CAfile, CApath, noCAfile, noCApath);
+        store = setup_verify(CAfile, noCAfile, CApath, noCApath,
+                             CAstore, noCAstore);
         if (!store)
             goto end;
     }
index a708064..781c3ad 100644 (file)
@@ -57,7 +57,7 @@ typedef enum OPTION_choice {
     OPT_NOMAC, OPT_LMK, OPT_NODES, OPT_MACALG, OPT_CERTPBE, OPT_KEYPBE,
     OPT_INKEY, OPT_CERTFILE, OPT_NAME, OPT_CSP, OPT_CANAME,
     OPT_IN, OPT_OUT, OPT_PASSIN, OPT_PASSOUT, OPT_PASSWORD, OPT_CAPATH,
-    OPT_CAFILE, OPT_NOCAPATH, OPT_NOCAFILE, OPT_ENGINE,
+    OPT_CAFILE, OPT_CASTORE, OPT_NOCAPATH, OPT_NOCAFILE, OPT_NOCASTORE, OPT_ENGINE,
     OPT_R_ENUM
 } OPTION_CHOICE;
 
@@ -108,10 +108,13 @@ const OPTIONS pkcs12_options[] = {
     {"password", OPT_PASSWORD, 's', "Set import/export password source"},
     {"CApath", OPT_CAPATH, '/', "PEM-format directory of CA's"},
     {"CAfile", OPT_CAFILE, '<', "PEM-format file of CA's"},
+    {"CAstore", OPT_CASTORE, ':', "URI to store if CA's"},
     {"no-CAfile", OPT_NOCAFILE, '-',
      "Do not load the default certificates file"},
     {"no-CApath", OPT_NOCAPATH, '-',
      "Do not load certificates from the default certificates directory"},
+    {"no-CAstore", OPT_NOCASTORE, '-',
+     "Do not load certificates from the default certificates store"},
     {"", OPT_CIPHER, '-', "Any supported cipher"},
 # ifndef OPENSSL_NO_ENGINE
     {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
@@ -137,8 +140,8 @@ int pkcs12_main(int argc, char **argv)
     char *passinarg = NULL, *passoutarg = NULL, *passarg = NULL;
     char *passin = NULL, *passout = NULL, *macalg = NULL;
     char *cpass = NULL, *mpass = NULL, *badpass = NULL;
-    const char *CApath = NULL, *CAfile = NULL, *prog;
-    int noCApath = 0, noCAfile = 0;
+    const char *CApath = NULL, *CAfile = NULL, *CAstore = NULL, *prog;
+    int noCApath = 0, noCAfile = 0, noCAstore = 0;
     ENGINE *e = NULL;
     BIO *in = NULL, *out = NULL;
     PKCS12 *p12 = NULL;
@@ -270,12 +273,18 @@ int pkcs12_main(int argc, char **argv)
         case OPT_CAPATH:
             CApath = opt_arg();
             break;
+        case OPT_CASTORE:
+            CAstore = opt_arg();
+            break;
         case OPT_CAFILE:
             CAfile = opt_arg();
             break;
         case OPT_NOCAPATH:
             noCApath = 1;
             break;
+        case OPT_NOCASTORE:
+            noCAstore = 1;
+            break;
         case OPT_NOCAFILE:
             noCAfile = 1;
             break;
@@ -404,7 +413,8 @@ int pkcs12_main(int argc, char **argv)
             int vret;
             STACK_OF(X509) *chain2;
             X509_STORE *store;
-            if ((store = setup_verify(CAfile, CApath, noCAfile, noCApath))
+            if ((store = setup_verify(CAfile, noCAfile, CApath, noCApath,
+                                      CAstore, noCAstore))
                     == NULL)
                 goto export_end;
 
index 392ab02..fa5cb95 100644 (file)
@@ -581,9 +581,11 @@ typedef enum OPTION_choice {
     OPT_SSL3, OPT_SSL_CONFIG,
     OPT_TLS1_3, OPT_TLS1_2, OPT_TLS1_1, OPT_TLS1, OPT_DTLS, OPT_DTLS1,
     OPT_DTLS1_2, OPT_SCTP, OPT_TIMEOUT, OPT_MTU, OPT_KEYFORM, OPT_PASS,
-    OPT_CERT_CHAIN, OPT_CAPATH, OPT_NOCAPATH, OPT_CHAINCAPATH, OPT_VERIFYCAPATH,
-    OPT_KEY, OPT_RECONNECT, OPT_BUILD_CHAIN, OPT_CAFILE, OPT_NOCAFILE,
-    OPT_CHAINCAFILE, OPT_VERIFYCAFILE, OPT_NEXTPROTONEG, OPT_ALPN,
+    OPT_CERT_CHAIN, OPT_KEY, OPT_RECONNECT, OPT_BUILD_CHAIN,
+    OPT_NEXTPROTONEG, OPT_ALPN,
+    OPT_CAPATH, OPT_NOCAPATH, OPT_CHAINCAPATH, OPT_VERIFYCAPATH,
+    OPT_CAFILE, OPT_NOCAFILE, OPT_CHAINCAFILE, OPT_VERIFYCAFILE,
+    OPT_CASTORE, OPT_NOCASTORE, OPT_CHAINCASTORE, OPT_VERIFYCASTORE,
     OPT_SERVERINFO, OPT_STARTTLS, OPT_SERVERNAME, OPT_NOSERVERNAME, OPT_ASYNC,
     OPT_USE_SRTP, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN, OPT_PROTOHOST,
     OPT_MAXFRAGLEN, OPT_MAX_SEND_FRAG, OPT_SPLIT_SEND_FRAG, OPT_MAX_PIPELINES,
@@ -630,10 +632,13 @@ const OPTIONS s_client_options[] = {
     {"pass", OPT_PASS, 's', "Private key file pass phrase source"},
     {"CApath", OPT_CAPATH, '/', "PEM format directory of CA's"},
     {"CAfile", OPT_CAFILE, '<', "PEM format file of CA's"},
+    {"CAstore", OPT_CAFILE, ':', "URI to store of CA's"},
     {"no-CAfile", OPT_NOCAFILE, '-',
      "Do not load the default certificates file"},
     {"no-CApath", OPT_NOCAPATH, '-',
      "Do not load certificates from the default certificates directory"},
+    {"no-CAstore", OPT_NOCAPATH, '-',
+     "Do not load certificates from the default certificates store"},
     {"requestCAfile", OPT_REQCAFILE, '<',
       "PEM format file of CA names to send to the server"},
     {"dane_tlsa_domain", OPT_DANE_TLSA_DOMAIN, 's', "DANE TLSA base domain"},
@@ -700,6 +705,10 @@ const OPTIONS s_client_options[] = {
      "CA file for certificate chain (PEM format)"},
     {"verifyCAfile", OPT_VERIFYCAFILE, '<',
      "CA file for certificate verification (PEM format)"},
+    {"chainCAstore", OPT_CHAINCASTORE, ':',
+     "CA store URI for certificate chain"},
+    {"verifyCAstore", OPT_VERIFYCASTORE, ':',
+     "CA store URI for certificate verification"},
     {"nocommands", OPT_NOCMDS, '-', "Do not use interactive command letters"},
     {"servername", OPT_SERVERNAME, 's',
      "Set TLS extension servername (SNI) in ClientHello (default)"},
@@ -899,22 +908,23 @@ int s_client_main(int argc, char **argv)
     int dane_ee_no_name = 0;
     STACK_OF(X509_CRL) *crls = NULL;
     const SSL_METHOD *meth = TLS_client_method();
-    const char *CApath = NULL, *CAfile = NULL;
+    const char *CApath = NULL, *CAfile = NULL, *CAstore = NULL;
     char *cbuf = NULL, *sbuf = NULL, *mbuf = NULL;
     char *proxystr = NULL, *proxyuser = NULL;
     char *proxypassarg = NULL, *proxypass = NULL;
     char *connectstr = NULL, *bindstr = NULL;
     char *cert_file = NULL, *key_file = NULL, *chain_file = NULL;
-    char *chCApath = NULL, *chCAfile = NULL, *host = NULL;
+    char *chCApath = NULL, *chCAfile = NULL, *chCAstore = NULL, *host = NULL;
     char *port = OPENSSL_strdup(PORT);
     char *bindhost = NULL, *bindport = NULL;
-    char *passarg = NULL, *pass = NULL, *vfyCApath = NULL, *vfyCAfile = NULL;
+    char *passarg = NULL, *pass = NULL;
+    char *vfyCApath = NULL, *vfyCAfile = NULL, *vfyCAstore = NULL;
     char *ReqCAfile = NULL;
     char *sess_in = NULL, *crl_file = NULL, *p;
     const char *protohost = NULL;
     struct timeval timeout, *timeoutp;
     fd_set readfds, writefds;
-    int noCApath = 0, noCAfile = 0;
+    int noCApath = 0, noCAfile = 0, noCAstore = 0;
     int build_chain = 0, cbuf_len, cbuf_off, cert_format = FORMAT_PEM;
     int key_format = FORMAT_PEM, crlf = 0, full_log = 1, mbuf_len = 0;
     int prexit = 0;
@@ -1416,6 +1426,18 @@ int s_client_main(int argc, char **argv)
         case OPT_VERIFYCAFILE:
             vfyCAfile = opt_arg();
             break;
+        case OPT_CASTORE:
+            CAstore = opt_arg();
+            break;
+        case OPT_NOCASTORE:
+            noCAstore = 1;
+            break;
+        case OPT_CHAINCASTORE:
+            chCAstore = opt_arg();
+            break;
+        case OPT_VERIFYCASTORE:
+            vfyCAstore = opt_arg();
+            break;
         case OPT_DANE_TLSA_DOMAIN:
             dane_tlsa_domain = opt_arg();
             break;
@@ -1796,7 +1818,9 @@ int s_client_main(int argc, char **argv)
         goto end;
     }
 
-    if (!ssl_load_stores(ctx, vfyCApath, vfyCAfile, chCApath, chCAfile,
+    if (!ssl_load_stores(ctx,
+                         vfyCApath, vfyCAfile, vfyCAstore,
+                         chCApath, chCAfile, chCAstore,
                          crls, crl_download)) {
         BIO_printf(bio_err, "Error loading store locations\n");
         ERR_print_errors(bio_err);
@@ -1925,7 +1949,8 @@ int s_client_main(int argc, char **argv)
 
     SSL_CTX_set_verify(ctx, verify, verify_callback);
 
-    if (!ctx_set_verify_locations(ctx, CAfile, CApath, noCAfile, noCApath)) {
+    if (!ctx_set_verify_locations(ctx, CAfile, noCAfile, CApath, noCApath,
+                                  CAstore, noCAstore)) {
         ERR_print_errors(bio_err);
         goto end;
     }
index 5f58ef6..03ff1b4 100644 (file)
@@ -735,7 +735,9 @@ typedef enum OPTION_choice {
     OPT_CAPATH, OPT_NOCAPATH, OPT_CHAINCAPATH, OPT_VERIFYCAPATH, OPT_NO_CACHE,
     OPT_EXT_CACHE, OPT_CRLFORM, OPT_VERIFY_RET_ERROR, OPT_VERIFY_QUIET,
     OPT_BUILD_CHAIN, OPT_CAFILE, OPT_NOCAFILE, OPT_CHAINCAFILE,
-    OPT_VERIFYCAFILE, OPT_NBIO, OPT_NBIO_TEST, OPT_IGN_EOF, OPT_NO_IGN_EOF,
+    OPT_VERIFYCAFILE,
+    OPT_CASTORE, OPT_NOCASTORE, OPT_CHAINCASTORE, OPT_VERIFYCASTORE,
+    OPT_NBIO, OPT_NBIO_TEST, OPT_IGN_EOF, OPT_NO_IGN_EOF,
     OPT_DEBUG, OPT_TLSEXTDEBUG, OPT_STATUS, OPT_STATUS_VERBOSE,
     OPT_STATUS_TIMEOUT, OPT_STATUS_URL, OPT_STATUS_FILE, OPT_MSG, OPT_MSGFILE,
     OPT_TRACE, OPT_SECURITY_DEBUG, OPT_SECURITY_DEBUG_VERBOSE, OPT_STATE,
@@ -807,10 +809,13 @@ const OPTIONS s_server_options[] = {
     {"state", OPT_STATE, '-', "Print the SSL states"},
     {"CAfile", OPT_CAFILE, '<', "PEM format file of CA's"},
     {"CApath", OPT_CAPATH, '/', "PEM format directory of CA's"},
+    {"CAstore", OPT_CASTORE, ':', "URI to store of CA's"},
     {"no-CAfile", OPT_NOCAFILE, '-',
      "Do not load the default certificates file"},
     {"no-CApath", OPT_NOCAPATH, '-',
      "Do not load certificates from the default certificates directory"},
+    {"no-CAstore", OPT_NOCASTORE, '-',
+     "Do not load certificates from the default certificates store URI"},
     {"nocert", OPT_NOCERT, '-', "Don't use any certificates (Anon-DH)"},
     {"quiet", OPT_QUIET, '-', "No server output"},
     {"no_resume_ephemeral", OPT_NO_RESUME_EPHEMERAL, '-',
@@ -844,8 +849,12 @@ const OPTIONS s_server_options[] = {
      "second certificate chain file in PEM format"},
     {"chainCApath", OPT_CHAINCAPATH, '/',
      "use dir as certificate store path to build CA certificate chain"},
+    {"chainCAstore", OPT_CHAINCASTORE, ':',
+     "use URI as certificate store to build CA certificate chain"},
     {"verifyCApath", OPT_VERIFYCAPATH, '/',
      "use dir as certificate store path to verify CA certificate"},
+    {"verifyCAstore", OPT_VERIFYCASTORE, ':',
+     "use URI as certificate store to verify CA certificate"},
     {"no_cache", OPT_NO_CACHE, '-', "Disable session cache"},
     {"ext_cache", OPT_EXT_CACHE, '-',
      "Disable internal cache, setup and use external cache"},
@@ -986,9 +995,11 @@ int s_server_main(int argc, char *argv[])
     STACK_OF(X509_CRL) *crls = NULL;
     X509 *s_cert = NULL, *s_dcert = NULL;
     X509_VERIFY_PARAM *vpm = NULL;
-    const char *CApath = NULL, *CAfile = NULL, *chCApath = NULL, *chCAfile = NULL;
+    const char *CApath = NULL, *CAfile = NULL, *CAstore = NULL;
+    const char *chCApath = NULL, *chCAfile = NULL, *chCAstore = NULL;
     char *dpassarg = NULL, *dpass = NULL;
-    char *passarg = NULL, *pass = NULL, *vfyCApath = NULL, *vfyCAfile = NULL;
+    char *passarg = NULL, *pass = NULL;
+    char *vfyCApath = NULL, *vfyCAfile = NULL, *vfyCAstore = NULL;
     char *crl_file = NULL, *prog;
 #ifdef AF_UNIX
     int unlink_unix_path = 0;
@@ -1000,7 +1011,7 @@ int s_server_main(int argc, char *argv[])
     int no_dhe = 0;
 #endif
     int nocert = 0, ret = 1;
-    int noCApath = 0, noCAfile = 0;
+    int noCApath = 0, noCAfile = 0, noCAstore = 0;
     int s_cert_format = FORMAT_PEM, s_key_format = FORMAT_PEM;
     int s_dcert_format = FORMAT_PEM, s_dkey_format = FORMAT_PEM;
     int rev = 0, naccept = -1, sdebug = 0;
@@ -1258,6 +1269,18 @@ int s_server_main(int argc, char *argv[])
         case OPT_VERIFYCAPATH:
             vfyCApath = opt_arg();
             break;
+        case OPT_CASTORE:
+            CAstore = opt_arg();
+            break;
+        case OPT_NOCASTORE:
+            noCAstore = 1;
+            break;
+        case OPT_CHAINCASTORE:
+            chCAstore = opt_arg();
+            break;
+        case OPT_VERIFYCASTORE:
+            vfyCAstore = opt_arg();
+            break;
         case OPT_NO_CACHE:
             no_cache = 1;
             break;
@@ -1880,7 +1903,8 @@ int s_server_main(int argc, char *argv[])
     }
 #endif
 
-    if (!ctx_set_verify_locations(ctx, CAfile, CApath, noCAfile, noCApath)) {
+    if (!ctx_set_verify_locations(ctx, CAfile, noCAfile, CApath, noCApath,
+                                  CAstore, noCAstore)) {
         ERR_print_errors(bio_err);
         goto end;
     }
@@ -1892,7 +1916,9 @@ int s_server_main(int argc, char *argv[])
 
     ssl_ctx_add_crls(ctx, crls, 0);
 
-    if (!ssl_load_stores(ctx, vfyCApath, vfyCAfile, chCApath, chCAfile,
+    if (!ssl_load_stores(ctx,
+                         vfyCApath, vfyCAfile, vfyCAstore,
+                         chCApath, chCAfile, chCAstore,
                          crls, crl_download)) {
         BIO_printf(bio_err, "Error loading store locations\n");
         ERR_print_errors(bio_err);
@@ -1941,8 +1967,8 @@ int s_server_main(int argc, char *argv[])
         if (async)
             SSL_CTX_set_mode(ctx2, SSL_MODE_ASYNC);
 
-        if (!ctx_set_verify_locations(ctx2, CAfile, CApath, noCAfile,
-                                      noCApath)) {
+        if (!ctx_set_verify_locations(ctx2, CAfile, noCAfile, CApath,
+                                      noCApath, CAstore, noCAstore)) {
             ERR_print_errors(bio_err);
             goto end;
         }
index f6dbfa0..43bec59 100644 (file)
@@ -45,8 +45,9 @@ static const size_t fmt_http_get_cmd_size = sizeof(fmt_http_get_cmd) - 2;
 typedef enum OPTION_choice {
     OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
     OPT_CONNECT, OPT_CIPHER, OPT_CIPHERSUITES, OPT_CERT, OPT_NAMEOPT, OPT_KEY,
-    OPT_CAPATH, OPT_CAFILE, OPT_NOCAPATH, OPT_NOCAFILE, OPT_NEW, OPT_REUSE,
-    OPT_BUGS, OPT_VERIFY, OPT_TIME, OPT_SSL3,
+    OPT_CAPATH, OPT_CAFILE, OPT_CASTORE,
+    OPT_NOCAPATH, OPT_NOCAFILE, OPT_NOCASTORE,
+    OPT_NEW, OPT_REUSE, OPT_BUGS, OPT_VERIFY, OPT_TIME, OPT_SSL3,
     OPT_WWW, OPT_TLS1, OPT_TLS1_1, OPT_TLS1_2, OPT_TLS1_3
 } OPTION_CHOICE;
 
@@ -60,12 +61,15 @@ const OPTIONS s_time_options[] = {
     {"cert", OPT_CERT, '<', "Cert file to use, PEM format assumed"},
     {"nameopt", OPT_NAMEOPT, 's', "Various certificate name options"},
     {"key", OPT_KEY, '<', "File with key, PEM; default is -cert file"},
-    {"CApath", OPT_CAPATH, '/', "PEM format directory of CA's"},
     {"cafile", OPT_CAFILE, '<', "PEM format file of CA's"},
+    {"CApath", OPT_CAPATH, '/', "PEM format directory of CA's"},
+    {"CAstore", OPT_CASTORE, ':', "URI to store of CA's"},
     {"no-CAfile", OPT_NOCAFILE, '-',
      "Do not load the default certificates file"},
     {"no-CApath", OPT_NOCAPATH, '-',
      "Do not load certificates from the default certificates directory"},
+    {"no-CAstore", OPT_NOCASTORE, '-',
+     "Do not load certificates from the default certificates store URI"},
     {"new", OPT_NEW, '-', "Just time new connections"},
     {"reuse", OPT_REUSE, '-', "Just time connection reuse"},
     {"bugs", OPT_BUGS, '-', "Turn on SSL bug compatibility"},
@@ -105,11 +109,12 @@ int s_time_main(int argc, char **argv)
     SSL *scon = NULL;
     SSL_CTX *ctx = NULL;
     const SSL_METHOD *meth = NULL;
-    char *CApath = NULL, *CAfile = NULL, *cipher = NULL, *ciphersuites = NULL;
+    char *CApath = NULL, *CAfile = NULL, *CAstore = NULL;
+    char *cipher = NULL, *ciphersuites = NULL;
     char *www_path = NULL;
     char *host = SSL_CONNECT_NAME, *certfile = NULL, *keyfile = NULL, *prog;
     double totalTime = 0.0;
-    int noCApath = 0, noCAfile = 0;
+    int noCApath = 0, noCAfile = 0, noCAstore = 0;
     int maxtime = SECONDS, nConn = 0, perform = 3, ret = 1, i, st_bugs = 0;
     long bytes_read = 0, finishtime = 0;
     OPTION_CHOICE o;
@@ -167,6 +172,12 @@ int s_time_main(int argc, char **argv)
         case OPT_NOCAFILE:
             noCAfile = 1;
             break;
+        case OPT_CASTORE:
+            CAstore = opt_arg();
+            break;
+        case OPT_NOCASTORE:
+            noCAstore = 1;
+            break;
         case OPT_CIPHER:
             cipher = opt_arg();
             break;
@@ -236,7 +247,8 @@ int s_time_main(int argc, char **argv)
     if (!set_cert_stuff(ctx, certfile, keyfile))
         goto end;
 
-    if (!ctx_set_verify_locations(ctx, CAfile, CApath, noCAfile, noCApath)) {
+    if (!ctx_set_verify_locations(ctx, CAfile, noCAfile, CApath, noCApath,
+                                  CAstore, noCAstore)) {
         ERR_print_errors(bio_err);
         goto end;
     }
index 0f99e0a..26bd028 100644 (file)
@@ -41,9 +41,10 @@ typedef enum OPTION_choice {
     OPT_CRLFEOL, OPT_ENGINE, OPT_PASSIN,
     OPT_TO, OPT_FROM, OPT_SUBJECT, OPT_SIGNER, OPT_RECIP, OPT_MD,
     OPT_CIPHER, OPT_INKEY, OPT_KEYFORM, OPT_CERTFILE, OPT_CAFILE,
+    OPT_CAPATH, OPT_CASTORE, OPT_NOCAFILE, OPT_NOCAPATH, OPT_NOCASTORE,
     OPT_R_ENUM,
     OPT_V_ENUM,
-    OPT_CAPATH, OPT_NOCAFILE, OPT_NOCAPATH, OPT_IN, OPT_INFORM, OPT_OUT,
+    OPT_IN, OPT_INFORM, OPT_OUT,
     OPT_OUTFORM, OPT_CONTENT
 } OPTION_CHOICE;
 
@@ -86,10 +87,13 @@ const OPTIONS smime_options[] = {
     {"text", OPT_TEXT, '-', "Include or delete text MIME headers"},
     {"CApath", OPT_CAPATH, '/', "Trusted certificates directory"},
     {"CAfile", OPT_CAFILE, '<', "Trusted certificates file"},
+    {"CAstore", OPT_CASTORE, ':', "Trusted certificates store URI"},
     {"no-CAfile", OPT_NOCAFILE, '-',
      "Do not load the default certificates file"},
     {"no-CApath", OPT_NOCAPATH, '-',
      "Do not load certificates from the default certificates directory"},
+    {"no-CAstore", OPT_NOCASTORE, '-',
+     "Do not load certificates from the default certificates store"},
     {"resign", OPT_RESIGN, '-', "Resign a signed message"},
     {"nochain", OPT_NOCHAIN, '-',
      "set PKCS7_NOCHAIN so certificates contained in the message are not used as untrusted CAs" },
@@ -121,12 +125,12 @@ int smime_main(int argc, char **argv)
     X509_VERIFY_PARAM *vpm = NULL;
     const EVP_CIPHER *cipher = NULL;
     const EVP_MD *sign_md = NULL;
-    const char *CAfile = NULL, *CApath = NULL, *prog = NULL;
+    const char *CAfile = NULL, *CApath = NULL, *CAstore = NULL, *prog = NULL;
     char *certfile = NULL, *keyfile = NULL, *contfile = NULL;
     char *infile = NULL, *outfile = NULL, *signerfile = NULL, *recipfile = NULL;
     char *passinarg = NULL, *passin = NULL, *to = NULL, *from = NULL, *subject = NULL;
     OPTION_CHOICE o;
-    int noCApath = 0, noCAfile = 0;
+    int noCApath = 0, noCAfile = 0, noCAstore = 0;
     int flags = PKCS7_DETACHED, operation = 0, ret = 0, indef = 0;
     int informat = FORMAT_SMIME, outformat = FORMAT_SMIME, keyform =
         FORMAT_PEM;
@@ -302,12 +306,18 @@ int smime_main(int argc, char **argv)
         case OPT_CAPATH:
             CApath = opt_arg();
             break;
+        case OPT_CASTORE:
+            CAstore = opt_arg();
+            break;
         case OPT_NOCAFILE:
             noCAfile = 1;
             break;
         case OPT_NOCAPATH:
             noCApath = 1;
             break;
+        case OPT_NOCASTORE:
+            noCAstore = 1;
+            break;
         case OPT_CONTENT:
             contfile = opt_arg();
             break;
@@ -473,7 +483,8 @@ int smime_main(int argc, char **argv)
         goto end;
 
     if (operation == SMIME_VERIFY) {
-        if ((store = setup_verify(CAfile, CApath, noCAfile, noCApath)) == NULL)
+        if ((store = setup_verify(CAfile, noCAfile, CApath, noCApath,
+                                  CAstore, noCAstore)) == NULL)
             goto end;
         X509_STORE_set_verify_cb(store, smime_cb);
         if (vpmtouched)
index b45c262..9fdba64 100644 (file)
--- a/apps/ts.c
+++ b/apps/ts.c
@@ -66,15 +66,17 @@ static int save_ts_serial(const char *serialfile, ASN1_INTEGER *serial);
 /* Verify related functions. */
 static int verify_command(const char *data, const char *digest, const char *queryfile,
                           const char *in, int token_in,
-                          const char *CApath, const char *CAfile, const char *untrusted,
-                          X509_VERIFY_PARAM *vpm);
+                          const char *CApath, const char *CAfile,
+                          const char *CAstore,
+                          const char *untrusted, X509_VERIFY_PARAM *vpm);
 static TS_VERIFY_CTX *create_verify_ctx(const char *data, const char *digest,
                                         const char *queryfile,
                                         const char *CApath, const char *CAfile,
+                                        const char *CAstore,
                                         const char *untrusted,
                                         X509_VERIFY_PARAM *vpm);
 static X509_STORE *create_cert_store(const char *CApath, const char *CAfile,
-                                     X509_VERIFY_PARAM *vpm);
+                                     const char *CAstore, X509_VERIFY_PARAM *vpm);
 static int verify_cb(int ok, X509_STORE_CTX *ctx);
 
 typedef enum OPTION_choice {
@@ -83,7 +85,7 @@ typedef enum OPTION_choice {
     OPT_DIGEST, OPT_TSPOLICY, OPT_NO_NONCE, OPT_CERT,
     OPT_IN, OPT_TOKEN_IN, OPT_OUT, OPT_TOKEN_OUT, OPT_TEXT,
     OPT_REPLY, OPT_QUERYFILE, OPT_PASSIN, OPT_INKEY, OPT_SIGNER,
-    OPT_CHAIN, OPT_VERIFY, OPT_CAPATH, OPT_CAFILE, OPT_UNTRUSTED,
+    OPT_CHAIN, OPT_VERIFY, OPT_CAPATH, OPT_CAFILE, OPT_CASTORE, OPT_UNTRUSTED,
     OPT_MD, OPT_V_ENUM, OPT_R_ENUM
 } OPTION_CHOICE;
 
@@ -112,6 +114,7 @@ const OPTIONS ts_options[] = {
     {"verify", OPT_VERIFY, '-', "Verify a TS response"},
     {"CApath", OPT_CAPATH, '/', "Path to trusted CA files"},
     {"CAfile", OPT_CAFILE, '<', "File with trusted CA certs"},
+    {"CAstore", OPT_CASTORE, ':', "URI to trusted CA store"},
     {"untrusted", OPT_UNTRUSTED, '<', "File with untrusted certs"},
     {"", OPT_MD, '-', "Any supported digest"},
 # ifndef OPENSSL_NO_ENGINE
@@ -143,7 +146,7 @@ static char* opt_helplist[] = {
     "          [-text]",
 # endif
     "  or",
-    "ts -verify -CApath dir -CAfile file.pem -untrusted file.pem",
+    "ts -verify -CApath dir -CAfile file.pem -CAstore uri -untrusted file.pem",
     "           [-data file] [-digest hexstring]",
     "           [-queryfile file] -in file [-token_in]",
     "           [[options specific to 'ts -verify']]",
@@ -161,6 +164,7 @@ int ts_main(int argc, char **argv)
     char *data = NULL, *digest = NULL, *policy = NULL;
     char *in = NULL, *out = NULL, *queryfile = NULL, *passin = NULL;
     char *inkey = NULL, *signer = NULL, *chain = NULL, *CApath = NULL;
+    char *CAstore = NULL;
     const EVP_MD *md = NULL;
     OPTION_CHOICE o, mode = OPT_ERR;
     int ret = 1, no_nonce = 0, cert = 0, text = 0;
@@ -256,6 +260,9 @@ int ts_main(int argc, char **argv)
         case OPT_CAFILE:
             CAfile = opt_arg();
             break;
+        case OPT_CASTORE:
+            CAstore = opt_arg();
+            break;
         case OPT_UNTRUSTED:
             untrusted = opt_arg();
             break;
@@ -311,7 +318,7 @@ int ts_main(int argc, char **argv)
         if ((in == NULL) || !EXACTLY_ONE(queryfile, data, digest))
             goto opthelp;
         ret = !verify_command(data, digest, queryfile, in, token_in,
-                              CApath, CAfile, untrusted,
+                              CApath, CAfile, CAstore, untrusted,
                               vpmtouched ? vpm : NULL);
     } else {
         goto opthelp;
@@ -820,7 +827,8 @@ static int save_ts_serial(const char *serialfile, ASN1_INTEGER *serial)
 
 static int verify_command(const char *data, const char *digest, const char *queryfile,
                           const char *in, int token_in,
-                          const char *CApath, const char *CAfile, const char *untrusted,
+                          const char *CApath, const char *CAfile,
+                          const char *CAstore, const char *untrusted,
                           X509_VERIFY_PARAM *vpm)
 {
     BIO *in_bio = NULL;
@@ -840,7 +848,7 @@ static int verify_command(const char *data, const char *digest, const char *quer
     }
 
     if ((verify_ctx = create_verify_ctx(data, digest, queryfile,
-                                        CApath, CAfile, untrusted,
+                                        CApath, CAfile, CAstore, untrusted,
                                         vpm)) == NULL)
         goto end;
 
@@ -867,6 +875,7 @@ static int verify_command(const char *data, const char *digest, const char *quer
 static TS_VERIFY_CTX *create_verify_ctx(const char *data, const char *digest,
                                         const char *queryfile,
                                         const char *CApath, const char *CAfile,
+                                        const char *CAstore,
                                         const char *untrusted,
                                         X509_VERIFY_PARAM *vpm)
 {
@@ -915,7 +924,8 @@ static TS_VERIFY_CTX *create_verify_ctx(const char *data, const char *digest,
     TS_VERIFY_CTX_add_flags(ctx, f | TS_VFY_SIGNATURE);
 
     /* Initialising the X509_STORE object. */
-    if (TS_VERIFY_CTX_set_store(ctx, create_cert_store(CApath, CAfile, vpm))
+    if (TS_VERIFY_CTX_set_store(ctx,
+                                create_cert_store(CApath, CAfile, CAstore, vpm))
             == NULL)
         goto err;
 
@@ -936,11 +946,10 @@ static TS_VERIFY_CTX *create_verify_ctx(const char *data, const char *digest,
 }
 
 static X509_STORE *create_cert_store(const char *CApath, const char *CAfile,
-                                     X509_VERIFY_PARAM *vpm)
+                                     const char *CAstore, X509_VERIFY_PARAM *vpm)
 {
     X509_STORE *cert_ctx = NULL;
     X509_LOOKUP *lookup = NULL;
-    int i;
 
     cert_ctx = X509_STORE_new();
     X509_STORE_set_verify_cb(cert_ctx, verify_cb);
@@ -950,8 +959,7 @@ static X509_STORE *create_cert_store(const char *CApath, const char *CAfile,
             BIO_printf(bio_err, "memory allocation failure\n");
             goto err;
         }
-        i = X509_LOOKUP_add_dir(lookup, CApath, X509_FILETYPE_PEM);
-        if (!i) {
+        if (!X509_LOOKUP_add_dir(lookup, CApath, X509_FILETYPE_PEM)) {
             BIO_printf(bio_err, "Error loading directory %s\n", CApath);
             goto err;
         }
@@ -963,13 +971,24 @@ static X509_STORE *create_cert_store(const char *CApath, const char *CAfile,
             BIO_printf(bio_err, "memory allocation failure\n");
             goto err;
         }
-        i = X509_LOOKUP_load_file(lookup, CAfile, X509_FILETYPE_PEM);
-        if (!i) {
+        if (!X509_LOOKUP_load_file(lookup, CAfile, X509_FILETYPE_PEM)) {
             BIO_printf(bio_err, "Error loading file %s\n", CAfile);
             goto err;
         }
     }
 
+    if (CAstore != NULL) {
+        lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_store());
+        if (lookup == NULL) {
+            BIO_printf(bio_err, "memory allocation failure\n");
+            goto err;
+        }
+        if (!X509_LOOKUP_load_store(lookup, CAstore)) {
+            BIO_printf(bio_err, "Error loading store URI %s\n", CAstore);
+            goto err;
+        }
+    }
+
     if (vpm != NULL)
         X509_STORE_set1_param(cert_ctx, vpm);
 
index fd40764..7b18de2 100644 (file)
@@ -27,7 +27,8 @@ static int v_verbose = 0, vflags = 0;
 
 typedef enum OPTION_choice {
     OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
-    OPT_ENGINE, OPT_CAPATH, OPT_CAFILE, OPT_NOCAPATH, OPT_NOCAFILE,
+    OPT_ENGINE, OPT_CAPATH, OPT_CAFILE, OPT_CASTORE,
+    OPT_NOCAPATH, OPT_NOCAFILE, OPT_NOCASTORE,
     OPT_UNTRUSTED, OPT_TRUSTED, OPT_CRLFILE, OPT_CRL_DOWNLOAD, OPT_SHOW_CHAIN,
     OPT_V_ENUM, OPT_NAMEOPT,
     OPT_VERBOSE, OPT_SM2ID, OPT_SM2HEXID
@@ -41,10 +42,13 @@ const OPTIONS verify_options[] = {
         "Print extra information about the operations being performed."},
     {"CApath", OPT_CAPATH, '/', "A directory of trusted certificates"},
     {"CAfile", OPT_CAFILE, '<', "A file of trusted certificates"},
+    {"CAstore", OPT_CASTORE, ':', "URI to a store of trusted certificates"},
     {"no-CAfile", OPT_NOCAFILE, '-',
      "Do not load the default certificates file"},
     {"no-CApath", OPT_NOCAPATH, '-',
      "Do not load certificates from the default certificates directory"},
+    {"no-CAstore", OPT_NOCAPATH, '-',
+     "Do not load certificates from the default certificates store"},
     {"untrusted", OPT_UNTRUSTED, '<', "A file of untrusted certificates"},
     {"trusted", OPT_TRUSTED, '<', "A file of trusted certificates"},
     {"CRLfile", OPT_CRLFILE, '<',
@@ -74,8 +78,8 @@ int verify_main(int argc, char **argv)
     STACK_OF(X509_CRL) *crls = NULL;
     X509_STORE *store = NULL;
     X509_VERIFY_PARAM *vpm = NULL;
-    const char *prog, *CApath = NULL, *CAfile = NULL;
-    int noCApath = 0, noCAfile = 0;
+    const char *prog, *CApath = NULL, *CAfile = NULL, *CAstore = NULL;
+    int noCApath = 0, noCAfile = 0, noCAstore = 0;
     int vpmtouched = 0, crl_download = 0, show_chain = 0, i = 0, ret = 1;
     OPTION_CHOICE o;
     unsigned char *sm2_id = NULL;
@@ -123,12 +127,18 @@ int verify_main(int argc, char **argv)
         case OPT_CAFILE:
             CAfile = opt_arg();
             break;
+        case OPT_CASTORE:
+            CAstore = opt_arg();
+            break;
         case OPT_NOCAPATH:
             noCApath = 1;
             break;
         case OPT_NOCAFILE:
             noCAfile = 1;
             break;
+        case OPT_NOCASTORE:
+            noCAstore = 1;
+            break;
         case OPT_UNTRUSTED:
             /* Zero or more times */
             if (!load_certs(opt_arg(), &untrusted, FORMAT_PEM, NULL,
@@ -139,6 +149,7 @@ int verify_main(int argc, char **argv)
             /* Zero or more times */
             noCAfile = 1;
             noCApath = 1;
+            noCAstore = 1;
             if (!load_certs(opt_arg(), &trusted, FORMAT_PEM, NULL,
                             "trusted certificates"))
                 goto end;
@@ -195,14 +206,16 @@ int verify_main(int argc, char **argv)
     }
     argc = opt_num_rest();
     argv = opt_rest();
-    if (trusted != NULL && (CAfile || CApath)) {
+    if (trusted != NULL
+        && (CAfile != NULL || CApath != NULL || CAstore != NULL)) {
         BIO_printf(bio_err,
-                   "%s: Cannot use -trusted with -CAfile or -CApath\n",
+                   "%s: Cannot use -trusted with -CAfile, -CApath or -CAstore\n",
                    prog);
         goto end;
     }
 
-    if ((store = setup_verify(CAfile, CApath, noCAfile, noCApath)) == NULL)
+    if ((store = setup_verify(CAfile, noCAfile, CApath, noCApath,
+                              CAstore, noCAstore)) == NULL)
         goto end;
     X509_STORE_set_verify_cb(store, cb);
 
index 3d8bcd7..83eb4fd 100644 (file)
@@ -736,6 +736,10 @@ the list of permitted ciphers in a database and only use those.
 
 No revocation checking is done on the signer's certificate.
 
+=head1 SEE ALSO
+
+L<ossl_store-file(7)>
+
 =head1 HISTORY
 
 The use of multiple B<-signer> options and the B<-resign> command were first
index 7441de4..829c2a7 100644 (file)
@@ -120,7 +120,8 @@ and files too.
 L<openssl(1)>,
 L<openssl-crl2pkcs7(1)>,
 L<openssl-ca(1)>,
-L<openssl-x509(1)>
+L<openssl-x509(1)>,
+L<ossl_store-file(7)>
 
 =head1 COPYRIGHT
 
index a3358e7..e163430 100644 (file)
@@ -395,9 +395,9 @@ the OCSP request checked using the responder certificate's public key.
 
 Then a normal certificate verify is performed on the OCSP responder certificate
 building up a certificate chain in the process. The locations of the trusted
-certificates used to build the chain can be specified by the B<-CAfile>
-and B<-CApath> options or they will be looked for in the standard OpenSSL
-certificates directory.
+certificates used to build the chain can be specified by the B<-CAfile>,
+B<-CApath> or B<-CAstore> options or they will be looked for in the
+standard OpenSSL certificates directory.
 
 If the initial verify fails then the OCSP verify process halts with an
 error.
@@ -432,8 +432,8 @@ with the B<-VAfile> option.
 =head1 NOTES
 
 As noted, most of the verify options are for testing or debugging purposes.
-Normally only the B<-CApath>, B<-CAfile> and (if the responder is a 'global
-VA') B<-VAfile> options need to be used.
+Normally only the B<-CApath>, B<-CAfile>, B<-CAstore> and (if the responder
+is a 'global VA') B<-VAfile> options need to be used.
 
 The OCSP server is only useful for test and demonstration purposes: it is
 not really usable as a full OCSP responder. It contains only a very
index 09b7511..3eef9dc 100644 (file)
@@ -338,7 +338,8 @@ Include some extra certificates:
 =head1 SEE ALSO
 
 L<openssl(1)>,
-L<openssl-pkcs8(1)>
+L<openssl-pkcs8(1)>,
+L<ossl_store-file(7)>
 
 =head1 COPYRIGHT
 
index 9752407..005e12a 100644 (file)
@@ -35,6 +35,7 @@ B<openssl> B<s_client>
 [B<-pass> I<arg>]
 [B<-chainCApath> I<directory>]
 [B<-chainCAfile> I<filename>]
+[B<-chainCAstore> I<uri>]
 [B<-requestCAfile> I<filename>]
 [B<-dane_tlsa_domain> I<domain>]
 [B<-dane_tlsa_rrdata> I<rrdata>]
@@ -303,6 +304,10 @@ information.
 A file containing trusted certificates to use when attempting to build the
 client certificate chain.
 
+=item B<-chainCAstore> I<uri>
+
+The URI to use when attempting to build the client certificate chain.
+
 =item B<-requestCAfile> I<file>
 
 A file containing a list of certificates whose subject names will be sent
@@ -807,7 +812,8 @@ L<openssl-ciphers(1)>,
 L<SSL_CONF_cmd(3)>,
 L<SSL_CTX_set_max_send_fragment(3)>,
 L<SSL_CTX_set_split_send_fragment(3)>,
-L<SSL_CTX_set_max_pipelines(3)>
+L<SSL_CTX_set_max_pipelines(3)>,
+L<ossl_store-file(7)>
 
 =head1 HISTORY
 
index 6385166..9e1c1d3 100644 (file)
@@ -61,6 +61,8 @@ B<openssl> B<s_server>
 [B<-dcert_chain> I<infile>]
 [B<-chainCApath> I<dir>]
 [B<-verifyCApath> I<dir>]
+[B<-chainCAstore> I<uri>]
+[B<-verifyCAstore> I<uri>]
 [B<-no_cache>]
 [B<-ext_cache>]
 [B<-verify_return_error>]
@@ -369,6 +371,16 @@ information.
 A file containing trusted certificates to use when attempting to build the
 server certificate chain.
 
+=item B<-chainCAstore> I<uri>
+
+The URI to a store to use for building the chain provided to the client.
+The URI may indicate a single certificate, as well as a collection of
+them.
+With URIs in the C<file:> scheme, this acts as B<-chainCAfile> or
+B<-chainCApath>, depending on if the URI indicates a directory or a
+single file.
+See L<ossl_store-file(7)> for more information on the C<file:> scheme.
+
 =item B<-nocert>
 
 If this option is set then no certificate is used. This restricts the
@@ -810,7 +822,8 @@ L<openssl-ciphers(1)>,
 L<SSL_CONF_cmd(3)>,
 L<SSL_CTX_set_max_send_fragment(3)>,
 L<SSL_CTX_set_split_send_fragment(3)>,
-L<SSL_CTX_set_max_pipelines(3)>
+L<SSL_CTX_set_max_pipelines(3)>,
+L<ossl_store-file(7)>
 
 =head1 HISTORY
 
index 737424d..18e2431 100644 (file)
@@ -87,12 +87,6 @@ I<option> argument can be a single option or multiple options separated by
 commas.  Alternatively the B<-nameopt> switch may be used more than once to
 set multiple options. See the L<openssl-x509(1)> manual page for details.
 
-=item B<-CApath> I<directory>
-
-The directory to use for server certificate verification. This directory
-must be in "hash format", see L<openssl-verify(1)> for more information.
-These are also used when building the client certificate chain.
-
 =item B<-new>
 
 Performs the timing test using a new session ID for each connection.
@@ -193,7 +187,8 @@ fails.
 L<openssl(1)>,
 L<openssl-s_client(1)>,
 L<openssl-s_server(1)>,
-L<openssl-ciphers(1)>
+L<openssl-ciphers(1)>,
+L<ossl_store-file(7)>
 
 =head1 COPYRIGHT
 
index 4e07af3..0f1c9bd 100644 (file)
@@ -479,6 +479,10 @@ No revocation checking is done on the signer's certificate.
 The current code can only handle S/MIME v2 messages, the more complex S/MIME v3
 structures may cause parsing errors.
 
+=head1 SEE ALSO
+
+L<ossl_store-file(7)>
+
 =head1 HISTORY
 
 The use of multiple B<-signer> options and the B<-resign> command were first
index d9354b2..0357632 100644 (file)
@@ -52,6 +52,7 @@ B<-verify>
 [B<-token_in>]
 [B<-CApath> I<trusted_cert_path>]
 [B<-CAfile> I<trusted_certs.pem>]
+[B<-CAstore> I<trusted_certs_uri>]
 [B<-untrusted> I<cert_file.pem>]
 [I<verify options>]
 
@@ -352,10 +353,12 @@ This flag can be used together with the B<-in> option and indicates
 that the input is a DER encoded timestamp token (ContentInfo) instead
 of a timestamp response (TimeStampResp). (Optional)
 
-=item B<-CAfile> I<file>, B<-CApath> I<dir>
+=item B<-CAfile> I<file>, B<-CApath> I<dir>, B<-CAstore> I<uri>
 
 See L<openssl(1)/Trusted Certificate Options> for more information.
 
+At least one of B<-CApath>, B<-CAfile> or B<-CAstore> must be specified.
+
 =item B<-untrusted> I<cert_file.pem>
 
 Set of additional untrusted certificates in PEM format which may be
@@ -649,7 +652,8 @@ L<openssl-req(1)>,
 L<openssl-x509(1)>,
 L<openssl-ca(1)>,
 L<openssl-genrsa(1)>,
-L<config(5)>
+L<config(5)>,
+L<ossl_store-file(7)>
 
 =head1 COPYRIGHT
 
index 72ef98c..9a92cb6 100644 (file)
@@ -190,8 +190,8 @@ P-256 and P-384.
 =item B<-trusted_first>
 
 When constructing the certificate chain, use the trusted certificates specified
-via B<-CAfile>, B<-CApath> or B<-trusted> before any certificates specified via
-B<-untrusted>.
+via B<-CAfile>, B<-CApath>, B<-CAstore> or B<-trusted> before any certificates
+specified via B<-untrusted>.
 This can be useful in environments with Bridge or Cross-Certified CAs.
 As of OpenSSL 1.1.0 this option is on by default and cannot be disabled.
 
@@ -222,9 +222,9 @@ consulted.
 That is, the only trust-anchors are those listed in I<file>.
 This option can be specified more than once to include trusted certificates
 from multiple I<file>s.
-This option implies the B<-no-CAfile> and B<-no-CApath> options.
-This option cannot be used in combination with either of the B<-CAfile> or
-B<-CApath> options.
+This option implies the B<-no-CAfile>, B<-no-CApath> and B<-no-CAstore> options.
+This option cannot be used in combination with any of the B<-CAfile>,
+B<-CApath> or B<-CAstore> options.
 
 =item B<-use_deltas>
 
@@ -743,8 +743,9 @@ Although the issuer checks are a considerable improvement over the old
 technique they still suffer from limitations in the underlying X509_LOOKUP
 API. One consequence of this is that trusted certificates with matching
 subject name must either appear in a file (as specified by the B<-CAfile>
-option) or a directory (as specified by B<-CApath>). If they occur in
-both then only the certificates in the file will be recognised.
+option), a directory (as specified by B<-CApath>), or a store (as specified
+by B<-CAstore>). If they occur in more than one location then only the
+certificates in the file will be recognised.
 
 Previous versions of OpenSSL assume certificates with matching subject
 name are identical and mishandled them.
@@ -756,7 +757,8 @@ B<X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY> error codes.
 =head1 SEE ALSO
 
 L<openssl(1)>,
-L<openssl-x509(1)>
+L<openssl-x509(1)>,
+L<ossl_store-file(7)>
 
 =head1 HISTORY
 
index 3198f90..e13a696 100644 (file)
@@ -700,6 +700,23 @@ See L<openssl-rehash(1)> for information on creating this type of directory.
 
 Do not use the default directory of trusted certificates.
 
+=item B<-CAstore> I<uri>
+
+Use I<uri> as a store of trusted CA certificates.  The URI may
+indicate a single certificate, as well as a collection of them.
+With URIs in the C<file:> scheme, this acts as B<-CAfile> or
+B<-CApath>, depending on if the URI indicates a single file or
+directory.
+See L<ossl_store-file(7)> for more information on the C<file:> scheme.
+
+These certificates are also used when building the server certificate
+chain (for example with L<openssl-s_server(1)>) or client certificate
+chain (for example with L<openssl-s_time(1)>).
+
+=item B<-no-CAstore>
+
+Do not use the default store.
+
 =back
 
 =head2 Random State Options
index ca62ca5..da61f77 100644 (file)
@@ -82,9 +82,12 @@ $OpenSSL::safe::opt_trust_synopsis = ""
 . "[B<-CAfile> I<file>]\n"
 . "[B<-no-CAfile>]\n"
 . "[B<-CApath> I<dir>]\n"
-. "[B<-no-CApath>]";
+. "[B<-no-CApath>]\n"
+. "[B<-CAstore> I<uri>]\n"
+. "[B<-no-CAstore>]";
 $OpenSSL::safe::opt_trust_item = ""
-. "=item B<-CAfile> I<file>, B<-no-CAfile>, B<-CApath> I<dir>, B<-no-CApath>\n"
+. "=item B<-CAfile> I<file>, B<-no-CAfile>, B<-CApath> I<dir>, B<-no-CApath>,\n"
+. "B<-CAstore> I<uri>, B<-no-CAstore>\n"
 . "\n"
 . "See L<openssl(1)/Trusted Certificate Options> for details.";