org.elasticsearch.common.ssl.PemTrustConfig Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of elasticsearch-ssl-config Show documentation
Show all versions of elasticsearch-ssl-config Show documentation
Elasticsearch subproject :libs:elasticsearch-ssl-config
The newest version!
/*
* 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", the "GNU Affero General Public License v3.0 only", 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", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/
package org.elasticsearch.common.ssl;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Path;
import java.security.AccessControlException;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509ExtendedTrustManager;
/**
* A {@link org.elasticsearch.common.ssl.SslTrustConfig} that reads a list of PEM encoded trusted certificates (CAs) from the file
* system.
* Strictly speaking, this class does not require PEM certificates, and will load any file that can be read by
* {@link java.security.cert.CertificateFactory#generateCertificate(InputStream)}.
*/
public final class PemTrustConfig implements SslTrustConfig {
private static final String CA_FILE_TYPE = "PEM " + SslConfigurationKeys.CERTIFICATE_AUTHORITIES;
private final List certificateAuthorities;
private final Path basePath;
/**
* Construct a new trust config for the provided paths (which will be resolved relative to the basePath).
* The paths are stored as-is, and are not read until {@link #createTrustManager()} is called.
* This means that
*
* - validation of the file (contents and accessibility) is deferred, and this constructor will not fail on missing
* of invalid files.
* -
* if the contents of the files are modified, then subsequent calls {@link #createTrustManager()} will return a new trust
* manager that trust a different set of CAs.
*
*
*/
public PemTrustConfig(List certificateAuthorities, Path basePath) {
this.certificateAuthorities = Collections.unmodifiableList(certificateAuthorities);
this.basePath = basePath;
}
@Override
public Collection getDependentFiles() {
return resolveFiles();
}
@Override
public Collection extends StoredCertificate> getConfiguredCertificates() {
final List info = new ArrayList<>(certificateAuthorities.size());
for (String caPath : certificateAuthorities) {
for (Certificate cert : readCertificates(List.of(resolveFile(caPath)))) {
if (cert instanceof X509Certificate) {
info.add(new StoredCertificate((X509Certificate) cert, caPath, "PEM", null, false));
}
}
}
return info;
}
@Override
public X509ExtendedTrustManager createTrustManager() {
final List paths = resolveFiles();
try {
final List certificates = readCertificates(paths);
final KeyStore store = KeyStoreUtil.buildTrustStore(certificates);
return KeyStoreUtil.createTrustManager(store, TrustManagerFactory.getDefaultAlgorithm());
} catch (GeneralSecurityException e) {
throw new SslConfigException("cannot create trust using PEM certificates [" + SslFileUtil.pathsToString(paths) + "]", e);
}
}
private List resolveFiles() {
return this.certificateAuthorities.stream().map(this::resolveFile).toList();
}
private Path resolveFile(String other) {
return basePath.resolve(other);
}
private List readCertificates(List paths) {
try {
return PemUtils.readCertificates(paths);
} catch (AccessControlException e) {
throw SslFileUtil.accessControlFailure(CA_FILE_TYPE, paths, e, basePath);
} catch (IOException e) {
throw SslFileUtil.ioException(CA_FILE_TYPE, paths, e);
} catch (GeneralSecurityException e) {
throw SslFileUtil.securityException(CA_FILE_TYPE, paths, e);
} catch (SslConfigException e) {
throw SslFileUtil.configException(CA_FILE_TYPE, paths, e);
}
}
@Override
public String toString() {
return "PEM-trust{" + SslFileUtil.pathsToString(resolveFiles()) + "}";
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final PemTrustConfig that = (PemTrustConfig) o;
return Objects.equals(this.certificateAuthorities, that.certificateAuthorities);
}
@Override
public int hashCode() {
return Objects.hash(certificateAuthorities);
}
}