This is an automated email from the ASF dual-hosted git repository.

mpetrov pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git


The following commit(s) were added to refs/heads/master by this push:
     new 04bbcfec30f IGNITE-19975 Introduced abstract SSL Context Factory 
(#10841)
04bbcfec30f is described below

commit 04bbcfec30fc05c87f8aec0cba30365b4a7bcfc9
Author: Mikhail Petrov <[email protected]>
AuthorDate: Sat Jul 15 16:17:01 2023 +0300

    IGNITE-19975 Introduced abstract SSL Context Factory (#10841)
---
 .../jdbc/thin/JdbcThinConnectionSSLTest.java       |   2 +-
 .../ignite/ssl/AbstractSslContextFactory.java      | 199 +++++++++++++++++++++
 .../org/apache/ignite/ssl/SslContextFactory.java   | 198 +++-----------------
 3 files changed, 224 insertions(+), 175 deletions(-)

diff --git 
a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinConnectionSSLTest.java
 
b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinConnectionSSLTest.java
index a59e0e49a8c..ad422a3b93f 100644
--- 
a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinConnectionSSLTest.java
+++ 
b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinConnectionSSLTest.java
@@ -654,7 +654,7 @@ public class JdbcThinConnectionSSLTest extends 
JdbcThinAbstractSelfTest {
 
                     return null;
                 }
-            }, SQLException.class, "Unsupported keystore algorithm: INVALID");
+            }, SQLException.class, "Unsupported key algorithm: INVALID");
         }
         finally {
             stopAllGrids();
diff --git 
a/modules/core/src/main/java/org/apache/ignite/ssl/AbstractSslContextFactory.java
 
b/modules/core/src/main/java/org/apache/ignite/ssl/AbstractSslContextFactory.java
new file mode 100644
index 00000000000..77dedf84eba
--- /dev/null
+++ 
b/modules/core/src/main/java/org/apache/ignite/ssl/AbstractSslContextFactory.java
@@ -0,0 +1,199 @@
+/*
+ * 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.ignite.ssl;
+
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.util.concurrent.atomic.AtomicReference;
+import javax.cache.configuration.Factory;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLParameters;
+import javax.net.ssl.TrustManager;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.internal.util.typedef.internal.A;
+
+/**
+ * Represents abstract implementation of SSL Context Factory that caches the 
result of the first successful
+ * attempt to create an {@link SSLContext} and always returns it as a result 
of further invocations of the
+ * {@link AbstractSslContextFactory#create()}} method.
+ */
+public abstract class AbstractSslContextFactory implements Factory<SSLContext> 
{
+    /** */
+    private static final long serialVersionUID = 0L;
+
+    /** Default SSL protocol. */
+    public static final String DFLT_SSL_PROTOCOL = "TLS";
+
+    /** SSL protocol. */
+    protected String proto = DFLT_SSL_PROTOCOL;
+
+    /** Enabled cipher suites. */
+    protected String[] cipherSuites;
+
+    /** Enabled protocols. */
+    protected String[] protocols;
+
+    /** Cached instance of an {@link SSLContext}. */
+    protected final AtomicReference<SSLContext> sslCtx = new 
AtomicReference<>();
+
+    /**
+     * Gets protocol for secure transport.
+     *
+     * @return SSL protocol name.
+     */
+    public String getProtocol() {
+        return proto;
+    }
+
+    /**
+     * Sets protocol for secure transport. If not specified, {@link 
#DFLT_SSL_PROTOCOL} will be used.
+     *
+     * @param proto SSL protocol name.
+     */
+    public void setProtocol(String proto) {
+        A.notNull(proto, "proto");
+
+        this.proto = proto;
+    }
+
+    /**
+     * Sets enabled cipher suites.
+     *
+     * @param cipherSuites enabled cipher suites.
+     */
+    public void setCipherSuites(String... cipherSuites) {
+        this.cipherSuites = cipherSuites;
+    }
+
+    /**
+     * Gets enabled cipher suites.
+     *
+     * @return enabled cipher suites
+     */
+    public String[] getCipherSuites() {
+        return cipherSuites;
+    }
+
+    /**
+     * Gets enabled protocols.
+     *
+     * @return Enabled protocols.
+     */
+    public String[] getProtocols() {
+        return protocols;
+    }
+
+    /**
+     * Sets enabled protocols.
+     *
+     * @param protocols Enabled protocols.
+     */
+    public void setProtocols(String... protocols) {
+        this.protocols = protocols;
+    }
+
+    /**
+     * Creates SSL context based on factory settings.
+     *
+     * @return Initialized SSL context.
+     * @throws SSLException If SSL context could not be created.
+     */
+    private SSLContext createSslContext() throws SSLException {
+        checkParameters();
+
+        KeyManager[] keyMgrs = createKeyManagers();
+
+        TrustManager[] trustMgrs = createTrustManagers();
+
+        try {
+            SSLContext ctx = SSLContext.getInstance(proto);
+
+            if (cipherSuites != null || protocols != null) {
+                SSLParameters sslParameters = new SSLParameters();
+
+                if (cipherSuites != null)
+                    sslParameters.setCipherSuites(cipherSuites);
+
+                if (protocols != null)
+                    sslParameters.setProtocols(protocols);
+
+                ctx = new SSLContextWrapper(ctx, sslParameters);
+            }
+
+            ctx.init(keyMgrs, trustMgrs, null);
+
+            return ctx;
+        }
+        catch (NoSuchAlgorithmException e) {
+            throw new SSLException("Unsupported SSL protocol: " + proto, e);
+        }
+        catch (KeyManagementException e) {
+            throw new SSLException("Failed to initialized SSL context.", e);
+        }
+    }
+
+    /**
+     * @param param Value.
+     * @param name Name.
+     * @throws SSLException If {@code null}.
+     */
+    protected void checkNullParameter(Object param, String name) throws 
SSLException {
+        if (param == null)
+            throw new SSLException("Failed to initialize SSL context 
(parameter cannot be null): " + name);
+    }
+
+    /**
+     * Checks that all required parameters are set.
+     *
+     * @throws SSLException If any of required parameters is missing.
+     */
+    protected abstract void checkParameters() throws SSLException;
+
+    /**
+     * @return Created Key Managers.
+     * @throws SSLException If Key Managers could not be created.
+     */
+    protected abstract KeyManager[] createKeyManagers() throws SSLException;
+
+    /**
+     * @return Created Trust Managers.
+     * @throws SSLException If Trust Managers could not be created.
+     */
+    protected abstract TrustManager[] createTrustManagers() throws 
SSLException;
+
+    /** {@inheritDoc} */
+    @Override public SSLContext create() {
+        SSLContext ctx = sslCtx.get();
+
+        if (ctx == null) {
+            try {
+                ctx = createSslContext();
+
+                if (!sslCtx.compareAndSet(null, ctx))
+                    ctx = sslCtx.get();
+            }
+            catch (SSLException e) {
+                throw new IgniteException(e);
+            }
+        }
+
+        return ctx;
+    }
+}
diff --git 
a/modules/core/src/main/java/org/apache/ignite/ssl/SslContextFactory.java 
b/modules/core/src/main/java/org/apache/ignite/ssl/SslContextFactory.java
index e8bc0de8ee3..af7d140b01f 100644
--- a/modules/core/src/main/java/org/apache/ignite/ssl/SslContextFactory.java
+++ b/modules/core/src/main/java/org/apache/ignite/ssl/SslContextFactory.java
@@ -22,23 +22,18 @@ import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.security.GeneralSecurityException;
-import java.security.KeyManagementException;
 import java.security.KeyStore;
 import java.security.NoSuchAlgorithmException;
 import java.security.cert.CertificateException;
 import java.security.cert.X509Certificate;
 import java.util.Arrays;
-import java.util.concurrent.atomic.AtomicReference;
-import javax.cache.configuration.Factory;
 import javax.net.ssl.KeyManager;
 import javax.net.ssl.KeyManagerFactory;
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLException;
-import javax.net.ssl.SSLParameters;
 import javax.net.ssl.TrustManager;
 import javax.net.ssl.TrustManagerFactory;
 import javax.net.ssl.X509TrustManager;
-import org.apache.ignite.IgniteException;
 import org.apache.ignite.internal.util.typedef.internal.A;
 
 /**
@@ -56,7 +51,7 @@ import org.apache.ignite.internal.util.typedef.internal.A;
  *     // Rest of initialization.
  * </pre>
  */
-public class SslContextFactory implements Factory<SSLContext> {
+public class SslContextFactory extends AbstractSslContextFactory {
     /** */
     private static final long serialVersionUID = 0L;
 
@@ -64,24 +59,10 @@ public class SslContextFactory implements 
Factory<SSLContext> {
     public static final String DFLT_STORE_TYPE = 
System.getProperty("javax.net.ssl.keyStoreType", "JKS");
 
     /** Default SSL protocol. */
-    public static final String DFLT_SSL_PROTOCOL = "TLS";
-
-    /**
-     * Property name to specify default key/trust manager algorithm.
-     *
-     * @deprecated Use {@code "ssl.KeyManagerFactory.algorithm"} instead as 
per JSSE standard.
-     *
-     * Should be considered for deletion in 9.0.
-     */
-    @Deprecated
-    public static final String IGNITE_KEY_ALGORITHM_PROPERTY = 
"ssl.key.algorithm";
+    public static final String DFLT_SSL_PROTOCOL = 
AbstractSslContextFactory.DFLT_SSL_PROTOCOL;
 
     /** Default key manager / trust manager algorithm. Specifying different 
trust manager algorithm is not supported. */
-    public static final String DFLT_KEY_ALGORITHM = 
System.getProperty("ssl.KeyManagerFactory.algorithm",
-        System.getProperty(IGNITE_KEY_ALGORITHM_PROPERTY, "SunX509"));
-
-    /** SSL protocol. */
-    protected String proto = DFLT_SSL_PROTOCOL;
+    public static final String DFLT_KEY_ALGORITHM = 
System.getProperty("ssl.KeyManagerFactory.algorithm", "SunX509");
 
     /** Key manager algorithm. */
     protected String keyAlgorithm = DFLT_KEY_ALGORITHM;
@@ -107,15 +88,6 @@ public class SslContextFactory implements 
Factory<SSLContext> {
     /** Trust managers. */
     protected TrustManager[] trustMgrs;
 
-    /** Enabled cipher suites. */
-    protected String[] cipherSuites;
-
-    /** Enabled protocols. */
-    protected String[] protocols;
-
-    /** Cached instance of an {@link SSLContext}. */
-    protected final AtomicReference<SSLContext> sslCtx = new 
AtomicReference<>();
-
     /**
      * Gets key store type used for context creation.
      *
@@ -158,26 +130,6 @@ public class SslContextFactory implements 
Factory<SSLContext> {
         this.trustStoreType = trustStoreType;
     }
 
-    /**
-     * Gets protocol for secure transport.
-     *
-     * @return SSL protocol name.
-     */
-    public String getProtocol() {
-        return proto;
-    }
-
-    /**
-     * Sets protocol for secure transport. If not specified, {@link 
#DFLT_SSL_PROTOCOL} will be used.
-     *
-     * @param proto SSL protocol name.
-     */
-    public void setProtocol(String proto) {
-        A.notNull(proto, "proto");
-
-        this.proto = proto;
-    }
-
     /**
      * Gets algorithm that will be used to create a key manager. If not 
specified, {@link #DFLT_KEY_ALGORITHM}
      * will be used.
@@ -306,53 +258,8 @@ public class SslContextFactory implements 
Factory<SSLContext> {
         return new DisabledX509TrustManager();
     }
 
-    /**
-     * Sets enabled cipher suites.
-     *
-     * @param cipherSuites enabled cipher suites.
-     */
-    public void setCipherSuites(String... cipherSuites) {
-        this.cipherSuites = cipherSuites;
-    }
-
-    /**
-     * Gets enabled cipher suites.
-     *
-     * @return enabled cipher suites
-     */
-    public String[] getCipherSuites() {
-        return cipherSuites;
-    }
-
-    /**
-     * Gets enabled protocols.
-     *
-     * @return Enabled protocols.
-     */
-    public String[] getProtocols() {
-        return protocols;
-    }
-
-    /**
-     * Sets enabled protocols.
-     *
-     * @param protocols Enabled protocols.
-     */
-    public void setProtocols(String... protocols) {
-        this.protocols = protocols;
-    }
-
-    /**
-     * Creates SSL context based on factory settings.
-     *
-     * @return Initialized SSL context.
-     * @throws SSLException If SSL context could not be created.
-     */
-    private SSLContext createSslContext() throws SSLException {
-        checkParameters();
-
-        final KeyManager[] keyMgrs;
-
+    /** {@inheritDoc} */
+    @Override protected final KeyManager[] createKeyManagers() throws 
SSLException {
         try {
             KeyManagerFactory keyMgrFactory = 
KeyManagerFactory.getInstance(keyAlgorithm);
 
@@ -360,61 +267,37 @@ public class SslContextFactory implements 
Factory<SSLContext> {
 
             keyMgrFactory.init(keyStore, keyStorePwd);
 
-            keyMgrs = keyMgrFactory.getKeyManagers();
+            return keyMgrFactory.getKeyManagers();
         }
         catch (NoSuchAlgorithmException e) {
-            throw new SSLException("Unsupported keystore algorithm: " + 
keyAlgorithm, e);
+            throw new SSLException("Unsupported key algorithm: " + 
keyAlgorithm, e);
         }
         catch (GeneralSecurityException e) {
-            throw new SSLException("Failed to initialize key store (security 
exception occurred) [type=" +
+            throw new SSLException("Failed to initialize Key Manager (security 
exception occurred) [type=" +
                 keyStoreType + ", keyStorePath=" + keyStoreFilePath + ']', e);
         }
+    }
 
-        TrustManager[] trustMgrs = this.trustMgrs;
-
-        if (trustMgrs == null) {
-            try {
-                TrustManagerFactory trustMgrFactory = 
TrustManagerFactory.getInstance(keyAlgorithm);
-
-                KeyStore trustStore = loadKeyStore(trustStoreType, 
trustStoreFilePath, trustStorePwd);
-
-                trustMgrFactory.init(trustStore);
+    /** {@inheritDoc} */
+    @Override protected final TrustManager[] createTrustManagers() throws 
SSLException {
+        if (trustMgrs != null)
+            return trustMgrs;
 
-                trustMgrs = trustMgrFactory.getTrustManagers();
-            }
-            catch (NoSuchAlgorithmException e) {
-                throw new SSLException("Unsupported keystore algorithm: " + 
keyAlgorithm, e);
-            }
-            catch (GeneralSecurityException e) {
-                throw new SSLException("Failed to initialize key store 
(security exception occurred) [type=" +
-                    keyStoreType + ", keyStorePath=" + keyStoreFilePath + ']', 
e);
-            }
-        }
+        KeyStore trustStore = loadKeyStore(trustStoreType, trustStoreFilePath, 
trustStorePwd);
 
         try {
-            SSLContext ctx = SSLContext.getInstance(proto);
-
-            if (cipherSuites != null || protocols != null) {
-                SSLParameters sslParameters = new SSLParameters();
-
-                if (cipherSuites != null)
-                    sslParameters.setCipherSuites(cipherSuites);
+            TrustManagerFactory trustMgrFactory = 
TrustManagerFactory.getInstance(keyAlgorithm);
 
-                if (protocols != null)
-                    sslParameters.setProtocols(protocols);
-
-                ctx = new SSLContextWrapper(ctx, sslParameters);
-            }
+            trustMgrFactory.init(trustStore);
 
-            ctx.init(keyMgrs, trustMgrs, null);
-
-            return ctx;
+            return trustMgrFactory.getTrustManagers();
         }
         catch (NoSuchAlgorithmException e) {
-            throw new SSLException("Unsupported SSL protocol: " + proto, e);
+            throw new SSLException("Unsupported key algorithm: " + 
keyAlgorithm, e);
         }
-        catch (KeyManagementException e) {
-            throw new SSLException("Failed to initialized SSL context.", e);
+        catch (GeneralSecurityException e) {
+            throw new SSLException("Failed to initialize Trust Manager 
(security exception occurred) [type=" +
+                trustStoreType + ", trustStorePath=" + trustStoreFilePath + 
']', e);
         }
     }
 
@@ -438,12 +321,8 @@ public class SslContextFactory implements 
Factory<SSLContext> {
         return buf.toString();
     }
 
-    /**
-     * Checks that all required parameters are set.
-     *
-     * @throws SSLException If any of required parameters is missing.
-     */
-    protected void checkParameters() throws SSLException {
+    /** {@inheritDoc} */
+    @Override protected void checkParameters() throws SSLException {
         assert keyStoreType != null;
         assert proto != null;
 
@@ -459,16 +338,6 @@ public class SslContextFactory implements 
Factory<SSLContext> {
         }
     }
 
-    /**
-     * @param param Value.
-     * @param name Name.
-     * @throws SSLException If {@code null}.
-     */
-    protected void checkNullParameter(Object param, String name) throws 
SSLException {
-        if (param == null)
-            throw new SSLException("Failed to initialize SSL context 
(parameter cannot be null): " + name);
-    }
-
     /**
      * By default, this method simply opens a raw file input stream. 
Subclasses may override this method
      * if some specific location should be handled (this may be a case for 
Android users).
@@ -504,7 +373,7 @@ public class SslContextFactory implements 
Factory<SSLContext> {
         }
         catch (GeneralSecurityException e) {
             throw new SSLException("Failed to initialize key store (security 
exception occurred) [type=" +
-                keyStoreType + ", keyStorePath=" + keyStoreFilePath + ']', e);
+                keyStoreType + ", keyStorePath=" + storeFilePath + ']', e);
         }
         catch (FileNotFoundException e) {
             throw new SSLException("Failed to initialize key store (key store 
file was not found): [path=" +
@@ -544,23 +413,4 @@ public class SslContextFactory implements 
Factory<SSLContext> {
             return CERTS;
         }
     }
-
-    /** {@inheritDoc} */
-    @Override public SSLContext create() {
-        SSLContext ctx = sslCtx.get();
-
-        if (ctx == null) {
-            try {
-                ctx = createSslContext();
-
-                if (!sslCtx.compareAndSet(null, ctx))
-                    ctx = sslCtx.get();
-            }
-            catch (SSLException e) {
-                throw new IgniteException(e);
-            }
-        }
-
-        return ctx;
-    }
 }

Reply via email to