Skip to content

Commit d124692

Browse files
committed
Add SSL Configuration Library (#37287)
This introduces a new ssl-config library that can parse and validate SSL/TLS settings and files. It supports the standard configuration settings as used in the Elastic Stack such as "ssl.verification_mode" and "ssl.certificate_authorities" as well as all file formats used in other parts of Elasticsearch security (such as PEM, JKS, PKCS#12, PKCS#8, et al).
1 parent 74c82ec commit d124692

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+5043
-0
lines changed

libs/ssl-config/build.gradle

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
dependencies {
21+
compile "org.elasticsearch:elasticsearch-core:${version}"
22+
23+
if (isEclipse == false || project.path == ":libs:ssl-config-tests") {
24+
testCompile("org.elasticsearch.test:framework:${version}") {
25+
exclude group: 'org.elasticsearch', module: 'elasticsearch-ssl-config'
26+
}
27+
}
28+
29+
testCompile "com.carrotsearch.randomizedtesting:randomizedtesting-runner:${versions.randomizedrunner}"
30+
testCompile "junit:junit:${versions.junit}"
31+
testCompile "org.hamcrest:hamcrest-all:${versions.hamcrest}"
32+
}
33+
34+
forbiddenApisMain {
35+
replaceSignatureFiles 'jdk-signatures'
36+
}
37+
forbiddenPatterns {
38+
exclude '**/*.key'
39+
exclude '**/*.pem'
40+
exclude '**/*.p12'
41+
exclude '**/*.jks'
42+
}
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.common.ssl;
21+
22+
import org.elasticsearch.common.Nullable;
23+
24+
import javax.net.ssl.TrustManagerFactory;
25+
import javax.net.ssl.X509ExtendedTrustManager;
26+
import java.io.IOException;
27+
import java.nio.file.Path;
28+
import java.security.GeneralSecurityException;
29+
import java.security.KeyStore;
30+
import java.util.Arrays;
31+
import java.util.Collection;
32+
import java.util.Collections;
33+
import java.util.function.BiFunction;
34+
35+
/**
36+
* This class represents a trust configuration that corresponds to the default trusted CAs of the JDK
37+
*/
38+
final class DefaultJdkTrustConfig implements SslTrustConfig {
39+
40+
private final BiFunction<String, String, String> systemProperties;
41+
private final char[] trustStorePassword;
42+
43+
/**
44+
* Create a trust config that uses System properties to determine the TrustStore type, and the relevant password.
45+
*/
46+
DefaultJdkTrustConfig() {
47+
this(System::getProperty);
48+
}
49+
50+
/**
51+
* Create a trust config that uses supplied {@link BiFunction} to determine the TrustStore type, and the relevant password.
52+
*/
53+
DefaultJdkTrustConfig(BiFunction<String, String, String> systemProperties) {
54+
this(systemProperties, isPkcs11Truststore(systemProperties) ? getSystemTrustStorePassword(systemProperties) : null);
55+
}
56+
57+
/**
58+
* @param trustStorePassword the password for the truststore. It applies only when PKCS#11 tokens are used, is null otherwise
59+
*/
60+
DefaultJdkTrustConfig(BiFunction<String, String, String> systemProperties, @Nullable char[] trustStorePassword) {
61+
this.systemProperties = systemProperties;
62+
this.trustStorePassword = trustStorePassword;
63+
}
64+
65+
@Override
66+
public X509ExtendedTrustManager createTrustManager() {
67+
try {
68+
return KeyStoreUtil.createTrustManager(getSystemTrustStore(), TrustManagerFactory.getDefaultAlgorithm());
69+
} catch (GeneralSecurityException e) {
70+
throw new SslConfigException("failed to initialize a TrustManager for the system keystore", e);
71+
}
72+
}
73+
74+
/**
75+
* When a PKCS#11 token is used as the system default keystore/truststore, we need to pass the keystore
76+
* password when loading, even for reading certificates only ( as opposed to i.e. JKS keystores where
77+
* we only need to pass the password for reading Private Key entries ).
78+
*
79+
* @return the KeyStore used as truststore for PKCS#11 initialized with the password, null otherwise
80+
*/
81+
private KeyStore getSystemTrustStore() {
82+
if (isPkcs11Truststore(systemProperties) && trustStorePassword != null) {
83+
try {
84+
KeyStore keyStore = KeyStore.getInstance("PKCS11");
85+
keyStore.load(null, trustStorePassword);
86+
return keyStore;
87+
} catch (GeneralSecurityException | IOException e) {
88+
throw new SslConfigException("failed to load the system PKCS#11 truststore", e);
89+
}
90+
}
91+
return null;
92+
}
93+
94+
private static boolean isPkcs11Truststore(BiFunction<String, String, String> systemProperties) {
95+
return systemProperties.apply("javax.net.ssl.trustStoreType", "").equalsIgnoreCase("PKCS11");
96+
}
97+
98+
private static char[] getSystemTrustStorePassword(BiFunction<String, String, String> systemProperties) {
99+
return systemProperties.apply("javax.net.ssl.trustStorePassword", "").toCharArray();
100+
}
101+
102+
@Override
103+
public Collection<Path> getDependentFiles() {
104+
return Collections.emptyList();
105+
}
106+
107+
@Override
108+
public String toString() {
109+
return "JDK-trusted-certs";
110+
}
111+
112+
@Override
113+
public boolean equals(Object o) {
114+
if (this == o) {
115+
return true;
116+
}
117+
if (o == null || getClass() != o.getClass()) {
118+
return false;
119+
}
120+
final DefaultJdkTrustConfig that = (DefaultJdkTrustConfig) o;
121+
return Arrays.equals(this.trustStorePassword, that.trustStorePassword);
122+
}
123+
124+
@Override
125+
public int hashCode() {
126+
return Arrays.hashCode(trustStorePassword);
127+
}
128+
}

0 commit comments

Comments
 (0)