Future compatibility with TLS ALPN
Motivation: According to TLS ALPN draft-05, a client sends the list of the supported protocols and a server responds with the selected protocol, which is different from NPN. Therefore, ApplicationProtocolSelector won't work with ALPN Modifications: - Use Iterable<String> to list the supported protocols on the client side, rather than using ApplicationProtocolSelector - Remove ApplicationProtocolSelector Result: Future compatibility with TLS ALPN
This commit is contained in:
parent
bbb5ee42b1
commit
ffa348273a
@ -1,34 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2014 The Netty Project
|
|
||||||
*
|
|
||||||
* The Netty Project licenses this file to you 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 org.jboss.netty.handler.ssl;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Selects an application layer protocol in TLS <a href="http://tools.ietf.org/html/draft-agl-tls-nextprotoneg-04">NPN
|
|
||||||
* (Next Protocol Negotiation)</a> or <a href="https://tools.ietf.org/html/draft-ietf-tls-applayerprotoneg-05">ALPN
|
|
||||||
* (Application Layer Protocol Negotiation)</a>.
|
|
||||||
*/
|
|
||||||
public interface ApplicationProtocolSelector {
|
|
||||||
/**
|
|
||||||
* Invoked to select a protocol from the list of specified application layer protocols.
|
|
||||||
*
|
|
||||||
* @param protocols the list of application layer protocols sent by the server.
|
|
||||||
* The list is empty if the server supports neither NPN nor ALPM.
|
|
||||||
* @return the selected protocol. {@code null} if no protocol was selected.
|
|
||||||
*/
|
|
||||||
String selectProtocol(List<String> protocols) throws Exception;
|
|
||||||
}
|
|
@ -20,7 +20,6 @@ import org.jboss.netty.buffer.ChannelBuffer;
|
|||||||
import org.jboss.netty.buffer.ChannelBufferInputStream;
|
import org.jboss.netty.buffer.ChannelBufferInputStream;
|
||||||
|
|
||||||
import javax.net.ssl.SSLContext;
|
import javax.net.ssl.SSLContext;
|
||||||
import javax.net.ssl.SSLEngine;
|
|
||||||
import javax.net.ssl.SSLException;
|
import javax.net.ssl.SSLException;
|
||||||
import javax.net.ssl.SSLSessionContext;
|
import javax.net.ssl.SSLSessionContext;
|
||||||
import javax.net.ssl.TrustManagerFactory;
|
import javax.net.ssl.TrustManagerFactory;
|
||||||
@ -29,6 +28,7 @@ import java.io.File;
|
|||||||
import java.security.KeyStore;
|
import java.security.KeyStore;
|
||||||
import java.security.cert.CertificateFactory;
|
import java.security.cert.CertificateFactory;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ import java.util.List;
|
|||||||
public final class JdkSslClientContext extends JdkSslContext {
|
public final class JdkSslClientContext extends JdkSslContext {
|
||||||
|
|
||||||
private final SSLContext ctx;
|
private final SSLContext ctx;
|
||||||
private final ApplicationProtocolSelector nextProtocolSelector;
|
private final List<String> nextProtocols;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance.
|
* Creates a new instance.
|
||||||
@ -93,8 +93,7 @@ public final class JdkSslClientContext extends JdkSslContext {
|
|||||||
* {@code null} to use the default.
|
* {@code null} to use the default.
|
||||||
* @param ciphers the cipher suites to enable, in the order of preference.
|
* @param ciphers the cipher suites to enable, in the order of preference.
|
||||||
* {@code null} to use the default cipher suites.
|
* {@code null} to use the default cipher suites.
|
||||||
* @param nextProtocolSelector the {@link ApplicationProtocolSelector} that chooses one of the application layer
|
* @param nextProtocols the application layer protocols to accept, in the order of preference.
|
||||||
* protocols returned by a TLS server.
|
|
||||||
* {@code null} to disable TLS NPN/ALPN extension.
|
* {@code null} to disable TLS NPN/ALPN extension.
|
||||||
* @param sessionCacheSize the size of the cache used for storing SSL session objects.
|
* @param sessionCacheSize the size of the cache used for storing SSL session objects.
|
||||||
* {@code 0} to use the default value.
|
* {@code 0} to use the default value.
|
||||||
@ -103,16 +102,23 @@ public final class JdkSslClientContext extends JdkSslContext {
|
|||||||
*/
|
*/
|
||||||
public JdkSslClientContext(
|
public JdkSslClientContext(
|
||||||
SslBufferPool bufPool, File certChainFile, TrustManagerFactory trustManagerFactory,
|
SslBufferPool bufPool, File certChainFile, TrustManagerFactory trustManagerFactory,
|
||||||
Iterable<String> ciphers, ApplicationProtocolSelector nextProtocolSelector,
|
Iterable<String> ciphers, Iterable<String> nextProtocols,
|
||||||
long sessionCacheSize, long sessionTimeout) throws SSLException {
|
long sessionCacheSize, long sessionTimeout) throws SSLException {
|
||||||
|
|
||||||
super(bufPool, ciphers);
|
super(bufPool, ciphers);
|
||||||
|
|
||||||
if (nextProtocolSelector != null && !JettyNpnSslEngine.isAvailable()) {
|
if (nextProtocols != null && nextProtocols.iterator().hasNext() && !JettyNpnSslEngine.isAvailable()) {
|
||||||
throw new SSLException("NPN/ALPN unsupported: " + nextProtocolSelector);
|
throw new SSLException("NPN/ALPN unsupported: " + nextProtocols);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.nextProtocolSelector = nextProtocolSelector;
|
List<String> nextProtoList = new ArrayList<String>();
|
||||||
|
for (String p: nextProtocols) {
|
||||||
|
if (p == null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
nextProtoList.add(p);
|
||||||
|
}
|
||||||
|
this.nextProtocols = Collections.unmodifiableList(nextProtoList);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (certChainFile == null) {
|
if (certChainFile == null) {
|
||||||
@ -162,27 +168,13 @@ public final class JdkSslClientContext extends JdkSslContext {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ApplicationProtocolSelector nextProtocolSelector() {
|
|
||||||
return nextProtocolSelector;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> nextProtocols() {
|
public List<String> nextProtocols() {
|
||||||
return Collections.emptyList();
|
return nextProtocols;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SSLContext context() {
|
public SSLContext context() {
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
SSLEngine wrapEngine(SSLEngine engine) {
|
|
||||||
if (nextProtocolSelector == null) {
|
|
||||||
return engine;
|
|
||||||
} else {
|
|
||||||
return new JettyNpnSslEngine(engine, nextProtocolSelector);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -161,7 +161,13 @@ public abstract class JdkSslContext extends SslContext {
|
|||||||
return wrapEngine(engine);
|
return wrapEngine(engine);
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract SSLEngine wrapEngine(SSLEngine engine);
|
private SSLEngine wrapEngine(SSLEngine engine) {
|
||||||
|
if (nextProtocols().isEmpty()) {
|
||||||
|
return engine;
|
||||||
|
} else {
|
||||||
|
return new JettyNpnSslEngine(engine, nextProtocols(), isServer());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static String[] toCipherSuiteArray(Iterable<String> ciphers) {
|
private static String[] toCipherSuiteArray(Iterable<String> ciphers) {
|
||||||
if (ciphers == null) {
|
if (ciphers == null) {
|
||||||
|
@ -21,7 +21,6 @@ import org.jboss.netty.buffer.ChannelBufferInputStream;
|
|||||||
|
|
||||||
import javax.net.ssl.KeyManagerFactory;
|
import javax.net.ssl.KeyManagerFactory;
|
||||||
import javax.net.ssl.SSLContext;
|
import javax.net.ssl.SSLContext;
|
||||||
import javax.net.ssl.SSLEngine;
|
|
||||||
import javax.net.ssl.SSLException;
|
import javax.net.ssl.SSLException;
|
||||||
import javax.net.ssl.SSLSessionContext;
|
import javax.net.ssl.SSLSessionContext;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@ -178,11 +177,6 @@ public final class JdkSslServerContext extends JdkSslContext {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ApplicationProtocolSelector nextProtocolSelector() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> nextProtocols() {
|
public List<String> nextProtocols() {
|
||||||
return nextProtocols;
|
return nextProtocols;
|
||||||
@ -192,13 +186,4 @@ public final class JdkSslServerContext extends JdkSslContext {
|
|||||||
public SSLContext context() {
|
public SSLContext context() {
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
SSLEngine wrapEngine(SSLEngine engine) {
|
|
||||||
if (nextProtocols.isEmpty()) {
|
|
||||||
return engine;
|
|
||||||
} else {
|
|
||||||
return new JettyNpnSslEngine(engine, nextProtocols);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -19,8 +19,6 @@ package org.jboss.netty.handler.ssl;
|
|||||||
import org.eclipse.jetty.npn.NextProtoNego;
|
import org.eclipse.jetty.npn.NextProtoNego;
|
||||||
import org.eclipse.jetty.npn.NextProtoNego.ClientProvider;
|
import org.eclipse.jetty.npn.NextProtoNego.ClientProvider;
|
||||||
import org.eclipse.jetty.npn.NextProtoNego.ServerProvider;
|
import org.eclipse.jetty.npn.NextProtoNego.ServerProvider;
|
||||||
import org.jboss.netty.logging.InternalLogger;
|
|
||||||
import org.jboss.netty.logging.InternalLoggerFactory;
|
|
||||||
|
|
||||||
import javax.net.ssl.SSLEngine;
|
import javax.net.ssl.SSLEngine;
|
||||||
import javax.net.ssl.SSLEngineResult;
|
import javax.net.ssl.SSLEngineResult;
|
||||||
@ -33,8 +31,6 @@ import java.util.List;
|
|||||||
|
|
||||||
final class JettyNpnSslEngine extends SSLEngine {
|
final class JettyNpnSslEngine extends SSLEngine {
|
||||||
|
|
||||||
private static final InternalLogger logger = InternalLoggerFactory.getInstance(JettyNpnSslEngine.class);
|
|
||||||
|
|
||||||
private static boolean available;
|
private static boolean available;
|
||||||
|
|
||||||
static boolean isAvailable() {
|
static boolean isAvailable() {
|
||||||
@ -64,12 +60,13 @@ final class JettyNpnSslEngine extends SSLEngine {
|
|||||||
private final SSLEngine engine;
|
private final SSLEngine engine;
|
||||||
private final JettyNpnSslSession session;
|
private final JettyNpnSslSession session;
|
||||||
|
|
||||||
JettyNpnSslEngine(SSLEngine engine, final List<String> nextProtocols) {
|
JettyNpnSslEngine(SSLEngine engine, final List<String> nextProtocols, boolean server) {
|
||||||
assert !nextProtocols.isEmpty();
|
assert !nextProtocols.isEmpty();
|
||||||
|
|
||||||
this.engine = engine;
|
this.engine = engine;
|
||||||
session = new JettyNpnSslSession(engine);
|
session = new JettyNpnSslSession(engine);
|
||||||
|
|
||||||
|
if (server) {
|
||||||
NextProtoNego.put(engine, new ServerProvider() {
|
NextProtoNego.put(engine, new ServerProvider() {
|
||||||
public void unsupported() {
|
public void unsupported() {
|
||||||
getSession().setApplicationProtocol(nextProtocols.get(nextProtocols.size() - 1));
|
getSession().setApplicationProtocol(nextProtocols.get(nextProtocols.size() - 1));
|
||||||
@ -83,11 +80,9 @@ final class JettyNpnSslEngine extends SSLEngine {
|
|||||||
getSession().setApplicationProtocol(protocol);
|
getSession().setApplicationProtocol(protocol);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
} else {
|
||||||
|
final String[] list = nextProtocols.toArray(new String[nextProtocols.size()]);
|
||||||
JettyNpnSslEngine(SSLEngine engine, final ApplicationProtocolSelector nextProtocolSelector) {
|
final String fallback = list[list.length - 1];
|
||||||
this.engine = engine;
|
|
||||||
session = new JettyNpnSslSession(engine);
|
|
||||||
|
|
||||||
NextProtoNego.put(engine, new ClientProvider() {
|
NextProtoNego.put(engine, new ClientProvider() {
|
||||||
public boolean supports() {
|
public boolean supports() {
|
||||||
@ -99,17 +94,16 @@ final class JettyNpnSslEngine extends SSLEngine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String selectProtocol(List<String> protocols) {
|
public String selectProtocol(List<String> protocols) {
|
||||||
String p = null;
|
for (String p: list) {
|
||||||
try {
|
if (protocols.contains(p)) {
|
||||||
p = nextProtocolSelector.selectProtocol(protocols);
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.warn("Failed to select the next protocol:", e);
|
|
||||||
}
|
|
||||||
session.setApplicationProtocol(p);
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JettyNpnSslSession getSession() {
|
public JettyNpnSslSession getSession() {
|
||||||
|
@ -64,8 +64,7 @@ public final class OpenSslServerContext extends SslContext {
|
|||||||
private final List<String> unmodifiableCiphers = Collections.unmodifiableList(ciphers);
|
private final List<String> unmodifiableCiphers = Collections.unmodifiableList(ciphers);
|
||||||
private final long sessionCacheSize;
|
private final long sessionCacheSize;
|
||||||
private final long sessionTimeout;
|
private final long sessionTimeout;
|
||||||
private final List<String> nextProtocols = new ArrayList<String>();
|
private final List<String> nextProtocols;
|
||||||
private final List<String> unmodifiableNextProtocols = Collections.unmodifiableList(nextProtocols);
|
|
||||||
|
|
||||||
/** The OpenSSL SSL_CTX object */
|
/** The OpenSSL SSL_CTX object */
|
||||||
private final long ctx;
|
private final long ctx;
|
||||||
@ -151,12 +150,14 @@ public final class OpenSslServerContext extends SslContext {
|
|||||||
this.ciphers.add(c);
|
this.ciphers.add(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<String> nextProtoList = new ArrayList<String>();
|
||||||
for (String p: nextProtocols) {
|
for (String p: nextProtocols) {
|
||||||
if (p == null) {
|
if (p == null) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
this.nextProtocols.add(p);
|
nextProtoList.add(p);
|
||||||
}
|
}
|
||||||
|
this.nextProtocols = Collections.unmodifiableList(nextProtoList);
|
||||||
|
|
||||||
// Allocate a new APR pool.
|
// Allocate a new APR pool.
|
||||||
aprPool = Pool.create(0);
|
aprPool = Pool.create(0);
|
||||||
@ -221,10 +222,10 @@ public final class OpenSslServerContext extends SslContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Set next protocols for next protocol negotiation extension, if specified */
|
/* Set next protocols for next protocol negotiation extension, if specified */
|
||||||
if (!this.nextProtocols.isEmpty()) {
|
if (!nextProtoList.isEmpty()) {
|
||||||
// Convert the protocol list into a comma-separated string.
|
// Convert the protocol list into a comma-separated string.
|
||||||
StringBuilder nextProtocolBuf = new StringBuilder();
|
StringBuilder nextProtocolBuf = new StringBuilder();
|
||||||
for (String p: this.nextProtocols) {
|
for (String p: nextProtoList) {
|
||||||
nextProtocolBuf.append(p);
|
nextProtocolBuf.append(p);
|
||||||
nextProtocolBuf.append(',');
|
nextProtocolBuf.append(',');
|
||||||
}
|
}
|
||||||
@ -290,14 +291,9 @@ public final class OpenSslServerContext extends SslContext {
|
|||||||
return sessionTimeout;
|
return sessionTimeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ApplicationProtocolSelector nextProtocolSelector() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> nextProtocols() {
|
public List<String> nextProtocols() {
|
||||||
return unmodifiableNextProtocols;
|
return nextProtocols;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -319,11 +315,11 @@ public final class OpenSslServerContext extends SslContext {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public SSLEngine newEngine() {
|
public SSLEngine newEngine() {
|
||||||
if (unmodifiableNextProtocols.isEmpty()) {
|
if (nextProtocols.isEmpty()) {
|
||||||
return new OpenSslEngine(ctx, bufferPool(), null);
|
return new OpenSslEngine(ctx, bufferPool(), null);
|
||||||
} else {
|
} else {
|
||||||
return new OpenSslEngine(
|
return new OpenSslEngine(
|
||||||
ctx, bufferPool(), unmodifiableNextProtocols.get(unmodifiableNextProtocols.size() - 1));
|
ctx, bufferPool(), nextProtocols.get(nextProtocols.size() - 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,6 @@ import javax.net.ssl.SSLException;
|
|||||||
import javax.net.ssl.TrustManager;
|
import javax.net.ssl.TrustManager;
|
||||||
import javax.net.ssl.TrustManagerFactory;
|
import javax.net.ssl.TrustManagerFactory;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -265,8 +264,7 @@ public abstract class SslContext {
|
|||||||
* {@code null} to use the default.
|
* {@code null} to use the default.
|
||||||
* @param ciphers the cipher suites to enable, in the order of preference.
|
* @param ciphers the cipher suites to enable, in the order of preference.
|
||||||
* {@code null} to use the default cipher suites.
|
* {@code null} to use the default cipher suites.
|
||||||
* @param nextProtocolSelector the {@link ApplicationProtocolSelector} that chooses one of the application layer
|
* @param nextProtocols the application layer protocols to accept, in the order of preference.
|
||||||
* protocols returned by a TLS server.
|
|
||||||
* {@code null} to disable TLS NPN/ALPN extension.
|
* {@code null} to disable TLS NPN/ALPN extension.
|
||||||
* @param sessionCacheSize the size of the cache used for storing SSL session objects.
|
* @param sessionCacheSize the size of the cache used for storing SSL session objects.
|
||||||
* {@code 0} to use the default value.
|
* {@code 0} to use the default value.
|
||||||
@ -278,11 +276,11 @@ public abstract class SslContext {
|
|||||||
public static SslContext newClientContext(
|
public static SslContext newClientContext(
|
||||||
SslBufferPool bufPool,
|
SslBufferPool bufPool,
|
||||||
File certChainFile, TrustManagerFactory trustManagerFactory,
|
File certChainFile, TrustManagerFactory trustManagerFactory,
|
||||||
Iterable<String> ciphers, ApplicationProtocolSelector nextProtocolSelector,
|
Iterable<String> ciphers, Iterable<String> nextProtocols,
|
||||||
long sessionCacheSize, long sessionTimeout) throws SSLException {
|
long sessionCacheSize, long sessionTimeout) throws SSLException {
|
||||||
return newClientContext(
|
return newClientContext(
|
||||||
null, bufPool, certChainFile, trustManagerFactory,
|
null, bufPool, certChainFile, trustManagerFactory,
|
||||||
ciphers, nextProtocolSelector, sessionCacheSize, sessionTimeout);
|
ciphers, nextProtocols, sessionCacheSize, sessionTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -359,8 +357,7 @@ public abstract class SslContext {
|
|||||||
* {@code null} to use the default.
|
* {@code null} to use the default.
|
||||||
* @param ciphers the cipher suites to enable, in the order of preference.
|
* @param ciphers the cipher suites to enable, in the order of preference.
|
||||||
* {@code null} to use the default cipher suites.
|
* {@code null} to use the default cipher suites.
|
||||||
* @param nextProtocolSelector the {@link ApplicationProtocolSelector} that chooses one of the application layer
|
* @param nextProtocols the application layer protocols to accept, in the order of preference.
|
||||||
* protocols returned by a TLS server.
|
|
||||||
* {@code null} to disable TLS NPN/ALPN extension.
|
* {@code null} to disable TLS NPN/ALPN extension.
|
||||||
* @param sessionCacheSize the size of the cache used for storing SSL session objects.
|
* @param sessionCacheSize the size of the cache used for storing SSL session objects.
|
||||||
* {@code 0} to use the default value.
|
* {@code 0} to use the default value.
|
||||||
@ -372,7 +369,7 @@ public abstract class SslContext {
|
|||||||
public static SslContext newClientContext(
|
public static SslContext newClientContext(
|
||||||
SslProvider provider, SslBufferPool bufPool,
|
SslProvider provider, SslBufferPool bufPool,
|
||||||
File certChainFile, TrustManagerFactory trustManagerFactory,
|
File certChainFile, TrustManagerFactory trustManagerFactory,
|
||||||
Iterable<String> ciphers, ApplicationProtocolSelector nextProtocolSelector,
|
Iterable<String> ciphers, Iterable<String> nextProtocols,
|
||||||
long sessionCacheSize, long sessionTimeout) throws SSLException {
|
long sessionCacheSize, long sessionTimeout) throws SSLException {
|
||||||
|
|
||||||
if (provider != null && provider != SslProvider.JDK) {
|
if (provider != null && provider != SslProvider.JDK) {
|
||||||
@ -381,83 +378,7 @@ public abstract class SslContext {
|
|||||||
|
|
||||||
return new JdkSslClientContext(
|
return new JdkSslClientContext(
|
||||||
bufPool, certChainFile, trustManagerFactory,
|
bufPool, certChainFile, trustManagerFactory,
|
||||||
ciphers, nextProtocolSelector, sessionCacheSize, sessionTimeout);
|
ciphers, nextProtocols, sessionCacheSize, sessionTimeout);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a simple client-side {@link ApplicationProtocolSelector} that selects the most preferred protocol
|
|
||||||
* among the application protocols sent by the server. If there is no match, it chooses the least preferred one.
|
|
||||||
*
|
|
||||||
* @param nextProtocols the list of the supported client-side application protocols, in the order of preference
|
|
||||||
* @return the new {@link ApplicationProtocolSelector}.
|
|
||||||
* {@code null} if the specified {@code nextProtocols} does not contain any elements.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public static ApplicationProtocolSelector newApplicationProtocolSelector(String... nextProtocols) {
|
|
||||||
if (nextProtocols == null) {
|
|
||||||
throw new NullPointerException("nextProtocols");
|
|
||||||
}
|
|
||||||
|
|
||||||
final List<String> list = new ArrayList<String>();
|
|
||||||
for (String p: nextProtocols) {
|
|
||||||
if (p == null) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
list.add(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (list.isEmpty()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return newApplicationProtocolSelector(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ApplicationProtocolSelector newApplicationProtocolSelector(final List<String> list) {
|
|
||||||
return new ApplicationProtocolSelector() {
|
|
||||||
public String selectProtocol(List<String> protocols) throws Exception {
|
|
||||||
for (String p: list) {
|
|
||||||
if (protocols.contains(p)) {
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return list.get(list.size() - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "ApplicationProtocolSelector(" + list + ')';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a simple client-side {@link ApplicationProtocolSelector} that selects the most preferred protocol
|
|
||||||
* among the application protocols sent by the server. If there is no match, it chooses the least preferred one.
|
|
||||||
*
|
|
||||||
* @param nextProtocols the list of the supported client-side application protocols, in the order of preference
|
|
||||||
* @return the new {@link ApplicationProtocolSelector}.
|
|
||||||
* {@code null} if the specified {@code nextProtocols} does not contain any elements.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public static ApplicationProtocolSelector newApplicationProtocolSelector(Iterable<String> nextProtocols) {
|
|
||||||
if (nextProtocols == null) {
|
|
||||||
throw new NullPointerException("nextProtocols");
|
|
||||||
}
|
|
||||||
|
|
||||||
final List<String> list = new ArrayList<String>();
|
|
||||||
for (String p: nextProtocols) {
|
|
||||||
if (p == null) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
list.add(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (list.isEmpty()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return newApplicationProtocolSelector(list);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private final SslBufferPool bufferPool;
|
private final SslBufferPool bufferPool;
|
||||||
@ -505,18 +426,9 @@ public abstract class SslContext {
|
|||||||
public abstract long sessionTimeout();
|
public abstract long sessionTimeout();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the client-side {@link ApplicationProtocolSelector} for the TLS NPN/ALPN extension.
|
* Returns the list of application layer protocols for the TLS NPN/ALPN extension, in the order of preference.
|
||||||
*
|
*
|
||||||
* @return the client-side {@link ApplicationProtocolSelector}.
|
* @return the list of application layer protocols.
|
||||||
* {@code null} if NPN/ALPN extension has been disabled.
|
|
||||||
*/
|
|
||||||
public abstract ApplicationProtocolSelector nextProtocolSelector();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the list of server-side application layer protocols for the TLS NPN/ALPN extension,
|
|
||||||
* in the order of preference.
|
|
||||||
*
|
|
||||||
* @return the list of server-side application layer protocols.
|
|
||||||
* {@code null} if NPN/ALPN extension has been disabled.
|
* {@code null} if NPN/ALPN extension has been disabled.
|
||||||
*/
|
*/
|
||||||
public abstract List<String> nextProtocols();
|
public abstract List<String> nextProtocols();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user