lhotari commented on a change in pull request #13740:
URL: https://github.com/apache/pulsar/pull/13740#discussion_r789411080



##########
File path: 
pulsar-broker/src/main/java/org/apache/pulsar/broker/web/WebService.java
##########
@@ -109,17 +108,24 @@ public WebService(PulsarService pulsar) throws 
PulsarServerException {
                             config.getTlsTrustStore(),
                             config.getTlsTrustStorePassword(),
                             config.isTlsRequireTrustedClientCertOnConnect(),
-                            config.getWebServiceTlsCiphers(),
-                            config.getWebServiceTlsProtocols(),
+                            config.getWebServiceTlsCiphers() != null ? 
config.getWebServiceTlsCiphers() :
+                                    config.getTlsCiphers(),
+                            config.getWebServiceTlsProtocols() != null ? 
config.getWebServiceTlsProtocols() :
+                                    config.getTlsCiphers(),

Review comment:
       typo
   ```suggestion
                                       config.getTlsProtocols(),
   ```

##########
File path: 
pulsar-broker/src/main/java/org/apache/pulsar/broker/web/WebService.java
##########
@@ -109,17 +108,24 @@ public WebService(PulsarService pulsar) throws 
PulsarServerException {
                             config.getTlsTrustStore(),
                             config.getTlsTrustStorePassword(),
                             config.isTlsRequireTrustedClientCertOnConnect(),
-                            config.getWebServiceTlsCiphers(),
-                            config.getWebServiceTlsProtocols(),
+                            config.getWebServiceTlsCiphers() != null ? 
config.getWebServiceTlsCiphers() :
+                                    config.getTlsCiphers(),
+                            config.getWebServiceTlsProtocols() != null ? 
config.getWebServiceTlsProtocols() :
+                                    config.getTlsCiphers(),
                             config.getTlsCertRefreshCheckDurationSec()
                     );
                 } else {
-                    sslCtxFactory = SecurityUtility.createSslContextFactory(
+                    sslCtxFactory = 
JettySslContextFactory.createServerSslContext(
+                            config.getTlsProvider(),
                             config.isTlsAllowInsecureConnection(),
                             config.getTlsTrustCertsFilePath(),
                             config.getTlsCertificateFilePath(),
                             config.getTlsKeyFilePath(),
-                            config.isTlsRequireTrustedClientCertOnConnect(), 
true,
+                            config.isTlsRequireTrustedClientCertOnConnect(),
+                            config.getWebServiceTlsCiphers() != null ? 
config.getWebServiceTlsCiphers() :
+                                    config.getTlsCiphers(),
+                            config.getWebServiceTlsProtocols() != null ? 
config.getWebServiceTlsProtocols() :
+                                    config.getTlsCiphers(),

Review comment:
       ```suggestion
                                       config.getTlsProtocols(),
   ```

##########
File path: 
pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/WebServer.java
##########
@@ -108,18 +107,24 @@ public WebServer(ProxyConfiguration config, 
AuthenticationService authentication
                             config.getTlsTrustStore(),
                             config.getTlsTrustStorePassword(),
                             config.isTlsRequireTrustedClientCertOnConnect(),
-                            config.getWebServiceTlsCiphers(),
-                            config.getWebServiceTlsProtocols(),
+                            config.getWebServiceTlsCiphers() != null ? 
config.getWebServiceTlsCiphers() :
+                                    config.getTlsCiphers(),
+                            config.getWebServiceTlsProtocols() != null ? 
config.getWebServiceTlsProtocols() :
+                                    config.getTlsCiphers(),
                             config.getTlsCertRefreshCheckDurationSec()
                     );
                 } else {
-                    sslCtxFactory = SecurityUtility.createSslContextFactory(
+                    sslCtxFactory = 
JettySslContextFactory.createServerSslContext(
+                            config.getTlsProvider(),
                             config.isTlsAllowInsecureConnection(),
                             config.getTlsTrustCertsFilePath(),
                             config.getTlsCertificateFilePath(),
                             config.getTlsKeyFilePath(),
                             config.isTlsRequireTrustedClientCertOnConnect(),
-                            true,
+                            config.getWebServiceTlsCiphers() != null ? 
config.getWebServiceTlsCiphers() :
+                                    config.getTlsCiphers(),
+                            config.getWebServiceTlsProtocols() != null ? 
config.getWebServiceTlsProtocols() :
+                                    config.getTlsCiphers(),

Review comment:
       ```suggestion
                                       config.getTlsProtocols(),
   ```

##########
File path: 
pulsar-common/src/main/java/org/apache/pulsar/common/util/SecurityUtility.java
##########
@@ -300,27 +310,65 @@ public static SslContext 
createNettySslContextForServer(boolean allowInsecureCon
     }
 
     public static SSLContext createSslContext(boolean allowInsecureConnection, 
Certificate[] trustCertficates,
-            Certificate[] certificates, PrivateKey privateKey) throws 
GeneralSecurityException {
+                                              Certificate[] certificates, 
PrivateKey privateKey)
+            throws GeneralSecurityException {
+        return createSslContext(allowInsecureConnection, trustCertficates, 
certificates, privateKey, null);
+    }
+
+    public static SSLContext createSslContext(boolean allowInsecureConnection, 
Certificate[] trustCertficates,
+                                              Certificate[] certificates, 
PrivateKey privateKey, String providerName)
+            throws GeneralSecurityException {
         KeyStoreHolder ksh = new KeyStoreHolder();
         TrustManager[] trustManagers = null;
         KeyManager[] keyManagers = null;
+        Provider provider = null;
+        if (providerName != null && !providerName.equals("")) {
+            if (providerName.equalsIgnoreCase(CONSCRYPT_PROVIDER_NAME)) {
+                provider = CONSCRYPT_PROVIDER;
+            } else {
+                provider = Security.getProvider(providerName);
+                if (provider == null) {
+                    log.warn("Cannot to get {} security provider, fallback to 
using JDK default security provider",
+                            providerName);
+                    provider = SSLContext.getDefault().getProvider();
+                }
+            }
+        }
 
-        trustManagers = setupTrustCerts(ksh, allowInsecureConnection, 
trustCertficates, CONSCRYPT_PROVIDER);
-        keyManagers = setupKeyManager(ksh, privateKey, certificates);
+        trustManagers = setupTrustCerts(ksh, allowInsecureConnection, 
trustCertficates, provider);
+        keyManagers = setupKeyManager(ksh, privateKey, certificates, provider);
 
-        SSLContext sslCtx = CONSCRYPT_PROVIDER != null ? 
SSLContext.getInstance("TLS", CONSCRYPT_PROVIDER)
+        SSLContext sslCtx = provider != null ? SSLContext.getInstance("TLS", 
provider)
                 : SSLContext.getInstance("TLS");
         sslCtx.init(keyManagers, trustManagers, new SecureRandom());
-        sslCtx.getDefaultSSLParameters();
         return sslCtx;
     }
 
-    private static KeyManager[] setupKeyManager(KeyStoreHolder ksh, PrivateKey 
privateKey, Certificate[] certificates)
+    private static KeyManager[] setupKeyManager(KeyStoreHolder ksh, PrivateKey 
privateKey, Certificate[] certificates,
+                                                Provider provider)
             throws KeyStoreException, NoSuchAlgorithmException, 
UnrecoverableKeyException {
         KeyManager[] keyManagers = null;
+        String algorithm = KeyManagerFactory.getDefaultAlgorithm();
+
         if (certificates != null && privateKey != null) {
             ksh.setPrivateKey("private", privateKey, certificates);
-            KeyManagerFactory kmf = 
KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
+            KeyManagerFactory kmf = null;
+
+            try {
+                kmf = provider != null ? 
KeyManagerFactory.getInstance(algorithm, provider) :
+                        KeyManagerFactory.getInstance(algorithm);
+            } catch (NoSuchAlgorithmException e) {
+                if (provider != null) {
+                    log.warn(
+                            "Unable to get KeyManagerFactory instance for 
algorithm [{}] on provider [{}], using JDK "
+                                    + "default",
+                            algorithm, provider.getName());
+                    kmf = KeyManagerFactory.getInstance(algorithm);
+                } else {
+                    throw e;
+                }
+            }
+

Review comment:
       It is possible that the provider wasn't passed here intentionally. There 
were some quirks in switching to use Conscrypt in #10541. This might have been 
one of them. If you come across test failures, the changes in setupKeyManager 
might be causing them.

##########
File path: 
pulsar-common/src/main/java/org/apache/pulsar/common/util/SecurityUtility.java
##########
@@ -300,27 +310,65 @@ public static SslContext 
createNettySslContextForServer(boolean allowInsecureCon
     }
 
     public static SSLContext createSslContext(boolean allowInsecureConnection, 
Certificate[] trustCertficates,
-            Certificate[] certificates, PrivateKey privateKey) throws 
GeneralSecurityException {
+                                              Certificate[] certificates, 
PrivateKey privateKey)
+            throws GeneralSecurityException {
+        return createSslContext(allowInsecureConnection, trustCertficates, 
certificates, privateKey, null);
+    }
+
+    public static SSLContext createSslContext(boolean allowInsecureConnection, 
Certificate[] trustCertficates,
+                                              Certificate[] certificates, 
PrivateKey privateKey, String providerName)
+            throws GeneralSecurityException {
         KeyStoreHolder ksh = new KeyStoreHolder();
         TrustManager[] trustManagers = null;
         KeyManager[] keyManagers = null;
+        Provider provider = null;
+        if (providerName != null && !providerName.equals("")) {
+            if (providerName.equalsIgnoreCase(CONSCRYPT_PROVIDER_NAME)) {

Review comment:
       ```suggestion
               if (CONSCRYPT_PROVIDER != null && 
providerName.equalsIgnoreCase(CONSCRYPT_PROVIDER_NAME)) {
   ```

##########
File path: 
pulsar-common/src/main/java/org/apache/pulsar/common/util/jetty/JettySslContextFactory.java
##########
@@ -0,0 +1,106 @@
+/**
+ * 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.pulsar.common.util.jetty;
+
+import java.util.Set;
+import javax.net.ssl.SSLContext;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.pulsar.common.util.DefaultSslContextBuilder;
+import org.apache.pulsar.common.util.SslContextAutoRefreshBuilder;
+import org.apache.pulsar.common.util.keystoretls.NetSslContextBuilder;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+
+@Slf4j
+public class JettySslContextFactory {
+    public static SslContextFactory.Server 
createServerSslContextWithKeystore(String sslProviderString,
+                                                                              
String keyStoreTypeString,
+                                                                              
String keyStore,
+                                                                              
String keyStorePassword,
+                                                                              
boolean allowInsecureConnection,
+                                                                              
String trustStoreTypeString,
+                                                                              
String trustStore,
+                                                                              
String trustStorePassword,
+                                                                              
boolean requireTrustedClientCertOnConnect,
+                                                                              
Set<String> ciphers,
+                                                                              
Set<String> protocols,
+                                                                              
long certRefreshInSec) {
+        NetSslContextBuilder sslCtxRefresher = new NetSslContextBuilder(
+                sslProviderString,
+                keyStoreTypeString,
+                keyStore,
+                keyStorePassword,
+                allowInsecureConnection,
+                trustStoreTypeString,
+                trustStore,
+                trustStorePassword,
+                requireTrustedClientCertOnConnect,
+                certRefreshInSec);
+
+        return new Server(sslProviderString, sslCtxRefresher, 
requireTrustedClientCertOnConnect, ciphers, protocols);
+    }
+
+    public static SslContextFactory createServerSslContext(String 
sslProviderString, boolean tlsAllowInsecureConnection,
+                                                           String 
tlsTrustCertsFilePath,
+                                                           String 
tlsCertificateFilePath,
+                                                           String 
tlsKeyFilePath,
+                                                           boolean 
tlsRequireTrustedClientCertOnConnect,
+                                                           Set<String> ciphers,
+                                                           Set<String> 
protocols,
+                                                           long 
certRefreshInSec) {
+        DefaultSslContextBuilder sslCtxRefresher =
+                new DefaultSslContextBuilder(tlsAllowInsecureConnection, 
tlsTrustCertsFilePath, tlsCertificateFilePath,
+                        tlsKeyFilePath, tlsRequireTrustedClientCertOnConnect, 
certRefreshInSec, sslProviderString);
+
+        return new Server(sslProviderString, sslCtxRefresher, 
tlsRequireTrustedClientCertOnConnect, ciphers, protocols);
+    }
+
+    private static class Server extends SslContextFactory.Server {
+        private final SslContextAutoRefreshBuilder<SSLContext> sslCtxRefresher;
+
+        public Server(String sslProviderString, 
SslContextAutoRefreshBuilder<SSLContext> sslCtxRefresher,
+                      boolean requireTrustedClientCertOnConnect, Set<String> 
ciphers, Set<String> protocols) {
+            super();
+            this.sslCtxRefresher = sslCtxRefresher;
+
+            if (ciphers != null && ciphers.size() > 0) {
+                this.setIncludeCipherSuites(ciphers.toArray(new String[0]));
+            }
+
+            if (protocols != null && protocols.size() > 0) {
+                this.setIncludeProtocols(protocols.toArray(new String[0]));
+            }
+
+            if (sslProviderString != null && !sslProviderString.equals("")) {
+                setProvider(sslProviderString);
+            }
+
+            if (requireTrustedClientCertOnConnect) {
+                this.setNeedClientAuth(true);
+            } else {
+                this.setWantClientAuth(true);
+            }
+            this.setTrustAll(true);

Review comment:
       I can see that the original code had a possible security issue. I would 
assume that this would be the right thing to do here:
   ```suggestion
               if (requireTrustedClientCertOnConnect) {
                   this.setNeedClientAuth(true);
                   this.setTrustAll(false);
               } else {
                   this.setWantClientAuth(true);
                   this.setTrustAll(true);
               }
   ```

##########
File path: 
pulsar-common/src/main/java/org/apache/pulsar/common/util/SecurityUtility.java
##########
@@ -300,27 +310,65 @@ public static SslContext 
createNettySslContextForServer(boolean allowInsecureCon
     }
 
     public static SSLContext createSslContext(boolean allowInsecureConnection, 
Certificate[] trustCertficates,
-            Certificate[] certificates, PrivateKey privateKey) throws 
GeneralSecurityException {
+                                              Certificate[] certificates, 
PrivateKey privateKey)
+            throws GeneralSecurityException {
+        return createSslContext(allowInsecureConnection, trustCertficates, 
certificates, privateKey, null);
+    }
+
+    public static SSLContext createSslContext(boolean allowInsecureConnection, 
Certificate[] trustCertficates,
+                                              Certificate[] certificates, 
PrivateKey privateKey, String providerName)
+            throws GeneralSecurityException {
         KeyStoreHolder ksh = new KeyStoreHolder();
         TrustManager[] trustManagers = null;
         KeyManager[] keyManagers = null;
+        Provider provider = null;
+        if (providerName != null && !providerName.equals("")) {
+            if (providerName.equalsIgnoreCase(CONSCRYPT_PROVIDER_NAME)) {
+                provider = CONSCRYPT_PROVIDER;
+            } else {
+                provider = Security.getProvider(providerName);
+                if (provider == null) {
+                    log.warn("Cannot to get {} security provider, fallback to 
using JDK default security provider",
+                            providerName);
+                    provider = SSLContext.getDefault().getProvider();
+                }
+            }

Review comment:
       extract provider resolving logic to private static helper method 
`resolveProvider(String providerName)`, improves readability

##########
File path: 
pulsar-common/src/main/java/org/apache/pulsar/common/util/SecurityUtility.java
##########
@@ -348,9 +410,10 @@ public static SSLContext createSslContext(boolean 
allowInsecureConnection, Certi
             }
 
             trustManagers = tmf.getTrustManagers();
-
-            for (TrustManager trustManager : trustManagers) {
-                processConscryptTrustManager(trustManager);
+            if (securityProvider != null && 
securityProvider.getName().equalsIgnoreCase(CONSCRYPT_PROVIDER_NAME)) {

Review comment:
       there's no need to add this check. `processConscryptTrustManager` 
contains the sufficient logic. A possible extra for-loop isn't a problem. 

##########
File path: 
pulsar-common/src/main/java/org/apache/pulsar/common/util/jetty/package-info.java
##########
@@ -0,0 +1,19 @@
+/**
+ * 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.pulsar.common.util.jetty;

Review comment:
       Please create this in `pulsar-broker-common` module instead of 
`pulsar-common` module. 
   Switch to use package name `org.apache.pulsar.jetty.tls` since these classes 
are about TLS support in Jetty.

##########
File path: 
pulsar-common/src/main/java/org/apache/pulsar/common/util/jetty/JettySslContextFactory.java
##########
@@ -0,0 +1,106 @@
+/**
+ * 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.pulsar.common.util.jetty;
+
+import java.util.Set;
+import javax.net.ssl.SSLContext;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.pulsar.common.util.DefaultSslContextBuilder;
+import org.apache.pulsar.common.util.SslContextAutoRefreshBuilder;
+import org.apache.pulsar.common.util.keystoretls.NetSslContextBuilder;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+
+@Slf4j
+public class JettySslContextFactory {

Review comment:
       Please create this in `pulsar-broker-common` module instead of 
`pulsar-common` module. 
   Switch to use package name `org.apache.pulsar.jetty.tls` since these classes 
are about TLS support in Jetty.
   
   We should remove any references to Jetty modules in `pulsar-common` since 
that is shared module also used on the client. Jetty shouldn't be pulled in to 
the client dependencies.
   

##########
File path: 
pulsar-common/src/test/java/org/apache/pulsar/common/util/jetty/JettySslContextFactoryWithKeyStoreTest.java
##########
@@ -16,9 +16,21 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.pulsar.common.util.keystoretls;
+
+package org.apache.pulsar.common.util.jetty;

Review comment:
       Please move this to `pulsar-broker-common` module.
   Switch to use package name `org.apache.pulsar.jetty.tls`.

##########
File path: 
pulsar-common/src/main/java/org/apache/pulsar/common/util/keystoretls/KeyStoreSSLContext.java
##########
@@ -38,6 +38,7 @@
 import lombok.Getter;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.pulsar.common.util.SecurityUtility;
+import org.apache.pulsar.common.util.jetty.JettySslContextFactory;

Review comment:
       Drop references to the Jetty support since pulsar-common is also used on 
the client. no need to have a deprecation cycle since this is not a public API 
for Pulsar. 

##########
File path: 
pulsar-common/src/test/java/org/apache/pulsar/common/util/jetty/JettySslContextFactoryTest.java
##########
@@ -0,0 +1,174 @@
+/**
+ * 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.pulsar.common.util.jetty;
+
+import com.google.common.io.Resources;
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLHandshakeException;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.config.RegistryBuilder;
+import org.apache.http.conn.socket.ConnectionSocketFactory;
+import org.apache.http.conn.ssl.NoopHostnameVerifier;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
+import org.apache.pulsar.common.util.SecurityUtility;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+import org.testng.annotations.Test;
+
+@Slf4j
+public class JettySslContextFactoryTest {

Review comment:
       Please create this in `pulsar-broker-common` module instead of 
`pulsar-common` module. 
   Switch to use package name `org.apache.pulsar.jetty.tls` since these classes 
are about TLS support in Jetty.

##########
File path: 
pulsar-common/src/main/java/org/apache/pulsar/common/util/keystoretls/KeyStoreSSLContext.java
##########
@@ -339,7 +340,10 @@ public static SSLContext createClientSslContext(String 
keyStoreTypeString,
         return keyStoreSSLContext.createSSLContext();
     }
 
-    // for web server. autoRefresh is default true.
+    /**
+     * for web server. autoRefresh is default true.
+     * @deprecated Use 
JettySslContextFactory.createServerSslContextWithKeystore instead.
+     */
     public static SslContextFactory.Server createSslContextFactory(String 
sslProviderString,
                                                                    String 
keyStoreTypeString,
                                                                    String 
keyStore,

Review comment:
       Please remove this method completely. It was there to be used in Jetty.
   
   Drop references to the Jetty support since pulsar-common is also used on the 
client. no need to have a deprecation cycle since this is not a public API for 
Pulsar end users.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to