You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by th...@apache.org on 2021/05/24 04:47:17 UTC

[nifi] branch main updated: NIFI-8037 Changed SSLContextServices to use runtime supported protocols for TLSv1.3

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

thenatog 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 01783a2  NIFI-8037 Changed SSLContextServices to use runtime supported protocols for TLSv1.3
01783a2 is described below

commit 01783a295c164dde29e5796fd2c010f2197a58b9
Author: exceptionfactory <ex...@apache.org>
AuthorDate: Mon Feb 8 14:48:31 2021 -0600

    NIFI-8037 Changed SSLContextServices to use runtime supported protocols for TLSv1.3
    
    Signed-off-by: Nathan Gough <th...@gmail.com>
    
    This closes #4827.
---
 .../org/apache/nifi/security/util/TlsPlatform.java |   4 +-
 .../server/ConnectionLoadBalanceServerTest.groovy  |  18 ----
 .../nifi/web/server/JettyServerGroovyTest.groovy   |  26 ++---
 .../ssl/StandardRestrictedSSLContextService.java   |  32 +++---
 .../apache/nifi/ssl/StandardSSLContextService.java |  31 +++---
 .../nifi/ssl/RestrictedSSLContextServiceTest.java  |  46 --------
 .../org/apache/nifi/ssl/SSLContextServiceTest.java |  30 ------
 .../StandardRestrictedSSLContextServiceTest.java   | 116 +++++++++++++++++++++
 .../org/apache/nifi/ssl/SSLContextService.java     |  56 ----------
 9 files changed, 157 insertions(+), 202 deletions(-)

diff --git a/nifi-commons/nifi-security-utils-api/src/main/java/org/apache/nifi/security/util/TlsPlatform.java b/nifi-commons/nifi-security-utils-api/src/main/java/org/apache/nifi/security/util/TlsPlatform.java
index c0627a8..bbbdb64 100644
--- a/nifi-commons/nifi-security-utils-api/src/main/java/org/apache/nifi/security/util/TlsPlatform.java
+++ b/nifi-commons/nifi-security-utils-api/src/main/java/org/apache/nifi/security/util/TlsPlatform.java
@@ -81,10 +81,10 @@ public class TlsPlatform {
 
     private static SortedMap<Float, String> getDefaultSslContextProtocols() {
         final SSLContext defaultContext = getDefaultSslContext();
-        final SSLParameters defaultParameters = defaultContext.getDefaultSSLParameters();
+        final SSLParameters sslParameters = defaultContext.getSupportedSSLParameters();
+        final String[] protocols = sslParameters.getProtocols();
 
         final SortedMap<Float, String> sslContextProtocols = new TreeMap<>();
-        final String[] protocols = defaultParameters.getProtocols();
         for (final String protocol : protocols) {
             final Matcher protocolVersionMatcher = PROTOCOL_VERSION.matcher(protocol);
             if (protocolVersionMatcher.matches()) {
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/groovy/org/apache/nifi/controller/queue/clustered/server/ConnectionLoadBalanceServerTest.groovy b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/groovy/org/apache/nifi/controller/queue/clustered/server/ConnectionLoadBalanceServerTest.groovy
index fafb4df..eabca30 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/groovy/org/apache/nifi/controller/queue/clustered/server/ConnectionLoadBalanceServerTest.groovy
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/groovy/org/apache/nifi/controller/queue/clustered/server/ConnectionLoadBalanceServerTest.groovy
@@ -84,16 +84,6 @@ class ConnectionLoadBalanceServerTest extends GroovyTestCase {
         }
     }
 
-    /**
-     * Asserts that the protocol versions in the parameters object are correct.
-     *
-     * @param enabledProtocols the actual protocols, either in {@code String[]} or {@code Collection<String>} form
-     * @param expectedProtocols the specific protocol versions to be present (ordered as desired)
-     */
-    void assertProtocolVersions(def enabledProtocols, def expectedProtocols) {
-        assert enabledProtocols as Set == expectedProtocols as Set
-    }
-
     @Test
     void testRequestPeerListShouldUseTLS() {
         // Arrange
@@ -113,16 +103,8 @@ class ConnectionLoadBalanceServerTest extends GroovyTestCase {
 
         // Assert
 
-        // Assert that the default parameters (which can't be modified) still have legacy protocols and no client auth
-        def defaultSSLParameters = sslContext.defaultSSLParameters
-        logger.info("Default SSL Parameters: ${KeyStoreUtils.sslParametersToString(defaultSSLParameters)}" as String)
-        assertProtocolVersions(defaultSSLParameters.protocols, TlsPlatform.supportedProtocols)
-        assert !defaultSSLParameters.needClientAuth
-
         // Assert that the actual socket is set correctly due to the override in the LB server
         SSLServerSocket socket = lbServer.serverSocket as SSLServerSocket
-        logger.info("Created SSL server socket: ${KeyStoreUtils.sslServerSocketToString(socket)}" as String)
-        assertProtocolVersions(socket.enabledProtocols, TlsPlatform.preferredProtocols)
         assert socket.needClientAuth
 
         // Clean up
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 8d783b3..6842e4c 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
@@ -53,6 +53,7 @@ import org.junit.runners.JUnit4
 import org.slf4j.Logger
 import org.slf4j.LoggerFactory
 
+import javax.net.ssl.SSLContext
 import javax.net.ssl.SSLSocket
 import javax.net.ssl.SSLSocketFactory
 import javax.servlet.DispatcherType
@@ -83,10 +84,6 @@ class JettyServerGroovyTest extends GroovyTestCase {
     private static final String TLS_1_3_PROTOCOL = "TLSv1.3"
     private static final List<String> TLS_1_3_CIPHER_SUITES = ["TLS_AES_128_GCM_SHA256"]
 
-    // Depending if the test is run on Java 8 or Java 11, these values change (TLSv1.2 vs. TLSv1.3)
-    private static final CURRENT_TLS_PROTOCOL_VERSION = TlsPlatform.latestProtocol
-    private static final List<String> CURRENT_TLS_PROTOCOL_VERSIONS = new ArrayList<>(TlsPlatform.preferredProtocols)
-
     // These protocol versions should not ever be supported
     static private final List<String> LEGACY_TLS_PROTOCOLS = ["TLS", "TLSv1", "TLSv1.1", "SSL", "SSLv2", "SSLv2Hello", "SSLv3"]
 
@@ -273,7 +270,7 @@ class JettyServerGroovyTest extends GroovyTestCase {
         jetty.start()
 
         // Assert
-        assertServerConnector(connectors, "TLS", CURRENT_TLS_PROTOCOL_VERSIONS, externalHostname, HTTPS_PORT)
+        assertServerConnector(connectors, externalHostname, HTTPS_PORT)
 
         // Clean up
         jetty.stop()
@@ -305,7 +302,7 @@ class JettyServerGroovyTest extends GroovyTestCase {
         jetty.start()
 
         // Assert
-        assertServerConnector(connectors, "TLS", CURRENT_TLS_PROTOCOL_VERSIONS, externalHostname, HTTPS_PORT)
+        assertServerConnector(connectors, externalHostname, HTTPS_PORT)
 
         // Clean up
         jetty.stop()
@@ -339,13 +336,14 @@ class JettyServerGroovyTest extends GroovyTestCase {
         List<Connector> connectors = Arrays.asList(internalServer.connectors)
 
         // Assert
-        assertServerConnector(connectors, "TLS", CURRENT_TLS_PROTOCOL_VERSIONS, externalHostname, HTTPS_PORT)
+        assertServerConnector(connectors, externalHostname, HTTPS_PORT)
     }
 
     @Test
     void testShouldSupportTLSv1_3WhenProtocolFound() {
         // Arrange
-        Assume.assumeTrue("This test should only run when TLSv1.3 is found in the set of default protocols", TlsPlatform.supportedProtocols.contains(TLS_1_3_PROTOCOL))
+        String[] defaultProtocols = SSLContext.getDefault().defaultSSLParameters.protocols
+        Assume.assumeTrue("This test should only run when TLSv1.3 is found in the set of default protocols", defaultProtocols.contains(TLS_1_3_PROTOCOL))
 
         Server internalServer = new Server()
         JettyServer jetty = new JettyServer(internalServer, httpsProps)
@@ -368,8 +366,7 @@ class JettyServerGroovyTest extends GroovyTestCase {
         // Assert
         assert response =~ "HTTP/1.1 400"
 
-        // Assert that the connector prefers TLSv1.3 but the JVM supports TLSv1.2 as well
-        assertServerConnector(connectors, "TLS", [CURRENT_TLS_PROTOCOL_VERSION])
+        assertServerConnector(connectors)
 
         // Clean up
         internalServer.stop()
@@ -411,8 +408,7 @@ class JettyServerGroovyTest extends GroovyTestCase {
         // Assert
         assert tls12Response =~ "HTTP"
 
-        // Assert that the connector only accepts TLSv1.2
-        assertServerConnector(connectors, "TLS", [CURRENT_TLS_PROTOCOL_VERSION])
+        assertServerConnector(connectors)
 
         // Clean up
         internalServer.stop()
@@ -444,8 +440,6 @@ class JettyServerGroovyTest extends GroovyTestCase {
     }
 
     private static void assertServerConnector(List<Connector> connectors,
-                                              String EXPECTED_TLS_PROTOCOL = "TLS",
-                                              List<String> EXPECTED_INCLUDED_PROTOCOLS = TlsPlatform.preferredProtocols,
                                               String EXPECTED_HOSTNAME = HTTPS_HOSTNAME,
                                               int EXPECTED_PORT = HTTPS_PORT) {
         // Assert the server connector is correct
@@ -457,10 +451,6 @@ class JettyServerGroovyTest extends GroovyTestCase {
 
         SslConnectionFactory connectionFactory = connector.getConnectionFactory("ssl") as SslConnectionFactory
         SslContextFactory sslContextFactory = connectionFactory.getSslContextFactory()
-        logger.debug("SSL Context Factory: ${sslContextFactory.dump()}")
-
-        assert sslContextFactory.getProtocol() == EXPECTED_TLS_PROTOCOL
-        assert Arrays.asList(sslContextFactory.getIncludeProtocols()).containsAll(EXPECTED_INCLUDED_PROTOCOLS ?: Collections.emptySet())
         assert (sslContextFactory.getExcludeProtocols() as List<String>).containsAll(LEGACY_TLS_PROTOCOLS)
     }
 
diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-bundle/nifi-ssl-context-service/src/main/java/org/apache/nifi/ssl/StandardRestrictedSSLContextService.java b/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-bundle/nifi-ssl-context-service/src/main/java/org/apache/nifi/ssl/StandardRestrictedSSLContextService.java
index 014979f..9e69dde 100644
--- a/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-bundle/nifi-ssl-context-service/src/main/java/org/apache/nifi/ssl/StandardRestrictedSSLContextService.java
+++ b/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-bundle/nifi-ssl-context-service/src/main/java/org/apache/nifi/ssl/StandardRestrictedSSLContextService.java
@@ -17,17 +17,15 @@
 package org.apache.nifi.ssl;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collections;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Set;
 import org.apache.nifi.annotation.documentation.CapabilityDescription;
 import org.apache.nifi.annotation.documentation.Tags;
 import org.apache.nifi.components.AllowableValue;
 import org.apache.nifi.components.PropertyDescriptor;
 import org.apache.nifi.processor.util.StandardValidators;
 import org.apache.nifi.security.util.TlsConfiguration;
+import org.apache.nifi.security.util.TlsPlatform;
 
 /**
  * This class is functionally the same as {@link StandardSSLContextService}, but it restricts the allowable
@@ -45,11 +43,10 @@ public class StandardRestrictedSSLContextService extends StandardSSLContextServi
     public static final PropertyDescriptor RESTRICTED_SSL_ALGORITHM = new PropertyDescriptor.Builder()
             .name("SSL Protocol")
             .displayName("TLS Protocol")
-            .defaultValue("TLS")
+            .defaultValue(TlsConfiguration.TLS_PROTOCOL)
             .required(false)
-            .allowableValues(buildAlgorithmAllowableValues())
-            .description(StandardSSLContextService.COMMON_TLS_PROTOCOL_DESCRIPTION +
-                    "On Java 11, for example, TLSv1.3 will be the default, but if a client does not support it, TLSv1.2 will be offered as a fallback. TLSv1.0 and TLSv1.1 are not supported at all. ")
+            .allowableValues(getRestrictedProtocolAllowableValues())
+            .description("TLS Protocol Version for encrypted connections. Supported versions depend on the specific version of Java used.")
             .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
             .sensitive(false)
             .build();
@@ -79,21 +76,16 @@ public class StandardRestrictedSSLContextService extends StandardSSLContextServi
         return configContext.getProperty(RESTRICTED_SSL_ALGORITHM).getValue();
     }
 
-    /**
-     * Build a restricted set of allowable TLS protocol algorithms.
-     *
-     * @return the computed set of allowable values
-     */
-    static AllowableValue[] buildAlgorithmAllowableValues() {
-        final Set<String> supportedProtocols = new HashSet<>();
+    private static AllowableValue[] getRestrictedProtocolAllowableValues() {
+        final List<AllowableValue> allowableValues = new ArrayList<>();
 
-        supportedProtocols.add(TlsConfiguration.TLS_PROTOCOL);
+        allowableValues.add(new AllowableValue(TlsConfiguration.TLS_PROTOCOL, TlsConfiguration.TLS_PROTOCOL, "Negotiate latest protocol version based on platform supported versions"));
 
-        /*
-         * Add specifically supported TLS versions
-         */
-        supportedProtocols.addAll(Arrays.asList(TlsConfiguration.getCurrentSupportedTlsProtocolVersions()));
+        for (final String preferredProtocol : TlsPlatform.getPreferredProtocols()) {
+            final String description = String.format("Require %s protocol version", preferredProtocol);
+            allowableValues.add(new AllowableValue(preferredProtocol, preferredProtocol, description));
+        }
 
-        return SSLContextService.formAllowableValues(supportedProtocols);
+        return allowableValues.toArray(new AllowableValue[allowableValues.size()]);
     }
 }
diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-bundle/nifi-ssl-context-service/src/main/java/org/apache/nifi/ssl/StandardSSLContextService.java b/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-bundle/nifi-ssl-context-service/src/main/java/org/apache/nifi/ssl/StandardSSLContextService.java
index 5d9675d..af304ea 100644
--- a/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-bundle/nifi-ssl-context-service/src/main/java/org/apache/nifi/ssl/StandardSSLContextService.java
+++ b/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-bundle/nifi-ssl-context-service/src/main/java/org/apache/nifi/ssl/StandardSSLContextService.java
@@ -19,6 +19,7 @@ package org.apache.nifi.ssl;
 import org.apache.nifi.annotation.documentation.CapabilityDescription;
 import org.apache.nifi.annotation.documentation.Tags;
 import org.apache.nifi.annotation.lifecycle.OnEnabled;
+import org.apache.nifi.components.AllowableValue;
 import org.apache.nifi.components.PropertyDescriptor;
 import org.apache.nifi.components.PropertyValue;
 import org.apache.nifi.components.ValidationContext;
@@ -37,6 +38,7 @@ import org.apache.nifi.security.util.SslContextFactory;
 import org.apache.nifi.security.util.StandardTlsConfiguration;
 import org.apache.nifi.security.util.TlsConfiguration;
 import org.apache.nifi.security.util.TlsException;
+import org.apache.nifi.security.util.TlsPlatform;
 import org.apache.nifi.util.StringUtils;
 
 import javax.net.ssl.SSLContext;
@@ -58,14 +60,6 @@ import java.util.Map;
         + "allows a specific set of SSL protocols to be chosen.")
 public class StandardSSLContextService extends AbstractControllerService implements SSLContextService {
 
-    // Shared description for other SSL context services
-    public static final String COMMON_TLS_PROTOCOL_DESCRIPTION = "The algorithm to use for this TLS/SSL context. \"TLS\" will instruct NiFi to allow all supported protocol versions " +
-            "and choose the highest available protocol for each connection. " +
-            "Java 8 enabled TLSv1.2, which is now the lowest version supported for incoming connections. " +
-            "Java 11 enabled TLSv1.3. Depending on the version of Java NiFi is running on, different protocol versions will be available. " +
-            "With \"TLS\" selected, as new protocol versions are made available, NiFi will automatically select them. " +
-            "It is recommended unless a specific protocol version is needed. ";
-
     public static final PropertyDescriptor TRUSTSTORE = new PropertyDescriptor.Builder()
             .name("Truststore Filename")
             .description("The fully-qualified filename of the Truststore")
@@ -121,11 +115,10 @@ public class StandardSSLContextService extends AbstractControllerService impleme
     public static final PropertyDescriptor SSL_ALGORITHM = new PropertyDescriptor.Builder()
             .name("SSL Protocol")
             .displayName("TLS Protocol")
-            .defaultValue("TLS")
+            .defaultValue(TlsConfiguration.TLS_PROTOCOL)
             .required(false)
-            .allowableValues(SSLContextService.buildAlgorithmAllowableValues())
-            .description(COMMON_TLS_PROTOCOL_DESCRIPTION +
-                    "For outgoing connections, legacy protocol versions like \"TLSv1.0\" are supported, but discouraged unless necessary. ")
+            .allowableValues(getProtocolAllowableValues())
+            .description("SSL or TLS Protocol Version for encrypted connections. Supported versions include insecure legacy options and depend on the specific version of Java used.")
             .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
             .sensitive(false)
             .build();
@@ -577,4 +570,18 @@ public class StandardSSLContextService extends AbstractControllerService impleme
     public String toString() {
         return "SSLContextService[id=" + getIdentifier() + "]";
     }
+
+    private static AllowableValue[] getProtocolAllowableValues() {
+        final List<AllowableValue> allowableValues = new ArrayList<>();
+
+        allowableValues.add(new AllowableValue(TlsConfiguration.SSL_PROTOCOL, TlsConfiguration.SSL_PROTOCOL, "Negotiate latest SSL or TLS protocol version based on platform supported versions"));
+        allowableValues.add(new AllowableValue(TlsConfiguration.TLS_PROTOCOL, TlsConfiguration.TLS_PROTOCOL, "Negotiate latest TLS protocol version based on platform supported versions"));
+
+        for (final String supportedProtocol : TlsPlatform.getSupportedProtocols()) {
+            final String description = String.format("Require %s protocol version", supportedProtocol);
+            allowableValues.add(new AllowableValue(supportedProtocol, supportedProtocol, description));
+        }
+
+        return allowableValues.toArray(new AllowableValue[allowableValues.size()]);
+    }
 }
diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-bundle/nifi-ssl-context-service/src/test/java/org/apache/nifi/ssl/RestrictedSSLContextServiceTest.java b/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-bundle/nifi-ssl-context-service/src/test/java/org/apache/nifi/ssl/RestrictedSSLContextServiceTest.java
deleted file mode 100644
index 61eaa0e..0000000
--- a/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-bundle/nifi-ssl-context-service/src/test/java/org/apache/nifi/ssl/RestrictedSSLContextServiceTest.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF 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
- *
- *     http://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 org.apache.nifi.ssl;
-
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.core.IsNull.notNullValue;
-import static org.junit.Assert.assertTrue;
-
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-import org.apache.nifi.components.AllowableValue;
-import org.apache.nifi.security.util.TlsConfiguration;
-import org.junit.Test;
-
-public class RestrictedSSLContextServiceTest {
-
-    @Test
-    public void testTLSAlgorithms() {
-        final Set<String> expected = new HashSet<>();
-        expected.add("TLS");
-        expected.addAll(Arrays.asList(TlsConfiguration.getCurrentSupportedTlsProtocolVersions()));
-
-        final AllowableValue[] allowableValues = StandardRestrictedSSLContextService.buildAlgorithmAllowableValues();
-        assertThat(allowableValues, notNullValue());
-        assertThat(allowableValues.length, equalTo(expected.size()));
-        for(final AllowableValue value : allowableValues) {
-            assertTrue(expected.contains(value.getValue()));
-        }
-    }
-}
diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-bundle/nifi-ssl-context-service/src/test/java/org/apache/nifi/ssl/SSLContextServiceTest.java b/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-bundle/nifi-ssl-context-service/src/test/java/org/apache/nifi/ssl/SSLContextServiceTest.java
index 25fe9d4..0bd7a87 100644
--- a/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-bundle/nifi-ssl-context-service/src/test/java/org/apache/nifi/ssl/SSLContextServiceTest.java
+++ b/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-bundle/nifi-ssl-context-service/src/test/java/org/apache/nifi/ssl/SSLContextServiceTest.java
@@ -16,9 +16,6 @@
  */
 package org.apache.nifi.ssl;
 
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.core.IsNull.notNullValue;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
@@ -26,15 +23,9 @@ import java.io.File;
 import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.StandardCopyOption;
-import java.security.NoSuchAlgorithmException;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Map;
-import java.util.Set;
-import javax.net.ssl.SSLContext;
-import org.apache.nifi.components.AllowableValue;
 import org.apache.nifi.components.ValidationContext;
 import org.apache.nifi.components.ValidationResult;
 import org.apache.nifi.reporting.InitializationException;
@@ -55,11 +46,8 @@ public class SSLContextServiceTest {
     private final String KEYSTORE_AND_TRUSTSTORE_PASSWORD = "passwordpassword";
     private final String JKS_TYPE = "JKS";
     private final String TRUSTSTORE_PATH = "src/test/resources/truststore.jks";
-    private final String DIFFERENT_PASS_KEYSTORE_PATH = "src/test/resources/keystore-different-password.jks";
-    private final String DIFFERENT_KEYSTORE_PASSWORD = "differentpassword";
     private static final String KEYSTORE_WITH_KEY_PASSWORD_PATH = "src/test/resources/keystore-with-key-password.jks";
 
-
     @Rule
     public TemporaryFolder tmp = new TemporaryFolder(new File("src/test/resources"));
 
@@ -338,22 +326,4 @@ public class SSLContextServiceTest {
             Assert.fail("Should not have thrown a exception " + e.getMessage());
         }
     }
-
-    @Test
-    public void testSSLAlgorithms() throws NoSuchAlgorithmException {
-        final AllowableValue[] allowableValues = SSLContextService.buildAlgorithmAllowableValues();
-
-        // we expect TLS, SSL, and all available configured JVM protocols
-        final Set<String> expected = new HashSet<>();
-        expected.add("SSL");
-        expected.add("TLS");
-        final String[] supportedProtocols = SSLContext.getDefault().createSSLEngine().getSupportedProtocols();
-        expected.addAll(Arrays.asList(supportedProtocols));
-
-        assertThat(allowableValues, notNullValue());
-        assertThat(allowableValues.length, equalTo(expected.size()));
-        for(final AllowableValue value : allowableValues) {
-            assertTrue(expected.contains(value.getValue()));
-        }
-    }
 }
diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-bundle/nifi-ssl-context-service/src/test/java/org/apache/nifi/ssl/StandardRestrictedSSLContextServiceTest.java b/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-bundle/nifi-ssl-context-service/src/test/java/org/apache/nifi/ssl/StandardRestrictedSSLContextServiceTest.java
new file mode 100644
index 0000000..135d993
--- /dev/null
+++ b/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-bundle/nifi-ssl-context-service/src/test/java/org/apache/nifi/ssl/StandardRestrictedSSLContextServiceTest.java
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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
+ *
+ *     http://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 org.apache.nifi.ssl;
+
+import org.apache.nifi.processor.Processor;
+import org.apache.nifi.reporting.InitializationException;
+import org.apache.nifi.security.util.KeyStoreUtils;
+import org.apache.nifi.security.util.TlsConfiguration;
+import org.apache.nifi.security.util.TlsPlatform;
+import org.apache.nifi.util.TestRunner;
+import org.apache.nifi.util.TestRunners;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+
+import javax.net.ssl.SSLContext;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.security.GeneralSecurityException;
+
+import static org.junit.Assert.assertEquals;
+
+@RunWith(MockitoJUnitRunner.class)
+public class StandardRestrictedSSLContextServiceTest {
+
+    private static final String SERVICE_ID = StandardRestrictedSSLContextService.class.getSimpleName();
+
+    private static TlsConfiguration tlsConfiguration;
+
+    @Mock
+    private Processor processor;
+
+    private StandardRestrictedSSLContextService service;
+
+    private TestRunner runner;
+
+    @BeforeClass
+    public static void setConfiguration() throws IOException, GeneralSecurityException {
+        tlsConfiguration = KeyStoreUtils.createTlsConfigAndNewKeystoreTruststore();
+    }
+
+    @AfterClass
+    public static void deleteConfiguration() throws IOException {
+        Files.deleteIfExists(Paths.get(tlsConfiguration.getKeystorePath()));
+        Files.deleteIfExists(Paths.get(tlsConfiguration.getTruststorePath()));
+    }
+
+    @Before
+    public void setRunner() {
+        runner = TestRunners.newTestRunner(processor);
+        service = new StandardRestrictedSSLContextService();
+    }
+
+    @Test
+    public void testMinimumPropertiesValid() throws InitializationException {
+        runner.addControllerService(SERVICE_ID, service);
+        setMinimumProperties();
+        runner.assertValid(service);
+    }
+
+    @Test
+    public void testPreferredProtocolsValid() throws InitializationException {
+        runner.addControllerService(SERVICE_ID, service);
+        setMinimumProperties();
+
+        for (final String protocol : TlsPlatform.getPreferredProtocols()) {
+            runner.setProperty(service, StandardRestrictedSSLContextService.SSL_ALGORITHM, protocol);
+            runner.assertValid(service);
+        }
+    }
+
+    @Test
+    public void testPreferredProtocolsCreateContext() throws InitializationException {
+        runner.addControllerService(SERVICE_ID, service);
+        setMinimumProperties();
+
+        for (final String protocol : TlsPlatform.getPreferredProtocols()) {
+            runner.setProperty(service, StandardRestrictedSSLContextService.SSL_ALGORITHM, protocol);
+            runner.assertValid(service);
+            runner.enableControllerService(service);
+
+            final SSLContext sslContext = service.createContext();
+            assertEquals(protocol, sslContext.getProtocol());
+
+            runner.disableControllerService(service);
+        }
+    }
+
+    private void setMinimumProperties() {
+        runner.setProperty(service, StandardRestrictedSSLContextService.KEYSTORE, tlsConfiguration.getKeystorePath());
+        runner.setProperty(service, StandardRestrictedSSLContextService.KEYSTORE_PASSWORD, tlsConfiguration.getKeystorePassword());
+        runner.setProperty(service, StandardRestrictedSSLContextService.KEYSTORE_TYPE, tlsConfiguration.getKeystoreType().getType());
+        runner.setProperty(service, StandardRestrictedSSLContextService.TRUSTSTORE, tlsConfiguration.getTruststorePath());
+        runner.setProperty(service, StandardRestrictedSSLContextService.TRUSTSTORE_PASSWORD, tlsConfiguration.getTruststorePassword());
+        runner.setProperty(service, StandardRestrictedSSLContextService.TRUSTSTORE_TYPE, tlsConfiguration.getTruststoreType().getType());
+    }
+}
diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-service-api/src/main/java/org/apache/nifi/ssl/SSLContextService.java b/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-service-api/src/main/java/org/apache/nifi/ssl/SSLContextService.java
index 1497d87..4e6cd43 100644
--- a/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-service-api/src/main/java/org/apache/nifi/ssl/SSLContextService.java
+++ b/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-service-api/src/main/java/org/apache/nifi/ssl/SSLContextService.java
@@ -16,19 +16,11 @@
  */
 package org.apache.nifi.ssl;
 
-import java.security.NoSuchAlgorithmException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.X509TrustManager;
 
 import org.apache.nifi.annotation.documentation.CapabilityDescription;
 import org.apache.nifi.annotation.documentation.Tags;
-import org.apache.nifi.components.AllowableValue;
 import org.apache.nifi.controller.ControllerService;
 import org.apache.nifi.processor.exception.ProcessException;
 import org.apache.nifi.security.util.TlsConfiguration;
@@ -117,52 +109,4 @@ public interface SSLContextService extends ControllerService {
     boolean isKeyStoreConfigured();
 
     String getSslAlgorithm();
-
-    /**
-     * Build a set of allowable TLS/SSL protocol algorithms based on JVM configuration.
-     *
-     * @return the computed set of allowable values
-     */
-    static AllowableValue[] buildAlgorithmAllowableValues() {
-        final Set<String> supportedProtocols = new HashSet<>();
-
-        /*
-         * Prepopulate protocols with generic instance types commonly used
-         * see: http://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#SSLContext
-         */
-        supportedProtocols.add(TlsConfiguration.TLS_PROTOCOL);
-
-        // This is still available for outgoing connections to legacy services, but can be disabled with jdk.tls.disabledAlgorithms
-        supportedProtocols.add(TlsConfiguration.SSL_PROTOCOL);
-
-        // Determine those provided by the JVM on the system
-        try {
-            supportedProtocols.addAll(Arrays.asList(SSLContext.getDefault().createSSLEngine().getSupportedProtocols()));
-        } catch (NoSuchAlgorithmException e) {
-            // ignored as default is used
-        }
-
-        return formAllowableValues(supportedProtocols);
-    }
-
-    /**
-     * Returns an array of {@link AllowableValue} objects formed from the provided
-     * set of Strings. The returned array is sorted for consistency in display order.
-     *
-     * @param rawValues the set of string values
-     * @return an array of AllowableValues
-     */
-    static AllowableValue[] formAllowableValues(Set<String> rawValues) {
-        final int numProtocols = rawValues.size();
-
-        // Sort for consistent presentation in configuration views
-        final List<String> valueList = new ArrayList<>(rawValues);
-        Collections.sort(valueList);
-
-        final List<AllowableValue> allowableValues = new ArrayList<>();
-        for (final String protocol : valueList) {
-            allowableValues.add(new AllowableValue(protocol));
-        }
-        return allowableValues.toArray(new AllowableValue[numProtocols]);
-    }
 }