Commit ca20e54e86 for openssl.org

commit ca20e54e86743b0eacc19e8f8042ec630746b85f
Author: Igor Ustinov <igus68@gmail.com>
Date:   Wed Jan 14 14:44:00 2026 +0100

    SSL_CTX_is_server() was added.

    Reviewed-by: Matt Caswell <matt@openssl.org>
    Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
    Reviewed-by: Paul Dale <paul.dale@oracle.com>
    Reviewed-by: Tim Hudson <tjh@openssl.org>
    Reviewed-by: Tomas Mraz <tomas@openssl.org>
    MergeDate: Fri Jan 16 13:19:25 2026
    (Merged from https://github.com/openssl/openssl/pull/29635)

diff --git a/CHANGES.md b/CHANGES.md
index 9b46ca53aa..067a2b0752 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -352,6 +352,10 @@ OpenSSL 3.6

    *Dimitri John Ledkov*

+ * SSL_CTX_is_server() was added.
+
+   *Igor Ustinov*
+
 OpenSSL 3.5
 -----------

diff --git a/doc/man3/SSL_get_version.pod b/doc/man3/SSL_get_version.pod
index 2412cbd1c2..cb729668b6 100644
--- a/doc/man3/SSL_get_version.pod
+++ b/doc/man3/SSL_get_version.pod
@@ -3,7 +3,8 @@
 =head1 NAME

 SSL_client_version, SSL_get_version, SSL_is_dtls, SSL_is_tls, SSL_is_quic,
-SSL_CTX_is_quic, SSL_version - get the protocol information of a connection
+SSL_CTX_is_quic, SSL_CTX_is_server, SSL_version - get the protocol information
+of a connection

 =head1 SYNOPSIS

@@ -17,6 +18,7 @@ SSL_CTX_is_quic, SSL_version - get the protocol information of a connection
  int SSL_is_tls(const SSL *ssl);
  int SSL_is_quic(const SSL *ssl);
  int SSL_CTX_is_quic(const SSL_CTX *ctx);
+ int SSL_CTX_is_server(const SSL_CTX *ctx);

  int SSL_version(const SSL *s);

@@ -41,6 +43,9 @@ SSL_is_quic() returns 1 if the connection is using QUIC or 0 if not.

 SSL_CTX_is_quic() returns 1 if the ctx creates QUIC SSL objects or 0 if not.

+SSL_CTX_is_server() returns 1 if the ctx uses a I<method> that allows it to be
+a server (i.e. server-only or generic method) or 0 if not.
+
 =head1 RETURN VALUES


@@ -143,7 +148,8 @@ L<ssl(7)>
 The SSL_is_dtls() function was added in OpenSSL 1.1.0. The SSL_is_tls() and
 SSL_is_quic() functions were added in OpenSSL 3.2.

-The SSL_CTX_is_quic() function was added in OpenSSL 4.0
+The SSL_CTX_is_quic() and SSL_CTX_is_server() functions were added in
+OpenSSL 4.0

 =head1 COPYRIGHT

diff --git a/include/openssl/ssl.h.in b/include/openssl/ssl.h.in
index 61e7ce67ef..7882b8bc67 100644
--- a/include/openssl/ssl.h.in
+++ b/include/openssl/ssl.h.in
@@ -1831,6 +1831,7 @@ int SSL_is_dtls(const SSL *s);
 int SSL_is_tls(const SSL *s);
 int SSL_is_quic(const SSL *s);
 int SSL_CTX_is_quic(const SSL_CTX *c);
+int SSL_CTX_is_server(const SSL_CTX *c);

 __owur int SSL_set_session_id_context(SSL *ssl, const unsigned char *sid_ctx,
     unsigned int sid_ctx_len);
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 2bafe473fb..e82ac8c040 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -1008,6 +1008,13 @@ int SSL_CTX_is_quic(const SSL_CTX *c)
     return IS_QUIC_CTX(c);
 }

+int SSL_CTX_is_server(const SSL_CTX *c)
+{
+    if (c == NULL || c->method == NULL)
+        return 0;
+    return (c->method->ssl_accept == ssl_undefined_function) ? 0 : 1;
+}
+
 int SSL_up_ref(SSL *s)
 {
     int i;
diff --git a/test/sslapitest.c b/test/sslapitest.c
index 6c13b8e226..efc3a863b3 100644
--- a/test/sslapitest.c
+++ b/test/sslapitest.c
@@ -12181,6 +12181,34 @@ end:
     return testresult;
 }

+/*
+ * Test that SSL_CTX_is_server returns the expected results.
+ */
+static int test_ssl_ctx_is_server(void)
+{
+    int testresult = 0;
+    SSL_CTX *cctx = NULL, *sctx = NULL, *gctx = NULL;
+
+    cctx = SSL_CTX_new_ex(libctx, NULL, TLS_client_method());
+    sctx = SSL_CTX_new_ex(libctx, NULL, TLS_server_method());
+    gctx = SSL_CTX_new_ex(libctx, NULL, TLS_method());
+
+    if (!TEST_ptr(cctx) || !TEST_ptr(sctx) || !TEST_ptr(gctx))
+        goto end;
+
+    if (!TEST_false(SSL_CTX_is_server(cctx))
+        || !TEST_true(SSL_CTX_is_server(sctx))
+        || !TEST_true(SSL_CTX_is_server(gctx)))
+        goto end;
+
+    testresult = 1;
+end:
+    SSL_CTX_free(cctx);
+    SSL_CTX_free(sctx);
+    SSL_CTX_free(gctx);
+    return testresult;
+}
+
 /*
  * Test that the SSL_rstate_string*() APIs return sane results
  */
@@ -14070,6 +14098,7 @@ int setup_tests(void)
     ADD_ALL_TESTS(test_serverinfo_custom, 4);
 #endif
     ADD_ALL_TESTS(test_version, 6);
+    ADD_TEST(test_ssl_ctx_is_server);
     ADD_TEST(test_rstate_string);
     ADD_ALL_TESTS(test_handshake_retry, 16);
     ADD_TEST(test_data_retry);
diff --git a/util/libssl.num b/util/libssl.num
index c657d5ee61..d43e75f4d5 100644
--- a/util/libssl.num
+++ b/util/libssl.num
@@ -606,5 +606,6 @@ SSL_set_quic_tls_cbs                    ?	4_0_0	EXIST::FUNCTION:
 SSL_set_quic_tls_transport_params       ?	4_0_0	EXIST::FUNCTION:
 SSL_set_quic_tls_early_data_enabled     ?	4_0_0	EXIST::FUNCTION:
 SSL_CTX_is_quic                         ?	4_0_0	EXIST::FUNCTION:
+SSL_CTX_is_server                       ?	4_0_0	EXIST::FUNCTION:
 OSSL_QUIC_method                        ?	4_0_0	EXIST::FUNCTION:QUIC
 SSL_listen_ex                           ?	4_0_0	EXIST::FUNCTION: