Fix URI handling in SSL_CERT_DIR/introduce SSL_CERT_URI env
authorHugo Landau <hlandau@openssl.org>
Fri, 8 Apr 2022 12:10:52 +0000 (13:10 +0100)
committerHugo Landau <hlandau@openssl.org>
Wed, 14 Sep 2022 13:10:10 +0000 (14:10 +0100)
Fixes #18068.

Reviewed-by: Richard Levitte <levitte@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/18070)

CHANGES.md
crypto/x509/by_dir.c
crypto/x509/by_store.c
crypto/x509/x509_def.c
include/internal/common.h
include/openssl/x509.h.in

index 27172e08a78a97598927887ae5e946a1dcab67b5..5a5bc9d91ff5f63125fa5fc8e5e8b326188532fb 100644 (file)
@@ -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
 -----------
 
index 3719e0fb240fdc28b0cfa327fa20880f70fb1ea2..e63686784dfa3b33c0bae953fe1e0825a74757b0 100644 (file)
@@ -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);
             }
index 81170b18682c8296ccbfb69c05196923b41da2df..8c7ae83fae70a4bac3ffa1c4164069a3a6d08da1 100644 (file)
@@ -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);
index b8bdcb4841950159b15533a683bb411b505c759c..a199cc86559d831a92287ced2b39d5405cd61934 100644 (file)
@@ -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;
index 3e21b1e59fd90a1e70eb0054f7d50e2a0341986b..d820f3e00db7be140cf8e6206de1509e9f077791 100644 (file)
@@ -13,8 +13,7 @@
 
 # include <stdlib.h>
 # include <string.h>
-
-# 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
index 92dd56e2e9cb59ffe21923f58135d75480ff9b3d..b7fcf91281c3d8608c595b3f45169721f9fb8327 100644 (file)
@@ -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);