From e33598335c4e4a8162a37b41d0965181b456ec1c Mon Sep 17 00:00:00 2001 From: HTHou Date: Fri, 5 Jun 2026 18:44:03 +0800 Subject: [PATCH 01/13] Add generic SSL TLS configuration support --- .../org/apache/iotdb/rest/RestService.java | 24 + .../org/apache/iotdb/cli/AbstractCli.java | 32 ++ .../main/java/org/apache/iotdb/cli/Cli.java | 8 + .../apache/iotdb/tool/common/Constants.java | 8 + .../apache/iotdb/tool/common/OptionsUtil.java | 20 + .../iotdb/tool/data/AbstractDataTool.java | 51 +++ .../iotdb/tool/data/ExportDataTable.java | 3 +- .../iotdb/tool/data/ExportDataTree.java | 3 +- .../iotdb/tool/data/ImportDataTable.java | 3 +- .../iotdb/tool/data/ImportDataTree.java | 3 +- .../iotdb/tool/schema/AbstractSchemaTool.java | 39 ++ .../iotdb/tool/schema/ExportSchemaTable.java | 3 +- .../iotdb/tool/schema/ExportSchemaTree.java | 3 +- .../iotdb/tool/schema/ImportSchemaTable.java | 3 +- .../iotdb/tool/schema/ImportSchemaTree.java | 3 +- .../apache/iotdb/isession/SessionConfig.java | 4 + .../java/org/apache/iotdb/jdbc/Config.java | 8 + .../apache/iotdb/jdbc/IoTDBConnection.java | 6 +- .../iotdb/jdbc/IoTDBConnectionParams.java | 18 + .../java/org/apache/iotdb/jdbc/Utils.java | 8 + .../java/org/apache/iotdb/jdbc/UtilsTest.java | 14 + .../iotdb/rpc/BaseRpcTransportFactory.java | 49 +- .../org/apache/iotdb/rpc/RpcSslUtils.java | 422 ++++++++++++++++++ .../iotdb/session/AbstractSessionBuilder.java | 2 + .../apache/iotdb/session/NodesSupplier.java | 12 + .../org/apache/iotdb/session/Session.java | 16 + .../iotdb/session/SessionConnection.java | 38 +- .../iotdb/session/TableSessionBuilder.java | 24 + .../iotdb/session/ThriftConnection.java | 8 +- .../iotdb/session/pool/SessionPool.java | 25 ++ .../session/pool/TableSessionPoolBuilder.java | 24 + .../iotdb/consensus/ratis/utils/Utils.java | 30 +- .../db/conf/rest/IoTDBRestServiceConfig.java | 22 + .../conf/rest/IoTDBRestServiceDescriptor.java | 3 + .../conf/iotdb-system.properties.template | 20 + .../iotdb/commons/conf/CommonConfig.java | 33 ++ .../iotdb/commons/conf/CommonDescriptor.java | 12 + .../service/AbstractThriftServiceThread.java | 52 +-- 38 files changed, 954 insertions(+), 102 deletions(-) create mode 100644 iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/RpcSslUtils.java diff --git a/external-service-impl/rest/src/main/java/org/apache/iotdb/rest/RestService.java b/external-service-impl/rest/src/main/java/org/apache/iotdb/rest/RestService.java index 2e072d87961c0..85d0ee4476aca 100644 --- a/external-service-impl/rest/src/main/java/org/apache/iotdb/rest/RestService.java +++ b/external-service-impl/rest/src/main/java/org/apache/iotdb/rest/RestService.java @@ -21,6 +21,7 @@ import org.apache.iotdb.externalservice.api.IExternalService; import org.apache.iotdb.rest.i18n.RestMessages; import org.apache.iotdb.rest.protocol.filter.ApiOriginFilter; +import org.apache.iotdb.rpc.RpcSslUtils; import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.server.HttpConfiguration; @@ -52,6 +53,8 @@ private void startSSL( String trustStorePath, String keyStorePwd, String trustStorePwd, + String sslProtocol, + String sslProviderClass, int idleTime, boolean clientAuth) { server = new Server(); @@ -61,6 +64,7 @@ private void startSSL( httpsConfig.addCustomizer(new SecureRequestCustomizer()); SslContextFactory.Server sslContextFactory = new SslContextFactory.Server(); + configureSSL(sslContextFactory, sslProtocol, sslProviderClass); sslContextFactory.setKeyStorePath(keyStorePath); sslContextFactory.setKeyStorePassword(keyStorePwd); if (clientAuth) { @@ -125,6 +129,8 @@ public void start() { config.getTrustStorePath(), config.getKeyStorePwd(), config.getTrustStorePwd(), + config.getSslProtocol(), + config.getSslProviderClass(), config.getIdleTimeoutInSeconds(), config.isClientAuth()); } else { @@ -142,4 +148,22 @@ public void stop() { server.destroy(); } } + + private void configureSSL( + SslContextFactory.Server sslContextFactory, String sslProtocol, String sslProviderClass) { + String protocol = trimToEmpty(sslProtocol); + try { + RpcSslUtils.ensureProvider(protocol, sslProviderClass); + } catch (Exception e) { + throw new IllegalArgumentException("Failed to initialize SSL provider for REST service", e); + } + if (!protocol.isEmpty()) { + sslContextFactory.setProtocol(protocol); + sslContextFactory.setIncludeProtocols(protocol); + } + } + + private String trimToEmpty(String value) { + return value == null ? "" : value.trim(); + } } diff --git a/iotdb-client/cli/src/main/java/org/apache/iotdb/cli/AbstractCli.java b/iotdb-client/cli/src/main/java/org/apache/iotdb/cli/AbstractCli.java index 22ecdc3a40ed1..1f079450f5a54 100644 --- a/iotdb-client/cli/src/main/java/org/apache/iotdb/cli/AbstractCli.java +++ b/iotdb-client/cli/src/main/java/org/apache/iotdb/cli/AbstractCli.java @@ -77,12 +77,18 @@ public abstract class AbstractCli { static final String TRUST_STORE_PWD_ARGS = "tpw"; + static final String SSL_PROTOCOL_ARGS = "ssl_protocol"; + + static final String SSL_PROVIDER_CLASS_ARGS = "ssl_provider_class"; + private static final String EXECUTE_NAME = "execute"; private static final String USE_SSL = "use_ssl"; private static final String TRUST_STORE = "trust_store"; private static final String TRUST_STORE_PWD = "trust_store_pwd"; + private static final String SSL_PROTOCOL = "ssl_protocol"; + private static final String SSL_PROVIDER_CLASS = "ssl_provider_class"; private static final String NULL = "null"; static final int CODE_OK = 0; @@ -132,6 +138,10 @@ public abstract class AbstractCli { static String trustStore; // TODO: Make non-static static String trustStorePwd; + // TODO: Make non-static + static String sslProtocol; + // TODO: Make non-static + static String sslProviderClass; static String execute; static boolean hasExecuteSQL = false; @@ -156,6 +166,10 @@ static void init() { keywordSet.add("-" + USE_SSL_ARGS); keywordSet.add("-" + TRUST_STORE_ARGS); keywordSet.add("-" + TRUST_STORE_PWD_ARGS); + keywordSet.add("-" + SSL_PROTOCOL_ARGS); + keywordSet.add("--" + SSL_PROTOCOL_ARGS); + keywordSet.add("-" + SSL_PROVIDER_CLASS_ARGS); + keywordSet.add("--" + SSL_PROVIDER_CLASS_ARGS); keywordSet.add("-" + EXECUTE_ARGS); keywordSet.add("-" + ISO8601_ARGS); keywordSet.add("-" + RPC_COMPRESS_ARGS); @@ -214,6 +228,24 @@ static Options createOptions() { .build(); options.addOption(useSSL); + Option sslProtocol = + Option.builder(SSL_PROTOCOL_ARGS) + .longOpt(SSL_PROTOCOL) + .argName(SSL_PROTOCOL) + .hasArg() + .desc("SSL protocol. (optional)") + .build(); + options.addOption(sslProtocol); + + Option sslProviderClass = + Option.builder(SSL_PROVIDER_CLASS_ARGS) + .longOpt(SSL_PROVIDER_CLASS) + .argName(SSL_PROVIDER_CLASS) + .hasArg() + .desc("JSSE provider class for SSL. (optional)") + .build(); + options.addOption(sslProviderClass); + Option execute = Option.builder(EXECUTE_ARGS) .argName(EXECUTE_NAME) diff --git a/iotdb-client/cli/src/main/java/org/apache/iotdb/cli/Cli.java b/iotdb-client/cli/src/main/java/org/apache/iotdb/cli/Cli.java index d1bbd6165f694..f4e3e6bdfddf5 100644 --- a/iotdb-client/cli/src/main/java/org/apache/iotdb/cli/Cli.java +++ b/iotdb-client/cli/src/main/java/org/apache/iotdb/cli/Cli.java @@ -111,6 +111,12 @@ private static void constructProperties() { info.setProperty("use_ssl", useSsl); info.setProperty("trust_store", trustStore); info.setProperty("trust_store_pwd", trustStorePwd); + if (sslProtocol != null) { + info.setProperty(Config.SSL_PROTOCOL, sslProtocol); + } + if (sslProviderClass != null) { + info.setProperty(Config.SSL_PROVIDER_CLASS, sslProviderClass); + } } info.setProperty("user", username); info.setProperty("password", password); @@ -159,6 +165,8 @@ private static boolean parseCommandLine( private static void serve(CliContext ctx) { try { useSsl = commandLine.getOptionValue(USE_SSL_ARGS); + sslProtocol = commandLine.getOptionValue(SSL_PROTOCOL_ARGS); + sslProviderClass = commandLine.getOptionValue(SSL_PROVIDER_CLASS_ARGS); if (Boolean.parseBoolean(useSsl)) { trustStore = ctx.getLineReader().readLine("please input your trust_store:", '\0'); trustStorePwd = ctx.getLineReader().readLine("please input your trust_store_pwd:", '\0'); diff --git a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/common/Constants.java b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/common/Constants.java index 0d4c5f218b73b..56c34dbdf0387 100644 --- a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/common/Constants.java +++ b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/common/Constants.java @@ -68,6 +68,14 @@ public class Constants { public static final String TRUST_STORE_PWD_NAME = "trust_store_password"; public static final String TRUST_STORE_PWD_DESC = "Trust store password. (optional)"; + public static final String SSL_PROTOCOL_ARGS = "ssl_protocol"; + public static final String SSL_PROTOCOL_NAME = "ssl_protocol"; + public static final String SSL_PROTOCOL_DESC = "SSL protocol. (optional)"; + + public static final String SSL_PROVIDER_CLASS_ARGS = "ssl_provider_class"; + public static final String SSL_PROVIDER_CLASS_NAME = "ssl_provider_class"; + public static final String SSL_PROVIDER_CLASS_DESC = "JSSE provider class for SSL. (optional)"; + public static final String FILE_TYPE_ARGS = "ft"; public static final String FILE_TYPE_NAME = "file_type"; public static final String FILE_TYPE_ARGS_NAME = "format"; diff --git a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/common/OptionsUtil.java b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/common/OptionsUtil.java index b60809eba636a..acbac88afbed6 100644 --- a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/common/OptionsUtil.java +++ b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/common/OptionsUtil.java @@ -133,6 +133,26 @@ public static Options createCommonOptions(Options options) { .build(); options.addOption(opTrustStorePwd); + Option opSslProtocol = + Option.builder(SSL_PROTOCOL_ARGS) + .longOpt(SSL_PROTOCOL_NAME) + .optionalArg(true) + .argName(SSL_PROTOCOL_NAME) + .hasArg() + .desc(SSL_PROTOCOL_DESC) + .build(); + options.addOption(opSslProtocol); + + Option opSslProviderClass = + Option.builder(SSL_PROVIDER_CLASS_ARGS) + .longOpt(SSL_PROVIDER_CLASS_NAME) + .optionalArg(true) + .argName(SSL_PROVIDER_CLASS_NAME) + .hasArg() + .desc(SSL_PROVIDER_CLASS_DESC) + .build(); + options.addOption(opSslProviderClass); + return options; } diff --git a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/AbstractDataTool.java b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/AbstractDataTool.java index 4ef95c78eda14..5a9b14f333715 100644 --- a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/AbstractDataTool.java +++ b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/AbstractDataTool.java @@ -34,6 +34,9 @@ import org.apache.iotdb.rpc.IoTDBConnectionException; import org.apache.iotdb.rpc.StatementExecutionException; import org.apache.iotdb.session.Session; +import org.apache.iotdb.session.TableSessionBuilder; +import org.apache.iotdb.session.pool.SessionPool; +import org.apache.iotdb.session.pool.TableSessionPoolBuilder; import org.apache.iotdb.tool.common.Constants; import org.apache.iotdb.tool.common.ImportTsFileOperation; @@ -94,6 +97,8 @@ public abstract class AbstractDataTool { protected static Boolean useSsl; protected static String trustStore; protected static String trustStorePwd; + protected static String sslProtocol; + protected static String sslProviderClass; protected static Boolean aligned; protected static String database; protected static String startTime; @@ -134,6 +139,50 @@ public abstract class AbstractDataTool { protected AbstractDataTool() {} + protected static Session.Builder configureSsl(Session.Builder builder) { + builder.useSSL(true).trustStore(trustStore).trustStorePwd(trustStorePwd); + if (sslProtocol != null) { + builder.sslProtocol(sslProtocol); + } + if (sslProviderClass != null) { + builder.sslProviderClass(sslProviderClass); + } + return builder; + } + + protected static SessionPool.Builder configureSsl(SessionPool.Builder builder) { + builder.useSSL(true).trustStore(trustStore).trustStorePwd(trustStorePwd); + if (sslProtocol != null) { + builder.sslProtocol(sslProtocol); + } + if (sslProviderClass != null) { + builder.sslProviderClass(sslProviderClass); + } + return builder; + } + + protected static TableSessionBuilder configureSsl(TableSessionBuilder builder) { + builder.useSSL(true).trustStore(trustStore).trustStorePwd(trustStorePwd); + if (sslProtocol != null) { + builder.sslProtocol(sslProtocol); + } + if (sslProviderClass != null) { + builder.sslProviderClass(sslProviderClass); + } + return builder; + } + + protected static TableSessionPoolBuilder configureSsl(TableSessionPoolBuilder builder) { + builder.useSSL(true).trustStore(trustStore).trustStorePwd(trustStorePwd); + if (sslProtocol != null) { + builder.sslProtocol(sslProtocol); + } + if (sslProviderClass != null) { + builder.sslProviderClass(sslProviderClass); + } + return builder; + } + protected static String checkRequiredArg( String arg, String name, CommandLine commandLine, String defaultValue) throws ArgsErrorException { @@ -170,6 +219,8 @@ protected static void parseBasicParams(CommandLine commandLine) String useSslStr = commandLine.getOptionValue(Constants.USE_SSL_ARGS); useSsl = Boolean.parseBoolean(useSslStr); if (useSsl) { + sslProtocol = commandLine.getOptionValue(Constants.SSL_PROTOCOL_ARGS); + sslProviderClass = commandLine.getOptionValue(Constants.SSL_PROVIDER_CLASS_ARGS); String givenTS = commandLine.getOptionValue(Constants.TRUST_STORE_ARGS); if (givenTS != null) { trustStore = givenTS; diff --git a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/ExportDataTable.java b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/ExportDataTable.java index dcf05baa14e66..458c447ba4f5b 100644 --- a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/ExportDataTable.java +++ b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/ExportDataTable.java @@ -71,8 +71,7 @@ public void init() throws IoTDBConnectionException, StatementExecutionException .database(database) .thriftMaxFrameSize(rpcMaxFrameSize); if (useSsl) { - tableSessionBuilder = - tableSessionBuilder.useSSL(true).trustStore(trustStore).trustStorePwd(trustStorePwd); + tableSessionBuilder = configureSsl(tableSessionBuilder); } tableSession = tableSessionBuilder.build(); SessionDataSet sessionDataSet = tableSession.executeQueryStatement("show databases", timeout); diff --git a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/ExportDataTree.java b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/ExportDataTree.java index 9d7d0ca521d09..fd8aeb0cbe352 100644 --- a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/ExportDataTree.java +++ b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/ExportDataTree.java @@ -80,8 +80,7 @@ public void init() throws IoTDBConnectionException, StatementExecutionException, .enableRedirection(SessionConfig.DEFAULT_REDIRECTION_MODE) .version(SessionConfig.DEFAULT_VERSION); if (useSsl) { - sessionBuilder = - sessionBuilder.useSSL(true).trustStore(trustStore).trustStorePwd(trustStorePwd); + sessionBuilder = configureSsl(sessionBuilder); } session = sessionBuilder.build(); session.open(false); diff --git a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/ImportDataTable.java b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/ImportDataTable.java index 506da8b8e17ce..d103c63555b67 100644 --- a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/ImportDataTable.java +++ b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/ImportDataTable.java @@ -88,8 +88,7 @@ public void init() throws InterruptedException { .enableAutoFetch(false) .database(database); if (useSsl) { - tableSessionPoolBuilder = - tableSessionPoolBuilder.useSSL(true).trustStore(trustStore).trustStorePwd(trustStorePwd); + tableSessionPoolBuilder = configureSsl(tableSessionPoolBuilder); } sessionPool = tableSessionPoolBuilder.build(); final File file = new File(targetPath); diff --git a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/ImportDataTree.java b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/ImportDataTree.java index 95aa92631422a..c976e847740d2 100644 --- a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/ImportDataTree.java +++ b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/ImportDataTree.java @@ -72,8 +72,7 @@ public void init() .enableRedirection(false) .enableAutoFetch(false); if (useSsl) { - sessionPoolBuilder = - sessionPoolBuilder.useSSL(true).trustStore(trustStore).trustStorePwd(trustStorePwd); + sessionPoolBuilder = configureSsl(sessionPoolBuilder); } sessionPool = sessionPoolBuilder.build(); sessionPool.setEnableQueryRedirection(false); diff --git a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/schema/AbstractSchemaTool.java b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/schema/AbstractSchemaTool.java index 09442bdab878f..7a18b84f559e7 100644 --- a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/schema/AbstractSchemaTool.java +++ b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/schema/AbstractSchemaTool.java @@ -25,6 +25,8 @@ import org.apache.iotdb.cli.utils.JlineUtils; import org.apache.iotdb.exception.ArgsErrorException; import org.apache.iotdb.session.Session; +import org.apache.iotdb.session.pool.SessionPool; +import org.apache.iotdb.session.pool.TableSessionPoolBuilder; import org.apache.iotdb.tool.common.Constants; import org.apache.commons.cli.CommandLine; @@ -53,6 +55,8 @@ public abstract class AbstractSchemaTool { protected static Boolean useSsl; protected static String trustStore; protected static String trustStorePwd; + protected static String sslProtocol; + protected static String sslProviderClass; protected static Session session; protected static String queryPath; protected static int threadNum = 8; @@ -73,6 +77,39 @@ public abstract class AbstractSchemaTool { protected AbstractSchemaTool() {} + protected static Session.Builder configureSsl(Session.Builder builder) { + builder.useSSL(true).trustStore(trustStore).trustStorePwd(trustStorePwd); + if (sslProtocol != null) { + builder.sslProtocol(sslProtocol); + } + if (sslProviderClass != null) { + builder.sslProviderClass(sslProviderClass); + } + return builder; + } + + protected static SessionPool.Builder configureSsl(SessionPool.Builder builder) { + builder.useSSL(true).trustStore(trustStore).trustStorePwd(trustStorePwd); + if (sslProtocol != null) { + builder.sslProtocol(sslProtocol); + } + if (sslProviderClass != null) { + builder.sslProviderClass(sslProviderClass); + } + return builder; + } + + protected static TableSessionPoolBuilder configureSsl(TableSessionPoolBuilder builder) { + builder.useSSL(true).trustStore(trustStore).trustStorePwd(trustStorePwd); + if (sslProtocol != null) { + builder.sslProtocol(sslProtocol); + } + if (sslProviderClass != null) { + builder.sslProviderClass(sslProviderClass); + } + return builder; + } + protected static String checkRequiredArg( String arg, String name, CommandLine commandLine, String defaultValue) throws ArgsErrorException { @@ -107,6 +144,8 @@ protected static void parseBasicParams(CommandLine commandLine) String useSslStr = commandLine.getOptionValue(Constants.USE_SSL_ARGS); useSsl = Boolean.parseBoolean(useSslStr); if (useSsl) { + sslProtocol = commandLine.getOptionValue(Constants.SSL_PROTOCOL_ARGS); + sslProviderClass = commandLine.getOptionValue(Constants.SSL_PROVIDER_CLASS_ARGS); String givenTS = commandLine.getOptionValue(Constants.TRUST_STORE_ARGS); if (givenTS != null) { trustStore = givenTS; diff --git a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/schema/ExportSchemaTable.java b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/schema/ExportSchemaTable.java index 1ed3e2c6b862a..c9b15870d2175 100644 --- a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/schema/ExportSchemaTable.java +++ b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/schema/ExportSchemaTable.java @@ -64,8 +64,7 @@ public void init() throws InterruptedException { .enableAutoFetch(false) .database(database); if (useSsl) { - tableSessionPoolBuilder = - tableSessionPoolBuilder.useSSL(true).trustStore(trustStore).trustStorePwd(trustStorePwd); + tableSessionPoolBuilder = configureSsl(tableSessionPoolBuilder); } sessionPool = tableSessionPoolBuilder.build(); checkDatabase(); diff --git a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/schema/ExportSchemaTree.java b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/schema/ExportSchemaTree.java index 334d8a8d8dc42..da304f87c4986 100644 --- a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/schema/ExportSchemaTree.java +++ b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/schema/ExportSchemaTree.java @@ -51,8 +51,7 @@ public void init() .username(username) .password(password); if (useSsl) { - sessionBuilder = - sessionBuilder.useSSL(true).trustStore(trustStore).trustStorePwd(trustStorePwd); + sessionBuilder = configureSsl(sessionBuilder); } session = sessionBuilder.build(); session.open(false); diff --git a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/schema/ImportSchemaTable.java b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/schema/ImportSchemaTable.java index 011042c34d29c..004ec8b4152bb 100644 --- a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/schema/ImportSchemaTable.java +++ b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/schema/ImportSchemaTable.java @@ -60,8 +60,7 @@ public void init() throws InterruptedException { .enableAutoFetch(false) .database(database); if (useSsl) { - tableSessionPoolBuilder = - tableSessionPoolBuilder.useSSL(true).trustStore(trustStore).trustStorePwd(trustStorePwd); + tableSessionPoolBuilder = configureSsl(tableSessionPoolBuilder); } sessionPool = tableSessionPoolBuilder.build(); final File file = new File(targetPath); diff --git a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/schema/ImportSchemaTree.java b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/schema/ImportSchemaTree.java index 9526447fd9654..5d7dfc35d8a0d 100644 --- a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/schema/ImportSchemaTree.java +++ b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/schema/ImportSchemaTree.java @@ -73,8 +73,7 @@ public void init() .enableRedirection(false) .enableAutoFetch(false); if (useSsl) { - sessionPoolBuilder = - sessionPoolBuilder.useSSL(true).trustStore(trustStore).trustStorePwd(trustStorePwd); + sessionPoolBuilder = configureSsl(sessionPoolBuilder); } sessionPool = sessionPoolBuilder.build(); sessionPool.setEnableQueryRedirection(false); diff --git a/iotdb-client/isession/src/main/java/org/apache/iotdb/isession/SessionConfig.java b/iotdb-client/isession/src/main/java/org/apache/iotdb/isession/SessionConfig.java index 611014c615c3b..0a577c45f2d74 100644 --- a/iotdb-client/isession/src/main/java/org/apache/iotdb/isession/SessionConfig.java +++ b/iotdb-client/isession/src/main/java/org/apache/iotdb/isession/SessionConfig.java @@ -56,5 +56,9 @@ public class SessionConfig { public static final String SQL_DIALECT = "tree"; + public static final String DEFAULT_SSL_PROTOCOL = "TLS"; + + public static final String DEFAULT_SSL_PROVIDER_CLASS = ""; + private SessionConfig() {} } diff --git a/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/Config.java b/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/Config.java index 0b1049330eae7..5aaf0f6836641 100644 --- a/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/Config.java +++ b/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/Config.java @@ -82,6 +82,14 @@ private Config() { public static final String TRUST_STORE_PWD = "trust_store_pwd"; + public static final String SSL_PROTOCOL = "ssl_protocol"; + + public static final String SSL_PROVIDER_CLASS = "ssl_provider_class"; + + static final String DEFAULT_SSL_PROTOCOL = "TLS"; + + static final String DEFAULT_SSL_PROVIDER_CLASS = ""; + public static final String SQL_DIALECT = "sql_dialect"; public static final String DATABASE = "db"; diff --git a/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBConnection.java b/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBConnection.java index 7f37e2206fb87..9b95939864d4a 100644 --- a/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBConnection.java +++ b/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBConnection.java @@ -544,12 +544,14 @@ private void openTransport() throws TTransportException { if (params.isUseSSL()) { transport = - DeepCopyRpcTransportFactory.INSTANCE.getTransport( + DeepCopyRpcTransportFactory.INSTANCE.getTransportWithSSLConfig( params.getHost(), params.getPort(), getNetworkTimeout(), params.getTrustStore(), - params.getTrustStorePwd()); + params.getTrustStorePwd(), + params.getSslProtocol(), + params.getSslProviderClass()); } else { transport = DeepCopyRpcTransportFactory.INSTANCE.getTransport( diff --git a/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBConnectionParams.java b/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBConnectionParams.java index 1112caabd4e20..4ae629e74b17c 100644 --- a/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBConnectionParams.java +++ b/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBConnectionParams.java @@ -51,6 +51,8 @@ public class IoTDBConnectionParams { private boolean useSSL = false; private String trustStore; private String trustStorePwd; + private String sslProtocol = Config.DEFAULT_SSL_PROTOCOL; + private String sslProviderClass = Config.DEFAULT_SSL_PROVIDER_CLASS; private String sqlDialect = TREE; @@ -184,6 +186,22 @@ public void setTrustStorePwd(String trustStorePwd) { this.trustStorePwd = trustStorePwd; } + public String getSslProtocol() { + return sslProtocol; + } + + public void setSslProtocol(String sslProtocol) { + this.sslProtocol = sslProtocol; + } + + public String getSslProviderClass() { + return sslProviderClass; + } + + public void setSslProviderClass(String sslProviderClass) { + this.sslProviderClass = sslProviderClass; + } + public String getSqlDialect() { return sqlDialect; } diff --git a/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/Utils.java b/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/Utils.java index 00e46cc340d15..8bd394cf11547 100644 --- a/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/Utils.java +++ b/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/Utils.java @@ -136,6 +136,12 @@ static IoTDBConnectionParams parseUrl(String url, Properties info) throws IoTDBU if (info.containsKey(Config.TRUST_STORE_PWD)) { params.setTrustStorePwd(info.getProperty(Config.TRUST_STORE_PWD)); } + if (info.containsKey(Config.SSL_PROTOCOL)) { + params.setSslProtocol(info.getProperty(Config.SSL_PROTOCOL)); + } + if (info.containsKey(Config.SSL_PROVIDER_CLASS)) { + params.setSslProviderClass(info.getProperty(Config.SSL_PROVIDER_CLASS)); + } if (info.containsKey(Config.SQL_DIALECT)) { params.setSqlDialect(info.getProperty(Config.SQL_DIALECT)); } @@ -175,6 +181,8 @@ private static boolean parseUrlParam(String subURL, Properties info) { case Config.USE_SSL: case Config.TRUST_STORE: case Config.TRUST_STORE_PWD: + case Config.SSL_PROTOCOL: + case Config.SSL_PROVIDER_CLASS: case Config.VERSION: case Config.NETWORK_TIMEOUT: case Config.SQL_DIALECT: diff --git a/iotdb-client/jdbc/src/test/java/org/apache/iotdb/jdbc/UtilsTest.java b/iotdb-client/jdbc/src/test/java/org/apache/iotdb/jdbc/UtilsTest.java index 4c401b88017af..32dd7a78a6dd7 100644 --- a/iotdb-client/jdbc/src/test/java/org/apache/iotdb/jdbc/UtilsTest.java +++ b/iotdb-client/jdbc/src/test/java/org/apache/iotdb/jdbc/UtilsTest.java @@ -159,4 +159,18 @@ public void testRpcCompress() throws IoTDBURLException { Utils.parseUrl("jdbc:iotdb://127.0.0.1:6667?rpc_compress=true", properties); assertTrue(Config.rpcThriftCompressionEnable); } + + @Test + public void testParseSslConfig() throws IoTDBURLException { + Properties properties = new Properties(); + IoTDBConnectionParams params = + Utils.parseUrl( + "jdbc:iotdb://127.0.0.1:6667?use_ssl=true&ssl_protocol=TLSv1.3" + + "&ssl_provider_class=com.example.ssl.Provider", + properties); + + assertTrue(params.isUseSSL()); + assertEquals("TLSv1.3", params.getSslProtocol()); + assertEquals("com.example.ssl.Provider", params.getSslProviderClass()); + } } diff --git a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/BaseRpcTransportFactory.java b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/BaseRpcTransportFactory.java index 22e104b6a58ac..58d8abbc60e1a 100644 --- a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/BaseRpcTransportFactory.java +++ b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/BaseRpcTransportFactory.java @@ -84,8 +84,24 @@ public TTransport getTransport( String ip, int port, int timeout, String trustStore, String trustStorePwd) throws TTransportException { TSSLTransportFactory.TSSLTransportParameters params = - new TSSLTransportFactory.TSSLTransportParameters(); - params.setTrustStore(trustStore, trustStorePwd); + RpcSslUtils.createTSSLTransportParameters(); + RpcSslUtils.setTrustStore(params, trustStore, trustStorePwd); + TTransport transport = TSSLTransportFactory.getClientSocket(ip, port, timeout, params); + return inner.getTransport(transport); + } + + public TTransport getTransportWithSSLConfig( + String ip, + int port, + int timeout, + String trustStore, + String trustStorePwd, + String sslProtocol, + String sslProviderClass) + throws TTransportException { + TSSLTransportFactory.TSSLTransportParameters params = + RpcSslUtils.createTSSLTransportParameters(sslProtocol, sslProviderClass, null); + RpcSslUtils.setTrustStore(params, trustStore, trustStorePwd, sslProtocol, sslProviderClass); TTransport transport = TSSLTransportFactory.getClientSocket(ip, port, timeout, params); return inner.getTransport(transport); } @@ -100,10 +116,33 @@ public TTransport getTransport( String keyStorePwd) throws TTransportException { TSSLTransportFactory.TSSLTransportParameters params = - new TSSLTransportFactory.TSSLTransportParameters(); + RpcSslUtils.createTSSLTransportParameters(); + if (Files.exists(Paths.get(trustStore)) && Files.exists(Paths.get(keyStore))) { + RpcSslUtils.setTrustStore(params, trustStore, trustStorePwd); + RpcSslUtils.setKeyStore(params, keyStore, keyStorePwd); + } else { + throw new TTransportException(new IOException(RpcMessages.COULD_NOT_LOAD_KEYSTORE)); + } + TTransport transport = TSSLTransportFactory.getClientSocket(ip, port, timeout, params); + return inner.getTransport(transport); + } + + public TTransport getTransport( + String ip, + int port, + int timeout, + String trustStore, + String trustStorePwd, + String keyStore, + String keyStorePwd, + String sslProtocol, + String sslProviderClass) + throws TTransportException { + TSSLTransportFactory.TSSLTransportParameters params = + RpcSslUtils.createTSSLTransportParameters(sslProtocol, sslProviderClass, null); if (Files.exists(Paths.get(trustStore)) && Files.exists(Paths.get(keyStore))) { - params.setTrustStore(trustStore, trustStorePwd); - params.setKeyStore(keyStore, keyStorePwd); + RpcSslUtils.setTrustStore(params, trustStore, trustStorePwd, sslProtocol, sslProviderClass); + RpcSslUtils.setKeyStore(params, keyStore, keyStorePwd, sslProtocol, sslProviderClass); } else { throw new TTransportException(new IOException(RpcMessages.COULD_NOT_LOAD_KEYSTORE)); } diff --git a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/RpcSslUtils.java b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/RpcSslUtils.java new file mode 100644 index 0000000000000..cfd0dca615e01 --- /dev/null +++ b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/RpcSslUtils.java @@ -0,0 +1,422 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.iotdb.rpc; + +import org.apache.thrift.transport.TSSLTransportFactory; +import org.apache.thrift.transport.TTransportException; + +import javax.net.ssl.KeyManager; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLEngine; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.nio.file.AccessDeniedException; +import java.security.GeneralSecurityException; +import java.security.KeyStore; +import java.security.Provider; +import java.security.Security; +import java.security.cert.X509Certificate; +import java.util.Arrays; +import java.util.Enumeration; +import java.util.Locale; +import java.util.stream.Stream; + +public final class RpcSslUtils { + + private static final String DEFAULT_PROTOCOL = "TLS"; + private static final String PKCS12_STORE_TYPE = "PKCS12"; + private static final String JKS_STORE_TYPE = "JKS"; + + private static volatile SslConfig config = new SslConfig(DEFAULT_PROTOCOL, "", null); + + private RpcSslUtils() {} + + public static void configure(String protocol, String providerClass, String cipherSuites) { + config = newSslConfig(protocol, providerClass, cipherSuites); + } + + public static void ensureProvider(String protocol, String providerClass) + throws TTransportException { + ensureProvider(newSslConfig(protocol, providerClass, null)); + } + + public static TSSLTransportFactory.TSSLTransportParameters createTSSLTransportParameters() + throws TTransportException { + SslConfig current = config; + ensureProvider(current); + return createTSSLTransportParameters(current); + } + + public static TSSLTransportFactory.TSSLTransportParameters createTSSLTransportParameters( + String protocol, String providerClass, String cipherSuites) throws TTransportException { + SslConfig current = newSslConfig(protocol, providerClass, cipherSuites); + ensureProvider(current); + return createTSSLTransportParameters(current); + } + + private static TSSLTransportFactory.TSSLTransportParameters createTSSLTransportParameters( + SslConfig current) { + return new TSSLTransportFactory.TSSLTransportParameters(current.protocol, current.cipherSuites); + } + + public static void setKeyStore( + TSSLTransportFactory.TSSLTransportParameters params, String keyStorePath, String keyStorePwd) + throws TTransportException { + setKeyStore(params, keyStorePath, keyStorePwd, config); + } + + public static void setKeyStore( + TSSLTransportFactory.TSSLTransportParameters params, + String keyStorePath, + String keyStorePwd, + String protocol, + String providerClass) + throws TTransportException { + setKeyStore(params, keyStorePath, keyStorePwd, newSslConfig(protocol, providerClass, null)); + } + + private static void setKeyStore( + TSSLTransportFactory.TSSLTransportParameters params, + String keyStorePath, + String keyStorePwd, + SslConfig current) + throws TTransportException { + try { + ensureProvider(current); + params.setKeyStore( + keyStorePath, + keyStorePwd, + KeyManagerFactory.getDefaultAlgorithm(), + detectStoreType(keyStorePath, keyStorePwd)); + } catch (GeneralSecurityException | IOException e) { + throw new TTransportException(e); + } + } + + public static void setTrustStore( + TSSLTransportFactory.TSSLTransportParameters params, + String trustStorePath, + String trustStorePwd) + throws TTransportException { + setTrustStore(params, trustStorePath, trustStorePwd, config); + } + + public static void setTrustStore( + TSSLTransportFactory.TSSLTransportParameters params, + String trustStorePath, + String trustStorePwd, + String protocol, + String providerClass) + throws TTransportException { + setTrustStore( + params, trustStorePath, trustStorePwd, newSslConfig(protocol, providerClass, null)); + } + + private static void setTrustStore( + TSSLTransportFactory.TSSLTransportParameters params, + String trustStorePath, + String trustStorePwd, + SslConfig current) + throws TTransportException { + try { + ensureProvider(current); + params.setTrustStore( + trustStorePath, + trustStorePwd, + TrustManagerFactory.getDefaultAlgorithm(), + detectStoreType(trustStorePath, trustStorePwd)); + } catch (GeneralSecurityException | IOException e) { + throw new TTransportException(e); + } + } + + public static SSLContext createSSLContext( + String keyStorePath, + String keyStorePassword, + String trustStorePath, + String trustStorePassword) + throws GeneralSecurityException, IOException, TTransportException { + return createSSLContext( + keyStorePath, keyStorePassword, trustStorePath, trustStorePassword, config); + } + + public static SSLContext createSSLContext( + String keyStorePath, + String keyStorePassword, + String trustStorePath, + String trustStorePassword, + String protocol, + String providerClass, + String cipherSuites) + throws GeneralSecurityException, IOException, TTransportException { + return createSSLContext( + keyStorePath, + keyStorePassword, + trustStorePath, + trustStorePassword, + newSslConfig(protocol, providerClass, cipherSuites)); + } + + private static SSLContext createSSLContext( + String keyStorePath, + String keyStorePassword, + String trustStorePath, + String trustStorePassword, + SslConfig current) + throws GeneralSecurityException, IOException, TTransportException { + ensureProvider(current); + SSLContext context = newSSLContext(current); + KeyManager[] keyManagers = + hasText(keyStorePath) ? loadKeyManagers(keyStorePath, keyStorePassword) : null; + TrustManager[] trustManagers = + hasText(trustStorePath) ? loadTrustManagers(trustStorePath, trustStorePassword) : null; + context.init(keyManagers, trustManagers, null); + return context; + } + + public static KeyManager[] createKeyManagers(String keyStorePath, String keyStorePassword) + throws GeneralSecurityException, IOException, TTransportException { + ensureProvider(config); + return loadKeyManagers(keyStorePath, keyStorePassword); + } + + public static TrustManager[] createTrustManagers(String trustStorePath, String trustStorePassword) + throws GeneralSecurityException, IOException, TTransportException { + ensureProvider(config); + return loadTrustManagers(trustStorePath, trustStorePassword); + } + + public static String getProtocol() { + return config.protocol; + } + + public static String[] getCipherSuites() { + SslConfig current = config; + return current.cipherSuites == null + ? null + : Arrays.copyOf(current.cipherSuites, current.cipherSuites.length); + } + + public static boolean hasConfiguredProvider() { + return hasText(config.providerClass); + } + + public static String getSSLContextProviderName() throws TTransportException { + ensureProvider(config); + try { + return newSSLContext(config).getProvider().getName(); + } catch (GeneralSecurityException e) { + throw new TTransportException("Failed to initialize SSL context", e); + } + } + + public static String[] getEnabledCipherSuites() throws TTransportException { + ensureProvider(config); + try { + SSLContext context = newSSLContext(config); + context.init(null, null, null); + SSLEngine engine = context.createSSLEngine(); + return engine.getEnabledCipherSuites(); + } catch (GeneralSecurityException e) { + throw new TTransportException("Failed to initialize SSL context", e); + } + } + + public static void validateKeyStore(String keyStorePath, String keyStorePassword) + throws TTransportException { + validateStore(keyStorePath, keyStorePassword); + } + + public static void validateTrustStore(String trustStorePath, String trustStorePassword) + throws TTransportException { + validateStore(trustStorePath, trustStorePassword); + } + + private static KeyManager[] loadKeyManagers(String keyStorePath, String keyStorePassword) + throws GeneralSecurityException, IOException { + KeyStore keyStore = loadStore(keyStorePath, keyStorePassword); + KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + kmf.init(keyStore, toPassword(keyStorePassword)); + return kmf.getKeyManagers(); + } + + private static TrustManager[] loadTrustManagers(String trustStorePath, String trustStorePassword) + throws GeneralSecurityException, IOException { + KeyStore trustStore = loadStore(trustStorePath, trustStorePassword); + TrustManagerFactory tmf = + TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + tmf.init(trustStore); + return tmf.getTrustManagers(); + } + + private static SSLContext newSSLContext(SslConfig current) throws GeneralSecurityException { + return SSLContext.getInstance(current.protocol); + } + + private static String detectStoreType(String storePath, String storePassword) + throws GeneralSecurityException, IOException { + return loadStore(storePath, storePassword).getType(); + } + + private static KeyStore loadStore(String storePath, String storePassword) + throws GeneralSecurityException, IOException { + Exception lastException = null; + for (String storeType : storeTypeCandidates()) { + try { + return loadStore(storePath, storePassword, storeType); + } catch (AccessDeniedException | FileNotFoundException e) { + throw e; + } catch (GeneralSecurityException | IOException e) { + lastException = e; + } + } + if (lastException instanceof GeneralSecurityException) { + throw (GeneralSecurityException) lastException; + } + if (lastException instanceof IOException) { + throw (IOException) lastException; + } + throw new IOException("No supported keystore or truststore type is available"); + } + + private static KeyStore loadStore(String storePath, String storePassword, String storeType) + throws GeneralSecurityException, IOException { + KeyStore store = KeyStore.getInstance(storeType); + try (FileInputStream fis = new FileInputStream(storePath)) { + store.load(fis, toPassword(storePassword)); + } catch (AccessDeniedException e) { + throw new AccessDeniedException("Failed to load keystore or truststore file"); + } catch (FileNotFoundException e) { + throw new FileNotFoundException("keystore or truststore file not found: " + storePath); + } + return store; + } + + private static void validateStore(String storePath, String storePassword) + throws TTransportException { + try { + ensureProvider(config); + KeyStore store = loadStore(storePath, storePassword); + Enumeration aliases = store.aliases(); + while (aliases.hasMoreElements()) { + X509Certificate cert = (X509Certificate) store.getCertificate(aliases.nextElement()); + if (cert != null) { + cert.checkValidity(); + } + } + } catch (Exception e) { + throw new TTransportException(e); + } + } + + private static synchronized void ensureProvider(SslConfig current) throws TTransportException { + if (!hasText(current.providerClass)) { + return; + } + try { + String[] providerClassNames = splitProviderClasses(current.providerClass); + for (int i = providerClassNames.length - 1; i >= 0; i--) { + String providerClassName = providerClassNames[i]; + Class providerClass = Class.forName(providerClassName); + Constructor constructor = providerClass.getDeclaredConstructor(); + constructor.setAccessible(true); + Provider provider = (Provider) constructor.newInstance(); + Provider firstProvider = Security.getProviders()[0]; + if (!provider.getName().equals(firstProvider.getName())) { + Security.removeProvider(provider.getName()); + Security.insertProviderAt(provider, 1); + } + } + } catch (Exception e) { + throw new TTransportException("Failed to initialize SSL provider", e); + } + } + + private static char[] toPassword(String password) { + return password == null ? null : password.toCharArray(); + } + + private static String trimToDefault(String value, String defaultValue) { + String trimmed = trimToEmpty(value); + return trimmed.isEmpty() ? defaultValue : trimmed; + } + + private static String trimToEmpty(String value) { + return value == null ? "" : value.trim(); + } + + private static boolean hasText(String value) { + return value != null && !value.trim().isEmpty(); + } + + private static String[] splitCipherSuites(String cipherSuites) { + if (!hasText(cipherSuites)) { + return null; + } + return splitCommaSeparated(cipherSuites); + } + + private static String[] splitProviderClasses(String providerClasses) { + return splitCommaSeparated(providerClasses); + } + + private static String[] splitCommaSeparated(String value) { + return Stream.of(value.split(",")) + .map(String::trim) + .filter(s -> !s.isEmpty()) + .toArray(String[]::new); + } + + private static String[] storeTypeCandidates() { + return Stream.of(KeyStore.getDefaultType(), PKCS12_STORE_TYPE, JKS_STORE_TYPE) + .map(String::trim) + .map(s -> s.toUpperCase(Locale.ROOT)) + .filter(s -> !s.isEmpty()) + .distinct() + .toArray(String[]::new); + } + + private static SslConfig newSslConfig( + String protocol, String providerClass, String cipherSuites) { + return new SslConfig( + trimToDefault(protocol, DEFAULT_PROTOCOL), + trimToEmpty(providerClass), + splitCipherSuites(cipherSuites)); + } + + private static final class SslConfig { + private final String protocol; + private final String providerClass; + private final String[] cipherSuites; + + private SslConfig(String protocol, String providerClass, String[] cipherSuites) { + this.protocol = protocol; + this.providerClass = providerClass; + this.cipherSuites = + cipherSuites == null ? null : Arrays.copyOf(cipherSuites, cipherSuites.length); + } + } +} diff --git a/iotdb-client/session/src/main/java/org/apache/iotdb/session/AbstractSessionBuilder.java b/iotdb-client/session/src/main/java/org/apache/iotdb/session/AbstractSessionBuilder.java index f6132d8041f1b..2fe601f994dbb 100644 --- a/iotdb-client/session/src/main/java/org/apache/iotdb/session/AbstractSessionBuilder.java +++ b/iotdb-client/session/src/main/java/org/apache/iotdb/session/AbstractSessionBuilder.java @@ -62,6 +62,8 @@ public abstract class AbstractSessionBuilder { public boolean useSSL = false; public String trustStore; public String trustStorePwd; + public String sslProtocol = SessionConfig.DEFAULT_SSL_PROTOCOL; + public String sslProviderClass = SessionConfig.DEFAULT_SSL_PROVIDER_CLASS; // max retry count, if set to 0, means that we won't do any retry // we can use any available DataNodes(fetched in background thread if enableAutoFetch is true, diff --git a/iotdb-client/session/src/main/java/org/apache/iotdb/session/NodesSupplier.java b/iotdb-client/session/src/main/java/org/apache/iotdb/session/NodesSupplier.java index d57844b499705..c6c2288b8b2d2 100644 --- a/iotdb-client/session/src/main/java/org/apache/iotdb/session/NodesSupplier.java +++ b/iotdb-client/session/src/main/java/org/apache/iotdb/session/NodesSupplier.java @@ -61,6 +61,8 @@ public class NodesSupplier implements INodeSupplier, Runnable { private final boolean useSSL; private final String trustStore; private final String trustStorePwd; + private final String sslProtocol; + private final String sslProviderClass; private final boolean enableRPCCompression; private final String userName; @@ -95,6 +97,8 @@ public static NodesSupplier createNodeSupplier( boolean useSSL, String trustStore, String trustStorePwd, + String sslProtocol, + String sslProviderClass, boolean enableRPCCompression, String version) { @@ -110,6 +114,8 @@ public static NodesSupplier createNodeSupplier( useSSL, trustStore, trustStorePwd, + sslProtocol, + sslProviderClass, enableRPCCompression, version); @@ -132,6 +138,8 @@ private NodesSupplier( boolean useSSL, String trustStore, String trustStorePwd, + String sslProtocol, + String sslProviderClass, boolean enableRPCCompression, String version) { this.availableNodes.addAll(new HashSet<>(endPointList)); @@ -140,6 +148,8 @@ private NodesSupplier( this.useSSL = useSSL; this.trustStore = trustStore; this.trustStorePwd = trustStorePwd; + this.sslProtocol = sslProtocol; + this.sslProviderClass = sslProviderClass; this.enableRPCCompression = enableRPCCompression; this.zoneId = zoneId == null ? ZoneId.systemDefault() : zoneId; this.thriftDefaultBufferSize = thriftDefaultBufferSize; @@ -188,6 +198,8 @@ private boolean createConnection(TEndPoint endPoint) { useSSL, trustStore, trustStorePwd, + sslProtocol, + sslProviderClass, userName, password, enableRPCCompression, diff --git a/iotdb-client/session/src/main/java/org/apache/iotdb/session/Session.java b/iotdb-client/session/src/main/java/org/apache/iotdb/session/Session.java index b92df62f5ad5b..81798b046ba9e 100644 --- a/iotdb-client/session/src/main/java/org/apache/iotdb/session/Session.java +++ b/iotdb-client/session/src/main/java/org/apache/iotdb/session/Session.java @@ -133,6 +133,8 @@ public class Session implements ISession { protected boolean useSSL; protected String trustStore; protected String trustStorePwd; + protected String sslProtocol; + protected String sslProviderClass; /** * Timeout of query can be set by users. A negative number means using the default configuration @@ -472,6 +474,8 @@ public Session(AbstractSessionBuilder builder) { this.useSSL = builder.useSSL; this.trustStore = builder.trustStore; this.trustStorePwd = builder.trustStorePwd; + this.sslProtocol = builder.sslProtocol; + this.sslProviderClass = builder.sslProviderClass; this.enableAutoFetch = builder.enableAutoFetch; this.maxRetryCount = builder.maxRetryCount; this.retryIntervalInMs = builder.retryIntervalInMs; @@ -541,6 +545,8 @@ public synchronized void open(boolean enableRPCCompaction, int connectionTimeout useSSL, trustStore, trustStorePwd, + sslProtocol, + sslProviderClass, enableRPCCompaction, version.toString()); } else { @@ -4433,6 +4439,16 @@ public Builder trustStorePwd(String trustStorePwd) { return this; } + public Builder sslProtocol(String sslProtocol) { + this.sslProtocol = sslProtocol; + return this; + } + + public Builder sslProviderClass(String sslProviderClass) { + this.sslProviderClass = sslProviderClass; + return this; + } + public Session build() { if (nodeUrls != null && (!SessionConfig.DEFAULT_HOST.equals(host) || rpcPort != SessionConfig.DEFAULT_PORT)) { diff --git a/iotdb-client/session/src/main/java/org/apache/iotdb/session/SessionConnection.java b/iotdb-client/session/src/main/java/org/apache/iotdb/session/SessionConnection.java index f6608d8fe4bfe..e12ccdcc0c5e2 100644 --- a/iotdb-client/session/src/main/java/org/apache/iotdb/session/SessionConnection.java +++ b/iotdb-client/session/src/main/java/org/apache/iotdb/session/SessionConnection.java @@ -151,7 +151,13 @@ public SessionConnection( this.sqlDialect = sqlDialect; this.database = database; try { - init(endPoint, session.useSSL, session.trustStore, session.trustStorePwd); + init( + endPoint, + session.useSSL, + session.trustStore, + session.trustStorePwd, + session.sslProtocol, + session.sslProviderClass); } catch (StatementExecutionException e) { throw new IoTDBConnectionException(e.getMessage()); } catch (IoTDBConnectionException e) { @@ -179,7 +185,13 @@ public SessionConnection( initClusterConn(); } - private void init(TEndPoint endPoint, boolean useSSL, String trustStore, String trustStorePwd) + private void init( + TEndPoint endPoint, + boolean useSSL, + String trustStore, + String trustStorePwd, + String sslProtocol, + String sslProviderClass) throws IoTDBConnectionException, StatementExecutionException { DeepCopyRpcTransportFactory.setDefaultBufferCapacity(session.thriftDefaultBufferSize); DeepCopyRpcTransportFactory.setThriftMaxFrameSize(session.thriftMaxFrameSize); @@ -189,12 +201,14 @@ private void init(TEndPoint endPoint, boolean useSSL, String trustStore, String } if (useSSL) { transport = - DeepCopyRpcTransportFactory.INSTANCE.getTransport( + DeepCopyRpcTransportFactory.INSTANCE.getTransportWithSSLConfig( endPoint.getIp(), endPoint.getPort(), session.connectionTimeoutInMs, trustStore, - trustStorePwd); + trustStorePwd, + sslProtocol, + sslProviderClass); } else { transport = DeepCopyRpcTransportFactory.INSTANCE.getTransport( @@ -262,7 +276,13 @@ private void initClusterConn() throws IoTDBConnectionException { for (TEndPoint tEndPoint : endPointList) { try { session.defaultEndPoint = tEndPoint; - init(tEndPoint, session.useSSL, session.trustStore, session.trustStorePwd); + init( + tEndPoint, + session.useSSL, + session.trustStore, + session.trustStorePwd, + session.sslProtocol, + session.sslProviderClass); } catch (IoTDBConnectionException e) { if (!reconnect()) { logger.error(SessionMessages.CLUSTER_NO_NODES); @@ -1079,7 +1099,13 @@ private boolean reconnect() { } tryHostNum++; try { - init(endPoint, session.useSSL, session.trustStore, session.trustStorePwd); + init( + endPoint, + session.useSSL, + session.trustStore, + session.trustStorePwd, + session.sslProtocol, + session.sslProviderClass); connectedSuccess = true; } catch (IoTDBConnectionException e) { logger.warn(SessionMessages.NODE_DOWN_TRY_NEXT, endPoint); diff --git a/iotdb-client/session/src/main/java/org/apache/iotdb/session/TableSessionBuilder.java b/iotdb-client/session/src/main/java/org/apache/iotdb/session/TableSessionBuilder.java index be53797165a6a..bc8ec1a1643a2 100644 --- a/iotdb-client/session/src/main/java/org/apache/iotdb/session/TableSessionBuilder.java +++ b/iotdb-client/session/src/main/java/org/apache/iotdb/session/TableSessionBuilder.java @@ -239,6 +239,30 @@ public TableSessionBuilder trustStorePwd(String trustStorePwd) { return this; } + /** + * Sets the SSL protocol for secure connections. + * + * @param sslProtocol the SSL protocol. + * @return the current {@link TableSessionBuilder} instance. + * @defaultValue TLS + */ + public TableSessionBuilder sslProtocol(String sslProtocol) { + this.sslProtocol = sslProtocol; + return this; + } + + /** + * Sets the JSSE provider class for SSL connections. + * + * @param sslProviderClass the JSSE provider class. + * @return the current {@link TableSessionBuilder} instance. + * @defaultValue empty + */ + public TableSessionBuilder sslProviderClass(String sslProviderClass) { + this.sslProviderClass = sslProviderClass; + return this; + } + /** * Enables or disables rpc compression for the connection. * diff --git a/iotdb-client/session/src/main/java/org/apache/iotdb/session/ThriftConnection.java b/iotdb-client/session/src/main/java/org/apache/iotdb/session/ThriftConnection.java index e3b9e8fc98987..251ed3566cbe1 100644 --- a/iotdb-client/session/src/main/java/org/apache/iotdb/session/ThriftConnection.java +++ b/iotdb-client/session/src/main/java/org/apache/iotdb/session/ThriftConnection.java @@ -78,6 +78,8 @@ public void init( boolean useSSL, String trustStore, String trustStorePwd, + String sslProtocol, + String sslProviderClass, String username, String password, boolean enableRPCCompression, @@ -89,12 +91,14 @@ public void init( try { if (useSSL) { transport = - DeepCopyRpcTransportFactory.INSTANCE.getTransport( + DeepCopyRpcTransportFactory.INSTANCE.getTransportWithSSLConfig( endPoint.getIp(), endPoint.getPort(), connectionTimeoutInMs, trustStore, - trustStorePwd); + trustStorePwd, + sslProtocol, + sslProviderClass); } else { transport = DeepCopyRpcTransportFactory.INSTANCE.getTransport( diff --git a/iotdb-client/session/src/main/java/org/apache/iotdb/session/pool/SessionPool.java b/iotdb-client/session/src/main/java/org/apache/iotdb/session/pool/SessionPool.java index 3eaabe7f1fa78..d7975f9b29121 100644 --- a/iotdb-client/session/src/main/java/org/apache/iotdb/session/pool/SessionPool.java +++ b/iotdb-client/session/src/main/java/org/apache/iotdb/session/pool/SessionPool.java @@ -116,6 +116,11 @@ public class SessionPool implements ISessionPool { private String trustStore; private String trustStorePwd; + + private String sslProtocol = SessionConfig.DEFAULT_SSL_PROTOCOL; + + private String sslProviderClass = SessionConfig.DEFAULT_SSL_PROVIDER_CLASS; + private ZoneId zoneId; // this field only take effect in write request, nothing to do with any other type requests, // like query, load and so on. @@ -466,6 +471,8 @@ public SessionPool( this.useSSL = useSSL; this.trustStore = trustStore; this.trustStorePwd = trustStorePwd; + this.sslProtocol = SessionConfig.DEFAULT_SSL_PROTOCOL; + this.sslProviderClass = SessionConfig.DEFAULT_SSL_PROVIDER_CLASS; initThreadPool(); initAvailableNodes(Collections.singletonList(new TEndPoint(host, port))); } @@ -536,6 +543,8 @@ public SessionPool(AbstractSessionPoolBuilder builder) { this.useSSL = builder.useSSL; this.trustStore = builder.trustStore; this.trustStorePwd = builder.trustStorePwd; + this.sslProtocol = builder.sslProtocol; + this.sslProviderClass = builder.sslProviderClass; this.maxRetryCount = builder.maxRetryCount; this.retryIntervalInMs = builder.retryIntervalInMs; this.sqlDialect = builder.sqlDialect; @@ -593,6 +602,8 @@ private Session constructNewSession() { .useSSL(useSSL) .trustStore(trustStore) .trustStorePwd(trustStorePwd) + .sslProtocol(sslProtocol) + .sslProviderClass(sslProviderClass) .maxRetryCount(maxRetryCount) .retryIntervalInMs(retryIntervalInMs) .sqlDialect(sqlDialect) @@ -618,6 +629,8 @@ private Session constructNewSession() { .useSSL(useSSL) .trustStore(trustStore) .trustStorePwd(trustStorePwd) + .sslProtocol(sslProtocol) + .sslProviderClass(sslProviderClass) .maxRetryCount(maxRetryCount) .retryIntervalInMs(retryIntervalInMs) .sqlDialect(sqlDialect) @@ -662,6 +675,8 @@ private void initAvailableNodes(List endPointList) { useSSL, trustStore, trustStorePwd, + sslProtocol, + sslProviderClass, enableThriftCompression, version.toString()); } @@ -3637,6 +3652,16 @@ public Builder trustStorePwd(String trustStorePwd) { return this; } + public Builder sslProtocol(String sslProtocol) { + this.sslProtocol = sslProtocol; + return this; + } + + public Builder sslProviderClass(String sslProviderClass) { + this.sslProviderClass = sslProviderClass; + return this; + } + public Builder host(String host) { this.host = host; return this; diff --git a/iotdb-client/session/src/main/java/org/apache/iotdb/session/pool/TableSessionPoolBuilder.java b/iotdb-client/session/src/main/java/org/apache/iotdb/session/pool/TableSessionPoolBuilder.java index d5f52f3a8dc73..ea02d8cf28cdf 100644 --- a/iotdb-client/session/src/main/java/org/apache/iotdb/session/pool/TableSessionPoolBuilder.java +++ b/iotdb-client/session/src/main/java/org/apache/iotdb/session/pool/TableSessionPoolBuilder.java @@ -281,6 +281,30 @@ public TableSessionPoolBuilder trustStorePwd(String trustStorePwd) { return this; } + /** + * Sets the SSL protocol for secure connections. + * + * @param sslProtocol the SSL protocol. + * @return the current {@link TableSessionPoolBuilder} instance. + * @defaultValue TLS + */ + public TableSessionPoolBuilder sslProtocol(String sslProtocol) { + this.sslProtocol = sslProtocol; + return this; + } + + /** + * Sets the JSSE provider class for SSL connections. + * + * @param sslProviderClass the JSSE provider class. + * @return the current {@link TableSessionPoolBuilder} instance. + * @defaultValue empty + */ + public TableSessionPoolBuilder sslProviderClass(String sslProviderClass) { + this.sslProviderClass = sslProviderClass; + return this; + } + /** * Builds and returns a configured {@link ITableSessionPool} instance. * diff --git a/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/ratis/utils/Utils.java b/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/ratis/utils/Utils.java index 2c24ff12b6d36..9e6cee1411558 100644 --- a/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/ratis/utils/Utils.java +++ b/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/ratis/utils/Utils.java @@ -29,6 +29,7 @@ import org.apache.iotdb.consensus.config.RatisConfig; import org.apache.iotdb.consensus.i18n.ConsensusMessages; import org.apache.iotdb.rpc.AutoScalingBufferWriteTransport; +import org.apache.iotdb.rpc.RpcSslUtils; import org.apache.ratis.client.RaftClientConfigKeys; import org.apache.ratis.conf.Parameters; @@ -53,19 +54,13 @@ import org.slf4j.LoggerFactory; import javax.net.ssl.KeyManager; -import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.TrustManager; -import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509TrustManager; import java.io.File; import java.io.FileNotFoundException; -import java.io.InputStream; import java.nio.ByteBuffer; import java.nio.file.AccessDeniedException; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.security.KeyStore; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; @@ -371,25 +366,10 @@ public static Parameters initRatisConfig(RaftProperties properties, RatisConfig String keyStorePassword = config.getGrpc().getSslKeyStorePassword(); String trustStorePath = config.getGrpc().getSslTrustStorePath(); String trustStorePassword = config.getGrpc().getSslTrustStorePassword(); - try (InputStream keyStoreStream = Files.newInputStream(Paths.get(keyStorePath)); - InputStream trustStoreStream = Files.newInputStream(Paths.get(trustStorePath))) { - // === 1) create KeyManager === - KeyStore keyStore = KeyStore.getInstance("JKS"); - keyStore.load(keyStoreStream, keyStorePassword.toCharArray()); - - KeyManagerFactory kmf = - KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); - kmf.init(keyStore, keyStorePassword.toCharArray()); - KeyManager keyManager = kmf.getKeyManagers()[0]; - - // === 2) create TrustManager === - KeyStore trustStore = KeyStore.getInstance("JKS"); - trustStore.load(trustStoreStream, trustStorePassword.toCharArray()); - - TrustManagerFactory tmf = - TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); - tmf.init(trustStore); - TrustManager originalTrustManager = tmf.getTrustManagers()[0]; + try { + KeyManager keyManager = RpcSslUtils.createKeyManagers(keyStorePath, keyStorePassword)[0]; + TrustManager originalTrustManager = + RpcSslUtils.createTrustManagers(trustStorePath, trustStorePassword)[0]; // The self-signed certification may not set Subject Alternative Name (SAN) // Thrift with ssl didn't check it, but Grpc did. diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/rest/IoTDBRestServiceConfig.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/rest/IoTDBRestServiceConfig.java index 64c0f65fe3034..4e142a426b7b8 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/rest/IoTDBRestServiceConfig.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/rest/IoTDBRestServiceConfig.java @@ -45,6 +45,12 @@ public class IoTDBRestServiceConfig { /** ssl trust Store password. */ private String trustStorePwd = ""; + /** SSL protocol. */ + private String sslProtocol = ""; + + /** SSL provider class. */ + private String sslProviderClass = ""; + /** ssl timeout. */ private int idleTimeoutInSeconds = 50000; @@ -78,6 +84,22 @@ public void setTrustStorePwd(String trustStorePwd) { this.trustStorePwd = trustStorePwd; } + public String getSslProtocol() { + return sslProtocol; + } + + public void setSslProtocol(String sslProtocol) { + this.sslProtocol = sslProtocol; + } + + public String getSslProviderClass() { + return sslProviderClass; + } + + public void setSslProviderClass(String sslProviderClass) { + this.sslProviderClass = sslProviderClass; + } + public int getIdleTimeoutInSeconds() { return idleTimeoutInSeconds; } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/rest/IoTDBRestServiceDescriptor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/rest/IoTDBRestServiceDescriptor.java index 2e4ed0c28a6d0..c832d6cea62e0 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/rest/IoTDBRestServiceDescriptor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/rest/IoTDBRestServiceDescriptor.java @@ -108,6 +108,9 @@ private void loadProps(TrimProperties trimProperties) { conf.setTrustStorePath( trimProperties.getProperty("trust_store_path", conf.getTrustStorePath())); conf.setTrustStorePwd(trimProperties.getProperty("trust_store_pwd", conf.getTrustStorePwd())); + conf.setSslProtocol(trimProperties.getProperty("ssl_protocol", conf.getSslProtocol())); + conf.setSslProviderClass( + trimProperties.getProperty("ssl_provider_class", conf.getSslProviderClass())); conf.setIdleTimeoutInSeconds( Integer.parseInt( trimProperties.getProperty( diff --git a/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template b/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template index 3b2d5ff54731c..4b9156f02dd90 100644 --- a/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template +++ b/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template @@ -474,6 +474,26 @@ trust_store_path= # Datatype: String trust_store_pwd= +# SSL protocol used by SSL services. +# effectiveMode: restart +# Datatype: String +# Privilege: SECURITY +ssl_protocol=TLS + +# Optional JSSE provider class used by SSL. If set, the provider is registered with highest priority. +# Multiple provider classes can be separated by commas. +# effectiveMode: restart +# Datatype: String +# Privilege: SECURITY +ssl_provider_class= + +# Comma-separated SSL cipher suites. +# Leave empty to use the provider default. +# effectiveMode: restart +# Datatype: String +# Privilege: SECURITY +ssl_cipher_suites= + #################### ### Connection Configuration #################### diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonConfig.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonConfig.java index 6a8956e423b48..73b286a30ab6e 100644 --- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonConfig.java +++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonConfig.java @@ -467,6 +467,15 @@ public class CommonConfig { /** ssl trust Store password. */ private String trustStorePwd = ""; + /** SSL protocol. */ + private String sslProtocol = "TLS"; + + /** SSL provider class. */ + private String sslProviderClass = ""; + + /** SSL cipher suites. */ + private String sslCipherSuites = ""; + private String userEncryptTokenHint = "not set yet"; private boolean enforceStrongPassword = false; @@ -2813,6 +2822,30 @@ public void setTrustStorePwd(String trustStorePwd) { this.trustStorePwd = trustStorePwd; } + public String getSslProtocol() { + return sslProtocol; + } + + public void setSslProtocol(String sslProtocol) { + this.sslProtocol = sslProtocol; + } + + public String getSslProviderClass() { + return sslProviderClass; + } + + public void setSslProviderClass(String sslProviderClass) { + this.sslProviderClass = sslProviderClass; + } + + public String getSslCipherSuites() { + return sslCipherSuites; + } + + public void setSslCipherSuites(String sslCipherSuites) { + this.sslCipherSuites = sslCipherSuites; + } + public boolean isEnforceStrongPassword() { return enforceStrongPassword; } diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonDescriptor.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonDescriptor.java index 5cd954a09f7b8..aad31835a28e0 100644 --- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonDescriptor.java +++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonDescriptor.java @@ -24,6 +24,7 @@ import org.apache.iotdb.commons.utils.CommonDateTimeUtils; import org.apache.iotdb.confignode.rpc.thrift.TAuditConfig; import org.apache.iotdb.confignode.rpc.thrift.TGlobalConfig; +import org.apache.iotdb.rpc.RpcSslUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -521,5 +522,16 @@ public void initThriftSSL(TrimProperties properties) { config.setTrustStorePath( properties.getProperty("trust_store_path", config.getTrustStorePath())); config.setTrustStorePwd(properties.getProperty("trust_store_pwd", config.getTrustStorePwd())); + config.setSslProtocol(properties.getProperty("ssl_protocol", config.getSslProtocol())); + config.setSslProviderClass( + properties.getProperty("ssl_provider_class", config.getSslProviderClass())); + config.setSslCipherSuites( + properties.getProperty("ssl_cipher_suites", config.getSslCipherSuites())); + configureRpcSsl(); + } + + public void configureRpcSsl() { + RpcSslUtils.configure( + config.getSslProtocol(), config.getSslProviderClass(), config.getSslCipherSuites()); } } diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/service/AbstractThriftServiceThread.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/service/AbstractThriftServiceThread.java index 84361727a32e0..cd2716108cebd 100644 --- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/service/AbstractThriftServiceThread.java +++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/service/AbstractThriftServiceThread.java @@ -24,6 +24,7 @@ import org.apache.iotdb.commons.conf.IoTDBConstant; import org.apache.iotdb.commons.exception.runtime.RPCServiceException; import org.apache.iotdb.commons.i18n.ServiceMessages; +import org.apache.iotdb.rpc.RpcSslUtils; import org.apache.thrift.TBaseAsyncProcessor; import org.apache.thrift.TProcessor; @@ -45,13 +46,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.net.InetSocketAddress; -import java.nio.file.AccessDeniedException; -import java.security.KeyStore; -import java.security.cert.X509Certificate; -import java.util.Enumeration; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; @@ -184,13 +179,13 @@ protected AbstractThriftServiceThread( this.serviceName = serviceName; try { - validateCertificate(keyStorePath, keyStorePwd); + RpcSslUtils.validateKeyStore(keyStorePath, keyStorePwd); TSSLTransportFactory.TSSLTransportParameters params = - new TSSLTransportFactory.TSSLTransportParameters(); - params.setKeyStore(keyStorePath, keyStorePwd); + RpcSslUtils.createTSSLTransportParameters(); + RpcSslUtils.setKeyStore(params, keyStorePath, keyStorePwd); if (trustStorePath != null && !trustStorePath.isEmpty()) { - validateCertificate(trustStorePath, trustStorePwd); - params.setTrustStore(trustStorePath, trustStorePwd); + RpcSslUtils.validateTrustStore(trustStorePath, trustStorePwd); + RpcSslUtils.setTrustStore(params, trustStorePath, trustStorePwd); params.requireClientAuth(true); } InetSocketAddress socketAddress = new InetSocketAddress(bindAddress, port); @@ -206,41 +201,6 @@ protected AbstractThriftServiceThread( } } - private static void validateCertificate(String keyStorePath, String keystorePassword) - throws TTransportException { - try { - KeyStore keystore = KeyStore.getInstance("JKS"); - try (FileInputStream fis = new FileInputStream(keyStorePath)) { - keystore.load(fis, keystorePassword.toCharArray()); - } - - Enumeration aliases = keystore.aliases(); - while (aliases.hasMoreElements()) { - String currentAlias = aliases.nextElement(); - checkCertificate(keystore, currentAlias); - } - } catch (AccessDeniedException e) { - throw new TTransportException(ServiceMessages.FAILED_TO_LOAD_KEYSTORE_OR_TRUSTSTORE); - } catch (FileNotFoundException e) { - throw new TTransportException(ServiceMessages.KEYSTORE_OR_TRUSTSTORE_NOT_FOUND); - } catch (Exception e) { - throw new TTransportException(e); - } - } - - private static void checkCertificate(KeyStore keystore, String alias) throws Exception { - if (!keystore.containsAlias(alias)) { - return; - } - - X509Certificate cert = (X509Certificate) keystore.getCertificate(alias); - if (cert == null) { - return; - } - - cert.checkValidity(); - } - @SuppressWarnings("squid:S107") protected AbstractThriftServiceThread( TProcessor processor, From 1b16d35390a60f65e78aa76cb37150d9b0e2dadb Mon Sep 17 00:00:00 2001 From: HTHou Date: Mon, 8 Jun 2026 10:30:05 +0800 Subject: [PATCH 02/13] Hide SSL cipher suites configuration --- .../iotdb/rpc/BaseRpcTransportFactory.java | 4 +- .../org/apache/iotdb/rpc/RpcSslUtils.java | 52 +++++-------------- .../conf/iotdb-system.properties.template | 7 --- .../iotdb/commons/conf/CommonConfig.java | 11 ---- .../iotdb/commons/conf/CommonDescriptor.java | 5 +- 5 files changed, 17 insertions(+), 62 deletions(-) diff --git a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/BaseRpcTransportFactory.java b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/BaseRpcTransportFactory.java index 58d8abbc60e1a..a3f6a3d1c88b9 100644 --- a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/BaseRpcTransportFactory.java +++ b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/BaseRpcTransportFactory.java @@ -100,7 +100,7 @@ public TTransport getTransportWithSSLConfig( String sslProviderClass) throws TTransportException { TSSLTransportFactory.TSSLTransportParameters params = - RpcSslUtils.createTSSLTransportParameters(sslProtocol, sslProviderClass, null); + RpcSslUtils.createTSSLTransportParameters(sslProtocol, sslProviderClass); RpcSslUtils.setTrustStore(params, trustStore, trustStorePwd, sslProtocol, sslProviderClass); TTransport transport = TSSLTransportFactory.getClientSocket(ip, port, timeout, params); return inner.getTransport(transport); @@ -139,7 +139,7 @@ public TTransport getTransport( String sslProviderClass) throws TTransportException { TSSLTransportFactory.TSSLTransportParameters params = - RpcSslUtils.createTSSLTransportParameters(sslProtocol, sslProviderClass, null); + RpcSslUtils.createTSSLTransportParameters(sslProtocol, sslProviderClass); if (Files.exists(Paths.get(trustStore)) && Files.exists(Paths.get(keyStore))) { RpcSslUtils.setTrustStore(params, trustStore, trustStorePwd, sslProtocol, sslProviderClass); RpcSslUtils.setKeyStore(params, keyStore, keyStorePwd, sslProtocol, sslProviderClass); diff --git a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/RpcSslUtils.java b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/RpcSslUtils.java index cfd0dca615e01..3ee311055c268 100644 --- a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/RpcSslUtils.java +++ b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/RpcSslUtils.java @@ -39,7 +39,6 @@ import java.security.Provider; import java.security.Security; import java.security.cert.X509Certificate; -import java.util.Arrays; import java.util.Enumeration; import java.util.Locale; import java.util.stream.Stream; @@ -50,17 +49,17 @@ public final class RpcSslUtils { private static final String PKCS12_STORE_TYPE = "PKCS12"; private static final String JKS_STORE_TYPE = "JKS"; - private static volatile SslConfig config = new SslConfig(DEFAULT_PROTOCOL, "", null); + private static volatile SslConfig config = new SslConfig(DEFAULT_PROTOCOL, ""); private RpcSslUtils() {} - public static void configure(String protocol, String providerClass, String cipherSuites) { - config = newSslConfig(protocol, providerClass, cipherSuites); + public static void configure(String protocol, String providerClass) { + config = newSslConfig(protocol, providerClass); } public static void ensureProvider(String protocol, String providerClass) throws TTransportException { - ensureProvider(newSslConfig(protocol, providerClass, null)); + ensureProvider(newSslConfig(protocol, providerClass)); } public static TSSLTransportFactory.TSSLTransportParameters createTSSLTransportParameters() @@ -71,15 +70,15 @@ public static TSSLTransportFactory.TSSLTransportParameters createTSSLTransportPa } public static TSSLTransportFactory.TSSLTransportParameters createTSSLTransportParameters( - String protocol, String providerClass, String cipherSuites) throws TTransportException { - SslConfig current = newSslConfig(protocol, providerClass, cipherSuites); + String protocol, String providerClass) throws TTransportException { + SslConfig current = newSslConfig(protocol, providerClass); ensureProvider(current); return createTSSLTransportParameters(current); } private static TSSLTransportFactory.TSSLTransportParameters createTSSLTransportParameters( SslConfig current) { - return new TSSLTransportFactory.TSSLTransportParameters(current.protocol, current.cipherSuites); + return new TSSLTransportFactory.TSSLTransportParameters(current.protocol, null); } public static void setKeyStore( @@ -95,7 +94,7 @@ public static void setKeyStore( String protocol, String providerClass) throws TTransportException { - setKeyStore(params, keyStorePath, keyStorePwd, newSslConfig(protocol, providerClass, null)); + setKeyStore(params, keyStorePath, keyStorePwd, newSslConfig(protocol, providerClass)); } private static void setKeyStore( @@ -131,8 +130,7 @@ public static void setTrustStore( String protocol, String providerClass) throws TTransportException { - setTrustStore( - params, trustStorePath, trustStorePwd, newSslConfig(protocol, providerClass, null)); + setTrustStore(params, trustStorePath, trustStorePwd, newSslConfig(protocol, providerClass)); } private static void setTrustStore( @@ -169,15 +167,14 @@ public static SSLContext createSSLContext( String trustStorePath, String trustStorePassword, String protocol, - String providerClass, - String cipherSuites) + String providerClass) throws GeneralSecurityException, IOException, TTransportException { return createSSLContext( keyStorePath, keyStorePassword, trustStorePath, trustStorePassword, - newSslConfig(protocol, providerClass, cipherSuites)); + newSslConfig(protocol, providerClass)); } private static SSLContext createSSLContext( @@ -213,13 +210,6 @@ public static String getProtocol() { return config.protocol; } - public static String[] getCipherSuites() { - SslConfig current = config; - return current.cipherSuites == null - ? null - : Arrays.copyOf(current.cipherSuites, current.cipherSuites.length); - } - public static boolean hasConfiguredProvider() { return hasText(config.providerClass); } @@ -372,13 +362,6 @@ private static boolean hasText(String value) { return value != null && !value.trim().isEmpty(); } - private static String[] splitCipherSuites(String cipherSuites) { - if (!hasText(cipherSuites)) { - return null; - } - return splitCommaSeparated(cipherSuites); - } - private static String[] splitProviderClasses(String providerClasses) { return splitCommaSeparated(providerClasses); } @@ -399,24 +382,17 @@ private static String[] storeTypeCandidates() { .toArray(String[]::new); } - private static SslConfig newSslConfig( - String protocol, String providerClass, String cipherSuites) { - return new SslConfig( - trimToDefault(protocol, DEFAULT_PROTOCOL), - trimToEmpty(providerClass), - splitCipherSuites(cipherSuites)); + private static SslConfig newSslConfig(String protocol, String providerClass) { + return new SslConfig(trimToDefault(protocol, DEFAULT_PROTOCOL), trimToEmpty(providerClass)); } private static final class SslConfig { private final String protocol; private final String providerClass; - private final String[] cipherSuites; - private SslConfig(String protocol, String providerClass, String[] cipherSuites) { + private SslConfig(String protocol, String providerClass) { this.protocol = protocol; this.providerClass = providerClass; - this.cipherSuites = - cipherSuites == null ? null : Arrays.copyOf(cipherSuites, cipherSuites.length); } } } diff --git a/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template b/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template index 4b9156f02dd90..c68230ebb1b2d 100644 --- a/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template +++ b/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template @@ -487,13 +487,6 @@ ssl_protocol=TLS # Privilege: SECURITY ssl_provider_class= -# Comma-separated SSL cipher suites. -# Leave empty to use the provider default. -# effectiveMode: restart -# Datatype: String -# Privilege: SECURITY -ssl_cipher_suites= - #################### ### Connection Configuration #################### diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonConfig.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonConfig.java index 73b286a30ab6e..584cdf8883d9f 100644 --- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonConfig.java +++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonConfig.java @@ -473,9 +473,6 @@ public class CommonConfig { /** SSL provider class. */ private String sslProviderClass = ""; - /** SSL cipher suites. */ - private String sslCipherSuites = ""; - private String userEncryptTokenHint = "not set yet"; private boolean enforceStrongPassword = false; @@ -2838,14 +2835,6 @@ public void setSslProviderClass(String sslProviderClass) { this.sslProviderClass = sslProviderClass; } - public String getSslCipherSuites() { - return sslCipherSuites; - } - - public void setSslCipherSuites(String sslCipherSuites) { - this.sslCipherSuites = sslCipherSuites; - } - public boolean isEnforceStrongPassword() { return enforceStrongPassword; } diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonDescriptor.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonDescriptor.java index aad31835a28e0..a382cb331a989 100644 --- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonDescriptor.java +++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonDescriptor.java @@ -525,13 +525,10 @@ public void initThriftSSL(TrimProperties properties) { config.setSslProtocol(properties.getProperty("ssl_protocol", config.getSslProtocol())); config.setSslProviderClass( properties.getProperty("ssl_provider_class", config.getSslProviderClass())); - config.setSslCipherSuites( - properties.getProperty("ssl_cipher_suites", config.getSslCipherSuites())); configureRpcSsl(); } public void configureRpcSsl() { - RpcSslUtils.configure( - config.getSslProtocol(), config.getSslProviderClass(), config.getSslCipherSuites()); + RpcSslUtils.configure(config.getSslProtocol(), config.getSslProviderClass()); } } From ed1a71ebafc225bf852f0ef23e9c9bb6174089bd Mon Sep 17 00:00:00 2001 From: HTHou Date: Mon, 8 Jun 2026 11:01:27 +0800 Subject: [PATCH 03/13] Avoid global SSL config in legacy transports --- .../iotdb/rpc/BaseRpcTransportFactory.java | 18 +++--------------- pom.xml | 2 +- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/BaseRpcTransportFactory.java b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/BaseRpcTransportFactory.java index a3f6a3d1c88b9..86a01f97461df 100644 --- a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/BaseRpcTransportFactory.java +++ b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/BaseRpcTransportFactory.java @@ -83,11 +83,7 @@ public TTransport getTransportWithNoTimeout(String ip, int port) throws TTranspo public TTransport getTransport( String ip, int port, int timeout, String trustStore, String trustStorePwd) throws TTransportException { - TSSLTransportFactory.TSSLTransportParameters params = - RpcSslUtils.createTSSLTransportParameters(); - RpcSslUtils.setTrustStore(params, trustStore, trustStorePwd); - TTransport transport = TSSLTransportFactory.getClientSocket(ip, port, timeout, params); - return inner.getTransport(transport); + return getTransportWithSSLConfig(ip, port, timeout, trustStore, trustStorePwd, null, null); } public TTransport getTransportWithSSLConfig( @@ -115,16 +111,8 @@ public TTransport getTransport( String keyStore, String keyStorePwd) throws TTransportException { - TSSLTransportFactory.TSSLTransportParameters params = - RpcSslUtils.createTSSLTransportParameters(); - if (Files.exists(Paths.get(trustStore)) && Files.exists(Paths.get(keyStore))) { - RpcSslUtils.setTrustStore(params, trustStore, trustStorePwd); - RpcSslUtils.setKeyStore(params, keyStore, keyStorePwd); - } else { - throw new TTransportException(new IOException(RpcMessages.COULD_NOT_LOAD_KEYSTORE)); - } - TTransport transport = TSSLTransportFactory.getClientSocket(ip, port, timeout, params); - return inner.getTransport(transport); + return getTransport( + ip, port, timeout, trustStore, trustStorePwd, keyStore, keyStorePwd, null, null); } public TTransport getTransport( diff --git a/pom.xml b/pom.xml index b06647be5382a..4a91224407b04 100644 --- a/pom.xml +++ b/pom.xml @@ -131,7 +131,7 @@ 1.5.6 2.0.9 1.0.11 - 3.2.2 + 3.3.0-b60fcf6-SNAPSHOT 1.0.4 1.2.9 3.7.9 From b65c79aefab37a1cd98d5b1e6b7d8f764e130577 Mon Sep 17 00:00:00 2001 From: HTHou Date: Thu, 11 Jun 2026 11:05:29 +0800 Subject: [PATCH 04/13] Refine generic SSL protocol configuration --- dependencies.json | 10 + .../org/apache/iotdb/rest/RestService.java | 22 +- .../org/apache/iotdb/cli/AbstractCli.java | 16 -- .../main/java/org/apache/iotdb/cli/Cli.java | 4 - .../apache/iotdb/tool/common/Constants.java | 4 - .../apache/iotdb/tool/common/OptionsUtil.java | 10 - .../iotdb/tool/data/AbstractDataTool.java | 14 -- .../iotdb/tool/schema/AbstractSchemaTool.java | 11 - .../apache/iotdb/isession/SessionConfig.java | 2 - .../java/org/apache/iotdb/jdbc/Config.java | 4 - .../apache/iotdb/jdbc/IoTDBConnection.java | 3 +- .../iotdb/jdbc/IoTDBConnectionParams.java | 9 - .../java/org/apache/iotdb/jdbc/Utils.java | 4 - .../java/org/apache/iotdb/jdbc/UtilsTest.java | 7 +- .../iotdb/rpc/BaseRpcTransportFactory.java | 26 +-- .../org/apache/iotdb/rpc/RpcSslUtils.java | 195 +++--------------- .../org/apache/iotdb/rpc/RpcUtilsTest.java | 15 ++ .../iotdb/session/AbstractSessionBuilder.java | 1 - .../apache/iotdb/session/NodesSupplier.java | 6 - .../org/apache/iotdb/session/Session.java | 8 - .../iotdb/session/SessionConnection.java | 19 +- .../iotdb/session/TableSessionBuilder.java | 12 -- .../iotdb/session/ThriftConnection.java | 4 +- .../iotdb/session/pool/SessionPool.java | 12 -- .../session/pool/TableSessionPoolBuilder.java | 12 -- .../client/SyncIoTConsensusServiceClient.java | 3 +- .../db/conf/rest/IoTDBRestServiceConfig.java | 11 - .../conf/rest/IoTDBRestServiceDescriptor.java | 7 +- .../db/protocol/client/ConfigNodeClient.java | 3 +- .../db/protocol/client/an/AINodeClient.java | 3 +- .../conf/iotdb-system.properties.template | 10 +- .../commons/client/sync/SyncAINodeClient.java | 3 +- .../sync/SyncConfigNodeIServiceClient.java | 3 +- .../SyncDataNodeInternalServiceClient.java | 3 +- ...cDataNodeMPPDataExchangeServiceClient.java | 3 +- .../sync/SyncIoTConsensusV2ServiceClient.java | 3 +- .../iotdb/commons/conf/CommonConfig.java | 11 - .../iotdb/commons/conf/CommonDescriptor.java | 8 +- 38 files changed, 103 insertions(+), 398 deletions(-) diff --git a/dependencies.json b/dependencies.json index eaaf50beae5b1..cea01d339ff64 100644 --- a/dependencies.json +++ b/dependencies.json @@ -66,6 +66,16 @@ "io.netty:netty-transport-native-kqueue", "io.netty:netty-transport-native-kqueue", "io.netty:netty-transport-native-unix-common", + "io.opentelemetry:opentelemetry-api", + "io.opentelemetry:opentelemetry-common", + "io.opentelemetry:opentelemetry-context", + "io.opentelemetry:opentelemetry-sdk", + "io.opentelemetry:opentelemetry-sdk-common", + "io.opentelemetry:opentelemetry-sdk-logs", + "io.opentelemetry:opentelemetry-sdk-metrics", + "io.opentelemetry:opentelemetry-sdk-testing", + "io.opentelemetry:opentelemetry-sdk-trace", + "io.opentelemetry.semconv:opentelemetry-semconv", "io.projectreactor:reactor-core", "io.projectreactor.netty:reactor-netty-core", "io.projectreactor.netty:reactor-netty-http", diff --git a/external-service-impl/rest/src/main/java/org/apache/iotdb/rest/RestService.java b/external-service-impl/rest/src/main/java/org/apache/iotdb/rest/RestService.java index 85d0ee4476aca..335f5f070c507 100644 --- a/external-service-impl/rest/src/main/java/org/apache/iotdb/rest/RestService.java +++ b/external-service-impl/rest/src/main/java/org/apache/iotdb/rest/RestService.java @@ -54,7 +54,6 @@ private void startSSL( String keyStorePwd, String trustStorePwd, String sslProtocol, - String sslProviderClass, int idleTime, boolean clientAuth) { server = new Server(); @@ -64,7 +63,7 @@ private void startSSL( httpsConfig.addCustomizer(new SecureRequestCustomizer()); SslContextFactory.Server sslContextFactory = new SslContextFactory.Server(); - configureSSL(sslContextFactory, sslProtocol, sslProviderClass); + configureSSL(sslContextFactory, sslProtocol); sslContextFactory.setKeyStorePath(keyStorePath); sslContextFactory.setKeyStorePassword(keyStorePwd); if (clientAuth) { @@ -130,7 +129,6 @@ public void start() { config.getKeyStorePwd(), config.getTrustStorePwd(), config.getSslProtocol(), - config.getSslProviderClass(), config.getIdleTimeoutInSeconds(), config.isClientAuth()); } else { @@ -149,21 +147,11 @@ public void stop() { } } - private void configureSSL( - SslContextFactory.Server sslContextFactory, String sslProtocol, String sslProviderClass) { - String protocol = trimToEmpty(sslProtocol); - try { - RpcSslUtils.ensureProvider(protocol, sslProviderClass); - } catch (Exception e) { - throw new IllegalArgumentException("Failed to initialize SSL provider for REST service", e); - } - if (!protocol.isEmpty()) { - sslContextFactory.setProtocol(protocol); + private void configureSSL(SslContextFactory.Server sslContextFactory, String sslProtocol) { + String protocol = RpcSslUtils.normalizeStandardTlsProtocol(sslProtocol); + sslContextFactory.setProtocol(protocol); + if (RpcSslUtils.isSpecificProtocol(protocol)) { sslContextFactory.setIncludeProtocols(protocol); } } - - private String trimToEmpty(String value) { - return value == null ? "" : value.trim(); - } } diff --git a/iotdb-client/cli/src/main/java/org/apache/iotdb/cli/AbstractCli.java b/iotdb-client/cli/src/main/java/org/apache/iotdb/cli/AbstractCli.java index 1f079450f5a54..8c45a89aead73 100644 --- a/iotdb-client/cli/src/main/java/org/apache/iotdb/cli/AbstractCli.java +++ b/iotdb-client/cli/src/main/java/org/apache/iotdb/cli/AbstractCli.java @@ -79,8 +79,6 @@ public abstract class AbstractCli { static final String SSL_PROTOCOL_ARGS = "ssl_protocol"; - static final String SSL_PROVIDER_CLASS_ARGS = "ssl_provider_class"; - private static final String EXECUTE_NAME = "execute"; private static final String USE_SSL = "use_ssl"; @@ -88,7 +86,6 @@ public abstract class AbstractCli { private static final String TRUST_STORE_PWD = "trust_store_pwd"; private static final String SSL_PROTOCOL = "ssl_protocol"; - private static final String SSL_PROVIDER_CLASS = "ssl_provider_class"; private static final String NULL = "null"; static final int CODE_OK = 0; @@ -140,8 +137,6 @@ public abstract class AbstractCli { static String trustStorePwd; // TODO: Make non-static static String sslProtocol; - // TODO: Make non-static - static String sslProviderClass; static String execute; static boolean hasExecuteSQL = false; @@ -168,8 +163,6 @@ static void init() { keywordSet.add("-" + TRUST_STORE_PWD_ARGS); keywordSet.add("-" + SSL_PROTOCOL_ARGS); keywordSet.add("--" + SSL_PROTOCOL_ARGS); - keywordSet.add("-" + SSL_PROVIDER_CLASS_ARGS); - keywordSet.add("--" + SSL_PROVIDER_CLASS_ARGS); keywordSet.add("-" + EXECUTE_ARGS); keywordSet.add("-" + ISO8601_ARGS); keywordSet.add("-" + RPC_COMPRESS_ARGS); @@ -237,15 +230,6 @@ static Options createOptions() { .build(); options.addOption(sslProtocol); - Option sslProviderClass = - Option.builder(SSL_PROVIDER_CLASS_ARGS) - .longOpt(SSL_PROVIDER_CLASS) - .argName(SSL_PROVIDER_CLASS) - .hasArg() - .desc("JSSE provider class for SSL. (optional)") - .build(); - options.addOption(sslProviderClass); - Option execute = Option.builder(EXECUTE_ARGS) .argName(EXECUTE_NAME) diff --git a/iotdb-client/cli/src/main/java/org/apache/iotdb/cli/Cli.java b/iotdb-client/cli/src/main/java/org/apache/iotdb/cli/Cli.java index f4e3e6bdfddf5..a9e911be6edc3 100644 --- a/iotdb-client/cli/src/main/java/org/apache/iotdb/cli/Cli.java +++ b/iotdb-client/cli/src/main/java/org/apache/iotdb/cli/Cli.java @@ -114,9 +114,6 @@ private static void constructProperties() { if (sslProtocol != null) { info.setProperty(Config.SSL_PROTOCOL, sslProtocol); } - if (sslProviderClass != null) { - info.setProperty(Config.SSL_PROVIDER_CLASS, sslProviderClass); - } } info.setProperty("user", username); info.setProperty("password", password); @@ -166,7 +163,6 @@ private static void serve(CliContext ctx) { try { useSsl = commandLine.getOptionValue(USE_SSL_ARGS); sslProtocol = commandLine.getOptionValue(SSL_PROTOCOL_ARGS); - sslProviderClass = commandLine.getOptionValue(SSL_PROVIDER_CLASS_ARGS); if (Boolean.parseBoolean(useSsl)) { trustStore = ctx.getLineReader().readLine("please input your trust_store:", '\0'); trustStorePwd = ctx.getLineReader().readLine("please input your trust_store_pwd:", '\0'); diff --git a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/common/Constants.java b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/common/Constants.java index 56c34dbdf0387..a106326095756 100644 --- a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/common/Constants.java +++ b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/common/Constants.java @@ -72,10 +72,6 @@ public class Constants { public static final String SSL_PROTOCOL_NAME = "ssl_protocol"; public static final String SSL_PROTOCOL_DESC = "SSL protocol. (optional)"; - public static final String SSL_PROVIDER_CLASS_ARGS = "ssl_provider_class"; - public static final String SSL_PROVIDER_CLASS_NAME = "ssl_provider_class"; - public static final String SSL_PROVIDER_CLASS_DESC = "JSSE provider class for SSL. (optional)"; - public static final String FILE_TYPE_ARGS = "ft"; public static final String FILE_TYPE_NAME = "file_type"; public static final String FILE_TYPE_ARGS_NAME = "format"; diff --git a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/common/OptionsUtil.java b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/common/OptionsUtil.java index acbac88afbed6..1f79b303f6e4e 100644 --- a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/common/OptionsUtil.java +++ b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/common/OptionsUtil.java @@ -143,16 +143,6 @@ public static Options createCommonOptions(Options options) { .build(); options.addOption(opSslProtocol); - Option opSslProviderClass = - Option.builder(SSL_PROVIDER_CLASS_ARGS) - .longOpt(SSL_PROVIDER_CLASS_NAME) - .optionalArg(true) - .argName(SSL_PROVIDER_CLASS_NAME) - .hasArg() - .desc(SSL_PROVIDER_CLASS_DESC) - .build(); - options.addOption(opSslProviderClass); - return options; } diff --git a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/AbstractDataTool.java b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/AbstractDataTool.java index 5a9b14f333715..6ea79a5b58216 100644 --- a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/AbstractDataTool.java +++ b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/AbstractDataTool.java @@ -98,7 +98,6 @@ public abstract class AbstractDataTool { protected static String trustStore; protected static String trustStorePwd; protected static String sslProtocol; - protected static String sslProviderClass; protected static Boolean aligned; protected static String database; protected static String startTime; @@ -144,9 +143,6 @@ protected static Session.Builder configureSsl(Session.Builder builder) { if (sslProtocol != null) { builder.sslProtocol(sslProtocol); } - if (sslProviderClass != null) { - builder.sslProviderClass(sslProviderClass); - } return builder; } @@ -155,9 +151,6 @@ protected static SessionPool.Builder configureSsl(SessionPool.Builder builder) { if (sslProtocol != null) { builder.sslProtocol(sslProtocol); } - if (sslProviderClass != null) { - builder.sslProviderClass(sslProviderClass); - } return builder; } @@ -166,9 +159,6 @@ protected static TableSessionBuilder configureSsl(TableSessionBuilder builder) { if (sslProtocol != null) { builder.sslProtocol(sslProtocol); } - if (sslProviderClass != null) { - builder.sslProviderClass(sslProviderClass); - } return builder; } @@ -177,9 +167,6 @@ protected static TableSessionPoolBuilder configureSsl(TableSessionPoolBuilder bu if (sslProtocol != null) { builder.sslProtocol(sslProtocol); } - if (sslProviderClass != null) { - builder.sslProviderClass(sslProviderClass); - } return builder; } @@ -220,7 +207,6 @@ protected static void parseBasicParams(CommandLine commandLine) useSsl = Boolean.parseBoolean(useSslStr); if (useSsl) { sslProtocol = commandLine.getOptionValue(Constants.SSL_PROTOCOL_ARGS); - sslProviderClass = commandLine.getOptionValue(Constants.SSL_PROVIDER_CLASS_ARGS); String givenTS = commandLine.getOptionValue(Constants.TRUST_STORE_ARGS); if (givenTS != null) { trustStore = givenTS; diff --git a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/schema/AbstractSchemaTool.java b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/schema/AbstractSchemaTool.java index 7a18b84f559e7..2bee5f5d33151 100644 --- a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/schema/AbstractSchemaTool.java +++ b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/schema/AbstractSchemaTool.java @@ -56,7 +56,6 @@ public abstract class AbstractSchemaTool { protected static String trustStore; protected static String trustStorePwd; protected static String sslProtocol; - protected static String sslProviderClass; protected static Session session; protected static String queryPath; protected static int threadNum = 8; @@ -82,9 +81,6 @@ protected static Session.Builder configureSsl(Session.Builder builder) { if (sslProtocol != null) { builder.sslProtocol(sslProtocol); } - if (sslProviderClass != null) { - builder.sslProviderClass(sslProviderClass); - } return builder; } @@ -93,9 +89,6 @@ protected static SessionPool.Builder configureSsl(SessionPool.Builder builder) { if (sslProtocol != null) { builder.sslProtocol(sslProtocol); } - if (sslProviderClass != null) { - builder.sslProviderClass(sslProviderClass); - } return builder; } @@ -104,9 +97,6 @@ protected static TableSessionPoolBuilder configureSsl(TableSessionPoolBuilder bu if (sslProtocol != null) { builder.sslProtocol(sslProtocol); } - if (sslProviderClass != null) { - builder.sslProviderClass(sslProviderClass); - } return builder; } @@ -145,7 +135,6 @@ protected static void parseBasicParams(CommandLine commandLine) useSsl = Boolean.parseBoolean(useSslStr); if (useSsl) { sslProtocol = commandLine.getOptionValue(Constants.SSL_PROTOCOL_ARGS); - sslProviderClass = commandLine.getOptionValue(Constants.SSL_PROVIDER_CLASS_ARGS); String givenTS = commandLine.getOptionValue(Constants.TRUST_STORE_ARGS); if (givenTS != null) { trustStore = givenTS; diff --git a/iotdb-client/isession/src/main/java/org/apache/iotdb/isession/SessionConfig.java b/iotdb-client/isession/src/main/java/org/apache/iotdb/isession/SessionConfig.java index 0a577c45f2d74..7885d50cf5da1 100644 --- a/iotdb-client/isession/src/main/java/org/apache/iotdb/isession/SessionConfig.java +++ b/iotdb-client/isession/src/main/java/org/apache/iotdb/isession/SessionConfig.java @@ -58,7 +58,5 @@ public class SessionConfig { public static final String DEFAULT_SSL_PROTOCOL = "TLS"; - public static final String DEFAULT_SSL_PROVIDER_CLASS = ""; - private SessionConfig() {} } diff --git a/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/Config.java b/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/Config.java index 5aaf0f6836641..d79656cc8d295 100644 --- a/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/Config.java +++ b/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/Config.java @@ -84,12 +84,8 @@ private Config() { public static final String SSL_PROTOCOL = "ssl_protocol"; - public static final String SSL_PROVIDER_CLASS = "ssl_provider_class"; - static final String DEFAULT_SSL_PROTOCOL = "TLS"; - static final String DEFAULT_SSL_PROVIDER_CLASS = ""; - public static final String SQL_DIALECT = "sql_dialect"; public static final String DATABASE = "db"; diff --git a/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBConnection.java b/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBConnection.java index 9b95939864d4a..0dc81115dd01b 100644 --- a/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBConnection.java +++ b/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBConnection.java @@ -550,8 +550,7 @@ private void openTransport() throws TTransportException { getNetworkTimeout(), params.getTrustStore(), params.getTrustStorePwd(), - params.getSslProtocol(), - params.getSslProviderClass()); + params.getSslProtocol()); } else { transport = DeepCopyRpcTransportFactory.INSTANCE.getTransport( diff --git a/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBConnectionParams.java b/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBConnectionParams.java index 4ae629e74b17c..8bf51379c5c2a 100644 --- a/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBConnectionParams.java +++ b/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBConnectionParams.java @@ -52,7 +52,6 @@ public class IoTDBConnectionParams { private String trustStore; private String trustStorePwd; private String sslProtocol = Config.DEFAULT_SSL_PROTOCOL; - private String sslProviderClass = Config.DEFAULT_SSL_PROVIDER_CLASS; private String sqlDialect = TREE; @@ -194,14 +193,6 @@ public void setSslProtocol(String sslProtocol) { this.sslProtocol = sslProtocol; } - public String getSslProviderClass() { - return sslProviderClass; - } - - public void setSslProviderClass(String sslProviderClass) { - this.sslProviderClass = sslProviderClass; - } - public String getSqlDialect() { return sqlDialect; } diff --git a/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/Utils.java b/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/Utils.java index 8bd394cf11547..16d84b81e9d2f 100644 --- a/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/Utils.java +++ b/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/Utils.java @@ -139,9 +139,6 @@ static IoTDBConnectionParams parseUrl(String url, Properties info) throws IoTDBU if (info.containsKey(Config.SSL_PROTOCOL)) { params.setSslProtocol(info.getProperty(Config.SSL_PROTOCOL)); } - if (info.containsKey(Config.SSL_PROVIDER_CLASS)) { - params.setSslProviderClass(info.getProperty(Config.SSL_PROVIDER_CLASS)); - } if (info.containsKey(Config.SQL_DIALECT)) { params.setSqlDialect(info.getProperty(Config.SQL_DIALECT)); } @@ -182,7 +179,6 @@ private static boolean parseUrlParam(String subURL, Properties info) { case Config.TRUST_STORE: case Config.TRUST_STORE_PWD: case Config.SSL_PROTOCOL: - case Config.SSL_PROVIDER_CLASS: case Config.VERSION: case Config.NETWORK_TIMEOUT: case Config.SQL_DIALECT: diff --git a/iotdb-client/jdbc/src/test/java/org/apache/iotdb/jdbc/UtilsTest.java b/iotdb-client/jdbc/src/test/java/org/apache/iotdb/jdbc/UtilsTest.java index 32dd7a78a6dd7..f2eb5a25629c7 100644 --- a/iotdb-client/jdbc/src/test/java/org/apache/iotdb/jdbc/UtilsTest.java +++ b/iotdb-client/jdbc/src/test/java/org/apache/iotdb/jdbc/UtilsTest.java @@ -165,12 +165,9 @@ public void testParseSslConfig() throws IoTDBURLException { Properties properties = new Properties(); IoTDBConnectionParams params = Utils.parseUrl( - "jdbc:iotdb://127.0.0.1:6667?use_ssl=true&ssl_protocol=TLSv1.3" - + "&ssl_provider_class=com.example.ssl.Provider", - properties); + "jdbc:iotdb://127.0.0.1:6667?use_ssl=true&ssl_protocol=CUSTOMv1", properties); assertTrue(params.isUseSSL()); - assertEquals("TLSv1.3", params.getSslProtocol()); - assertEquals("com.example.ssl.Provider", params.getSslProviderClass()); + assertEquals("CUSTOMv1", params.getSslProtocol()); } } diff --git a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/BaseRpcTransportFactory.java b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/BaseRpcTransportFactory.java index 86a01f97461df..03bf2070bca98 100644 --- a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/BaseRpcTransportFactory.java +++ b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/BaseRpcTransportFactory.java @@ -83,21 +83,15 @@ public TTransport getTransportWithNoTimeout(String ip, int port) throws TTranspo public TTransport getTransport( String ip, int port, int timeout, String trustStore, String trustStorePwd) throws TTransportException { - return getTransportWithSSLConfig(ip, port, timeout, trustStore, trustStorePwd, null, null); + return getTransportWithSSLConfig(ip, port, timeout, trustStore, trustStorePwd, null); } public TTransport getTransportWithSSLConfig( - String ip, - int port, - int timeout, - String trustStore, - String trustStorePwd, - String sslProtocol, - String sslProviderClass) + String ip, int port, int timeout, String trustStore, String trustStorePwd, String sslProtocol) throws TTransportException { TSSLTransportFactory.TSSLTransportParameters params = - RpcSslUtils.createTSSLTransportParameters(sslProtocol, sslProviderClass); - RpcSslUtils.setTrustStore(params, trustStore, trustStorePwd, sslProtocol, sslProviderClass); + RpcSslUtils.createTSSLTransportParameters(sslProtocol); + RpcSslUtils.setTrustStore(params, trustStore, trustStorePwd); TTransport transport = TSSLTransportFactory.getClientSocket(ip, port, timeout, params); return inner.getTransport(transport); } @@ -111,8 +105,7 @@ public TTransport getTransport( String keyStore, String keyStorePwd) throws TTransportException { - return getTransport( - ip, port, timeout, trustStore, trustStorePwd, keyStore, keyStorePwd, null, null); + return getTransport(ip, port, timeout, trustStore, trustStorePwd, keyStore, keyStorePwd, null); } public TTransport getTransport( @@ -123,14 +116,13 @@ public TTransport getTransport( String trustStorePwd, String keyStore, String keyStorePwd, - String sslProtocol, - String sslProviderClass) + String sslProtocol) throws TTransportException { TSSLTransportFactory.TSSLTransportParameters params = - RpcSslUtils.createTSSLTransportParameters(sslProtocol, sslProviderClass); + RpcSslUtils.createTSSLTransportParameters(sslProtocol); if (Files.exists(Paths.get(trustStore)) && Files.exists(Paths.get(keyStore))) { - RpcSslUtils.setTrustStore(params, trustStore, trustStorePwd, sslProtocol, sslProviderClass); - RpcSslUtils.setKeyStore(params, keyStore, keyStorePwd, sslProtocol, sslProviderClass); + RpcSslUtils.setTrustStore(params, trustStore, trustStorePwd); + RpcSslUtils.setKeyStore(params, keyStore, keyStorePwd); } else { throw new TTransportException(new IOException(RpcMessages.COULD_NOT_LOAD_KEYSTORE)); } diff --git a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/RpcSslUtils.java b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/RpcSslUtils.java index 3ee311055c268..ae0f0ec748763 100644 --- a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/RpcSslUtils.java +++ b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/RpcSslUtils.java @@ -25,19 +25,15 @@ import javax.net.ssl.KeyManager; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLEngine; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; -import java.lang.reflect.Constructor; import java.nio.file.AccessDeniedException; import java.security.GeneralSecurityException; import java.security.KeyStore; -import java.security.Provider; -import java.security.Security; import java.security.cert.X509Certificate; import java.util.Enumeration; import java.util.Locale; @@ -49,62 +45,27 @@ public final class RpcSslUtils { private static final String PKCS12_STORE_TYPE = "PKCS12"; private static final String JKS_STORE_TYPE = "JKS"; - private static volatile SslConfig config = new SslConfig(DEFAULT_PROTOCOL, ""); + private static volatile String protocol = DEFAULT_PROTOCOL; private RpcSslUtils() {} - public static void configure(String protocol, String providerClass) { - config = newSslConfig(protocol, providerClass); + public static void configure(String sslProtocol) { + protocol = normalizeProtocol(sslProtocol); } - public static void ensureProvider(String protocol, String providerClass) - throws TTransportException { - ensureProvider(newSslConfig(protocol, providerClass)); - } - - public static TSSLTransportFactory.TSSLTransportParameters createTSSLTransportParameters() - throws TTransportException { - SslConfig current = config; - ensureProvider(current); - return createTSSLTransportParameters(current); + public static TSSLTransportFactory.TSSLTransportParameters createTSSLTransportParameters() { + return createTSSLTransportParameters(protocol); } public static TSSLTransportFactory.TSSLTransportParameters createTSSLTransportParameters( - String protocol, String providerClass) throws TTransportException { - SslConfig current = newSslConfig(protocol, providerClass); - ensureProvider(current); - return createTSSLTransportParameters(current); - } - - private static TSSLTransportFactory.TSSLTransportParameters createTSSLTransportParameters( - SslConfig current) { - return new TSSLTransportFactory.TSSLTransportParameters(current.protocol, null); + String sslProtocol) { + return new TSSLTransportFactory.TSSLTransportParameters(normalizeProtocol(sslProtocol), null); } public static void setKeyStore( TSSLTransportFactory.TSSLTransportParameters params, String keyStorePath, String keyStorePwd) throws TTransportException { - setKeyStore(params, keyStorePath, keyStorePwd, config); - } - - public static void setKeyStore( - TSSLTransportFactory.TSSLTransportParameters params, - String keyStorePath, - String keyStorePwd, - String protocol, - String providerClass) - throws TTransportException { - setKeyStore(params, keyStorePath, keyStorePwd, newSslConfig(protocol, providerClass)); - } - - private static void setKeyStore( - TSSLTransportFactory.TSSLTransportParameters params, - String keyStorePath, - String keyStorePwd, - SslConfig current) - throws TTransportException { try { - ensureProvider(current); params.setKeyStore( keyStorePath, keyStorePwd, @@ -120,27 +81,7 @@ public static void setTrustStore( String trustStorePath, String trustStorePwd) throws TTransportException { - setTrustStore(params, trustStorePath, trustStorePwd, config); - } - - public static void setTrustStore( - TSSLTransportFactory.TSSLTransportParameters params, - String trustStorePath, - String trustStorePwd, - String protocol, - String providerClass) - throws TTransportException { - setTrustStore(params, trustStorePath, trustStorePwd, newSslConfig(protocol, providerClass)); - } - - private static void setTrustStore( - TSSLTransportFactory.TSSLTransportParameters params, - String trustStorePath, - String trustStorePwd, - SslConfig current) - throws TTransportException { try { - ensureProvider(current); params.setTrustStore( trustStorePath, trustStorePwd, @@ -156,9 +97,9 @@ public static SSLContext createSSLContext( String keyStorePassword, String trustStorePath, String trustStorePassword) - throws GeneralSecurityException, IOException, TTransportException { + throws GeneralSecurityException, IOException { return createSSLContext( - keyStorePath, keyStorePassword, trustStorePath, trustStorePassword, config); + keyStorePath, keyStorePassword, trustStorePath, trustStorePassword, protocol); } public static SSLContext createSSLContext( @@ -166,26 +107,9 @@ public static SSLContext createSSLContext( String keyStorePassword, String trustStorePath, String trustStorePassword, - String protocol, - String providerClass) - throws GeneralSecurityException, IOException, TTransportException { - return createSSLContext( - keyStorePath, - keyStorePassword, - trustStorePath, - trustStorePassword, - newSslConfig(protocol, providerClass)); - } - - private static SSLContext createSSLContext( - String keyStorePath, - String keyStorePassword, - String trustStorePath, - String trustStorePassword, - SslConfig current) - throws GeneralSecurityException, IOException, TTransportException { - ensureProvider(current); - SSLContext context = newSSLContext(current); + String sslProtocol) + throws GeneralSecurityException, IOException { + SSLContext context = SSLContext.getInstance(normalizeProtocol(sslProtocol)); KeyManager[] keyManagers = hasText(keyStorePath) ? loadKeyManagers(keyStorePath, keyStorePassword) : null; TrustManager[] trustManagers = @@ -195,44 +119,36 @@ private static SSLContext createSSLContext( } public static KeyManager[] createKeyManagers(String keyStorePath, String keyStorePassword) - throws GeneralSecurityException, IOException, TTransportException { - ensureProvider(config); + throws GeneralSecurityException, IOException { return loadKeyManagers(keyStorePath, keyStorePassword); } public static TrustManager[] createTrustManagers(String trustStorePath, String trustStorePassword) - throws GeneralSecurityException, IOException, TTransportException { - ensureProvider(config); + throws GeneralSecurityException, IOException { return loadTrustManagers(trustStorePath, trustStorePassword); } public static String getProtocol() { - return config.protocol; + return protocol; } - public static boolean hasConfiguredProvider() { - return hasText(config.providerClass); + public static boolean isSpecificProtocol(String sslProtocol) { + String trimmed = trimToEmpty(sslProtocol); + return !trimmed.isEmpty() && !DEFAULT_PROTOCOL.equals(trimmed.toUpperCase(Locale.ROOT)); } - public static String getSSLContextProviderName() throws TTransportException { - ensureProvider(config); - try { - return newSSLContext(config).getProvider().getName(); - } catch (GeneralSecurityException e) { - throw new TTransportException("Failed to initialize SSL context", e); + public static String normalizeStandardTlsProtocol(String sslProtocol) { + String protocol = normalizeProtocol(sslProtocol); + if (!isStandardTlsProtocol(protocol)) { + throw new IllegalArgumentException( + "Unsupported SSL protocol " + protocol + ". Only standard TLS protocols are supported."); } + return protocol; } - public static String[] getEnabledCipherSuites() throws TTransportException { - ensureProvider(config); - try { - SSLContext context = newSSLContext(config); - context.init(null, null, null); - SSLEngine engine = context.createSSLEngine(); - return engine.getEnabledCipherSuites(); - } catch (GeneralSecurityException e) { - throw new TTransportException("Failed to initialize SSL context", e); - } + public static boolean isStandardTlsProtocol(String sslProtocol) { + String protocol = normalizeProtocol(sslProtocol).toUpperCase(Locale.ROOT); + return DEFAULT_PROTOCOL.equals(protocol) || protocol.matches("TLSV\\d+(\\.\\d+)*"); } public static void validateKeyStore(String keyStorePath, String keyStorePassword) @@ -262,10 +178,6 @@ private static TrustManager[] loadTrustManagers(String trustStorePath, String tr return tmf.getTrustManagers(); } - private static SSLContext newSSLContext(SslConfig current) throws GeneralSecurityException { - return SSLContext.getInstance(current.protocol); - } - private static String detectStoreType(String storePath, String storePassword) throws GeneralSecurityException, IOException { return loadStore(storePath, storePassword).getType(); @@ -308,7 +220,6 @@ private static KeyStore loadStore(String storePath, String storePassword, String private static void validateStore(String storePath, String storePassword) throws TTransportException { try { - ensureProvider(config); KeyStore store = loadStore(storePath, storePassword); Enumeration aliases = store.aliases(); while (aliases.hasMoreElements()) { @@ -322,36 +233,13 @@ private static void validateStore(String storePath, String storePassword) } } - private static synchronized void ensureProvider(SslConfig current) throws TTransportException { - if (!hasText(current.providerClass)) { - return; - } - try { - String[] providerClassNames = splitProviderClasses(current.providerClass); - for (int i = providerClassNames.length - 1; i >= 0; i--) { - String providerClassName = providerClassNames[i]; - Class providerClass = Class.forName(providerClassName); - Constructor constructor = providerClass.getDeclaredConstructor(); - constructor.setAccessible(true); - Provider provider = (Provider) constructor.newInstance(); - Provider firstProvider = Security.getProviders()[0]; - if (!provider.getName().equals(firstProvider.getName())) { - Security.removeProvider(provider.getName()); - Security.insertProviderAt(provider, 1); - } - } - } catch (Exception e) { - throw new TTransportException("Failed to initialize SSL provider", e); - } - } - private static char[] toPassword(String password) { return password == null ? null : password.toCharArray(); } - private static String trimToDefault(String value, String defaultValue) { + private static String normalizeProtocol(String value) { String trimmed = trimToEmpty(value); - return trimmed.isEmpty() ? defaultValue : trimmed; + return trimmed.isEmpty() ? DEFAULT_PROTOCOL : trimmed; } private static String trimToEmpty(String value) { @@ -362,17 +250,6 @@ private static boolean hasText(String value) { return value != null && !value.trim().isEmpty(); } - private static String[] splitProviderClasses(String providerClasses) { - return splitCommaSeparated(providerClasses); - } - - private static String[] splitCommaSeparated(String value) { - return Stream.of(value.split(",")) - .map(String::trim) - .filter(s -> !s.isEmpty()) - .toArray(String[]::new); - } - private static String[] storeTypeCandidates() { return Stream.of(KeyStore.getDefaultType(), PKCS12_STORE_TYPE, JKS_STORE_TYPE) .map(String::trim) @@ -381,18 +258,4 @@ private static String[] storeTypeCandidates() { .distinct() .toArray(String[]::new); } - - private static SslConfig newSslConfig(String protocol, String providerClass) { - return new SslConfig(trimToDefault(protocol, DEFAULT_PROTOCOL), trimToEmpty(providerClass)); - } - - private static final class SslConfig { - private final String protocol; - private final String providerClass; - - private SslConfig(String protocol, String providerClass) { - this.protocol = protocol; - this.providerClass = providerClass; - } - } } diff --git a/iotdb-client/service-rpc/src/test/java/org/apache/iotdb/rpc/RpcUtilsTest.java b/iotdb-client/service-rpc/src/test/java/org/apache/iotdb/rpc/RpcUtilsTest.java index a698027607455..c0f823bd347a2 100644 --- a/iotdb-client/service-rpc/src/test/java/org/apache/iotdb/rpc/RpcUtilsTest.java +++ b/iotdb-client/service-rpc/src/test/java/org/apache/iotdb/rpc/RpcUtilsTest.java @@ -74,4 +74,19 @@ public void testIsSetSqlDialect() { Assert.assertFalse(RpcUtils.isSetSqlDialect("setsql_dialect =table")); Assert.assertFalse(RpcUtils.isSetSqlDialect("set sql_dia")); } + + @Test + public void testStandardTlsProtocol() { + Assert.assertEquals("TLS", RpcSslUtils.normalizeStandardTlsProtocol(null)); + Assert.assertEquals("TLSv1.3", RpcSslUtils.normalizeStandardTlsProtocol(" TLSv1.3 ")); + Assert.assertTrue(RpcSslUtils.isStandardTlsProtocol("TLSv1.2")); + Assert.assertFalse(RpcSslUtils.isStandardTlsProtocol("CUSTOMv1")); + + try { + RpcSslUtils.normalizeStandardTlsProtocol("CUSTOMv1"); + Assert.fail(); + } catch (IllegalArgumentException e) { + Assert.assertTrue(e.getMessage().contains("Only standard TLS protocols are supported")); + } + } } diff --git a/iotdb-client/session/src/main/java/org/apache/iotdb/session/AbstractSessionBuilder.java b/iotdb-client/session/src/main/java/org/apache/iotdb/session/AbstractSessionBuilder.java index 2fe601f994dbb..0ce0293ab42fc 100644 --- a/iotdb-client/session/src/main/java/org/apache/iotdb/session/AbstractSessionBuilder.java +++ b/iotdb-client/session/src/main/java/org/apache/iotdb/session/AbstractSessionBuilder.java @@ -63,7 +63,6 @@ public abstract class AbstractSessionBuilder { public String trustStore; public String trustStorePwd; public String sslProtocol = SessionConfig.DEFAULT_SSL_PROTOCOL; - public String sslProviderClass = SessionConfig.DEFAULT_SSL_PROVIDER_CLASS; // max retry count, if set to 0, means that we won't do any retry // we can use any available DataNodes(fetched in background thread if enableAutoFetch is true, diff --git a/iotdb-client/session/src/main/java/org/apache/iotdb/session/NodesSupplier.java b/iotdb-client/session/src/main/java/org/apache/iotdb/session/NodesSupplier.java index c6c2288b8b2d2..a41db581e9cc7 100644 --- a/iotdb-client/session/src/main/java/org/apache/iotdb/session/NodesSupplier.java +++ b/iotdb-client/session/src/main/java/org/apache/iotdb/session/NodesSupplier.java @@ -62,7 +62,6 @@ public class NodesSupplier implements INodeSupplier, Runnable { private final String trustStore; private final String trustStorePwd; private final String sslProtocol; - private final String sslProviderClass; private final boolean enableRPCCompression; private final String userName; @@ -98,7 +97,6 @@ public static NodesSupplier createNodeSupplier( String trustStore, String trustStorePwd, String sslProtocol, - String sslProviderClass, boolean enableRPCCompression, String version) { @@ -115,7 +113,6 @@ public static NodesSupplier createNodeSupplier( trustStore, trustStorePwd, sslProtocol, - sslProviderClass, enableRPCCompression, version); @@ -139,7 +136,6 @@ private NodesSupplier( String trustStore, String trustStorePwd, String sslProtocol, - String sslProviderClass, boolean enableRPCCompression, String version) { this.availableNodes.addAll(new HashSet<>(endPointList)); @@ -149,7 +145,6 @@ private NodesSupplier( this.trustStore = trustStore; this.trustStorePwd = trustStorePwd; this.sslProtocol = sslProtocol; - this.sslProviderClass = sslProviderClass; this.enableRPCCompression = enableRPCCompression; this.zoneId = zoneId == null ? ZoneId.systemDefault() : zoneId; this.thriftDefaultBufferSize = thriftDefaultBufferSize; @@ -199,7 +194,6 @@ private boolean createConnection(TEndPoint endPoint) { trustStore, trustStorePwd, sslProtocol, - sslProviderClass, userName, password, enableRPCCompression, diff --git a/iotdb-client/session/src/main/java/org/apache/iotdb/session/Session.java b/iotdb-client/session/src/main/java/org/apache/iotdb/session/Session.java index 81798b046ba9e..6dd0d4fb46a27 100644 --- a/iotdb-client/session/src/main/java/org/apache/iotdb/session/Session.java +++ b/iotdb-client/session/src/main/java/org/apache/iotdb/session/Session.java @@ -134,7 +134,6 @@ public class Session implements ISession { protected String trustStore; protected String trustStorePwd; protected String sslProtocol; - protected String sslProviderClass; /** * Timeout of query can be set by users. A negative number means using the default configuration @@ -475,7 +474,6 @@ public Session(AbstractSessionBuilder builder) { this.trustStore = builder.trustStore; this.trustStorePwd = builder.trustStorePwd; this.sslProtocol = builder.sslProtocol; - this.sslProviderClass = builder.sslProviderClass; this.enableAutoFetch = builder.enableAutoFetch; this.maxRetryCount = builder.maxRetryCount; this.retryIntervalInMs = builder.retryIntervalInMs; @@ -546,7 +544,6 @@ public synchronized void open(boolean enableRPCCompaction, int connectionTimeout trustStore, trustStorePwd, sslProtocol, - sslProviderClass, enableRPCCompaction, version.toString()); } else { @@ -4444,11 +4441,6 @@ public Builder sslProtocol(String sslProtocol) { return this; } - public Builder sslProviderClass(String sslProviderClass) { - this.sslProviderClass = sslProviderClass; - return this; - } - public Session build() { if (nodeUrls != null && (!SessionConfig.DEFAULT_HOST.equals(host) || rpcPort != SessionConfig.DEFAULT_PORT)) { diff --git a/iotdb-client/session/src/main/java/org/apache/iotdb/session/SessionConnection.java b/iotdb-client/session/src/main/java/org/apache/iotdb/session/SessionConnection.java index e12ccdcc0c5e2..e6dc09b962b50 100644 --- a/iotdb-client/session/src/main/java/org/apache/iotdb/session/SessionConnection.java +++ b/iotdb-client/session/src/main/java/org/apache/iotdb/session/SessionConnection.java @@ -152,12 +152,7 @@ public SessionConnection( this.database = database; try { init( - endPoint, - session.useSSL, - session.trustStore, - session.trustStorePwd, - session.sslProtocol, - session.sslProviderClass); + endPoint, session.useSSL, session.trustStore, session.trustStorePwd, session.sslProtocol); } catch (StatementExecutionException e) { throw new IoTDBConnectionException(e.getMessage()); } catch (IoTDBConnectionException e) { @@ -190,8 +185,7 @@ private void init( boolean useSSL, String trustStore, String trustStorePwd, - String sslProtocol, - String sslProviderClass) + String sslProtocol) throws IoTDBConnectionException, StatementExecutionException { DeepCopyRpcTransportFactory.setDefaultBufferCapacity(session.thriftDefaultBufferSize); DeepCopyRpcTransportFactory.setThriftMaxFrameSize(session.thriftMaxFrameSize); @@ -207,8 +201,7 @@ private void init( session.connectionTimeoutInMs, trustStore, trustStorePwd, - sslProtocol, - sslProviderClass); + sslProtocol); } else { transport = DeepCopyRpcTransportFactory.INSTANCE.getTransport( @@ -281,8 +274,7 @@ private void initClusterConn() throws IoTDBConnectionException { session.useSSL, session.trustStore, session.trustStorePwd, - session.sslProtocol, - session.sslProviderClass); + session.sslProtocol); } catch (IoTDBConnectionException e) { if (!reconnect()) { logger.error(SessionMessages.CLUSTER_NO_NODES); @@ -1104,8 +1096,7 @@ private boolean reconnect() { session.useSSL, session.trustStore, session.trustStorePwd, - session.sslProtocol, - session.sslProviderClass); + session.sslProtocol); connectedSuccess = true; } catch (IoTDBConnectionException e) { logger.warn(SessionMessages.NODE_DOWN_TRY_NEXT, endPoint); diff --git a/iotdb-client/session/src/main/java/org/apache/iotdb/session/TableSessionBuilder.java b/iotdb-client/session/src/main/java/org/apache/iotdb/session/TableSessionBuilder.java index bc8ec1a1643a2..e724c0fd53220 100644 --- a/iotdb-client/session/src/main/java/org/apache/iotdb/session/TableSessionBuilder.java +++ b/iotdb-client/session/src/main/java/org/apache/iotdb/session/TableSessionBuilder.java @@ -251,18 +251,6 @@ public TableSessionBuilder sslProtocol(String sslProtocol) { return this; } - /** - * Sets the JSSE provider class for SSL connections. - * - * @param sslProviderClass the JSSE provider class. - * @return the current {@link TableSessionBuilder} instance. - * @defaultValue empty - */ - public TableSessionBuilder sslProviderClass(String sslProviderClass) { - this.sslProviderClass = sslProviderClass; - return this; - } - /** * Enables or disables rpc compression for the connection. * diff --git a/iotdb-client/session/src/main/java/org/apache/iotdb/session/ThriftConnection.java b/iotdb-client/session/src/main/java/org/apache/iotdb/session/ThriftConnection.java index 251ed3566cbe1..3ab3abd581d9a 100644 --- a/iotdb-client/session/src/main/java/org/apache/iotdb/session/ThriftConnection.java +++ b/iotdb-client/session/src/main/java/org/apache/iotdb/session/ThriftConnection.java @@ -79,7 +79,6 @@ public void init( String trustStore, String trustStorePwd, String sslProtocol, - String sslProviderClass, String username, String password, boolean enableRPCCompression, @@ -97,8 +96,7 @@ public void init( connectionTimeoutInMs, trustStore, trustStorePwd, - sslProtocol, - sslProviderClass); + sslProtocol); } else { transport = DeepCopyRpcTransportFactory.INSTANCE.getTransport( diff --git a/iotdb-client/session/src/main/java/org/apache/iotdb/session/pool/SessionPool.java b/iotdb-client/session/src/main/java/org/apache/iotdb/session/pool/SessionPool.java index d7975f9b29121..8136b2be68fd1 100644 --- a/iotdb-client/session/src/main/java/org/apache/iotdb/session/pool/SessionPool.java +++ b/iotdb-client/session/src/main/java/org/apache/iotdb/session/pool/SessionPool.java @@ -119,8 +119,6 @@ public class SessionPool implements ISessionPool { private String sslProtocol = SessionConfig.DEFAULT_SSL_PROTOCOL; - private String sslProviderClass = SessionConfig.DEFAULT_SSL_PROVIDER_CLASS; - private ZoneId zoneId; // this field only take effect in write request, nothing to do with any other type requests, // like query, load and so on. @@ -472,7 +470,6 @@ public SessionPool( this.trustStore = trustStore; this.trustStorePwd = trustStorePwd; this.sslProtocol = SessionConfig.DEFAULT_SSL_PROTOCOL; - this.sslProviderClass = SessionConfig.DEFAULT_SSL_PROVIDER_CLASS; initThreadPool(); initAvailableNodes(Collections.singletonList(new TEndPoint(host, port))); } @@ -544,7 +541,6 @@ public SessionPool(AbstractSessionPoolBuilder builder) { this.trustStore = builder.trustStore; this.trustStorePwd = builder.trustStorePwd; this.sslProtocol = builder.sslProtocol; - this.sslProviderClass = builder.sslProviderClass; this.maxRetryCount = builder.maxRetryCount; this.retryIntervalInMs = builder.retryIntervalInMs; this.sqlDialect = builder.sqlDialect; @@ -603,7 +599,6 @@ private Session constructNewSession() { .trustStore(trustStore) .trustStorePwd(trustStorePwd) .sslProtocol(sslProtocol) - .sslProviderClass(sslProviderClass) .maxRetryCount(maxRetryCount) .retryIntervalInMs(retryIntervalInMs) .sqlDialect(sqlDialect) @@ -630,7 +625,6 @@ private Session constructNewSession() { .trustStore(trustStore) .trustStorePwd(trustStorePwd) .sslProtocol(sslProtocol) - .sslProviderClass(sslProviderClass) .maxRetryCount(maxRetryCount) .retryIntervalInMs(retryIntervalInMs) .sqlDialect(sqlDialect) @@ -676,7 +670,6 @@ private void initAvailableNodes(List endPointList) { trustStore, trustStorePwd, sslProtocol, - sslProviderClass, enableThriftCompression, version.toString()); } @@ -3657,11 +3650,6 @@ public Builder sslProtocol(String sslProtocol) { return this; } - public Builder sslProviderClass(String sslProviderClass) { - this.sslProviderClass = sslProviderClass; - return this; - } - public Builder host(String host) { this.host = host; return this; diff --git a/iotdb-client/session/src/main/java/org/apache/iotdb/session/pool/TableSessionPoolBuilder.java b/iotdb-client/session/src/main/java/org/apache/iotdb/session/pool/TableSessionPoolBuilder.java index ea02d8cf28cdf..2c7aba1a45213 100644 --- a/iotdb-client/session/src/main/java/org/apache/iotdb/session/pool/TableSessionPoolBuilder.java +++ b/iotdb-client/session/src/main/java/org/apache/iotdb/session/pool/TableSessionPoolBuilder.java @@ -293,18 +293,6 @@ public TableSessionPoolBuilder sslProtocol(String sslProtocol) { return this; } - /** - * Sets the JSSE provider class for SSL connections. - * - * @param sslProviderClass the JSSE provider class. - * @return the current {@link TableSessionPoolBuilder} instance. - * @defaultValue empty - */ - public TableSessionPoolBuilder sslProviderClass(String sslProviderClass) { - this.sslProviderClass = sslProviderClass; - return this; - } - /** * Builds and returns a configured {@link ITableSessionPool} instance. * diff --git a/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/iot/client/SyncIoTConsensusServiceClient.java b/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/iot/client/SyncIoTConsensusServiceClient.java index 43b2f60d89f47..3f3eb2d358e60 100644 --- a/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/iot/client/SyncIoTConsensusServiceClient.java +++ b/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/iot/client/SyncIoTConsensusServiceClient.java @@ -61,7 +61,8 @@ public SyncIoTConsensusServiceClient( commonConfig.getTrustStorePath(), commonConfig.getTrustStorePwd(), commonConfig.getKeyStorePath(), - commonConfig.getKeyStorePwd()) + commonConfig.getKeyStorePwd(), + commonConfig.getSslProtocol()) : DeepCopyRpcTransportFactory.INSTANCE.getTransport( new TSocket( TConfigurationConst.defaultTConfiguration, diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/rest/IoTDBRestServiceConfig.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/rest/IoTDBRestServiceConfig.java index 4e142a426b7b8..7e3729af4d0a3 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/rest/IoTDBRestServiceConfig.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/rest/IoTDBRestServiceConfig.java @@ -48,9 +48,6 @@ public class IoTDBRestServiceConfig { /** SSL protocol. */ private String sslProtocol = ""; - /** SSL provider class. */ - private String sslProviderClass = ""; - /** ssl timeout. */ private int idleTimeoutInSeconds = 50000; @@ -92,14 +89,6 @@ public void setSslProtocol(String sslProtocol) { this.sslProtocol = sslProtocol; } - public String getSslProviderClass() { - return sslProviderClass; - } - - public void setSslProviderClass(String sslProviderClass) { - this.sslProviderClass = sslProviderClass; - } - public int getIdleTimeoutInSeconds() { return idleTimeoutInSeconds; } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/rest/IoTDBRestServiceDescriptor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/rest/IoTDBRestServiceDescriptor.java index c832d6cea62e0..a05ade4863d4a 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/rest/IoTDBRestServiceDescriptor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/rest/IoTDBRestServiceDescriptor.java @@ -23,6 +23,7 @@ import org.apache.iotdb.commons.conf.TrimProperties; import org.apache.iotdb.db.conf.IoTDBConfig; import org.apache.iotdb.db.i18n.DataNodeMiscMessages; +import org.apache.iotdb.rpc.RpcSslUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -108,9 +109,9 @@ private void loadProps(TrimProperties trimProperties) { conf.setTrustStorePath( trimProperties.getProperty("trust_store_path", conf.getTrustStorePath())); conf.setTrustStorePwd(trimProperties.getProperty("trust_store_pwd", conf.getTrustStorePwd())); - conf.setSslProtocol(trimProperties.getProperty("ssl_protocol", conf.getSslProtocol())); - conf.setSslProviderClass( - trimProperties.getProperty("ssl_provider_class", conf.getSslProviderClass())); + conf.setSslProtocol( + RpcSslUtils.normalizeStandardTlsProtocol( + trimProperties.getProperty("ssl_protocol", conf.getSslProtocol()))); conf.setIdleTimeoutInSeconds( Integer.parseInt( trimProperties.getProperty( diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/client/ConfigNodeClient.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/client/ConfigNodeClient.java index 1f0b09f0b8689..e5f766d25725e 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/client/ConfigNodeClient.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/client/ConfigNodeClient.java @@ -279,7 +279,8 @@ public void connect(TEndPoint endpoint, int timeoutMs) throws TException { commonConfig.getTrustStorePath(), commonConfig.getTrustStorePwd(), commonConfig.getKeyStorePath(), - commonConfig.getKeyStorePwd()) + commonConfig.getKeyStorePwd(), + commonConfig.getSslProtocol()) : DeepCopyRpcTransportFactory.INSTANCE.getTransport( // As there is a try-catch already, we do not need to use TSocket.wrap endpoint.getIp(), endpoint.getPort(), timeoutMs); diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/client/an/AINodeClient.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/client/an/AINodeClient.java index 46af33b3172d2..6efb5a8c02167 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/client/an/AINodeClient.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/client/an/AINodeClient.java @@ -222,7 +222,8 @@ public void connect(TEndPoint endpoint, int timeoutMs) throws TException { COMMON_CONFIG.getTrustStorePath(), COMMON_CONFIG.getTrustStorePwd(), COMMON_CONFIG.getKeyStorePath(), - COMMON_CONFIG.getKeyStorePwd()) + COMMON_CONFIG.getKeyStorePwd(), + COMMON_CONFIG.getSslProtocol()) : DeepCopyRpcTransportFactory.INSTANCE.getTransport( // As there is a try-catch already, we do not need to use TSocket.wrap endpoint.getIp(), endpoint.getPort(), timeoutMs); diff --git a/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template b/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template index c68230ebb1b2d..5c6ddfc58a1f8 100644 --- a/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template +++ b/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template @@ -474,19 +474,13 @@ trust_store_path= # Datatype: String trust_store_pwd= -# SSL protocol used by SSL services. +# SSL protocol used by server-side SSL services. +# Only standard TLS protocol names are supported, such as TLS, TLSv1.2, or TLSv1.3. # effectiveMode: restart # Datatype: String # Privilege: SECURITY ssl_protocol=TLS -# Optional JSSE provider class used by SSL. If set, the provider is registered with highest priority. -# Multiple provider classes can be separated by commas. -# effectiveMode: restart -# Datatype: String -# Privilege: SECURITY -ssl_provider_class= - #################### ### Connection Configuration #################### diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/client/sync/SyncAINodeClient.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/client/sync/SyncAINodeClient.java index 054b644609958..636007107048e 100644 --- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/client/sync/SyncAINodeClient.java +++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/client/sync/SyncAINodeClient.java @@ -63,7 +63,8 @@ public SyncAINodeClient( COMMON_CONFIG.getTrustStorePath(), COMMON_CONFIG.getTrustStorePwd(), COMMON_CONFIG.getKeyStorePath(), - COMMON_CONFIG.getKeyStorePwd()) + COMMON_CONFIG.getKeyStorePwd(), + COMMON_CONFIG.getSslProtocol()) : DeepCopyRpcTransportFactory.INSTANCE.getTransport( new TSocket( TConfigurationConst.defaultTConfiguration, diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/client/sync/SyncConfigNodeIServiceClient.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/client/sync/SyncConfigNodeIServiceClient.java index ced2c92b4a0ef..323e00bace104 100644 --- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/client/sync/SyncConfigNodeIServiceClient.java +++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/client/sync/SyncConfigNodeIServiceClient.java @@ -63,7 +63,8 @@ public SyncConfigNodeIServiceClient( commonConfig.getTrustStorePath(), commonConfig.getTrustStorePwd(), commonConfig.getKeyStorePath(), - commonConfig.getKeyStorePwd()) + commonConfig.getKeyStorePwd(), + commonConfig.getSslProtocol()) : DeepCopyRpcTransportFactory.INSTANCE.getTransport( new TSocket( TConfigurationConst.defaultTConfiguration, diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/client/sync/SyncDataNodeInternalServiceClient.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/client/sync/SyncDataNodeInternalServiceClient.java index 854b4a4aa18b6..3f51cfa5d3e9c 100644 --- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/client/sync/SyncDataNodeInternalServiceClient.java +++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/client/sync/SyncDataNodeInternalServiceClient.java @@ -64,7 +64,8 @@ public SyncDataNodeInternalServiceClient( commonConfig.getTrustStorePath(), commonConfig.getTrustStorePwd(), commonConfig.getKeyStorePath(), - commonConfig.getKeyStorePwd()) + commonConfig.getKeyStorePwd(), + commonConfig.getSslProtocol()) : DeepCopyRpcTransportFactory.INSTANCE.getTransport( new TSocket( TConfigurationConst.defaultTConfiguration, diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/client/sync/SyncDataNodeMPPDataExchangeServiceClient.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/client/sync/SyncDataNodeMPPDataExchangeServiceClient.java index 4dcde11bfac6b..b4393bfd4eedd 100644 --- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/client/sync/SyncDataNodeMPPDataExchangeServiceClient.java +++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/client/sync/SyncDataNodeMPPDataExchangeServiceClient.java @@ -63,7 +63,8 @@ public SyncDataNodeMPPDataExchangeServiceClient( commonConfig.getTrustStorePath(), commonConfig.getTrustStorePwd(), commonConfig.getKeyStorePath(), - commonConfig.getKeyStorePwd()) + commonConfig.getKeyStorePwd(), + commonConfig.getSslProtocol()) : DeepCopyRpcTransportFactory.INSTANCE.getTransport( new TSocket( TConfigurationConst.defaultTConfiguration, diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/client/sync/SyncIoTConsensusV2ServiceClient.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/client/sync/SyncIoTConsensusV2ServiceClient.java index 3073434c92186..0b74424277593 100644 --- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/client/sync/SyncIoTConsensusV2ServiceClient.java +++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/client/sync/SyncIoTConsensusV2ServiceClient.java @@ -63,7 +63,8 @@ public SyncIoTConsensusV2ServiceClient( commonConfig.getTrustStorePath(), commonConfig.getTrustStorePwd(), commonConfig.getKeyStorePath(), - commonConfig.getKeyStorePwd()) + commonConfig.getKeyStorePwd(), + commonConfig.getSslProtocol()) : DeepCopyRpcTransportFactory.INSTANCE.getTransport( new TSocket( TConfigurationConst.defaultTConfiguration, diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonConfig.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonConfig.java index 584cdf8883d9f..99014627a30e2 100644 --- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonConfig.java +++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonConfig.java @@ -470,9 +470,6 @@ public class CommonConfig { /** SSL protocol. */ private String sslProtocol = "TLS"; - /** SSL provider class. */ - private String sslProviderClass = ""; - private String userEncryptTokenHint = "not set yet"; private boolean enforceStrongPassword = false; @@ -2827,14 +2824,6 @@ public void setSslProtocol(String sslProtocol) { this.sslProtocol = sslProtocol; } - public String getSslProviderClass() { - return sslProviderClass; - } - - public void setSslProviderClass(String sslProviderClass) { - this.sslProviderClass = sslProviderClass; - } - public boolean isEnforceStrongPassword() { return enforceStrongPassword; } diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonDescriptor.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonDescriptor.java index a382cb331a989..86cb93c2de0ca 100644 --- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonDescriptor.java +++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonDescriptor.java @@ -522,13 +522,13 @@ public void initThriftSSL(TrimProperties properties) { config.setTrustStorePath( properties.getProperty("trust_store_path", config.getTrustStorePath())); config.setTrustStorePwd(properties.getProperty("trust_store_pwd", config.getTrustStorePwd())); - config.setSslProtocol(properties.getProperty("ssl_protocol", config.getSslProtocol())); - config.setSslProviderClass( - properties.getProperty("ssl_provider_class", config.getSslProviderClass())); + config.setSslProtocol( + RpcSslUtils.normalizeStandardTlsProtocol( + properties.getProperty("ssl_protocol", config.getSslProtocol()))); configureRpcSsl(); } public void configureRpcSsl() { - RpcSslUtils.configure(config.getSslProtocol(), config.getSslProviderClass()); + RpcSslUtils.configure(config.getSslProtocol()); } } From 3c96378af48ad272c87978d8ce6943fae76a5fcb Mon Sep 17 00:00:00 2001 From: HTHou Date: Thu, 11 Jun 2026 11:52:48 +0800 Subject: [PATCH 05/13] Remove TODO from SSL protocol option --- .../cli/src/main/java/org/apache/iotdb/cli/AbstractCli.java | 1 - 1 file changed, 1 deletion(-) diff --git a/iotdb-client/cli/src/main/java/org/apache/iotdb/cli/AbstractCli.java b/iotdb-client/cli/src/main/java/org/apache/iotdb/cli/AbstractCli.java index 8c45a89aead73..484569cf42474 100644 --- a/iotdb-client/cli/src/main/java/org/apache/iotdb/cli/AbstractCli.java +++ b/iotdb-client/cli/src/main/java/org/apache/iotdb/cli/AbstractCli.java @@ -135,7 +135,6 @@ public abstract class AbstractCli { static String trustStore; // TODO: Make non-static static String trustStorePwd; - // TODO: Make non-static static String sslProtocol; static String execute; From 4c3fe70cb09339836544e0b1b918111c84cf94ec Mon Sep 17 00:00:00 2001 From: HTHou Date: Thu, 11 Jun 2026 12:06:25 +0800 Subject: [PATCH 06/13] Remove redundant SSL protocol keyword --- .../cli/src/main/java/org/apache/iotdb/cli/AbstractCli.java | 1 - 1 file changed, 1 deletion(-) diff --git a/iotdb-client/cli/src/main/java/org/apache/iotdb/cli/AbstractCli.java b/iotdb-client/cli/src/main/java/org/apache/iotdb/cli/AbstractCli.java index 484569cf42474..7375b037acdf9 100644 --- a/iotdb-client/cli/src/main/java/org/apache/iotdb/cli/AbstractCli.java +++ b/iotdb-client/cli/src/main/java/org/apache/iotdb/cli/AbstractCli.java @@ -161,7 +161,6 @@ static void init() { keywordSet.add("-" + TRUST_STORE_ARGS); keywordSet.add("-" + TRUST_STORE_PWD_ARGS); keywordSet.add("-" + SSL_PROTOCOL_ARGS); - keywordSet.add("--" + SSL_PROTOCOL_ARGS); keywordSet.add("-" + EXECUTE_ARGS); keywordSet.add("-" + ISO8601_ARGS); keywordSet.add("-" + RPC_COMPRESS_ARGS); From bf10b28ad5672570de8c5cff7e919a6090ced1ee Mon Sep 17 00:00:00 2001 From: HTHou Date: Mon, 15 Jun 2026 17:57:24 +0800 Subject: [PATCH 07/13] Fix REST annotation dependency --- external-service-impl/rest/pom.xml | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/external-service-impl/rest/pom.xml b/external-service-impl/rest/pom.xml index 7ef130ace317e..6bf8983a207f2 100644 --- a/external-service-impl/rest/pom.xml +++ b/external-service-impl/rest/pom.xml @@ -38,13 +38,6 @@ org.glassfish.jersey.inject jersey-hk2 runtime - - - - jakarta.annotation - jakarta.annotation-api - - org.apache.iotdb @@ -81,11 +74,6 @@ jakarta.validation jakarta.validation-api - - - jakarta.annotation - jakarta.annotation-api - From 3f903d9bb652d5565ac18224b67f4f78b2ec1161 Mon Sep 17 00:00:00 2001 From: HTHou Date: Tue, 16 Jun 2026 09:21:36 +0800 Subject: [PATCH 08/13] Update Ratis snapshot and exclude OpenTelemetry --- pom.xml | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ea1732c43bbae..2de8e5421f2ad 100644 --- a/pom.xml +++ b/pom.xml @@ -119,7 +119,7 @@ 1.5.6 2.0.9 1.0.11 - 3.3.0-b60fcf6-SNAPSHOT + 3.3.0-adac7ef-SNAPSHOT 1.0.4 1.2.9 3.7.9 @@ -331,6 +331,28 @@ org.apache.ratis ratis-common ${ratis.version} + + + io.opentelemetry + opentelemetry-api + + + io.opentelemetry + opentelemetry-context + + + io.opentelemetry + opentelemetry-sdk + + + io.opentelemetry + opentelemetry-sdk-testing + + + io.opentelemetry.semconv + opentelemetry-semconv + + org.apache.ratis From 2cde545c9b2d15c7803e3146da0963e7ef181ebf Mon Sep 17 00:00:00 2001 From: HTHou Date: Tue, 16 Jun 2026 09:44:18 +0800 Subject: [PATCH 09/13] Narrow OpenTelemetry exclusions --- pom.xml | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/pom.xml b/pom.xml index 2de8e5421f2ad..3f3b235f19a1e 100644 --- a/pom.xml +++ b/pom.xml @@ -340,18 +340,6 @@ io.opentelemetry opentelemetry-context - - io.opentelemetry - opentelemetry-sdk - - - io.opentelemetry - opentelemetry-sdk-testing - - - io.opentelemetry.semconv - opentelemetry-semconv - From a55227f16f9db534ba15732ad8fe662b32e3cc6c Mon Sep 17 00:00:00 2001 From: HTHou Date: Tue, 16 Jun 2026 12:27:27 +0800 Subject: [PATCH 10/13] Add client SSL integration tests --- .../it/env/cluster/config/MppBaseConfig.java | 4 + .../env/cluster/config/MppCommonConfig.java | 6 + .../cluster/config/MppSharedCommonConfig.java | 7 + .../iotdb/it/env/cluster/env/AbstractEnv.java | 201 ++++++++++----- .../env/remote/config/RemoteCommonConfig.java | 5 + .../apache/iotdb/itbase/env/CommonConfig.java | 2 + .../iotdb/session/it/IoTDBClientSSLIT.java | 232 ++++++++++++++++++ 7 files changed, 397 insertions(+), 60 deletions(-) create mode 100644 integration-test/src/test/java/org/apache/iotdb/session/it/IoTDBClientSSLIT.java diff --git a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/config/MppBaseConfig.java b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/config/MppBaseConfig.java index e0758de70c952..69b2e540e9682 100644 --- a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/config/MppBaseConfig.java +++ b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/config/MppBaseConfig.java @@ -120,6 +120,10 @@ protected final void setProperty(@NotNull String key, String value) { } } + public final String getProperty(@NotNull String key, String defaultValue) { + return properties.getProperty(key, defaultValue); + } + /** Create an instance but with empty properties. */ public abstract MppBaseConfig emptyClone(); } diff --git a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/config/MppCommonConfig.java b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/config/MppCommonConfig.java index c7ff02002dc58..5c3f011accd08 100644 --- a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/config/MppCommonConfig.java +++ b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/config/MppCommonConfig.java @@ -635,6 +635,12 @@ public CommonConfig setEnforceStrongPassword(boolean enforceStrongPassword) { return this; } + @Override + public CommonConfig setEnableThriftClientSSL(boolean enableThriftClientSSL) { + setProperty("enable_thrift_ssl", String.valueOf(enableThriftClientSSL)); + return this; + } + @Override public CommonConfig setEnableInternalSSL(boolean enableInternalSSL) { setProperty("enable_internal_ssl", String.valueOf(enableInternalSSL)); diff --git a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/config/MppSharedCommonConfig.java b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/config/MppSharedCommonConfig.java index 5ed27b2f5024e..a7f0797a6df49 100644 --- a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/config/MppSharedCommonConfig.java +++ b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/config/MppSharedCommonConfig.java @@ -659,6 +659,13 @@ public CommonConfig setEnforceStrongPassword(boolean enforceStrongPassword) { return this; } + @Override + public CommonConfig setEnableThriftClientSSL(boolean enableThriftClientSSL) { + cnConfig.setEnableThriftClientSSL(enableThriftClientSSL); + dnConfig.setEnableThriftClientSSL(enableThriftClientSSL); + return this; + } + @Override public CommonConfig setEnableInternalSSL(boolean enableInternalSSL) { cnConfig.setEnableInternalSSL(enableInternalSSL); diff --git a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/env/AbstractEnv.java b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/env/AbstractEnv.java index 0e7eefb3a4188..399aeeb7a3262 100644 --- a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/env/AbstractEnv.java +++ b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/env/AbstractEnv.java @@ -614,6 +614,74 @@ public void cleanClusterEnvironment() { clusterConfig = new MppClusterConfig(); } + private boolean isThriftClientSSLEnabled() { + return Boolean.parseBoolean(getDataNodeCommonConfigProperty("enable_thrift_ssl", "false")); + } + + private String getDataNodeCommonConfigProperty(final String key, final String defaultValue) { + return ((MppCommonConfig) clusterConfig.getDataNodeCommonConfig()) + .getProperty(key, defaultValue); + } + + private Properties constructConnectionProperties( + final String username, final String password, final String sqlDialect) { + final Properties info = BaseEnv.constructProperties(username, password, sqlDialect); + if (isThriftClientSSLEnabled()) { + info.put(Config.USE_SSL, Boolean.TRUE.toString()); + putIfPresent( + info, Config.TRUST_STORE, getDataNodeCommonConfigProperty("trust_store_path", "")); + putIfPresent( + info, Config.TRUST_STORE_PWD, getDataNodeCommonConfigProperty("trust_store_pwd", "")); + } + return info; + } + + private void putIfPresent(final Properties properties, final String key, final String value) { + if (value != null && !value.isEmpty()) { + properties.put(key, value); + } + } + + private Session.Builder configureClientSSL(final Session.Builder builder) { + if (isThriftClientSSLEnabled()) { + builder + .useSSL(true) + .trustStore(getDataNodeCommonConfigProperty("trust_store_path", "")) + .trustStorePwd(getDataNodeCommonConfigProperty("trust_store_pwd", "")); + } + return builder; + } + + private TableSessionBuilder configureClientSSL(final TableSessionBuilder builder) { + if (isThriftClientSSLEnabled()) { + builder + .useSSL(true) + .trustStore(getDataNodeCommonConfigProperty("trust_store_path", "")) + .trustStorePwd(getDataNodeCommonConfigProperty("trust_store_pwd", "")); + } + return builder; + } + + private SessionPool.Builder configureClientSSL(final SessionPool.Builder builder) { + if (isThriftClientSSLEnabled()) { + builder + .useSSL(true) + .trustStore(getDataNodeCommonConfigProperty("trust_store_path", "")) + .trustStorePwd(getDataNodeCommonConfigProperty("trust_store_pwd", "")); + } + return builder; + } + + private TableSessionPoolBuilder configureClientSSL(final TableSessionPoolBuilder builder) { + if (isThriftClientSSLEnabled()) { + builder + .useSSL(true) + .trustStore(getDataNodeCommonConfigProperty("trust_store_path", "")) + .trustStorePwd(getDataNodeCommonConfigProperty("trust_store_pwd", "")); + } + return builder; + } + @Override public Connection getConnection( final String username, final String password, final String sqlDialect) throws SQLException { @@ -695,7 +763,8 @@ public ISession getSessionConnection() throws IoTDBConnectionException { final DataNodeWrapper dataNode = this.dataNodeWrapperList.get(rand.nextInt(this.dataNodeWrapperList.size())); final Session session = - new Session.Builder().host(dataNode.getIp()).port(dataNode.getPort()).build(); + configureClientSSL(new Session.Builder().host(dataNode.getIp()).port(dataNode.getPort())) + .build(); session.open(); return session; } @@ -705,10 +774,11 @@ public ISession getSessionConnection(ZoneId zoneId) throws IoTDBConnectionExcept final DataNodeWrapper dataNode = this.dataNodeWrapperList.get(rand.nextInt(this.dataNodeWrapperList.size())); final Session session = - new Session.Builder() - .host(dataNode.getIp()) - .port(dataNode.getPort()) - .zoneId(zoneId) + configureClientSSL( + new Session.Builder() + .host(dataNode.getIp()) + .port(dataNode.getPort()) + .zoneId(zoneId)) .build(); session.open(); return session; @@ -720,11 +790,12 @@ public ISession getSessionConnection(final String userName, final String passwor final DataNodeWrapper dataNode = this.dataNodeWrapperList.get(rand.nextInt(this.dataNodeWrapperList.size())); final Session session = - new Session.Builder() - .host(dataNode.getIp()) - .port(dataNode.getPort()) - .username(userName) - .password(password) + configureClientSSL( + new Session.Builder() + .host(dataNode.getIp()) + .port(dataNode.getPort()) + .username(userName) + .password(password)) .build(); session.open(); return session; @@ -734,16 +805,17 @@ public ISession getSessionConnection(final String userName, final String passwor public ISession getSessionConnection(final List nodeUrls) throws IoTDBConnectionException { final Session session = - new Session.Builder() - .nodeUrls(nodeUrls) - .username(SessionConfig.DEFAULT_USER) - .password(SessionConfig.DEFAULT_PASSWORD) - .fetchSize(SessionConfig.DEFAULT_FETCH_SIZE) - .zoneId(null) - .thriftDefaultBufferSize(SessionConfig.DEFAULT_INITIAL_BUFFER_CAPACITY) - .thriftMaxFrameSize(SessionConfig.DEFAULT_MAX_FRAME_SIZE) - .enableRedirection(SessionConfig.DEFAULT_REDIRECTION_MODE) - .version(SessionConfig.DEFAULT_VERSION) + configureClientSSL( + new Session.Builder() + .nodeUrls(nodeUrls) + .username(SessionConfig.DEFAULT_USER) + .password(SessionConfig.DEFAULT_PASSWORD) + .fetchSize(SessionConfig.DEFAULT_FETCH_SIZE) + .zoneId(null) + .thriftDefaultBufferSize(SessionConfig.DEFAULT_INITIAL_BUFFER_CAPACITY) + .thriftMaxFrameSize(SessionConfig.DEFAULT_MAX_FRAME_SIZE) + .enableRedirection(SessionConfig.DEFAULT_REDIRECTION_MODE) + .version(SessionConfig.DEFAULT_VERSION)) .build(); session.open(); return session; @@ -753,8 +825,9 @@ public ISession getSessionConnection(final List nodeUrls) public ITableSession getTableSessionConnection() throws IoTDBConnectionException { final DataNodeWrapper dataNode = this.dataNodeWrapperList.get(rand.nextInt(this.dataNodeWrapperList.size())); - return new TableSessionBuilder() - .nodeUrls(Collections.singletonList(dataNode.getIpAndPortString())) + return configureClientSSL( + new TableSessionBuilder() + .nodeUrls(Collections.singletonList(dataNode.getIpAndPortString()))) .build(); } @@ -763,10 +836,11 @@ public ITableSession getTableSessionConnection(String userName, String password) throws IoTDBConnectionException { final DataNodeWrapper dataNode = this.dataNodeWrapperList.get(rand.nextInt(this.dataNodeWrapperList.size())); - return new TableSessionBuilder() - .nodeUrls(Collections.singletonList(dataNode.getIpAndPortString())) - .username(userName) - .password(password) + return configureClientSSL( + new TableSessionBuilder() + .nodeUrls(Collections.singletonList(dataNode.getIpAndPortString())) + .username(userName) + .password(password)) .build(); } @@ -775,23 +849,25 @@ public ITableSession getTableSessionConnectionWithDB(final String database) throws IoTDBConnectionException { final DataNodeWrapper dataNode = this.dataNodeWrapperList.get(rand.nextInt(this.dataNodeWrapperList.size())); - return new TableSessionBuilder() - .nodeUrls(Collections.singletonList(dataNode.getIpAndPortString())) - .database(database) + return configureClientSSL( + new TableSessionBuilder() + .nodeUrls(Collections.singletonList(dataNode.getIpAndPortString())) + .database(database)) .build(); } public ITableSession getTableSessionConnection(List nodeUrls) throws IoTDBConnectionException { - return new TableSessionBuilder() - .nodeUrls(nodeUrls) - .username(SessionConfig.DEFAULT_USER) - .password(SessionConfig.DEFAULT_PASSWORD) - .fetchSize(SessionConfig.DEFAULT_FETCH_SIZE) - .zoneId(null) - .thriftDefaultBufferSize(SessionConfig.DEFAULT_INITIAL_BUFFER_CAPACITY) - .thriftMaxFrameSize(SessionConfig.DEFAULT_MAX_FRAME_SIZE) - .enableRedirection(SessionConfig.DEFAULT_REDIRECTION_MODE) + return configureClientSSL( + new TableSessionBuilder() + .nodeUrls(nodeUrls) + .username(SessionConfig.DEFAULT_USER) + .password(SessionConfig.DEFAULT_PASSWORD) + .fetchSize(SessionConfig.DEFAULT_FETCH_SIZE) + .zoneId(null) + .thriftDefaultBufferSize(SessionConfig.DEFAULT_INITIAL_BUFFER_CAPACITY) + .thriftMaxFrameSize(SessionConfig.DEFAULT_MAX_FRAME_SIZE) + .enableRedirection(SessionConfig.DEFAULT_REDIRECTION_MODE)) .build(); } @@ -799,12 +875,13 @@ public ITableSession getTableSessionConnection(List nodeUrls) public ISessionPool getSessionPool(final int maxSize) { final DataNodeWrapper dataNode = this.dataNodeWrapperList.get(rand.nextInt(this.dataNodeWrapperList.size())); - return new SessionPool.Builder() - .host(dataNode.getIp()) - .port(dataNode.getPort()) - .user(SessionConfig.DEFAULT_USER) - .password(SessionConfig.DEFAULT_PASSWORD) - .maxSize(maxSize) + return configureClientSSL( + new SessionPool.Builder() + .host(dataNode.getIp()) + .port(dataNode.getPort()) + .user(SessionConfig.DEFAULT_USER) + .password(SessionConfig.DEFAULT_PASSWORD) + .maxSize(maxSize)) .build(); } @@ -812,11 +889,12 @@ public ISessionPool getSessionPool(final int maxSize) { public ITableSessionPool getTableSessionPool(final int maxSize) { final DataNodeWrapper dataNode = this.dataNodeWrapperList.get(rand.nextInt(this.dataNodeWrapperList.size())); - return new TableSessionPoolBuilder() - .nodeUrls(Collections.singletonList(dataNode.getIpAndPortString())) - .user(SessionConfig.DEFAULT_USER) - .password(SessionConfig.DEFAULT_PASSWORD) - .maxSize(maxSize) + return configureClientSSL( + new TableSessionPoolBuilder() + .nodeUrls(Collections.singletonList(dataNode.getIpAndPortString())) + .user(SessionConfig.DEFAULT_USER) + .password(SessionConfig.DEFAULT_PASSWORD) + .maxSize(maxSize)) .build(); } @@ -824,12 +902,13 @@ public ITableSessionPool getTableSessionPool(final int maxSize) { public ITableSessionPool getTableSessionPool(final int maxSize, final String database) { DataNodeWrapper dataNode = this.dataNodeWrapperList.get(rand.nextInt(this.dataNodeWrapperList.size())); - return new TableSessionPoolBuilder() - .nodeUrls(Collections.singletonList(dataNode.getIpAndPortString())) - .user(SessionConfig.DEFAULT_USER) - .password(SessionConfig.DEFAULT_PASSWORD) - .database(database) - .maxSize(maxSize) + return configureClientSSL( + new TableSessionPoolBuilder() + .nodeUrls(Collections.singletonList(dataNode.getIpAndPortString())) + .user(SessionConfig.DEFAULT_USER) + .password(SessionConfig.DEFAULT_PASSWORD) + .database(database) + .maxSize(maxSize)) .build(); } @@ -853,7 +932,7 @@ protected NodeConnection getWriteConnectionWithSpecifiedDataNode( Config.IOTDB_URL_PREFIX + endpoint + getParam(version, NODE_NETWORK_TIMEOUT_MS, ZERO_TIME_ZONE), - BaseEnv.constructProperties(username, password, sqlDialect)); + constructConnectionProperties(username, password, sqlDialect)); return new NodeConnection( endpoint, NodeConnection.NodeRole.DATA_NODE, @@ -910,7 +989,7 @@ protected List getReadConnections( Config.IOTDB_URL_PREFIX + endpoint + getParam(version, NODE_NETWORK_TIMEOUT_MS, ZERO_TIME_ZONE), - BaseEnv.constructProperties(username, password, sqlDialect)))); + constructConnectionProperties(username, password, sqlDialect)))); }); return readConnRequestDelegate.requestAll(); } @@ -957,7 +1036,7 @@ protected List getReadConnections( Config.IOTDB_URL_PREFIX + dataNode.getIpAndPortString() + getParam(version, NODE_NETWORK_TIMEOUT_MS, ZERO_TIME_ZONE), - BaseEnv.constructProperties(username, password, sqlDialect)))); + constructConnectionProperties(username, password, sqlDialect)))); return readConnRequestDelegate.requestAll(); } @@ -988,8 +1067,10 @@ protected void testJDBCConnection() { Config.IOTDB_URL_PREFIX + dataNodeEndpoint + getParam(null, NODE_NETWORK_TIMEOUT_MS, ZERO_TIME_ZONE), - System.getProperty("User", "root"), - System.getProperty("Password", "root"))) { + constructConnectionProperties( + System.getProperty("User", "root"), + System.getProperty("Password", "root"), + TREE_SQL_DIALECT))) { logger.info("Successfully connecting to DataNode: {}.", dataNodeEndpoint); return null; } catch (final Exception e) { diff --git a/integration-test/src/main/java/org/apache/iotdb/it/env/remote/config/RemoteCommonConfig.java b/integration-test/src/main/java/org/apache/iotdb/it/env/remote/config/RemoteCommonConfig.java index 03948e2371f79..5667845326d7d 100644 --- a/integration-test/src/main/java/org/apache/iotdb/it/env/remote/config/RemoteCommonConfig.java +++ b/integration-test/src/main/java/org/apache/iotdb/it/env/remote/config/RemoteCommonConfig.java @@ -447,6 +447,11 @@ public CommonConfig setEnforceStrongPassword(boolean enforceStrongPassword) { return this; } + @Override + public CommonConfig setEnableThriftClientSSL(boolean enableThriftClientSSL) { + return this; + } + @Override public CommonConfig setSubscriptionPrefetchTsFileBatchMaxDelayInMs( int subscriptionPrefetchTsFileBatchMaxDelayInMs) { diff --git a/integration-test/src/main/java/org/apache/iotdb/itbase/env/CommonConfig.java b/integration-test/src/main/java/org/apache/iotdb/itbase/env/CommonConfig.java index ad9168faebfb2..c204f502c9b30 100644 --- a/integration-test/src/main/java/org/apache/iotdb/itbase/env/CommonConfig.java +++ b/integration-test/src/main/java/org/apache/iotdb/itbase/env/CommonConfig.java @@ -204,6 +204,8 @@ default CommonConfig setDefaultDatabaseLevel(int defaultDatabaseLevel) { CommonConfig setEnforceStrongPassword(boolean enforceStrongPassword); + CommonConfig setEnableThriftClientSSL(boolean enableThriftClientSSL); + CommonConfig setEnableInternalSSL(boolean enableInternalSSL); CommonConfig setKeyStorePath(String keyStorePath); diff --git a/integration-test/src/test/java/org/apache/iotdb/session/it/IoTDBClientSSLIT.java b/integration-test/src/test/java/org/apache/iotdb/session/it/IoTDBClientSSLIT.java new file mode 100644 index 0000000000000..8aa1aa1403727 --- /dev/null +++ b/integration-test/src/test/java/org/apache/iotdb/session/it/IoTDBClientSSLIT.java @@ -0,0 +1,232 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.iotdb.session.it; + +import org.apache.iotdb.isession.ISession; +import org.apache.iotdb.isession.ITableSession; +import org.apache.iotdb.isession.SessionConfig; +import org.apache.iotdb.isession.SessionDataSet; +import org.apache.iotdb.it.env.EnvFactory; +import org.apache.iotdb.it.env.cluster.node.DataNodeWrapper; +import org.apache.iotdb.it.framework.IoTDBTestRunner; +import org.apache.iotdb.itbase.category.ClusterIT; +import org.apache.iotdb.itbase.category.LocalStandaloneIT; +import org.apache.iotdb.itbase.category.TableClusterIT; +import org.apache.iotdb.itbase.category.TableLocalStandaloneIT; +import org.apache.iotdb.jdbc.Config; +import org.apache.iotdb.rpc.IoTDBConnectionException; +import org.apache.iotdb.session.Session; +import org.apache.iotdb.session.TableSessionBuilder; + +import org.apache.tsfile.read.common.RowRecord; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.runner.RunWith; + +import java.io.File; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.Statement; +import java.util.Collections; +import java.util.Properties; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; + +@RunWith(IoTDBTestRunner.class) +@Category({ + LocalStandaloneIT.class, + ClusterIT.class, + TableLocalStandaloneIT.class, + TableClusterIT.class +}) +public class IoTDBClientSSLIT { + + private static final String STORE_PASSWORD = "thrift"; + private static String keyDir; + + @BeforeClass + public static void setUp() throws Exception { + keyDir = + System.getProperty("user.dir") + + File.separator + + "target" + + File.separator + + "test-classes" + + File.separator; + + EnvFactory.getEnv() + .getConfig() + .getCommonConfig() + .setEnableThriftClientSSL(true) + .setKeyStorePath(keyStorePath()) + .setKeyStorePwd(STORE_PASSWORD) + .setTrustStorePath(trustStorePath()) + .setTrustStorePwd(STORE_PASSWORD); + EnvFactory.getEnv().initClusterEnvironment(); + } + + @After + public void tearDown() { + try (ISession session = newSSLSession()) { + deleteTreeDatabase(session, "root.client_ssl_tree"); + deleteTreeDatabase(session, "root.client_ssl_jdbc"); + } catch (Exception ignored) { + // ignored + } + try (ITableSession session = newSSLTableSession()) { + session.executeNonQueryStatement("DROP DATABASE IF EXISTS client_ssl_table"); + } catch (Exception ignored) { + // ignored + } + } + + @AfterClass + public static void tearDownClass() { + EnvFactory.getEnv().cleanClusterEnvironment(); + } + + @Test + public void nonSSLClientCanNotConnectToSSLPort() { + final DataNodeWrapper dataNode = EnvFactory.getEnv().getDataNodeWrapper(0); + final Session session = + new Session.Builder().host(dataNode.getIp()).port(dataNode.getPort()).build(); + + assertThrows(IoTDBConnectionException.class, session::open); + } + + @Test + public void treeSessionCanConnectWithSSL() throws Exception { + try (ISession session = newSSLSession()) { + session.executeNonQueryStatement("CREATE DATABASE root.client_ssl_tree"); + session.executeNonQueryStatement( + "CREATE TIMESERIES root.client_ssl_tree.d1.s1 WITH DATATYPE=INT32, ENCODING=PLAIN"); + session.executeNonQueryStatement( + "INSERT INTO root.client_ssl_tree.d1(time, s1) VALUES (1, 11)"); + + try (SessionDataSet dataSet = + session.executeQueryStatement("SELECT s1 FROM root.client_ssl_tree.d1")) { + assertTrue(dataSet.hasNext()); + final RowRecord record = dataSet.next(); + assertEquals(1L, record.getTimestamp()); + assertEquals(11, record.getFields().get(0).getIntV()); + assertFalse(dataSet.hasNext()); + } + } + } + + @Test + public void tableSessionCanConnectWithSSL() throws Exception { + try (ITableSession session = newSSLTableSession()) { + session.executeNonQueryStatement("CREATE DATABASE IF NOT EXISTS client_ssl_table"); + session.executeNonQueryStatement("USE client_ssl_table"); + session.executeNonQueryStatement( + "CREATE TABLE IF NOT EXISTS ssl_table (tag1 STRING TAG, value INT32 FIELD)"); + session.executeNonQueryStatement( + "INSERT INTO ssl_table(time, tag1, value) VALUES (1, 'tag1', 22)"); + + try (SessionDataSet dataSet = + session.executeQueryStatement("SELECT time, value FROM ssl_table WHERE tag1 = 'tag1'")) { + assertTrue(dataSet.hasNext()); + final RowRecord record = dataSet.next(); + assertEquals(1L, record.getFields().get(0).getLongV()); + assertEquals(22, record.getFields().get(1).getIntV()); + assertFalse(dataSet.hasNext()); + } + } + } + + @Test + public void jdbcCanConnectWithSSL() throws Exception { + final DataNodeWrapper dataNode = EnvFactory.getEnv().getDataNodeWrapper(0); + + try (Connection connection = + DriverManager.getConnection( + Config.IOTDB_URL_PREFIX + dataNode.getIpAndPortString(), sslProperties()); + Statement statement = connection.createStatement()) { + statement.execute("CREATE DATABASE root.client_ssl_jdbc"); + statement.execute( + "CREATE TIMESERIES root.client_ssl_jdbc.d1.s1 WITH DATATYPE=INT32, ENCODING=PLAIN"); + statement.execute("INSERT INTO root.client_ssl_jdbc.d1(time, s1) VALUES (1, 33)"); + + try (ResultSet resultSet = statement.executeQuery("SELECT s1 FROM root.client_ssl_jdbc.d1")) { + assertTrue(resultSet.next()); + assertEquals(1L, resultSet.getLong(1)); + assertEquals(33, resultSet.getInt(2)); + assertFalse(resultSet.next()); + } + } + } + + private static ISession newSSLSession() throws IoTDBConnectionException { + final DataNodeWrapper dataNode = EnvFactory.getEnv().getDataNodeWrapper(0); + final Session session = + new Session.Builder() + .host(dataNode.getIp()) + .port(dataNode.getPort()) + .useSSL(true) + .trustStore(trustStorePath()) + .trustStorePwd(STORE_PASSWORD) + .build(); + session.open(); + return session; + } + + private static ITableSession newSSLTableSession() throws IoTDBConnectionException { + final DataNodeWrapper dataNode = EnvFactory.getEnv().getDataNodeWrapper(0); + return new TableSessionBuilder() + .nodeUrls(Collections.singletonList(dataNode.getIpAndPortString())) + .useSSL(true) + .trustStore(trustStorePath()) + .trustStorePwd(STORE_PASSWORD) + .build(); + } + + private static Properties sslProperties() { + final Properties properties = new Properties(); + properties.put("user", SessionConfig.DEFAULT_USER); + properties.put("password", SessionConfig.DEFAULT_PASSWORD); + properties.put(Config.USE_SSL, Boolean.TRUE.toString()); + properties.put(Config.TRUST_STORE, trustStorePath()); + properties.put(Config.TRUST_STORE_PWD, STORE_PASSWORD); + return properties; + } + + private void deleteTreeDatabase(final ISession session, final String database) { + try { + session.executeNonQueryStatement("DELETE DATABASE " + database); + } catch (Exception ignored) { + // ignored + } + } + + private static String keyStorePath() { + return keyDir + "test-keystore"; + } + + private static String trustStorePath() { + return keyDir + "test-truststore"; + } +} From 272dc477a4af10f7999a924a6143e4a61dcccd0a Mon Sep 17 00:00:00 2001 From: HTHou Date: Tue, 16 Jun 2026 18:15:04 +0800 Subject: [PATCH 11/13] Propagate SSL protocol in integration test env --- .../it/env/cluster/config/MppCommonConfig.java | 6 ++++++ .../cluster/config/MppSharedCommonConfig.java | 7 +++++++ .../iotdb/it/env/cluster/env/AbstractEnv.java | 17 +++++++++++++---- .../env/remote/config/RemoteCommonConfig.java | 5 +++++ .../apache/iotdb/itbase/env/CommonConfig.java | 2 ++ .../iotdb/session/it/IoTDBClientSSLIT.java | 3 ++- 6 files changed, 35 insertions(+), 5 deletions(-) diff --git a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/config/MppCommonConfig.java b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/config/MppCommonConfig.java index 5c3f011accd08..dc6dda073169c 100644 --- a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/config/MppCommonConfig.java +++ b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/config/MppCommonConfig.java @@ -671,6 +671,12 @@ public CommonConfig setTrustStorePwd(String trustStorePwd) { return this; } + @Override + public CommonConfig setSslProtocol(String sslProtocol) { + setProperty("ssl_protocol", sslProtocol); + return this; + } + @Override public CommonConfig setDatanodeMemoryProportion(String datanodeMemoryProportion) { setProperty("datanode_memory_proportion", datanodeMemoryProportion); diff --git a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/config/MppSharedCommonConfig.java b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/config/MppSharedCommonConfig.java index a7f0797a6df49..67774979d28ee 100644 --- a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/config/MppSharedCommonConfig.java +++ b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/config/MppSharedCommonConfig.java @@ -701,6 +701,13 @@ public CommonConfig setTrustStorePwd(String trustStorePwd) { return this; } + @Override + public CommonConfig setSslProtocol(String sslProtocol) { + cnConfig.setSslProtocol(sslProtocol); + dnConfig.setSslProtocol(sslProtocol); + return this; + } + @Override public CommonConfig setDatanodeMemoryProportion(String datanodeMemoryProportion) { dnConfig.setDatanodeMemoryProportion(datanodeMemoryProportion); diff --git a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/env/AbstractEnv.java b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/env/AbstractEnv.java index 399aeeb7a3262..7bcee29be6e91 100644 --- a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/env/AbstractEnv.java +++ b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/env/AbstractEnv.java @@ -623,6 +623,10 @@ private String getDataNodeCommonConfigProperty(final String key, final String de .getProperty(key, defaultValue); } + private String getClientSSLProtocol() { + return getDataNodeCommonConfigProperty("ssl_protocol", SessionConfig.DEFAULT_SSL_PROTOCOL); + } + private Properties constructConnectionProperties( final String username, final String password, final String sqlDialect) { final Properties info = BaseEnv.constructProperties(username, password, sqlDialect); @@ -632,6 +636,7 @@ private Properties constructConnectionProperties( info, Config.TRUST_STORE, getDataNodeCommonConfigProperty("trust_store_path", "")); putIfPresent( info, Config.TRUST_STORE_PWD, getDataNodeCommonConfigProperty("trust_store_pwd", "")); + putIfPresent(info, Config.SSL_PROTOCOL, getClientSSLProtocol()); } return info; } @@ -647,7 +652,8 @@ private Session.Builder configureClientSSL(final Session.Builder builder) { builder .useSSL(true) .trustStore(getDataNodeCommonConfigProperty("trust_store_path", "")) - .trustStorePwd(getDataNodeCommonConfigProperty("trust_store_pwd", "")); + .trustStorePwd(getDataNodeCommonConfigProperty("trust_store_pwd", "")) + .sslProtocol(getClientSSLProtocol()); } return builder; } @@ -657,7 +663,8 @@ private TableSessionBuilder configureClientSSL(final TableSessionBuilder builder builder .useSSL(true) .trustStore(getDataNodeCommonConfigProperty("trust_store_path", "")) - .trustStorePwd(getDataNodeCommonConfigProperty("trust_store_pwd", "")); + .trustStorePwd(getDataNodeCommonConfigProperty("trust_store_pwd", "")) + .sslProtocol(getClientSSLProtocol()); } return builder; } @@ -667,7 +674,8 @@ private SessionPool.Builder configureClientSSL(final SessionPool.Builder builder builder .useSSL(true) .trustStore(getDataNodeCommonConfigProperty("trust_store_path", "")) - .trustStorePwd(getDataNodeCommonConfigProperty("trust_store_pwd", "")); + .trustStorePwd(getDataNodeCommonConfigProperty("trust_store_pwd", "")) + .sslProtocol(getClientSSLProtocol()); } return builder; } @@ -677,7 +685,8 @@ private TableSessionPoolBuilder configureClientSSL(final TableSessionPoolBuilder builder .useSSL(true) .trustStore(getDataNodeCommonConfigProperty("trust_store_path", "")) - .trustStorePwd(getDataNodeCommonConfigProperty("trust_store_pwd", "")); + .trustStorePwd(getDataNodeCommonConfigProperty("trust_store_pwd", "")) + .sslProtocol(getClientSSLProtocol()); } return builder; } diff --git a/integration-test/src/main/java/org/apache/iotdb/it/env/remote/config/RemoteCommonConfig.java b/integration-test/src/main/java/org/apache/iotdb/it/env/remote/config/RemoteCommonConfig.java index 5667845326d7d..01ef8f468fa6e 100644 --- a/integration-test/src/main/java/org/apache/iotdb/it/env/remote/config/RemoteCommonConfig.java +++ b/integration-test/src/main/java/org/apache/iotdb/it/env/remote/config/RemoteCommonConfig.java @@ -489,6 +489,11 @@ public CommonConfig setTrustStorePwd(String trustStorePwd) { return this; } + @Override + public CommonConfig setSslProtocol(String sslProtocol) { + return this; + } + @Override public CommonConfig setDatanodeMemoryProportion(String datanodeMemoryProportion) { return this; diff --git a/integration-test/src/main/java/org/apache/iotdb/itbase/env/CommonConfig.java b/integration-test/src/main/java/org/apache/iotdb/itbase/env/CommonConfig.java index c204f502c9b30..767a047239f98 100644 --- a/integration-test/src/main/java/org/apache/iotdb/itbase/env/CommonConfig.java +++ b/integration-test/src/main/java/org/apache/iotdb/itbase/env/CommonConfig.java @@ -216,6 +216,8 @@ default CommonConfig setDefaultDatabaseLevel(int defaultDatabaseLevel) { CommonConfig setTrustStorePwd(String trustStorePwd); + CommonConfig setSslProtocol(String sslProtocol); + CommonConfig setDatanodeMemoryProportion(String datanodeMemoryProportion); CommonConfig setEnableAuditLog(boolean enableAuditLog); diff --git a/integration-test/src/test/java/org/apache/iotdb/session/it/IoTDBClientSSLIT.java b/integration-test/src/test/java/org/apache/iotdb/session/it/IoTDBClientSSLIT.java index 8aa1aa1403727..23906fdb4c87d 100644 --- a/integration-test/src/test/java/org/apache/iotdb/session/it/IoTDBClientSSLIT.java +++ b/integration-test/src/test/java/org/apache/iotdb/session/it/IoTDBClientSSLIT.java @@ -84,7 +84,8 @@ public static void setUp() throws Exception { .setKeyStorePath(keyStorePath()) .setKeyStorePwd(STORE_PASSWORD) .setTrustStorePath(trustStorePath()) - .setTrustStorePwd(STORE_PASSWORD); + .setTrustStorePwd(STORE_PASSWORD) + .setSslProtocol(SessionConfig.DEFAULT_SSL_PROTOCOL); EnvFactory.getEnv().initClusterEnvironment(); } From 6fa902f8482d5d426da1469ae5c16865c4bcd316 Mon Sep 17 00:00:00 2001 From: HTHou Date: Fri, 19 Jun 2026 17:39:14 +0800 Subject: [PATCH 12/13] Support provider-specific SSL protocols --- .../org/apache/iotdb/rest/RestService.java | 5 +-- .../java/org/apache/iotdb/jdbc/Utils.java | 4 ++- .../java/org/apache/iotdb/jdbc/UtilsTest.java | 4 +-- .../org/apache/iotdb/rpc/RpcSslUtils.java | 32 +++++-------------- .../org/apache/iotdb/rpc/RpcUtilsTest.java | 16 +++------- .../conf/rest/IoTDBRestServiceDescriptor.java | 2 +- .../conf/iotdb-system.properties.template | 3 +- .../iotdb/commons/conf/CommonDescriptor.java | 2 +- 8 files changed, 22 insertions(+), 46 deletions(-) diff --git a/external-service-impl/rest/src/main/java/org/apache/iotdb/rest/RestService.java b/external-service-impl/rest/src/main/java/org/apache/iotdb/rest/RestService.java index ce3624b383f11..506facdb4ce25 100644 --- a/external-service-impl/rest/src/main/java/org/apache/iotdb/rest/RestService.java +++ b/external-service-impl/rest/src/main/java/org/apache/iotdb/rest/RestService.java @@ -148,10 +148,7 @@ public void stop() { } private void configureSSL(SslContextFactory.Server sslContextFactory, String sslProtocol) { - String protocol = RpcSslUtils.normalizeStandardTlsProtocol(sslProtocol); + String protocol = RpcSslUtils.normalizeProtocol(sslProtocol); sslContextFactory.setProtocol(protocol); - if (RpcSslUtils.isSpecificProtocol(protocol)) { - sslContextFactory.setIncludeProtocols(protocol); - } } } diff --git a/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/Utils.java b/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/Utils.java index 16d84b81e9d2f..ea205ef726757 100644 --- a/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/Utils.java +++ b/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/Utils.java @@ -19,6 +19,8 @@ package org.apache.iotdb.jdbc; +import org.apache.iotdb.rpc.RpcSslUtils; + import java.nio.charset.Charset; import java.time.DateTimeException; import java.time.ZoneId; @@ -137,7 +139,7 @@ static IoTDBConnectionParams parseUrl(String url, Properties info) throws IoTDBU params.setTrustStorePwd(info.getProperty(Config.TRUST_STORE_PWD)); } if (info.containsKey(Config.SSL_PROTOCOL)) { - params.setSslProtocol(info.getProperty(Config.SSL_PROTOCOL)); + params.setSslProtocol(RpcSslUtils.normalizeProtocol(info.getProperty(Config.SSL_PROTOCOL))); } if (info.containsKey(Config.SQL_DIALECT)) { params.setSqlDialect(info.getProperty(Config.SQL_DIALECT)); diff --git a/iotdb-client/jdbc/src/test/java/org/apache/iotdb/jdbc/UtilsTest.java b/iotdb-client/jdbc/src/test/java/org/apache/iotdb/jdbc/UtilsTest.java index f2eb5a25629c7..d201a9b2d4569 100644 --- a/iotdb-client/jdbc/src/test/java/org/apache/iotdb/jdbc/UtilsTest.java +++ b/iotdb-client/jdbc/src/test/java/org/apache/iotdb/jdbc/UtilsTest.java @@ -165,9 +165,9 @@ public void testParseSslConfig() throws IoTDBURLException { Properties properties = new Properties(); IoTDBConnectionParams params = Utils.parseUrl( - "jdbc:iotdb://127.0.0.1:6667?use_ssl=true&ssl_protocol=CUSTOMv1", properties); + "jdbc:iotdb://127.0.0.1:6667?use_ssl=true&ssl_protocol=ProviderProtocol", properties); assertTrue(params.isUseSSL()); - assertEquals("CUSTOMv1", params.getSslProtocol()); + assertEquals("ProviderProtocol", params.getSslProtocol()); } } diff --git a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/RpcSslUtils.java b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/RpcSslUtils.java index ae0f0ec748763..c6ceb5b4c5d64 100644 --- a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/RpcSslUtils.java +++ b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/RpcSslUtils.java @@ -28,10 +28,13 @@ import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; -import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; +import java.io.InputStream; import java.nio.file.AccessDeniedException; +import java.nio.file.Files; +import java.nio.file.NoSuchFileException; +import java.nio.file.Path; import java.security.GeneralSecurityException; import java.security.KeyStore; import java.security.cert.X509Certificate; @@ -132,25 +135,6 @@ public static String getProtocol() { return protocol; } - public static boolean isSpecificProtocol(String sslProtocol) { - String trimmed = trimToEmpty(sslProtocol); - return !trimmed.isEmpty() && !DEFAULT_PROTOCOL.equals(trimmed.toUpperCase(Locale.ROOT)); - } - - public static String normalizeStandardTlsProtocol(String sslProtocol) { - String protocol = normalizeProtocol(sslProtocol); - if (!isStandardTlsProtocol(protocol)) { - throw new IllegalArgumentException( - "Unsupported SSL protocol " + protocol + ". Only standard TLS protocols are supported."); - } - return protocol; - } - - public static boolean isStandardTlsProtocol(String sslProtocol) { - String protocol = normalizeProtocol(sslProtocol).toUpperCase(Locale.ROOT); - return DEFAULT_PROTOCOL.equals(protocol) || protocol.matches("TLSV\\d+(\\.\\d+)*"); - } - public static void validateKeyStore(String keyStorePath, String keyStorePassword) throws TTransportException { validateStore(keyStorePath, keyStorePassword); @@ -207,11 +191,11 @@ private static KeyStore loadStore(String storePath, String storePassword) private static KeyStore loadStore(String storePath, String storePassword, String storeType) throws GeneralSecurityException, IOException { KeyStore store = KeyStore.getInstance(storeType); - try (FileInputStream fis = new FileInputStream(storePath)) { - store.load(fis, toPassword(storePassword)); + try (InputStream inputStream = Files.newInputStream(Path.of(storePath))) { + store.load(inputStream, toPassword(storePassword)); } catch (AccessDeniedException e) { throw new AccessDeniedException("Failed to load keystore or truststore file"); - } catch (FileNotFoundException e) { + } catch (FileNotFoundException | NoSuchFileException e) { throw new FileNotFoundException("keystore or truststore file not found: " + storePath); } return store; @@ -237,7 +221,7 @@ private static char[] toPassword(String password) { return password == null ? null : password.toCharArray(); } - private static String normalizeProtocol(String value) { + public static String normalizeProtocol(String value) { String trimmed = trimToEmpty(value); return trimmed.isEmpty() ? DEFAULT_PROTOCOL : trimmed; } diff --git a/iotdb-client/service-rpc/src/test/java/org/apache/iotdb/rpc/RpcUtilsTest.java b/iotdb-client/service-rpc/src/test/java/org/apache/iotdb/rpc/RpcUtilsTest.java index 8c9521e00d1bb..143de1d9ab76a 100644 --- a/iotdb-client/service-rpc/src/test/java/org/apache/iotdb/rpc/RpcUtilsTest.java +++ b/iotdb-client/service-rpc/src/test/java/org/apache/iotdb/rpc/RpcUtilsTest.java @@ -101,17 +101,9 @@ public void testVerifySuccessListThrowsOnFailure() { } @Test - public void testStandardTlsProtocol() { - Assert.assertEquals("TLS", RpcSslUtils.normalizeStandardTlsProtocol(null)); - Assert.assertEquals("TLSv1.3", RpcSslUtils.normalizeStandardTlsProtocol(" TLSv1.3 ")); - Assert.assertTrue(RpcSslUtils.isStandardTlsProtocol("TLSv1.2")); - Assert.assertFalse(RpcSslUtils.isStandardTlsProtocol("CUSTOMv1")); - - try { - RpcSslUtils.normalizeStandardTlsProtocol("CUSTOMv1"); - Assert.fail(); - } catch (IllegalArgumentException e) { - Assert.assertTrue(e.getMessage().contains("Only standard TLS protocols are supported")); - } + public void testSslProtocolNormalization() { + Assert.assertEquals("TLS", RpcSslUtils.normalizeProtocol(null)); + Assert.assertEquals("TLSv1.3", RpcSslUtils.normalizeProtocol(" TLSv1.3 ")); + Assert.assertEquals("ProviderProtocol", RpcSslUtils.normalizeProtocol(" ProviderProtocol ")); } } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/rest/IoTDBRestServiceDescriptor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/rest/IoTDBRestServiceDescriptor.java index a05ade4863d4a..807ef3054e712 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/rest/IoTDBRestServiceDescriptor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/rest/IoTDBRestServiceDescriptor.java @@ -110,7 +110,7 @@ private void loadProps(TrimProperties trimProperties) { trimProperties.getProperty("trust_store_path", conf.getTrustStorePath())); conf.setTrustStorePwd(trimProperties.getProperty("trust_store_pwd", conf.getTrustStorePwd())); conf.setSslProtocol( - RpcSslUtils.normalizeStandardTlsProtocol( + RpcSslUtils.normalizeProtocol( trimProperties.getProperty("ssl_protocol", conf.getSslProtocol()))); conf.setIdleTimeoutInSeconds( Integer.parseInt( diff --git a/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template b/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template index 0f51ad536c9b2..55a716f52813a 100644 --- a/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template +++ b/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template @@ -475,7 +475,8 @@ trust_store_path= trust_store_pwd= # SSL protocol used by server-side SSL services. -# Only standard TLS protocol names are supported, such as TLS, TLSv1.2, or TLSv1.3. +# The protocol is passed to the current JSSE provider, such as TLS, TLSv1.2, +# TLSv1.3, or another provider-specific SSL protocol name. # effectiveMode: restart # Datatype: String # Privilege: SECURITY diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonDescriptor.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonDescriptor.java index 0749df5ace984..9c039cf25c207 100644 --- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonDescriptor.java +++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonDescriptor.java @@ -660,7 +660,7 @@ public void initThriftSSL(TrimProperties properties) { properties.getProperty("trust_store_path", config.getTrustStorePath())); config.setTrustStorePwd(properties.getProperty("trust_store_pwd", config.getTrustStorePwd())); config.setSslProtocol( - RpcSslUtils.normalizeStandardTlsProtocol( + RpcSslUtils.normalizeProtocol( properties.getProperty("ssl_protocol", config.getSslProtocol()))); configureRpcSsl(); } From 5d44daa68d85159534e8148dc9fdf5861660b7d0 Mon Sep 17 00:00:00 2001 From: HTHou Date: Fri, 19 Jun 2026 18:16:16 +0800 Subject: [PATCH 13/13] Remove SSL hostname verification bypass --- .../src/test/resources/test-keystore | Bin 2710 -> 2742 bytes .../src/test/resources/test-truststore | Bin 1238 -> 1270 bytes .../NoHostnameVerificationTrustManager.java | 88 ------------------ .../iotdb/consensus/ratis/utils/Utils.java | 9 +- 4 files changed, 1 insertion(+), 96 deletions(-) delete mode 100644 iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/ratis/utils/NoHostnameVerificationTrustManager.java diff --git a/integration-test/src/test/resources/test-keystore b/integration-test/src/test/resources/test-keystore index 2346c547259fd7e4dfa04cd14d9c99546d08c080..766057947174cc7ddb3cd7fa4312c2793333b18e 100644 GIT binary patch delta 2554 zcmV_?Vl#BKtBn9ZjqhP>WiH?&m1|)yNA5G{wpDD$^w9x?X(SWrCf&|cd_wvi740&P@ zcy@ht7Ibs-Bg%a-HMhgs{t5efOB^_K4zJY@pR4= zcz!8K>{KL?Xrhc|uCbj}FoL3vK8@}R^4@FALyN7gKxQs3tK05lsc}-xHFbZG|A*GN zC0TuRvx@LBz7tV=OEhf^ z09WU8=A`aZxJf#E10W++HspV==`1`&1_A#ehxRN6sRk+P06cHfQDy%COcGfZjGE7l zKMIcTfB`(|-5%!RxUc8bsT9Z-HPl7c!Y7cC)Ld)su(m3OdR+Ct0dsy??kMyFg=Rqe zQjv4GFfwL;@*7HYu^+?&^C4x+wizcJ(0~FkZq=$d2rGCU_U&UtS zfD-m87{$jYispiat7>pYN_b$*;7hYJDztEvm2<@4FXu0uNRkqvC+_G8b$uf&E#g{9 zNwTuE*--ztX4F6M5lx?P%^bjP!|~sk(4#J6o9h_tMcs%aTNu|8tKFK78Y6%da+{VK z>d!-Jv6l!>F6kfH($;^867_yHnQE;?nOf@Av6;4u;=)N$)Oq9^iv9B~pAq_y{@Z5V zA$LwIL6Q^tb(qfyn%og)BJICnHMdlb4OmLdZkJ-u7Futw^?A1(FmmA(=OJ+YSUxS3 zOxcI@1+LR$=qS{FWe}D%yG-|^PjX~O&oX1Cfx7?R;JT_fPR@U_uR}uNs$%MxeRwes z;7Ka(KD|vOB5X`1drLzuz1H?J|7;&JcI$syC6a@N4@IEg91X~%Er~;%xpT~EPAC9c zxui^nS3#y z{%C#y;EGp$%@u!{K<)Y|62mbJ9#j=7KH6>_@vbhm%$xamZ9wLW|&OqG%f!vM%?b)5xvt%S2x zQnY@X_w0~vEP=g>RG|XWZOzwztfFEW=_*O8U^uQ?tE*2gh%%j#Xq)@iM=YvNo>_KZ zU}j|??sI?DZPk(!lOSCh#bL79iJ>bIF8(1a zVbGjvKQcuMwIg2$j5;enA4n(kCDl!)ZBX9guW=I|ypUbS1l2e<{C{&&NPd5b`p{r2 zWV2IjxAs2HU`A`tOS;n0Gz{5FX1M7gzR_$eE7N~Ph!_%SeltFmbHGZ?;*O1Kb&LNQU_Duzgg_YDCD2B3ljf-r&vegXjiFoFbklkf#A z6nRODTEk6-A%IyoP&fYb4D}1(|C28UB!AHZY=9uS>l)ng*3qpD?%05W1OWI-Q9|)& zRvwR+=e$ezmcnelk=N$F54`-txXkeCPd&Q!8w4*;+T-@JL|XljWvQ4uBt!0%Q2QR~ zvV5ouN>t@QT*()Rh%oh8+or{500Nbivli*KH3d}{y`Fqv(l%)P`E~HqyStn)I)9fd zgXqgOlO3gMTp^+5E2L0SA}&HHINHD2_z-ki+REm0gqC`#7Rq`OW$wG9`Y~Hk+QWc_ z8+sf7ELH)((r9zRBhX3QW&5@|NdsFd&XfGs{nG)bR#UC{$rQ`6Yxc04c7{yzi+QH1 z9J0T=dNr$Qxg(%16?ng2=vh9A#(x36Kw)q@V0Ns5!awd%`h9(uREiRVB+V{nmcDh{ z8~mpj>34}Cx#Se^bXzmLx0SCp;vr2eR5e7Tua?jTu(X=Fe*WU|@!kATHuu9!r%riH zgu`KEzp)|sY#j3@q$M?*Eg{3YR`@ddr5@5TRwkVSl$XaF@t2IC;{CAyVSk2n7*u8w zAf(KQkxx^I4Vr3|?7cZ$-F4x``?%x<=47R{#6YmxQn;eZA?muK!UH-+PLi*7OhD+X z;CtzC$lxgY<_pKVyx=V43k=I~hy#NOwMQTk_1eEra)sI`o*rs=>Tw>X;D*f*3iKt03mJXNVzSL!o9I5gS$lFh} z%>KDN&|H1a)xjImhYW4JgMM)1MFyx4Qa>bR8P@$ub`VfQi3~LFM_Ea`T9Dej5=$6| z-r_NhRL~Mfi;~Ya5@SB`(ec`bU$lco*I}T5kcMw3tK632n}4N~LdNfB8SwQA zSClZnmY$fiwln6>-B_6$eBd=GuI2*L)0Nv*rIYOYT}UC^wMPT+vr4 ziQdV$J2N>Ox?#_>xkfNfVpgUF_T_7k`cX<}v?VxNb~HJF7ZFaBx{b3Kz(VzrI~w&o zV2OJnYJnVRZ6GP0wSQgVI(Vs=7yCWEGd7wUenFt#Ge2mc+b8KH2?mPtX(Wa~%jrPz zDX`c^iT(TdAg@+M-)YA{SrRWF44TefCdX^3?Azl_ulFB1)+e=y2hi(WN;o?X%WIEY zQ75E?r1MqfYfnBWs$+1}T40su*D|>PtME7{uF|iK&LV(yjeqcgUp4jCPE~kB4apf@ z!CCM#>I5gAVvA)M6jQnk0jYStvWj8MY*QXl9@90Gd>YkS+qmu=gt_ZUMxNymw$q|( z7tAs#(nTcW$=pnNC9O7 z1OfpC00bZqmQ&)9o)ue`^p&sz-H#5d&C>gaUs@a67Hu3LHp6!pynmU87oXpEjR QJ0SfdmBZjg$^rr>5Ph@Sga7~l delta 2522 zcmV<02_^Qn6_ynuFoFt_0s#Xsf(kqa2`Yw2hW8Bt2LYgh3M~YJ3Mnvx3MG*uR21+p zx?dRTwS7N|@;G3bH8g4#qgs0vG8pi` zd?zi4L1;;6!B#EAvY=D%rctsQ;lwt_q~^G7NEY|Dq2-k%tv&;5HkbDhUB7=ZhR`X2 zmrtT+;9afMw5lsXpdzQv1ci!}UaESBLnwWw2bw_2l35zCp@4UST-b}rzK9yRu4RUa zCt2$IUX+<4l#?Pd521R?@s>QscdVxDNI7zdS))OOx5TqnpOgbCpiVzNtVbKEM97aD z_s%4?LojbJ(h^&}1YSHA4H&cuyNRs$#Wke*U1KnEJEL1kKm6fqR*#IObIGM3i z@3qAJZ=hPD7TaySaCJ_seU_9NhA&*=YotiaK#*4kQj|zdwJGqDPTS{uPGYsZ$xq zP}EkAuT9$&m+oAzc6X95xr!fQ5wj78vb$v2_|&OG8;`%ycMy=zH1!=PIX}X#&VPH_ zBzv;wEn*;I=Qoa>?c(}B4ZOcg*C`PemUsH-{A1kaa^%G}O}|; zBcDED5Po0Ic+G#tOBWp=MH@9zhdCipHTiED%#p?)Y03KzentQaZpG1@1Y`bACpA&5 zNmxWePFDakdn_nGbC9ue{nlU`+B`qvqQ6o?!n*jjIIKGpF;giFU%;z!rI}h?jBSyz zGzK(Ko}|UlcUZ#`nlq6R0hM2%nMr@#C7`3VHXTxoy-R=DA}pc9%pG$VbujF5fHzl5 zA<53Ps^Q=>WRBAlw#%iD4CR0j*ZQO!KNmjhu3XRcC(yL-2#D``xPxN|oDk};8Ar=` z2>fKDBThwn&dG|-C)B@h57}jY%_)-=i2Csv?-^ACG2|aOnjE2i=K05;kfTzI_uG%i zW_hNf9)W+b__wg=($^%7MTcJD1}SW{P7PRydfps>9!AJ^s|qn!brAGnmOl)EIN`t7 zMCl8MwWmjS`5G}hQ&=*Rmkuru0i@s}y68gXQNX5_pn^c=$VINOJiCLz>Vpx343{pf zXZE=H{44YIMv6bAg-*f$GY^evkLx2UWKpPDH}!wj?u^XG3+|nHwHgGeP0o7H1F(1L zJaT$LgVf7wMv$9vJf9z$p^DQdc>v&7c4*1)$w(Hiq_s_i={6BcMfSuu+yVO6VTQVc zs8FLHhaZ07GKxNteEN#`qV`3ff#0&LNQU3pa<~cqFILB9ku$B!8qXTxs%v?s|FjNyf#^xHW)+1K^YO=c7O| zuJJErWoD?ge6VgIMPri84_EH>OOnNgi8eLhUw@S|E_mEEjLoA8hSQi+{>- zR3>X1oBx(gBu;$EXSGg6{L4k%-?J<~CQZiwbrF&FJhr^RT^Eb<6SS)*bbyI{m$r5M{arF*-{ylL_-5*E4mSZOkc*q&oiYb7Gp5jK(zUg=~%9HN6Gj&B}y|g9ByEAMBF5u zL0h_L{dE*OHAWGd4CQ2QNxIT0khzO@4Z?PQqcFq);NXCS(_<02oHZaV@B`?eax=9@9{7a;S#`$994D{Kyo# zhY~tMorLA&FwkH~Q1o9ZBWMQ%1>TbnA&w+Rfkdug9e8tSd_vm#UZ(8JFJ=P0nryVW z7h_T`%iqQUlr4z)9uA>%sMMsl^sV1d#ujPrUV@(lyJEGQsPcE1&y34;;ww-Jfx4tg^djO z;jM{X#RBkfk8sjXF-Irx#K0N zh?Ot1^$*Cj{2@%UX5N>4P=x*p^*-4>w0E~-iue4C&O0;V%YTNY$PO-w^ysWsXk=pk z+Sn5OB$X(=M1qONC9O71OfpC00bb?4A+5dBCJi(53M~=i75T_^b>$x1H4=r k06uq5oRb{{6jQ)jK%l=M5Pu6n%XX+2NI-v@!2$v&5SJ&v(*OVf diff --git a/integration-test/src/test/resources/test-truststore b/integration-test/src/test/resources/test-truststore index 92c5b819f21f1705578b3d58552afb63764988e0..c6b93a476c560d6d4fc0fe5636d9f48bcef7a1c7 100644 GIT binary patch delta 1212 zcmV;t1Vj7Q3HAvNN{1n5HN)$~;Zg3x8IW)bYo)5BUC(<)-3ihSj;L5!k@}(R-*mJa1;}NEDy3Y^{nn zKun4u@Rw?&OI$4w>jB$c@0_l9daB}o0dP}gUK^Lm6F&uXS-K2Ykj8mvP1bavmYnYRQ)oHyY_#T->9C=k z61&EheJ8YgY;_hSXiF|aUa8a}I2c=#Cx#Q6f|vrY3b3%aQ7!6_eZ(B0~GPAb?^ zGC?SzDfuz;_QX6CvLp+O6sJHkprpPQPiYDsvb){m*>MZa8S%MnVej3Rzke$cJ!0=S zR1eas-$ypsDfg<7s!&*8G43UQk;B>=IBYXouF;KUC!GnzHbYU%=!!ZHhFnqOyDnr( z#i}@wh1lfX~@w&$k zY+^$H0AM?w#yy#o?%GgH5YZ`ftVX8c@YP-4!fTJ1Gu|LOuGeaOMM2AeB?`t@UiL?4 z*=wVALgATzt+2uNm8Cb|}iZL61{dRcgl5 z=IaiA`ara9AeqbPIIj{V-Gx~XH)}{)1+UrU0LZOAXmeWe`O=zrWCr4ShRmX zF_3M0&1D%ovuQfx6Ikn{}vJ-OjIn%ozqof~H*B(9|3h z+9J1i)caIDho*grNPRk`n80A0R9Kw$o;o0v2@P-YYt>?H%p#t4%^Xb(0gy51g11GP zQ5;G8z)}7)jE_5#Bfey}DL%Z5u0UVI1RtF9eFd8X52{GwK>93Lq7_PNP|5oA#~V+9 z?B@KjXxUCPPHZNBEE3SXBrQqukphchgTM~0rrS1sggwkFQiDkickoS2YP5AM*+_D+ zf}6tnPd5f1eG0>eE?wVMI9qqaoO0(bm(QWg0pl<)GT#k#bB5oWV7v0y!5%Mj0}?zO z8bFzq3<#Z0dF*;dljzA@XlD0|vTp!%l@JHKtAB>FyZJ9$(f*$%XNm#!Gg;IwFikKq zFbxI?V1`HmWdj5P0R;dAAWfi16YAKEwn!!(Oc0wdngce#vsN{9dc6-8=NWD8Ed&%9 a0I@7mZ~_Rk6sk$Vs<3{X+cXIR0w)li=P}>_ delta 1180 zcmV;N1Y`U53DyZfFoFcq0s#Xsf&_d92`Yw2hW8Bt2LYgh1Z@O@1ZgmW1Z6OS1YrgV zDuzgg_YDCD2B3ljQZRx9P67b{FoFa}kw7aHo#QH&-P_u#zW{S74fTgY4nw*ak$)tA z0f;3L7|Uz!8v64Ffa&FofPw?iE8pyxZ_P2ExI`}UD1Rj;^l|4JUt)cb^4~i3rBFpk zT1<}@RRf9YFvfRNCr(R<&Gqw<9NVGI=1%x!$dE%oJ(zrCw(mSHd7*N7cZ(ePj#ejr zyMoKsDP9h1jUlI-EE)wW;ezXz>|8^O76dSl~sqW0(oLksa{E!oYC#$fSE&#p4WQRXZ#oc zHh^sc7ckB7{k)$ zy#~t89^Xpp3|pF!9OtLC+xsq|pkcx;nRT1I&oba`wk@=xsLlYXOKrA)M)lbh8TO$l zjaThzB+uBV7!ghtrU^*k!k)FYvpW5P`g5jnjX{4D>I{9Fo}uCaZNR-E zfx|r-0-@(xL+(F`4iq+N5@a(E#8>SJldNf>b^K)DTSSe0;ze$Mu;A+RCIkW3L3mf< z-ftY++*p>d2$mierdVL!DfDJ$0eh!=Ef)wfySm9B6v~n_hfa$pG zqVtS9(7_me>JzAc<9JR1svMi925(VoePK67x|1jj5GlqX2w@|=O^`f{=Y*8~)H<0%pNW_#4`^LoCP`(fLK0*faC0w)j?*E+}m diff --git a/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/ratis/utils/NoHostnameVerificationTrustManager.java b/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/ratis/utils/NoHostnameVerificationTrustManager.java deleted file mode 100644 index fb5c908548861..0000000000000 --- a/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/ratis/utils/NoHostnameVerificationTrustManager.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.apache.iotdb.consensus.ratis.utils; - -import javax.net.ssl.SSLEngine; -import javax.net.ssl.X509ExtendedTrustManager; -import javax.net.ssl.X509TrustManager; - -import java.net.Socket; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; - -public class NoHostnameVerificationTrustManager extends X509ExtendedTrustManager { - - private final X509TrustManager delegate; - - public NoHostnameVerificationTrustManager(X509TrustManager delegate) { - this.delegate = delegate; - } - - @Override - public X509Certificate[] getAcceptedIssuers() { - return delegate.getAcceptedIssuers(); - } - - @Override - public void checkClientTrusted(X509Certificate[] chain, String authType) - throws CertificateException { - delegate.checkClientTrusted(chain, authType); - } - - @Override - public void checkServerTrusted(X509Certificate[] chain, String authType) - throws CertificateException { - delegate.checkServerTrusted(chain, authType); - } - - @Override - public void checkClientTrusted(X509Certificate[] chain, String authType, Socket socket) - throws CertificateException { - if (delegate instanceof X509ExtendedTrustManager) { - ((X509ExtendedTrustManager) delegate).checkClientTrusted(chain, authType, socket); - } else { - delegate.checkClientTrusted(chain, authType); - } - } - - @Override - public void checkServerTrusted(X509Certificate[] chain, String authType, Socket socket) - throws CertificateException { - // Skip hostname check by calling base method - delegate.checkServerTrusted(chain, authType); - } - - @Override - public void checkClientTrusted(X509Certificate[] chain, String authType, SSLEngine engine) - throws CertificateException { - if (delegate instanceof X509ExtendedTrustManager) { - ((X509ExtendedTrustManager) delegate).checkClientTrusted(chain, authType, engine); - } else { - delegate.checkClientTrusted(chain, authType); - } - } - - @Override - public void checkServerTrusted(X509Certificate[] chain, String authType, SSLEngine engine) - throws CertificateException { - // Skip hostname check by calling base method - delegate.checkServerTrusted(chain, authType); - } -} diff --git a/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/ratis/utils/Utils.java b/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/ratis/utils/Utils.java index 9e6cee1411558..442ac4840649e 100644 --- a/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/ratis/utils/Utils.java +++ b/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/ratis/utils/Utils.java @@ -55,7 +55,6 @@ import javax.net.ssl.KeyManager; import javax.net.ssl.TrustManager; -import javax.net.ssl.X509TrustManager; import java.io.File; import java.io.FileNotFoundException; @@ -368,14 +367,8 @@ public static Parameters initRatisConfig(RaftProperties properties, RatisConfig String trustStorePassword = config.getGrpc().getSslTrustStorePassword(); try { KeyManager keyManager = RpcSslUtils.createKeyManagers(keyStorePath, keyStorePassword)[0]; - TrustManager originalTrustManager = - RpcSslUtils.createTrustManagers(trustStorePath, trustStorePassword)[0]; - - // The self-signed certification may not set Subject Alternative Name (SAN) - // Thrift with ssl didn't check it, but Grpc did. - // Wrap to disable the verification TrustManager trustManager = - new NoHostnameVerificationTrustManager((X509TrustManager) originalTrustManager); + RpcSslUtils.createTrustManagers(trustStorePath, trustStorePassword)[0]; GrpcConfigKeys.TLS.setConf(parameters, new GrpcTlsConfig(keyManager, trustManager, true)); } catch (AccessDeniedException e) { LOGGER.error(ConsensusMessages.FAILED_TO_LOAD_KEYSTORE);