From: Tommy Chiang Date: Sun, 25 Jan 2026 13:12:28 +0000 (+0800) Subject: SSL_CONF_FLAG: Prevent setting both CMDLINE and FILE flags X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=59a62db65bd643ade3cbe1a2f74021c38ca9a2da;p=thirdparty%2Fopenssl.git 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 Reviewed-by: Paul Dale Reviewed-by: Tomas Mraz 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 78c3ce7585d..117575e7d5f 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 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 0d61def3dd4..f113d59c710 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 30dc17ce3c1..1db7bddac36 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: