Allow to config no-password truststore (#13424)

* Allow to config no-password truststore
diff --git a/conf/broker.conf b/conf/broker.conf
index e46f0ca..54432ec 100644
--- a/conf/broker.conf
+++ b/conf/broker.conf
@@ -622,7 +622,7 @@
 # TLS TrustStore path in broker
 tlsTrustStore=
 
-# TLS TrustStore password in broker
+# TLS TrustStore password in broker, default value is empty password
 tlsTrustStorePassword=
 
 # Whether internal client use KeyStore type to authenticate with Pulsar brokers
diff --git a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/ServiceConfiguration.java b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/ServiceConfiguration.java
index ed89818..9ba3f52 100644
--- a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/ServiceConfiguration.java
+++ b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/ServiceConfiguration.java
@@ -2389,7 +2389,7 @@
 
     @FieldContext(
             category = CATEGORY_KEYSTORE_TLS,
-            doc = "TLS TrustStore password for broker"
+            doc = "TLS TrustStore password for broker, null means empty password."
     )
     private String tlsTrustStorePassword = null;
 
diff --git a/pulsar-broker/src/test/java/org/apache/pulsar/client/impl/KeyStoreTlsTest.java b/pulsar-broker/src/test/java/org/apache/pulsar/client/impl/KeyStoreTlsTest.java
index 8974962..2e839b9 100644
--- a/pulsar-broker/src/test/java/org/apache/pulsar/client/impl/KeyStoreTlsTest.java
+++ b/pulsar-broker/src/test/java/org/apache/pulsar/client/impl/KeyStoreTlsTest.java
@@ -43,6 +43,12 @@
     protected final String CLIENT_TRUSTSTORE_PW = "111111";
     protected final String KEYSTORE_TYPE = "JKS";
 
+    protected final String BROKER_TRUSTSTORE_FILE_NPD_PATH =
+            "./src/test/resources/authentication/keystoretls/pulsar_server_trust_npd.jks";
+
+    protected final String CLIENT_TRUSTSTORE_FILE_NPD_PATH =
+            "./src/test/resources/authentication/keystoretls/pulsar_client_trust_npd.jks";
+
     public static final Provider BC_PROVIDER = getProvider();
 
     @Test(timeOut = 300000)
@@ -78,4 +84,38 @@
 
         SSLContextValidatorEngine.validate(clientSSLContext::createSSLEngine, serverSSLContext::createSSLEngine);
     }
+
+    @Test(timeOut = 300000)
+    public void testValidateKeyStoreNoPwd() throws Exception {
+        KeyStoreSSLContext serverSSLContext = new KeyStoreSSLContext(KeyStoreSSLContext.Mode.SERVER,
+                null,
+                KEYSTORE_TYPE,
+                BROKER_KEYSTORE_FILE_PATH,
+                BROKER_KEYSTORE_PW,
+                false,
+                KEYSTORE_TYPE,
+                BROKER_TRUSTSTORE_FILE_NPD_PATH,
+                null,
+                true,
+                null,
+                null);
+        serverSSLContext.createSSLContext();
+
+        KeyStoreSSLContext clientSSLContext = new KeyStoreSSLContext(KeyStoreSSLContext.Mode.CLIENT,
+                null,
+                KEYSTORE_TYPE,
+                CLIENT_KEYSTORE_FILE_PATH,
+                CLIENT_KEYSTORE_PW,
+                false,
+                KEYSTORE_TYPE,
+                CLIENT_TRUSTSTORE_FILE_NPD_PATH,
+                null,
+                false,
+                null,
+                // set client's protocol to TLSv1.2 since SSLContextValidatorEngine.validate doesn't handle TLSv1.3
+                Collections.singleton("TLSv1.2"));
+        clientSSLContext.createSSLContext();
+
+        SSLContextValidatorEngine.validate(clientSSLContext::createSSLEngine, serverSSLContext::createSSLEngine);
+    }
 }
diff --git a/pulsar-broker/src/test/resources/authentication/keystoretls/pulsar_client_trust_npd.jks b/pulsar-broker/src/test/resources/authentication/keystoretls/pulsar_client_trust_npd.jks
new file mode 100644
index 0000000..48b299c
--- /dev/null
+++ b/pulsar-broker/src/test/resources/authentication/keystoretls/pulsar_client_trust_npd.jks
Binary files differ
diff --git a/pulsar-broker/src/test/resources/authentication/keystoretls/pulsar_server_trust_npd.jks b/pulsar-broker/src/test/resources/authentication/keystoretls/pulsar_server_trust_npd.jks
new file mode 100644
index 0000000..9697ecd
--- /dev/null
+++ b/pulsar-broker/src/test/resources/authentication/keystoretls/pulsar_server_trust_npd.jks
Binary files differ
diff --git a/pulsar-common/src/main/java/org/apache/pulsar/common/util/keystoretls/KeyStoreSSLContext.java b/pulsar-common/src/main/java/org/apache/pulsar/common/util/keystoretls/KeyStoreSSLContext.java
index 987a32b..f48872f 100644
--- a/pulsar-common/src/main/java/org/apache/pulsar/common/util/keystoretls/KeyStoreSSLContext.java
+++ b/pulsar-common/src/main/java/org/apache/pulsar/common/util/keystoretls/KeyStoreSSLContext.java
@@ -105,7 +105,11 @@
                 ? DEFAULT_KEYSTORE_TYPE
                 : trustStoreTypeString;
         this.trustStorePath = trustStorePath;
-        this.trustStorePassword = trustStorePassword;
+        if (trustStorePassword == null) {
+            this.trustStorePassword = "";
+        } else {
+            this.trustStorePassword = trustStorePassword;
+        }
         this.needClientAuth = requireTrustedClientCertOnConnect;
 
         if (protocols != null && protocols.size() > 0) {
diff --git a/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ProxyConfiguration.java b/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ProxyConfiguration.java
index 41ec92f..155fcf5 100644
--- a/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ProxyConfiguration.java
+++ b/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ProxyConfiguration.java
@@ -406,7 +406,7 @@
 
     @FieldContext(
             category = CATEGORY_KEYSTORE_TLS,
-            doc = "TLS TrustStore password for proxy"
+            doc = "TLS TrustStore password for proxy, null means empty password."
     )
     private String tlsTrustStorePassword = null;