diff --git a/src/main/java/org/opensearch/security/ssl/util/SSLRequestHelper.java b/src/main/java/org/opensearch/security/ssl/util/SSLRequestHelper.java index 2dd4bef9c4..77638b1648 100644 --- a/src/main/java/org/opensearch/security/ssl/util/SSLRequestHelper.java +++ b/src/main/java/org/opensearch/security/ssl/util/SSLRequestHelper.java @@ -17,9 +17,12 @@ package org.opensearch.security.ssl.util; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; import java.nio.file.Path; import java.security.GeneralSecurityException; import java.security.KeyStore; @@ -31,6 +34,7 @@ import java.security.cert.TrustAnchor; import java.security.cert.X509Certificate; import java.util.Arrays; +import java.util.Base64; import java.util.Collection; import java.util.Date; import java.util.Enumeration; @@ -66,13 +70,17 @@ public static class SSLInfo { private final String principal; private final String protocol; private final String cipher; + private final X509Certificate[] headerCerts; + private final String headerPrincipal; public SSLInfo( final X509Certificate[] x509Certs, final String principal, final String protocol, final String cipher, - X509Certificate[] localCertificates + X509Certificate[] localCertificates, + final X509Certificate[] headerCerts, + final String headerPrincipal ) { super(); this.x509Certs = x509Certs; @@ -80,6 +88,8 @@ public SSLInfo( this.protocol = protocol; this.cipher = cipher; this.localCertificates = localCertificates; + this.headerCerts = headerCerts; + this.headerPrincipal = headerPrincipal; } public X509Certificate[] getX509Certs() { @@ -131,9 +141,32 @@ public static SSLInfo getSSLInfo( final SSLSession session = engine.getSession(); X509Certificate[] x509Certs = null; + X509Certificate[] x509HeaderCerts = null; final String protocol = session.getProtocol(); final String cipher = session.getCipherSuite(); String principal = null; + String headerCertPrincipal = null; + final String clientCertHeaderName = settings.get("clientCertHeaderName", "ClientCert"); + final boolean isURLEncoded = Boolean.parseBoolean(settings.get("isURLEncoded", "true")); + + String clientCertEncoded = request.header(clientCertHeaderName); + if (isURLEncoded) { + String clientCertFromHeader = URLDecoder.decode(clientCertEncoded, StandardCharsets.UTF_8); + byte[] decodedClientCert = Base64.getDecoder().decode(clientCertFromHeader); + + CertificateFactory factory = null; + try { + factory = CertificateFactory.getInstance("X.509"); + x509HeaderCerts = new X509Certificate[1]; + x509HeaderCerts[0] = (X509Certificate) factory.generateCertificate(new ByteArrayInputStream(decodedClientCert)); + headerCertPrincipal = principalExtractor == null + ? null + : principalExtractor.extractPrincipal(x509HeaderCerts[0], Type.HTTP); + } catch (CertificateException e) { + + } + + } if (engine.getNeedClientAuth() || engine.getWantClientAuth()) { Certificate[] certs = null; @@ -157,7 +190,7 @@ public static SSLInfo getSSLInfo( localCerts = Arrays.stream(session.getLocalCertificates()).map(X509Certificate.class::cast).toArray(X509Certificate[]::new); } - return new SSLInfo(x509Certs, principal, protocol, cipher, localCerts); + return new SSLInfo(x509Certs, principal, protocol, cipher, localCerts, x509HeaderCerts, headerCertPrincipal); } private static void validatePeerCerts(final X509Certificate[] x509Certs, final Settings settings, final Path configPath) diff --git a/src/test/java/org/opensearch/security/ssl/util/SSLRequestHelperTest.java b/src/test/java/org/opensearch/security/ssl/util/SSLRequestHelperTest.java index 8baf65a787..57612738fe 100644 --- a/src/test/java/org/opensearch/security/ssl/util/SSLRequestHelperTest.java +++ b/src/test/java/org/opensearch/security/ssl/util/SSLRequestHelperTest.java @@ -158,7 +158,15 @@ public void configureValidator_leavesDateNull_whenTimestampIsNegative() throws E @Test public void sslInfoToString_containsAllFields() { - SSLRequestHelper.SSLInfo info = new SSLRequestHelper.SSLInfo(null, "CN=test", "TLSv1.3", "TLS_AES_256_GCM_SHA384", null); + SSLRequestHelper.SSLInfo info = new SSLRequestHelper.SSLInfo( + null, + "CN=test", + "TLSv1.3", + "TLS_AES_256_GCM_SHA384", + null, + null, + null + ); assertThat(info.toString(), is("SSLInfo [x509Certs=null, principal=CN=test, protocol=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384]")); }