Skip to content

Commit

Permalink
UNDERTOW-750 Add built in SNI support
Browse files Browse the repository at this point in the history
  • Loading branch information
stuartwdouglas committed Aug 8, 2018
1 parent 16e156e commit 36d3908
Show file tree
Hide file tree
Showing 17 changed files with 2,386 additions and 89 deletions.
20 changes: 20 additions & 0 deletions core/src/main/java/io/undertow/UndertowMessages.java
Expand Up @@ -20,6 +20,8 @@

import java.io.IOException;
import java.nio.channels.ClosedChannelException;

import javax.net.ssl.SSLException;
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.SSLPeerUnverifiedException;

Expand Down Expand Up @@ -574,4 +576,22 @@ public interface UndertowMessages {

@Message(id = 185, value = "Invalid IP address %s")
IOException invalidIpAddress(String addressString);

@Message(id = 186, value = "Invalid TLS extension")
SSLException invalidTlsExt();

@Message(id = 187, value = "Not enough data")
SSLException notEnoughData();

@Message(id = 188, value = "Empty host name in SNI extension")
SSLException emptyHostNameSni();

@Message(id = 189, value = "Duplicated host name of type %s")
SSLException duplicatedSniServerName(int type);

@Message(id = 190, value = "No context for SSL connection")
SSLException noContextForSslConnection();

@Message(id = 191, value = "Default context cannot be null")
IllegalStateException defaultContextCannotBeNull();
}
@@ -0,0 +1,36 @@
/*
* JBoss, Home of Professional Open Source.
* Copyright 2018 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
* 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 io.undertow.protocols.alpn;

import java.util.function.Function;

import javax.net.ssl.SSLEngine;

public interface ALPNEngineManager {

/**
* @return The priority of this provider, higher priority managers will be tried first
*/
int getPriority();

/**
* @param engine The original SSL Engine
* @param selectedFunction A function that must be called when the Underlying SSL engine has been selected. The return value of this callback may be a wrapped engine, which must replace the selected engine
* @return <code>true</code> if the engine was registered, false otherwise
*/
boolean registerEngine(SSLEngine engine, Function<SSLEngine, SSLEngine> selectedFunction);

}
31 changes: 28 additions & 3 deletions core/src/main/java/io/undertow/protocols/alpn/ALPNManager.java
Expand Up @@ -23,6 +23,8 @@
import java.util.Comparator;
import java.util.List;
import java.util.ServiceLoader;
import java.util.function.Function;

import javax.net.ssl.SSLEngine;

/**
Expand All @@ -31,13 +33,14 @@
public class ALPNManager {

private final ALPNProvider[] alpnProviders;
private final ALPNEngineManager[] alpnEngineManagers;

public static final ALPNManager INSTANCE = new ALPNManager(ALPNManager.class.getClassLoader());

public ALPNManager(ClassLoader classLoader) {
ServiceLoader<ALPNProvider> loader = ServiceLoader.load(ALPNProvider.class, classLoader);
List<ALPNProvider> provider = new ArrayList<>();
for(ALPNProvider prov : loader) {
for (ALPNProvider prov : loader) {
provider.add(prov);
}
Collections.sort(provider, new Comparator<ALPNProvider>() {
Expand All @@ -47,15 +50,37 @@ public int compare(ALPNProvider o1, ALPNProvider o2) {
}
});
this.alpnProviders = provider.toArray(new ALPNProvider[0]);

ServiceLoader<ALPNEngineManager> managerLoader = ServiceLoader.load(ALPNEngineManager.class, classLoader);
List<ALPNEngineManager> managers = new ArrayList<>();
for (ALPNEngineManager manager : managerLoader) {
managers.add(manager);
}
Collections.sort(managers, new Comparator<ALPNEngineManager>() {
@Override
public int compare(ALPNEngineManager o1, ALPNEngineManager o2) {
return Integer.compare(o2.getPriority(), o1.getPriority()); //highest first
}
});
this.alpnEngineManagers = managers.toArray(new ALPNEngineManager[0]);

}

public ALPNProvider getProvider(SSLEngine engine) {
for(ALPNProvider provider: alpnProviders) {
if(provider.isEnabled(engine)) {
for (ALPNProvider provider : alpnProviders) {
if (provider.isEnabled(engine)) {
return provider;
}
}
return null;
}

public void registerEngineCallback(SSLEngine original, Function<SSLEngine, SSLEngine> selectionFunction) {
for(ALPNEngineManager manager : alpnEngineManagers) {
if(manager.registerEngine(original, selectionFunction)) {
return;
}
}
}

}
@@ -0,0 +1,34 @@
/*
* JBoss, Home of Professional Open Source.
* Copyright 2018 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
* 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 io.undertow.protocols.alpn;

import java.util.function.Function;

import javax.net.ssl.SSLEngine;

public class DefaultAlpnEngineManager implements ALPNEngineManager {

@Override
public int getPriority() {
return 0;
}

@Override
public boolean registerEngine(SSLEngine engine, Function<SSLEngine, SSLEngine> selectedFunction) {
selectedFunction.apply(engine);
return true;
}
}

0 comments on commit 36d3908

Please sign in to comment.