File 0007-Revert-Support-session-cache-for-client-and-server-w.patch of Package netty.23695
From cb84a4f349059bde42a2867c0fdf08bcc4d1ba3b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fridrich=20=C5=A0trba?= <fridrich.strba@bluewin.ch>
Date: Thu, 11 Mar 2021 12:08:33 +0100
Subject: [PATCH 7/7] Revert "Support session cache for client and server when
using native SSLEngine implementation (#10994)"
This reverts commit 7d4aaa268b8a536f61fbc7711365147c58238745.
---
.../handler/ssl/ExtendedOpenSslSession.java | 72 +--
.../io/netty/handler/ssl/JdkSslContext.java | 10 +
.../ssl/OpenSslClientSessionCache.java | 138 -----
.../io/netty/handler/ssl/OpenSslSession.java | 32 +-
.../handler/ssl/OpenSslSessionCache.java | 492 ------------------
.../netty/handler/ssl/OpenSslSessionId.java | 66 ---
.../java/io/netty/handler/ssl/SslContext.java | 8 +-
.../ssl/util/LazyJavaxX509Certificate.java | 8 -
.../ssl/ConscryptJdkSslEngineInteropTest.java | 8 -
.../ConscryptOpenSslEngineInteropTest.java | 8 -
.../handler/ssl/ConscryptSslEngineTest.java | 15 -
.../ssl/JdkConscryptSslEngineInteropTest.java | 20 +-
.../ssl/JdkOpenSslEngineInteroptTest.java | 2 -
.../OpenSslConscryptSslEngineInteropTest.java | 8 -
.../netty/handler/ssl/OpenSslEngineTest.java | 52 --
.../ssl/OpenSslJdkSslEngineInteroptTest.java | 3 +-
.../ReferenceCountedOpenSslEngineTest.java | 2 -
.../io/netty/handler/ssl/SSLEngineTest.java | 331 +-----------
.../io/netty/handler/ssl/SslHandlerTest.java | 75 +--
19 files changed, 52 insertions(+), 1298 deletions(-)
delete mode 100644 handler/src/main/java/io/netty/handler/ssl/OpenSslClientSessionCache.java
delete mode 100644 handler/src/main/java/io/netty/handler/ssl/OpenSslSessionCache.java
delete mode 100644 handler/src/main/java/io/netty/handler/ssl/OpenSslSessionId.java
diff --git a/handler/src/main/java/io/netty/handler/ssl/ExtendedOpenSslSession.java b/handler/src/main/java/io/netty/handler/ssl/ExtendedOpenSslSession.java
index 5924325893..79acea7686 100644
--- a/handler/src/main/java/io/netty/handler/ssl/ExtendedOpenSslSession.java
+++ b/handler/src/main/java/io/netty/handler/ssl/ExtendedOpenSslSession.java
@@ -15,14 +15,12 @@
*/
package io.netty.handler.ssl;
-import io.netty.util.internal.EmptyArrays;
import io.netty.util.internal.SuppressJava6Requirement;
import javax.net.ssl.ExtendedSSLSession;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLPeerUnverifiedException;
-import javax.net.ssl.SSLSessionBindingEvent;
-import javax.net.ssl.SSLSessionBindingListener;
+import javax.net.ssl.SSLSessionContext;
import javax.security.cert.X509Certificate;
import java.security.Principal;
import java.security.cert.Certificate;
@@ -64,23 +62,8 @@ abstract class ExtendedOpenSslSession extends ExtendedSSLSession implements Open
}
@Override
- public OpenSslSessionId sessionId() {
- return wrapped.sessionId();
- }
-
- @Override
- public void setSessionId(OpenSslSessionId id) {
- wrapped.setSessionId(id);
- }
-
- @Override
- public final void setLocalCertificate(Certificate[] localCertificate) {
- wrapped.setLocalCertificate(localCertificate);
- }
-
- @Override
- public String[] getPeerSupportedSignatureAlgorithms() {
- return EmptyArrays.EMPTY_STRINGS;
+ public final void handshakeFinished() throws SSLException {
+ wrapped.handshakeFinished();
}
@Override
@@ -99,7 +82,7 @@ abstract class ExtendedOpenSslSession extends ExtendedSSLSession implements Open
}
@Override
- public final OpenSslSessionContext getSessionContext() {
+ public final SSLSessionContext getSessionContext() {
return wrapped.getSessionContext();
}
@@ -124,22 +107,13 @@ abstract class ExtendedOpenSslSession extends ExtendedSSLSession implements Open
}
@Override
- public final void putValue(String name, Object value) {
- if (value instanceof SSLSessionBindingListener) {
- // Decorate the value if needed so we submit the correct SSLSession instance
- value = new SSLSessionBindingListenerDecorator((SSLSessionBindingListener) value);
- }
- wrapped.putValue(name, value);
+ public final void putValue(String s, Object o) {
+ wrapped.putValue(s, o);
}
@Override
public final Object getValue(String s) {
- Object value = wrapped.getValue(s);
- if (value instanceof SSLSessionBindingListenerDecorator) {
- // Unwrap as needed so we return the original value
- return ((SSLSessionBindingListenerDecorator) value).delegate;
- }
- return value;
+ return wrapped.getValue(s);
}
@Override
@@ -206,36 +180,4 @@ abstract class ExtendedOpenSslSession extends ExtendedSSLSession implements Open
public final int getApplicationBufferSize() {
return wrapped.getApplicationBufferSize();
}
-
- private final class SSLSessionBindingListenerDecorator implements SSLSessionBindingListener {
-
- final SSLSessionBindingListener delegate;
-
- SSLSessionBindingListenerDecorator(SSLSessionBindingListener delegate) {
- this.delegate = delegate;
- }
-
- @Override
- public void valueBound(SSLSessionBindingEvent event) {
- delegate.valueBound(new SSLSessionBindingEvent(ExtendedOpenSslSession.this, event.getName()));
- }
-
- @Override
- public void valueUnbound(SSLSessionBindingEvent event) {
- delegate.valueUnbound(new SSLSessionBindingEvent(ExtendedOpenSslSession.this, event.getName()));
- }
- }
-
- @Override
- public void handshakeFinished(byte[] id, String cipher, String protocol, byte[] peerCertificate,
- byte[][] peerCertificateChain, long creationTime, long timeout) throws SSLException {
- wrapped.handshakeFinished(id, cipher, protocol, peerCertificate, peerCertificateChain, creationTime, timeout);
- }
-
- @Override
- public String toString() {
- return "ExtendedOpenSslSession{" +
- "wrapped=" + wrapped +
- '}';
- }
}
diff --git a/handler/src/main/java/io/netty/handler/ssl/JdkSslContext.java b/handler/src/main/java/io/netty/handler/ssl/JdkSslContext.java
index a452924829..48e5237863 100644
--- a/handler/src/main/java/io/netty/handler/ssl/JdkSslContext.java
+++ b/handler/src/main/java/io/netty/handler/ssl/JdkSslContext.java
@@ -316,6 +316,16 @@ public class JdkSslContext extends SslContext {
return unmodifiableCipherSuites;
}
+ @Override
+ public final long sessionCacheSize() {
+ return sessionContext().getSessionCacheSize();
+ }
+
+ @Override
+ public final long sessionTimeout() {
+ return sessionContext().getSessionTimeout();
+ }
+
@Override
public final SSLEngine newEngine(ByteBufAllocator alloc) {
return configureAndWrapEngine(context().createSSLEngine(), alloc);
diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSslClientSessionCache.java b/handler/src/main/java/io/netty/handler/ssl/OpenSslClientSessionCache.java
deleted file mode 100644
index f0c6daf4f6..0000000000
--- a/handler/src/main/java/io/netty/handler/ssl/OpenSslClientSessionCache.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright 2021 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:
- *
- * https://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.netty.handler.ssl;
-
-import io.netty.internal.tcnative.SSL;
-import io.netty.util.AsciiString;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * {@link OpenSslSessionCache} that is used by the client-side.
- */
-final class OpenSslClientSessionCache extends OpenSslSessionCache {
- // TODO: Should we support to have a List of OpenSslSessions for a Host/Port key and so be able to
- // support sessions for different protocols / ciphers to the same remote peer ?
- private final Map<HostPort, NativeSslSession> sessions = new HashMap<HostPort, NativeSslSession>();
-
- OpenSslClientSessionCache(OpenSslEngineMap engineMap) {
- super(engineMap);
- }
-
- @Override
- protected boolean sessionCreated(NativeSslSession session) {
- assert Thread.holdsLock(this);
- HostPort hostPort = keyFor(session.getPeerHost(), session.getPeerPort());
- if (hostPort == null || sessions.containsKey(hostPort)) {
- return false;
- }
- sessions.put(hostPort, session);
- return true;
- }
-
- @Override
- protected void sessionRemoved(NativeSslSession session) {
- assert Thread.holdsLock(this);
- HostPort hostPort = keyFor(session.getPeerHost(), session.getPeerPort());
- if (hostPort == null) {
- return;
- }
- sessions.remove(hostPort);
- }
-
- @Override
- void setSession(long ssl, String host, int port) {
- HostPort hostPort = keyFor(host, port);
- if (hostPort == null) {
- return;
- }
- final NativeSslSession session;
- final boolean reused;
- synchronized (this) {
- session = sessions.get(hostPort);
- if (session == null) {
- return;
- }
- if (!session.isValid()) {
- removeSessionWithId(session.sessionId());
- return;
- }
- // Try to set the session, if true is returned OpenSSL incremented the reference count
- // of the underlying SSL_SESSION*.
- reused = SSL.setSession(ssl, session.session());
- }
-
- if (reused) {
- if (session.shouldBeSingleUse()) {
- // Should only be used once
- session.invalidate();
- }
- session.updateLastAccessedTime();
- }
- }
-
- private static HostPort keyFor(String host, int port) {
- if (host == null && port < 1) {
- return null;
- }
- return new HostPort(host, port);
- }
-
- @Override
- synchronized void clear() {
- super.clear();
- sessions.clear();
- }
-
- /**
- * Host / Port tuple used to find a {@link OpenSslSession} in the cache.
- */
- private static final class HostPort {
- private final int hash;
- private final String host;
- private final int port;
-
- HostPort(String host, int port) {
- this.host = host;
- this.port = port;
- // Calculate a hashCode that does ignore case.
- this.hash = 31 * AsciiString.hashCode(host) + port;
- }
-
- @Override
- public int hashCode() {
- return hash;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (!(obj instanceof HostPort)) {
- return false;
- }
- HostPort other = (HostPort) obj;
- return port == other.port && host.equalsIgnoreCase(other.host);
- }
-
- @Override
- public String toString() {
- return "HostPort{" +
- "host='" + host + '\'' +
- ", port=" + port +
- '}';
- }
- }
-}
diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSslSession.java b/handler/src/main/java/io/netty/handler/ssl/OpenSslSession.java
index 4e6ef35d23..056d55f743 100644
--- a/handler/src/main/java/io/netty/handler/ssl/OpenSslSession.java
+++ b/handler/src/main/java/io/netty/handler/ssl/OpenSslSession.java
@@ -15,36 +15,16 @@
*/
package io.netty.handler.ssl;
-import io.netty.util.ReferenceCounted;
-
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSession;
-import java.security.cert.Certificate;
-/**
- * {@link SSLSession} that is specific to our native implementation and {@link ReferenceCounted} to track native
- * resources.
- */
interface OpenSslSession extends SSLSession {
/**
- * Return the {@link OpenSslSessionId} that can be used to identify this session.
- */
- OpenSslSessionId sessionId();
-
- /**
- * Set the local certificate chain that is used. It is not expected that this array will be changed at all
- * and so its ok to not copy the array.
- */
- void setLocalCertificate(Certificate[] localCertificate);
-
- /**
- * Set the {@link OpenSslSessionId} for the {@link OpenSslSession}.
+ * Finish the handshake and so init everything in the {@link OpenSslSession} that should be accessible by
+ * the user.
*/
- void setSessionId(OpenSslSessionId id);
-
- @Override
- OpenSslSessionContext getSessionContext();
+ void handshakeFinished() throws SSLException;
/**
* Expand (or increase) the value returned by {@link #getApplicationBufferSize()} if necessary.
@@ -53,10 +33,4 @@ interface OpenSslSession extends SSLSession {
* @param packetLengthDataOnly The packet size which exceeds the current {@link #getApplicationBufferSize()}.
*/
void tryExpandApplicationBufferSize(int packetLengthDataOnly);
-
- /**
- * Called once the handshake has completed.
- */
- void handshakeFinished(byte[] id, String cipher, String protocol, byte[] peerCertificate,
- byte[][] peerCertificateChain, long creationTime, long timeout) throws SSLException;
}
diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSslSessionCache.java b/handler/src/main/java/io/netty/handler/ssl/OpenSslSessionCache.java
deleted file mode 100644
index 2881a457d9..0000000000
--- a/handler/src/main/java/io/netty/handler/ssl/OpenSslSessionCache.java
+++ /dev/null
@@ -1,492 +0,0 @@
-/*
- * Copyright 2021 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:
- *
- * https://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.netty.handler.ssl;
-
-import io.netty.internal.tcnative.SSLSession;
-import io.netty.internal.tcnative.SSLSessionCache;
-import io.netty.util.ResourceLeakDetector;
-import io.netty.util.ResourceLeakDetectorFactory;
-import io.netty.util.ResourceLeakTracker;
-import io.netty.util.internal.EmptyArrays;
-import io.netty.util.internal.SystemPropertyUtil;
-
-import javax.security.cert.X509Certificate;
-import java.security.Principal;
-import java.security.cert.Certificate;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * {@link SSLSessionCache} implementation for our native SSL implementation.
- */
-class OpenSslSessionCache implements SSLSessionCache {
- private static final OpenSslSession[] EMPTY_SESSIONS = new OpenSslSession[0];
-
- private static final int DEFAULT_CACHE_SIZE;
- static {
- // Respect the same system property as the JDK implementation to make it easy to switch between implementations.
- int cacheSize = SystemPropertyUtil.getInt("javax.net.ssl.sessionCacheSize", 20480);
- if (cacheSize >= 0) {
- DEFAULT_CACHE_SIZE = cacheSize;
- } else {
- DEFAULT_CACHE_SIZE = 20480;
- }
- }
- private final OpenSslEngineMap engineMap;
-
- private final Map<OpenSslSessionId, NativeSslSession> sessions =
- new LinkedHashMap<OpenSslSessionId, NativeSslSession>() {
-
- private static final long serialVersionUID = -7773696788135734448L;
-
- @Override
- protected boolean removeEldestEntry(Map.Entry<OpenSslSessionId, NativeSslSession> eldest) {
- int maxSize = maximumCacheSize.get();
- if (maxSize >= 0 && size() > maxSize) {
- removeSessionWithId(eldest.getKey());
- }
- // We always need to return false as we modify the map directly.
- return false;
- }
- };
-
- private final AtomicInteger maximumCacheSize = new AtomicInteger(DEFAULT_CACHE_SIZE);
-
- // Let's use the same default value as OpenSSL does.
- // See https://www.openssl.org/docs/man1.1.1/man3/SSL_get_default_timeout.html
- private final AtomicInteger sessionTimeout = new AtomicInteger(300);
- private int sessionCounter;
-
- OpenSslSessionCache(OpenSslEngineMap engineMap) {
- this.engineMap = engineMap;
- }
-
- final void setSessionTimeout(int seconds) {
- int oldTimeout = sessionTimeout.getAndSet(seconds);
- if (oldTimeout > seconds) {
- // Drain the whole cache as this way we can use the ordering of the LinkedHashMap to detect early
- // if there are any other sessions left that are invalid.
- clear();
- }
- }
-
- final int getSessionTimeout() {
- return sessionTimeout.get();
- }
-
- /**
- * Called once a new {@link OpenSslSession} was created.
- *
- * @param session the new session.
- * @return {@code true} if the session should be cached, {@code false} otherwise.
- */
- protected boolean sessionCreated(NativeSslSession session) {
- return true;
- }
-
- /**
- * Called once an {@link OpenSslSession} was removed from the cache.
- *
- * @param session the session to remove.
- */
- protected void sessionRemoved(NativeSslSession session) { }
-
- final void setSessionCacheSize(int size) {
- long oldSize = maximumCacheSize.getAndSet(size);
- if (oldSize > size || size == 0) {
- // Just keep it simple for now and drain the whole cache.
- clear();
- }
- }
-
- final int getSessionCacheSize() {
- return maximumCacheSize.get();
- }
-
- private void expungeInvalidSessions() {
- if (sessions.isEmpty()) {
- return;
- }
- long now = System.currentTimeMillis();
- Iterator<Map.Entry<OpenSslSessionId, NativeSslSession>> iterator = sessions.entrySet().iterator();
- while (iterator.hasNext()) {
- NativeSslSession session = iterator.next().getValue();
- // As we use a LinkedHashMap we can break the while loop as soon as we find a valid session.
- // This is true as we always drain the cache as soon as we change the timeout to a smaller value as
- // it was set before. This way its true that the insertion order matches the timeout order.
- if (session.isValid(now)) {
- break;
- }
- iterator.remove();
-
- notifyRemovalAndFree(session);
- }
- }
-
- @Override
- public final boolean sessionCreated(long ssl, long sslSession) {
- ReferenceCountedOpenSslEngine engine = engineMap.get(ssl);
- if (engine == null) {
- // We couldn't find the engine itself.
- return false;
- }
- NativeSslSession session = new NativeSslSession(sslSession, engine.getPeerHost(), engine.getPeerPort(),
- getSessionTimeout() * 1000L);
- engine.setSessionId(session.sessionId());
- synchronized (this) {
- // Mimic what OpenSSL is doing and expunge every 255 new sessions
- // See https://www.openssl.org/docs/man1.0.2/man3/SSL_CTX_flush_sessions.html
- if (++sessionCounter == 255) {
- sessionCounter = 0;
- expungeInvalidSessions();
- }
-
- if (!sessionCreated(session)) {
- // Should not be cached, return false. In this case we also need to call close() to ensure we
- // close the ResourceLeakTracker.
- session.close();
- return false;
- }
-
- final NativeSslSession old = sessions.put(session.sessionId(), session);
- if (old != null) {
- notifyRemovalAndFree(old);
- }
- }
- return true;
- }
-
- @Override
- public final long getSession(long ssl, byte[] sessionId) {
- OpenSslSessionId id = new OpenSslSessionId(sessionId);
- final NativeSslSession session;
- synchronized (this) {
- session = sessions.get(id);
- if (session == null) {
- return -1;
- }
-
- // If the session is not valid anymore we should remove it from the cache and just signal back
- // that we couldn't find a session that is re-usable.
- if (!session.isValid() ||
- // This needs to happen in the synchronized block so we ensure we never destroy it before we
- // incremented the reference count. If we cant increment the reference count there is something
- // wrong. In this case just remove the session from the cache and signal back that we couldn't
- // find a session for re-use.
- !session.upRef()) {
- // Remove the session from the cache. This will also take care of calling SSL_SESSION_free(...)
- removeSessionWithId(session.sessionId());
- return -1;
- }
-
- // At this point we already incremented the reference count via SSL_SESSION_up_ref(...).
- if (session.shouldBeSingleUse()) {
- // Should only be used once. In this case invalidate the session which will also ensure we remove it
- // from the cache and call SSL_SESSION_free(...).
- removeSessionWithId(session.sessionId());
- }
- }
- session.updateLastAccessedTime();
- return session.session();
- }
-
- void setSession(long ssl, String host, int port) {
- // Do nothing by default as this needs special handling for the client side.
- }
-
- /**
- * Remove the session with the given id from the cache
- */
- final synchronized void removeSessionWithId(OpenSslSessionId id) {
- NativeSslSession sslSession = sessions.remove(id);
- if (sslSession != null) {
- notifyRemovalAndFree(sslSession);
- }
- }
-
- /**
- * Returns {@code true} if there is a session for the given id in the cache.
- */
- final synchronized boolean containsSessionWithId(OpenSslSessionId id) {
- return sessions.containsKey(id);
- }
-
- private void notifyRemovalAndFree(NativeSslSession session) {
- sessionRemoved(session);
- session.free();
- }
-
- /**
- * Return the {@link OpenSslSession} which is cached for the given id.
- */
- final synchronized OpenSslSession getSession(OpenSslSessionId id) {
- NativeSslSession session = sessions.get(id);
- if (session != null && !session.isValid()) {
- // The session is not valid anymore, let's remove it and just signal back that there is no session
- // with the given ID in the cache anymore. This also takes care of calling SSL_SESSION_free(...)
- removeSessionWithId(session.sessionId());
- return null;
- }
- return session;
- }
-
- /**
- * Returns a snapshot of the session ids of the current valid sessions.
- */
- final List<OpenSslSessionId> getIds() {
- final OpenSslSession[] sessionsArray;
- synchronized (this) {
- sessionsArray = sessions.values().toArray(EMPTY_SESSIONS);
- }
- List<OpenSslSessionId> ids = new ArrayList<OpenSslSessionId>(sessionsArray.length);
- for (OpenSslSession session: sessionsArray) {
- if (session.isValid()) {
- ids.add(session.sessionId());
- }
- }
- return ids;
- }
-
- /**
- * Clear the cache and free all cached SSL_SESSION*.
- */
- synchronized void clear() {
- Iterator<Map.Entry<OpenSslSessionId, NativeSslSession>> iterator = sessions.entrySet().iterator();
- while (iterator.hasNext()) {
- NativeSslSession session = iterator.next().getValue();
- iterator.remove();
-
- // Notify about removal. This also takes care of calling SSL_SESSION_free(...).
- notifyRemovalAndFree(session);
- }
- }
-
- /**
- * {@link OpenSslSession} implementation which wraps the native SSL_SESSION* while in cache.
- */
- static final class NativeSslSession implements OpenSslSession {
- static final ResourceLeakDetector<NativeSslSession> LEAK_DETECTOR = ResourceLeakDetectorFactory.instance()
- .newResourceLeakDetector(NativeSslSession.class);
- private final ResourceLeakTracker<NativeSslSession> leakTracker;
- private final long session;
- private final String peerHost;
- private final int peerPort;
- private final OpenSslSessionId id;
- private final long timeout;
- private final long creationTime = System.currentTimeMillis();
- private volatile long lastAccessedTime = creationTime;
- private volatile boolean valid = true;
- private boolean freed;
-
- NativeSslSession(long session, String peerHost, int peerPort, long timeout) {
- this.session = session;
- this.peerHost = peerHost;
- this.peerPort = peerPort;
- this.timeout = timeout;
- this.id = new OpenSslSessionId(io.netty.internal.tcnative.SSLSession.getSessionId(session));
- leakTracker = LEAK_DETECTOR.track(this);
- }
-
- @Override
- public void setSessionId(OpenSslSessionId id) {
- throw new UnsupportedOperationException();
- }
-
- boolean shouldBeSingleUse() {
- assert !freed;
- return SSLSession.shouldBeSingleUse(session);
- }
-
- long session() {
- assert !freed;
- return session;
- }
-
- boolean upRef() {
- assert !freed;
- return SSLSession.upRef(session);
- }
-
- synchronized void free() {
- close();
- SSLSession.free(session);
- }
-
- void close() {
- assert !freed;
- freed = true;
- invalidate();
- if (leakTracker != null) {
- leakTracker.close(this);
- }
- }
-
- @Override
- public OpenSslSessionId sessionId() {
- return id;
- }
-
- boolean isValid(long now) {
- return creationTime + timeout >= now && valid;
- }
-
- @Override
- public void setLocalCertificate(Certificate[] localCertificate) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public OpenSslSessionContext getSessionContext() {
- return null;
- }
-
- @Override
- public void tryExpandApplicationBufferSize(int packetLengthDataOnly) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void handshakeFinished(byte[] id, String cipher, String protocol, byte[] peerCertificate,
- byte[][] peerCertificateChain, long creationTime, long timeout) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public byte[] getId() {
- return id.cloneBytes();
- }
-
- @Override
- public long getCreationTime() {
- return creationTime;
- }
-
- void updateLastAccessedTime() {
- lastAccessedTime = System.currentTimeMillis();
- }
-
- @Override
- public long getLastAccessedTime() {
- return lastAccessedTime;
- }
-
- @Override
- public void invalidate() {
- valid = false;
- }
-
- @Override
- public boolean isValid() {
- return isValid(System.currentTimeMillis());
- }
-
- @Override
- public void putValue(String name, Object value) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Object getValue(String name) {
- return null;
- }
-
- @Override
- public void removeValue(String name) {
- // NOOP
- }
-
- @Override
- public String[] getValueNames() {
- return EmptyArrays.EMPTY_STRINGS;
- }
-
- @Override
- public Certificate[] getPeerCertificates() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Certificate[] getLocalCertificates() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public X509Certificate[] getPeerCertificateChain() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Principal getPeerPrincipal() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Principal getLocalPrincipal() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public String getCipherSuite() {
- return null;
- }
-
- @Override
- public String getProtocol() {
- return null;
- }
-
- @Override
- public String getPeerHost() {
- return peerHost;
- }
-
- @Override
- public int getPeerPort() {
- return peerPort;
- }
-
- @Override
- public int getPacketBufferSize() {
- return ReferenceCountedOpenSslEngine.MAX_RECORD_SIZE;
- }
-
- @Override
- public int getApplicationBufferSize() {
- return ReferenceCountedOpenSslEngine.MAX_PLAINTEXT_LENGTH;
- }
-
- @Override
- public int hashCode() {
- return id.hashCode();
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (!(o instanceof OpenSslSession)) {
- return false;
- }
- OpenSslSession session1 = (OpenSslSession) o;
- return id.equals(session1.sessionId());
- }
- }
-}
diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSslSessionId.java b/handler/src/main/java/io/netty/handler/ssl/OpenSslSessionId.java
deleted file mode 100644
index 76941f74ae..0000000000
--- a/handler/src/main/java/io/netty/handler/ssl/OpenSslSessionId.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright 2021 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:
- *
- * https://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.netty.handler.ssl;
-
-import io.netty.util.internal.EmptyArrays;
-
-import java.util.Arrays;
-
-/**
- * Represent the session ID used by an {@link OpenSslSession}.
- */
-final class OpenSslSessionId {
-
- private final byte[] id;
- private final int hashCode;
-
- static final OpenSslSessionId NULL_ID = new OpenSslSessionId(EmptyArrays.EMPTY_BYTES);
-
- OpenSslSessionId(byte[] id) {
- // We take ownership if the byte[] and so there is no need to clone it.
- this.id = id;
- // cache the hashCode as the byte[] array will never change
- this.hashCode = Arrays.hashCode(id);
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (!(o instanceof OpenSslSessionId)) {
- return false;
- }
-
- return Arrays.equals(id, ((OpenSslSessionId) o).id);
- }
-
- @Override
- public String toString() {
- return "OpenSslSessionId{" +
- "id=" + Arrays.toString(id) +
- '}';
- }
-
- @Override
- public int hashCode() {
- return hashCode;
- }
-
- byte[] cloneBytes() {
- return id.clone();
- }
-}
diff --git a/handler/src/main/java/io/netty/handler/ssl/SslContext.java b/handler/src/main/java/io/netty/handler/ssl/SslContext.java
index 1c8efb7151..c3c67e0425 100644
--- a/handler/src/main/java/io/netty/handler/ssl/SslContext.java
+++ b/handler/src/main/java/io/netty/handler/ssl/SslContext.java
@@ -867,16 +867,12 @@ public abstract class SslContext {
/**
* Returns the size of the cache used for storing SSL session objects.
*/
- public long sessionCacheSize() {
- return sessionContext().getSessionCacheSize();
- }
+ public abstract long sessionCacheSize();
/**
* Returns the timeout for the cached SSL session objects, in seconds.
*/
- public long sessionTimeout() {
- return sessionContext().getSessionTimeout();
- }
+ public abstract long sessionTimeout();
/**
* @deprecated Use {@link #applicationProtocolNegotiator()} instead.
diff --git a/handler/src/main/java/io/netty/handler/ssl/util/LazyJavaxX509Certificate.java b/handler/src/main/java/io/netty/handler/ssl/util/LazyJavaxX509Certificate.java
index 66a769d14a..65831c0628 100644
--- a/handler/src/main/java/io/netty/handler/ssl/util/LazyJavaxX509Certificate.java
+++ b/handler/src/main/java/io/netty/handler/ssl/util/LazyJavaxX509Certificate.java
@@ -101,14 +101,6 @@ public final class LazyJavaxX509Certificate extends X509Certificate {
return bytes.clone();
}
- /**
- * Return the underyling {@code byte[]} without cloning it first. This {@code byte[]} <strong>must</strong> never
- * be mutated.
- */
- byte[] getBytes() {
- return bytes;
- }
-
@Override
public void verify(PublicKey key)
throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException,
diff --git a/handler/src/test/java/io/netty/handler/ssl/ConscryptJdkSslEngineInteropTest.java b/handler/src/test/java/io/netty/handler/ssl/ConscryptJdkSslEngineInteropTest.java
index 6d8a9c7e3e..20af113d86 100644
--- a/handler/src/test/java/io/netty/handler/ssl/ConscryptJdkSslEngineInteropTest.java
+++ b/handler/src/test/java/io/netty/handler/ssl/ConscryptJdkSslEngineInteropTest.java
@@ -22,9 +22,6 @@ import org.junit.jupiter.api.condition.DisabledIf;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
-import javax.net.ssl.SSLSessionContext;
-
-
@DisabledIf("checkConscryptDisabled")
public class ConscryptJdkSslEngineInteropTest extends SSLEngineTest {
@@ -75,11 +72,6 @@ public class ConscryptJdkSslEngineInteropTest extends SSLEngineTest {
return super.mySetupMutualAuthServerIsValidServerException(cause) || causedBySSLException(cause);
}
- @Override
- protected void invalidateSessionsAndAssert(SSLSessionContext context) {
- // Not supported by conscrypt
- }
-
@MethodSource("newTestParams")
@ParameterizedTest
@Disabled("Disabled due a conscrypt bug")
diff --git a/handler/src/test/java/io/netty/handler/ssl/ConscryptOpenSslEngineInteropTest.java b/handler/src/test/java/io/netty/handler/ssl/ConscryptOpenSslEngineInteropTest.java
index 9e3c485b58..ef0147e518 100644
--- a/handler/src/test/java/io/netty/handler/ssl/ConscryptOpenSslEngineInteropTest.java
+++ b/handler/src/test/java/io/netty/handler/ssl/ConscryptOpenSslEngineInteropTest.java
@@ -22,7 +22,6 @@ import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import javax.net.ssl.SSLEngine;
-import javax.net.ssl.SSLSessionContext;
import java.security.Provider;
import java.util.ArrayList;
@@ -162,11 +161,6 @@ public class ConscryptOpenSslEngineInteropTest extends ConscryptSslEngineTest {
super.testSessionLocalWhenNonMutualWithoutKeyManager(param);
}
- @Override
- protected void invalidateSessionsAndAssert(SSLSessionContext context) {
- // Not supported by conscrypt
- }
-
@MethodSource("newTestParams")
@ParameterizedTest
@Override
@@ -211,8 +205,6 @@ public class ConscryptOpenSslEngineInteropTest extends ConscryptSslEngineTest {
if (param instanceof OpenSslEngineTestParam) {
((OpenSslContext) context).setUseTasks(((OpenSslEngineTestParam) param).useTasks);
}
- // Explicit enable the session cache as its disabled by default on the client side.
- ((OpenSslContext) context).sessionContext().setSessionCacheEnabled(true);
}
return context;
}
diff --git a/handler/src/test/java/io/netty/handler/ssl/ConscryptSslEngineTest.java b/handler/src/test/java/io/netty/handler/ssl/ConscryptSslEngineTest.java
index 58221857f0..2698acc09e 100644
--- a/handler/src/test/java/io/netty/handler/ssl/ConscryptSslEngineTest.java
+++ b/handler/src/test/java/io/netty/handler/ssl/ConscryptSslEngineTest.java
@@ -21,7 +21,6 @@ import org.junit.jupiter.api.condition.DisabledIf;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
-import javax.net.ssl.SSLSessionContext;
import java.security.Provider;
@DisabledIf("checkConscryptDisabled")
@@ -69,20 +68,6 @@ public class ConscryptSslEngineTest extends SSLEngineTest {
public void testMutualAuthValidClientCertChainTooLongFailRequireClientAuth(SSLEngineTestParam param) {
}
- @Override
- protected void invalidateSessionsAndAssert(SSLSessionContext context) {
- // Not supported by conscrypt
- }
-
- @MethodSource("newTestParams")
- @ParameterizedTest
- @Disabled("Possible Conscrypt bug")
- @Override
- public void testSessionCacheTimeout(SSLEngineTestParam param) throws Exception {
- // Skip
- // https://github.com/google/conscrypt/issues/851
- }
-
@Disabled("Not supported")
@Override
public void testRSASSAPSS(SSLEngineTestParam param) {
diff --git a/handler/src/test/java/io/netty/handler/ssl/JdkConscryptSslEngineInteropTest.java b/handler/src/test/java/io/netty/handler/ssl/JdkConscryptSslEngineInteropTest.java
index be453dbbfa..8d0e66f96d 100644
--- a/handler/src/test/java/io/netty/handler/ssl/JdkConscryptSslEngineInteropTest.java
+++ b/handler/src/test/java/io/netty/handler/ssl/JdkConscryptSslEngineInteropTest.java
@@ -22,7 +22,13 @@ import org.junit.jupiter.api.condition.DisabledIf;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
+<<<<<<< HEAD
import javax.net.ssl.SSLSessionContext;
+=======
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+>>>>>>> 5b23a90531 (Revert "Support session cache for client and server when using native SSLEngine implementation (#10994)")
@DisabledIf("checkConscryptDisabled")
public class JdkConscryptSslEngineInteropTest extends SSLEngineTest {
@@ -83,20 +89,6 @@ public class JdkConscryptSslEngineInteropTest extends SSLEngineTest {
// See https://github.com/google/conscrypt/issues/634
}
- @Override
- protected void invalidateSessionsAndAssert(SSLSessionContext context) {
- // Not supported by conscrypt
- }
-
- @MethodSource("newTestParams")
- @ParameterizedTest
- @Disabled("Possible Conscrypt bug")
- @Override
- public void testSessionCacheTimeout(SSLEngineTestParam param) {
- // Skip
- // https://github.com/google/conscrypt/issues/851
- }
-
@Disabled("Not supported")
@Override
public void testRSASSAPSS(SSLEngineTestParam param) {
diff --git a/handler/src/test/java/io/netty/handler/ssl/JdkOpenSslEngineInteroptTest.java b/handler/src/test/java/io/netty/handler/ssl/JdkOpenSslEngineInteroptTest.java
index a0c04188b4..534beeec65 100644
--- a/handler/src/test/java/io/netty/handler/ssl/JdkOpenSslEngineInteroptTest.java
+++ b/handler/src/test/java/io/netty/handler/ssl/JdkOpenSslEngineInteroptTest.java
@@ -247,8 +247,6 @@ public class JdkOpenSslEngineInteroptTest extends SSLEngineTest {
protected SslContext wrapContext(SSLEngineTestParam param, SslContext context) {
if (context instanceof OpenSslContext && param instanceof OpenSslEngineTestParam) {
((OpenSslContext) context).setUseTasks(((OpenSslEngineTestParam) param).useTasks);
- // Explicit enable the session cache as its disabled by default on the client side.
- ((OpenSslContext) context).sessionContext().setSessionCacheEnabled(true);
}
return context;
}
diff --git a/handler/src/test/java/io/netty/handler/ssl/OpenSslConscryptSslEngineInteropTest.java b/handler/src/test/java/io/netty/handler/ssl/OpenSslConscryptSslEngineInteropTest.java
index b5d4903938..8014000630 100644
--- a/handler/src/test/java/io/netty/handler/ssl/OpenSslConscryptSslEngineInteropTest.java
+++ b/handler/src/test/java/io/netty/handler/ssl/OpenSslConscryptSslEngineInteropTest.java
@@ -22,7 +22,6 @@ import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import javax.net.ssl.SSLEngine;
-import javax.net.ssl.SSLSessionContext;
import java.security.Provider;
import java.util.ArrayList;
import java.util.List;
@@ -166,11 +165,6 @@ public class OpenSslConscryptSslEngineInteropTest extends ConscryptSslEngineTest
super.testSessionCacheSize(param);
}
- @Override
- protected void invalidateSessionsAndAssert(SSLSessionContext context) {
- // Not supported by conscrypt
- }
-
@Override
protected SSLEngine wrapEngine(SSLEngine engine) {
return Java8SslTestUtils.wrapSSLEngineForTesting(engine);
@@ -183,8 +177,6 @@ public class OpenSslConscryptSslEngineInteropTest extends ConscryptSslEngineTest
if (param instanceof OpenSslEngineTestParam) {
((OpenSslContext) context).setUseTasks(((OpenSslEngineTestParam) param).useTasks);
}
- // Explicit enable the session cache as its disabled by default on the client side.
- ((OpenSslContext) context).sessionContext().setSessionCacheEnabled(true);
}
return context;
}
diff --git a/handler/src/test/java/io/netty/handler/ssl/OpenSslEngineTest.java b/handler/src/test/java/io/netty/handler/ssl/OpenSslEngineTest.java
index 9ad1c3b10f..ef559db1df 100644
--- a/handler/src/test/java/io/netty/handler/ssl/OpenSslEngineTest.java
+++ b/handler/src/test/java/io/netty/handler/ssl/OpenSslEngineTest.java
@@ -1514,62 +1514,10 @@ public class OpenSslEngineTest extends SSLEngineTest {
if (param instanceof OpenSslEngineTestParam) {
((OpenSslContext) context).setUseTasks(((OpenSslEngineTestParam) param).useTasks);
}
- // Explicit enable the session cache as its disabled by default on the client side.
- ((OpenSslContext) context).sessionContext().setSessionCacheEnabled(true);
}
return context;
}
- @MethodSource("newTestParams")
- @ParameterizedTest
- @Override
- public void testSessionCache(SSLEngineTestParam param) throws Exception {
- assumeTrue(OpenSsl.isSessionCacheSupported());
- super.testSessionCache(param);
- assertSessionContext(clientSslCtx);
- assertSessionContext(serverSslCtx);
- }
-
- @MethodSource("newTestParams")
- @ParameterizedTest
- @Override
- public void testSessionCacheTimeout(SSLEngineTestParam param) throws Exception {
- assumeTrue(OpenSsl.isSessionCacheSupported());
- super.testSessionCacheTimeout(param);
- }
-
- @MethodSource("newTestParams")
- @ParameterizedTest
- @Override
- public void testSessionCacheSize(SSLEngineTestParam param) throws Exception {
- assumeTrue(OpenSsl.isSessionCacheSupported());
- super.testSessionCacheSize(param);
- }
-
- private static void assertSessionContext(SslContext context) {
- if (context == null) {
- return;
- }
- OpenSslSessionContext serverSessionCtx = (OpenSslSessionContext) context.sessionContext();
- assertTrue(serverSessionCtx.isSessionCacheEnabled());
- if (serverSessionCtx.getIds().hasMoreElements()) {
- serverSessionCtx.setSessionCacheEnabled(false);
- assertFalse(serverSessionCtx.getIds().hasMoreElements());
- assertFalse(serverSessionCtx.isSessionCacheEnabled());
- }
- }
-
- @Override
- protected void assertSessionReusedForEngine(SSLEngine clientEngine, SSLEngine serverEngine, boolean reuse) {
- assertEquals(reuse, unwrapEngine(clientEngine).isSessionReused());
- assertEquals(reuse, unwrapEngine(serverEngine).isSessionReused());
- }
-
- @Override
- protected boolean isSessionMaybeReused(SSLEngine engine) {
- return unwrapEngine(engine).isSessionReused();
- }
-
@MethodSource("newTestParams")
@ParameterizedTest
@Override
diff --git a/handler/src/test/java/io/netty/handler/ssl/OpenSslJdkSslEngineInteroptTest.java b/handler/src/test/java/io/netty/handler/ssl/OpenSslJdkSslEngineInteroptTest.java
index 0d47fd09b3..3eda99e7f9 100644
--- a/handler/src/test/java/io/netty/handler/ssl/OpenSslJdkSslEngineInteroptTest.java
+++ b/handler/src/test/java/io/netty/handler/ssl/OpenSslJdkSslEngineInteroptTest.java
@@ -19,6 +19,7 @@ import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
+import io.netty.util.internal.PlatformDependent;
import javax.net.ssl.SSLEngine;
@@ -194,8 +195,6 @@ public class OpenSslJdkSslEngineInteroptTest extends SSLEngineTest {
protected SslContext wrapContext(SSLEngineTestParam param, SslContext context) {
if (context instanceof OpenSslContext && param instanceof OpenSslEngineTestParam) {
((OpenSslContext) context).setUseTasks(((OpenSslEngineTestParam) param).useTasks);
- // Explicit enable the session cache as its disabled by default on the client side.
- ((OpenSslContext) context).sessionContext().setSessionCacheEnabled(true);
}
return context;
}
diff --git a/handler/src/test/java/io/netty/handler/ssl/ReferenceCountedOpenSslEngineTest.java b/handler/src/test/java/io/netty/handler/ssl/ReferenceCountedOpenSslEngineTest.java
index aa32b7de2f..01f56519ee 100644
--- a/handler/src/test/java/io/netty/handler/ssl/ReferenceCountedOpenSslEngineTest.java
+++ b/handler/src/test/java/io/netty/handler/ssl/ReferenceCountedOpenSslEngineTest.java
@@ -84,8 +84,6 @@ public class ReferenceCountedOpenSslEngineTest extends OpenSslEngineTest {
if (param instanceof OpenSslEngineTestParam) {
((ReferenceCountedOpenSslContext) context).setUseTasks(((OpenSslEngineTestParam) param).useTasks);
}
- // Explicit enable the session cache as its disabled by default on the client side.
- ((ReferenceCountedOpenSslContext) context).sessionContext().setSessionCacheEnabled(true);
}
return context;
}
diff --git a/handler/src/test/java/io/netty/handler/ssl/SSLEngineTest.java b/handler/src/test/java/io/netty/handler/ssl/SSLEngineTest.java
index 6a187fded3..fba11d0ce3 100644
--- a/handler/src/test/java/io/netty/handler/ssl/SSLEngineTest.java
+++ b/handler/src/test/java/io/netty/handler/ssl/SSLEngineTest.java
@@ -88,7 +88,6 @@ import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
-import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -116,7 +115,6 @@ import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSessionBindingEvent;
import javax.net.ssl.SSLSessionBindingListener;
-import javax.net.ssl.SSLSessionContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
@@ -1366,14 +1364,14 @@ public abstract class SSLEngineTest {
.trustManager(InsecureTrustManagerFactory.INSTANCE)
.sslProvider(sslClientProvider())
// This test only works for non TLSv1.3 for now
- .protocols(param.protocols())
+ .protocols(PROTOCOL_TLS_V1_2)
.sslContextProvider(clientSslContextProvider())
.build());
SelfSignedCertificate ssc = new SelfSignedCertificate();
serverSslCtx = wrapContext(param, SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey())
.sslProvider(sslServerProvider())
// This test only works for non TLSv1.3 for now
- .protocols(param.protocols())
+ .protocols(PROTOCOL_TLS_V1_2)
.sslContextProvider(serverSslContextProvider())
.build());
SSLEngine clientEngine = null;
@@ -1388,54 +1386,10 @@ public abstract class SSLEngineTest {
handshake(param.type(), param.delegate(), clientEngine, serverEngine);
- if (param.protocolCipherCombo == ProtocolCipherCombo.TLSV13) {
- // Allocate something which is big enough for sure
- ByteBuffer packetBuffer = allocateBuffer(param.type(), 32 * 1024);
- ByteBuffer appBuffer = allocateBuffer(param.type(), 32 * 1024);
-
- appBuffer.clear().position(4).flip();
- packetBuffer.clear();
-
- do {
- SSLEngineResult result;
-
- do {
- result = serverEngine.wrap(appBuffer, packetBuffer);
- } while (appBuffer.hasRemaining() || result.bytesProduced() > 0);
-
- appBuffer.clear();
- packetBuffer.flip();
- do {
- result = clientEngine.unwrap(packetBuffer, appBuffer);
- } while (packetBuffer.hasRemaining() || result.bytesProduced() > 0);
-
- packetBuffer.clear();
- appBuffer.clear().position(4).flip();
-
- do {
- result = clientEngine.wrap(appBuffer, packetBuffer);
- } while (appBuffer.hasRemaining() || result.bytesProduced() > 0);
-
- appBuffer.clear();
- packetBuffer.flip();
-
- do {
- result = serverEngine.unwrap(packetBuffer, appBuffer);
- } while (packetBuffer.hasRemaining() || result.bytesProduced() > 0);
-
- packetBuffer.clear();
- appBuffer.clear().position(4).flip();
- } while (clientEngine.getSession().getId().length == 0);
-
- // With TLS1.3 we should see pseudo IDs and so these should never match.
- assertFalse(Arrays.equals(clientEngine.getSession().getId(), serverEngine.getSession().getId()));
- } else {
- // 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());
- }
+ // 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);
@@ -1629,6 +1583,7 @@ public abstract class SSLEngineTest {
boolean clientHandshakeFinished = false;
boolean serverHandshakeFinished = false;
+
boolean cTOsHasRemaining;
boolean sTOcHasRemaining;
@@ -3127,274 +3082,6 @@ public abstract class SSLEngineTest {
}
}
- @MethodSource("newTestParams")
- @ParameterizedTest
- public void testSessionCache(SSLEngineTestParam param) throws Exception {
- clientSslCtx = wrapContext(param, SslContextBuilder.forClient()
- .trustManager(InsecureTrustManagerFactory.INSTANCE)
- .sslProvider(sslClientProvider())
- .sslContextProvider(clientSslContextProvider())
- .protocols(param.protocols())
- .ciphers(param.ciphers())
- .build());
- SelfSignedCertificate ssc = new SelfSignedCertificate();
- serverSslCtx = wrapContext(param, SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey())
- .sslProvider(sslServerProvider())
- .sslContextProvider(serverSslContextProvider())
- .protocols(param.protocols())
- .ciphers(param.ciphers())
- .build());
-
- try {
- doHandshakeVerifyReusedAndClose(param, "a.netty.io", 9999, false);
- doHandshakeVerifyReusedAndClose(param, "a.netty.io", 9999, true);
- doHandshakeVerifyReusedAndClose(param, "b.netty.io", 9999, false);
- invalidateSessionsAndAssert(serverSslCtx.sessionContext());
- invalidateSessionsAndAssert(clientSslCtx.sessionContext());
- } finally {
- ssc.delete();
- }
- }
-
- protected void invalidateSessionsAndAssert(SSLSessionContext context) {
- Enumeration<byte[]> ids = context.getIds();
- while (ids.hasMoreElements()) {
- byte[] id = ids.nextElement();
- SSLSession session = context.getSession(id);
- if (session != null) {
- session.invalidate();
- assertFalse(session.isValid());
- assertNull(context.getSession(id));
- }
- }
- }
-
- private static void assertSessionCache(SSLSessionContext sessionContext, int numSessions) {
- Enumeration<byte[]> ids = sessionContext.getIds();
- int numIds = 0;
- while (ids.hasMoreElements()) {
- numIds++;
- byte[] id = ids.nextElement();
- assertNotEquals(0, id.length);
- SSLSession session = sessionContext.getSession(id);
- assertArrayEquals(id, session.getId());
- }
- assertEquals(numSessions, numIds);
- }
-
- private void doHandshakeVerifyReusedAndClose(SSLEngineTestParam param, String host, int port, boolean reuse)
- throws Exception {
- SSLEngine clientEngine = null;
- SSLEngine serverEngine = null;
- try {
- clientEngine = wrapEngine(clientSslCtx.newEngine(UnpooledByteBufAllocator.DEFAULT, host, port));
- serverEngine = wrapEngine(serverSslCtx.newEngine(UnpooledByteBufAllocator.DEFAULT));
- handshake(param.type(), param.delegate(), clientEngine, serverEngine);
- int clientSessions = currentSessionCacheSize(clientSslCtx.sessionContext());
- int serverSessions = currentSessionCacheSize(serverSslCtx.sessionContext());
- int nCSessions = clientSessions;
- int nSSessions = serverSessions;
- boolean clientSessionReused = false;
- boolean serverSessionReused = false;
- if (param.protocolCipherCombo == ProtocolCipherCombo.TLSV13) {
- // Allocate something which is big enough for sure
- ByteBuffer packetBuffer = allocateBuffer(param.type(), 32 * 1024);
- ByteBuffer appBuffer = allocateBuffer(param.type(), 32 * 1024);
-
- appBuffer.clear().position(4).flip();
- packetBuffer.clear();
-
- do {
- SSLEngineResult result;
-
- do {
- result = serverEngine.wrap(appBuffer, packetBuffer);
- } while (appBuffer.hasRemaining() || result.bytesProduced() > 0);
-
- appBuffer.clear();
- packetBuffer.flip();
- do {
- result = clientEngine.unwrap(packetBuffer, appBuffer);
- } while (packetBuffer.hasRemaining() || result.bytesProduced() > 0);
-
- packetBuffer.clear();
- appBuffer.clear().position(4).flip();
-
- do {
- result = clientEngine.wrap(appBuffer, packetBuffer);
- } while (appBuffer.hasRemaining() || result.bytesProduced() > 0);
-
- appBuffer.clear();
- packetBuffer.flip();
-
- do {
- result = serverEngine.unwrap(packetBuffer, appBuffer);
- } while (packetBuffer.hasRemaining() || result.bytesProduced() > 0);
-
- packetBuffer.clear();
- appBuffer.clear().position(4).flip();
- nCSessions = currentSessionCacheSize(clientSslCtx.sessionContext());
- nSSessions = currentSessionCacheSize(serverSslCtx.sessionContext());
- clientSessionReused = isSessionMaybeReused(clientEngine);
- serverSessionReused = isSessionMaybeReused(serverEngine);
- } while ((reuse && (!clientSessionReused || !serverSessionReused))
- || (!reuse && (nCSessions < clientSessions ||
- // server may use multiple sessions
- nSSessions < serverSessions)));
- }
-
- assertSessionReusedForEngine(clientEngine, serverEngine, reuse);
-
- closeOutboundAndInbound(param.type(), clientEngine, serverEngine);
- } finally {
- cleanupClientSslEngine(clientEngine);
- cleanupServerSslEngine(serverEngine);
- }
- }
-
- protected boolean isSessionMaybeReused(SSLEngine engine) {
- return true;
- }
-
- private static int currentSessionCacheSize(SSLSessionContext ctx) {
- Enumeration<byte[]> ids = ctx.getIds();
- int i = 0;
- while (ids.hasMoreElements()) {
- i++;
- ids.nextElement();
- }
- return i;
- }
-
- private void closeOutboundAndInbound(
- BufferType type, SSLEngine clientEngine, SSLEngine serverEngine) throws SSLException {
- assertFalse(clientEngine.isInboundDone());
- assertFalse(clientEngine.isOutboundDone());
- assertFalse(serverEngine.isInboundDone());
- assertFalse(serverEngine.isOutboundDone());
-
- ByteBuffer empty = allocateBuffer(type, 0);
-
- // Ensure we allocate a bit more so we can fit in multiple packets. This is needed as we may call multiple
- // time wrap / unwrap in a for loop before we drain the buffer we are writing in.
- ByteBuffer cTOs = allocateBuffer(type, clientEngine.getSession().getPacketBufferSize() * 4);
- ByteBuffer sTOs = allocateBuffer(type, serverEngine.getSession().getPacketBufferSize() * 4);
- ByteBuffer cApps = allocateBuffer(type, clientEngine.getSession().getApplicationBufferSize() * 4);
- ByteBuffer sApps = allocateBuffer(type, serverEngine.getSession().getApplicationBufferSize() * 4);
-
- clientEngine.closeOutbound();
- for (;;) {
- // call wrap till we produced all data
- SSLEngineResult result = clientEngine.wrap(empty, cTOs);
- if (result.getStatus() == Status.CLOSED && result.bytesProduced() == 0) {
- break;
- }
- assertTrue(cTOs.hasRemaining());
- }
- cTOs.flip();
-
- for (;;) {
- // call unwrap till we consumed all data
- SSLEngineResult result = serverEngine.unwrap(cTOs, sApps);
- if (result.getStatus() == Status.CLOSED && result.bytesProduced() == 0) {
- break;
- }
- assertTrue(sApps.hasRemaining());
- }
-
- serverEngine.closeOutbound();
- for (;;) {
- // call wrap till we produced all data
- SSLEngineResult result = serverEngine.wrap(empty, sTOs);
- if (result.getStatus() == Status.CLOSED && result.bytesProduced() == 0) {
- break;
- }
- assertTrue(sTOs.hasRemaining());
- }
- sTOs.flip();
-
- for (;;) {
- // call unwrap till we consumed all data
- SSLEngineResult result = clientEngine.unwrap(sTOs, cApps);
- if (result.getStatus() == Status.CLOSED && result.bytesProduced() == 0) {
- break;
- }
- assertTrue(cApps.hasRemaining());
- }
-
- // Now close the inbound as well
- clientEngine.closeInbound();
- serverEngine.closeInbound();
- }
-
- protected void assertSessionReusedForEngine(SSLEngine clientEngine, SSLEngine serverEngine, boolean reuse) {
- // NOOP
- }
-
- @MethodSource("newTestParams")
- @ParameterizedTest
- public void testSessionCacheTimeout(SSLEngineTestParam param) throws Exception {
- clientSslCtx = wrapContext(param, SslContextBuilder.forClient()
- .trustManager(InsecureTrustManagerFactory.INSTANCE)
- .sslProvider(sslClientProvider())
- .sslContextProvider(clientSslContextProvider())
- .protocols(param.protocols())
- .ciphers(param.ciphers())
- .sessionTimeout(1)
- .build());
- SelfSignedCertificate ssc = new SelfSignedCertificate();
- serverSslCtx = wrapContext(param, SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey())
- .sslProvider(sslServerProvider())
- .sslContextProvider(serverSslContextProvider())
- .protocols(param.protocols())
- .ciphers(param.ciphers())
- .sessionTimeout(1)
- .build());
-
- try {
- doHandshakeVerifyReusedAndClose(param, "a.netty.io", 9999, false);
-
- // Let's sleep for a bit more then 1 second so the cache should timeout the sessions.
- Thread.sleep(1500);
-
- assertSessionCache(serverSslCtx.sessionContext(), 0);
- assertSessionCache(clientSslCtx.sessionContext(), 0);
- } finally {
- ssc.delete();
- }
- }
-
- @MethodSource("newTestParams")
- @ParameterizedTest
- public void testSessionCacheSize(SSLEngineTestParam param) throws Exception {
- clientSslCtx = wrapContext(param, SslContextBuilder.forClient()
- .trustManager(InsecureTrustManagerFactory.INSTANCE)
- .sslProvider(sslClientProvider())
- .sslContextProvider(clientSslContextProvider())
- .protocols(param.protocols())
- .ciphers(param.ciphers())
- .sessionCacheSize(1)
- .build());
- SelfSignedCertificate ssc = new SelfSignedCertificate();
- serverSslCtx = wrapContext(param, SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey())
- .sslProvider(sslServerProvider())
- .sslContextProvider(serverSslContextProvider())
- .protocols(param.protocols())
- .ciphers(param.ciphers())
- .build());
-
- try {
- doHandshakeVerifyReusedAndClose(param, "a.netty.io", 9999, false);
- // As we have a cache size of 1 we should never have more then one session in the cache
- doHandshakeVerifyReusedAndClose(param, "b.netty.io", 9999, false);
-
- // We should at least reuse b.netty.io
- doHandshakeVerifyReusedAndClose(param, "b.netty.io", 9999, true);
- } finally {
- ssc.delete();
- }
- }
-
@MethodSource("newTestParams")
@ParameterizedTest
public void testSessionBindingEvent(SSLEngineTestParam param) throws Exception {
@@ -4020,7 +3707,7 @@ public abstract class SSLEngineTest {
final Promise<SecretKey> promise = sb.config().group().next().newPromise();
serverChannel = sb.childHandler(new ChannelInitializer<Channel>() {
@Override
- protected void initChannel(Channel ch) {
+ protected void initChannel(Channel ch) throws Exception {
ch.config().setAllocator(new TestByteBufAllocator(ch.config().getAllocator(), param.type()));
SslHandler sslHandler = !param.delegate() ?
@@ -4078,7 +3765,7 @@ public abstract class SSLEngineTest {
new java.security.cert.X509Certificate[] { ssc.cert() }, null, ssc.key(), null, null, null);
}
- private static final class TestTrustManagerFactory extends X509ExtendedTrustManager {
+ private final class TestTrustManagerFactory extends X509ExtendedTrustManager {
private final Certificate localCert;
private volatile boolean verified;
diff --git a/handler/src/test/java/io/netty/handler/ssl/SslHandlerTest.java b/handler/src/test/java/io/netty/handler/ssl/SslHandlerTest.java
index 70aef23b60..53f5a2fcbc 100644
--- a/handler/src/test/java/io/netty/handler/ssl/SslHandlerTest.java
+++ b/handler/src/test/java/io/netty/handler/ssl/SslHandlerTest.java
@@ -1297,10 +1297,6 @@ public class SslHandlerTest {
.protocols(protocol)
.build();
- // Explicit enable session cache as it's disabled by default atm.
- ((OpenSslContext) sslClientCtx).sessionContext()
- .setSessionCacheEnabled(true);
-
final SelfSignedCertificate cert = new SelfSignedCertificate();
final SslContext sslServerCtx = SslContextBuilder.forServer(cert.key(), cert.cert())
.sslProvider(provider)
@@ -1319,41 +1315,25 @@ public class SslHandlerTest {
EventLoopGroup group = new NioEventLoopGroup();
Channel sc = null;
+ Channel cc = null;
+ final SslHandler clientSslHandler = sslClientCtx.newHandler(UnpooledByteBufAllocator.DEFAULT);
+ final SslHandler serverSslHandler = sslServerCtx.newHandler(UnpooledByteBufAllocator.DEFAULT);
+
+ final BlockingQueue<Object> queue = new LinkedBlockingQueue<Object>();
final byte[] bytes = new byte[96];
PlatformDependent.threadLocalRandom().nextBytes(bytes);
try {
- final AtomicReference<AssertionError> assertErrorRef = new AtomicReference<AssertionError>();
sc = new ServerBootstrap()
.group(group)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(Channel ch) {
- final SslHandler sslHandler = sslServerCtx.newHandler(ch.alloc());
- ch.pipeline().addLast(sslServerCtx.newHandler(UnpooledByteBufAllocator.DEFAULT));
+ ch.pipeline().addLast(serverSslHandler);
ch.pipeline().addLast(new ChannelInboundHandlerAdapter() {
-
- private int handshakeCount;
-
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
if (evt instanceof SslHandshakeCompletionEvent) {
- handshakeCount++;
- ReferenceCountedOpenSslEngine engine =
- (ReferenceCountedOpenSslEngine) sslHandler.engine();
- // This test only works for non TLSv1.3 as TLSv1.3 will establish sessions after
- // the handshake is done.
- // See https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_sess_set_get_cb.html
- if (!SslProtocols.TLS_v1_3.equals(engine.getSession().getProtocol())) {
- // First should not re-use the session
- try {
- assertEquals(handshakeCount > 1, engine.isSessionReused());
- } catch (AssertionError error) {
- assertErrorRef.set(error);
- return;
- }
- }
-
ctx.writeAndFlush(Unpooled.wrappedBuffer(bytes));
}
}
@@ -1362,31 +1342,6 @@ public class SslHandlerTest {
})
.bind(new InetSocketAddress(0)).syncUninterruptibly().channel();
- InetSocketAddress serverAddr = (InetSocketAddress) sc.localAddress();
- testSessionTickets(serverAddr, group, sslClientCtx, bytes, false);
- testSessionTickets(serverAddr, group, sslClientCtx, bytes, true);
- AssertionError error = assertErrorRef.get();
- if (error != null) {
- throw error;
- }
- } finally {
- if (sc != null) {
- sc.close().syncUninterruptibly();
- }
- group.shutdownGracefully();
- ReferenceCountUtil.release(sslClientCtx);
- }
- }
-
- private static void testSessionTickets(InetSocketAddress serverAddress, EventLoopGroup group,
- SslContext sslClientCtx, final byte[] bytes, boolean isReused)
- throws Throwable {
- Channel cc = null;
- final BlockingQueue<Object> queue = new LinkedBlockingQueue<Object>();
- try {
- final SslHandler clientSslHandler = sslClientCtx.newHandler(UnpooledByteBufAllocator.DEFAULT,
- serverAddress.getAddress().getHostAddress(), serverAddress.getPort());
-
ChannelFuture future = new Bootstrap()
.group(group)
.channel(NioSocketChannel.class)
@@ -1409,18 +1364,11 @@ public class SslHandlerTest {
}
});
}
- }).connect(serverAddress);
+ }).connect(sc.localAddress());
cc = future.syncUninterruptibly().channel();
- assertTrue(clientSslHandler.handshakeFuture().sync().isSuccess());
-
- ReferenceCountedOpenSslEngine engine = (ReferenceCountedOpenSslEngine) clientSslHandler.engine();
- // This test only works for non TLSv1.3 as TLSv1.3 will establish sessions after
- // the handshake is done.
- // See https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_sess_set_get_cb.html
- if (!SslProtocols.TLS_v1_3.equals(engine.getSession().getProtocol())) {
- assertEquals(isReused, engine.isSessionReused());
- }
+ assertTrue(clientSslHandler.handshakeFuture().await().isSuccess());
+ assertTrue(serverSslHandler.handshakeFuture().await().isSuccess());
Object obj = queue.take();
if (obj instanceof ByteBuf) {
ByteBuf buffer = (ByteBuf) obj;
@@ -1438,6 +1386,11 @@ public class SslHandlerTest {
if (cc != null) {
cc.close().syncUninterruptibly();
}
+ if (sc != null) {
+ sc.close().syncUninterruptibly();
+ }
+ group.shutdownGracefully();
+ ReferenceCountUtil.release(sslClientCtx);
}
}
--
2.35.1