From: Richard Levitte Date: Thu, 7 Mar 2019 14:26:34 +0000 (+0100) Subject: Add -CAstore and similar to all openssl commands that have -CApath X-Git-Tag: openssl-3.0.0-alpha1~1036 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=fd3397fc47bfd92e7e33d88aa566cb0c8bd29330;p=oweals%2Fopenssl.git Add -CAstore and similar to all openssl commands that have -CApath Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/8442) --- diff --git a/apps/cms.c b/apps/cms.c index 0e0df5e052..468820f3cf 100644 --- a/apps/cms.c +++ b/apps/cms.c @@ -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) diff --git a/apps/crl.c b/apps/crl.c index d36b93ba64..f7f4fb7150 100644 --- a/apps/crl.c +++ b/apps/crl.c @@ -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) diff --git a/apps/include/apps.h b/apps/include/apps.h index 41db80740b..21a2a90544 100644 --- a/apps/include/apps.h +++ b/apps/include/apps.h @@ -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 diff --git a/apps/include/s_apps.h b/apps/include/s_apps.h index 4f976da0b2..1bbe5fe09d 100644 --- a/apps/include/s_apps.h +++ b/apps/include/s_apps.h @@ -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); diff --git a/apps/lib/apps.c b/apps/lib/apps.c index 73483d99f4..8b840bb2a1 100644 --- a/apps/lib/apps.c +++ b/apps/lib/apps.c @@ -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: diff --git a/apps/lib/opt.c b/apps/lib/opt.c index 44d2570ae7..98979fc2a1 100644 --- a/apps/lib/opt.c +++ b/apps/lib/opt.c @@ -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 '/': diff --git a/apps/lib/s_cb.c b/apps/lib/s_cb.c index 47b8afe9ef..7b81d60fe7 100644 --- a/apps/lib/s_cb.c +++ b/apps/lib/s_cb.c @@ -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); } diff --git a/apps/ocsp.c b/apps/ocsp.c index 71c6a56f2f..458c808634 100644 --- a/apps/ocsp.c +++ b/apps/ocsp.c @@ -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; } diff --git a/apps/pkcs12.c b/apps/pkcs12.c index a708064db1..781c3ad7ec 100644 --- a/apps/pkcs12.c +++ b/apps/pkcs12.c @@ -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; diff --git a/apps/s_client.c b/apps/s_client.c index 392ab02234..fa5cb95f68 100644 --- a/apps/s_client.c +++ b/apps/s_client.c @@ -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; } diff --git a/apps/s_server.c b/apps/s_server.c index 5f58ef68fe..03ff1b410e 100644 --- a/apps/s_server.c +++ b/apps/s_server.c @@ -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; } diff --git a/apps/s_time.c b/apps/s_time.c index f6dbfa0462..43bec59037 100644 --- a/apps/s_time.c +++ b/apps/s_time.c @@ -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; } diff --git a/apps/smime.c b/apps/smime.c index 0f99e0a5e9..26bd028bea 100644 --- a/apps/smime.c +++ b/apps/smime.c @@ -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) diff --git a/apps/ts.c b/apps/ts.c index b45c262789..9fdba649c1 100644 --- 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); diff --git a/apps/verify.c b/apps/verify.c index fd407646f5..7b18de2bab 100644 --- a/apps/verify.c +++ b/apps/verify.c @@ -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); diff --git a/doc/man1/openssl-cms.pod.in b/doc/man1/openssl-cms.pod.in index 3d8bcd792e..83eb4fdb57 100644 --- a/doc/man1/openssl-cms.pod.in +++ b/doc/man1/openssl-cms.pod.in @@ -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 + =head1 HISTORY The use of multiple B<-signer> options and the B<-resign> command were first diff --git a/doc/man1/openssl-crl.pod.in b/doc/man1/openssl-crl.pod.in index 7441de446c..829c2a7235 100644 --- a/doc/man1/openssl-crl.pod.in +++ b/doc/man1/openssl-crl.pod.in @@ -120,7 +120,8 @@ and files too. L, L, L, -L +L, +L =head1 COPYRIGHT diff --git a/doc/man1/openssl-ocsp.pod.in b/doc/man1/openssl-ocsp.pod.in index a3358e724a..e1634301a2 100644 --- a/doc/man1/openssl-ocsp.pod.in +++ b/doc/man1/openssl-ocsp.pod.in @@ -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 diff --git a/doc/man1/openssl-pkcs12.pod.in b/doc/man1/openssl-pkcs12.pod.in index 09b75111db..3eef9dc856 100644 --- a/doc/man1/openssl-pkcs12.pod.in +++ b/doc/man1/openssl-pkcs12.pod.in @@ -338,7 +338,8 @@ Include some extra certificates: =head1 SEE ALSO L, -L +L, +L =head1 COPYRIGHT diff --git a/doc/man1/openssl-s_client.pod.in b/doc/man1/openssl-s_client.pod.in index 9752407a82..005e12ab2d 100644 --- a/doc/man1/openssl-s_client.pod.in +++ b/doc/man1/openssl-s_client.pod.in @@ -35,6 +35,7 @@ B B [B<-pass> I] [B<-chainCApath> I] [B<-chainCAfile> I] +[B<-chainCAstore> I] [B<-requestCAfile> I] [B<-dane_tlsa_domain> I] [B<-dane_tlsa_rrdata> I] @@ -303,6 +304,10 @@ information. A file containing trusted certificates to use when attempting to build the client certificate chain. +=item B<-chainCAstore> I + +The URI to use when attempting to build the client certificate chain. + =item B<-requestCAfile> I A file containing a list of certificates whose subject names will be sent @@ -807,7 +812,8 @@ L, L, L, L, -L +L, +L =head1 HISTORY diff --git a/doc/man1/openssl-s_server.pod.in b/doc/man1/openssl-s_server.pod.in index 638516695f..9e1c1d3e0e 100644 --- a/doc/man1/openssl-s_server.pod.in +++ b/doc/man1/openssl-s_server.pod.in @@ -61,6 +61,8 @@ B B [B<-dcert_chain> I] [B<-chainCApath> I] [B<-verifyCApath> I] +[B<-chainCAstore> I] +[B<-verifyCAstore> I] [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 + +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 scheme, this acts as B<-chainCAfile> or +B<-chainCApath>, depending on if the URI indicates a directory or a +single file. +See L for more information on the C scheme. + =item B<-nocert> If this option is set then no certificate is used. This restricts the @@ -810,7 +822,8 @@ L, L, L, L, -L +L, +L =head1 HISTORY diff --git a/doc/man1/openssl-s_time.pod.in b/doc/man1/openssl-s_time.pod.in index 737424da87..18e243146e 100644 --- a/doc/man1/openssl-s_time.pod.in +++ b/doc/man1/openssl-s_time.pod.in @@ -87,12 +87,6 @@ I