From: Hugo Landau Date: Fri, 8 Apr 2022 12:10:52 +0000 (+0100) Subject: Fix URI handling in SSL_CERT_DIR/introduce SSL_CERT_URI env X-Git-Tag: openssl-3.2.0-alpha1~2086 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=021859bf810a3614758c2f4871b9cd7202fac9b2;p=thirdparty%2Fopenssl.git Fix URI handling in SSL_CERT_DIR/introduce SSL_CERT_URI env Fixes #18068. Reviewed-by: Richard Levitte Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/18070) --- diff --git a/CHANGES.md b/CHANGES.md index 27172e08a78..5a5bc9d91ff 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -179,6 +179,15 @@ OpenSSL 3.1 *Hugo Landau* + * The `SSL_CERT_URI` environment variable has been added, which can be used + to specify a default URI for certificate stores. Previously, the + `SSL_CERT_DIR` environment variable was used for this purpose, and could + accept either a URI or a delimiter-separated list of paths. This usage is now + deprecated; to specify a delimiter-separated list of paths, use + `SSL_CERT_DIR`, and to specify a URI, use `SSL_CERT_URI`. + + *Hugo Landau* + OpenSSL 3.0 ----------- diff --git a/crypto/x509/by_dir.c b/crypto/x509/by_dir.c index 3719e0fb240..e63686784df 100644 --- a/crypto/x509/by_dir.c +++ b/crypto/x509/by_dir.c @@ -90,11 +90,17 @@ static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl, if (argl == X509_FILETYPE_DEFAULT) { const char *dir = ossl_safe_getenv(X509_get_default_cert_dir_env()); - if (dir) - ret = add_cert_dir(ld, dir, X509_FILETYPE_PEM); - else - ret = add_cert_dir(ld, X509_get_default_cert_dir(), - X509_FILETYPE_PEM); + /* + * If SSL_CERT_DIR seems to specify a URI, don't process it as a + * directory. + */ + if (dir != NULL && ossl_is_uri(dir)) + return 0; + + if (dir == NULL) + dir = X509_get_default_cert_dir(); + + ret = add_cert_dir(ld, dir, X509_FILETYPE_PEM); if (!ret) { ERR_raise(ERR_LIB_X509, X509_R_LOADING_CERT_DIR); } diff --git a/crypto/x509/by_store.c b/crypto/x509/by_store.c index 81170b18682..8c7ae83fae7 100644 --- a/crypto/x509/by_store.c +++ b/crypto/x509/by_store.c @@ -111,11 +111,24 @@ static int by_store_ctrl_ex(X509_LOOKUP *ctx, int cmd, const char *argp, { switch (cmd) { case X509_L_ADD_STORE: - /* If no URI is given, use the default cert dir as default URI */ + /* First try the newer default cert URI envvar. */ if (argp == NULL) + argp = ossl_safe_getenv(X509_get_default_cert_uri_env()); + + /* If not set, see if we have a URI in the older cert dir envvar. */ + if (argp == NULL) { argp = ossl_safe_getenv(X509_get_default_cert_dir_env()); + if (argp != NULL && !ossl_is_uri(argp)) + argp = NULL; + } + + /* Fallback to default store URI. */ if (argp == NULL) - argp = X509_get_default_cert_dir(); + argp = X509_get_default_cert_uri(); + + /* No point adding an empty URI. */ + if (!*argp) + return 1; { STACK_OF(OPENSSL_STRING) *uris = X509_LOOKUP_get_method_data(ctx); diff --git a/crypto/x509/x509_def.c b/crypto/x509/x509_def.c index b8bdcb48419..a199cc86559 100644 --- a/crypto/x509/x509_def.c +++ b/crypto/x509/x509_def.c @@ -22,6 +22,11 @@ const char *X509_get_default_cert_area(void) return X509_CERT_AREA; } +const char *X509_get_default_cert_uri(void) +{ + return X509_CERT_URI; +} + const char *X509_get_default_cert_dir(void) { return X509_CERT_DIR; @@ -32,6 +37,11 @@ const char *X509_get_default_cert_file(void) return X509_CERT_FILE; } +const char *X509_get_default_cert_uri_env(void) +{ + return X509_CERT_URI_EVP; +} + const char *X509_get_default_cert_dir_env(void) { return X509_CERT_DIR_EVP; diff --git a/include/internal/common.h b/include/internal/common.h index 3e21b1e59fd..d820f3e00db 100644 --- a/include/internal/common.h +++ b/include/internal/common.h @@ -13,8 +13,7 @@ # include # include - -# include "internal/e_os.h" /* ossl_inline in many files */ +# include "internal/e_os.h" /* To get strncasecmp() on Windows */ # include "internal/nelem.h" #ifdef NDEBUG @@ -74,6 +73,9 @@ __owur static ossl_inline int ossl_assert_int(int expr, const char *exprstr, # define CTLOG_FILE "OSSL$DATAROOT:[000000]ct_log_list.cnf" # endif +#define X509_CERT_URI "" + +# define X509_CERT_URI_EVP "SSL_CERT_URI" # define X509_CERT_DIR_EVP "SSL_CERT_DIR" # define X509_CERT_FILE_EVP "SSL_CERT_FILE" # define CTLOG_FILE_EVP "CTLOG_FILE" @@ -112,4 +114,15 @@ static ossl_inline int ossl_is_absolute_path(const char *path) return path[0] == '/'; } +static ossl_inline int ossl_is_uri(const char *s) +{ + const char *x; + for (x=s; ossl_isalnum(*x); ++x); +#ifdef _WIN32 + if (x-s <= 1) + return 0; +#endif + return x > s && HAS_PREFIX(x, "://"); +} + #endif diff --git a/include/openssl/x509.h.in b/include/openssl/x509.h.in index 92dd56e2e9c..b7fcf91281c 100644 --- a/include/openssl/x509.h.in +++ b/include/openssl/x509.h.in @@ -491,8 +491,10 @@ ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s, ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj); const char *X509_get_default_cert_area(void); +const char *X509_get_default_cert_uri(void); const char *X509_get_default_cert_dir(void); const char *X509_get_default_cert_file(void); +const char *X509_get_default_cert_uri_env(void); const char *X509_get_default_cert_dir_env(void); const char *X509_get_default_cert_file_env(void); const char *X509_get_default_private_dir(void);