]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
SSL_CONF_FLAG: Prevent setting both CMDLINE and FILE flags
authorTommy Chiang <ototot@google.com>
Sun, 25 Jan 2026 13:12:28 +0000 (21:12 +0800)
committerTomas Mraz <tomas@openssl.org>
Tue, 3 Feb 2026 09:39:56 +0000 (10:39 +0100)
The `SSL_CONF_CTX_set_flags` function did not prevent setting both
`SSL_CONF_FLAG_CMDLINE` and `SSL_CONF_FLAG_FILE` flags, which is an
invalid combination. This commit adds a check to prevent this and
updates the documentation to clarify that only one of these flags
can be set.

A new test case is also added to verify the correct behavior.

Fixes https://github.com/openssl/openssl/issues/15508

Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Paul Dale <paul.dale@oracle.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
MergeDate: Tue Feb  3 09:40:04 2026
(Merged from https://github.com/openssl/openssl/pull/29752)

doc/man3/SSL_CONF_CTX_set_flags.pod
ssl/ssl_conf.c
test/sslapitest.c

index 78c3ce7585dc64bcb9a0c5308dfbc50e3a41ed55..117575e7d5f6a38a957d9156e39b24eb8115a51e 100644 (file)
@@ -28,8 +28,9 @@ Currently the following B<flags> values are recognised:
 
 =item SSL_CONF_FLAG_CMDLINE, SSL_CONF_FLAG_FILE
 
-recognise options intended for command line or configuration file use. At
-least one of these flags must be set.
+recognise options intended for command line or configuration file use. One of
+these flags, but not both, must be set. If an attempt is made to set one of
+these flags when the other is already set then the new flag is ignored.
 
 =item SSL_CONF_FLAG_CLIENT, SSL_CONF_FLAG_SERVER
 
index 0d61def3dd45084f2448673f6e768ef23d0979c9..f113d59c710d866d7a1f15ac543aae214a4a1a50 100644 (file)
@@ -1123,6 +1123,14 @@ void SSL_CONF_CTX_free(SSL_CONF_CTX *cctx)
 
 unsigned int SSL_CONF_CTX_set_flags(SSL_CONF_CTX *cctx, unsigned int flags)
 {
+    if ((cctx->flags & SSL_CONF_FLAG_CMDLINE)
+        && (flags & SSL_CONF_FLAG_FILE))
+        flags &= ~SSL_CONF_FLAG_FILE;
+
+    if ((cctx->flags & SSL_CONF_FLAG_FILE)
+        && (flags & SSL_CONF_FLAG_CMDLINE))
+        flags &= ~SSL_CONF_FLAG_CMDLINE;
+
     cctx->flags |= flags;
     return cctx->flags;
 }
index 30dc17ce3c14eae9996783742c1ed41d522287f9..1db7bddac36e4c50c876c29e96be9db1a660341f 100644 (file)
@@ -13843,6 +13843,66 @@ err:
 }
 #endif
 
+static int test_ssl_conf_flags(void)
+{
+    SSL_CONF_CTX *cctx = NULL;
+    int ret = 0;
+
+    if (!TEST_ptr(cctx = SSL_CONF_CTX_new()))
+        goto err;
+
+    /* Initial flags should be 0 */
+    if (!TEST_uint_eq(SSL_CONF_CTX_set_flags(cctx, 0), 0))
+        goto err;
+
+    /* Setting CMDLINE should succeed */
+    if (!TEST_uint_eq(SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CMDLINE),
+            SSL_CONF_FLAG_CMDLINE))
+        goto err;
+
+    /*
+     * Setting FILE when CMDLINE is set should fail to set the flag but return
+     * success (return the original flags value).
+     * If we also try to set a non-conflicting flag at the same time it should
+     * succeed.
+     */
+    if (!TEST_uint_eq(SSL_CONF_CTX_set_flags(cctx,
+                          SSL_CONF_FLAG_FILE
+                              | SSL_CONF_FLAG_SHOW_ERRORS),
+            SSL_CONF_FLAG_CMDLINE | SSL_CONF_FLAG_SHOW_ERRORS))
+        goto err;
+
+    SSL_CONF_CTX_free(cctx);
+    cctx = NULL;
+
+    /* Retry in reverse */
+    if (!TEST_ptr(cctx = SSL_CONF_CTX_new()))
+        goto err;
+
+    /* Setting FILE should succeed */
+    if (!TEST_uint_eq(SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_FILE),
+            SSL_CONF_FLAG_FILE))
+        goto err;
+
+    /*
+     * Setting CMDLINE when FILE is set should fail to set the flag but return
+     * success (return the original flags value)
+     * If we also try to set a non-conflicting flag at the same time it should
+     * succeed.
+     */
+    if (!TEST_uint_eq(SSL_CONF_CTX_set_flags(cctx,
+                          SSL_CONF_FLAG_CMDLINE
+                              | SSL_CONF_FLAG_SHOW_ERRORS),
+            SSL_CONF_FLAG_FILE | SSL_CONF_FLAG_SHOW_ERRORS))
+        goto err;
+
+    ret = 1;
+
+err:
+    SSL_CONF_CTX_free(cctx);
+    return ret;
+}
+
 /*
  * Test that SSL_CTX_set1_groups() when called with a list where the first
  * entry is unsupported, will send a key_share that uses the next usable entry.
@@ -14244,6 +14304,7 @@ int setup_tests(void)
         ADD_TEST(test_ssl_trace);
 #endif
     ADD_ALL_TESTS(test_ssl_set_groups_unsupported_keyshare, 2);
+    ADD_TEST(test_ssl_conf_flags);
     return 1;
 
 err: