From af16eec5128b861180c7569b06d1c9539b012d1f Mon Sep 17 00:00:00 2001 From: jaymode Date: Tue, 2 Aug 2016 14:07:16 -0400 Subject: [PATCH] fix PKI cert extraction Original commit: elastic/x-pack-elasticsearch@9c686115579eea0eee9fdf909cabbffd2367fc89 --- .../transport/ServerTransportFilter.java | 46 +++++++++++-------- .../netty4/SecurityNetty4Transport.java | 6 ++- 2 files changed, 33 insertions(+), 19 deletions(-) diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/transport/ServerTransportFilter.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/transport/ServerTransportFilter.java index bc17f7fe4ea..a942fbecce7 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/transport/ServerTransportFilter.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/transport/ServerTransportFilter.java @@ -5,6 +5,7 @@ */ package org.elasticsearch.xpack.security.transport; +import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLPeerUnverifiedException; import java.io.IOException; import java.security.cert.Certificate; @@ -81,30 +82,39 @@ public interface ServerTransportFilter { unwrappedChannel = ((DelegatingTransportChannel) unwrappedChannel).getChannel(); } - if (extractClientCert && (unwrappedChannel instanceof TcpTransportChannel) - && ((TcpTransportChannel) unwrappedChannel).getChannel() instanceof Channel) { - Channel channel = (Channel) ((TcpTransportChannel) unwrappedChannel).getChannel(); - SslHandler sslHandler = channel.getPipeline().get(SslHandler.class); - assert sslHandler != null; - - try { - Certificate[] certs = sslHandler.getEngine().getSession().getPeerCertificates(); - if (certs instanceof X509Certificate[]) { - threadContext.putTransient(PkiRealm.PKI_CERT_HEADER_NAME, certs); - } - } catch (SSLPeerUnverifiedException e) { - // this happens when we only request client authentication and the client does not provide it - if (logger.isTraceEnabled()) { - logger.trace("SSL Peer did not present a certificate on channel [{}]", e, channel); - } else if (logger.isDebugEnabled()) { - logger.debug("SSL Peer did not present a certificate on channel [{}]", channel); - } + if (extractClientCert && (unwrappedChannel instanceof TcpTransportChannel)) { + if (((TcpTransportChannel) unwrappedChannel).getChannel() instanceof Channel) { + Channel channel = (Channel) ((TcpTransportChannel) unwrappedChannel).getChannel(); + SslHandler sslHandler = channel.getPipeline().get(SslHandler.class); + assert sslHandler != null; + extactClientCertificates(sslHandler.getEngine(), channel); + } else if (((TcpTransportChannel) unwrappedChannel).getChannel() instanceof io.netty.channel.Channel) { + io.netty.channel.Channel channel = (io.netty.channel.Channel) ((TcpTransportChannel) unwrappedChannel).getChannel(); + io.netty.handler.ssl.SslHandler sslHandler = channel.pipeline().get(io.netty.handler.ssl.SslHandler.class); + assert sslHandler != null; + extactClientCertificates(sslHandler.engine(), channel); } } Authentication authentication = authcService.authenticate(securityAction, request, null); authzService.authorize(authentication, securityAction, request); } + + private void extactClientCertificates(SSLEngine sslEngine, Object channel) { + try { + Certificate[] certs = sslEngine.getSession().getPeerCertificates(); + if (certs instanceof X509Certificate[]) { + threadContext.putTransient(PkiRealm.PKI_CERT_HEADER_NAME, certs); + } + } catch (SSLPeerUnverifiedException e) { + // this happens when we only request client authentication and the client does not provide it + if (logger.isTraceEnabled()) { + logger.trace("SSL Peer did not present a certificate on channel [{}]", e, channel); + } else if (logger.isDebugEnabled()) { + logger.debug("SSL Peer did not present a certificate on channel [{}]", channel); + } + } + } } /** diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/transport/netty4/SecurityNetty4Transport.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/transport/netty4/SecurityNetty4Transport.java index ec85aadea24..a024e9801f5 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/transport/netty4/SecurityNetty4Transport.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/transport/netty4/SecurityNetty4Transport.java @@ -45,7 +45,7 @@ import static org.elasticsearch.xpack.security.transport.netty3.SecurityNetty3Tr import static org.elasticsearch.xpack.security.transport.netty3.SecurityNetty3Transport.SSL_SETTING; /** - * + * Implementation of a transport that extends the {@link Netty4Transport} to add SSL and IP Filtering */ public class SecurityNetty4Transport extends Netty4Transport { @@ -86,6 +86,10 @@ public class SecurityNetty4Transport extends Netty4Transport { return new SecurityClientChannelInitializer(); } + /** + * This method ensures that all channels have their SSL handshakes completed. This is necessary to prevent the application from + * writing data while the handshake is in progress which could cause the handshake to fail. + */ @Override protected void onAfterChannelsConnected(NodeChannels nodeChannels) { for (Channel channel : nodeChannels.allChannels) {