From ce923a3a1a831a9573c2188320b6fd1848ce5e60 Mon Sep 17 00:00:00 2001 From: ywy2090 <912554887@qq.com> Date: Thu, 18 Apr 2024 16:22:28 +0800 Subject: [PATCH 1/3] load sm context builder from class loader (#914) * load sm context builder from class loader * fix load cert by relative path failed bug --- build.gradle | 2 +- .../bcos/sdk/config/model/ConfigProperty.java | 2 +- .../bcos/sdk/network/ConnectionManager.java | 91 +---------- .../sdk/network/SslContextInitializer.java | 142 ++++++++++++++++++ 4 files changed, 149 insertions(+), 88 deletions(-) create mode 100644 sdk-core/src/main/java/org/fisco/bcos/sdk/network/SslContextInitializer.java diff --git a/build.gradle b/build.gradle index fc476b823..5a558ab47 100644 --- a/build.gradle +++ b/build.gradle @@ -35,7 +35,7 @@ ext { // integrationTest.mustRunAfter test allprojects { group = 'org.fisco-bcos.java-sdk' - version = '2.10.0' + version = '2.10.1-SNAPSHOT' apply plugin: 'maven' apply plugin: 'maven-publish' apply plugin: 'idea' diff --git a/sdk-core/src/main/java/org/fisco/bcos/sdk/config/model/ConfigProperty.java b/sdk-core/src/main/java/org/fisco/bcos/sdk/config/model/ConfigProperty.java index f8f440e1a..206d4a8bc 100644 --- a/sdk-core/src/main/java/org/fisco/bcos/sdk/config/model/ConfigProperty.java +++ b/sdk-core/src/main/java/org/fisco/bcos/sdk/config/model/ConfigProperty.java @@ -105,7 +105,7 @@ public static InputStream getConfigInputStream(String configFilePath) throws Con } InputStream inputStream = null; try { - configFilePath = configFilePath.replace("..", ""); + // configFilePath = configFilePath.replace("..", ""); inputStream = new FileInputStream(configFilePath); if (inputStream != null) { return inputStream; diff --git a/sdk-core/src/main/java/org/fisco/bcos/sdk/network/ConnectionManager.java b/sdk-core/src/main/java/org/fisco/bcos/sdk/network/ConnectionManager.java index 69e5d84fb..14c8c2c22 100644 --- a/sdk-core/src/main/java/org/fisco/bcos/sdk/network/ConnectionManager.java +++ b/sdk-core/src/main/java/org/fisco/bcos/sdk/network/ConnectionManager.java @@ -28,16 +28,11 @@ import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.handler.codec.LengthFieldBasedFrameDecoder; -import io.netty.handler.ssl.SMSslClientContextFactory; import io.netty.handler.ssl.SslContext; -import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.SslHandler; -import io.netty.handler.ssl.SslProvider; import io.netty.handler.timeout.IdleStateHandler; import io.netty.util.concurrent.Future; -import java.io.IOException; import java.nio.channels.ClosedChannelException; -import java.security.Security; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -70,6 +65,9 @@ public class ConnectionManager { private EventLoopGroup workerGroup; private Boolean running = false; private Bootstrap bootstrap = new Bootstrap(); + + private SslContextInitializer sslContextInitializer = new SslContextInitializer(); + private List connChannelFuture = new ArrayList(); private ScheduledExecutorService reconnSchedule = new ScheduledThreadPoolExecutor(1); private int cryptoType; @@ -228,85 +226,6 @@ public ChannelHandlerContext getConnectionCtx(String peer) { return availableConnections.get(peer); } - private SslContext initSslContext(ConfigOption configOption) throws NetworkException { - try { - Security.setProperty("jdk.disabled.namedCurves", ""); - System.setProperty("jdk.sunec.disableNative", "false"); - - // Get file, file existence is already checked when check config file. - // Init SslContext - logger.info(" build ECDSA ssl context with configured certificates "); - SslContext sslCtx = - SslContextBuilder.forClient() - .trustManager(configOption.getCryptoMaterialConfig().getCaInputStream()) - .keyManager( - configOption.getCryptoMaterialConfig().getSdkCertInputStream(), - configOption - .getCryptoMaterialConfig() - .getSdkPrivateKeyInputStream()) - .sslProvider(SslProvider.OPENSSL) - // .sslProvider(SslProvider.JDK) - .build(); - return sslCtx; - } catch (IOException e) { - logger.error( - "initSslContext failed, caCert: {}, sslCert: {}, sslKey: {}, error: {}, e: {}", - configOption.getCryptoMaterialConfig().getCaCertPath(), - configOption.getCryptoMaterialConfig().getSdkCertPath(), - configOption.getCryptoMaterialConfig().getSdkPrivateKeyPath(), - e.getMessage(), - e); - throw new NetworkException( - "SSL context init failed, please make sure your cert and key files are properly configured. error info: " - + e.getMessage(), - NetworkException.INIT_CONTEXT_FAILED); - } catch (IllegalArgumentException e) { - logger.error("initSslContext failed, error: {}, e: {}", e.getMessage(), e); - throw new NetworkException( - "SSL context init failed, error info: " + e.getMessage(), - NetworkException.INIT_CONTEXT_FAILED); - } - } - - private SslContext initSMSslContext(ConfigOption configOption) throws NetworkException { - try { - // Get file, file existence is already checked when check config file. - // Init SslContext - return SMSslClientContextFactory.build( - configOption.getCryptoMaterialConfig().getCaInputStream(), - configOption.getCryptoMaterialConfig().getEnSSLCertInputStream(), - configOption.getCryptoMaterialConfig().getEnSSLPrivateKeyInputStream(), - configOption.getCryptoMaterialConfig().getSdkCertInputStream(), - configOption.getCryptoMaterialConfig().getSdkPrivateKeyInputStream()); - } catch (Exception e) { - if (configOption.getCryptoMaterialConfig().getCryptoProvider().equalsIgnoreCase(HSM)) { - logger.error( - "initSMSslContext failed, caCert:{}, sslCert: {}, sslKeyIndex: {}, enCert: {}, enSslKeyIndex: {}, error: {}, e: {}", - configOption.getCryptoMaterialConfig().getCaCertPath(), - configOption.getCryptoMaterialConfig().getSdkCertPath(), - configOption.getCryptoMaterialConfig().getSslKeyIndex(), - configOption.getCryptoMaterialConfig().getEnSSLCertPath(), - configOption.getCryptoMaterialConfig().getEnSslKeyIndex(), - e.getMessage(), - e); - } else { - logger.error( - "initSMSslContext failed, caCert:{}, sslCert: {}, sslKey: {}, enCert: {}, enSslKey: {}, error: {}, e: {}", - configOption.getCryptoMaterialConfig().getCaCertPath(), - configOption.getCryptoMaterialConfig().getSdkCertPath(), - configOption.getCryptoMaterialConfig().getSdkPrivateKeyPath(), - configOption.getCryptoMaterialConfig().getEnSSLCertPath(), - configOption.getCryptoMaterialConfig().getEnSSLPrivateKeyPath(), - e.getMessage(), - e); - } - throw new NetworkException( - "SSL context init failed, please make sure your cert and key files are properly configured. error info: " - + e.getMessage(), - e); - } - } - private void initNetty(ConfigOption configOption) throws NetworkException { workerGroup = new NioEventLoopGroup(); bootstrap.group(workerGroup); @@ -324,8 +243,8 @@ private void initNetty(ConfigOption configOption) throws NetworkException { } sslContext = (sslCryptoType == CryptoType.ECDSA_TYPE - ? initSslContext(configOption) - : initSMSslContext(configOption)); + ? sslContextInitializer.initSslContext(configOption) + : sslContextInitializer.initSMSslContext(configOption)); SslContext finalSslContext = sslContext; ChannelInitializer initializer = new ChannelInitializer() { diff --git a/sdk-core/src/main/java/org/fisco/bcos/sdk/network/SslContextInitializer.java b/sdk-core/src/main/java/org/fisco/bcos/sdk/network/SslContextInitializer.java new file mode 100644 index 000000000..56e34a47a --- /dev/null +++ b/sdk-core/src/main/java/org/fisco/bcos/sdk/network/SslContextInitializer.java @@ -0,0 +1,142 @@ +package org.fisco.bcos.sdk.network; + +import static org.fisco.bcos.sdk.model.CryptoProviderType.HSM; + +import io.netty.handler.ssl.SslContext; +import io.netty.handler.ssl.SslContextBuilder; +import io.netty.handler.ssl.SslProvider; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Method; +import java.security.Security; +import org.fisco.bcos.sdk.config.ConfigOption; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SslContextInitializer { + + private static Logger logger = LoggerFactory.getLogger(SslContextInitializer.class); + + private static boolean enableNettyOpenSSLProvider = false; + + static { + String property = System.getProperty("fisco.netty.enable.openssl.provider"); + if (property != null) { + enableNettyOpenSSLProvider = Boolean.valueOf(property); + logger.info("load `fisco.netty.enable.openssl.provider` value: {}", property); + } + } + + public SslContext initSslContext(ConfigOption configOption) throws NetworkException { + try { + Security.setProperty("jdk.disabled.namedCurves", ""); + System.setProperty("jdk.sunec.disableNative", "false"); + + // Get file, file existence is already checked when check config file. + // Init SslContext + logger.info(" build ECDSA ssl context with configured certificates "); + + SslProvider sslProvider = SslProvider.JDK; + if (enableNettyOpenSSLProvider) { + sslProvider = SslProvider.OPENSSL; + } + + logger.info("sslProvider: {}", sslProvider); + + SslContext sslCtx = + SslContextBuilder.forClient() + .trustManager(configOption.getCryptoMaterialConfig().getCaInputStream()) + .keyManager( + configOption.getCryptoMaterialConfig().getSdkCertInputStream(), + configOption + .getCryptoMaterialConfig() + .getSdkPrivateKeyInputStream()) + // .sslProvider(SslProvider.OPENSSL) + .sslProvider(sslProvider) + .build(); + return sslCtx; + } catch (IOException e) { + logger.error( + "initSslContext failed, caCert: {}, sslCert: {}, sslKey: {}, error: {}, e: {}", + configOption.getCryptoMaterialConfig().getCaCertPath(), + configOption.getCryptoMaterialConfig().getSdkCertPath(), + configOption.getCryptoMaterialConfig().getSdkPrivateKeyPath(), + e.getMessage(), + e); + throw new NetworkException( + "SSL context init failed, please make sure your cert and key files are properly configured. error info: " + + e.getMessage(), + NetworkException.INIT_CONTEXT_FAILED); + } catch (IllegalArgumentException e) { + logger.error("initSslContext failed, error: {}, e: {}", e.getMessage(), e); + throw new NetworkException( + "SSL context init failed, error info: " + e.getMessage(), + NetworkException.INIT_CONTEXT_FAILED); + } + } + + public SslContext initSMSslContext(ConfigOption configOption) throws NetworkException { + try { + // Get file, file existence is already checked when check config file. + InputStream caInputStream = configOption.getCryptoMaterialConfig().getCaInputStream(); + InputStream enSSLCertInputStream = + configOption.getCryptoMaterialConfig().getEnSSLCertInputStream(); + InputStream enSSLPrivateKeyInputStream = + configOption.getCryptoMaterialConfig().getEnSSLPrivateKeyInputStream(); + InputStream sdkCertInputStream = + configOption.getCryptoMaterialConfig().getSdkCertInputStream(); + InputStream sdkPrivateKeyInputStream = + configOption.getCryptoMaterialConfig().getSdkPrivateKeyInputStream(); + + String smContextFactoryClassName = "io.netty.handler.ssl.SMSslClientContextFactory"; + + Class smContextFactoryClass = Class.forName(smContextFactoryClassName); + logger.info("加载类`{}`成功", smContextFactoryClassName); + Method buildMethod = + smContextFactoryClass.getMethod( + "build", + InputStream.class, + InputStream.class, + InputStream.class, + InputStream.class, + InputStream.class); + SslContext sslContext = + (SslContext) + buildMethod.invoke( + null, + caInputStream, + enSSLCertInputStream, + enSSLPrivateKeyInputStream, + sdkCertInputStream, + sdkPrivateKeyInputStream); + + return sslContext; + } catch (Exception e) { + if (configOption.getCryptoMaterialConfig().getCryptoProvider().equalsIgnoreCase(HSM)) { + logger.error( + "initSMSslContext failed, caCert:{}, sslCert: {}, sslKeyIndex: {}, enCert: {}, enSslKeyIndex: {}, error: {}, e: {}", + configOption.getCryptoMaterialConfig().getCaCertPath(), + configOption.getCryptoMaterialConfig().getSdkCertPath(), + configOption.getCryptoMaterialConfig().getSslKeyIndex(), + configOption.getCryptoMaterialConfig().getEnSSLCertPath(), + configOption.getCryptoMaterialConfig().getEnSslKeyIndex(), + e.getMessage(), + e); + } else { + logger.error( + "initSMSslContext failed, caCert:{}, sslCert: {}, sslKey: {}, enCert: {}, enSslKey: {}, error: {}, e: {}", + configOption.getCryptoMaterialConfig().getCaCertPath(), + configOption.getCryptoMaterialConfig().getSdkCertPath(), + configOption.getCryptoMaterialConfig().getSdkPrivateKeyPath(), + configOption.getCryptoMaterialConfig().getEnSSLCertPath(), + configOption.getCryptoMaterialConfig().getEnSSLPrivateKeyPath(), + e.getMessage(), + e); + } + throw new NetworkException( + "SSL context init failed, please make sure your cert and key files are properly configured. error info: " + + e.getMessage(), + e); + } + } +} From bb06a4b6c2500ecde494c399fe4c821e9925fb35 Mon Sep 17 00:00:00 2001 From: Kyon <32325790+kyonRay@users.noreply.github.com> Date: Tue, 23 Apr 2024 09:55:31 +0800 Subject: [PATCH 2/3] (crypto,core): fix read relative path file bug. (#915) --- .../main/java/org/fisco/bcos/sdk/codegen/CodeGenUtils.java | 2 +- .../java/org/fisco/bcos/sdk/config/model/ConfigProperty.java | 1 - .../main/java/org/fisco/bcos/sdk/crypto/keystore/KeyTool.java | 4 +--- .../java/org/fisco/bcos/sdk/crypto/keystore/P12KeyStore.java | 1 - .../java/org/fisco/bcos/sdk/crypto/keystore/PEMKeyStore.java | 1 - 5 files changed, 2 insertions(+), 7 deletions(-) diff --git a/sdk-codegen/src/main/java/org/fisco/bcos/sdk/codegen/CodeGenUtils.java b/sdk-codegen/src/main/java/org/fisco/bcos/sdk/codegen/CodeGenUtils.java index 75b893fad..84e3dce20 100644 --- a/sdk-codegen/src/main/java/org/fisco/bcos/sdk/codegen/CodeGenUtils.java +++ b/sdk-codegen/src/main/java/org/fisco/bcos/sdk/codegen/CodeGenUtils.java @@ -77,7 +77,7 @@ public static List loadContractAbiDefinition(String abi) throws I public static byte[] readBytes(File file) throws CodeGenException, IOException { byte[] bytes = new byte[(int) file.length()]; FileInputStream fileInputStream = null; - if (!file.canRead() || file.getPath().contains("..")) { + if (!file.canRead()) { throw new CodeGenException( "file " + file + " is not readable or contains invalid characters"); } diff --git a/sdk-core/src/main/java/org/fisco/bcos/sdk/config/model/ConfigProperty.java b/sdk-core/src/main/java/org/fisco/bcos/sdk/config/model/ConfigProperty.java index 206d4a8bc..53f33f778 100644 --- a/sdk-core/src/main/java/org/fisco/bcos/sdk/config/model/ConfigProperty.java +++ b/sdk-core/src/main/java/org/fisco/bcos/sdk/config/model/ConfigProperty.java @@ -105,7 +105,6 @@ public static InputStream getConfigInputStream(String configFilePath) throws Con } InputStream inputStream = null; try { - // configFilePath = configFilePath.replace("..", ""); inputStream = new FileInputStream(configFilePath); if (inputStream != null) { return inputStream; diff --git a/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/keystore/KeyTool.java b/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/keystore/KeyTool.java index 9ee5bd375..1b22715d7 100644 --- a/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/keystore/KeyTool.java +++ b/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/keystore/KeyTool.java @@ -272,7 +272,6 @@ public static void storePublicKeyWithPem(PrivateKey privateKey, String privateKe public static void storePublicKeyWithPem(PublicKey publicKey, String privateKeyFilePath) throws IOException { String publicKeyPath = privateKeyFilePath + ".pub"; - publicKeyPath = publicKeyPath.replace("..", ""); try (PemWriter writer = new PemWriter(new FileWriter(publicKeyPath))) { writer.writeObject(new PemObject("PUBLIC KEY", publicKey.getEncoded())); writer.flush(); @@ -289,8 +288,7 @@ public static void storePublicKeyWithPem(PublicKey publicKey, String privateKeyF /** load information from the keyStoreFile */ protected void load() { try { - String safeFile = keyStoreFile.replace("..", ""); - InputStream keyStoreFileInputStream = new FileInputStream(safeFile); + InputStream keyStoreFileInputStream = new FileInputStream(keyStoreFile); this.load(keyStoreFileInputStream); } catch (FileNotFoundException | org.bouncycastle.util.encoders.DecoderException e) { String errorMessage = diff --git a/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/keystore/P12KeyStore.java b/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/keystore/P12KeyStore.java index 5d5c12b72..6b31978b5 100644 --- a/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/keystore/P12KeyStore.java +++ b/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/keystore/P12KeyStore.java @@ -150,7 +150,6 @@ public static void storeKeyPairWithP12Format( Certificate[] certChain = new Certificate[1]; certChain[0] = generateSelfSignedCertificate(keyPair, signatureAlgorithm); keyStore.setKeyEntry(NAME, privateKey, password.toCharArray(), certChain); - privateKeyFilePath = privateKeyFilePath.replace("..", ""); keyStore.store(new FileOutputStream(privateKeyFilePath), password.toCharArray()); // store the public key storePublicKeyWithPem(privateKey, privateKeyFilePath); diff --git a/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/keystore/PEMKeyStore.java b/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/keystore/PEMKeyStore.java index e1ffb831c..89c6c99b8 100644 --- a/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/keystore/PEMKeyStore.java +++ b/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/keystore/PEMKeyStore.java @@ -69,7 +69,6 @@ public static void storeKeyPairWithPemFormat( try { KeyPair keyPair = convertHexedStringToKeyPair(hexedPrivateKey, curveName); // save the private key - privateKeyFilePath = privateKeyFilePath.replace("..", ""); PemWriter writer = new PemWriter(new FileWriter(privateKeyFilePath)); BCECPrivateKey bcecPrivateKey = (BCECPrivateKey) (keyPair.getPrivate()); writer.writeObject(new PemObject(PRIVATE_KEY, bcecPrivateKey.getEncoded())); From b2d7b2f7cdb0f6f80d8c9baf603717079be07159 Mon Sep 17 00:00:00 2001 From: kyonRay Date: Thu, 25 Apr 2024 14:22:38 +0800 Subject: [PATCH 3/3] (changelog): add change log of 2.10.1. --- Changelog.md | 23 +++++++++++++++++++ .../bcos/sdk/utils/SystemInformation.java | 2 +- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index bbb8a6e5c..5f37ad1b9 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,26 @@ +## v2.10.1 + +(2024-04-25) + +请参考文档: + +* [英文版用户手册](https://fisco-bcos-documentation.readthedocs.io/en/latest/docs/sdk/java_sdk/index.html) +* [中文版用户手册](https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/sdk/java_sdk/index.html#) +* [中文版WIKI](https://github.com/FISCO-BCOS/java-sdk/wiki) + +新增: + +- 新增启动配置fisco.netty.enable.openssl.provider,置为true时使用openssl provider,置为false时使用JDK provider。 + +更新: + +- Java SDK不再强依赖tcnative,解决在部分环境下无法加载tcnative的问题。 +- 非国密环境下默认采用JDK的provider模式建立ssl连接。需要能提供给更高性能的openssl provider时,可以通过开关切换。 + +修复: + +- 修复部分场景不能配置相对路径的问题。 + ## v2.10.0 (2024-03-08) diff --git a/sdk-core/src/main/java/org/fisco/bcos/sdk/utils/SystemInformation.java b/sdk-core/src/main/java/org/fisco/bcos/sdk/utils/SystemInformation.java index 95370f016..56146d944 100644 --- a/sdk-core/src/main/java/org/fisco/bcos/sdk/utils/SystemInformation.java +++ b/sdk-core/src/main/java/org/fisco/bcos/sdk/utils/SystemInformation.java @@ -20,7 +20,7 @@ public class SystemInformation { // Note: must update the version if publish new-version - private static final String sdkVersion = "2.10.0"; + private static final String sdkVersion = "2.10.1"; public static final String connectionFaqIssueUrl = "https://github.com/FISCO-BCOS/java-sdk/issues/536"; public static final String connectionFaqDocUrl =