This is an automated email from the ASF dual-hosted git repository.

exceptionfactory pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi.git


The following commit(s) were added to refs/heads/main by this push:
     new b862fff8f0 NIFI-10498 Added Cipher Suite configuration to NiFi Registry
b862fff8f0 is described below

commit b862fff8f0cc7f2d2f7fd25a2f7c8802bee21670
Author: Jeremy Snyder <[email protected]>
AuthorDate: Tue Sep 20 14:24:36 2022 -0400

    NIFI-10498 Added Cipher Suite configuration to NiFi Registry
    
    This closes #6458
    
    Signed-off-by: David Handermann <[email protected]>
---
 .../src/main/asciidoc/administration-guide.adoc    | 23 +++++++++++++++++
 .../apache/nifi/registry/jetty/JettyServer.java    | 18 ++++++++++++++
 .../registry/jetty/JettyServerGroovyTest.groovy    | 29 ++++++++++++++++++++++
 .../properties/NiFiRegistryProperties.java         | 10 ++++++++
 4 files changed, 80 insertions(+)

diff --git 
a/nifi-registry/nifi-registry-core/nifi-registry-docs/src/main/asciidoc/administration-guide.adoc
 
b/nifi-registry/nifi-registry-core/nifi-registry-docs/src/main/asciidoc/administration-guide.adoc
index f8c6f8839f..c14e86b242 100644
--- 
a/nifi-registry/nifi-registry-core/nifi-registry-docs/src/main/asciidoc/administration-guide.adoc
+++ 
b/nifi-registry/nifi-registry-core/nifi-registry-docs/src/main/asciidoc/administration-guide.adoc
@@ -101,6 +101,29 @@ should run on. If it is desired that the HTTPS interface 
be accessible from all
 
 NOTE: It is important when enabling HTTPS that the 
`nifi.registry.web.http.port` property be unset.
 
+[[tls_cipher_suites]]
+=== TLS Cipher Suites
+
+The Java Runtime Environment provides the ability to specify custom TLS cipher 
suites to be used by servers when accepting client connections.  See
+link:https://java.com/en/configure_crypto.html[here^] for more information.  
To use this feature for the NiFi web service, the following NiFi properties
+may be set:
+
+[options="header,footer"]
+|==================================================================================================================================================
+| Property Name | Description
+|`nifi.registry.web.https.ciphersuites.include` | Set of ciphers that are 
available to be used by incoming client connections.  Replaces system defaults 
if set.
+|`nifi.registry.web.https.ciphersuites.exclude` | Set of ciphers that must not 
be used by incoming client connections.  Filters available ciphers if set.
+|==================================================================================================================================================
+
+Each property should take the form of a comma-separated list of common cipher 
names as specified
+link:https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#ciphersuites[here^].
  Regular expressions
+(for example `^.*GCM_SHA256$`) may also be specified.
+
+The semantics match the use of the following Jetty APIs:
+
+* 
link:https://www.eclipse.org/jetty/javadoc/jetty-9/org/eclipse/jetty/util/ssl/SslContextFactory.html#setIncludeCipherSuites(java.lang.String\...)[SslContextFactory.setIncludeCipherSuites()]
+* 
link:https://www.eclipse.org/jetty/javadoc/jetty-9/org/eclipse/jetty/util/ssl/SslContextFactory.html#setExcludeCipherSuites(java.lang.String\...)[SslContextFactory.setExcludeCipherSuites()]
+
 [[user_authentication]]
 == User Authentication
 
diff --git 
a/nifi-registry/nifi-registry-core/nifi-registry-jetty/src/main/java/org/apache/nifi/registry/jetty/JettyServer.java
 
b/nifi-registry/nifi-registry-core/nifi-registry-jetty/src/main/java/org/apache/nifi/registry/jetty/JettyServer.java
index 04d08de7b0..6d8b47ce1a 100644
--- 
a/nifi-registry/nifi-registry-core/nifi-registry-jetty/src/main/java/org/apache/nifi/registry/jetty/JettyServer.java
+++ 
b/nifi-registry/nifi-registry-core/nifi-registry-jetty/src/main/java/org/apache/nifi/registry/jetty/JettyServer.java
@@ -73,6 +73,8 @@ public class JettyServer {
     private static final Logger logger = 
LoggerFactory.getLogger(JettyServer.class);
     private static final String WEB_DEFAULTS_XML = 
"org/apache/nifi-registry/web/webdefault.xml";
     private static final int HEADER_BUFFER_SIZE = 16 * 1024; // 16kb
+    private static final String CIPHER_SUITE_SEPARATOR_PATTERN = ",\\s*";
+
 
     private static final FileFilter WAR_FILTER = new FileFilter() {
         @Override
@@ -214,6 +216,10 @@ public class JettyServer {
         }
     }
 
+    private static String[] getCipherSuites(final String cipherSuitesProperty) 
{
+        return cipherSuitesProperty.split(CIPHER_SUITE_SEPARATOR_PATTERN);
+    }
+
     private SslContextFactory createSslContextFactory() {
         final SslContextFactory.Server contextFactory = new 
SslContextFactory.Server();
 
@@ -259,6 +265,18 @@ public class JettyServer {
             
contextFactory.setTrustStorePassword(properties.getTrustStorePassword());
         }
 
+        final String includeCipherSuites = 
properties.getHttpsCipherSuitesInclude();
+        if (StringUtils.isNotBlank(includeCipherSuites)) {
+            final String[] cipherSuites = getCipherSuites(includeCipherSuites);
+            contextFactory.setIncludeCipherSuites(cipherSuites);
+        }
+
+        final String excludeCipherSuites = 
properties.getHttpsCipherSuitesExclude();
+        if (StringUtils.isNotBlank(excludeCipherSuites)) {
+            final String[] cipherSuites = getCipherSuites(excludeCipherSuites);
+            contextFactory.setExcludeCipherSuites(cipherSuites);
+        }
+
         return contextFactory;
     }
 
diff --git 
a/nifi-registry/nifi-registry-core/nifi-registry-jetty/src/test/groovy/org/apache/nifi/registry/jetty/JettyServerGroovyTest.groovy
 
b/nifi-registry/nifi-registry-core/nifi-registry-jetty/src/test/groovy/org/apache/nifi/registry/jetty/JettyServerGroovyTest.groovy
index a96e5c1872..e0c1c2f23e 100644
--- 
a/nifi-registry/nifi-registry-core/nifi-registry-jetty/src/test/groovy/org/apache/nifi/registry/jetty/JettyServerGroovyTest.groovy
+++ 
b/nifi-registry/nifi-registry-core/nifi-registry-jetty/src/test/groovy/org/apache/nifi/registry/jetty/JettyServerGroovyTest.groovy
@@ -133,4 +133,33 @@ class JettyServerGroovyTest extends GroovyTestCase {
         // Act but expect exception
         SslContextFactory sslContextFactory = 
testServer.createSslContextFactory()
     }
+
+    @Test
+    void testCreateSslContextFactoryWithCipherSuites() throws Exception {
+
+        // Arrange
+        NiFiRegistryProperties properties = new NiFiRegistryProperties()
+        properties.setProperty(NiFiRegistryProperties.SECURITY_TRUSTSTORE, 
"src/test/resources/truststore.jks")
+        
properties.setProperty(NiFiRegistryProperties.SECURITY_TRUSTSTORE_PASSWD, 
truststorePassword)
+        
properties.setProperty(NiFiRegistryProperties.SECURITY_TRUSTSTORE_TYPE, "JKS")
+        properties.setProperty(NiFiRegistryProperties.SECURITY_KEYSTORE, 
"src/test/resources/keystoreSamePassword.jks")
+        
properties.setProperty(NiFiRegistryProperties.SECURITY_KEYSTORE_PASSWD, 
matchingPassword)
+        properties.setProperty(NiFiRegistryProperties.SECURITY_KEYSTORE_TYPE, 
"JKS")
+        
properties.setProperty(NiFiRegistryProperties.WEB_HTTPS_CIPHERSUITES_INCLUDE, 
"TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,TLS_DHE_RSA_WITH_AES_256_GCM_SHA384")
+        
properties.setProperty(NiFiRegistryProperties.WEB_HTTPS_CIPHERSUITES_EXCLUDE, 
"BAD_CIPHER")
+
+        Server internalServer = new Server()
+        JettyServer testServer = new JettyServer(internalServer, properties)
+
+        // Act
+        SslContextFactory sslContextFactory = 
testServer.createSslContextFactory()
+        sslContextFactory.start()
+
+        // Assert this
+        assertNotNull(sslContextFactory)
+        assertNotNull(sslContextFactory.getSslContext())
+        assertEquals("INCLUDE_CIPHER_SUITES", 
sslContextFactory.getIncludeCipherSuites(), 
["TLS_DHE_RSA_WITH_AES_128_GCM_SHA256","TLS_DHE_RSA_WITH_AES_256_GCM_SHA384"])
+        assertEquals("EXCLUDE_CIPHER_SUITES", 
sslContextFactory.getExcludeCipherSuites(), ["BAD_CIPHER"])
+    }
+
 }
diff --git 
a/nifi-registry/nifi-registry-core/nifi-registry-properties/src/main/java/org/apache/nifi/registry/properties/NiFiRegistryProperties.java
 
b/nifi-registry/nifi-registry-core/nifi-registry-properties/src/main/java/org/apache/nifi/registry/properties/NiFiRegistryProperties.java
index 3f8ec6bb94..0b908715ce 100644
--- 
a/nifi-registry/nifi-registry-core/nifi-registry-properties/src/main/java/org/apache/nifi/registry/properties/NiFiRegistryProperties.java
+++ 
b/nifi-registry/nifi-registry-core/nifi-registry-properties/src/main/java/org/apache/nifi/registry/properties/NiFiRegistryProperties.java
@@ -51,6 +51,8 @@ public class NiFiRegistryProperties extends 
ApplicationProperties {
     public static final String WEB_HTTP_HOST = "nifi.registry.web.http.host";
     public static final String WEB_HTTPS_PORT = "nifi.registry.web.https.port";
     public static final String WEB_HTTPS_HOST = "nifi.registry.web.https.host";
+    public static final String WEB_HTTPS_CIPHERSUITES_INCLUDE = 
"nifi.registry.web.https.ciphersuites.include";
+    public static final String WEB_HTTPS_CIPHERSUITES_EXCLUDE = 
"nifi.registry.web.https.ciphersuites.exclude";
     public static final String WEB_WORKING_DIR = 
"nifi.registry.web.jetty.working.directory";
     public static final String WEB_THREADS = "nifi.registry.web.jetty.threads";
     public static final String WEB_SHOULD_SEND_SERVER_VERSION = 
"nifi.registry.web.should.send.server.version";
@@ -174,6 +176,14 @@ public class NiFiRegistryProperties extends 
ApplicationProperties {
         return getProperty(WEB_HTTPS_HOST);
     }
 
+    public String getHttpsCipherSuitesInclude() {
+        return getProperty(WEB_HTTPS_CIPHERSUITES_INCLUDE);
+    }
+
+    public String getHttpsCipherSuitesExclude() {
+        return getProperty(WEB_HTTPS_CIPHERSUITES_EXCLUDE);
+    }
+
     public boolean getNeedClientAuth() {
         boolean needClientAuth = true;
         String rawNeedClientAuth = getProperty(SECURITY_NEED_CLIENT_AUTH);

Reply via email to