You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by il...@apache.org on 2020/03/11 09:30:38 UTC

[ignite] branch master updated: IGNITE-12753 Cache SSLContext in SslContextFactory - Fixes #7497.

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

ilyak 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 3094ade  IGNITE-12753 Cache SSLContext in SslContextFactory - Fixes #7497.
3094ade is described below

commit 3094ade035fdb65f5ebee764314594caf535635f
Author: Denis Mekhanikov <dm...@gmail.com>
AuthorDate: Wed Mar 11 12:23:58 2020 +0300

    IGNITE-12753 Cache SSLContext in SslContextFactory - Fixes #7497.
    
    Signed-off-by: Ilya Kasnacheev <il...@gmail.com>
---
 .../JdbcThinConnectionAdditionalSecurityTest.java  |   2 +-
 .../jdbc/thin/JdbcThinConnectionSSLTest.java       |   2 +-
 modules/clients/src/test/keystore/README.txt       |  11 +
 modules/clients/src/test/keystore/ca/node01.jks    | Bin 3719 -> 0 bytes
 modules/clients/src/test/keystore/ca/node02.jks    | Bin 4599 -> 0 bytes
 modules/clients/src/test/keystore/ca/node02old.jks | Bin 4598 -> 0 bytes
 modules/clients/src/test/keystore/ca/node03.jks    | Bin 3753 -> 0 bytes
 .../clients/src/test/keystore/ca/oneca-index.txt   |   3 +
 modules/clients/src/test/keystore/ca/oneca-serial  |   1 +
 modules/clients/src/test/keystore/ca/oneca.cnf     |  13 +-
 modules/clients/src/test/keystore/ca/oneca.key     |  52 ++--
 modules/clients/src/test/keystore/ca/oneca.pem     |  21 ++
 modules/clients/src/test/keystore/ca/oneindex.txt  |   1 -
 .../clients/src/test/keystore/ca/oneindex.txt.attr |   1 -
 modules/clients/src/test/keystore/ca/oneserial     |   1 -
 .../clients/src/test/keystore/ca/threeca-index.txt |   2 +
 .../test/keystore/ca/{twoserial => threeca-serial} |   0
 .../test/keystore/ca/{oneca.cnf => threeca.cnf}    |  17 +-
 modules/clients/src/test/keystore/ca/threeca.key   |  28 +++
 modules/clients/src/test/keystore/ca/threeca.pem   |  21 ++
 .../clients/src/test/keystore/ca/trust-both.jks    | Bin 1718 -> 0 bytes
 modules/clients/src/test/keystore/ca/trust-one.jks | Bin 877 -> 0 bytes
 modules/clients/src/test/keystore/ca/trust-two.jks | Bin 891 -> 0 bytes
 .../clients/src/test/keystore/ca/twoca-index.txt   |   5 +
 modules/clients/src/test/keystore/ca/twoca-serial  |   1 +
 modules/clients/src/test/keystore/ca/twoca.cnf     |  15 +-
 modules/clients/src/test/keystore/ca/twoca.key     |  52 ++--
 modules/clients/src/test/keystore/ca/twoca.pem     |  21 ++
 modules/clients/src/test/keystore/ca/twoindex.txt  |   2 -
 .../clients/src/test/keystore/ca/twoindex.txt.attr |   1 -
 modules/clients/src/test/keystore/client.jks       | Bin 3232 -> 2324 bytes
 modules/clients/src/test/keystore/client.pem       |  69 ------
 modules/clients/src/test/keystore/client.pfx       | Bin 3148 -> 0 bytes
 .../clients/src/test/keystore/connectorClient.jks  | Bin 0 -> 2353 bytes
 .../clients/src/test/keystore/connectorServer.jks  | Bin 0 -> 2355 bytes
 modules/clients/src/test/keystore/generate-ca.sh   |  97 ++++++++
 modules/clients/src/test/keystore/generate-keys.sh |  92 +++++++
 modules/clients/src/test/keystore/generate.sh      |  99 --------
 modules/clients/src/test/keystore/node01.jks       | Bin 0 -> 2325 bytes
 modules/clients/src/test/keystore/node02.jks       | Bin 0 -> 2325 bytes
 modules/clients/src/test/keystore/node02old.jks    | Bin 0 -> 2331 bytes
 modules/clients/src/test/keystore/node03.jks       | Bin 0 -> 2327 bytes
 modules/clients/src/test/keystore/server.jks       | Bin 3230 -> 2324 bytes
 modules/clients/src/test/keystore/server.pem       |  69 ------
 modules/clients/src/test/keystore/server.pfx       | Bin 3148 -> 0 bytes
 modules/clients/src/test/keystore/thinClient.jks   | Bin 0 -> 2332 bytes
 modules/clients/src/test/keystore/thinServer.jks   | Bin 0 -> 2332 bytes
 modules/clients/src/test/keystore/trust-both.jks   | Bin 0 -> 1888 bytes
 modules/clients/src/test/keystore/trust-one.jks    | Bin 0 -> 960 bytes
 modules/clients/src/test/keystore/trust-three.jks  | Bin 0 -> 970 bytes
 modules/clients/src/test/keystore/trust-two.jks    | Bin 0 -> 960 bytes
 modules/clients/src/test/keystore/trust.jks        | Bin 2432 -> 0 bytes
 .../src/test/resources/jetty/rest-jetty-ssl.xml    |   2 +-
 .../src/test/resources/jetty/router-jetty-ssl.xml  |   2 +-
 .../src/test/resources/spring-router-ssl.xml       |   2 +-
 .../src/test/resources/spring-server-ssl-node.xml  |   2 +-
 .../org/apache/ignite/ssl/SslContextFactory.java   |  29 ++-
 modules/core/src/test/config/tests.properties      |  25 +-
 .../apache/ignite/ssl/MultipleSSLContextsTest.java | 263 +++++++++++++++++++++
 .../ignite/testsuites/SecurityTestSuite.java       |   4 +-
 60 files changed, 691 insertions(+), 337 deletions(-)

diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinConnectionAdditionalSecurityTest.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinConnectionAdditionalSecurityTest.java
index 0574379..23dca3c 100644
--- a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinConnectionAdditionalSecurityTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinConnectionAdditionalSecurityTest.java
@@ -56,7 +56,7 @@ public class JdbcThinConnectionAdditionalSecurityTest extends JdbcThinAbstractSe
 
     /** Trust key store path. */
     private static final String TRUST_KEY_STORE_PATH = U.getIgniteHome() +
-        "/modules/clients/src/test/keystore/trust.jks";
+        "/modules/clients/src/test/keystore/trust-one.jks";
 
     /** SSL context factory. */
     private static Factory<SSLContext> sslCtxFactory;
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 e859a0f..a59e0e4 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
@@ -51,7 +51,7 @@ public class JdbcThinConnectionSSLTest extends JdbcThinAbstractSelfTest {
 
     /** Trust key store path. */
     private static final String TRUST_KEY_STORE_PATH = U.getIgniteHome() +
-        "/modules/clients/src/test/keystore/trust.jks";
+        "/modules/clients/src/test/keystore/trust-one.jks";
 
     /** SSL context factory. */
     private static Factory<SSLContext> sslCtxFactory;
diff --git a/modules/clients/src/test/keystore/README.txt b/modules/clients/src/test/keystore/README.txt
new file mode 100644
index 0000000..f980b0c
--- /dev/null
+++ b/modules/clients/src/test/keystore/README.txt
@@ -0,0 +1,11 @@
+This directory contains certification authorities, trust stores and keys, that are used in tests.
+
+In order to generate CAs, run the generate-ca.sh script.
+It will create all needed CAs from scratch and all needed trust-stores.
+In order for it to work, the ca directory should be removed.
+
+To generate keys, run the generate-keys.sh script.
+In order to create new keys, you can comment out calls to createStore, add new ones and run the script.
+
+If keys are expired and need to be generated again, the easiest way is to generate CAs from scratch and replace all
+keys with the new ones.
diff --git a/modules/clients/src/test/keystore/ca/node01.jks b/modules/clients/src/test/keystore/ca/node01.jks
deleted file mode 100644
index 7dec684..0000000
Binary files a/modules/clients/src/test/keystore/ca/node01.jks and /dev/null differ
diff --git a/modules/clients/src/test/keystore/ca/node02.jks b/modules/clients/src/test/keystore/ca/node02.jks
deleted file mode 100644
index 985abae..0000000
Binary files a/modules/clients/src/test/keystore/ca/node02.jks and /dev/null differ
diff --git a/modules/clients/src/test/keystore/ca/node02old.jks b/modules/clients/src/test/keystore/ca/node02old.jks
deleted file mode 100644
index 26da4b5..0000000
Binary files a/modules/clients/src/test/keystore/ca/node02old.jks and /dev/null differ
diff --git a/modules/clients/src/test/keystore/ca/node03.jks b/modules/clients/src/test/keystore/ca/node03.jks
deleted file mode 100644
index 9a6ab40..0000000
Binary files a/modules/clients/src/test/keystore/ca/node03.jks and /dev/null differ
diff --git a/modules/clients/src/test/keystore/ca/oneca-index.txt b/modules/clients/src/test/keystore/ca/oneca-index.txt
new file mode 100644
index 0000000..6f5860f
--- /dev/null
+++ b/modules/clients/src/test/keystore/ca/oneca-index.txt
@@ -0,0 +1,3 @@
+V	391107193744Z		01	unknown	/CN=client
+V	391107193746Z		02	unknown	/CN=server
+V	391107193750Z		03	unknown	/CN=node01
diff --git a/modules/clients/src/test/keystore/ca/oneca-serial b/modules/clients/src/test/keystore/ca/oneca-serial
new file mode 100644
index 0000000..6496923
--- /dev/null
+++ b/modules/clients/src/test/keystore/ca/oneca-serial
@@ -0,0 +1 @@
+04
diff --git a/modules/clients/src/test/keystore/ca/oneca.cnf b/modules/clients/src/test/keystore/ca/oneca.cnf
index 39fa7ad..15e4041 100644
--- a/modules/clients/src/test/keystore/ca/oneca.cnf
+++ b/modules/clients/src/test/keystore/ca/oneca.cnf
@@ -18,14 +18,15 @@
 default_ca = oneca
 
 [ oneca ]
-certificate = ./oneca.pem
-database = ./oneindex.txt
-private_key = ./oneca.key
-new_certs_dir = ./
+dir=ca
+certificate = $dir/oneca.pem
+database = $dir/oneca-index.txt
+private_key = $dir/oneca.key
+new_certs_dir = $dir/certs
 default_md = sha1
-serial = ./oneserial
-default_days = 365
 policy = policy_match
+serial = $dir/oneca-serial
+default_days = 365
 
 [policy_match]
 commonName = supplied
diff --git a/modules/clients/src/test/keystore/ca/oneca.key b/modules/clients/src/test/keystore/ca/oneca.key
index 8815206..8f7f8a6 100644
--- a/modules/clients/src/test/keystore/ca/oneca.key
+++ b/modules/clients/src/test/keystore/ca/oneca.key
@@ -1,28 +1,28 @@
 -----BEGIN PRIVATE KEY-----
-MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDw4NjQ0YkcVbBo
-jvaXpcIB6fay0saNihfQ85anbxI63fvnOnUZrXnfwruUP5Az57WHi2+qzHLujytE
-QqCqo/PlSQ5jJ7s2HJVPgDVCM6qlc9/wXaYHTfGmurbf3DCGY8+qDBNcs2M5Kztj
-Pb0RIn++idVUBiiVlgrj+Tqy6AatNT6r70EBLQnVmR6aU+z/iuDNzj4M/DA35C61
-Fug4zYQIJEENSRNtNtp5VDfMaopAwZTg0ENCz5nhSAv6d0NHDsZWtK60P9nuOFsJ
-16Hmlv/RyHaVSf+OvxZjZDcWhEorlHA5mhF/RU/8iczstE2JMk6vOQ0LwKO+05gL
-2/9oJKYrAgMBAAECggEBAOf8xRQoGdMuO94Xgir/O2A4gp4rHYsHqnRVhYzwDjCf
-xpIl3M3EI5J7q8jVhv5WdKB8jCmFClPzkwoE2VQ+3xC+UZrxkv5EfRC6O5DszbbX
-aJ/IsbRrPwcC4EmteRaVXlU5mBQ5uKBAoMutlD/CaCGMAecQn1mhzg9N41iW2odI
-2AxK8ATSogCyNdVe82bedVXauBW8Kbsr5TCOxpUTrnLFhCl2aDvqFzmJFop+13E7
-V25Xz6DzrsCrWhw8Ghjh5YAYTq8RatAx53/DBYuOFlMLuSxbBcISEXjzSmNtIgsY
-BgVMPltzbIVgkzvdNDtr0JMXPdHgX9aJ1lR2Obod+zECgYEA/XxcqmWq/mY+DbXf
-5ZPXf26bms1Mx9FAK5t4hF8GGOO63HMH5n84tUKhWTJCSFo8rjsGc/b+amj1oY6J
-BJtTLUP8sJSdYQzC2SybOrFT5XskHv4NgIdVX9zNbJS+Z5BYoLfwTyziSMjay6B7
-5kE8QbBzK6MyhyBYoItMQDZMwicCgYEA80R5ArTGCMsTK0YNFlS2Y5XKORRunwEM
-1Mm741P9ejhf/NUiwez8TrcRB+i7BjjC68idhP0zUKEsKEedAP4uWpic2wbBYOuH
-7BsNxXLQ3XJeLJ066fhqOdPA3pz3NP82EBp65g41RxpzlW74LpfnE4/kxk1pi4UP
-LpJpzqeFsl0CgYEA1ICWOq9Cm0ThTqMjERZQuV7jifIEJRtR3XzXmrkCpoj7VOYG
-QIB07Nfv5ZPRp1AmwLVw4nS0skZNbWPNkBQatb7iLrJYAU0uZ9wSQjD4sU/7ZxP6
-A77wno2/lQBZYv7Knem1xtpM1VG0wrJGTDByMGuZEYMdz9QZGHXOtaIP1U8CgYAy
-ZJTMwrXjTG4EINbFMXc22eiyOlFQDt+hlMifJt7zWopHzb8NfRInHDUi9ksH1upJ
-/Zzj16+xnDGRhoQ3mG/xxHt5w8R7V08o0dHgfRBXT0HC7C8wGI2ovPzPIKT1DYkd
-fN7ImVjgCdK3ue0fecgcfUpe6dpbVIz4kMvqSzme4QKBgQDjUk7m8szM4C8BIYQH
-1yo5kSPYQUZuc2UFYozd5ZNj791iAptrSSd2Mmck8MkT3oDAbH+SWg4Qw7UA/kNe
-264vVvNIzss7bw8UFcHT6JN9gdk08EsrW+IT3vopt3QlB/wYCHCqr47VviVneqWn
-og1hf+rw1WNr3atLP/NLnWWN7g==
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCgjpT9MM9b7BZa
+zSvEftEj5FtzJVHVtpK1yZa82bug0eCeWNr4JIPxg0rPWGVQVF2gnSidSVEfokuw
++LxRQGXKAPkJYHsVsk4t/lv5tynWTPHz293VlkaXyqHV2hS+3Wlu6TEOIepp0sZK
+KpzDfJfYfeNnq8Cib+s83XzbdNKbamkKSjHmMzeE1Qpwi9UYVw+0lzxDqxpTIZiX
+uFFFKwOR3D5I4euWT4zNWVGD001EJD3vFuzYeOPE8VK42qmj7VNr+1NV0iVI5oEj
+UbRS0eCkjonEkVCWhavVZIC85m0b74UPY99VcG+1kviTOnZ07xUCwLu5Qe+On56I
+q2GsKG9DAgMBAAECggEAXloL4hJ5+OnvZSLnEoz3+GCtASiwQ6gL5Tp3E7ncUjCk
+EEnlPCexRg9CukCXITLC5q0UfgHk43Mrie9SM2llp+UUdFc3XdOvr8WnZUMnGeGT
+2hud7HNoPrF8k0CaKmPRHrV493Yk3FVZ46HRB+xDC51HMtgy1wJwOg9q3Uh0r5FV
+ewSAxNn9HN/LCQU9+e0WO7+FxBcx7Z/RuQYGM+CS5Q+0pfSTQ7orugBsYGV8dhNU
+WQsYPMIRgz6mW43syPe+7cUoMYOvZDQsiaiZpzXEYbJEfYDajg0JeU0G6eVQWGIi
+8ISrOqQuigs0oeR9mzLVB1aImcgrpn+ZohI4FYl28QKBgQDS62zZKLMOU4+qOPt2
+pNsaz/dJaNpuMzG5YUaaD85n0kLA/CS4+0JlcDS98UYmQppOnwkwa4lr3ddB90Qz
+RLb3MFWie/Q8apm6HTGJbMU7wAE0rPp3OxJ5tMFoQAdoo9J3Trq9fkA+dxawoHH1
+ro5sKXhPc9rLVcRvvCN0EAu0WQKBgQDC34mq6oKB8Fsh5tOLbJ+8pyrSvsIJCglV
+ra6CMswl+jkaCLzYCyHKPk5TDNo2lUWqjXTpGgmOdExu54p0mQ1LjwINd6Sy2RrR
+yxkzB4BhLPYaU5w/AWJoi4u6ymovsoS2k/zyfb33oB6vb798ee7VQBOgGLPfcKZ7
+0jcZK3/8+wKBgHiFHcVYhDgDd2wE82tv9+LyQpMn3uhpSFhtRTJzJbYdZxdu/GzW
+5bGg1AJVA4iJNjMGnPGWAQgp0v5WlBnXgdTtQYF+4qhDIWQ/mja0eF8T75xx2wyW
+LJBuwLUZISKhuXmC+yGcKomG8ugqRfPksm0LpTuBL9xQPda64mdHY+jBAoGBAJP/
+y4FX+2gOEFhuAym3hJV1bCuEHr9YtQAyGP/e7nbFVAq2qh12TuJXcYrXjv63XaKL
+Lkg+sxVStB3ikZ++AX/qC4gI3rfJ9PlyQyAjSVgEGqCh8V9UgNWfba6ePgkdjndP
+a2MLJnRjUgqxVv+FZ2Lj+EO1nx5KYtZVL+1YwSpzAoGBAMdF3xClFY5Hk39+aHpY
+1ttkiQIU9t8cZYzKWC0f7BvFvoy0T88spaQK2UrCjkcVBFUekZ/3EOMm+soR0Cpo
+yJ569KA2LQ/EaUkWPGbbDzlrWcAHbBc58GjO5V0tXxhbCGhOzipa6PxhBRztSdpM
+C1UPVDjQO5+mohRUjFBPAj6+
 -----END PRIVATE KEY-----
diff --git a/modules/clients/src/test/keystore/ca/oneca.pem b/modules/clients/src/test/keystore/ca/oneca.pem
new file mode 100644
index 0000000..722c0e3
--- /dev/null
+++ b/modules/clients/src/test/keystore/ca/oneca.pem
@@ -0,0 +1,21 @@
+-----BEGIN TRUSTED CERTIFICATE-----
+MIIDfjCCAmYCCQD0mP2SbCTi+TANBgkqhkiG9w0BAQUFADCBgDEmMCQGCSqGSIb3
+DQEJARYXb25lY2FAaWduaXRlLmFwYWNoZS5vcmcxDjAMBgNVBAMMBW9uZWNhMQww
+CgYDVQQLDANEZXYxDzANBgNVBAoMBklnbml0ZTEMMAoGA1UEBwwDU1BiMQwwCgYD
+VQQIDANTUGIxCzAJBgNVBAYTAlJVMB4XDTE5MTEwNzE2MzczNloXDTM5MTEwNzE2
+MzczNlowgYAxJjAkBgkqhkiG9w0BCQEWF29uZWNhQGlnbml0ZS5hcGFjaGUub3Jn
+MQ4wDAYDVQQDDAVvbmVjYTEMMAoGA1UECwwDRGV2MQ8wDQYDVQQKDAZJZ25pdGUx
+DDAKBgNVBAcMA1NQYjEMMAoGA1UECAwDU1BiMQswCQYDVQQGEwJSVTCCASIwDQYJ
+KoZIhvcNAQEBBQADggEPADCCAQoCggEBAKCOlP0wz1vsFlrNK8R+0SPkW3MlUdW2
+krXJlrzZu6DR4J5Y2vgkg/GDSs9YZVBUXaCdKJ1JUR+iS7D4vFFAZcoA+QlgexWy
+Ti3+W/m3KdZM8fPb3dWWRpfKodXaFL7daW7pMQ4h6mnSxkoqnMN8l9h942erwKJv
+6zzdfNt00ptqaQpKMeYzN4TVCnCL1RhXD7SXPEOrGlMhmJe4UUUrA5HcPkjh65ZP
+jM1ZUYPTTUQkPe8W7Nh448TxUrjaqaPtU2v7U1XSJUjmgSNRtFLR4KSOicSRUJaF
+q9VkgLzmbRvvhQ9j31Vwb7WS+JM6dnTvFQLAu7lB746fnoirYawob0MCAwEAATAN
+BgkqhkiG9w0BAQUFAAOCAQEAJzTrPMjfIb6/8lzvLcfesPjr+CqMAm86P+cE9lyo
+iV7MVcoDTQgT7hu8A9TBO/6x+iFDjgaw74EKu9fPOIPbqJlh3kJmdISGozMjGAeO
+gsruUteGIdW6GdG4a3fIgu/M2KQjN769cMb2GiYGwzLN+CyKGGBFZeBaPNyVP8pR
+KhqiOAWT0Va3fP62r6BrhiEqFxPOaG/NEjnaskJz0AuWEW+O8eNW2GiHWjXNRulH
+tMoIHz91RtVfbQBaznQ7BadT7qoDozhGRx0biHDwprW4cC+vHwvWKrON83TSv91K
+zohgcpfRHx3RVk8zbRKVg8ssMjzVXL9PqpS4YvT1+G8N/w==
+-----END TRUSTED CERTIFICATE-----
diff --git a/modules/clients/src/test/keystore/ca/oneindex.txt b/modules/clients/src/test/keystore/ca/oneindex.txt
deleted file mode 100644
index 5d0e1c9..0000000
--- a/modules/clients/src/test/keystore/ca/oneindex.txt
+++ /dev/null
@@ -1 +0,0 @@
-V	210823155040Z		01	unknown	/CN=node01
diff --git a/modules/clients/src/test/keystore/ca/oneindex.txt.attr b/modules/clients/src/test/keystore/ca/oneindex.txt.attr
deleted file mode 100644
index 8f7e63a..0000000
--- a/modules/clients/src/test/keystore/ca/oneindex.txt.attr
+++ /dev/null
@@ -1 +0,0 @@
-unique_subject = yes
diff --git a/modules/clients/src/test/keystore/ca/oneserial b/modules/clients/src/test/keystore/ca/oneserial
deleted file mode 100644
index 9e22bcb..0000000
--- a/modules/clients/src/test/keystore/ca/oneserial
+++ /dev/null
@@ -1 +0,0 @@
-02
diff --git a/modules/clients/src/test/keystore/ca/threeca-index.txt b/modules/clients/src/test/keystore/ca/threeca-index.txt
new file mode 100644
index 0000000..3b8eab1
--- /dev/null
+++ b/modules/clients/src/test/keystore/ca/threeca-index.txt
@@ -0,0 +1,2 @@
+V	391107193748Z		01	unknown	/CN=connectorClient
+V	391107193749Z		02	unknown	/CN=connectorServer
diff --git a/modules/clients/src/test/keystore/ca/twoserial b/modules/clients/src/test/keystore/ca/threeca-serial
similarity index 100%
rename from modules/clients/src/test/keystore/ca/twoserial
rename to modules/clients/src/test/keystore/ca/threeca-serial
diff --git a/modules/clients/src/test/keystore/ca/oneca.cnf b/modules/clients/src/test/keystore/ca/threeca.cnf
similarity index 82%
copy from modules/clients/src/test/keystore/ca/oneca.cnf
copy to modules/clients/src/test/keystore/ca/threeca.cnf
index 39fa7ad..531e28b 100644
--- a/modules/clients/src/test/keystore/ca/oneca.cnf
+++ b/modules/clients/src/test/keystore/ca/threeca.cnf
@@ -15,17 +15,18 @@
 #  limitations under the License.
 
 [ ca ]
-default_ca = oneca
+default_ca = threeca
 
-[ oneca ]
-certificate = ./oneca.pem
-database = ./oneindex.txt
-private_key = ./oneca.key
-new_certs_dir = ./
+[ threeca ]
+dir=ca
+certificate = $dir/threeca.pem
+database = $dir/threeca-index.txt
+private_key = $dir/threeca.key
+new_certs_dir = $dir/certs
 default_md = sha1
-serial = ./oneserial
-default_days = 365
 policy = policy_match
+serial = $dir/threeca-serial
+default_days = 365
 
 [policy_match]
 commonName = supplied
diff --git a/modules/clients/src/test/keystore/ca/threeca.key b/modules/clients/src/test/keystore/ca/threeca.key
new file mode 100644
index 0000000..f117edb
--- /dev/null
+++ b/modules/clients/src/test/keystore/ca/threeca.key
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDKKXeRCE49Lctj
+0ZLGdd/umBYUMiURTIIDdw4vWGBoEvMt2NO9fnBXl3829nHW/87WeZbBnv2BUzOE
+pHmdTKqbQZM3+u65ZDgvKL7EAuLjBzT5Hlsh51cCJ/N63FpjWtwqbUjFEb/WHcqY
+N/nWVd0wfPge45SqEAkQsJm6Ckk/4t+wG4i/2SVfpfcixOYQX11JY0GCP68qAzAH
+qsfrRgxF0yk6l3GqaZrDy/ChS5t1MzaxNZYG1GWXjBK8ckDmO/yrmXsmjTg9z+sL
+m2uXPJyMFB90zKm2xtLKJXp6k/4J9itt8XZvopZWMX5qrS5g1kOlgmd2PmhK3Q/h
+nclcQNP/AgMBAAECggEAUPLdv6M1wOWPZX7LaNBWRHF9lcSmdxDNlpmbgnW+1K2R
+1i/WSTBRx6EP/XAdEVwI9HRnW0xQcfJg1KIPWF8UiWpuiqHd6ToqDSghitclBoci
+PQZcs2ywuFpK8k09nD8Lnal41ABRcmkncGApmBt1oC7KI4Q5SQd2ucodJBNuVTfK
+6hldCkcUic0qEs1zJDVbtCBQXsIPFb/cXG27u7BZ+oYcHdec9WYnJ+FlKfZeMxJr
+929dck9qmAWS8ZpuviPN3UchoPCjf13b7LDB5WdcoyAo7EYm52LV8X+1EkP3UpPa
+hR1FdGGhkE1mAjYoS/0gZqQF27FkdlIjmMyChjLUAQKBgQDmhKAGIZEIGyyoBt3p
+KBgICf8xLonFjsueMJXBzI8Eqfjmu9Wv9DcVAfQNyVDI/u8JtfvfZzmMWhYPwCta
+IpARyB56urrCD+izf3NzLvB+DigwGFvhsMx8Cna1I1ebiC+nyZIQQlMQQubP7LD8
+yF26FF+/rxRuNm5zl5sDr+We/wKBgQDggmZjdpOD55sVUY+3kdJi/PnrsedzpX1v
+u401Um/gnixpwEvEgumRCLhnt8WsYe4alYrKkQqd2t8qOsGe0qGErlLW+tBArk83
+Sdoi62+g0ZNlGp7VqnSodNLSMtaZ+HeVLDpNwMMREf6gNs72hAd9EBZg1v6VY0na
+Zuy2T7nLAQKBgQCBWfSN3DIM8Wq6krfdSKFLiYiIaYvnrrw1dR/j0syCGnrPxqEf
+DhQGlsUDI29QijVKJrNCZiMVzctJZVUuS+y5/aiUx8laciDq8F6xSKqsoXcNne2Z
+FGN6S0jXVhCn9uB+744lz4Hawx/PlwqtniVx8FLWNgFp4uNRu8XBaOeZswKBgHdy
+aW85wzpGmyg4gLI2Dy1DUuSnfnD090vfCT35YjSrcw3AlY8z53iWnyXvjGguojPa
+pEEp8fASZvFc2W7aubyR0tk2EF6ZXuQXkstJX9a8KiN8ik07p12I6jGTgsHghB8F
+rO95Q09tt38eKfbWP/W1/XIAcOqiLMTaRc6plDwBAoGBANK5dW87pYQYtSW8ZFHS
+G4xK9EcyVqZ/MoaX4fplN7TZy/CApvJ6qfUst9wMeE4Sja6CI+mGcnWE8bZcTF2z
+gS6769E+nCMbD33ScRrT+yJ1isAPRc0MBQG+498mZn1R2EfuSuICllf/UiqgmgFh
+kUNhYgBYx/2yViWzmj1V+0zh
+-----END PRIVATE KEY-----
diff --git a/modules/clients/src/test/keystore/ca/threeca.pem b/modules/clients/src/test/keystore/ca/threeca.pem
new file mode 100644
index 0000000..1b548fe
--- /dev/null
+++ b/modules/clients/src/test/keystore/ca/threeca.pem
@@ -0,0 +1,21 @@
+-----BEGIN TRUSTED CERTIFICATE-----
+MIIDhjCCAm4CCQC0QnJWqwJwjDANBgkqhkiG9w0BAQUFADCBhDEoMCYGCSqGSIb3
+DQEJARYZdGhyZWVjYUBpZ25pdGUuYXBhY2hlLm9yZzEQMA4GA1UEAwwHdGhyZWVj
+YTEMMAoGA1UECwwDRGV2MQ8wDQYDVQQKDAZJZ25pdGUxDDAKBgNVBAcMA1NQYjEM
+MAoGA1UECAwDU1BiMQswCQYDVQQGEwJSVTAeFw0xOTExMDcxNjM3MzZaFw0zOTEx
+MDcxNjM3MzZaMIGEMSgwJgYJKoZIhvcNAQkBFhl0aHJlZWNhQGlnbml0ZS5hcGFj
+aGUub3JnMRAwDgYDVQQDDAd0aHJlZWNhMQwwCgYDVQQLDANEZXYxDzANBgNVBAoM
+Bklnbml0ZTEMMAoGA1UEBwwDU1BiMQwwCgYDVQQIDANTUGIxCzAJBgNVBAYTAlJV
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyil3kQhOPS3LY9GSxnXf
+7pgWFDIlEUyCA3cOL1hgaBLzLdjTvX5wV5d/NvZx1v/O1nmWwZ79gVMzhKR5nUyq
+m0GTN/ruuWQ4Lyi+xALi4wc0+R5bIedXAifzetxaY1rcKm1IxRG/1h3KmDf51lXd
+MHz4HuOUqhAJELCZugpJP+LfsBuIv9klX6X3IsTmEF9dSWNBgj+vKgMwB6rH60YM
+RdMpOpdxqmmaw8vwoUubdTM2sTWWBtRll4wSvHJA5jv8q5l7Jo04Pc/rC5trlzyc
+jBQfdMyptsbSyiV6epP+CfYrbfF2b6KWVjF+aq0uYNZDpYJndj5oSt0P4Z3JXEDT
+/wIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQAwm1lXDHwNhDGJ8EyLyLzMgLzTkHrv
++6+C4+PF1MrSp++ofTvv79UJDOem5ThlbPkbxlA3QKHUp7Gi4VbiNL+foCmaYe9P
+WED+OZ6DN1LyuFs+GQSyCxS80DKGFo6xZsCD04a6QSMR0HfLqCh4jOlhuasPSM6p
+f04RoaxLUL8AER95MQDsZgPjUSjVsUGNdaOvKHdW+4YLreE+qhHt+4Pk837osyo1
+KxL72N2N2/aBqhUW/EeDta9HVeIqrAJiuZ+KePMFFaczMub74VsL8ZpV5WEvEMzk
+elSnMM7tShTVHGEKDi5c9as63OhjEK2uTCX9aN9LV1xrP5xcGtebiP3H
+-----END TRUSTED CERTIFICATE-----
diff --git a/modules/clients/src/test/keystore/ca/trust-both.jks b/modules/clients/src/test/keystore/ca/trust-both.jks
deleted file mode 100644
index 1d8ccc2..0000000
Binary files a/modules/clients/src/test/keystore/ca/trust-both.jks and /dev/null differ
diff --git a/modules/clients/src/test/keystore/ca/trust-one.jks b/modules/clients/src/test/keystore/ca/trust-one.jks
deleted file mode 100644
index 0b91ca7..0000000
Binary files a/modules/clients/src/test/keystore/ca/trust-one.jks and /dev/null differ
diff --git a/modules/clients/src/test/keystore/ca/trust-two.jks b/modules/clients/src/test/keystore/ca/trust-two.jks
deleted file mode 100644
index 1939287..0000000
Binary files a/modules/clients/src/test/keystore/ca/trust-two.jks and /dev/null differ
diff --git a/modules/clients/src/test/keystore/ca/twoca-index.txt b/modules/clients/src/test/keystore/ca/twoca-index.txt
new file mode 100644
index 0000000..695905f
--- /dev/null
+++ b/modules/clients/src/test/keystore/ca/twoca-index.txt
@@ -0,0 +1,5 @@
+V	391107193746Z		01	unknown	/CN=thinClient
+V	391107193747Z		02	unknown	/CN=thinServer
+V	391107193751Z		03	unknown	/CN=node02
+V	391107193753Z		04	unknown	/CN=node03
+V	191106193754Z		05	unknown	/CN=node02old
diff --git a/modules/clients/src/test/keystore/ca/twoca-serial b/modules/clients/src/test/keystore/ca/twoca-serial
new file mode 100644
index 0000000..cd672a5
--- /dev/null
+++ b/modules/clients/src/test/keystore/ca/twoca-serial
@@ -0,0 +1 @@
+06
diff --git a/modules/clients/src/test/keystore/ca/twoca.cnf b/modules/clients/src/test/keystore/ca/twoca.cnf
index 8bb5e50..30867f5 100644
--- a/modules/clients/src/test/keystore/ca/twoca.cnf
+++ b/modules/clients/src/test/keystore/ca/twoca.cnf
@@ -16,16 +16,17 @@
 
 [ ca ]
 default_ca = twoca
- 
+
 [ twoca ]
-certificate = ./twoca.pem
-database = ./twoindex.txt
-private_key = ./twoca.key
-new_certs_dir = ./
+dir=ca
+certificate = $dir/twoca.pem
+database = $dir/twoca-index.txt
+private_key = $dir/twoca.key
+new_certs_dir = $dir/certs
 default_md = sha1
 policy = policy_match
-serial = ./twoserial
+serial = $dir/twoca-serial
 default_days = 365
- 
+
 [policy_match]
 commonName = supplied
diff --git a/modules/clients/src/test/keystore/ca/twoca.key b/modules/clients/src/test/keystore/ca/twoca.key
index 4053881..754cb64 100644
--- a/modules/clients/src/test/keystore/ca/twoca.key
+++ b/modules/clients/src/test/keystore/ca/twoca.key
@@ -1,28 +1,28 @@
 -----BEGIN PRIVATE KEY-----
-MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCvv6fLWOIk9Hhn
-JMsfoySItogO+hhV4kREDEGi8SfAblHEKCiY4GxvtgtxS3EWyoYFynI8HK7GQNma
-tAQ49QtUP5FA36VRx3/9eh85je4AqXVgF/4qX0PdygMuSFOIxWYshj9CIwVHmiS2
-+IiVthe6OsAUSMnfIFzIxlEygpi6/I2N2WchkOlWiWo1G9E4RQOjKrwCGM/mWy6Y
-KIB2u3dSaNpfNZy2+sxBRXrtDUQzDxbVv9lCQ3DkZwVr2HnfMxZ9oFP5x8HoPyJi
-uS4qLUWypnbvIuBLnlR4LX/VSONCg6PzkafQdSvoYX5XPYDF32PUiSZS+U7URHzN
-nqC7nn97AgMBAAECggEAdEvHlfjoFHotXltrijDjkQ/wMrDt/47ti3XszQz1OBII
-S1wjmR4Qw09cfQjl+aXkT9qqAvsb8BajqAptLN+CMqqpzJrxg48XM71nAifYEVoR
-UJgv2QwXFaGCv1Ke7EdrmBTxsSsJaFso5mbJwv+u7c3IouOTqfF5VGZe/qSKulgh
-/swDJTFCo+JwISTJlVppR6xUVTtLpl4JFyWWExfGpOFmCfy818lhpJLV9HZzh142
-zssJCBevpaKng4DsHVmhvhi1f8zNV674C0cJ8yCBCVFAVw5WufaWRSh8PnHT9AR8
-+dqrGh+0EtmjJR9qy88LLEayWZKxE4oQLSUcDSe6OQKBgQDUK8/gZPzsepq0AOTD
-qL21nkMmA00J5u4USgB5S27PrYQB1p4uf1wfwVfmXC21Pyrwl+/mx9ukkQB907jG
-5vQTF81YEV1Z9eT5gCjE0XeCK40kYNdvfhlTPeuJteqEnrFDWZQ3WGD+6/TQoEfj
-BibgaAroKvlGF8mLWfAC9qqcrQKBgQDUDbkdUtthgZdDVoAzMS9kWB37pj1io3+8
-dOZ9i8farzTW3FcX9T504YPvazoNllKVaiO/q1sODI+7gtixYVKriZsqqE/h7ndS
-mc7OVfxqxoy5bW2XZUHNbefG/JTJvy4Zj8ANnes7Cb5fJtNtB3xa3JaGRFo91te6
-2M/6v2MpxwKBgG1Hf5MpEKhQYbwStcEc+VFBCX7btmNCQR/MGcBfnNx0l4hG3UQ/
-rthgQgDRO22d8mTnLNYl3Dg/wwwL76DqtY3b9ZTFpNo/70aevuDYroAqJFE3W97+
-CNc6DkXon7jc75or2k5DQ/oo1/hYhY4lzgJJNEzuTWPPvqv6j8dG+wslAoGAY+tn
-e8LMLuDihs9er0CQ5UaEMkz+Bdmm2gV3ilbwQEJosom23EoqOOb+xTUQcNCRb2hJ
-GgrDaBZRL/kS5FpImx3HKM2QfpRgU2K4SQ/JVgLi0okWp80Fuaf9HA1uirX0IgVT
-aNctvW707l8cJvbtCN+CahgRMaxnkNqS/cNrFYcCgYBBzR2qDcTn48gs7LvrlzMO
-RwamzD0LEibRUvw17rcmf4x2tFqx8hnyh4ahpPxlcB5SRSKhs2RKFf4AONGHMFAW
-IU/pxQJdk32NX1Xg5TjiNS+khW2Yp7voytvYyP7JMbSlp1NZbgNVYA4voikFNZ/O
-63NWew8dD+Gx5ZEWXg2Nvw==
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDWh4dVuZN+SuC1
+LJYHn1kk8bcC4s/00R6ZebxZItzbo0eSaBB9xBIk0Hf7xEWoBJAUJ+FMsEZz4/ZK
+tV1UlBxKksvGlaiJ55Gf1YEBCf6IJ6EAzbGlammvFZALygsY0vvVIFqQbqVDg82N
+TfVByP4GMblwos4ogzPKxGoOFTRVEfROdQQUXGPIBoqOPpBlLO4d3i8+istIIQvU
+JJK+4P90W+nSXmfrh/lfI8BaIAt0mcIS3PBawZQole+O1/7jH79Kn7L43CK8KhkJ
+rYfL0wuMqua8t3dYtxVcM8e7NgVUxa2drNEjEESB1MoApxq3QWoP+MyepslDoaSJ
+3FQZQKtHAgMBAAECggEAFXhk7AhxoX8e9CLtNQAWrOLgHRLUGz1eoZ+UYRtjHTw/
+KoDtvZiE9FhE2dav3fvu64V+P+2Yb3rOKHX0TEWyeygr6skJoBuj8GouygrVBY1p
+yKnNcK+wugwfaX6kE6zx9UeSqMfaFGK5jL3ToOzbt4T8eTBiD53p7g4wSw6GOUku
+rw79vSmLPZqY1G1x8uR6RsdScDyj71Fir1r4Iz3mtKOHKmE52VL5hoaMXNPFVe43
+3ttBAKbLUEqJH9Dmw3pUPKRcW8Nf4C6EIRsLL+XYjMGxv6T0TQwpk6C2s4VEdVHm
+dnqY2cQum1nlrDgYGCc8ZNvc0Ln4IOpvFEx4T1rYiQKBgQD8i+Kv1jfg5t77R1Hy
+9hMsSn5kWj+xWxkw+TUJZRF4wHEuGBnGgKWAx/sQyBMCg80GuH91HTLgJgjeAUGM
+gjp7e2PQbiDoPNrvnYooQAxPVETTJdykeSF5FTOGQSuezTMPEavZJcC+iCR9quX8
+8SpCqqBLFERpJ/qMgBDJEQMOMwKBgQDZdo2dQzSddBIxcniuIDQikmeDF9lwL0Cu
+1s/dGgiXMQoBFo8/ZA+sjzGgzWkt3/68y1BpaEO6LGW/sVamCjSf7BfSJPNeRDO2
+Gj7qzvw6db6x2BYI7inmwWOJPo9Ct0D58O8Ud6ti3cMmHqcSIhJy6nfcL1+6HdED
+PtrbtvkynQKBgQCiI71aXxJpFlC6y0NV1Z7hpMIY88hIudAmnRjr+zOIbyU7DsYd
+p6KaV8pdL9bkmnIbioBqVGDBgCnZPr0y1LlvZfzjaJFACTIW/PIifVxp4hR966UJ
+A6v17SKzY0v6HIxXdGT8eTySFx42gG5AQyV6v8lB6rUxPjWh1ubv8Dgh+QKBgBz1
+K4BwjZYV+cI54xYU1bxw0HXlfB/zOuLNWhqwN8qiThm8/lBLq8anvs0R7VqdhFdx
+n4CZ0ML+3IG9RLORklZlYvqpzvqTjGtIbW5pJ69FNKKMCssfo9bFk9KX0Q3qRy3B
+RqTsFpdwvmbaGBdTEC/bRyC78jxfchDDkvNFF0QFAoGBAMWFUlLNWdrUrQHi48qc
+tlgcDf6kkZpuLFXf0s7LMJvhjrN+eLSarpHeFR6+WVVHDgAbPFf1rQzLDBp8Mq3U
+bzDSMvOLkiB7ELy7cq8CvrvIpVhFC4EcJ3xZCtJXONWK95ZRr+/oRCuoRhwIRVT5
+as0UwWnNTd7YAQKzvIuygA+c
 -----END PRIVATE KEY-----
diff --git a/modules/clients/src/test/keystore/ca/twoca.pem b/modules/clients/src/test/keystore/ca/twoca.pem
new file mode 100644
index 0000000..05a0bbc
--- /dev/null
+++ b/modules/clients/src/test/keystore/ca/twoca.pem
@@ -0,0 +1,21 @@
+-----BEGIN TRUSTED CERTIFICATE-----
+MIIDfjCCAmYCCQD/llUaqH4aMDANBgkqhkiG9w0BAQUFADCBgDEmMCQGCSqGSIb3
+DQEJARYXdHdvY2FAaWduaXRlLmFwYWNoZS5vcmcxDjAMBgNVBAMMBXR3b2NhMQww
+CgYDVQQLDANEZXYxDzANBgNVBAoMBklnbml0ZTEMMAoGA1UEBwwDU1BiMQwwCgYD
+VQQIDANTUGIxCzAJBgNVBAYTAlJVMB4XDTE5MTEwNzE2MzczNloXDTM5MTEwNzE2
+MzczNlowgYAxJjAkBgkqhkiG9w0BCQEWF3R3b2NhQGlnbml0ZS5hcGFjaGUub3Jn
+MQ4wDAYDVQQDDAV0d29jYTEMMAoGA1UECwwDRGV2MQ8wDQYDVQQKDAZJZ25pdGUx
+DDAKBgNVBAcMA1NQYjEMMAoGA1UECAwDU1BiMQswCQYDVQQGEwJSVTCCASIwDQYJ
+KoZIhvcNAQEBBQADggEPADCCAQoCggEBANaHh1W5k35K4LUslgefWSTxtwLiz/TR
+Hpl5vFki3NujR5JoEH3EEiTQd/vERagEkBQn4UywRnPj9kq1XVSUHEqSy8aVqInn
+kZ/VgQEJ/ognoQDNsaVqaa8VkAvKCxjS+9UgWpBupUODzY1N9UHI/gYxuXCiziiD
+M8rEag4VNFUR9E51BBRcY8gGio4+kGUs7h3eLz6Ky0ghC9Qkkr7g/3Rb6dJeZ+uH
++V8jwFogC3SZwhLc8FrBlCiV747X/uMfv0qfsvjcIrwqGQmth8vTC4yq5ry3d1i3
+FVwzx7s2BVTFrZ2s0SMQRIHUygCnGrdBag/4zJ6myUOhpIncVBlAq0cCAwEAATAN
+BgkqhkiG9w0BAQUFAAOCAQEAN+ICtYXDTLe4hVk4o5jYY9yLGUUGosVexL2VzRPB
+OE7qTG6jAT/REvLfyJW6Chypr0eGNtuY+Oysc2kbAzdzssHq0UL+K1+wC6PURcJ8
+0evos3r0CRye7ZLv2ZNRakti6GqplhooCkvqBKoAzwndbMyFPV+KwPHq0yf4lenc
+40/PjnmdLy6sePd5AEzl9pZhes0b3+odnhNJwqjSto7g/pD69k+1d3eDLfRKxOw5
+/qis3IwGTmi2fQ7pKM0SfaeJnZmgNRjKc5BdhSr2MX3DUlYjuUTgEDMBKPUinqvK
+3ZqNTrTsg8n1/L1nGduKE9Cb+on3bxbrIq2gPxAWXBy7sg==
+-----END TRUSTED CERTIFICATE-----
diff --git a/modules/clients/src/test/keystore/ca/twoindex.txt b/modules/clients/src/test/keystore/ca/twoindex.txt
deleted file mode 100644
index 1f9359d..0000000
--- a/modules/clients/src/test/keystore/ca/twoindex.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-V	210823155541Z		01	unknown	/CN=node02
-V	210823155835Z		02	unknown	/CN=node03
diff --git a/modules/clients/src/test/keystore/ca/twoindex.txt.attr b/modules/clients/src/test/keystore/ca/twoindex.txt.attr
deleted file mode 100644
index 8f7e63a..0000000
--- a/modules/clients/src/test/keystore/ca/twoindex.txt.attr
+++ /dev/null
@@ -1 +0,0 @@
-unique_subject = yes
diff --git a/modules/clients/src/test/keystore/client.jks b/modules/clients/src/test/keystore/client.jks
index 1875c71..cf16ae1 100644
Binary files a/modules/clients/src/test/keystore/client.jks and b/modules/clients/src/test/keystore/client.jks differ
diff --git a/modules/clients/src/test/keystore/client.pem b/modules/clients/src/test/keystore/client.pem
deleted file mode 100644
index a71a87e..0000000
--- a/modules/clients/src/test/keystore/client.pem
+++ /dev/null
@@ -1,69 +0,0 @@
-Bag Attributes
-    friendlyName: client
-    localKeyID: 54 69 6D 65 20 31 33 33 39 32 33 39 38 35 39 34 34 36 
-Key Attributes: <No Attributes>
------BEGIN RSA PRIVATE KEY-----
-Proc-Type: 4,ENCRYPTED
-DEK-Info: DES-EDE3-CBC,CE61EDD98349D0C7
-
-Kzl16sj8R7YUXPCEZCqCrY4LSAjiKCRFNOagEehvN9Jpswcz4JbatoFmvVvOCgBF
-7kkeCaALhfM5a+46uynZ1sOOFUOn8fUFgguN3lLInWfm6vTuXDPslg0/tRNI0YqW
-ujfxyzrm1/k4RX0oLzRE1jZr69VZsBmZndkz9nkz3anWKLE7X/VIFV6U/N6YNPch
-BG1Fxpt/HtM9p3B5wNDSjCVaeNP1ROKe3APLRY6k+SppTuntHV5q9Ni82r1l3ahU
-zf2QvocSy9MLh+bGusJGHyJJAGuwPHm6ytPwbXGHn5xe4HPIno28j9kN7EL1ZoUs
-q0PhipAkFrGIM4zg6nAwVdzY5iGySDQ3fWpz2MkrKMDRftBwA3o/M321NBUW9/2X
-l+XmjXcJd0dEOslGxveb6UXLL2YvYszjQXRR4dCV/40bMJL3umRhVSay0NteoXfY
-82rQchm2NHKOiDfB4RpD8JJtVQeDSMXc9TH5y2Ua7FZND60JXtFpdnfCVfVZuBJm
-yBafyIsXR7EQzLG4z28Dvp4fs42A3JkF+e9Aq6Y6MmYA1wsvIKKT9HKEifqKmbgG
-4E9WOZn5IWi4ZJ44VAwN/uBGrLm//3OjByeB9y8vszNbyY8dQ8x5XqnF/IzIvgqc
-uKA8xuLAkTFmgRGQ/lmMDR+iMhet5dCtg9Orb9tYVL55JAb/OfsCX0LTJ3Y2RmIx
-CaFpkUP7KKYD+69ajnFCxvfGnGxyBkf+JeuDYIZVFklVT9SUtL9RJh26jUdvHt2A
-LQerBl8UCkVbPxsxYjdawvxuBNTD6tSRykM8zwtWcvIubp+gxE7png==
------END RSA PRIVATE KEY-----
-Bag Attributes
-    friendlyName: 1.2.840.113549.1.9.1=#1613636c69656e7440677269646761696e2e636f6d,CN=client,OU=Dev,O=GridGain,ST=SPb,C=RU
-    localKeyID: 54 69 6D 65 20 31 33 33 39 32 33 39 38 35 39 34 34 36 
-subject=/C=RU/ST=SPb/O=GridGain/OU=Dev/CN=client/emailAddress=client@gridgain.com
-issuer=/C=RU/ST=SPb/L=SPb/O=GridGain/OU=Dev/CN=ca/emailAddress=ca@gridgain.com
------BEGIN CERTIFICATE-----
-MIIC2TCCAkKgAwIBAgIBJDANBgkqhkiG9w0BAQUFADB3MQswCQYDVQQGEwJSVTEM
-MAoGA1UECBMDU1BiMQwwCgYDVQQHEwNTUGIxETAPBgNVBAoTCEdyaWRHYWluMQww
-CgYDVQQLEwNEZXYxCzAJBgNVBAMTAmNhMR4wHAYJKoZIhvcNAQkBFg9jYUBncmlk
-Z2Fpbi5jb20wHhcNMTIwNjA5MTEwNDE3WhcNMzIwNjA5MTEwNDE3WjBxMQswCQYD
-VQQGEwJSVTEMMAoGA1UECBMDU1BiMREwDwYDVQQKEwhHcmlkR2FpbjEMMAoGA1UE
-CxMDRGV2MQ8wDQYDVQQDEwZjbGllbnQxIjAgBgkqhkiG9w0BCQEWE2NsaWVudEBn
-cmlkZ2Fpbi5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANIHHcYiA+CP
-EBPKNZJ6mtvN4d9Yj43B5/hzs/TK3e4XImLsMhXaElYtrXQX/SDK7Zv5zdj6AkKH
-QkJ9BT8Jw7wvOQx/v4Qxrl+gTgcf6gjk6DvzqMlZUwH+ohbALj2TWsy9y+0uHKal
-EVrHpbYeB9TGpD+3NHwO/CG4SySk/Y4nAgMBAAGjezB5MAkGA1UdEwQCMAAwLAYJ
-YIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1Ud
-DgQWBBRD/TKyBQyoVxqEupLzUB8hDrSF6DAfBgNVHSMEGDAWgBS1+Ah4ZG58tImL
-KqLVX+xBKbeFUTANBgkqhkiG9w0BAQUFAAOBgQCL2vhjwcJkA1OJGuXsuO2/87Zu
-HMa7gc4pm+Iol1B1gD2ksQEAU2dz/adD3369H7gZdHuk3RYPeYmD5Ppp9eECDsXc
-gNWrNYaqcSTYWRAUe1/St7vB9HzPdOm/eADfQaMnal6fmjfpzTgg65A/2w4GCsqt
-RL98pvdAft8v5WSx7A==
------END CERTIFICATE-----
-Bag Attributes
-    friendlyName: 1.2.840.113549.1.9.1=#160f636140677269646761696e2e636f6d,CN=ca,OU=Dev,O=GridGain,L=SPb,ST=SPb,C=RU
-subject=/C=RU/ST=SPb/L=SPb/O=GridGain/OU=Dev/CN=ca/emailAddress=ca@gridgain.com
-issuer=/C=RU/ST=SPb/L=SPb/O=GridGain/OU=Dev/CN=ca/emailAddress=ca@gridgain.com
------BEGIN CERTIFICATE-----
-MIIDSTCCArKgAwIBAgIJAKmuj925215OMA0GCSqGSIb3DQEBBQUAMHcxCzAJBgNV
-BAYTAlJVMQwwCgYDVQQIEwNTUGIxDDAKBgNVBAcTA1NQYjERMA8GA1UEChMIR3Jp
-ZEdhaW4xDDAKBgNVBAsTA0RldjELMAkGA1UEAxMCY2ExHjAcBgkqhkiG9w0BCQEW
-D2NhQGdyaWRnYWluLmNvbTAeFw0xMjA2MDkwNjU1MTJaFw0zMjA2MDQwNjU1MTJa
-MHcxCzAJBgNVBAYTAlJVMQwwCgYDVQQIEwNTUGIxDDAKBgNVBAcTA1NQYjERMA8G
-A1UEChMIR3JpZEdhaW4xDDAKBgNVBAsTA0RldjELMAkGA1UEAxMCY2ExHjAcBgkq
-hkiG9w0BCQEWD2NhQGdyaWRnYWluLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAw
-gYkCgYEAtd16DCObyM63NKF/cvRcE+8cr1dc3c7mSnTEQ61WfqPJ2QqsQAB6e+5+
-q9Np1SaJyqFTTag6483ibrU+DkGPGgEXndRHtQHQPbStWsf47DBBW2bMi6+bkPox
-Cp6BhYO1DQUG5tP9CQ/g32mLQLB7LH0KtS1JcKpAClCjjWZC8b8CAwEAAaOB3DCB
-2TAdBgNVHQ4EFgQUtfgIeGRufLSJiyqi1V/sQSm3hVEwgakGA1UdIwSBoTCBnoAU
-tfgIeGRufLSJiyqi1V/sQSm3hVGhe6R5MHcxCzAJBgNVBAYTAlJVMQwwCgYDVQQI
-EwNTUGIxDDAKBgNVBAcTA1NQYjERMA8GA1UEChMIR3JpZEdhaW4xDDAKBgNVBAsT
-A0RldjELMAkGA1UEAxMCY2ExHjAcBgkqhkiG9w0BCQEWD2NhQGdyaWRnYWluLmNv
-bYIJAKmuj925215OMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAhrzd
-qusVLHO3wtyu0o+EAFyoDv5avCBTFsQLeDDPMyfDcEO6wfxhTanfH8C7gZc0rRnv
-2nbkVbfortHIOfU2wch5gClju0cXSTIXSKOAWPIMp3HLxC/l+KpFo3epFz0rsMVB
-M1ymOOdRDdAcTxcTTGY7WJXquEM3ZbT5Gh4RLDk=
------END CERTIFICATE-----
diff --git a/modules/clients/src/test/keystore/client.pfx b/modules/clients/src/test/keystore/client.pfx
deleted file mode 100644
index 494a63e..0000000
Binary files a/modules/clients/src/test/keystore/client.pfx and /dev/null differ
diff --git a/modules/clients/src/test/keystore/connectorClient.jks b/modules/clients/src/test/keystore/connectorClient.jks
new file mode 100644
index 0000000..8365b001
Binary files /dev/null and b/modules/clients/src/test/keystore/connectorClient.jks differ
diff --git a/modules/clients/src/test/keystore/connectorServer.jks b/modules/clients/src/test/keystore/connectorServer.jks
new file mode 100644
index 0000000..1021a76
Binary files /dev/null and b/modules/clients/src/test/keystore/connectorServer.jks differ
diff --git a/modules/clients/src/test/keystore/generate-ca.sh b/modules/clients/src/test/keystore/generate-ca.sh
new file mode 100755
index 0000000..bdf6fb6
--- /dev/null
+++ b/modules/clients/src/test/keystore/generate-ca.sh
@@ -0,0 +1,97 @@
+#!/bin/sh
+
+#  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.
+
+set -e
+
+pwd="123456"
+
+#
+# Create certificate authority with a specified name.
+#
+# param #1 CA name.
+#
+function createCa {
+    ca_name=$1
+
+    echo
+    echo Create a certificate signing request for ${ca_name}.
+    openssl req -new -newkey rsa:2048 -nodes -out ${ca_name}.csr -keyout ${ca_name}.key \
+        -subj "/emailAddress=${ca_name}@ignite.apache.org/CN=${ca_name}/OU=Dev/O=Ignite/L=SPb/ST=SPb/C=RU"
+
+    echo
+    echo Self-sign the CSR for ${ca_name}.
+    openssl x509 -trustout -signkey ${ca_name}.key -days 7305 -req -in ${ca_name}.csr -out ${ca_name}.pem
+
+    rm ${ca_name}.csr
+
+    echo
+    echo Create auxiliary files for ${ca_name}.
+    touch ${ca_name}-index.txt
+    echo 01 > ${ca_name}-serial
+    echo "
+#  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.
+
+[ ca ]
+default_ca = ${ca_name}
+
+[ ${ca_name} ]
+dir=ca
+certificate = \$dir/${ca_name}.pem
+database = \$dir/${ca_name}-index.txt
+private_key = \$dir/${ca_name}.key
+new_certs_dir = \$dir/certs
+default_md = sha1
+policy = policy_match
+serial = \$dir/${ca_name}-serial
+default_days = 365
+
+[policy_match]
+commonName = supplied" > ${ca_name}.cnf
+}
+
+mkdir ca
+
+cd ca
+
+createCa oneca
+createCa twoca
+createCa threeca
+
+cd ..
+
+# Create four trust stores: trust-one, trust-two, trust-three and trust-both.
+# trust-both contains keys of oneca and twoca.
+
+keytool -import -noprompt -file ca/oneca.pem -alias oneca -keypass ${pwd} -storepass ${pwd} -keystore trust-one.jks
+keytool -import -noprompt -file ca/twoca.pem -alias twoca -keypass ${pwd} -storepass ${pwd} -keystore trust-two.jks
+keytool -import -noprompt -file ca/threeca.pem -alias threeca -keypass ${pwd} -storepass ${pwd} -keystore trust-three.jks
+
+keytool -import -noprompt -file ca/oneca.pem -alias oneca -keypass ${pwd} -storepass ${pwd} -keystore trust-both.jks
+keytool -import -noprompt -file ca/twoca.pem -alias twoca -keypass ${pwd} -storepass ${pwd} -keystore trust-both.jks
diff --git a/modules/clients/src/test/keystore/generate-keys.sh b/modules/clients/src/test/keystore/generate-keys.sh
new file mode 100755
index 0000000..227ac99
--- /dev/null
+++ b/modules/clients/src/test/keystore/generate-keys.sh
@@ -0,0 +1,92 @@
+#!/bin/sh
+
+#  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.
+
+set -e
+
+pwd="123456"
+
+#
+# Create artifacts for specified name: key pair-> cert request -> ca-signed certificate.
+# Save private key and CA-signed certificate into JKS key storage.
+#
+# param $1 Artifact name.
+# param $2 Name of a certificate authority.
+# param $3 If true, then an expired certificate will be generated.
+#
+function createStore {
+	artifact=$1
+	ca_name=$2
+	expired=$3
+
+	if [[ "$expired" = true ]]; then
+        startdate=`date -d '2 days ago' '+%y%m%d%H%M%SZ'`
+        enddate=`date -d 'yesterday' '+%y%m%d%H%M%SZ'`
+    else
+        startdate=`date -d 'today 00:00:00' '+%y%m%d%H%M%SZ'`
+        enddate=`date -d 'today + 7305 days' '+%y%m%d%H%M%SZ'`
+    fi
+
+	ca_cert=ca/${ca_name}.pem
+
+	echo
+	echo Clean up all old artifacts: ${artifact}.*
+	rm -f ${artifact}.*
+
+	echo
+	echo Generate a certificate and private key pair for ${artifact}.
+	keytool -genkey -keyalg RSA -keysize 1024 \
+	        -dname "emailAddress=${artifact}@ignite.apache.org, CN=${artifact}, OU=Dev, O=Ignite, L=SPb, ST=SPb, C=RU" \
+	        -alias ${artifact} -keypass ${pwd} -keystore ${artifact}.jks -storepass ${pwd}
+
+	echo
+	echo Create a certificate signing request for ${artifact}.
+	keytool -certreq -alias ${artifact} -file ${artifact}.csr -keypass ${pwd} -keystore ${artifact}.jks -storepass ${pwd}
+
+	echo
+	echo Sign the CSR using ${ca_name}.
+	openssl ca -config ca/${ca_name}.cnf \
+	        -startdate ${startdate} -enddate ${enddate} \
+	        -batch -out ${artifact}.pem -infiles ${artifact}.csr
+
+	echo
+	echo Convert to PEM format.
+	openssl x509 -in ${artifact}.pem -out ${artifact}.pem -outform PEM
+
+	echo
+	echo Concatenate the CA certificate file and ${artifact}.pem certificate file into certificates chain.
+	cat ${artifact}.pem ${ca_cert} > ${artifact}.chain
+
+	echo
+	echo Update the keystore, ${artifact}.jks, by importing the full certificate chain for the ${artifact}.
+	keytool -import -alias ${artifact} -file ${artifact}.chain -keypass ${pwd} -noprompt -trustcacerts -keystore ${artifact}.jks -storepass ${pwd}
+
+	rm -f ${artifact}.chain ${artifact}.csr ${artifact}.pem
+}
+
+mkdir -p ca/certs
+
+createStore client oneca
+createStore server oneca
+createStore thinClient twoca
+createStore thinServer twoca
+createStore connectorClient threeca
+createStore connectorServer threeca
+
+createStore node01 oneca
+createStore node02 twoca
+createStore node03 twoca
+createStore node02old twoca true
diff --git a/modules/clients/src/test/keystore/generate.sh b/modules/clients/src/test/keystore/generate.sh
deleted file mode 100644
index 9b1d6fa..0000000
--- a/modules/clients/src/test/keystore/generate.sh
+++ /dev/null
@@ -1,99 +0,0 @@
-#!/bin/sh
-#
-# 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.
-#
-# Initialize openssl & CA.
-#
-# Instruction: https://access.redhat.com/documentation/en-US/Red_Hat_JBoss_Fuse/6.0/html/Web_Services_Security_Guide/files/i305191.html
-#
-
-# Path to CA certificate.
-ca_cert=/usr/ssl/ca/ca.pem
-
-#
-# Create artifacts for specified name: key pair-> cert request -> ca-signed certificate.
-# Save private key and CA-signed certificate into key storages: PEM, JKS, PFX (PKCS12).
-#
-# param $1 Artifact name.
-# param $2 Password for all keys and storages.
-#
-function createStore {
-	artifact=$1
-	pwd=$2
-
-	echo
-	echo Clean up all old artifacts: ${artifact}.*
-	rm -f ${artifact}.*
-
-	echo
-	echo Generate a certificate and private key pair for ${artifact}.
-	keytool -genkey -keyalg RSA -keysize 1024 -dname "emailAddress=${artifact}@ignite.com, CN=${artifact}, OU=Dev, O=Ignite, L=SPb, ST=SPb, C=RU" -validity 7305 -alias ${artifact} -keypass ${pwd} -keystore ${artifact}.jks -storepass ${pwd}
-
-	echo
-	echo Create a certificate signing request for ${artifact}.
-	keytool -certreq -alias ${artifact} -file ${artifact}.csr -keypass ${pwd} -keystore ${artifact}.jks -storepass ${pwd}
-
-	echo
-	echo "Sign the CSR using CA (default SSL configuration)."
-	openssl ca -days 7305 -in ${artifact}.csr -out ${artifact}.pem
-
-	echo
-	echo Convert to PEM format.
-	openssl x509 -in ${artifact}.pem -out ${artifact}.pem -outform PEM
-
-	echo
-	echo Concatenate the CA certificate file and ${artifact}.pem certificate file into certificates chain.
-	cat ${artifact}.pem ${ca_cert} > ${artifact}.chain
-
-	echo
-	echo Update the keystore, ${artifact}.jks, by importing the CA certificate.
-	keytool -import -alias ca          -file ${ca_cert} -keypass ${pwd} -noprompt -trustcacerts -keystore ${artifact}.jks -storepass ${pwd}
-
-	echo
-	echo Update the keystore, ${artifact}.jks, by importing the full certificate chain for the ${artifact}.
-	keytool -import -alias ${artifact} -file ${artifact}.chain -keypass ${pwd} -noprompt -trustcacerts -keystore ${artifact}.jks -storepass ${pwd}
-
-	echo
-	echo Generate PKCS12 storage for the private key and certificate chain.
-	keytool -importkeystore \
-		-srcstoretype JKS -deststoretype PKCS12 \
-		-srckeystore ${artifact}.jks -destkeystore ${artifact}.pfx \
-		-srcstorepass ${pwd} -deststorepass ${pwd} \
-		-srcalias ${artifact} -destalias ${artifact} \
-		-srckeypass ${pwd} -destkeypass ${pwd} \
-		-noprompt
-
-	echo
-	echo Generate PEM storage for the private key and certificate chain.
-	openssl pkcs12 \
-		-in ${artifact}.pfx -out ${artifact}.pem \
-		-passin pass:${pwd} -passout pass:${pwd}
-
-	rm -f ${artifact}.chain ${artifact}.csr
-}
-
-pwd="123456"
-
-createStore "client" ${pwd}
-createStore "server" ${pwd}
-
-echo
-echo Update trust store with certificates: CA, client, server.
-keytool -import -alias ca -file ${ca_cert} -keypass ${pwd} -noprompt -trustcacerts -keystore trust.jks -storepass ${pwd}
-#keytool -importkeystore -srckeystore client.jks -destkeystore trust.jks -srcstorepass ${pwd} -deststorepass ${pwd} -alias client -noprompt
-#keytool -importkeystore -srckeystore server.jks -destkeystore trust.jks -srcstorepass ${pwd} -deststorepass ${pwd} -alias server -noprompt
-keytool -export -alias client -keystore client.jks -storepass ${pwd} | keytool -importcert -alias client -noprompt -keystore trust.jks -storepass ${pwd}
-keytool -export -alias server -keystore server.jks -storepass ${pwd} | keytool -importcert -alias server -noprompt -keystore trust.jks -storepass ${pwd}
diff --git a/modules/clients/src/test/keystore/node01.jks b/modules/clients/src/test/keystore/node01.jks
new file mode 100644
index 0000000..2f3d58e
Binary files /dev/null and b/modules/clients/src/test/keystore/node01.jks differ
diff --git a/modules/clients/src/test/keystore/node02.jks b/modules/clients/src/test/keystore/node02.jks
new file mode 100644
index 0000000..7bab71b
Binary files /dev/null and b/modules/clients/src/test/keystore/node02.jks differ
diff --git a/modules/clients/src/test/keystore/node02old.jks b/modules/clients/src/test/keystore/node02old.jks
new file mode 100644
index 0000000..fcfacd0
Binary files /dev/null and b/modules/clients/src/test/keystore/node02old.jks differ
diff --git a/modules/clients/src/test/keystore/node03.jks b/modules/clients/src/test/keystore/node03.jks
new file mode 100644
index 0000000..91395da
Binary files /dev/null and b/modules/clients/src/test/keystore/node03.jks differ
diff --git a/modules/clients/src/test/keystore/server.jks b/modules/clients/src/test/keystore/server.jks
index 006ecec..e89c563 100644
Binary files a/modules/clients/src/test/keystore/server.jks and b/modules/clients/src/test/keystore/server.jks differ
diff --git a/modules/clients/src/test/keystore/server.pem b/modules/clients/src/test/keystore/server.pem
deleted file mode 100644
index b8d2174..0000000
--- a/modules/clients/src/test/keystore/server.pem
+++ /dev/null
@@ -1,69 +0,0 @@
-Bag Attributes
-    friendlyName: server
-    localKeyID: 54 69 6D 65 20 31 33 33 39 32 33 39 38 36 35 34 32 34 
-Key Attributes: <No Attributes>
------BEGIN RSA PRIVATE KEY-----
-Proc-Type: 4,ENCRYPTED
-DEK-Info: DES-EDE3-CBC,FA0E52C780B7D5E8
-
-3B9LjnvxRjASvnPUp3c6ICSk02znhERV1XRQLRR7rhGnMJVI1FJHzRFJsLTmOE/B
-irHCzKtOAw3MDlDhRoAncLiZcvaoUwzWCU2SZ0IS7ERLi+wDoV22ftGfXV815x0Y
-L2ut3BatgkzFpY6QUGK9ReEenLfZ6AfGhImjAubYvPr1Z3q+fk5ZoNz9Z9ZgpmEX
-BfQb1A1XHXvlu/dUXdn46t2DSpYD7RgqTRKCmCJeerWrZak2CwvCCIPC5w0+IHbT
-nBTyTquhig3bbsybZHjnNsttLeBPQrhnc0K+ydbNDcHS3OQB7sqPYce5fz2Y2dnF
-Adva9r7o9K06e3P0/TSTyHQJyHiFsns157wBOXElRQvGGi8XtDaKHIYIJROeRbKU
-2kRYcDOdwN7aRt9k3q7Jo52IyHQ78asL1f1kN4kt1IHl5CVFMPyWPgXeSj+hMzOF
-hkV0dWfSX8ZdIZOVzFMZOrqf5dXzAGs3GIbkaWX2lG5DWVnVobch82kDuTYnCIJs
-9N7VwwptUCsYqM5WWDo1OUYfvljEhoYyIXNxhn94Fe2lIXYttymsaIW/Dt/rwh9K
-ukKGOnehtayNQKaOtiWfnqUxHLJTUZOTGd3ImJQb6A/Ygs79xO1xeWPlYQilNdEN
-A/d2x6Auo3P0Axf+FMMNZDfuXzd02FAnYWz2McQT8RXCG0/CIsrYTydVnFRyXTrM
-/AjzPgp54r9l3/xBg1GSPwjKb75Vsw4WMG0HUDvBRIGTw3tr3+ng30/JtN93H7Ga
-TMqUuOzG1qgRhT0yFUz5pknGesjTnVKzd9TbYD9KtuNHFsTC+7y5Hw==
------END RSA PRIVATE KEY-----
-Bag Attributes
-    friendlyName: 1.2.840.113549.1.9.1=#161373657276657240677269646761696e2e636f6d,CN=server,OU=Dev,O=GridGain,ST=SPb,C=RU
-    localKeyID: 54 69 6D 65 20 31 33 33 39 32 33 39 38 36 35 34 32 34 
-subject=/C=RU/ST=SPb/O=GridGain/OU=Dev/CN=server/emailAddress=server@gridgain.com
-issuer=/C=RU/ST=SPb/L=SPb/O=GridGain/OU=Dev/CN=ca/emailAddress=ca@gridgain.com
------BEGIN CERTIFICATE-----
-MIIC2TCCAkKgAwIBAgIBJTANBgkqhkiG9w0BAQUFADB3MQswCQYDVQQGEwJSVTEM
-MAoGA1UECBMDU1BiMQwwCgYDVQQHEwNTUGIxETAPBgNVBAoTCEdyaWRHYWluMQww
-CgYDVQQLEwNEZXYxCzAJBgNVBAMTAmNhMR4wHAYJKoZIhvcNAQkBFg9jYUBncmlk
-Z2Fpbi5jb20wHhcNMTIwNjA5MTEwNDIyWhcNMzIwNjA5MTEwNDIyWjBxMQswCQYD
-VQQGEwJSVTEMMAoGA1UECBMDU1BiMREwDwYDVQQKEwhHcmlkR2FpbjEMMAoGA1UE
-CxMDRGV2MQ8wDQYDVQQDEwZzZXJ2ZXIxIjAgBgkqhkiG9w0BCQEWE3NlcnZlckBn
-cmlkZ2Fpbi5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANb9uaho52Cs
-V5qd70ID38ElGyLH7ac366biFypx9wdkqtie8H8qNjm+JUpHQnDqfxFEh8Pnny6K
-ytLd8yvtvBibWXFOCxwPw1xCf63q+vMGGnrz6T9uv3L2JDUNhexuLycei8Uf6K6J
-jvstGKOSD4uvA5USzn2Hf1yJrEAL5nfVAgMBAAGjezB5MAkGA1UdEwQCMAAwLAYJ
-YIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1Ud
-DgQWBBSEo9T8PK4ZFCB6lCQ1Vheyop8sMjAfBgNVHSMEGDAWgBS1+Ah4ZG58tImL
-KqLVX+xBKbeFUTANBgkqhkiG9w0BAQUFAAOBgQCv9LKixciXDP4p2grYGBoE3WMG
-Du1S+seCrg+NGcRihtQEwGCwYZ8O2UHtqjKeBeKe8wLo8X+niUdjUO3pFftsQhg4
-iMViBxlEXtnGGi+UAm4m2F9SDsPmyHZ4BWxjD/n49HhU4ZFure6BySkx5l59oyPp
-Yj+nsBrWq7aK4tD7sg==
------END CERTIFICATE-----
-Bag Attributes
-    friendlyName: 1.2.840.113549.1.9.1=#160f636140677269646761696e2e636f6d,CN=ca,OU=Dev,O=GridGain,L=SPb,ST=SPb,C=RU
-subject=/C=RU/ST=SPb/L=SPb/O=GridGain/OU=Dev/CN=ca/emailAddress=ca@gridgain.com
-issuer=/C=RU/ST=SPb/L=SPb/O=GridGain/OU=Dev/CN=ca/emailAddress=ca@gridgain.com
------BEGIN CERTIFICATE-----
-MIIDSTCCArKgAwIBAgIJAKmuj925215OMA0GCSqGSIb3DQEBBQUAMHcxCzAJBgNV
-BAYTAlJVMQwwCgYDVQQIEwNTUGIxDDAKBgNVBAcTA1NQYjERMA8GA1UEChMIR3Jp
-ZEdhaW4xDDAKBgNVBAsTA0RldjELMAkGA1UEAxMCY2ExHjAcBgkqhkiG9w0BCQEW
-D2NhQGdyaWRnYWluLmNvbTAeFw0xMjA2MDkwNjU1MTJaFw0zMjA2MDQwNjU1MTJa
-MHcxCzAJBgNVBAYTAlJVMQwwCgYDVQQIEwNTUGIxDDAKBgNVBAcTA1NQYjERMA8G
-A1UEChMIR3JpZEdhaW4xDDAKBgNVBAsTA0RldjELMAkGA1UEAxMCY2ExHjAcBgkq
-hkiG9w0BCQEWD2NhQGdyaWRnYWluLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAw
-gYkCgYEAtd16DCObyM63NKF/cvRcE+8cr1dc3c7mSnTEQ61WfqPJ2QqsQAB6e+5+
-q9Np1SaJyqFTTag6483ibrU+DkGPGgEXndRHtQHQPbStWsf47DBBW2bMi6+bkPox
-Cp6BhYO1DQUG5tP9CQ/g32mLQLB7LH0KtS1JcKpAClCjjWZC8b8CAwEAAaOB3DCB
-2TAdBgNVHQ4EFgQUtfgIeGRufLSJiyqi1V/sQSm3hVEwgakGA1UdIwSBoTCBnoAU
-tfgIeGRufLSJiyqi1V/sQSm3hVGhe6R5MHcxCzAJBgNVBAYTAlJVMQwwCgYDVQQI
-EwNTUGIxDDAKBgNVBAcTA1NQYjERMA8GA1UEChMIR3JpZEdhaW4xDDAKBgNVBAsT
-A0RldjELMAkGA1UEAxMCY2ExHjAcBgkqhkiG9w0BCQEWD2NhQGdyaWRnYWluLmNv
-bYIJAKmuj925215OMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAhrzd
-qusVLHO3wtyu0o+EAFyoDv5avCBTFsQLeDDPMyfDcEO6wfxhTanfH8C7gZc0rRnv
-2nbkVbfortHIOfU2wch5gClju0cXSTIXSKOAWPIMp3HLxC/l+KpFo3epFz0rsMVB
-M1ymOOdRDdAcTxcTTGY7WJXquEM3ZbT5Gh4RLDk=
------END CERTIFICATE-----
diff --git a/modules/clients/src/test/keystore/server.pfx b/modules/clients/src/test/keystore/server.pfx
deleted file mode 100644
index 798e2f9..0000000
Binary files a/modules/clients/src/test/keystore/server.pfx and /dev/null differ
diff --git a/modules/clients/src/test/keystore/thinClient.jks b/modules/clients/src/test/keystore/thinClient.jks
new file mode 100644
index 0000000..f370bfa
Binary files /dev/null and b/modules/clients/src/test/keystore/thinClient.jks differ
diff --git a/modules/clients/src/test/keystore/thinServer.jks b/modules/clients/src/test/keystore/thinServer.jks
new file mode 100644
index 0000000..e88faf4
Binary files /dev/null and b/modules/clients/src/test/keystore/thinServer.jks differ
diff --git a/modules/clients/src/test/keystore/trust-both.jks b/modules/clients/src/test/keystore/trust-both.jks
new file mode 100644
index 0000000..69b729e
Binary files /dev/null and b/modules/clients/src/test/keystore/trust-both.jks differ
diff --git a/modules/clients/src/test/keystore/trust-one.jks b/modules/clients/src/test/keystore/trust-one.jks
new file mode 100644
index 0000000..4b76a4d
Binary files /dev/null and b/modules/clients/src/test/keystore/trust-one.jks differ
diff --git a/modules/clients/src/test/keystore/trust-three.jks b/modules/clients/src/test/keystore/trust-three.jks
new file mode 100644
index 0000000..aee225b
Binary files /dev/null and b/modules/clients/src/test/keystore/trust-three.jks differ
diff --git a/modules/clients/src/test/keystore/trust-two.jks b/modules/clients/src/test/keystore/trust-two.jks
new file mode 100644
index 0000000..bf25562
Binary files /dev/null and b/modules/clients/src/test/keystore/trust-two.jks differ
diff --git a/modules/clients/src/test/keystore/trust.jks b/modules/clients/src/test/keystore/trust.jks
deleted file mode 100644
index a00f125..0000000
Binary files a/modules/clients/src/test/keystore/trust.jks and /dev/null differ
diff --git a/modules/clients/src/test/resources/jetty/rest-jetty-ssl.xml b/modules/clients/src/test/resources/jetty/rest-jetty-ssl.xml
index eb4daf6..77f9471 100644
--- a/modules/clients/src/test/resources/jetty/rest-jetty-ssl.xml
+++ b/modules/clients/src/test/resources/jetty/rest-jetty-ssl.xml
@@ -42,7 +42,7 @@
         <Set name="keyStorePath"><SystemProperty name="CLIENTS_MODULE_PATH"/>/src/test/keystore/server.jks</Set>
         <Set name="keyStorePassword">123456</Set>
         <Set name="keyManagerPassword">123456</Set>
-        <Set name="trustStorePath"><SystemProperty name="CLIENTS_MODULE_PATH"/>/src/test/keystore/trust.jks</Set>
+        <Set name="trustStorePath"><SystemProperty name="CLIENTS_MODULE_PATH"/>/src/test/keystore/trust-one.jks</Set>
         <Set name="trustStorePassword">123456</Set>
     </New>
 
diff --git a/modules/clients/src/test/resources/jetty/router-jetty-ssl.xml b/modules/clients/src/test/resources/jetty/router-jetty-ssl.xml
index 287c184..564989c 100644
--- a/modules/clients/src/test/resources/jetty/router-jetty-ssl.xml
+++ b/modules/clients/src/test/resources/jetty/router-jetty-ssl.xml
@@ -42,7 +42,7 @@
         <Set name="keyStorePath"><SystemProperty name="CLIENTS_MODULE_PATH"/>/src/test/keystore/server.jks</Set>
         <Set name="keyStorePassword">123456</Set>
         <Set name="keyManagerPassword">123456</Set>
-        <Set name="trustStorePath"><SystemProperty name="CLIENTS_MODULE_PATH"/>/src/test/keystore/trust.jks</Set>
+        <Set name="trustStorePath"><SystemProperty name="CLIENTS_MODULE_PATH"/>/src/test/keystore/trust-one.jks</Set>
         <Set name="trustStorePassword">123456</Set>
     </New>
 
diff --git a/modules/clients/src/test/resources/spring-router-ssl.xml b/modules/clients/src/test/resources/spring-router-ssl.xml
index efd03fb..6f092f6 100644
--- a/modules/clients/src/test/resources/spring-router-ssl.xml
+++ b/modules/clients/src/test/resources/spring-router-ssl.xml
@@ -86,7 +86,7 @@
             <bean class="org.apache.ignite.internal.client.ssl.GridSslBasicContextFactory">
                 <property name="keyStoreFilePath" value="${CLIENTS_MODULE_PATH}/src/test/keystore/server.jks"/>
                 <property name="keyStorePassword" value="123456"/>
-                <property name="trustStoreFilePath" value="${CLIENTS_MODULE_PATH}/src/test/keystore/trust.jks"/>
+                <property name="trustStoreFilePath" value="${CLIENTS_MODULE_PATH}/src/test/keystore/trust-one.jks"/>
                 <property name="trustStorePassword" value="123456"/>
             </bean>
         </property>
diff --git a/modules/clients/src/test/resources/spring-server-ssl-node.xml b/modules/clients/src/test/resources/spring-server-ssl-node.xml
index 05b1d51..d71540d 100644
--- a/modules/clients/src/test/resources/spring-server-ssl-node.xml
+++ b/modules/clients/src/test/resources/spring-server-ssl-node.xml
@@ -72,7 +72,7 @@
                     <bean class="org.apache.ignite.internal.client.ssl.GridSslBasicContextFactory">
                         <property name="keyStoreFilePath" value="${CLIENTS_MODULE_PATH}/src/test/keystore/server.jks"/>
                         <property name="keyStorePassword" value="123456"/>
-                        <property name="trustStoreFilePath" value="${CLIENTS_MODULE_PATH}/src/test/keystore/trust.jks"/>
+                        <property name="trustStoreFilePath" value="${CLIENTS_MODULE_PATH}/src/test/keystore/trust-one.jks"/>
                         <property name="trustStorePassword" value="123456"/>
                     </bean>
                 </property>
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 47aad6e..7fe7c6f 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
@@ -28,6 +28,7 @@ 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;
@@ -41,8 +42,10 @@ import org.apache.ignite.IgniteException;
 import org.apache.ignite.internal.util.typedef.internal.A;
 
 /**
- * This SSL context factory that provides ssl context configuration with specified key
- * and trust stores.
+ * SSL context factory that provides SSL context configuration with specified key and trust stores.
+ *
+ * This factory 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 SslContextFactory#create()}} method.
  * <p>
  * In some cases it is useful to disable certificate validation of client side (e.g. when connecting
  * to a server with self-signed certificate). This can be achieved by setting a disabled trust manager
@@ -99,6 +102,9 @@ public class SslContextFactory implements Factory<SSLContext> {
     /** Enabled protocols. */
     private String[] protocols;
 
+    /** Cached instance of an {@link SSLContext}. */
+    private final AtomicReference<SSLContext> sslCtx = new AtomicReference<>();
+
     /**
      * Gets key store type used for context creation.
      *
@@ -531,11 +537,20 @@ public class SslContextFactory implements Factory<SSLContext> {
 
     /** {@inheritDoc} */
     @Override public SSLContext create() {
-        try {
-            return createSslContext();
-        }
-        catch (SSLException e) {
-            throw new IgniteException(e);
+        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/test/config/tests.properties b/modules/core/src/test/config/tests.properties
index a8e446f..d659224 100644
--- a/modules/core/src/test/config/tests.properties
+++ b/modules/core/src/test/config/tests.properties
@@ -144,13 +144,24 @@ ssl.keystore.client.path=@{IGNITE_HOME}/modules/clients/src/test/keystore/client
 
 # node01 signed with trust-one, node02 and node03 by trust-two, node02old is expired
 # trust-both contains both CAs
-ssl.keystore.node01.path=@{IGNITE_HOME}/modules/clients/src/test/keystore/ca/node01.jks
-ssl.keystore.node02.path=@{IGNITE_HOME}/modules/clients/src/test/keystore/ca/node02.jks
-ssl.keystore.node03.path=@{IGNITE_HOME}/modules/clients/src/test/keystore/ca/node03.jks
-ssl.keystore.trustone.path=@{IGNITE_HOME}/modules/clients/src/test/keystore/ca/trust-one.jks
-ssl.keystore.trusttwo.path=@{IGNITE_HOME}/modules/clients/src/test/keystore/ca/trust-two.jks
-ssl.keystore.trustboth.path=@{IGNITE_HOME}/modules/clients/src/test/keystore/ca/trust-both.jks
-ssl.keystore.node02old.path=@{IGNITE_HOME}/modules/clients/src/test/keystore/ca/node02old.jks
+ssl.keystore.node01.path=@{IGNITE_HOME}/modules/clients/src/test/keystore/node01.jks
+ssl.keystore.node02.path=@{IGNITE_HOME}/modules/clients/src/test/keystore/node02.jks
+ssl.keystore.node02old.path=@{IGNITE_HOME}/modules/clients/src/test/keystore/node02old.jks
+ssl.keystore.node03.path=@{IGNITE_HOME}/modules/clients/src/test/keystore/node03.jks
+
+# Cluster certificate is signed by trust-one, thinServer and thinClient – by trust-two,
+# connectorServer and connectorClient – by trust-three.
+ssl.keystore.server.path=@{IGNITE_HOME}/modules/clients/src/test/keystore/server.jks
+ssl.keystore.client.path=@{IGNITE_HOME}/modules/clients/src/test/keystore/client.jks
+ssl.keystore.thinServer.path=@{IGNITE_HOME}/modules/clients/src/test/keystore/thinServer.jks
+ssl.keystore.thinClient.path=@{IGNITE_HOME}/modules/clients/src/test/keystore/thinClient.jks
+ssl.keystore.connectorServer.path=@{IGNITE_HOME}/modules/clients/src/test/keystore/connectorServer.jks
+ssl.keystore.connectorClient.path=@{IGNITE_HOME}/modules/clients/src/test/keystore/connectorClient.jks
+
+ssl.keystore.trustone.path=@{IGNITE_HOME}/modules/clients/src/test/keystore/trust-one.jks
+ssl.keystore.trusttwo.path=@{IGNITE_HOME}/modules/clients/src/test/keystore/trust-two.jks
+ssl.keystore.trustboth.path=@{IGNITE_HOME}/modules/clients/src/test/keystore/trust-both.jks
+ssl.keystore.trustthree.path=@{IGNITE_HOME}/modules/clients/src/test/keystore/trust-three.jks
 
 # Hadoop home directory.
 hadoop.home=@{HADOOP_HOME}
diff --git a/modules/core/src/test/java/org/apache/ignite/ssl/MultipleSSLContextsTest.java b/modules/core/src/test/java/org/apache/ignite/ssl/MultipleSSLContextsTest.java
new file mode 100644
index 0000000..414eb66
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/ssl/MultipleSSLContextsTest.java
@@ -0,0 +1,263 @@
+/*
+ * 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.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.cache.configuration.Factory;
+import javax.net.ssl.SSLContext;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.Ignition;
+import org.apache.ignite.client.ClientCache;
+import org.apache.ignite.client.ClientException;
+import org.apache.ignite.client.IgniteClient;
+import org.apache.ignite.client.SslMode;
+import org.apache.ignite.configuration.ClientConfiguration;
+import org.apache.ignite.configuration.ClientConnectorConfiguration;
+import org.apache.ignite.configuration.ConnectorConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.commandline.CommandHandler;
+import org.apache.ignite.testframework.GridTestUtils;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.junit.Test;
+
+import static org.apache.ignite.internal.commandline.CommandHandler.EXIT_CODE_OK;
+
+/**
+ * Test SSL configuration, where certificates for nodes, connectors and client connectors are signed using different
+ * trust stores. SSL for all three transports are enabled at the same time.
+ */
+public class MultipleSSLContextsTest extends GridCommonAbstractTest {
+    /** */
+    private boolean clientMode = false;
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
+        IgniteConfiguration igniteCfg = super.getConfiguration(igniteInstanceName);
+
+        if (clientMode) {
+            igniteCfg.setClientMode(true);
+
+            igniteCfg.setSslContextFactory(clientSSLFactory());
+        }
+        else
+            igniteCfg.setSslContextFactory(serverSSLFactory());
+
+        ClientConnectorConfiguration clientConnectorCfg = new ClientConnectorConfiguration()
+            .setSslEnabled(true)
+            .setSslClientAuth(true)
+            .setUseIgniteSslContextFactory(false)
+            .setSslContextFactory(clientConnectorSSLFactory());
+        igniteCfg.setClientConnectorConfiguration(clientConnectorCfg);
+
+        ConnectorConfiguration connectorConfiguration = new ConnectorConfiguration()
+            .setSslEnabled(true)
+            .setSslFactory(connectorSSLFactory());
+        igniteCfg.setConnectorConfiguration(connectorConfiguration);
+
+        return igniteCfg;
+    }
+
+    /**
+     * @return SSL context factory to use on server nodes for communication between nodes in a cluster.
+     */
+    private Factory<SSLContext> serverSSLFactory() {
+        return GridTestUtils.sslTrustedFactory("server", "trustone");
+    }
+
+    /**
+     * @return SSL context factory to use on client nodes for communication between nodes in a cluster.
+     */
+    private Factory<SSLContext> clientSSLFactory() {
+        return GridTestUtils.sslTrustedFactory("client", "trustone");
+    }
+
+    /**
+     * @return SSL context factory to use in client connectors.
+     */
+    private Factory<SSLContext> clientConnectorSSLFactory() {
+        return GridTestUtils.sslTrustedFactory("thinServer", "trusttwo");
+    }
+
+    /**
+     * @return SSL context factory to use in thin clients.
+     */
+    private Factory<SSLContext> thinClientSSLFactory() {
+        return GridTestUtils.sslTrustedFactory("thinClient", "trusttwo");
+    }
+
+    /**
+     * @param addr Address of a node to connect to.
+     * @return {@link ClientConfiguration} that can be used to start a thin client.
+     */
+    private ClientConfiguration clientConfiguration(String addr) {
+        ClientConfiguration clientCfg = new ClientConfiguration().setAddresses(addr);
+        clientCfg.setSslContextFactory(thinClientSSLFactory());
+        clientCfg.setSslMode(SslMode.REQUIRED);
+
+        return clientCfg;
+    }
+
+    /**
+     * @return SSL context factory to use in client connectors.
+     */
+    private Factory<SSLContext> connectorSSLFactory() {
+        return GridTestUtils.sslTrustedFactory("connectorServer", "trustthree");
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTestsStarted() throws Exception {
+        clientMode = false;
+        startGrids(3);
+    }
+
+    /**
+     * Checks that thick clients with SSL enabled can join the cluster and perform some work on it.
+     *
+     * @throws Exception If failed.
+     */
+    @Test
+    public void testThickClients() throws Exception {
+        int clientsNum = 3;
+        int keysNum = 1000;
+        String cacheName = "thickClientCache";
+
+        List<Ignite> clients = new ArrayList<>(clientsNum);
+
+        clientMode = true;
+
+        try {
+            for (int i = 0; i < clientsNum; i++)
+                clients.add(startGrid("client" + i));
+
+            Map<Integer, Integer> expMap = new HashMap<>();
+
+            for (int i = 0; i < keysNum; i++) {
+                int clientId = keysNum % clientsNum;
+
+                IgniteCache<Integer, Integer> cache = clients.get(clientId).getOrCreateCache(cacheName);
+
+                cache.put(i, i);
+                expMap.put(i, i);
+            }
+
+            IgniteCache<Integer, Integer> cache = grid(0).cache(cacheName);
+
+            assertCacheContent(expMap, cache);
+        }
+        finally {
+            for (Ignite client : clients)
+                client.close();
+
+            IgniteCache cache = grid(0).cache(cacheName);
+
+            if (cache != null)
+                cache.destroy();
+        }
+    }
+
+    /**
+     * Checks that thin clients with SSL enabled can join the cluster and perform some work on it.
+     *
+     * @throws Exception If failed.
+     */
+    @Test
+    public void testThinClients() throws Exception {
+        int clientsNum = 3;
+        int keysNum = 1000;
+        String cacheName = "thinClientCache";
+
+        List<IgniteClient> clients = new ArrayList<>(clientsNum);
+
+        try {
+            for (int i = 0; i < clientsNum; i++) {
+                IgniteClient client = Ignition.startClient(clientConfiguration("127.0.0.1:1080" + i));
+
+                clients.add(client);
+            }
+
+            Map<Integer, Integer> expMap = new HashMap<>();
+
+            for (int i = 0; i < keysNum; i++) {
+                int clientId = keysNum % clientsNum;
+
+                ClientCache<Integer, Integer> cache = clients.get(clientId).getOrCreateCache(cacheName);
+
+                cache.put(i, i);
+                expMap.put(i, i);
+            }
+
+            IgniteCache<Integer, Integer> cache = grid(0).cache(cacheName);
+
+            assertCacheContent(expMap, cache);
+        }
+        catch (ClientException ex) {
+            ex.printStackTrace();
+
+            fail("Failed to start thin Java clients: " + ex.getMessage());
+        }
+        finally {
+            for (IgniteClient client : clients)
+                client.close();
+
+            IgniteCache cache = grid(0).cache(cacheName);
+
+            if (cache != null)
+                cache.destroy();
+        }
+    }
+
+    /**
+     * Checks that control.sh script can connect to the cluster, that has SSL enabled.
+     */
+    @Test
+    public void testConnector() {
+        CommandHandler hnd = new CommandHandler();
+
+        int exitCode = hnd.execute(Arrays.asList(
+            "--state",
+            "--keystore", GridTestUtils.keyStorePath("connectorClient"),
+            "--keystore-password", GridTestUtils.keyStorePassword(),
+            "--truststore", GridTestUtils.keyStorePath("trustthree"),
+            "--truststore-password", GridTestUtils.keyStorePassword()));
+
+        assertEquals(EXIT_CODE_OK, exitCode);
+    }
+
+    /**
+     * Checks that the {@code cache} has contents that math the provided map.
+     *
+     * @param exp A map with expected contents.
+     * @param cache A cache to check.
+     */
+    private void assertCacheContent(Map<Integer, Integer> exp, IgniteCache<Integer, Integer> cache) {
+        assertEquals("Cache has an unexpected size.", exp.size(), cache.size());
+
+        for (Map.Entry<Integer, Integer> e : exp.entrySet()) {
+            int key = e.getKey();
+            Integer expVal = e.getValue();
+            Integer actVal = cache.get(key);
+
+            assertEquals("Cache contains an unexpected value for a key=" + key, expVal, actVal);
+        }
+    }
+}
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/SecurityTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testsuites/SecurityTestSuite.java
index 1e2d7fa..b38f491 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/SecurityTestSuite.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/SecurityTestSuite.java
@@ -47,6 +47,7 @@ import org.apache.ignite.internal.processors.security.sandbox.DataStreamerSandbo
 import org.apache.ignite.internal.processors.security.sandbox.DoPrivilegedOnRemoteNodeTest;
 import org.apache.ignite.internal.processors.security.sandbox.IgniteOperationsInsideSandboxTest;
 import org.apache.ignite.internal.processors.security.sandbox.SecuritySubjectPermissionsTest;
+import org.apache.ignite.ssl.MultipleSSLContextsTest;
 import org.junit.runner.RunWith;
 import org.junit.runners.Suite;
 
@@ -87,7 +88,8 @@ import org.junit.runners.Suite;
     SecuritySubjectPermissionsTest.class,
     AccessToClassesInsideInternalPackageTest.class,
     IgniteSecurityProcessorTest.class,
-    GridCommandHandlerSslWithSecurityTest.class
+    GridCommandHandlerSslWithSecurityTest.class,
+    MultipleSSLContextsTest.class
 })
 public class SecurityTestSuite {
 }