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 2e072d87961c0..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 @@ -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,7 @@ private void startSSL( String trustStorePath, String keyStorePwd, String trustStorePwd, + String sslProtocol, int idleTime, boolean clientAuth) { server = new Server(); @@ -61,6 +63,7 @@ private void startSSL( httpsConfig.addCustomizer(new SecureRequestCustomizer()); SslContextFactory.Server sslContextFactory = new SslContextFactory.Server(); + configureSSL(sslContextFactory, sslProtocol); sslContextFactory.setKeyStorePath(keyStorePath); sslContextFactory.setKeyStorePassword(keyStorePwd); if (clientAuth) { @@ -125,6 +128,7 @@ public void start() { config.getTrustStorePath(), config.getKeyStorePwd(), config.getTrustStorePwd(), + config.getSslProtocol(), config.getIdleTimeoutInSeconds(), config.isClientAuth()); } else { @@ -142,4 +146,12 @@ public void stop() { server.destroy(); } } + + private void configureSSL(SslContextFactory.Server sslContextFactory, String sslProtocol) { + String protocol = RpcSslUtils.normalizeStandardTlsProtocol(sslProtocol); + sslContextFactory.setProtocol(protocol); + if (RpcSslUtils.isSpecificProtocol(protocol)) { + sslContextFactory.setIncludeProtocols(protocol); + } + } } 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..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 @@ -77,12 +77,15 @@ public abstract class AbstractCli { static final String TRUST_STORE_PWD_ARGS = "tpw"; + static final String SSL_PROTOCOL_ARGS = "ssl_protocol"; + 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 NULL = "null"; static final int CODE_OK = 0; @@ -132,6 +135,7 @@ public abstract class AbstractCli { static String trustStore; // TODO: Make non-static static String trustStorePwd; + static String sslProtocol; static String execute; static boolean hasExecuteSQL = false; @@ -156,6 +160,7 @@ 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("-" + EXECUTE_ARGS); keywordSet.add("-" + ISO8601_ARGS); keywordSet.add("-" + RPC_COMPRESS_ARGS); @@ -214,6 +219,15 @@ 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 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..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 @@ -111,6 +111,9 @@ 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); + } } info.setProperty("user", username); info.setProperty("password", password); @@ -159,6 +162,7 @@ private static boolean parseCommandLine( private static void serve(CliContext ctx) { try { useSsl = commandLine.getOptionValue(USE_SSL_ARGS); + sslProtocol = commandLine.getOptionValue(SSL_PROTOCOL_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..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 @@ -68,6 +68,10 @@ 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 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..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 @@ -133,6 +133,16 @@ 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); + 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..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 @@ -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,7 @@ public abstract class AbstractDataTool { protected static Boolean useSsl; protected static String trustStore; protected static String trustStorePwd; + protected static String sslProtocol; protected static Boolean aligned; protected static String database; protected static String startTime; @@ -134,6 +138,38 @@ 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); + } + return builder; + } + + protected static SessionPool.Builder configureSsl(SessionPool.Builder builder) { + builder.useSSL(true).trustStore(trustStore).trustStorePwd(trustStorePwd); + if (sslProtocol != null) { + builder.sslProtocol(sslProtocol); + } + return builder; + } + + protected static TableSessionBuilder configureSsl(TableSessionBuilder builder) { + builder.useSSL(true).trustStore(trustStore).trustStorePwd(trustStorePwd); + if (sslProtocol != null) { + builder.sslProtocol(sslProtocol); + } + return builder; + } + + protected static TableSessionPoolBuilder configureSsl(TableSessionPoolBuilder builder) { + builder.useSSL(true).trustStore(trustStore).trustStorePwd(trustStorePwd); + if (sslProtocol != null) { + builder.sslProtocol(sslProtocol); + } + return builder; + } + protected static String checkRequiredArg( String arg, String name, CommandLine commandLine, String defaultValue) throws ArgsErrorException { @@ -170,6 +206,7 @@ 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); 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..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 @@ -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,7 @@ public abstract class AbstractSchemaTool { protected static Boolean useSsl; protected static String trustStore; protected static String trustStorePwd; + protected static String sslProtocol; protected static Session session; protected static String queryPath; protected static int threadNum = 8; @@ -73,6 +76,30 @@ 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); + } + return builder; + } + + protected static SessionPool.Builder configureSsl(SessionPool.Builder builder) { + builder.useSSL(true).trustStore(trustStore).trustStorePwd(trustStorePwd); + if (sslProtocol != null) { + builder.sslProtocol(sslProtocol); + } + return builder; + } + + protected static TableSessionPoolBuilder configureSsl(TableSessionPoolBuilder builder) { + builder.useSSL(true).trustStore(trustStore).trustStorePwd(trustStorePwd); + if (sslProtocol != null) { + builder.sslProtocol(sslProtocol); + } + return builder; + } + protected static String checkRequiredArg( String arg, String name, CommandLine commandLine, String defaultValue) throws ArgsErrorException { @@ -107,6 +134,7 @@ 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); 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..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 @@ -56,5 +56,7 @@ public class SessionConfig { public static final String SQL_DIALECT = "tree"; + public static final String DEFAULT_SSL_PROTOCOL = "TLS"; + 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..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 @@ -82,6 +82,10 @@ private Config() { public static final String TRUST_STORE_PWD = "trust_store_pwd"; + public static final String SSL_PROTOCOL = "ssl_protocol"; + + static final String DEFAULT_SSL_PROTOCOL = "TLS"; + 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..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 @@ -544,12 +544,13 @@ 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()); } 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..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 @@ -51,6 +51,7 @@ public class IoTDBConnectionParams { private boolean useSSL = false; private String trustStore; private String trustStorePwd; + private String sslProtocol = Config.DEFAULT_SSL_PROTOCOL; private String sqlDialect = TREE; @@ -184,6 +185,14 @@ public void setTrustStorePwd(String trustStorePwd) { this.trustStorePwd = trustStorePwd; } + public String getSslProtocol() { + return sslProtocol; + } + + public void setSslProtocol(String sslProtocol) { + this.sslProtocol = sslProtocol; + } + 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..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 @@ -136,6 +136,9 @@ 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.SQL_DIALECT)) { params.setSqlDialect(info.getProperty(Config.SQL_DIALECT)); } @@ -175,6 +178,7 @@ 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.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..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 @@ -159,4 +159,15 @@ 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=CUSTOMv1", properties); + + assertTrue(params.isUseSSL()); + 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 22e104b6a58ac..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,9 +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); + } + + public TTransport getTransportWithSSLConfig( + String ip, int port, int timeout, String trustStore, String trustStorePwd, String sslProtocol) + throws TTransportException { TSSLTransportFactory.TSSLTransportParameters params = - new TSSLTransportFactory.TSSLTransportParameters(); - params.setTrustStore(trustStore, trustStorePwd); + RpcSslUtils.createTSSLTransportParameters(sslProtocol); + RpcSslUtils.setTrustStore(params, trustStore, trustStorePwd); TTransport transport = TSSLTransportFactory.getClientSocket(ip, port, timeout, params); return inner.getTransport(transport); } @@ -99,11 +105,24 @@ public TTransport getTransport( String keyStore, String keyStorePwd) throws TTransportException { + return getTransport(ip, port, timeout, trustStore, trustStorePwd, keyStore, keyStorePwd, null); + } + + public TTransport getTransport( + String ip, + int port, + int timeout, + String trustStore, + String trustStorePwd, + String keyStore, + String keyStorePwd, + String sslProtocol) + throws TTransportException { TSSLTransportFactory.TSSLTransportParameters params = - new TSSLTransportFactory.TSSLTransportParameters(); + RpcSslUtils.createTSSLTransportParameters(sslProtocol); if (Files.exists(Paths.get(trustStore)) && Files.exists(Paths.get(keyStore))) { - params.setTrustStore(trustStore, trustStorePwd); - params.setKeyStore(keyStore, keyStorePwd); + 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 new file mode 100644 index 0000000000000..ae0f0ec748763 --- /dev/null +++ b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/RpcSslUtils.java @@ -0,0 +1,261 @@ +/* + * 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.TrustManager; +import javax.net.ssl.TrustManagerFactory; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.nio.file.AccessDeniedException; +import java.security.GeneralSecurityException; +import java.security.KeyStore; +import java.security.cert.X509Certificate; +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 String protocol = DEFAULT_PROTOCOL; + + private RpcSslUtils() {} + + public static void configure(String sslProtocol) { + protocol = normalizeProtocol(sslProtocol); + } + + public static TSSLTransportFactory.TSSLTransportParameters createTSSLTransportParameters() { + return createTSSLTransportParameters(protocol); + } + + public static TSSLTransportFactory.TSSLTransportParameters createTSSLTransportParameters( + String sslProtocol) { + return new TSSLTransportFactory.TSSLTransportParameters(normalizeProtocol(sslProtocol), null); + } + + public static void setKeyStore( + TSSLTransportFactory.TSSLTransportParameters params, String keyStorePath, String keyStorePwd) + throws TTransportException { + try { + 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 { + try { + 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 { + return createSSLContext( + keyStorePath, keyStorePassword, trustStorePath, trustStorePassword, protocol); + } + + public static SSLContext createSSLContext( + String keyStorePath, + String keyStorePassword, + String trustStorePath, + String trustStorePassword, + String sslProtocol) + throws GeneralSecurityException, IOException { + SSLContext context = SSLContext.getInstance(normalizeProtocol(sslProtocol)); + 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 { + return loadKeyManagers(keyStorePath, keyStorePassword); + } + + public static TrustManager[] createTrustManagers(String trustStorePath, String trustStorePassword) + throws GeneralSecurityException, IOException { + return loadTrustManagers(trustStorePath, trustStorePassword); + } + + 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); + } + + 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 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 { + 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 char[] toPassword(String password) { + return password == null ? null : password.toCharArray(); + } + + private static String normalizeProtocol(String value) { + String trimmed = trimToEmpty(value); + return trimmed.isEmpty() ? DEFAULT_PROTOCOL : 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[] 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); + } +} 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 f6132d8041f1b..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 @@ -62,6 +62,7 @@ public abstract class AbstractSessionBuilder { public boolean useSSL = false; public String trustStore; public String trustStorePwd; + public String sslProtocol = SessionConfig.DEFAULT_SSL_PROTOCOL; // 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..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 @@ -61,6 +61,7 @@ public class NodesSupplier implements INodeSupplier, Runnable { private final boolean useSSL; private final String trustStore; private final String trustStorePwd; + private final String sslProtocol; private final boolean enableRPCCompression; private final String userName; @@ -95,6 +96,7 @@ public static NodesSupplier createNodeSupplier( boolean useSSL, String trustStore, String trustStorePwd, + String sslProtocol, boolean enableRPCCompression, String version) { @@ -110,6 +112,7 @@ public static NodesSupplier createNodeSupplier( useSSL, trustStore, trustStorePwd, + sslProtocol, enableRPCCompression, version); @@ -132,6 +135,7 @@ private NodesSupplier( boolean useSSL, String trustStore, String trustStorePwd, + String sslProtocol, boolean enableRPCCompression, String version) { this.availableNodes.addAll(new HashSet<>(endPointList)); @@ -140,6 +144,7 @@ private NodesSupplier( this.useSSL = useSSL; this.trustStore = trustStore; this.trustStorePwd = trustStorePwd; + this.sslProtocol = sslProtocol; this.enableRPCCompression = enableRPCCompression; this.zoneId = zoneId == null ? ZoneId.systemDefault() : zoneId; this.thriftDefaultBufferSize = thriftDefaultBufferSize; @@ -188,6 +193,7 @@ private boolean createConnection(TEndPoint endPoint) { useSSL, trustStore, trustStorePwd, + sslProtocol, 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..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 @@ -133,6 +133,7 @@ public class Session implements ISession { protected boolean useSSL; protected String trustStore; protected String trustStorePwd; + protected String sslProtocol; /** * Timeout of query can be set by users. A negative number means using the default configuration @@ -472,6 +473,7 @@ public Session(AbstractSessionBuilder builder) { this.useSSL = builder.useSSL; this.trustStore = builder.trustStore; this.trustStorePwd = builder.trustStorePwd; + this.sslProtocol = builder.sslProtocol; this.enableAutoFetch = builder.enableAutoFetch; this.maxRetryCount = builder.maxRetryCount; this.retryIntervalInMs = builder.retryIntervalInMs; @@ -541,6 +543,7 @@ public synchronized void open(boolean enableRPCCompaction, int connectionTimeout useSSL, trustStore, trustStorePwd, + sslProtocol, enableRPCCompaction, version.toString()); } else { @@ -4433,6 +4436,11 @@ public Builder trustStorePwd(String trustStorePwd) { return this; } + public Builder sslProtocol(String sslProtocol) { + this.sslProtocol = sslProtocol; + 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..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 @@ -151,7 +151,8 @@ 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); } catch (StatementExecutionException e) { throw new IoTDBConnectionException(e.getMessage()); } catch (IoTDBConnectionException e) { @@ -179,7 +180,12 @@ 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) throws IoTDBConnectionException, StatementExecutionException { DeepCopyRpcTransportFactory.setDefaultBufferCapacity(session.thriftDefaultBufferSize); DeepCopyRpcTransportFactory.setThriftMaxFrameSize(session.thriftMaxFrameSize); @@ -189,12 +195,13 @@ 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); } else { transport = DeepCopyRpcTransportFactory.INSTANCE.getTransport( @@ -262,7 +269,12 @@ 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); } catch (IoTDBConnectionException e) { if (!reconnect()) { logger.error(SessionMessages.CLUSTER_NO_NODES); @@ -1079,7 +1091,12 @@ private boolean reconnect() { } tryHostNum++; try { - init(endPoint, session.useSSL, session.trustStore, session.trustStorePwd); + init( + endPoint, + session.useSSL, + session.trustStore, + session.trustStorePwd, + 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 be53797165a6a..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 @@ -239,6 +239,18 @@ 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; + } + /** * 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..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 @@ -78,6 +78,7 @@ public void init( boolean useSSL, String trustStore, String trustStorePwd, + String sslProtocol, String username, String password, boolean enableRPCCompression, @@ -89,12 +90,13 @@ public void init( try { if (useSSL) { transport = - DeepCopyRpcTransportFactory.INSTANCE.getTransport( + DeepCopyRpcTransportFactory.INSTANCE.getTransportWithSSLConfig( endPoint.getIp(), endPoint.getPort(), connectionTimeoutInMs, trustStore, - trustStorePwd); + trustStorePwd, + 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 3eaabe7f1fa78..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 @@ -116,6 +116,9 @@ public class SessionPool implements ISessionPool { private String trustStore; private String trustStorePwd; + + private String sslProtocol = SessionConfig.DEFAULT_SSL_PROTOCOL; + 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 +469,7 @@ public SessionPool( this.useSSL = useSSL; this.trustStore = trustStore; this.trustStorePwd = trustStorePwd; + this.sslProtocol = SessionConfig.DEFAULT_SSL_PROTOCOL; initThreadPool(); initAvailableNodes(Collections.singletonList(new TEndPoint(host, port))); } @@ -536,6 +540,7 @@ public SessionPool(AbstractSessionPoolBuilder builder) { this.useSSL = builder.useSSL; this.trustStore = builder.trustStore; this.trustStorePwd = builder.trustStorePwd; + this.sslProtocol = builder.sslProtocol; this.maxRetryCount = builder.maxRetryCount; this.retryIntervalInMs = builder.retryIntervalInMs; this.sqlDialect = builder.sqlDialect; @@ -593,6 +598,7 @@ private Session constructNewSession() { .useSSL(useSSL) .trustStore(trustStore) .trustStorePwd(trustStorePwd) + .sslProtocol(sslProtocol) .maxRetryCount(maxRetryCount) .retryIntervalInMs(retryIntervalInMs) .sqlDialect(sqlDialect) @@ -618,6 +624,7 @@ private Session constructNewSession() { .useSSL(useSSL) .trustStore(trustStore) .trustStorePwd(trustStorePwd) + .sslProtocol(sslProtocol) .maxRetryCount(maxRetryCount) .retryIntervalInMs(retryIntervalInMs) .sqlDialect(sqlDialect) @@ -662,6 +669,7 @@ private void initAvailableNodes(List endPointList) { useSSL, trustStore, trustStorePwd, + sslProtocol, enableThriftCompression, version.toString()); } @@ -3637,6 +3645,11 @@ public Builder trustStorePwd(String trustStorePwd) { return this; } + public Builder sslProtocol(String sslProtocol) { + this.sslProtocol = sslProtocol; + 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..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 @@ -281,6 +281,18 @@ 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; + } + /** * 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/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..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 @@ -45,6 +45,9 @@ public class IoTDBRestServiceConfig { /** ssl trust Store password. */ private String trustStorePwd = ""; + /** SSL protocol. */ + private String sslProtocol = ""; + /** ssl timeout. */ private int idleTimeoutInSeconds = 50000; @@ -78,6 +81,14 @@ public void setTrustStorePwd(String trustStorePwd) { this.trustStorePwd = trustStorePwd; } + public String getSslProtocol() { + return sslProtocol; + } + + public void setSslProtocol(String sslProtocol) { + this.sslProtocol = sslProtocol; + } + 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..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,6 +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( + 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 3b2d5ff54731c..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,6 +474,13 @@ trust_store_path= # Datatype: String 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. +# effectiveMode: restart +# Datatype: String +# Privilege: SECURITY +ssl_protocol=TLS + #################### ### 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 6a8956e423b48..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 @@ -467,6 +467,9 @@ public class CommonConfig { /** ssl trust Store password. */ private String trustStorePwd = ""; + /** SSL protocol. */ + private String sslProtocol = "TLS"; + private String userEncryptTokenHint = "not set yet"; private boolean enforceStrongPassword = false; @@ -2813,6 +2816,14 @@ public void setTrustStorePwd(String trustStorePwd) { this.trustStorePwd = trustStorePwd; } + public String getSslProtocol() { + return sslProtocol; + } + + public void setSslProtocol(String sslProtocol) { + this.sslProtocol = sslProtocol; + } + 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..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 @@ -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,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( + RpcSslUtils.normalizeStandardTlsProtocol( + properties.getProperty("ssl_protocol", config.getSslProtocol()))); + configureRpcSsl(); + } + + public void configureRpcSsl() { + RpcSslUtils.configure(config.getSslProtocol()); } } 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, 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