Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Step:15-SP2
netty.23812
0007-Revert-Support-session-cache-for-client-an...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0007-Revert-Support-session-cache-for-client-and-server-w.patch of Package netty.23812
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
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor