BAEL-7340 Using Custom TrustStore in Java (#15562)

* BAEL-6953 implemented

* BAEL-6953 added live test

* Fixed test

* BAEL-7340 Using Custom TrustStore in Java

* BAEL-7340 Added explicit --add-exports statement for core-java-security-4
This commit is contained in:
Mikhail Polivakha 2024-01-09 06:08:14 +03:00 committed by GitHub
parent b467eb65f6
commit 7a14fcdb32
5 changed files with 176 additions and 0 deletions

View File

@ -31,4 +31,30 @@
<cryptacular.version>1.2.6</cryptacular.version> <cryptacular.version>1.2.6</cryptacular.version>
</properties> </properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.1.2</version>
<configuration>
<argLine>--add-opens java.base/sun.security.x509=ALL-UNNAMED</argLine>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<target>17</target>
<source>17</source>
<compilerArgs>
<arg>--add-exports</arg>
<arg>java.base/sun.security.x509=ALL-UNNAMED</arg>
</compilerArgs>
</configuration>
</plugin>
</plugins>
</build>
</project> </project>

View File

@ -0,0 +1,87 @@
package com.baeldung.multiple_truststores;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
public class SslContextConfigurer {
public static X509TrustManager addAdditionalTrustStore(String trustStoreLocation, String trustStorePassword)
throws NoSuchAlgorithmException, KeyStoreException, CertificateException, IOException, KeyManagementException {
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init((KeyStore) null);
X509TrustManager defaultX509CertificateTrustManager = null;
for (TrustManager trustManager : trustManagerFactory.getTrustManagers()) {
if (trustManager instanceof X509TrustManager) {
defaultX509CertificateTrustManager = (X509TrustManager) trustManager;
break;
}
}
try (InputStream myKeys = SslContextConfigurer.class.getClassLoader().getResourceAsStream(trustStoreLocation)) {
KeyStore myTrustStore = KeyStore.getInstance(KeyStore.getDefaultType());
myTrustStore.load(myKeys, trustStorePassword.toCharArray());
trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(myTrustStore);
X509TrustManager myTrustManager = null;
for (TrustManager tm : trustManagerFactory.getTrustManagers()) {
if (tm instanceof X509TrustManager) {
myTrustManager = (X509TrustManager) tm;
break;
}
}
final X509TrustManager finalDefaultTm = defaultX509CertificateTrustManager;
final X509TrustManager finalMyTm = myTrustManager;
X509TrustManager wrapper = new X509TrustManager() {
private X509Certificate[] mergeCertificates() {
ArrayList<X509Certificate> resultingCerts = new ArrayList<>();
resultingCerts.addAll(Arrays.asList(finalDefaultTm.getAcceptedIssuers()));
resultingCerts.addAll(Arrays.asList(finalMyTm.getAcceptedIssuers()));
return resultingCerts.toArray(new X509Certificate[resultingCerts.size()]);
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return mergeCertificates();
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
try {
finalMyTm.checkServerTrusted(chain, authType);
} catch (CertificateException e) {
finalDefaultTm.checkServerTrusted(chain, authType);
}
}
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
finalDefaultTm.checkClientTrusted(mergeCertificates(), authType);
}
};
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[] { wrapper }, null);
SSLContext.setDefault(sslContext);
return wrapper;
}
}
}

View File

@ -0,0 +1,31 @@
-----BEGIN CERTIFICATE-----
MIIFYTCCBEmgAwIBAgISBF19/wT1rCVfNkni8qzXVDQHMA0GCSqGSIb3DQEBCwUA
MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD
EwJSMzAeFw0yMzAyMDcxNjI1MzFaFw0yMzA1MDgxNjI1MzBaMBkxFzAVBgNVBAMT
DmFsZW5rYS5jYXBpdGFsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
42xLbY0Xby6wz97gMeojVQF5EorW5GOuF0tvokXaBm7R5evhat/nRjYfO4MvFC/9
McP6/+AfrIy8z/xsFe8JZ1WlNdkZj5Y60HAvVct53DPMdQlZlUxWDn+LnlXw7YcV
Vh2I9Lfucn88zmEupUfpfgCzAQISKhic6aBLHsxsz+j7jM1toHnf1Bj/rSnjBO+J
B1yFqkE/Js+NBJy2SwhQDsimtkz/hezAesEO0Yfl5WpBqIgEkoA/7esuNvlmcelT
lsFynvD72dX9zP+qIptX/59F/MzKKyskeAIQI3O+gM99ZWe0NUgBOvgDZBqxTsbU
X7vOUtdCm/nn1lmTZPe/lwIDAQABo4ICiDCCAoQwDgYDVR0PAQH/BAQDAgWgMB0G
A1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMB0GA1Ud
DgQWBBQtALBDAFYOq3K8RuQC19+X2GpjZzAfBgNVHSMEGDAWgBQULrMXt1hWy65Q
CUDmH6+dixTCxjBVBggrBgEFBQcBAQRJMEcwIQYIKwYBBQUHMAGGFWh0dHA6Ly9y
My5vLmxlbmNyLm9yZzAiBggrBgEFBQcwAoYWaHR0cDovL3IzLmkubGVuY3Iub3Jn
LzBXBgNVHREEUDBOgg5hbGVua2EuY2FwaXRhbIIRYWxlbmthY2FwaXRhbC5jb22C
End3dy5hbGVua2EuY2FwaXRhbIIVd3d3LmFsZW5rYWNhcGl0YWwuY29tMEwGA1Ud
IARFMEMwCAYGZ4EMAQIBMDcGCysGAQQBgt8TAQEBMCgwJgYIKwYBBQUHAgEWGmh0
dHA6Ly9jcHMubGV0c2VuY3J5cHQub3JnMIIBBQYKKwYBBAHWeQIEAgSB9gSB8wDx
AHYAtz77JN+cTbp18jnFulj0bF38Qs96nzXEnh0JgSXttJkAAAGGLOlI/QAABAMA
RzBFAiEAiEUAyyMSZ2Q/b06aISXfkWImzhs6AO87tFaC0+w59xoCIE6VbmOlnyiF
YH/sNNUkxbqIZ9lrindoBhW5HOZBI4i0AHcAejKMVNi3LbYg6jjgUh7phBZwMhOF
TTvSK8E6V6NS61IAAAGGLOlJEAAABAMASDBGAiEA34TXhp1cv/gKDpNk3yd+gLl6
NcnoRiu/YJpYnRfAWJECIQDGTXDa6l2fZ3kAg1Ijeue0rBl7efIwpBUk0EmdC+Eq
aDANBgkqhkiG9w0BAQsFAAOCAQEABCopAP4By3YdmqgO2gcQJaLp0Fs67JGc9X6c
CPwbb5dIBn915cYKcupvfffr47/kA9o3kCqJNmhY3qgqgtaBwkJS3057ULmKG4Z2
aNnJLP8wM84+dVKBiUQKxxSQQQGXldVkzeBj47bCJt60wkz/vgychQrS/oPQlqgN
KKuZ7+jdMOrFnRONuaFxovYIwra6dGekzEvCqP1TWDJ4BVsMFc2RL5Qy48/oEsTQ
x8ErPfxhQI1T9ChtphuxnA9pVtkhqOWB6R+4qeIIvEPoOmGTzzX39o90mIA1m5M2
iKyX0O/CxtvvVxRmta8OQ6p4x558GxF7g9f3SjzrCNHkJ2iwpg==
-----END CERTIFICATE-----

View File

@ -0,0 +1,32 @@
package com.baeldung.multiple_truststores;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.X509TrustManager;
import org.junit.jupiter.api.Test;
import com.baeldung.multiple_truststores.SslContextConfigurer;
import sun.security.x509.X509CertImpl;
public class SslContextConfigurerUnitTest {
@Test
public void givenCustomTrustManager_whenCheckingCertificateValidity_thenTrustManagerApprovesCert()
throws IOException, CertificateException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
X509TrustManager trustManager = SslContextConfigurer.addAdditionalTrustStore(
"new_trustStore.p12",
"change"
);
InputStream resourceAsStream = getClass().getClassLoader().getResourceAsStream("cert_to_check.pem");
X509CertImpl x509Cert = new X509CertImpl(resourceAsStream);
trustManager.checkClientTrusted(new X509Certificate[]{x509Cert}, "server");
}
}