Add SSLEngineTest to ensure Signature Algorithms are present during KeyManager calls. (#8965)

Motivation:

We had a bug which could case ExtendedSSLSession.getPeerSupportedSignatureAlgorithms() return an empty array when using BoringSSL. This testcase verifies we correctly return algorithms after the fix in https://github.com/netty/netty-tcnative/pull/449.

Modifications:

Add testcase to verify behaviour.

Result:

Ensure we correctly retuen the algorithms.
This commit is contained in:
Norman Maurer 2019-03-24 07:35:03 +01:00
parent 2c007f8fa6
commit a817e30d41
2 changed files with 127 additions and 2 deletions

View File

@ -55,6 +55,10 @@ import org.mockito.ArgumentCaptor;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
import javax.net.ssl.ExtendedSSLSession;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactorySpi;
import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.ManagerFactoryParameters; import javax.net.ssl.ManagerFactoryParameters;
import javax.net.ssl.SNIHostName; import javax.net.ssl.SNIHostName;
@ -72,6 +76,7 @@ import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.TrustManagerFactorySpi; import javax.net.ssl.TrustManagerFactorySpi;
import javax.net.ssl.X509ExtendedKeyManager;
import javax.net.ssl.X509ExtendedTrustManager; import javax.net.ssl.X509ExtendedTrustManager;
import javax.net.ssl.X509TrustManager; import javax.net.ssl.X509TrustManager;
import javax.security.cert.X509Certificate; import javax.security.cert.X509Certificate;
@ -88,6 +93,7 @@ import java.security.KeyStore;
import java.security.KeyStoreException; import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.Principal; import java.security.Principal;
import java.security.PrivateKey;
import java.security.Provider; import java.security.Provider;
import java.security.UnrecoverableKeyException; import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate; import java.security.cert.Certificate;
@ -114,7 +120,6 @@ import static io.netty.handler.ssl.SslUtils.PROTOCOL_TLS_V1_1;
import static io.netty.handler.ssl.SslUtils.PROTOCOL_TLS_V1_2; import static io.netty.handler.ssl.SslUtils.PROTOCOL_TLS_V1_2;
import static io.netty.handler.ssl.SslUtils.PROTOCOL_TLS_V1_3; import static io.netty.handler.ssl.SslUtils.PROTOCOL_TLS_V1_3;
import static io.netty.handler.ssl.SslUtils.SSL_RECORD_HEADER_LENGTH; import static io.netty.handler.ssl.SslUtils.SSL_RECORD_HEADER_LENGTH;
import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
@ -3068,6 +3073,126 @@ public abstract class SSLEngineTest {
} }
} }
@Test
public void testSupportedSignatureAlgorithms() throws Exception {
final SelfSignedCertificate ssc = new SelfSignedCertificate();
final class TestKeyManagerFactory extends KeyManagerFactory {
TestKeyManagerFactory(final KeyManagerFactory factory) {
super(new KeyManagerFactorySpi() {
private final KeyManager[] managers = factory.getKeyManagers();
@Override
protected void engineInit(KeyStore keyStore, char[] chars) {
throw new UnsupportedOperationException();
}
@Override
protected void engineInit(ManagerFactoryParameters managerFactoryParameters) {
throw new UnsupportedOperationException();
}
@Override
protected KeyManager[] engineGetKeyManagers() {
KeyManager[] array = new KeyManager[managers.length];
for (int i = 0 ; i < array.length; i++) {
final X509ExtendedKeyManager x509ExtendedKeyManager = (X509ExtendedKeyManager) managers[i];
array[i] = new X509ExtendedKeyManager() {
@Override
public String[] getClientAliases(String s, Principal[] principals) {
fail();
return null;
}
@Override
public String chooseClientAlias(
String[] strings, Principal[] principals, Socket socket) {
fail();
return null;
}
@Override
public String[] getServerAliases(String s, Principal[] principals) {
fail();
return null;
}
@Override
public String chooseServerAlias(String s, Principal[] principals, Socket socket) {
fail();
return null;
}
@Override
public String chooseEngineClientAlias(
String[] strings, Principal[] principals, SSLEngine sslEngine) {
assertNotEquals(0, ((ExtendedSSLSession) sslEngine.getHandshakeSession())
.getPeerSupportedSignatureAlgorithms().length);
assertNotEquals(0, ((ExtendedSSLSession) sslEngine.getHandshakeSession())
.getLocalSupportedSignatureAlgorithms().length);
return x509ExtendedKeyManager.chooseEngineClientAlias(
strings, principals, sslEngine);
}
@Override
public String chooseEngineServerAlias(
String s, Principal[] principals, SSLEngine sslEngine) {
assertNotEquals(0, ((ExtendedSSLSession) sslEngine.getHandshakeSession())
.getPeerSupportedSignatureAlgorithms().length);
assertNotEquals(0, ((ExtendedSSLSession) sslEngine.getHandshakeSession())
.getLocalSupportedSignatureAlgorithms().length);
return x509ExtendedKeyManager.chooseEngineServerAlias(s, principals, sslEngine);
}
@Override
public java.security.cert.X509Certificate[] getCertificateChain(String s) {
return x509ExtendedKeyManager.getCertificateChain(s);
}
@Override
public PrivateKey getPrivateKey(String s) {
return x509ExtendedKeyManager.getPrivateKey(s);
}
};
}
return array;
}
}, factory.getProvider(), factory.getAlgorithm());
}
}
clientSslCtx = SslContextBuilder.forClient().keyManager(new TestKeyManagerFactory(newKeyManagerFactory(ssc)))
.trustManager(InsecureTrustManagerFactory.INSTANCE)
.sslProvider(sslClientProvider())
.sslContextProvider(clientSslContextProvider())
.protocols(protocols())
.ciphers(ciphers())
.build();
serverSslCtx = SslContextBuilder.forServer(new TestKeyManagerFactory(newKeyManagerFactory(ssc)))
.trustManager(InsecureTrustManagerFactory.INSTANCE)
.sslContextProvider(serverSslContextProvider())
.sslProvider(sslServerProvider())
.protocols(protocols())
.ciphers(ciphers())
.clientAuth(ClientAuth.REQUIRE)
.build();
SSLEngine clientEngine = null;
SSLEngine serverEngine = null;
try {
clientEngine = wrapEngine(clientSslCtx.newEngine(UnpooledByteBufAllocator.DEFAULT));
serverEngine = wrapEngine(serverSslCtx.newEngine(UnpooledByteBufAllocator.DEFAULT));
handshake(clientEngine, serverEngine);
} finally {
cleanupClientSslEngine(clientEngine);
cleanupServerSslEngine(serverEngine);
ssc.delete();
}
}
@Test @Test
public void testHandshakeSession() throws Exception { public void testHandshakeSession() throws Exception {
final SelfSignedCertificate ssc = new SelfSignedCertificate(); final SelfSignedCertificate ssc = new SelfSignedCertificate();

View File

@ -277,7 +277,7 @@
<!-- Fedora-"like" systems. This is currently only used for the netty-tcnative dependency --> <!-- Fedora-"like" systems. This is currently only used for the netty-tcnative dependency -->
<os.detection.classifierWithLikes>fedora</os.detection.classifierWithLikes> <os.detection.classifierWithLikes>fedora</os.detection.classifierWithLikes>
<tcnative.artifactId>netty-tcnative</tcnative.artifactId> <tcnative.artifactId>netty-tcnative</tcnative.artifactId>
<tcnative.version>2.0.22.Final</tcnative.version> <tcnative.version>2.0.23.Final</tcnative.version>
<tcnative.classifier>${os.detected.classifier}</tcnative.classifier> <tcnative.classifier>${os.detected.classifier}</tcnative.classifier>
<conscrypt.groupId>org.conscrypt</conscrypt.groupId> <conscrypt.groupId>org.conscrypt</conscrypt.groupId>
<conscrypt.artifactId>conscrypt-openjdk-uber</conscrypt.artifactId> <conscrypt.artifactId>conscrypt-openjdk-uber</conscrypt.artifactId>