Skip to content

Commit

Permalink
TLS PSK implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
sunnysingh85 committed May 17, 2024
1 parent 305325e commit 29124da
Show file tree
Hide file tree
Showing 5 changed files with 566 additions and 11 deletions.
5 changes: 3 additions & 2 deletions zuul-core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ dependencies {
implementation libraries.guava
// TODO(carl-mastrangelo): this can be implementation; remove Logger from public api points.
api libraries.slf4j
implementation 'org.bouncycastle:bcprov-jdk18on:1.76'
implementation 'org.bouncycastle:bcpkix-jdk18on:1.76'
implementation 'org.bouncycastle:bcprov-jdk18on:1.78'
implementation 'org.bouncycastle:bcpkix-jdk18on:1.78'
implementation 'org.bouncycastle:bctls-jdk18on:1.78'
implementation 'com.fasterxml.jackson.core:jackson-core:2.16.1'
api 'com.fasterxml.jackson.core:jackson-databind:2.16.1'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import com.netflix.netty.common.channel.config.CommonChannelConfigKeys;
import com.netflix.netty.common.http2.DynamicHttp2FrameLogger;
import com.netflix.zuul.netty.server.BaseZuulChannelInitializer;
import com.netflix.zuul.netty.server.psk.TlsPskHandler;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline;
Expand All @@ -33,7 +34,9 @@
import io.netty.handler.logging.LogLevel;
import io.netty.handler.ssl.ApplicationProtocolNames;
import io.netty.handler.ssl.ApplicationProtocolNegotiationHandler;
import io.netty.handler.ssl.SslHandshakeCompletionEvent;
import io.netty.util.AttributeKey;

import java.util.function.Consumer;

/**
Expand All @@ -45,6 +48,8 @@
public class Http2OrHttpHandler extends ApplicationProtocolNegotiationHandler {
public static final AttributeKey<String> PROTOCOL_NAME = AttributeKey.valueOf("protocol_name");

private static final String FALLBACK_APPLICATION_PROTOCOL = ApplicationProtocolNames.HTTP_1_1;

private static final DynamicHttp2FrameLogger FRAME_LOGGER =
new DynamicHttp2FrameLogger(LogLevel.DEBUG, Http2FrameCodec.class);

Expand All @@ -60,7 +65,7 @@ public Http2OrHttpHandler(
ChannelHandler http2StreamHandler,
ChannelConfig channelConfig,
Consumer<ChannelPipeline> addHttpHandlerFn) {
super(ApplicationProtocolNames.HTTP_1_1);
super(FALLBACK_APPLICATION_PROTOCOL);
this.http2StreamHandler = http2StreamHandler;
this.maxConcurrentStreams = channelConfig.get(CommonChannelConfigKeys.maxConcurrentStreams);
this.initialWindowSize = channelConfig.get(CommonChannelConfigKeys.initialWindowSize);
Expand All @@ -70,6 +75,42 @@ public Http2OrHttpHandler(
this.addHttpHandlerFn = addHttpHandlerFn;
}

@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
if (evt instanceof SslHandshakeCompletionEvent handshakeEvent) {
if (handshakeEvent.isSuccess()) {
TlsPskHandler tlsPskHandler = ctx.channel().pipeline().get(TlsPskHandler.class);
if (tlsPskHandler != null) {
// PSK mode
try {
String tlsPskApplicationProtocol = tlsPskHandler.getApplicationProtocol();
configurePipeline(
ctx,
tlsPskApplicationProtocol != null
? tlsPskApplicationProtocol
: FALLBACK_APPLICATION_PROTOCOL);
} catch (Throwable cause) {
exceptionCaught(ctx, cause);
} finally {
// Handshake failures are handled in exceptionCaught(...).
if (handshakeEvent.isSuccess()) {
removeSelfIfPresent(ctx);
}
}
} else {
// non PSK mode
super.userEventTriggered(ctx, evt);
}
} else {
// handshake failures
// TODO sunnys - handle PSK handshake failures
super.userEventTriggered(ctx, evt);
}
} else {
super.userEventTriggered(ctx, evt);
}
}

@Override
protected void configurePipeline(ChannelHandlerContext ctx, String protocol) throws Exception {
if (ApplicationProtocolNames.HTTP_2.equals(protocol)) {
Expand Down Expand Up @@ -118,4 +159,11 @@ private void configureHttp2(ChannelPipeline pipeline) {
private void configureHttp1(ChannelPipeline pipeline) {
addHttpHandlerFn.accept(pipeline);
}

private void removeSelfIfPresent(ChannelHandlerContext ctx) {
ChannelPipeline pipeline = ctx.pipeline();
if (!ctx.isRemoved()) {
pipeline.remove(this);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright 2024 Netflix, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.netflix.zuul.netty.server.psk;

import org.bouncycastle.tls.TlsPSKExternal;

import java.util.Vector;

public interface ExternalTlsPskProvider {
TlsPSKExternal provide(Vector clientPskIdentities);
}
Loading

0 comments on commit 29124da

Please sign in to comment.