<properties>
<category>*</category>
<skipIts>false</skipIts>
+ <jetty.version>9.3.11.v20160721</jetty.version>
</properties>
<dependencies>
<artifactId>subethasmtp</artifactId>
<version>3.1.6</version>
</dependency>
+
+ <!-- SSL tests -->
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-server</artifactId>
+ <version>${jetty.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-servlet</artifactId>
+ <version>${jetty.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-proxy</artifactId>
+ <version>${jetty.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.sonarsource.scanner.cli</groupId>
+ <artifactId>sonar-scanner-cli</artifactId>
+ <version>2.7</version>
+ <type>zip</type>
+ </dependency>
</dependencies>
<build>
import it.analysis.ProjectBuilderTest;
import it.analysis.ProjectProvisioningTest;
import it.analysis.ReportDumpTest;
+import it.analysis.SSLTest;
import it.analysis.SettingsEncryptionTest;
import it.analysis.TempFolderTest;
import it.measure.DecimalScaleMetricTest;
IssuesModeTest.class,
SettingsEncryptionTest.class,
ReportDumpTest.class,
+ SSLTest.class,
// measures
DecimalScaleMetricTest.class
})
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package it.analysis;
+
+import com.sonar.orchestrator.Orchestrator;
+import com.sonar.orchestrator.build.BuildResult;
+import com.sonar.orchestrator.build.SonarScanner;
+import com.sonar.orchestrator.util.NetworkUtils;
+import it.Category3Suite;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import org.eclipse.jetty.http.HttpVersion;
+import org.eclipse.jetty.proxy.ProxyServlet;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.HttpConfiguration;
+import org.eclipse.jetty.server.HttpConnectionFactory;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.server.SslConnectionFactory;
+import org.eclipse.jetty.server.handler.DefaultHandler;
+import org.eclipse.jetty.server.handler.HandlerCollection;
+import org.eclipse.jetty.servlet.ServletContextHandler;
+import org.eclipse.jetty.servlet.ServletHandler;
+import org.eclipse.jetty.servlet.ServletHolder;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+import org.eclipse.jetty.util.thread.QueuedThreadPool;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Test;
+import util.ItUtils;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class SSLTest {
+
+ private static final String CLIENT_KEYSTORE = "/analysis/SSLTest/clientkeystore.jks";
+ private static final String CLIENT_KEYSTORE_PWD = "clientp12pwd";
+
+ private static final String CLIENT_TRUSTSTORE = "/analysis/SSLTest/clienttruststore.jks";
+ private static final String CLIENT_TRUSTSTORE_PWD = "clienttruststorepwd";
+
+ @ClassRule
+ public static Orchestrator orchestrator = Category3Suite.ORCHESTRATOR;
+
+ private static Server server;
+ private static int httpsPort;
+
+ @Before
+ public void deleteData() {
+ orchestrator.resetData();
+ }
+
+ public static void startSSLTransparentReverseProxy(boolean requireClientAuth) throws Exception {
+ int httpPort = NetworkUtils.getNextAvailablePort();
+ httpsPort = NetworkUtils.getNextAvailablePort();
+
+ // Setup Threadpool
+ QueuedThreadPool threadPool = new QueuedThreadPool();
+ threadPool.setMaxThreads(500);
+
+ server = new Server(threadPool);
+
+ // HTTP Configuration
+ HttpConfiguration httpConfig = new HttpConfiguration();
+ httpConfig.setSecureScheme("https");
+ httpConfig.setSecurePort(httpsPort);
+ httpConfig.setSendServerVersion(true);
+ httpConfig.setSendDateHeader(false);
+
+ // Handler Structure
+ HandlerCollection handlers = new HandlerCollection();
+ handlers.setHandlers(new Handler[] {proxyHandler(), new DefaultHandler()});
+ server.setHandler(handlers);
+
+ ServerConnector http = new ServerConnector(server, new HttpConnectionFactory(httpConfig));
+ http.setPort(httpPort);
+ server.addConnector(http);
+
+ Path serverKeyStore = Paths.get(SSLTest.class.getResource("/analysis/SSLTest/serverkeystore.jks").toURI()).toAbsolutePath();
+ String keyStorePassword = "serverkeystorepwd";
+ String serverKeyPassword = "serverp12pwd";
+ Path serverTrustStore = Paths.get(SSLTest.class.getResource("/analysis/SSLTest/servertruststore.jks").toURI()).toAbsolutePath();
+ String trustStorePassword = "servertruststorepwd";
+
+ // SSL Context Factory
+ SslContextFactory sslContextFactory = new SslContextFactory();
+ sslContextFactory.setKeyStorePath(serverKeyStore.toString());
+ sslContextFactory.setKeyStorePassword(keyStorePassword);
+ sslContextFactory.setKeyManagerPassword(serverKeyPassword);
+ sslContextFactory.setTrustStorePath(serverTrustStore.toString());
+ sslContextFactory.setTrustStorePassword(trustStorePassword);
+ sslContextFactory.setNeedClientAuth(requireClientAuth);
+ sslContextFactory.setExcludeCipherSuites("SSL_RSA_WITH_DES_CBC_SHA",
+ "SSL_DHE_RSA_WITH_DES_CBC_SHA", "SSL_DHE_DSS_WITH_DES_CBC_SHA",
+ "SSL_RSA_EXPORT_WITH_RC4_40_MD5",
+ "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
+ "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
+ "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA");
+
+ // SSL HTTP Configuration
+ HttpConfiguration httpsConfig = new HttpConfiguration(httpConfig);
+
+ // SSL Connector
+ ServerConnector sslConnector = new ServerConnector(server,
+ new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.asString()),
+ new HttpConnectionFactory(httpsConfig));
+ sslConnector.setPort(httpsPort);
+ server.addConnector(sslConnector);
+
+ server.start();
+ }
+
+ private static ServletContextHandler proxyHandler() {
+ ServletContextHandler contextHandler = new ServletContextHandler();
+ contextHandler.setServletHandler(newServletHandler());
+ return contextHandler;
+ }
+
+ private static ServletHandler newServletHandler() {
+ ServletHandler handler = new ServletHandler();
+ ServletHolder holder = handler.addServletWithMapping(ProxyServlet.Transparent.class, "/*");
+ holder.setInitParameter("proxyTo", orchestrator.getServer().getUrl());
+ return handler;
+ }
+
+ @After
+ public void stopProxy() throws Exception {
+ if (server != null && server.isStarted()) {
+ server.stop();
+ }
+ }
+
+ @Test
+ public void simple_analysis_with_server_and_client_certificate() throws Exception {
+ startSSLTransparentReverseProxy(true);
+
+ SonarScanner sonarScanner = SonarScanner.create(ItUtils.projectDir("shared/xoo-sample"))
+ .setScannerVersion("2.7")
+ .setProperty("sonar.host.url", "https://localhost:" + httpsPort);
+
+ BuildResult buildResult = orchestrator.executeBuildQuietly(sonarScanner);
+ assertThat(buildResult.getLastStatus()).isNotEqualTo(0);
+ assertThat(buildResult.getLogs()).contains("javax.net.ssl.SSLHandshakeException");
+
+ Path clientTruststore = Paths.get(SSLTest.class.getResource(CLIENT_TRUSTSTORE).toURI()).toAbsolutePath();
+ String truststorePassword = CLIENT_TRUSTSTORE_PWD;
+ Path clientKeystore = Paths.get(SSLTest.class.getResource(CLIENT_KEYSTORE).toURI()).toAbsolutePath();
+ String keystorePassword = CLIENT_KEYSTORE_PWD;
+
+ buildResult = orchestrator.executeBuild(sonarScanner
+ .setEnvironmentVariable("SONAR_SCANNER_OPTS",
+ "-Djavax.net.ssl.trustStore=" + clientTruststore.toString() +
+ " -Djavax.net.ssl.trustStorePassword=" + truststorePassword +
+ " -Djavax.net.ssl.keyStore=" + clientKeystore.toString() +
+ " -Djavax.net.ssl.keyStorePassword=" + keystorePassword));
+ }
+
+ @Test
+ public void simple_analysis_with_server_certificate() throws Exception {
+ startSSLTransparentReverseProxy(false);
+
+ SonarScanner sonarScanner = SonarScanner.create(ItUtils.projectDir("shared/xoo-sample"))
+ .setScannerVersion("2.7")
+ .setProperty("sonar.host.url", "https://localhost:" + httpsPort);
+
+ BuildResult buildResult = orchestrator.executeBuildQuietly(sonarScanner);
+ assertThat(buildResult.getLastStatus()).isNotEqualTo(0);
+ assertThat(buildResult.getLogs()).contains("javax.net.ssl.SSLHandshakeException");
+
+ Path clientTruststore = Paths.get(SSLTest.class.getResource(CLIENT_TRUSTSTORE).toURI()).toAbsolutePath();
+ String truststorePassword = CLIENT_TRUSTSTORE_PWD;
+
+ buildResult = orchestrator.executeBuild(sonarScanner
+ .setEnvironmentVariable("SONAR_SCANNER_OPTS",
+ "-Djavax.net.ssl.trustStore=" + clientTruststore.toString() +
+ " -Djavax.net.ssl.trustStorePassword=" + truststorePassword));
+ }
+}
--- /dev/null
+$ openssl req -config ./openssl.cnf -newkey rsa:2048 -nodes -keyform PEM -keyout ca.key -x509 -days 3650 -extensions certauth -outform PEM -out ca.cer
+Generating a 2048 bit RSA private key
+..............................................+++
+........................................................................................................+++
+writing new private key to 'ca.key'
+-----
+You are about to be asked to enter information that will be incorporated
+into your certificate request.
+What you are about to enter is what is called a Distinguished Name or a DN.
+There are quite a few fields but you can leave some blank
+For some fields there will be a default value,
+If you enter '.', the field will be left blank.
+-----
+Country [FR]:
+Locality [Poitiers]:
+Organization [SonarSource]:
+Common Name []:CA for SonarQube ITs
+
+$ openssl genrsa -out server.key 2048
+Generating RSA private key, 2048 bit long modulus
+........................+++
+............................+++
+e is 65537 (0x10001)
+
+$ openssl req -config ./openssl.cnf -new -key server.key -out server.req
+You are about to be asked to enter information that will be incorporated
+into your certificate request.
+What you are about to enter is what is called a Distinguished Name or a DN.
+There are quite a few fields but you can leave some blank
+For some fields there will be a default value,
+If you enter '.', the field will be left blank.
+-----
+Country [FR]:
+Locality [Poitiers]:
+Organization [SonarSource]:
+Common Name []:localhost
+
+$ openssl x509 -req -in server.req -CA ca.cer -CAkey ca.key -set_serial 100 -extfile openssl.cnf -extensions server -days 3650 -outform PEM -out server.cer
+Signature ok
+subject=/C=FR/L=Poitiers/O=SonarSource/CN=localhost
+Getting CA Private Key
+
+$ openssl genrsa -out client.key 2048
+Generating RSA private key, 2048 bit long modulus
+...................................+++
+.....................................................+++
+e is 65537 (0x10001)
+
+$ openssl req -config ./openssl.cnf -new -key client.key -out client.req
+You are about to be asked to enter information that will be incorporated
+into your certificate request.
+What you are about to enter is what is called a Distinguished Name or a DN.
+There are quite a few fields but you can leave some blank
+For some fields there will be a default value,
+If you enter '.', the field will be left blank.
+-----
+Country [FR]:
+Locality [Poitiers]:
+Organization [SonarSource]:
+Common Name []:Julien Henry
+
+$ openssl x509 -req -in client.req -CA ca.cer -CAkey ca.key -set_serial 101 -extfile openssl.cnf -extensions client -days 3650 -outform PEM -out client.cer
+Signature ok
+subject=/C=FR/L=Poitiers/O=SonarSource/CN=Julien Henry
+Getting CA Private Key
+
+$ openssl pkcs12 -export -inkey client.key -in client.cer -out client.p12
+Enter Export Password: clientp12pwd
+Verifying - Enter Export Password: clientp12pwd
+
+$ openssl pkcs12 -inkey server.key -in server.cer -export -out server.p12
+Enter Export Password: serverp12pwd
+Verifying - Enter Export Password: serverp12pwd
+
+$ keytool -importkeystore -srckeystore server.p12 -srcstoretype PKCS12 -destkeystore serverkeystore.jks
+Entrez le mot de passe du fichier de clés de destination : serverkeystorepwd
+Ressaisissez le nouveau mot de passe : serverkeystorepwd
+Entrez le mot de passe du fichier de clés source : serverp12pwd
+L'entrée de l'alias 1 a été importée.
+Commande d'import exécutée : 1 entrées importées, échec ou annulation de 0 entrées
+
+$ keytool -import -file ca.cer -keystore servertruststore.jks
+Entrez le mot de passe du fichier de clés : servertruststorepwd
+Ressaisissez le nouveau mot de passe : servertruststorepwd
+Propriétaire : CN=Test CA, O=SonarSource, L=Poitiers, C=FR
+Emetteur : CN=Test CA, O=SonarSource, L=Poitiers, C=FR
+Numéro de série : dabbebc7bce2fc6a
+Valide du : Wed Aug 31 14:42:15 CEST 2016 au : Sat Aug 29 14:42:15 CEST 2026
+Empreintes du certificat :
+ MD5: 69:36:AE:65:51:CD:F4:C3:83:77:DE:45:AE:49:01:1A
+ SHA1 : 77:92:45:84:18:FC:34:7A:2A:B0:EC:3D:22:48:15:1A:19:71:1D:B3
+ SHA256 : 99:03:89:84:6E:E3:D3:B7:12:2D:70:7E:49:88:49:41:52:1C:89:3A:9B:C0:83:D1:C5:44:D4:93:FB:42:C8:07
+ Nom de l'algorithme de signature : SHA1withRSA
+ Version : 3
+
+Extensions :
+
+#1: ObjectId: 2.5.29.35 Criticality=false
+AuthorityKeyIdentifier [
+KeyIdentifier [
+0000: 3A 61 C1 86 AD BE FC 15 82 B3 59 FF 00 28 5E F9 :a........Y..(^.
+0010: B5 5A 87 04 .Z..
+]
+[CN=Test CA, O=SonarSource, L=Poitiers, C=FR]
+SerialNumber: [ dabbebc7 bce2fc6a]
+]
+
+#2: ObjectId: 2.5.29.19 Criticality=false
+BasicConstraints:[
+ CA:true
+ PathLen:2147483647
+]
+
+#3: ObjectId: 2.5.29.31 Criticality=false
+CRLDistributionPoints [
+ [DistributionPoint:
+ [URIName: http://testca.local/ca.crl]
+]]
+
+#4: ObjectId: 2.5.29.14 Criticality=false
+SubjectKeyIdentifier [
+KeyIdentifier [
+0000: 3A 61 C1 86 AD BE FC 15 82 B3 59 FF 00 28 5E F9 :a........Y..(^.
+0010: B5 5A 87 04 .Z..
+]
+]
+
+Faire confiance à ce certificat ? [non] : oui
+Certificat ajouté au fichier de clés
+
+$ keytool -import -file server.cer -keystore clienttruststore.jks
+Entrez le mot de passe du fichier de clés : clienttruststorepwd
+Ressaisissez le nouveau mot de passe : clienttruststorepwd
+Propriétaire : CN=localhost, O=SonarSource, L=Poitiers, C=FR
+Emetteur : CN=Test CA, O=SonarSource, L=Poitiers, C=FR
+Numéro de série : 64
+Valide du : Wed Aug 31 14:45:30 CEST 2016 au : Thu Aug 31 14:45:30 CEST 2017
+Empreintes du certificat :
+ MD5: 40:52:F4:5E:67:C3:68:B6:00:7D:70:C0:1E:8E:75:2E
+ SHA1 : 83:3F:4F:AC:4E:E6:F4:06:14:01:E6:5B:F2:63:34:94:68:12:8C:3A
+ SHA256 : 7C:03:9A:CA:0D:B5:57:A5:66:56:75:09:23:45:9E:D5:CC:6C:72:14:0B:4B:9B:E8:29:3F:78:4C:9F:D6:77:E2
+ Nom de l'algorithme de signature : SHA256withRSA
+ Version : 3
+
+Extensions :
+
+#1: ObjectId: 2.5.29.19 Criticality=false
+BasicConstraints:[
+ CA:false
+ PathLen: undefined
+]
+
+#2: ObjectId: 2.5.29.31 Criticality=false
+CRLDistributionPoints [
+ [DistributionPoint:
+ [URIName: http://testca.local/ca.crl]
+]]
+
+#3: ObjectId: 2.5.29.37 Criticality=false
+ExtendedKeyUsages [
+ serverAuth
+]
+
+#4: ObjectId: 2.5.29.15 Criticality=false
+KeyUsage [
+ DigitalSignature
+ Key_Encipherment
+ Data_Encipherment
+]
+
+#5: ObjectId: 2.16.840.1.113730.1.1 Criticality=false
+NetscapeCertType [
+ SSL server
+]
+
+Faire confiance à ce certificat ? [non] : oui
+Certificat ajouté au fichier de clés
+
+$ keytool -importkeystore -srckeystore client.p12 -srcstoretype PKCS12 -destkeystore clientkeystore.jks
+Entrez le mot de passe du fichier de clés de destination : clientp12pwd
+Ressaisissez le nouveau mot de passe : clientp12pwd
+Entrez le mot de passe du fichier de clés source : clientp12pwd
+L'entrée de l'alias 1 a été importée.
+Commande d'import exécutée : 1 entrées importées, échec ou annulation de 0 entrées
--- /dev/null
+[ req ]
+default_md = sha1
+distinguished_name = req_distinguished_name
+
+[ req_distinguished_name ]
+countryName = Country
+countryName_default = FR
+countryName_min = 2
+countryName_max = 2
+localityName = Locality
+localityName_default = Poitiers
+organizationName = Organization
+organizationName_default = SonarSource
+commonName = Common Name
+commonName_max = 64
+
+[ certauth ]
+subjectKeyIdentifier = hash
+authorityKeyIdentifier = keyid:always,issuer:always
+basicConstraints = CA:true
+crlDistributionPoints = @crl
+
+[ server ]
+basicConstraints = CA:FALSE
+keyUsage = digitalSignature, keyEncipherment, dataEncipherment
+extendedKeyUsage = serverAuth
+nsCertType = server
+crlDistributionPoints = @crl
+
+[ client ]
+basicConstraints = CA:FALSE
+keyUsage = digitalSignature, keyEncipherment, dataEncipherment
+extendedKeyUsage = clientAuth
+nsCertType = client
+crlDistributionPoints = @crl
+
+[ crl ]
+URI=http://testca.local/ca.crl
\ No newline at end of file
*/
package org.sonarqube.ws.client;
+import java.io.FileInputStream;
import java.io.IOException;
import java.net.Proxy;
+import java.security.GeneralSecurityException;
+import java.security.KeyStore;
+import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509TrustManager;
import okhttp3.Call;
import okhttp3.ConnectionSpec;
import okhttp3.Credentials;
public static final int DEFAULT_CONNECT_TIMEOUT_MILLISECONDS = 30_000;
public static final int DEFAULT_READ_TIMEOUT_MILLISECONDS = 60_000;
+ private static final String NONE = "NONE";
+ private static final String P11KEYSTORE = "PKCS11";
/**
* Base URL with trailing slash, for instance "https://localhost/sonarqube/".
.supportsTlsExtensions(true)
.build();
okHttpClientBuilder.connectionSpecs(asList(tls, ConnectionSpec.CLEARTEXT));
+ X509TrustManager systemDefaultTrustManager = systemDefaultTrustManager();
+ okHttpClientBuilder.sslSocketFactory(systemDefaultSslSocketFactory(systemDefaultTrustManager), systemDefaultTrustManager);
return okHttpClientBuilder.build();
}
+ private static X509TrustManager systemDefaultTrustManager() {
+ try {
+ TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+ trustManagerFactory.init((KeyStore) null);
+ TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
+ if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
+ throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(trustManagers));
+ }
+ return (X509TrustManager) trustManagers[0];
+ } catch (GeneralSecurityException e) {
+ // The system has no TLS. Just give up.
+ throw new AssertionError(e);
+ }
+ }
+
+ private static SSLSocketFactory systemDefaultSslSocketFactory(X509TrustManager trustManager) {
+ KeyManager[] defaultKeyManager;
+ try {
+ defaultKeyManager = getDefaultKeyManager();
+ } catch (Exception e) {
+ throw new IllegalStateException("Unable to get default key manager", e);
+ }
+ try {
+ SSLContext sslContext = SSLContext.getInstance("TLS");
+ sslContext.init(defaultKeyManager, new TrustManager[] {trustManager}, null);
+ return sslContext.getSocketFactory();
+ } catch (GeneralSecurityException e) {
+ // The system has no TLS. Just give up.
+ throw new AssertionError(e);
+ }
+ }
+
+ private static void logDebug(String msg) {
+ boolean debugEnabled = "all".equals(System.getProperty("javax.net.debug"));
+ if (debugEnabled) {
+ System.out.println(msg);
+ }
+ }
+
+ /**
+ * Inspired from sun.security.ssl.SSLContextImpl#getDefaultKeyManager()
+ */
+ private static synchronized KeyManager[] getDefaultKeyManager() throws Exception {
+
+ final String defaultKeyStore = System.getProperty("javax.net.ssl.keyStore", "");
+ String defaultKeyStoreType = System.getProperty("javax.net.ssl.keyStoreType", KeyStore.getDefaultType());
+ String defaultKeyStoreProvider = System.getProperty("javax.net.ssl.keyStoreProvider", "");
+
+ logDebug("keyStore is : " + defaultKeyStore);
+ logDebug("keyStore type is : " + defaultKeyStoreType);
+ logDebug("keyStore provider is : " + defaultKeyStoreProvider);
+
+ if (P11KEYSTORE.equals(defaultKeyStoreType) && !NONE.equals(defaultKeyStore)) {
+ throw new IllegalArgumentException("if keyStoreType is " + P11KEYSTORE + ", then keyStore must be " + NONE);
+ }
+
+ KeyStore ks = null;
+ String defaultKeyStorePassword = System.getProperty("javax.net.ssl.keyStorePassword", "");
+ char[] passwd = defaultKeyStorePassword.isEmpty() ? null : defaultKeyStorePassword.toCharArray();
+
+ /**
+ * Try to initialize key store.
+ */
+ if (!defaultKeyStoreType.isEmpty()) {
+ logDebug("init keystore");
+ if (defaultKeyStoreProvider.isEmpty()) {
+ ks = KeyStore.getInstance(defaultKeyStoreType);
+ } else {
+ ks = KeyStore.getInstance(defaultKeyStoreType, defaultKeyStoreProvider);
+ }
+ if (!defaultKeyStore.isEmpty() && !NONE.equals(defaultKeyStore)) {
+ try (FileInputStream fs = new FileInputStream(defaultKeyStore)) {
+ ks.load(fs, passwd);
+ }
+ } else {
+ ks.load(null, passwd);
+ }
+ }
+
+ /*
+ * Try to initialize key manager.
+ */
+ logDebug("init keymanager of type " + KeyManagerFactory.getDefaultAlgorithm());
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
+
+ if (P11KEYSTORE.equals(defaultKeyStoreType)) {
+ // do not pass key passwd if using token
+ kmf.init(ks, null);
+ } else {
+ kmf.init(ks, passwd);
+ }
+
+ return kmf.getKeyManagers();
+ }
+
@Override
public String baseUrl() {
return baseUrl.url().toExternalForm();