Skip to content

Commit e83f547

Browse files
authored
Fix keystore for APM-server communication (#2362)
* use keystore when provided * update changelog * issue a warning+log error in debug
1 parent 2fa7f8b commit e83f547

File tree

2 files changed

+54
-4
lines changed

2 files changed

+54
-4
lines changed

CHANGELOG.asciidoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ endif::[]
3333
[float]
3434
===== Bug fixes
3535
* Gracefully handle JDBC drivers which don't support `Connection#getCatalog` - {pull}2340[#2340]
36+
* Fix using JVM keystore options for communication with APM Server - {pull}2362[#2362]
3637
3738
[[release-notes-1.x]]
3839
=== Java Agent version 1.x

apm-agent-core/src/main/java/co/elastic/apm/agent/report/ssl/SslUtils.java

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,17 @@
2323

2424
import javax.annotation.Nullable;
2525
import javax.net.ssl.HostnameVerifier;
26+
import javax.net.ssl.KeyManager;
27+
import javax.net.ssl.KeyManagerFactory;
2628
import javax.net.ssl.SSLContext;
2729
import javax.net.ssl.SSLSession;
2830
import javax.net.ssl.SSLSocketFactory;
2931
import javax.net.ssl.TrustManager;
3032
import javax.net.ssl.X509TrustManager;
31-
import java.security.KeyManagementException;
33+
import java.io.FileInputStream;
34+
import java.io.IOException;
35+
import java.security.GeneralSecurityException;
36+
import java.security.KeyStore;
3237
import java.security.NoSuchAlgorithmException;
3338
import java.security.cert.X509Certificate;
3439
import java.util.Objects;
@@ -108,19 +113,28 @@ public static SSLSocketFactory getSSLSocketFactory(boolean validateCertificates)
108113
}
109114

110115
@Nullable
111-
private static SSLSocketFactory createSocketFactory(TrustManager[] trustAllCerts) throws NoSuchAlgorithmException, KeyManagementException {
116+
private static SSLSocketFactory createSocketFactory(@Nullable TrustManager[] trustManagers) throws IOException, GeneralSecurityException {
112117
SSLContext sslContext;
113118
try {
114119
sslContext = SSLContext.getInstance("SSL");
115120
} catch (NoSuchAlgorithmException e) {
116121
logger.info("SSL is not supported, trying to use TLS instead.");
117122
sslContext = SSLContext.getInstance("TLS");
118123
}
119-
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
124+
125+
KeyManager[] keyManagers = null;
126+
try {
127+
keyManagers = getKeyManagers();
128+
} catch (IOException | GeneralSecurityException e) {
129+
logger.warn("unable to setup key managers, keystore options will be ignored");
130+
logger.debug("key manager creation error stack trace: ", e);
131+
}
132+
133+
sslContext.init(keyManagers, trustManagers, new java.security.SecureRandom());
120134
return sslContext.getSocketFactory();
121135
}
122136

123-
public static SSLSocketFactory createTrustAllSocketFactory() throws NoSuchAlgorithmException, KeyManagementException {
137+
public static SSLSocketFactory createTrustAllSocketFactory() throws GeneralSecurityException, IOException {
124138
return Objects.requireNonNull(createSocketFactory(new TrustManager[]{X_509_TRUST_ALL}));
125139
}
126140

@@ -132,4 +146,39 @@ public static X509TrustManager getTrustAllManager() {
132146
return X_509_TRUST_ALL;
133147
}
134148

149+
@Nullable
150+
public static KeyManager[] getKeyManagers() throws IOException, GeneralSecurityException {
151+
// re-implements parts of sun.security.ssl.SSLContextImpl.DefaultManagersHolder.getKeyManagers
152+
// as there is no simple way to reuse existing implementation
153+
154+
String keyStore = System.getProperty("javax.net.ssl.keyStore");
155+
String keyStorePassword = System.getProperty("javax.net.ssl.keyStorePassword");
156+
String keyStoreType = System.getProperty("javax.net.ssl.keyStoreType");
157+
String keyStoreProvider = System.getProperty("javax.net.ssl.keyStoreProvider");
158+
159+
if (keyStore == null) {
160+
return null;
161+
}
162+
logger.debug("using keystore {}", keyStore);
163+
164+
char[] pwd = keyStorePassword != null ? keyStorePassword.toCharArray() : null;
165+
166+
KeyStore ks = null;
167+
try (FileInputStream input = new FileInputStream(keyStore)) {
168+
if (keyStoreType != null) {
169+
ks = keyStoreProvider == null ?
170+
KeyStore.getInstance(keyStoreType) :
171+
KeyStore.getInstance(keyStoreType, keyStoreProvider);
172+
ks.load(input, pwd);
173+
}
174+
}
175+
176+
KeyManagerFactory kmf = KeyManagerFactory.getInstance(
177+
KeyManagerFactory.getDefaultAlgorithm());
178+
179+
kmf.init(ks, pwd);
180+
181+
return kmf.getKeyManagers();
182+
}
183+
135184
}

0 commit comments

Comments
 (0)