You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by gg...@apache.org on 2021/10/10 18:36:09 UTC
[httpcomponents-core] branch master updated: Add SSLContextBuilder
NIO Path versions of IO File APIs and re-implement internals with NIO.
(#301)
This is an automated email from the ASF dual-hosted git repository.
ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/httpcomponents-core.git
The following commit(s) were added to refs/heads/master by this push:
new 6f6a4a2 Add SSLContextBuilder NIO Path versions of IO File APIs and re-implement internals with NIO. (#301)
6f6a4a2 is described below
commit 6f6a4a2e55e0aac36414ab2e14397703f1c4cbc6
Author: Gary Gregory <ga...@users.noreply.github.com>
AuthorDate: Sun Oct 10 14:36:05 2021 -0400
Add SSLContextBuilder NIO Path versions of IO File APIs and re-implement internals with NIO. (#301)
* Add SSLContextBuilder NIO Path versions of IO File APIs and re-implement
internals with NIO.
Using NIO, we no longer create FileInputStream instances which required
finalization from the JVM.
* Clean ups.
- Remove redundant calls to super().
- Reduce duplication.
- Camel-case parameter names.
- Use {} notation.
* Update JApiCmp 0.15.3 -> 0.15.4 and use a property to tack its
version.
Co-authored-by: Gary Gregory <gg...@rocketsoftware.com>
---
.../apache/hc/core5/benchmark/HttpBenchmark.java | 3 +-
.../org/apache/hc/core5/ssl/SSLContextBuilder.java | 159 ++++++++++++++-------
pom.xml | 5 +-
3 files changed, 111 insertions(+), 56 deletions(-)
diff --git a/httpcore5-testing/src/main/java/org/apache/hc/core5/benchmark/HttpBenchmark.java b/httpcore5-testing/src/main/java/org/apache/hc/core5/benchmark/HttpBenchmark.java
index f4455ac..dc72131 100644
--- a/httpcore5-testing/src/main/java/org/apache/hc/core5/benchmark/HttpBenchmark.java
+++ b/httpcore5-testing/src/main/java/org/apache/hc/core5/benchmark/HttpBenchmark.java
@@ -32,6 +32,7 @@ import java.net.SocketAddress;
import java.net.URI;
import java.nio.ByteBuffer;
import java.nio.channels.ByteChannel;
+import java.nio.file.Paths;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -138,7 +139,7 @@ public class HttpBenchmark {
}
if (config.getIdentityStorePath() != null) {
sslContextBuilder.loadKeyMaterial(
- new File(config.getIdentityStorePath()),
+ Paths.get(config.getIdentityStorePath()),
config.getIdentityStorePassword() != null ? config.getIdentityStorePassword().toCharArray() : null,
config.getIdentityStorePassword() != null ? config.getIdentityStorePassword().toCharArray() : null);
}
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/ssl/SSLContextBuilder.java b/httpcore5/src/main/java/org/apache/hc/core5/ssl/SSLContextBuilder.java
index 886003b..97f2b4b 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/ssl/SSLContextBuilder.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/ssl/SSLContextBuilder.java
@@ -28,11 +28,13 @@
package org.apache.hc.core5.ssl;
import java.io.File;
-import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.OpenOption;
+import java.nio.file.Path;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
@@ -95,12 +97,12 @@ public class SSLContextBuilder {
/**
* An empty immutable {@code KeyManager} array.
*/
- private static final KeyManager[] EMPTY_KEY_MANAGER_ARRAY = new KeyManager[0];
+ private static final KeyManager[] EMPTY_KEY_MANAGER_ARRAY = {};
/**
* An empty immutable {@code TrustManager} array.
*/
- private static final TrustManager[] EMPTY_TRUST_MANAGER_ARRAY = new TrustManager[0];
+ private static final TrustManager[] EMPTY_TRUST_MANAGER_ARRAY = {};
@@ -109,7 +111,6 @@ public class SSLContextBuilder {
}
public SSLContextBuilder() {
- super();
this.keyManagers = new LinkedHashSet<>();
this.trustManagers = new LinkedHashSet<>();
}
@@ -161,10 +162,7 @@ public class SSLContextBuilder {
* @since 5.2
*/
public SSLContextBuilder setTrustStoreProvider(final String name) throws NoSuchProviderException {
- this.tsProvider = Security.getProvider(name);
- if (this.tsProvider == null) {
- throw new NoSuchProviderException(name);
- }
+ this.tsProvider = requireNonNullProvider(name);
return this;
}
@@ -186,10 +184,7 @@ public class SSLContextBuilder {
* @since 5.2
*/
public SSLContextBuilder setKeyStoreProvider(final String name) throws NoSuchProviderException {
- this.ksProvider = Security.getProvider(name);
- if (this.ksProvider == null) {
- throw new NoSuchProviderException(name);
- }
+ this.ksProvider = requireNonNullProvider(name);
return this;
}
@@ -259,7 +254,7 @@ public class SSLContextBuilder {
}
public SSLContextBuilder loadTrustMaterial(
- final KeyStore truststore,
+ final KeyStore trustStore,
final TrustStrategy trustStrategy) throws NoSuchAlgorithmException, KeyStoreException {
final String alg = trustManagerFactoryAlgorithm == null ?
@@ -268,15 +263,14 @@ public class SSLContextBuilder {
final TrustManagerFactory tmFactory = tsProvider == null ?
TrustManagerFactory.getInstance(alg) : TrustManagerFactory.getInstance(alg, tsProvider);
- tmFactory.init(truststore);
+ tmFactory.init(trustStore);
final TrustManager[] tms = tmFactory.getTrustManagers();
if (tms != null) {
if (trustStrategy != null) {
for (int i = 0; i < tms.length; i++) {
final TrustManager tm = tms[i];
if (tm instanceof X509TrustManager) {
- tms[i] = new TrustManagerDelegate(
- (X509TrustManager) tm, trustStrategy);
+ tms[i] = new TrustManagerDelegate((X509TrustManager) tm, trustStrategy);
}
}
}
@@ -285,6 +279,35 @@ public class SSLContextBuilder {
return this;
}
+ /**
+ * @since 5.2
+ */
+ public SSLContextBuilder loadTrustMaterial(
+ final Path file) throws NoSuchAlgorithmException, KeyStoreException, CertificateException, IOException {
+ return loadTrustMaterial(file, null);
+ }
+
+ /**
+ * @since 5.2
+ */
+ public SSLContextBuilder loadTrustMaterial(
+ final Path file,
+ final char[] storePassword) throws NoSuchAlgorithmException, KeyStoreException, CertificateException, IOException {
+ return loadTrustMaterial(file, storePassword, null);
+ }
+
+ /**
+ * @since 5.2
+ */
+ public SSLContextBuilder loadTrustMaterial(
+ final Path file,
+ final char[] storePassword,
+ final TrustStrategy trustStrategy,
+ final OpenOption... openOptions) throws NoSuchAlgorithmException, KeyStoreException, CertificateException, IOException {
+ Args.notNull(file, "Truststore file");
+ return loadTrustMaterial(loadKeyStore(file, storePassword, openOptions), trustStrategy);
+ }
+
public SSLContextBuilder loadTrustMaterial(
final TrustStrategy trustStrategy) throws NoSuchAlgorithmException, KeyStoreException {
return loadTrustMaterial(null, trustStrategy);
@@ -295,11 +318,7 @@ public class SSLContextBuilder {
final char[] storePassword,
final TrustStrategy trustStrategy) throws NoSuchAlgorithmException, KeyStoreException, CertificateException, IOException {
Args.notNull(file, "Truststore file");
- final KeyStore trustStore = KeyStore.getInstance(keyStoreType);
- try (final FileInputStream inStream = new FileInputStream(file)) {
- trustStore.load(inStream, storePassword);
- }
- return loadTrustMaterial(trustStore, trustStrategy);
+ return loadTrustMaterial(file.toPath(), storePassword, trustStrategy);
}
public SSLContextBuilder loadTrustMaterial(
@@ -318,11 +337,7 @@ public class SSLContextBuilder {
final char[] storePassword,
final TrustStrategy trustStrategy) throws NoSuchAlgorithmException, KeyStoreException, CertificateException, IOException {
Args.notNull(url, "Truststore URL");
- final KeyStore trustStore = KeyStore.getInstance(keyStoreType);
- try (final InputStream inStream = url.openStream()) {
- trustStore.load(inStream, storePassword);
- }
- return loadTrustMaterial(trustStore, trustStrategy);
+ return loadTrustMaterial(loadKeyStore(url, storePassword), trustStrategy);
}
public SSLContextBuilder loadTrustMaterial(
@@ -332,7 +347,7 @@ public class SSLContextBuilder {
}
public SSLContextBuilder loadKeyMaterial(
- final KeyStore keystore,
+ final KeyStore keyStore,
final char[] keyPassword,
final PrivateKeyStrategy aliasStrategy)
throws NoSuchAlgorithmException, KeyStoreException, UnrecoverableKeyException {
@@ -343,7 +358,7 @@ public class SSLContextBuilder {
final KeyManagerFactory kmFactory = ksProvider == null ?
KeyManagerFactory.getInstance(alg) : KeyManagerFactory.getInstance(alg, ksProvider);
- kmFactory.init(keystore, keyPassword);
+ kmFactory.init(keyStore, keyPassword);
final KeyManager[] kms = kmFactory.getKeyManagers();
if (kms != null) {
if (aliasStrategy != null) {
@@ -359,10 +374,34 @@ public class SSLContextBuilder {
return this;
}
+ /**
+ * @since 5.2
+ */
public SSLContextBuilder loadKeyMaterial(
- final KeyStore keystore,
+ final Path file,
+ final char[] storePassword,
+ final char[] keyPassword,
+ final OpenOption... openOptions) throws NoSuchAlgorithmException, KeyStoreException, UnrecoverableKeyException, CertificateException, IOException {
+ return loadKeyMaterial(file, storePassword, keyPassword, null, openOptions);
+ }
+
+ /**
+ * @since 5.2
+ */
+ public SSLContextBuilder loadKeyMaterial(
+ final Path file,
+ final char[] storePassword,
+ final char[] keyPassword,
+ final PrivateKeyStrategy aliasStrategy,
+ final OpenOption... openOptions) throws NoSuchAlgorithmException, KeyStoreException, UnrecoverableKeyException, CertificateException, IOException {
+ Args.notNull(file, "Keystore file");
+ return loadKeyMaterial(loadKeyStore(file, storePassword, openOptions), keyPassword, aliasStrategy);
+ }
+
+ public SSLContextBuilder loadKeyMaterial(
+ final KeyStore keyStore,
final char[] keyPassword) throws NoSuchAlgorithmException, KeyStoreException, UnrecoverableKeyException {
- return loadKeyMaterial(keystore, keyPassword, null);
+ return loadKeyMaterial(keyStore, keyPassword, null);
}
public SSLContextBuilder loadKeyMaterial(
@@ -371,11 +410,7 @@ public class SSLContextBuilder {
final char[] keyPassword,
final PrivateKeyStrategy aliasStrategy) throws NoSuchAlgorithmException, KeyStoreException, UnrecoverableKeyException, CertificateException, IOException {
Args.notNull(file, "Keystore file");
- final KeyStore identityStore = KeyStore.getInstance(keyStoreType);
- try (final FileInputStream inStream = new FileInputStream(file)) {
- identityStore.load(inStream, storePassword);
- }
- return loadKeyMaterial(identityStore, keyPassword, aliasStrategy);
+ return loadKeyMaterial(file.toPath(), storePassword, keyPassword, aliasStrategy);
}
public SSLContextBuilder loadKeyMaterial(
@@ -391,11 +426,7 @@ public class SSLContextBuilder {
final char[] keyPassword,
final PrivateKeyStrategy aliasStrategy) throws NoSuchAlgorithmException, KeyStoreException, UnrecoverableKeyException, CertificateException, IOException {
Args.notNull(url, "Keystore URL");
- final KeyStore identityStore = KeyStore.getInstance(keyStoreType);
- try (final InputStream inStream = url.openStream()) {
- identityStore.load(inStream, storePassword);
- }
- return loadKeyMaterial(identityStore, keyPassword, aliasStrategy);
+ return loadKeyMaterial(loadKeyStore(url, storePassword), keyPassword, aliasStrategy);
}
public SSLContextBuilder loadKeyMaterial(
@@ -416,6 +447,24 @@ public class SSLContextBuilder {
secureRandom);
}
+ private KeyStore loadKeyStore(final Path file, final char[] password, final OpenOption... openOptions)
+ throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException {
+ final KeyStore keyStore = KeyStore.getInstance(keyStoreType);
+ try (final InputStream inputStream = Files.newInputStream(file, openOptions)) {
+ keyStore.load(inputStream, password);
+ }
+ return keyStore;
+ }
+
+ private KeyStore loadKeyStore(final URL url, final char[] password)
+ throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException {
+ final KeyStore keyStore = KeyStore.getInstance(keyStoreType);
+ try (final InputStream inputStream = url.openStream()) {
+ keyStore.load(inputStream, password);
+ }
+ return keyStore;
+ }
+
public SSLContext build() throws NoSuchAlgorithmException, KeyManagementException {
final SSLContext sslContext;
final String protocolStr = this.protocol != null ? this.protocol : TLS;
@@ -434,7 +483,6 @@ public class SSLContextBuilder {
private final TrustStrategy trustStrategy;
TrustManagerDelegate(final X509TrustManager trustManager, final TrustStrategy trustStrategy) {
- super();
this.trustManager = trustManager;
this.trustStrategy = trustStrategy;
}
@@ -466,7 +514,6 @@ public class SSLContextBuilder {
private final PrivateKeyStrategy aliasStrategy;
KeyManagerDelegate(final X509ExtendedKeyManager keyManager, final PrivateKeyStrategy aliasStrategy) {
- super();
this.keyManager = keyManager;
this.aliasStrategy = aliasStrategy;
}
@@ -481,13 +528,7 @@ public class SSLContextBuilder {
final String[] keyTypes, final Principal[] issuers) {
final Map<String, PrivateKeyDetails> validAliases = new HashMap<>();
for (final String keyType: keyTypes) {
- final String[] aliases = this.keyManager.getClientAliases(keyType, issuers);
- if (aliases != null) {
- for (final String alias: aliases) {
- validAliases.put(alias,
- new PrivateKeyDetails(keyType, this.keyManager.getCertificateChain(alias)));
- }
- }
+ putPrivateKeyDetails(validAliases, keyType, this.keyManager.getClientAliases(keyType, issuers));
}
return validAliases;
}
@@ -495,14 +536,17 @@ public class SSLContextBuilder {
public Map<String, PrivateKeyDetails> getServerAliasMap(
final String keyType, final Principal[] issuers) {
final Map<String, PrivateKeyDetails> validAliases = new HashMap<>();
- final String[] aliases = this.keyManager.getServerAliases(keyType, issuers);
+ putPrivateKeyDetails(validAliases, keyType, this.keyManager.getServerAliases(keyType, issuers));
+ return validAliases;
+ }
+
+ private void putPrivateKeyDetails(final Map<String, PrivateKeyDetails> validAliases, final String keyType,
+ final String[] aliases) {
if (aliases != null) {
for (final String alias: aliases) {
- validAliases.put(alias,
- new PrivateKeyDetails(keyType, this.keyManager.getCertificateChain(alias)));
+ validAliases.put(alias, new PrivateKeyDetails(keyType, this.keyManager.getCertificateChain(alias)));
}
}
- return validAliases;
}
@Override
@@ -553,6 +597,14 @@ public class SSLContextBuilder {
}
+ private Provider requireNonNullProvider(final String name) throws NoSuchProviderException {
+ final Provider provider = Security.getProvider(name);
+ if (provider == null) {
+ throw new NoSuchProviderException(name);
+ }
+ return provider;
+ }
+
@Override
public String toString() {
return "[provider=" + provider + ", protocol=" + protocol + ", keyStoreType=" + keyStoreType
@@ -560,4 +612,5 @@ public class SSLContextBuilder {
+ ", trustManagerFactoryAlgorithm=" + trustManagerFactoryAlgorithm + ", trustManagers=" + trustManagers
+ ", secureRandom=" + secureRandom + "]";
}
+
}
diff --git a/pom.xml b/pom.xml
index 4435050..96de1c8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -78,6 +78,7 @@
<log4j.version>2.8.2</log4j.version>
<rxjava.version>2.2.8</rxjava.version>
<api.comparison.version>5.1</api.comparison.version>
+ <japicmp.version>0.15.4</japicmp.version>
<hc.animal-sniffer.signature.ignores>javax.net.ssl.SSLEngine,javax.net.ssl.SSLParameters</hc.animal-sniffer.signature.ignores>
</properties>
@@ -167,7 +168,7 @@
<plugin>
<groupId>com.github.siom79.japicmp</groupId>
<artifactId>japicmp-maven-plugin</artifactId>
- <version>0.15.3</version>
+ <version>${japicmp.version}</version>
<configuration>
<oldVersion>
<dependency>
@@ -298,7 +299,7 @@
<plugin>
<groupId>com.github.siom79.japicmp</groupId>
<artifactId>japicmp-maven-plugin</artifactId>
- <version>0.15.3</version>
+ <version>${japicmp.version}</version>
<reportSets>
<reportSet>
<reports>