下面列出了怎么用javax.net.ssl.SSLEngine的API类实例代码及写法,或者点击链接到github查看源代码。
/**
* Initialize the channel.
*
* @param channel the channel.
*/
@Override
public void initChannel(SocketChannel channel) {
ChannelPipeline pipeline = channel.pipeline();
if (ssl) {
try {
SSLContext sslContext = SSLContext.getDefault();
SSLEngine sslEngine = sslContext.createSSLEngine();
sslEngine.setUseClientMode(false);
pipeline.addLast(new SslHandler(sslEngine));
} catch (NoSuchAlgorithmException e) {
if (LOGGER.isLoggable(SEVERE)) {
LOGGER.log(WARNING, "Unable to match SSL algorithm", e);
}
}
}
pipeline.addLast(new HttpRequestDecoder());
pipeline.addLast(new HttpResponseEncoder());
pipeline.addLast(new HttpObjectAggregator(10*1024*1024));
pipeline.addLast(new NettyHttpServerHandler(httpServerProcessor));
}
private ClientTlsChannel(
ByteChannel underlying,
SSLEngine engine,
Consumer<SSLSession> sessionInitCallback,
boolean runTasks,
BufferAllocator plainBufAllocator,
BufferAllocator encryptedBufAllocator,
boolean releaseBuffers,
boolean waitForCloseNotifyOnClose) {
if (!engine.getUseClientMode()) {
throw new IllegalArgumentException("SSLEngine must be in client mode");
}
this.underlying = underlying;
TrackingAllocator trackingPlainBufAllocator = new TrackingAllocator(plainBufAllocator);
TrackingAllocator trackingEncryptedAllocator = new TrackingAllocator(encryptedBufAllocator);
impl = new TlsChannelImpl(underlying, underlying, engine, Optional.empty(), sessionInitCallback, runTasks,
trackingPlainBufAllocator, trackingEncryptedAllocator, releaseBuffers, waitForCloseNotifyOnClose);
}
@Test
public void testCreateSslEngineFromJksStoreWithExplicitEnabledAndDisabledProtocolsJDK() throws Exception {
// Discover the default enabled protocols
TransportOptions options = createJksSslOptions();
SSLEngine directEngine = createSSLEngineDirectly(options);
String[] protocols = directEngine.getEnabledProtocols();
assertTrue("There were no initial protocols to choose from!", protocols.length > 1);
// Pull out two to enable, and one to disable specifically
String protocol1 = protocols[0];
String protocol2 = protocols[1];
String[] enabledProtocols = new String[] { protocol1, protocol2 };
String[] disabledProtocol = new String[] { protocol1 };
String[] remainingProtocols = new String[] { protocol2 };
options.setEnabledProtocols(enabledProtocols);
options.setDisabledProtocols(disabledProtocol);
SSLContext context = TransportSupport.createJdkSslContext(options);
SSLEngine engine = TransportSupport.createJdkSslEngine(null, context, options);
// verify the option took effect, that the disabled protocols were removed from the enabled list.
assertNotNull(engine);
assertArrayEquals("Enabled protocols not as expected", remainingProtocols, engine.getEnabledProtocols());
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType, SSLEngine engine)
throws CertificateException {
if (extendedTrustManager == null) {
out.print("(fallback to X509TrustManager) ");
checkServerTrusted(chain, authType);
return;
}
out.print("TestTrustManager.checkServerTrusted "
+ "chain=" + chain.length + " "
+ "authType=" + authType + " "
+ "engine=" + engine.toString() + " ");
try {
assertServerAuthType(authType);
extendedTrustManager.checkServerTrusted(chain, authType, engine);
out.println("OK");
} catch (CertificateException e) {
e.printStackTrace(out);
throw e;
}
}
private static String[] buildEnabledCipherSuites(SSLEngine engine, NettyTransportSslOptions options) {
List<String> enabledCipherSuites = new ArrayList<>();
if (options.getEnabledCipherSuites() != null) {
List<String> configuredCipherSuites = Arrays.asList(options.getEnabledCipherSuites());
LOG.trace("Configured cipher suites from transport options: {}", configuredCipherSuites);
enabledCipherSuites.addAll(configuredCipherSuites);
} else {
List<String> engineCipherSuites = Arrays.asList(engine.getEnabledCipherSuites());
LOG.trace("Default cipher suites from the SSLEngine: {}", engineCipherSuites);
enabledCipherSuites.addAll(engineCipherSuites);
}
String[] disabledCipherSuites = options.getDisabledCipherSuites();
if (disabledCipherSuites != null) {
List<String> disabled = Arrays.asList(disabledCipherSuites);
LOG.trace("Disabled cipher suites: {}", disabled);
enabledCipherSuites.removeAll(disabled);
}
LOG.trace("Enabled cipher suites: {}", enabledCipherSuites);
return enabledCipherSuites.toArray(new String[0]);
}
@Test
public void testLegacySslProtocolsDisabledByDefaultOpenSSL() throws Exception {
assumeTrue(OpenSsl.isAvailable());
assumeTrue(OpenSsl.supportsKeyManagerFactory());
TransportOptions options = createJksSslOptions(null);
SslContext context = TransportSupport.createOpenSslContext(options);
assertNotNull(context);
SSLEngine engine = TransportSupport.createOpenSslEngine(PooledByteBufAllocator.DEFAULT, null, context, options);
assertNotNull(engine);
List<String> engineProtocols = Arrays.asList(engine.getEnabledProtocols());
assertFalse("SSLv3 should not be enabled by default", engineProtocols.contains("SSLv3"));
// TODO - Netty is currently unable to disable OpenSSL SSLv2Hello so we are stuck with it for now.
// assertFalse("SSLv2Hello should not be enabled by default", engineProtocols.contains("SSLv2Hello"));
}
@Override
protected void testOneCipher(String cipher) throws SSLException {
SSLContext context = getContext();
int maxPacketSize = getMaxPacketSize();
boolean useSNI = !TEST_MODE.equals("norm");
SSLEngine clientEngine = getClientSSLEngine(context, useSNI);
SSLEngine serverEngine = getServerSSLEngine(context, useSNI);
clientEngine.setEnabledCipherSuites(new String[]{cipher});
serverEngine.setEnabledCipherSuites(new String[]{cipher});
serverEngine.setNeedClientAuth(!cipher.contains("anon"));
doHandshake(clientEngine, serverEngine, maxPacketSize,
HandshakeMode.INITIAL_HANDSHAKE);
checkBufferOverflowOnWrap(clientEngine);
checkBufferOverflowOnWrap(serverEngine);
checkBufferOverflowOnUnWrap(clientEngine, serverEngine);
checkBufferOverflowOnUnWrap(serverEngine, clientEngine);
checkBufferUnderflowOnUnWrap(serverEngine, clientEngine);
checkBufferUnderflowOnUnWrap(clientEngine, serverEngine);
}
/**
* Create a new SSLEngine instance in client mode from the given SSLContext and
* TransportSslOptions instances.
*
* @param remote
* the URI of the remote peer that will be used to initialize the engine, may be null
* if none should.
* @param context
* the SSLContext to use when creating the engine.
* @param options
* the TransportSslOptions to use to configure the new SSLEngine.
*
* @return a new SSLEngine instance in client mode.
*
* @throws Exception
* if an error occurs while creating the new SSLEngine.
*/
public static SSLEngine createSslEngine(URI remote, SSLContext context, NettyTransportSslOptions options) throws Exception {
SSLEngine engine = null;
if (remote == null) {
engine = context.createSSLEngine();
} else {
engine = context.createSSLEngine(remote.getHost(), remote.getPort());
}
engine.setEnabledProtocols(buildEnabledProtocols(engine, options));
engine.setEnabledCipherSuites(buildEnabledCipherSuites(engine, options));
engine.setUseClientMode(true);
if (options.isVerifyHost()) {
SSLParameters sslParameters = engine.getSSLParameters();
sslParameters.setEndpointIdentificationAlgorithm("HTTPS");
engine.setSSLParameters(sslParameters);
}
return engine;
}
@Test
public void testCloseInboundAfterBeginHandshake() throws Exception {
SelfSignedCertificate cert = new SelfSignedCertificate();
clientSslCtx = SslContextBuilder
.forClient()
.sslProvider(sslClientProvider())
.build();
SSLEngine client = clientSslCtx.newEngine(UnpooledByteBufAllocator.DEFAULT);
serverSslCtx = SslContextBuilder
.forServer(cert.certificate(), cert.privateKey())
.sslProvider(sslServerProvider())
.build();
SSLEngine server = serverSslCtx.newEngine(UnpooledByteBufAllocator.DEFAULT);
try {
testCloseInboundAfterBeginHandshake(client);
testCloseInboundAfterBeginHandshake(server);
} finally {
cleanupClientSslEngine(client);
cleanupServerSslEngine(server);
cert.delete();
}
}
@NotNull
private String[] determineFinalCipherSuites(SSLEngine sslEngine) {
Collection<String> filteredCipherSuites;
if (useDefaultCiperSuites) {
filteredCipherSuites = getSupportedValuesFromSpecified(
Arrays.asList(sslEngine.getSupportedCipherSuites()),
Arrays.asList(MODERN_CIPHER_SUITES),
"Cipher suite"
);
} else {
filteredCipherSuites = getSupportedValuesFromSpecified(Arrays.asList(sslEngine.getSupportedCipherSuites()),
cipherSuites,
"Cipher suite"
);
}
return filteredCipherSuites.toArray(new String[0]);
}
TlsSocket(InetSocketAddress localAddress, InetSocketAddress remoteAddress, SocketChannel channel,
SSLEngine sslEngine, IpSettings ipSettings, boolean isClient) {
if (sslEngine == null) {
throw new NullPointerException();
}
this.localAddress = localAddress;
this.remoteAddress = remoteAddress;
this.channel = channel;
this.sslEngine = sslEngine;
this.ipSettings = ipSettings;
this.flowControl = FlowControl.WAIT;
this.status = isClient ? CLIENT : SERVER;
final SSLSession sslSession = this.sslEngine.getSession();
final TcpSettings tcpSettings = this.ipSettings.tcpSettings();
final int readBufferSize = Math.max(tcpSettings.readBufferSize(), sslSession.getApplicationBufferSize());
final int writeBufferSize = Math.max(tcpSettings.writeBufferSize(), sslSession.getPacketBufferSize());
this.readBuffer = ByteBuffer.allocate(readBufferSize);
this.writeBuffer = ByteBuffer.allocate(writeBufferSize);
((Buffer) this.writeBuffer).position(this.writeBuffer.capacity());
this.inputBuffer = ByteBuffer.allocate(readBufferSize);
this.outputBuffer = ByteBuffer.allocate(writeBufferSize);
((Buffer) this.outputBuffer).position(this.outputBuffer.capacity());
this.reader = Binary.inputBuffer(inputBuffer);
this.writer = Binary.outputBuffer(outputBuffer);
}
ServerEngine(SSLEngine engine, ByteBufAllocator alloc,
JdkApplicationProtocolNegotiator applicationNegotiator) {
super(engine, alloc, applicationNegotiator.protocols());
// Register for completion of the handshake.
Conscrypt.setHandshakeListener(engine, new HandshakeListener() {
@Override
public void onHandshakeFinished() throws SSLException {
selectProtocol();
}
});
protocolSelector = checkNotNull(applicationNegotiator.protocolSelectorFactory()
.newSelector(this,
new LinkedHashSet<String>(applicationNegotiator.protocols())),
"protocolSelector");
}
public static void main (String[] args) throws Exception {
SSLContext context = SSLContext.getDefault();
// set the property before initialization SSLEngine.
System.setProperty("jsse.SSLEngine.acceptLargeFragments", "true");
SSLEngine cliEngine = context.createSSLEngine();
cliEngine.setUseClientMode(true);
SSLEngine srvEngine = context.createSSLEngine();
srvEngine.setUseClientMode(false);
SSLSession cliSession = cliEngine.getSession();
SSLSession srvSession = srvEngine.getSession();
// check packet buffer sizes.
if (cliSession.getPacketBufferSize() < 33049 ||
srvSession.getPacketBufferSize() < 33049) {
throw new Exception("Don't accept large SSL/TLS fragments");
}
// check application data buffer sizes.
if (cliSession.getApplicationBufferSize() < 32768 ||
srvSession.getApplicationBufferSize() < 32768) {
throw new Exception(
"Don't accept large SSL/TLS application data ");
}
}
/**
* Create a Channel Initializer which is to to setup {@link ChannelPipeline}.
*/
@VisibleForTesting
ChannelInitializer<SocketChannel> getChannelInitializer(final PravegaNodeUri location,
final FlowHandler handler) {
final SslContext sslCtx = getSslContext();
return new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline p = ch.pipeline();
if (sslCtx != null) {
SslHandler sslHandler = sslCtx.newHandler(ch.alloc(), location.getEndpoint(), location.getPort());
if (clientConfig.isValidateHostName()) {
SSLEngine sslEngine = sslHandler.engine();
SSLParameters sslParameters = sslEngine.getSSLParameters();
sslParameters.setEndpointIdentificationAlgorithm("HTTPS");
sslEngine.setSSLParameters(sslParameters);
}
p.addLast(sslHandler);
}
p.addLast(
new ExceptionLoggingHandler(location.getEndpoint()),
new CommandEncoder(handler::getAppendBatchSizeTracker, metricNotifier),
new LengthFieldBasedFrameDecoder(WireCommands.MAX_WIRECOMMAND_SIZE, 4, 4),
new CommandDecoder(),
handler);
}
};
}
@Test
public void testSSLSessionId() throws Exception {
clientSslCtx = SslContextBuilder.forClient()
.trustManager(InsecureTrustManagerFactory.INSTANCE)
.sslProvider(sslClientProvider())
.sslContextProvider(clientSslContextProvider())
.build();
SelfSignedCertificate ssc = new SelfSignedCertificate();
serverSslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey())
.sslProvider(sslServerProvider())
.sslContextProvider(serverSslContextProvider())
.build();
SSLEngine clientEngine = null;
SSLEngine serverEngine = null;
try {
clientEngine = clientSslCtx.newEngine(UnpooledByteBufAllocator.DEFAULT);
serverEngine = serverSslCtx.newEngine(UnpooledByteBufAllocator.DEFAULT);
// Before the handshake the id should have length == 0
assertEquals(0, clientEngine.getSession().getId().length);
assertEquals(0, serverEngine.getSession().getId().length);
handshake(clientEngine, serverEngine);
// After the handshake the id should have length > 0
assertNotEquals(0, clientEngine.getSession().getId().length);
assertNotEquals(0, serverEngine.getSession().getId().length);
assertArrayEquals(clientEngine.getSession().getId(), serverEngine.getSession().getId());
} finally {
cleanupClientSslEngine(clientEngine);
cleanupServerSslEngine(serverEngine);
ssc.delete();
}
}
@Override
public void doClientAuth(SSLSupport sslSupport) throws IOException {
SecureNio2Channel sslChannel = (SecureNio2Channel) getSocket();
SSLEngine engine = sslChannel.getSslEngine();
if (!engine.getNeedClientAuth()) {
// Need to re-negotiate SSL connection
engine.setNeedClientAuth(true);
sslChannel.rehandshake();
((JSSESupport) sslSupport).setSession(engine.getSession());
}
}
@Override
public void initChannel(final SocketChannel channel) throws Exception {
SSLContext sslContext = certManagerSrv.getServerContext();
if (sslContext != null) {
/* First add ssl handler if ssl context is given */
SSLEngine engine = sslContext.createSSLEngine(address.toString(), port);
engine.setUseClientMode(true);
channel.pipeline().addLast("ssl", new SslHandler(engine));
}
super.initChannel(channel);
}
@Override
public SSLEngine createSSLEngine() {
return new OpenSSLEngine(ctx, defaultProtocol, false, sessionContext,
(negotiableProtocols != null && negotiableProtocols.size() > 0), initialized,
sslHostConfig.getCertificateVerificationDepth(),
sslHostConfig.getCertificateVerification() == CertificateVerification.OPTIONAL_NO_CA);
}
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType,
SSLEngine engine) throws CertificateException {
if (!option.isAuthPeer()) {
return;
}
String ip = null;
if (engine != null) {
SSLSession session = engine.getHandshakeSession();
ip = session.getPeerHost();
}
checkTrustedCustom(chain, ip);
trustManager.checkClientTrusted(chain, authType, engine);
}
@Ignore("connecting to the outside world makes this test flaky")
@Test(expected = SSLHandshakeException.class)
public void testCommonClientUsesExtensibleTrustManagerFailure() throws Throwable {
doThrow(new CertificateException()).when(extensibleTrustManager).checkServerTrusted(
ArgumentMatchers.any(X509Certificate[].class), anyString(), ArgumentMatchers.any(SSLEngine.class));
HttpClient httpClient = webClientFactory.getCommonHttpClient();
try {
httpClient.GET(TEST_URL);
} catch (ExecutionException e) {
throw e.getCause();
}
}
public static ChannelHandler getSslHandler(SocketChannel channel, boolean useClientCA, String sslKeyStoreType, String sslKeyFilePath, String sslManagerPwd, String sslStorePwd) {
SslContext sslContext = createSSLContext(useClientCA, sslKeyStoreType, sslKeyFilePath, sslManagerPwd, sslStorePwd);
SSLEngine sslEngine = sslContext.newEngine(
channel.alloc(),
channel.remoteAddress().getHostString(),
channel.remoteAddress().getPort());
sslEngine.setUseClientMode(false); // server mode
if (useClientCA) {
sslEngine.setNeedClientAuth(true);
}
return new SslHandler(sslEngine);
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType, SSLEngine sslEngine)
throws CertificateException {
X509ExtendedTrustManager linkedTrustManager = getLinkedTrustMananger(chain, sslEngine);
if (linkedTrustManager == null) {
logger.trace("No specific trust manager found, falling back to default");
defaultTrustManager.checkServerTrusted(chain, authType, sslEngine);
} else {
linkedTrustManager.checkServerTrusted(chain, authType, sslEngine);
}
}
private static void testServerContext(SslProvider provider) throws Exception {
SelfSignedCertificate cert = new SelfSignedCertificate();
SslContextBuilder builder = SslContextBuilder.forServer(cert.key(), cert.cert())
.sslProvider(provider)
.trustManager(cert.cert())
.clientAuth(ClientAuth.REQUIRE);
SslContext context = builder.build();
SSLEngine engine = context.newEngine(UnpooledByteBufAllocator.DEFAULT);
assertFalse(engine.getWantClientAuth());
assertTrue(engine.getNeedClientAuth());
engine.closeInbound();
engine.closeOutbound();
}
private SSLEngine createSSLEngine() {
try {
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init((KeyStore) null);
return SslContextBuilder
.forClient()
.trustManager(trustManagerFactory)
.build()
.newEngine(getAllocator());
} catch (Exception e) {
throw new RuntimeException("Could not create SSLEngine", e);
}
}
@Override
public void configureEngine(SSLEngine engine, AsyncHttpClientMiddleware.GetSocketData data, String host, int port) {
if (useSni == null || skipReflection)
return;
try {
peerHost.set(engine, host);
peerPort.set(engine, port);
Object sslp = sslParameters.get(engine);
useSni.set(sslp, true);
}
catch (IllegalAccessException e) {
}
}
@Override
public SSLEngine createSSLEngine(String peerHost, int peerPort, Mode mode) {
SslContext context = mode == Mode.CLIENT ? nettyClientSslContext : nettyServerSslContext;
SSLEngine sslEngine = context.newEngine(ByteBufAllocator.DEFAULT, peerHost, peerPort);
if (mode == Mode.CLIENT) {
SSLParameters sslParams = sslEngine.getSSLParameters();
sslParams.setEndpointIdentificationAlgorithm(endpointIdentification);
sslEngine.setSSLParameters(sslParams);
}
return sslEngine;
}
@Override
public SSLEngine newSslEngine(String remoteHost, int remotePort) {
SSLEngine sslEngine = sslContext
.createSSLEngine(remoteHost, remotePort);
sslEngine.setUseClientMode(true);
if (!tryHostNameVerificationJava7(sslEngine)) {
LOG.debug("Host Name Verification is not supported, causes insecure HTTPS connection");
}
filterWeakCipherSuites(sslEngine);
return sslEngine;
}
@Override
SSLEngine createSSLEngine(boolean isClient) throws Exception {
SSLEngine engine = super.createSSLEngine(isClient);
if (isClient) {
engine.setEnabledCipherSuites(new String[]{cipherSuite});
}
return engine;
}
private void runDelegatedTasks(SSLEngine engine) {
while (true) {
final Runnable task = engine.getDelegatedTask();
if (task == null) {
break;
}
task.run();
}
}
/**
* Generates an 1024 bit RSA key pair using SHA1PRNG. Thoughts: 2048 takes
* much longer time on older CPUs. And for almost every client, 1024 is
* sufficient.
*
* Derived from Zed Attack Proxy (ZAP). ZAP is an HTTP/HTTPS proxy for
* assessing web application security. Copyright 2011 [email protected]
* Licensed under the Apache License, Version 2.0
*
* @param commonName
* the common name to use in the server certificate
*
* @param subjectAlternativeNames
* a List of the subject alternative names to use in the server
* certificate, could be empty, but must not be null
*
* @see org.parosproxy.paros.security.SslCertificateServiceImpl.
* createCertForHost(String)
* @see org.parosproxy.paros.network.SSLConnector.getTunnelSSLSocketFactory(
* String)
*/
public SSLEngine createCertForHost(final String commonName,
final SubjectAlternativeNameHolder subjectAlternativeNames)
throws GeneralSecurityException, OperatorCreationException,
IOException, ExecutionException {
if (commonName == null) {
throw new IllegalArgumentException(
"Error, 'commonName' is not allowed to be null!");
}
if (subjectAlternativeNames == null) {
throw new IllegalArgumentException(
"Error, 'subjectAlternativeNames' is not allowed to be null!");
}
SSLContext ctx;
if (serverSSLContexts == null) {
ctx = createServerContext(commonName, subjectAlternativeNames);
} else {
ctx = serverSSLContexts.get(commonName, new Callable<SSLContext>() {
@Override
public SSLContext call() throws Exception {
return createServerContext(commonName,
subjectAlternativeNames);
}
});
}
return ctx.createSSLEngine();
}