From c3cab48325a8c013f267c9ccc3a375ceb0e3c5e9 Mon Sep 17 00:00:00 2001 From: Kotaro Terada Date: Tue, 11 Aug 2020 18:19:23 +0900 Subject: [PATCH] NIFI-7730 Added regression tests for multiple certificate keystores. Cleaned up JettyServer code. Changed test logging severity to include debug statements. Added test resources. This closes #4498. Co-authored-by: Kotaro Terada --- .../remote/client/http/TestHttpClient.java | 2 +- .../apache/nifi/web/server/JettyServer.java | 14 +-- .../web/server/JettyServerGroovyTest.groovy | 105 +++++++++++++++--- .../nifi/web/server/JettyServerTest.java | 56 +++++----- .../src/test/resources/log4j.properties | 1 + .../test/resources/multiple_cert_keystore.jks | Bin 0 -> 4457 bytes .../test/resources/multiple_cert_keystore.p12 | Bin 0 -> 4949 bytes .../nifi/integration/util/NiFiTestServer.java | 7 +- .../prometheus/PrometheusServer.java | 2 +- .../standard/HandleHttpRequest.java | 7 +- .../nifi/processors/standard/ListenHTTP.java | 7 +- .../standard/TestGetHTTPGroovy.groovy | 4 +- .../standard/TestPostHTTPGroovy.groovy | 4 +- .../org/apache/nifi/web/util/TestServer.java | 7 +- .../jetty/AbstractJettyWebSocketService.java | 2 +- .../example/WebSocketClientExample.java | 2 +- .../example/WebSocketServerExample.java | 7 +- .../TlsCertificateAuthorityService.java | 7 +- 18 files changed, 136 insertions(+), 98 deletions(-) create mode 100644 nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/resources/multiple_cert_keystore.jks create mode 100644 nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/resources/multiple_cert_keystore.p12 diff --git a/nifi-commons/nifi-site-to-site-client/src/test/java/org/apache/nifi/remote/client/http/TestHttpClient.java b/nifi-commons/nifi-site-to-site-client/src/test/java/org/apache/nifi/remote/client/http/TestHttpClient.java index f6bf811e92..ab71c56532 100644 --- a/nifi-commons/nifi-site-to-site-client/src/test/java/org/apache/nifi/remote/client/http/TestHttpClient.java +++ b/nifi-commons/nifi-site-to-site-client/src/test/java/org/apache/nifi/remote/client/http/TestHttpClient.java @@ -453,7 +453,7 @@ public class TestHttpClient { final ServletHandler wrongPathServletHandler = new ServletHandler(); wrongPathContextHandler.insertHandler(wrongPathServletHandler); - final SslContextFactory sslContextFactory = new SslContextFactory(); + final SslContextFactory sslContextFactory = new SslContextFactory.Server(); sslContextFactory.setKeyStorePath("src/test/resources/certs/keystore.jks"); sslContextFactory.setKeyStorePassword("passwordpassword"); sslContextFactory.setKeyStoreType("JKS"); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/JettyServer.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/JettyServer.java index ca7944f0a2..e53c785922 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/JettyServer.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/JettyServer.java @@ -975,19 +975,13 @@ public class JettyServer implements NiFiServer, ExtensionUiLoader { } private SslContextFactory createSslContextFactory() { - final SslContextFactory contextFactory = new SslContextFactory(); - configureSslContextFactory(contextFactory, props); - return contextFactory; + final SslContextFactory.Server serverContextFactory = new SslContextFactory.Server(); + configureSslContextFactory(serverContextFactory, props); + return serverContextFactory; } - protected static void configureSslContextFactory(SslContextFactory contextFactory, NiFiProperties props) { - // Need to set SslContextFactory's endpointIdentificationAlgorithm to null; this is a server, - // not a client. Server does not need to perform hostname verification on the client. - // Previous to Jetty 9.4.15.v20190215, this defaulted to null, and now defaults to "HTTPS". - contextFactory.setEndpointIdentificationAlgorithm(null); - + protected static void configureSslContextFactory(SslContextFactory.Server contextFactory, NiFiProperties props) { // Explicitly exclude legacy TLS protocol versions - // contextFactory.setProtocol(CertificateUtils.getHighestCurrentSupportedTlsProtocolVersion()); contextFactory.setIncludeProtocols(CertificateUtils.getCurrentSupportedTlsProtocolVersions()); contextFactory.setExcludeProtocols("TLS", "TLSv1", "TLSv1.1", "SSL", "SSLv2", "SSLv2Hello", "SSLv3"); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/groovy/org/apache/nifi/web/server/JettyServerGroovyTest.groovy b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/groovy/org/apache/nifi/web/server/JettyServerGroovyTest.groovy index 64077a0e72..054ad080b8 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/groovy/org/apache/nifi/web/server/JettyServerGroovyTest.groovy +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/groovy/org/apache/nifi/web/server/JettyServerGroovyTest.groovy @@ -19,6 +19,9 @@ package org.apache.nifi.web.server import org.apache.log4j.AppenderSkeleton import org.apache.log4j.spi.LoggingEvent import org.apache.nifi.bundle.Bundle +import org.apache.nifi.nar.ExtensionManagerHolder +import org.apache.nifi.nar.ExtensionMapping +import org.apache.nifi.nar.SystemBundle import org.apache.nifi.processor.DataUnit import org.apache.nifi.properties.StandardNiFiProperties import org.apache.nifi.security.util.CertificateUtils @@ -121,6 +124,8 @@ class JettyServerGroovyTest extends GroovyTestCase { @After void tearDown() throws Exception { + // Cleans up the EMH so it can be reinitialized when a new Jetty server starts + ExtensionManagerHolder.INSTANCE = null TestAppender.reset() } @@ -196,10 +201,9 @@ class JettyServerGroovyTest extends GroovyTestCase { assert !bothConfigsPresentForHttp assert !bothConfigsPresentForHttps - // Verifies that the warning was not logged - assert log.size() == 2 - assert log.first() == "Both configs present for HTTP properties: false" - assert log.last() == "Both configs present for HTTPS properties: false" + // Verifies that the warning was not logged (messages are duplicated because of log4j.properties settings) + assert log.size() == 4 + assert log.every { it =~ "Both configs present for HTTPS? properties: false" } } @Test @@ -242,10 +246,84 @@ class JettyServerGroovyTest extends GroovyTestCase { // Assertions defined above } + /** + * Regression test added after NiFi 1.12.0 because Jetty upgrade to 9.4.26 no longer works + * with multiple certificate keystores. + */ + @Test + void testShouldStartWithMultipleCertificatePKCS12Keystore() { + // Arrange + final String externalHostname = "localhost" + + NiFiProperties httpsProps = new StandardNiFiProperties(rawProperties: new Properties([ + (NiFiProperties.WEB_HTTPS_PORT): HTTPS_PORT as String, + (NiFiProperties.WEB_HTTPS_HOST): externalHostname, + (NiFiProperties.SECURITY_KEYSTORE): "src/test/resources/multiple_cert_keystore.p12", + (NiFiProperties.SECURITY_KEYSTORE_PASSWD): "passwordpassword", + (NiFiProperties.SECURITY_KEYSTORE_TYPE): "PKCS12", + (NiFiProperties.NAR_LIBRARY_DIRECTORY): "target/" + ])) + + JettyServer jetty = createJettyServer(httpsProps) + Server internalServer = jetty.server + List connectors = Arrays.asList(internalServer.connectors) + + // Act + jetty.start() + + // Assert + assertServerConnector(connectors, "TLS", CURRENT_TLS_PROTOCOL_VERSIONS, CURRENT_TLS_PROTOCOL_VERSIONS, externalHostname, HTTPS_PORT) + + // Clean up + jetty.stop() + } + + /** + * Regression test added after NiFi 1.12.0 because Jetty upgrade to 9.4.26 no longer works + * with multiple certificate keystores. + */ + @Test + void testShouldStartWithMultipleCertificateJKSKeystore() { + // Arrange + final String externalHostname = "localhost" + + NiFiProperties httpsProps = new StandardNiFiProperties(rawProperties: new Properties([ + (NiFiProperties.WEB_HTTPS_PORT): HTTPS_PORT as String, + (NiFiProperties.WEB_HTTPS_HOST): externalHostname, + (NiFiProperties.SECURITY_KEYSTORE): "src/test/resources/multiple_cert_keystore.jks", + (NiFiProperties.SECURITY_KEYSTORE_PASSWD): "passwordpassword", + (NiFiProperties.SECURITY_KEYSTORE_TYPE): "JKS", + (NiFiProperties.NAR_LIBRARY_DIRECTORY): "target/" + ])) + + JettyServer jetty = createJettyServer(httpsProps) + Server internalServer = jetty.server + List connectors = Arrays.asList(internalServer.connectors) + + // Act + jetty.start() + + // Assert + assertServerConnector(connectors, "TLS", CURRENT_TLS_PROTOCOL_VERSIONS, CURRENT_TLS_PROTOCOL_VERSIONS, externalHostname, HTTPS_PORT) + + // Clean up + jetty.stop() + } + + private static JettyServer createJettyServer(StandardNiFiProperties httpsProps) { + Server internalServer = new Server() + JettyServer jetty = new JettyServer(internalServer, httpsProps) + jetty.systemBundle = SystemBundle.create(httpsProps) + jetty.bundles = [] as Set + jetty.extensionMapping = [size: { -> 0 }] as ExtensionMapping + jetty.configureHttpsConnector(internalServer, new HttpConfiguration()) + jetty + } + @Test void testShouldConfigureHTTPSConnector() { // Arrange - final String externalHostname = "secure.host.com" + final String externalHostname = "localhost" NiFiProperties httpsProps = new StandardNiFiProperties(rawProperties: new Properties([ (NiFiProperties.WEB_HTTPS_PORT): HTTPS_PORT as String, @@ -260,9 +338,7 @@ class JettyServerGroovyTest extends GroovyTestCase { List connectors = Arrays.asList(internalServer.connectors) // Assert - - // Set the expected TLS protocols to null because no actual keystore/truststore is loaded here - assertServerConnector(connectors, "TLS", null, null, externalHostname, HTTPS_PORT) + assertServerConnector(connectors, "TLS", CURRENT_TLS_PROTOCOL_VERSIONS, CURRENT_TLS_PROTOCOL_VERSIONS, externalHostname, HTTPS_PORT) } @Test @@ -411,16 +487,13 @@ class JettyServerGroovyTest extends GroovyTestCase { assert connector.port == EXPECTED_PORT assert connector.getProtocols() == ['ssl', 'http/1.1'] - // This kind of testing is not ideal as it breaks encapsulation, but is necessary to enforce verification of the TLS protocol versions specified SslConnectionFactory connectionFactory = connector.getConnectionFactory("ssl") as SslConnectionFactory - SslContextFactory sslContextFactory = connectionFactory._sslContextFactory as SslContextFactory + SslContextFactory sslContextFactory = connectionFactory.getSslContextFactory() logger.debug("SSL Context Factory: ${sslContextFactory.dump()}") - // Using the getters is subject to NPE due to blind array copies - assert sslContextFactory._sslProtocol == EXPECTED_TLS_PROTOCOL - assert sslContextFactory._includeProtocols.containsAll(EXPECTED_INCLUDED_PROTOCOLS ?: Collections.emptySet()) - assert (sslContextFactory._excludeProtocols as List).containsAll(LEGACY_TLS_PROTOCOLS) - assert sslContextFactory._selectedProtocols == EXPECTED_SELECTED_PROTOCOLS as String[] + assert sslContextFactory.getProtocol() == EXPECTED_TLS_PROTOCOL + assert Arrays.asList(sslContextFactory.getIncludeProtocols()).containsAll(EXPECTED_INCLUDED_PROTOCOLS ?: Collections.emptySet()) + assert (sslContextFactory.getExcludeProtocols() as List).containsAll(LEGACY_TLS_PROTOCOLS) } @Test @@ -531,4 +604,4 @@ class TestAppender extends AppenderSkeleton { events.collect { LoggingEvent le -> le.getRenderedMessage() } } } -} \ No newline at end of file +} diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/java/org/apache/nifi/web/server/JettyServerTest.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/java/org/apache/nifi/web/server/JettyServerTest.java index d25980a002..63e9ad5fe9 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/java/org/apache/nifi/web/server/JettyServerTest.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/java/org/apache/nifi/web/server/JettyServerTest.java @@ -43,12 +43,12 @@ public class JettyServerTest { addProps.put(NiFiProperties.SECURITY_KEYSTORE_PASSWD, testKeystorePassword); addProps.put(NiFiProperties.SECURITY_KEY_PASSWD, testKeyPassword); NiFiProperties nifiProperties = NiFiProperties.createBasicNiFiProperties(null, addProps); - SslContextFactory contextFactory = mock(SslContextFactory.class); + SslContextFactory.Server mockSCF = mock(SslContextFactory.Server.class); - JettyServer.configureSslContextFactory(contextFactory, nifiProperties); + JettyServer.configureSslContextFactory(mockSCF, nifiProperties); - verify(contextFactory).setKeyStorePassword(testKeystorePassword); - verify(contextFactory).setKeyManagerPassword(testKeyPassword); + verify(mockSCF).setKeyStorePassword(testKeystorePassword); + verify(mockSCF).setKeyManagerPassword(testKeyPassword); } @Test @@ -59,12 +59,12 @@ public class JettyServerTest { final Map addProps = new HashMap<>(); addProps.put(NiFiProperties.SECURITY_KEY_PASSWD, testKeyPassword); NiFiProperties nifiProperties = NiFiProperties.createBasicNiFiProperties(null, addProps); - SslContextFactory contextFactory = mock(SslContextFactory.class); + SslContextFactory.Server mockSCF = mock(SslContextFactory.Server.class); - JettyServer.configureSslContextFactory(contextFactory, nifiProperties); + JettyServer.configureSslContextFactory(mockSCF, nifiProperties); - verify(contextFactory).setKeyManagerPassword(testKeyPassword); - verify(contextFactory, never()).setKeyStorePassword(anyString()); + verify(mockSCF).setKeyManagerPassword(testKeyPassword); + verify(mockSCF, never()).setKeyStorePassword(anyString()); } @Test @@ -75,12 +75,12 @@ public class JettyServerTest { final Map addProps = new HashMap<>(); addProps.put(NiFiProperties.SECURITY_KEYSTORE_PASSWD, testKeystorePassword); NiFiProperties nifiProperties = NiFiProperties.createBasicNiFiProperties(null, addProps); - SslContextFactory contextFactory = mock(SslContextFactory.class); + SslContextFactory.Server mockSCF = mock(SslContextFactory.Server.class); - JettyServer.configureSslContextFactory(contextFactory, nifiProperties); + JettyServer.configureSslContextFactory(mockSCF, nifiProperties); - verify(contextFactory).setKeyStorePassword(testKeystorePassword); - verify(contextFactory).setKeyManagerPassword(testKeystorePassword); + verify(mockSCF).setKeyStorePassword(testKeystorePassword); + verify(mockSCF).setKeyManagerPassword(testKeystorePassword); } @Test @@ -90,12 +90,12 @@ public class JettyServerTest { String keyStoreType = KeystoreType.JKS.toString(); addProps.put(NiFiProperties.SECURITY_KEYSTORE_TYPE, keyStoreType); NiFiProperties nifiProperties = NiFiProperties.createBasicNiFiProperties(null, addProps); - SslContextFactory contextFactory = mock(SslContextFactory.class); + SslContextFactory.Server mockSCF = mock(SslContextFactory.Server.class); - JettyServer.configureSslContextFactory(contextFactory, nifiProperties); + JettyServer.configureSslContextFactory(mockSCF, nifiProperties); - verify(contextFactory).setKeyStoreType(keyStoreType); - verify(contextFactory).setKeyStoreProvider(SUN_PROVIDER_NAME); + verify(mockSCF).setKeyStoreType(keyStoreType); + verify(mockSCF).setKeyStoreProvider(SUN_PROVIDER_NAME); } @Test @@ -105,12 +105,12 @@ public class JettyServerTest { String keyStoreType = KeystoreType.PKCS12.toString(); addProps.put(NiFiProperties.SECURITY_KEYSTORE_TYPE, keyStoreType); NiFiProperties nifiProperties = NiFiProperties.createBasicNiFiProperties(null, addProps); - SslContextFactory contextFactory = mock(SslContextFactory.class); + SslContextFactory.Server mockSCF = mock(SslContextFactory.Server.class); - JettyServer.configureSslContextFactory(contextFactory, nifiProperties); + JettyServer.configureSslContextFactory(mockSCF, nifiProperties); - verify(contextFactory).setKeyStoreType(keyStoreType); - verify(contextFactory).setKeyStoreProvider(BouncyCastleProvider.PROVIDER_NAME); + verify(mockSCF).setKeyStoreType(keyStoreType); + verify(mockSCF).setKeyStoreProvider(BouncyCastleProvider.PROVIDER_NAME); } @Test @@ -120,12 +120,12 @@ public class JettyServerTest { String trustStoreType = KeystoreType.JKS.toString(); addProps.put(NiFiProperties.SECURITY_TRUSTSTORE_TYPE, trustStoreType); NiFiProperties nifiProperties = NiFiProperties.createBasicNiFiProperties(null, addProps); - SslContextFactory contextFactory = mock(SslContextFactory.class); + SslContextFactory.Server mockSCF = mock(SslContextFactory.Server.class); - JettyServer.configureSslContextFactory(contextFactory, nifiProperties); + JettyServer.configureSslContextFactory(mockSCF, nifiProperties); - verify(contextFactory).setTrustStoreType(trustStoreType); - verify(contextFactory).setTrustStoreProvider(SUN_PROVIDER_NAME); + verify(mockSCF).setTrustStoreType(trustStoreType); + verify(mockSCF).setTrustStoreProvider(SUN_PROVIDER_NAME); } @Test @@ -135,11 +135,11 @@ public class JettyServerTest { String trustStoreType = KeystoreType.PKCS12.toString(); addProps.put(NiFiProperties.SECURITY_TRUSTSTORE_TYPE, trustStoreType); NiFiProperties nifiProperties = NiFiProperties.createBasicNiFiProperties(null, addProps); - SslContextFactory contextFactory = mock(SslContextFactory.class); + SslContextFactory.Server mockSCF = mock(SslContextFactory.Server.class); - JettyServer.configureSslContextFactory(contextFactory, nifiProperties); + JettyServer.configureSslContextFactory(mockSCF, nifiProperties); - verify(contextFactory).setTrustStoreType(trustStoreType); - verify(contextFactory).setTrustStoreProvider(BouncyCastleProvider.PROVIDER_NAME); + verify(mockSCF).setTrustStoreType(trustStoreType); + verify(mockSCF).setTrustStoreProvider(BouncyCastleProvider.PROVIDER_NAME); } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/resources/log4j.properties b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/resources/log4j.properties index 162521fb88..2d5c71c91b 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/resources/log4j.properties +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/resources/log4j.properties @@ -16,6 +16,7 @@ # log4j.rootLogger=INFO,console,test +log4j.logger.org.apache.nifi.web=DEBUG,console,test log4j.appender.console=org.apache.log4j.ConsoleAppender log4j.appender.console.Target=System.err diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/resources/multiple_cert_keystore.jks b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/resources/multiple_cert_keystore.jks new file mode 100644 index 0000000000000000000000000000000000000000..e563d456994ab8ae7e7c5c59ba26599b98ec0953 GIT binary patch literal 4457 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 Qy;2`0mu6mI+uIfY0n%r*O8@`> literal 0 HcmV?d00001 diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/resources/multiple_cert_keystore.p12 b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/resources/multiple_cert_keystore.p12 new file mode 100644 index 0000000000000000000000000000000000000000..2bdec71b74fa7aac5bbac085feacf67c0d4553ce GIT binary patch literal 4949 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 sslProperties) { - SslContextFactory ssl = new SslContextFactory(); + SslContextFactory ssl = new SslContextFactory.Server(); if (sslProperties.get(StandardSSLContextService.KEYSTORE.getName()) != null) { ssl.setKeyStorePath(sslProperties.get(StandardSSLContextService.KEYSTORE.getName())); @@ -97,11 +97,6 @@ public class TestServer { ssl.setNeedClientAuth(Boolean.parseBoolean(clientAuth)); } - // Need to set SslContextFactory's endpointIdentificationAlgorithm to null; this is a server, - // not a client. Server does not need to perform hostname verification on the client. - // Previous to Jetty 9.4.15.v20190215, this defaulted to null, and now defaults to "HTTPS". - ssl.setEndpointIdentificationAlgorithm(null); - // build the connector final ServerConnector https = new ServerConnector(jetty, ssl); diff --git a/nifi-nar-bundles/nifi-websocket-bundle/nifi-websocket-services-jetty/src/main/java/org/apache/nifi/websocket/jetty/AbstractJettyWebSocketService.java b/nifi-nar-bundles/nifi-websocket-bundle/nifi-websocket-services-jetty/src/main/java/org/apache/nifi/websocket/jetty/AbstractJettyWebSocketService.java index 546a853759..abff7856cc 100644 --- a/nifi-nar-bundles/nifi-websocket-bundle/nifi-websocket-services-jetty/src/main/java/org/apache/nifi/websocket/jetty/AbstractJettyWebSocketService.java +++ b/nifi-nar-bundles/nifi-websocket-bundle/nifi-websocket-services-jetty/src/main/java/org/apache/nifi/websocket/jetty/AbstractJettyWebSocketService.java @@ -67,7 +67,7 @@ public abstract class AbstractJettyWebSocketService extends AbstractWebSocketSer protected SslContextFactory createSslFactory(final SSLContextService sslService, final boolean needClientAuth, final boolean wantClientAuth, final String endpointIdentificationAlgorithm) { - final SslContextFactory sslFactory = new SslContextFactory(); + final SslContextFactory sslFactory = new SslContextFactory.Server(); sslFactory.setNeedClientAuth(needClientAuth); sslFactory.setWantClientAuth(wantClientAuth); diff --git a/nifi-nar-bundles/nifi-websocket-bundle/nifi-websocket-services-jetty/src/test/java/org/apache/nifi/websocket/example/WebSocketClientExample.java b/nifi-nar-bundles/nifi-websocket-bundle/nifi-websocket-services-jetty/src/test/java/org/apache/nifi/websocket/example/WebSocketClientExample.java index f8c9b3a6fe..f222bc25c4 100644 --- a/nifi-nar-bundles/nifi-websocket-bundle/nifi-websocket-services-jetty/src/test/java/org/apache/nifi/websocket/example/WebSocketClientExample.java +++ b/nifi-nar-bundles/nifi-websocket-bundle/nifi-websocket-services-jetty/src/test/java/org/apache/nifi/websocket/example/WebSocketClientExample.java @@ -46,7 +46,7 @@ public class WebSocketClientExample { String destUri = "wss://localhost:50010/test"; final CountDownLatch replyLatch = new CountDownLatch(1); - final SslContextFactory sslContextFactory = new SslContextFactory(); + final SslContextFactory sslContextFactory = new SslContextFactory.Client(); sslContextFactory.setKeyStorePath("src/test/resources/certs/keystore.jks"); sslContextFactory.setKeyStorePassword("passwordpassword"); sslContextFactory.setKeyStoreType("JKS"); diff --git a/nifi-nar-bundles/nifi-websocket-bundle/nifi-websocket-services-jetty/src/test/java/org/apache/nifi/websocket/example/WebSocketServerExample.java b/nifi-nar-bundles/nifi-websocket-bundle/nifi-websocket-services-jetty/src/test/java/org/apache/nifi/websocket/example/WebSocketServerExample.java index dad8520a39..913031a557 100644 --- a/nifi-nar-bundles/nifi-websocket-bundle/nifi-websocket-services-jetty/src/test/java/org/apache/nifi/websocket/example/WebSocketServerExample.java +++ b/nifi-nar-bundles/nifi-websocket-bundle/nifi-websocket-services-jetty/src/test/java/org/apache/nifi/websocket/example/WebSocketServerExample.java @@ -152,16 +152,11 @@ public class WebSocketServerExample { httpConnector = new ServerConnector(server); httpConnector.setPort(50010); - final SslContextFactory sslContextFactory = new SslContextFactory(); + final SslContextFactory sslContextFactory = new SslContextFactory.Server(); sslContextFactory.setKeyStorePath("src/test/resources/certs/keystore.jks"); sslContextFactory.setKeyStorePassword("passwordpassword"); sslContextFactory.setKeyStoreType("JKS"); - // Need to set SslContextFactory's endpointIdentificationAlgorithm to null; this is a server, - // not a client. Server does not need to perform hostname verification on the client. - // Previous to Jetty 9.4.15.v20190215, this defaulted to null, and now defaults to "HTTPS". - sslContextFactory.setEndpointIdentificationAlgorithm(null); - final HttpConfiguration https = new HttpConfiguration(); https.addCustomizer(new SecureRequestCustomizer()); sslConnector = new ServerConnector(server, diff --git a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/server/TlsCertificateAuthorityService.java b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/server/TlsCertificateAuthorityService.java index 7b6d1e2dbc..d95ae8ec46 100644 --- a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/server/TlsCertificateAuthorityService.java +++ b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/server/TlsCertificateAuthorityService.java @@ -62,16 +62,11 @@ public class TlsCertificateAuthorityService { private static Server createServer(Handler handler, int port, KeyStore keyStore, String keyPassword) throws Exception { Server server = new Server(); - SslContextFactory sslContextFactory = new SslContextFactory(); + SslContextFactory sslContextFactory = new SslContextFactory.Server(); sslContextFactory.setIncludeProtocols(CertificateUtils.getHighestCurrentSupportedTlsProtocolVersion()); sslContextFactory.setKeyStore(keyStore); sslContextFactory.setKeyManagerPassword(keyPassword); - // Need to set SslContextFactory's endpointIdentificationAlgorithm to null; this is a server, - // not a client. Server does not need to perform hostname verification on the client. - // Previous to Jetty 9.4.15.v20190215, this defaulted to null, and now defaults to "HTTPS". - sslContextFactory.setEndpointIdentificationAlgorithm(null); - HttpConfiguration httpsConfig = new HttpConfiguration(); httpsConfig.addCustomizer(new SecureRequestCustomizer());