SSL/TLS configuration library for Elasticsearch providing comprehensive security management utilities.
—
Advanced diagnostic capabilities for troubleshooting SSL trust failures, certificate issues, and connection problems with detailed error reporting and trust validation analysis.
Comprehensive diagnostic engine for analyzing SSL trust failures and providing detailed troubleshooting information.
/**
* SSL diagnostics for troubleshooting trust failures
*/
public class SslDiagnostics {
/**
* Singleton instance for SSL diagnostics
*/
public static final SslDiagnostics INSTANCE;
/**
* Creates SSL diagnostics with custom clock
* @param clock clock for timestamp generation in diagnostics
*/
public SslDiagnostics(Clock clock);
/**
* Gets comprehensive diagnostic information for SSL trust failures
* @param chain certificate chain that failed validation
* @param peerType type of peer (CLIENT or SERVER)
* @param session SSL session information
* @param contextName descriptive name for the SSL context
* @param trustedIssuers map of trusted issuer DN to certificate lists (optional)
* @return detailed diagnostic message explaining the trust failure
*/
public String getTrustDiagnosticFailure(X509Certificate[] chain, PeerType peerType,
SSLSession session, String contextName,
@Nullable Map<String, List<X509Certificate>> trustedIssuers);
/**
* Describes valid hostnames for a certificate
* @param certificate X509 certificate to analyze
* @return list of valid hostname patterns from certificate
*/
public static List<String> describeValidHostnames(X509Certificate certificate);
/**
* Checks issuer trust status for a certificate
* @param trustedIssuers map of trusted issuer DN to certificate lists
* @param peerCert certificate to check issuer trust for
* @return issuer trust analysis result
*/
public static IssuerTrust checkIssuerTrust(Map<String, List<X509Certificate>> trustedIssuers,
X509Certificate peerCert);
}Usage Examples:
import org.elasticsearch.common.ssl.SslDiagnostics;
import org.elasticsearch.common.ssl.SslDiagnostics.PeerType;
import javax.net.ssl.SSLSession;
import java.security.cert.X509Certificate;
import java.util.List;
import java.util.Map;
// Get diagnostic information for trust failure
X509Certificate[] failedChain = // ... certificate chain that failed validation
SSLSession session = // ... SSL session
Map<String, List<X509Certificate>> trustedIssuers = // ... trusted CA certificates
String diagnostic = SslDiagnostics.INSTANCE.getTrustDiagnosticFailure(
failedChain,
PeerType.SERVER, // analyzing server certificate
session,
"Elasticsearch HTTPS connection", // context description
trustedIssuers // trusted CAs for comparison
);
System.out.println("SSL Trust Failure Diagnosis:");
System.out.println(diagnostic);
// Analyze certificate hostname validity
X509Certificate serverCert = failedChain[0];
List<String> validHostnames = SslDiagnostics.describeValidHostnames(serverCert);
System.out.println("Certificate is valid for hostnames: " + validHostnames);
// Check issuer trust
SslDiagnostics.IssuerTrust issuerTrust = SslDiagnostics.checkIssuerTrust(
trustedIssuers,
serverCert
);
System.out.println("Issuer trust status: " + issuerTrust);Enumeration for SSL peer types in diagnostic analysis.
/**
* SSL peer types for diagnostic analysis
*/
public enum PeerType {
/**
* Client peer (analyzing client certificate)
*/
CLIENT,
/**
* Server peer (analyzing server certificate)
*/
SERVER
}X509ExtendedTrustManager wrapper that provides detailed diagnostic logging for SSL trust operations and failures.
/**
* Trust manager wrapper that provides diagnostic logging for SSL trust failures
*/
public final class DiagnosticTrustManager extends X509ExtendedTrustManager {
/**
* Creates diagnostic trust manager wrapper
* @param delegate underlying trust manager to wrap
* @param contextName supplier for context name in diagnostic messages
* @param logger logger for diagnostic messages
*/
public DiagnosticTrustManager(X509ExtendedTrustManager delegate,
Supplier<String> contextName,
DiagnosticLogger logger);
/**
* Checks client certificate trust with socket context and diagnostic logging
* @param chain client certificate chain to validate
* @param authType authentication type
* @param socket SSL socket for context
* @throws CertificateException if certificate validation fails
*/
public void checkClientTrusted(X509Certificate[] chain, String authType, Socket socket)
throws CertificateException;
/**
* Checks server certificate trust with socket context and diagnostic logging
* @param chain server certificate chain to validate
* @param authType authentication type
* @param socket SSL socket for context
* @throws CertificateException if certificate validation fails
*/
public void checkServerTrusted(X509Certificate[] chain, String authType, Socket socket)
throws CertificateException;
/**
* Checks client certificate trust with SSL engine context and diagnostic logging
* @param chain client certificate chain to validate
* @param authType authentication type
* @param engine SSL engine for context
* @throws CertificateException if certificate validation fails
*/
public void checkClientTrusted(X509Certificate[] chain, String authType, SSLEngine engine)
throws CertificateException;
/**
* Checks server certificate trust with SSL engine context and diagnostic logging
* @param chain server certificate chain to validate
* @param authType authentication type
* @param engine SSL engine for context
* @throws CertificateException if certificate validation fails
*/
public void checkServerTrusted(X509Certificate[] chain, String authType, SSLEngine engine)
throws CertificateException;
/**
* Checks client certificate trust with basic context and diagnostic logging
* @param chain client certificate chain to validate
* @param authType authentication type
* @throws CertificateException if certificate validation fails
*/
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException;
/**
* Checks server certificate trust with basic context and diagnostic logging
* @param chain server certificate chain to validate
* @param authType authentication type
* @throws CertificateException if certificate validation fails
*/
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException;
/**
* Gets accepted certificate authorities from underlying trust manager
* @return array of accepted CA certificates
*/
public X509Certificate[] getAcceptedIssuers();
}Functional interface for diagnostic message logging.
/**
* Functional interface for diagnostic message logging
*/
@FunctionalInterface
public interface DiagnosticLogger {
/**
* Logs diagnostic warning message with exception cause
* @param message diagnostic message to log
* @param cause underlying security exception that triggered the diagnostic
*/
void warning(String message, GeneralSecurityException cause);
}Usage Examples:
import org.elasticsearch.common.ssl.DiagnosticTrustManager;
import org.elasticsearch.common.ssl.DiagnosticTrustManager.DiagnosticLogger;
import javax.net.ssl.X509ExtendedTrustManager;
import java.util.function.Supplier;
import java.util.logging.Logger;
// Create diagnostic logger
DiagnosticLogger logger = (message, cause) -> {
Logger.getLogger("ssl-diagnostics").warning(message + " - " + cause.getMessage());
};
// Create diagnostic trust manager
X509ExtendedTrustManager baseTrustManager = // ... base trust manager
DiagnosticTrustManager diagnosticTrustManager = new DiagnosticTrustManager(
baseTrustManager,
() -> "Elasticsearch cluster connection", // context name
logger // diagnostic logger
);
// Use diagnostic trust manager in SSL context
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(
keyManagers,
new TrustManager[] { diagnosticTrustManager }, // use diagnostic wrapper
secureRandom
);
// When trust failures occur, detailed diagnostic messages will be logged:
// "SSL trust failed for Elasticsearch cluster connection: Certificate hostname mismatch.
// Expected: [elasticsearch.example.com], Found: [old-server.example.com]"Implement custom diagnostic logging for different use cases:
// Console diagnostic logger
DiagnosticLogger consoleLogger = (message, cause) -> {
System.err.println("SSL DIAGNOSTIC: " + message);
if (cause != null) {
System.err.println("Caused by: " + cause.getClass().getSimpleName() + ": " + cause.getMessage());
}
};
// File-based diagnostic logger
DiagnosticLogger fileLogger = (message, cause) -> {
try (FileWriter writer = new FileWriter("ssl-diagnostics.log", true)) {
writer.write(String.format("[%s] %s%n", Instant.now(), message));
if (cause != null) {
writer.write(String.format("Caused by: %s%n", cause.toString()));
}
} catch (IOException e) {
// Handle logging error
}
};
// Structured logging with JSON
DiagnosticLogger jsonLogger = (message, cause) -> {
JsonObject diagnostic = new JsonObject();
diagnostic.addProperty("timestamp", Instant.now().toString());
diagnostic.addProperty("message", message);
diagnostic.addProperty("context", "ssl-trust-validation");
if (cause != null) {
diagnostic.addProperty("exception", cause.getClass().getSimpleName());
diagnostic.addProperty("exceptionMessage", cause.getMessage());
}
logger.warn(diagnostic.toString());
};Use diagnostic utilities for certificate analysis:
import org.elasticsearch.common.ssl.SslDiagnostics;
import java.security.cert.X509Certificate;
import java.util.List;
// Analyze certificate hostname validity
public void analyzeCertificate(X509Certificate cert) {
List<String> hostnames = SslDiagnostics.describeValidHostnames(cert);
System.out.println("Certificate Analysis:");
System.out.println("Subject: " + cert.getSubjectX500Principal().getName());
System.out.println("Issuer: " + cert.getIssuerX500Principal().getName());
System.out.println("Valid hostnames: " + String.join(", ", hostnames));
System.out.println("Valid from: " + cert.getNotBefore());
System.out.println("Valid until: " + cert.getNotAfter());
// Check if certificate is currently valid
try {
cert.checkValidity();
System.out.println("Certificate is currently valid");
} catch (Exception e) {
System.out.println("Certificate validity issue: " + e.getMessage());
}
}
// Check hostname match
public boolean checkHostnameMatch(X509Certificate cert, String hostname) {
List<String> validHostnames = SslDiagnostics.describeValidHostnames(cert);
return validHostnames.stream().anyMatch(pattern -> {
if (pattern.startsWith("*.")) {
// Wildcard match
String domain = pattern.substring(2);
return hostname.endsWith("." + domain) || hostname.equals(domain);
} else {
// Exact match
return hostname.equalsIgnoreCase(pattern);
}
});
}Comprehensive analysis of trust failures:
public void analyzeTrustFailure(X509Certificate[] chain, Map<String, List<X509Certificate>> trustedIssuers) {
// Check each certificate in the chain
for (int i = 0; i < chain.length; i++) {
X509Certificate cert = chain[i];
System.out.println("Certificate " + i + ":");
System.out.println(" Subject: " + cert.getSubjectX500Principal().getName());
System.out.println(" Issuer: " + cert.getIssuerX500Principal().getName());
// Check issuer trust
SslDiagnostics.IssuerTrust issuerTrust = SslDiagnostics.checkIssuerTrust(trustedIssuers, cert);
System.out.println(" Issuer trust: " + issuerTrust);
// Check validity period
try {
cert.checkValidity();
System.out.println(" Validity: OK");
} catch (Exception e) {
System.out.println(" Validity: FAILED - " + e.getMessage());
}
}
// Get comprehensive diagnostic
String diagnostic = SslDiagnostics.INSTANCE.getTrustDiagnosticFailure(
chain,
SslDiagnostics.PeerType.SERVER,
null, // no session info
"Trust Analysis",
trustedIssuers
);
System.out.println("\nDetailed Diagnostic:");
System.out.println(diagnostic);
}The diagnostic system provides detailed, human-readable error messages:
SSL trust failed for Elasticsearch HTTPS connection: Certificate hostname verification failed.
Certificate is valid for: [old-server.example.com, *.old-domain.com]
Requested hostname: elasticsearch.example.comSSL trust failed for Elasticsearch HTTPS connection: Certificate signed by untrusted authority.
Certificate issuer: CN=Internal CA, O=Example Corp
Trusted authorities: [29 certificates including CN=DigiCert Global Root CA, CN=Let's Encrypt Authority X3, ...]SSL trust failed for Elasticsearch HTTPS connection: Certificate has expired.
Certificate valid from: 2023-01-01T00:00:00Z
Certificate expired on: 2024-01-01T00:00:00Z
Current time: 2024-02-15T10:30:00ZSSL trust failed for Elasticsearch HTTPS connection: Unable to build certificate chain.
End entity certificate: CN=elasticsearch.example.com
Missing intermediate certificate: CN=Example Intermediate CA
Available trusted roots: [CN=Example Root CA, CN=DigiCert Global Root CA, ...]Install with Tessl CLI
npx tessl i tessl/maven-org-elasticsearch--elasticsearch-ssl-config