Browse Source

Fix URI handling in SSL_CERT_DIR/introduce SSL_CERT_URI env

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)
Hugo Landau 2 years ago
parent
commit
021859bf81
6 changed files with 62 additions and 9 deletions
  1. 9 0
      CHANGES.md
  2. 11 5
      crypto/x509/by_dir.c
  3. 15 2
      crypto/x509/by_store.c
  4. 10 0
      crypto/x509/x509_def.c
  5. 15 2
      include/internal/common.h
  6. 2 0
      include/openssl/x509.h.in

+ 9 - 0
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
 -----------
 

+ 11 - 5
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);
             }

+ 15 - 2
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);

+ 10 - 0
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;

+ 15 - 2
include/internal/common.h

@@ -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

+ 2 - 0
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);