Commit 59a62db65b for openssl.org
commit 59a62db65bd643ade3cbe1a2f74021c38ca9a2da
Author: Tommy Chiang <ototot@google.com>
Date: Sun Jan 25 21:12:28 2026 +0800
SSL_CONF_FLAG: Prevent setting both CMDLINE and FILE flags
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)
diff --git a/doc/man3/SSL_CONF_CTX_set_flags.pod b/doc/man3/SSL_CONF_CTX_set_flags.pod
index 78c3ce7585..117575e7d5 100644
--- a/doc/man3/SSL_CONF_CTX_set_flags.pod
+++ b/doc/man3/SSL_CONF_CTX_set_flags.pod
@@ -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
diff --git a/ssl/ssl_conf.c b/ssl/ssl_conf.c
index 0d61def3dd..f113d59c71 100644
--- a/ssl/ssl_conf.c
+++ b/ssl/ssl_conf.c
@@ -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;
}
diff --git a/test/sslapitest.c b/test/sslapitest.c
index 30dc17ce3c..1db7bddac3 100644
--- a/test/sslapitest.c
+++ b/test/sslapitest.c
@@ -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: