Skip to content

Commit

Permalink
Update "ssl-config" to support X-Pack features (elastic#74887)
Browse files Browse the repository at this point in the history
This commit upgrades the existing SSPL licensed "ssl-config" library
to include additional features that are supported by the X-Pack SSL
library.

This commit does not make any changes to X-Pack to use these new
features - it introduces them in preparation for their future use by
X-Pack.

The reindex module is updated to reflect API changes in ssl-config
  • Loading branch information
tvernum authored and ywangd committed Jul 30, 2021
1 parent 42d3daa commit 2893098
Show file tree
Hide file tree
Showing 26 changed files with 1,342 additions and 303 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

package org.elasticsearch.common.ssl;

import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509ExtendedTrustManager;
import java.nio.file.Path;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
* A TrustConfiguration that merges trust anchors from a number of other trust configs to produce a single {@link X509ExtendedTrustManager}.
*/
public class CompositeTrustConfig implements SslTrustConfig {
private final List<SslTrustConfig> configs;

CompositeTrustConfig(List<SslTrustConfig> configs) {
this.configs = List.copyOf(configs);
}

@Override
public Collection<Path> getDependentFiles() {
return configs.stream().map(SslTrustConfig::getDependentFiles).flatMap(Collection::stream).collect(Collectors.toUnmodifiableSet());
}

@Override
public boolean isSystemDefault() {
return configs.stream().allMatch(SslTrustConfig::isSystemDefault);
}

@Override
public X509ExtendedTrustManager createTrustManager() {
try {
Collection<Certificate> trustedIssuers = configs.stream()
.map(c -> c.createTrustManager())
.map(tm -> tm.getAcceptedIssuers())
.flatMap(Arrays::stream)
.collect(Collectors.toSet());
final KeyStore store = KeyStoreUtil.buildTrustStore(trustedIssuers);
return KeyStoreUtil.createTrustManager(store, TrustManagerFactory.getDefaultAlgorithm());
} catch (GeneralSecurityException e) {
throw new SslConfigException("Cannot combine trust configurations ["
+ configs.stream().map(SslTrustConfig::toString).collect(Collectors.joining(","))
+ "]",
e);
}
}

@Override
public Collection<? extends StoredCertificate> getConfiguredCertificates() {
return configs.stream().map(SslTrustConfig::getConfiguredCertificates)
.flatMap(Collection::stream)
.collect(Collectors.toUnmodifiableList());
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CompositeTrustConfig that = (CompositeTrustConfig) o;
return configs.equals(that.configs);
}

@Override
public int hashCode() {
return Objects.hash(configs);
}

@Override
public String toString() {
return "Composite-Trust{" + configs.stream().map(SslTrustConfig::toString).collect(Collectors.joining(",")) + '}';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,15 @@
import java.security.KeyStore;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.function.BiFunction;

/**
* This class represents a trust configuration that corresponds to the default trusted CAs of the JDK
*/
final class DefaultJdkTrustConfig implements SslTrustConfig {
public final class DefaultJdkTrustConfig implements SslTrustConfig {

public static final DefaultJdkTrustConfig DEFAULT_INSTANCE = new DefaultJdkTrustConfig();

private final BiFunction<String, String, String> systemProperties;
private final char[] trustStorePassword;
Expand All @@ -51,6 +53,11 @@ final class DefaultJdkTrustConfig implements SslTrustConfig {
this.trustStorePassword = trustStorePassword;
}

@Override
public boolean isSystemDefault() {
return true;
}

@Override
public X509ExtendedTrustManager createTrustManager() {
try {
Expand Down Expand Up @@ -90,7 +97,12 @@ private static char[] getSystemTrustStorePassword(BiFunction<String, String, Str

@Override
public Collection<Path> getDependentFiles() {
return Collections.emptyList();
return List.of();
}

@Override
public Collection<? extends StoredCertificate> getConfiguredCertificates() {
return List.of();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
* Based on https://github.com/groovenauts/jmeter_oauth_plugin/blob/master/jmeter/src/
* main/java/org/apache/jmeter/protocol/oauth/sampler/PrivateKeyReader.java
*/
final class DerParser {
public final class DerParser {
// Constructed Flag
private static final int CONSTRUCTED = 0x20;

Expand All @@ -55,12 +55,12 @@ final class DerParser {
private InputStream derInputStream;
private int maxAsnObjectLength;

DerParser(byte[] bytes) {
public DerParser(byte[] bytes) {
this.derInputStream = new ByteArrayInputStream(bytes);
this.maxAsnObjectLength = bytes.length;
}

Asn1Object readAsn1Object() throws IOException {
public Asn1Object readAsn1Object() throws IOException {
int tag = derInputStream.read();
if (tag == -1) {
throw new IOException("Invalid DER: stream too short, missing tag");
Expand Down Expand Up @@ -133,7 +133,7 @@ private int getLength() throws IOException {
*
* @author zhang
*/
static class Asn1Object {
public static class Asn1Object {

protected final int type;
protected final int length;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,45 @@

package org.elasticsearch.common.ssl;

import javax.net.ssl.X509ExtendedKeyManager;
import org.elasticsearch.core.Tuple;

import java.nio.file.Path;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import javax.net.ssl.X509ExtendedKeyManager;

/**
* A {@link SslKeyConfig} that does nothing (provides a null key manager)
*/
final class EmptyKeyConfig implements SslKeyConfig {
public final class EmptyKeyConfig implements SslKeyConfig {

static final EmptyKeyConfig INSTANCE = new EmptyKeyConfig();
public static final EmptyKeyConfig INSTANCE = new EmptyKeyConfig();

private EmptyKeyConfig() {
// Enforce a single instance
}

@Override
public Collection<Path> getDependentFiles() {
return Collections.emptyList();
return List.of();
}

@Override
public List<Tuple<PrivateKey, X509Certificate>> getKeys() {
return List.of();
}

@Override
public Collection<StoredCertificate> getConfiguredCertificates() {
return List.of();
}

@Override
public boolean hasKeyMaterial() {
return false;
}

@Override
Expand Down
Loading

0 comments on commit 2893098

Please sign in to comment.