Repository: incubator-nifi
Updated Branches:
  refs/heads/develop 8b5a8ab05 -> 64502d0e1


NIFI-419 Providing a user configurable selection of the SSL Protocol algorithm 
used for connections withing an SSL Context controller service.  This provides 
defaults of TLS/SSL values as well as performs a look up of the available items 
within the JVM.


Project: http://git-wip-us.apache.org/repos/asf/incubator-nifi/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-nifi/commit/64502d0e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-nifi/tree/64502d0e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-nifi/diff/64502d0e

Branch: refs/heads/develop
Commit: 64502d0e10e964bebddd0ad35c4c074f002d536d
Parents: 8b5a8ab
Author: Aldrin Piri <[email protected]>
Authored: Tue Jun 9 00:54:26 2015 -0400
Committer: Aldrin Piri <[email protected]>
Committed: Thu Jun 18 23:13:49 2015 -0400

----------------------------------------------------------------------
 .../nifi/processor/util/SSLProperties.java      | 10 ++-
 .../nifi/security/util/SslContextFactory.java   | 15 ++--
 .../nifi/ssl/StandardSSLContextService.java     | 91 ++++++++++++++++----
 .../org/apache/nifi/ssl/SSLContextService.java  |  1 +
 4 files changed, 91 insertions(+), 26 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/64502d0e/nifi/nifi-commons/nifi-processor-utilities/src/main/java/org/apache/nifi/processor/util/SSLProperties.java
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-commons/nifi-processor-utilities/src/main/java/org/apache/nifi/processor/util/SSLProperties.java
 
b/nifi/nifi-commons/nifi-processor-utilities/src/main/java/org/apache/nifi/processor/util/SSLProperties.java
index 87d63de..dca15b0 100644
--- 
a/nifi/nifi-commons/nifi-processor-utilities/src/main/java/org/apache/nifi/processor/util/SSLProperties.java
+++ 
b/nifi/nifi-commons/nifi-processor-utilities/src/main/java/org/apache/nifi/processor/util/SSLProperties.java
@@ -163,6 +163,8 @@ public class SSLProperties {
         KEYSTORE, TRUSTSTORE
     }
 
+    private static final String DEFAULT_SSL_PROTOCOL_ALGORITHM = "TLS";
+
     public static List<PropertyDescriptor> getKeystoreDescriptors(final 
boolean required) {
         final List<PropertyDescriptor> descriptors = new ArrayList<>();
         for (final PropertyDescriptor descriptor : KEYSTORE_DESCRIPTORS) {
@@ -196,14 +198,15 @@ public class SSLProperties {
             return SslContextFactory.createTrustSslContext(
                     context.getProperty(TRUSTSTORE).getValue(),
                     
context.getProperty(TRUSTSTORE_PASSWORD).getValue().toCharArray(),
-                    context.getProperty(TRUSTSTORE_TYPE).getValue());
+                    context.getProperty(TRUSTSTORE_TYPE).getValue(),
+                    DEFAULT_SSL_PROTOCOL_ALGORITHM);
         } else {
             final String truststoreFile = 
context.getProperty(TRUSTSTORE).getValue();
             if (truststoreFile == null) {
                 return SslContextFactory.createSslContext(
                         context.getProperty(KEYSTORE).getValue(),
                         
context.getProperty(KEYSTORE_PASSWORD).getValue().toCharArray(),
-                        context.getProperty(KEYSTORE_TYPE).getValue());
+                        context.getProperty(KEYSTORE_TYPE).getValue(), 
DEFAULT_SSL_PROTOCOL_ALGORITHM);
             } else {
                 return SslContextFactory.createSslContext(
                         context.getProperty(KEYSTORE).getValue(),
@@ -212,7 +215,8 @@ public class SSLProperties {
                         context.getProperty(TRUSTSTORE).getValue(),
                         
context.getProperty(TRUSTSTORE_PASSWORD).getValue().toCharArray(),
                         context.getProperty(TRUSTSTORE_TYPE).getValue(),
-                        clientAuth);
+                        clientAuth,
+                        DEFAULT_SSL_PROTOCOL_ALGORITHM);
             }
         }
     }

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/64502d0e/nifi/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/util/SslContextFactory.java
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/util/SslContextFactory.java
 
b/nifi/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/util/SslContextFactory.java
index 78cf6e6..656573d 100644
--- 
a/nifi/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/util/SslContextFactory.java
+++ 
b/nifi/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/util/SslContextFactory.java
@@ -57,6 +57,7 @@ public final class SslContextFactory {
      * @param truststorePasswd the truststore password
      * @param truststoreType the type of truststore (e.g., PKCS12, JKS)
      * @param clientAuth the type of client authentication
+     * @param protocol         the protocol to use for the SSL connection
      *
      * @return a SSLContext instance
      * @throws java.security.KeyStoreException if any issues accessing the 
keystore
@@ -69,7 +70,7 @@ public final class SslContextFactory {
     public static SSLContext createSslContext(
             final String keystore, final char[] keystorePasswd, final String 
keystoreType,
             final String truststore, final char[] truststorePasswd, final 
String truststoreType,
-            final ClientAuth clientAuth)
+            final ClientAuth clientAuth, final String protocol)
             throws KeyStoreException, IOException, NoSuchAlgorithmException, 
CertificateException,
             UnrecoverableKeyException, KeyManagementException {
 
@@ -90,7 +91,7 @@ public final class SslContextFactory {
         trustManagerFactory.init(trustStore);
 
         // initialize the ssl context
-        final SSLContext sslContext = SSLContext.getInstance("TLS");
+        final SSLContext sslContext = SSLContext.getInstance(protocol);
         sslContext.init(keyManagerFactory.getKeyManagers(), 
trustManagerFactory.getTrustManagers(), new SecureRandom());
         if (ClientAuth.REQUIRED == clientAuth) {
             sslContext.getDefaultSSLParameters().setNeedClientAuth(true);
@@ -110,6 +111,7 @@ public final class SslContextFactory {
      * @param keystore the full path to the keystore
      * @param keystorePasswd the keystore password
      * @param keystoreType the type of keystore (e.g., PKCS12, JKS)
+     * @param protocol the protocol to use for the SSL connection
      *
      * @return a SSLContext instance
      * @throws java.security.KeyStoreException if any issues accessing the 
keystore
@@ -120,7 +122,7 @@ public final class SslContextFactory {
      * @throws java.security.KeyManagementException if unable to manage the key
      */
     public static SSLContext createSslContext(
-            final String keystore, final char[] keystorePasswd, final String 
keystoreType)
+            final String keystore, final char[] keystorePasswd, final String 
keystoreType, final String protocol)
             throws KeyStoreException, IOException, NoSuchAlgorithmException, 
CertificateException,
             UnrecoverableKeyException, KeyManagementException {
 
@@ -133,7 +135,7 @@ public final class SslContextFactory {
         keyManagerFactory.init(keyStore, keystorePasswd);
 
         // initialize the ssl context
-        final SSLContext ctx = SSLContext.getInstance("TLS");
+        final SSLContext ctx = SSLContext.getInstance(protocol);
         ctx.init(keyManagerFactory.getKeyManagers(), new TrustManager[0], new 
SecureRandom());
 
         return ctx;
@@ -146,6 +148,7 @@ public final class SslContextFactory {
      * @param truststore the full path to the truststore
      * @param truststorePasswd the truststore password
      * @param truststoreType the type of truststore (e.g., PKCS12, JKS)
+     * @param protocol the protocol to use for the SSL connection
      *
      * @return a SSLContext instance
      * @throws java.security.KeyStoreException if any issues accessing the 
keystore
@@ -156,7 +159,7 @@ public final class SslContextFactory {
      * @throws java.security.KeyManagementException if unable to manage the key
      */
     public static SSLContext createTrustSslContext(
-            final String truststore, final char[] truststorePasswd, final 
String truststoreType)
+            final String truststore, final char[] truststorePasswd, final 
String truststoreType, final String protocol)
             throws KeyStoreException, IOException, NoSuchAlgorithmException, 
CertificateException,
             UnrecoverableKeyException, KeyManagementException {
 
@@ -169,7 +172,7 @@ public final class SslContextFactory {
         trustManagerFactory.init(trustStore);
 
         // initialize the ssl context
-        final SSLContext ctx = SSLContext.getInstance("TLS");
+        final SSLContext ctx = SSLContext.getInstance(protocol);
         ctx.init(new KeyManager[0], trustManagerFactory.getTrustManagers(), 
new SecureRandom());
 
         return ctx;

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/64502d0e/nifi/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-bundle/nifi-ssl-context-service/src/main/java/org/apache/nifi/ssl/StandardSSLContextService.java
----------------------------------------------------------------------
diff --git 
a/nifi/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/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-bundle/nifi-ssl-context-service/src/main/java/org/apache/nifi/ssl/StandardSSLContextService.java
index cde71da..8fa9100 100644
--- 
a/nifi/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/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-bundle/nifi-ssl-context-service/src/main/java/org/apache/nifi/ssl/StandardSSLContextService.java
@@ -16,19 +16,10 @@
  */
 package org.apache.nifi.ssl;
 
-import java.io.File;
-import java.net.MalformedURLException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import javax.net.ssl.SSLContext;
-
 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.ValidationContext;
 import org.apache.nifi.components.ValidationResult;
@@ -42,6 +33,19 @@ import org.apache.nifi.security.util.CertificateUtils;
 import org.apache.nifi.security.util.KeystoreType;
 import org.apache.nifi.security.util.SslContextFactory;
 
+import javax.net.ssl.SSLContext;
+import java.io.File;
+import java.net.MalformedURLException;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
 @Tags({"ssl", "secure", "certificate", "keystore", "truststore", "jks", "p12", 
"pkcs12", "pkcs"})
 @CapabilityDescription("Standard implementation of the SSLContextService. 
Provides the ability to configure "
         + "keystore and/or truststore properties once and reuse that 
configuration throughout the application")
@@ -92,6 +96,15 @@ public class StandardSSLContextService extends 
AbstractControllerService impleme
             .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
             .sensitive(true)
             .build();
+    public static final PropertyDescriptor SSL_ALGORITHM = new 
PropertyDescriptor.Builder()
+            .name("SSL Protocol")
+            .defaultValue("TLS")
+            .required(false)
+            .allowableValues(buildAlgorithmAllowableValues())
+            .description("The algorithm to use for this SSL context")
+            .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
+            .sensitive(false)
+            .build();
 
     private static final List<PropertyDescriptor> properties;
     private ConfigurationContext configContext;
@@ -104,6 +117,7 @@ public class StandardSSLContextService extends 
AbstractControllerService impleme
         props.add(TRUSTSTORE);
         props.add(TRUSTSTORE_PASSWORD);
         props.add(TRUSTSTORE_TYPE);
+        props.add(SSL_ALGORITHM);
         properties = Collections.unmodifiableList(props);
     }
 
@@ -207,13 +221,15 @@ public class StandardSSLContextService extends 
AbstractControllerService impleme
     }
 
     private void verifySslConfig(final ValidationContext validationContext) 
throws ProcessException {
+        final String protocol = 
validationContext.getProperty(SSL_ALGORITHM).getValue();
         try {
             final String keystoreFile = 
validationContext.getProperty(KEYSTORE).getValue();
             if (keystoreFile == null) {
                 SslContextFactory.createTrustSslContext(
                         validationContext.getProperty(TRUSTSTORE).getValue(),
                         
validationContext.getProperty(TRUSTSTORE_PASSWORD).getValue().toCharArray(),
-                        
validationContext.getProperty(TRUSTSTORE_TYPE).getValue());
+                        
validationContext.getProperty(TRUSTSTORE_TYPE).getValue(),
+                        protocol);
                 return;
             }
             final String truststoreFile = 
validationContext.getProperty(TRUSTSTORE).getValue();
@@ -221,7 +237,8 @@ public class StandardSSLContextService extends 
AbstractControllerService impleme
                 SslContextFactory.createSslContext(
                         validationContext.getProperty(KEYSTORE).getValue(),
                         
validationContext.getProperty(KEYSTORE_PASSWORD).getValue().toCharArray(),
-                        
validationContext.getProperty(KEYSTORE_TYPE).getValue());
+                        
validationContext.getProperty(KEYSTORE_TYPE).getValue(),
+                        protocol);
                 return;
             }
 
@@ -232,7 +249,8 @@ public class StandardSSLContextService extends 
AbstractControllerService impleme
                     validationContext.getProperty(TRUSTSTORE).getValue(),
                     
validationContext.getProperty(TRUSTSTORE_PASSWORD).getValue().toCharArray(),
                     validationContext.getProperty(TRUSTSTORE_TYPE).getValue(),
-                    
org.apache.nifi.security.util.SslContextFactory.ClientAuth.REQUIRED);
+                    
org.apache.nifi.security.util.SslContextFactory.ClientAuth.REQUIRED,
+                    protocol);
         } catch (final Exception e) {
             throw new ProcessException(e);
         }
@@ -240,20 +258,23 @@ public class StandardSSLContextService extends 
AbstractControllerService impleme
 
     @Override
     public SSLContext createSSLContext(final ClientAuth clientAuth) throws 
ProcessException {
+        final String protocol = 
configContext.getProperty(SSL_ALGORITHM).getValue();
         try {
             final String keystoreFile = 
configContext.getProperty(KEYSTORE).getValue();
             if (keystoreFile == null) {
                 return SslContextFactory.createTrustSslContext(
                         configContext.getProperty(TRUSTSTORE).getValue(),
                         
configContext.getProperty(TRUSTSTORE_PASSWORD).getValue().toCharArray(),
-                        configContext.getProperty(TRUSTSTORE_TYPE).getValue());
+                        configContext.getProperty(TRUSTSTORE_TYPE).getValue(),
+                        protocol);
             }
             final String truststoreFile = 
configContext.getProperty(TRUSTSTORE).getValue();
             if (truststoreFile == null) {
                 return SslContextFactory.createSslContext(
                         configContext.getProperty(KEYSTORE).getValue(),
                         
configContext.getProperty(KEYSTORE_PASSWORD).getValue().toCharArray(),
-                        configContext.getProperty(KEYSTORE_TYPE).getValue());
+                        configContext.getProperty(KEYSTORE_TYPE).getValue(),
+                        protocol);
             }
 
             return SslContextFactory.createSslContext(
@@ -263,7 +284,8 @@ public class StandardSSLContextService extends 
AbstractControllerService impleme
                     configContext.getProperty(TRUSTSTORE).getValue(),
                     
configContext.getProperty(TRUSTSTORE_PASSWORD).getValue().toCharArray(),
                     configContext.getProperty(TRUSTSTORE_TYPE).getValue(),
-                    
org.apache.nifi.security.util.SslContextFactory.ClientAuth.valueOf(clientAuth.name()));
+                    
org.apache.nifi.security.util.SslContextFactory.ClientAuth.valueOf(clientAuth.name()),
+                    protocol);
         } catch (final Exception e) {
             throw new ProcessException(e);
         }
@@ -309,8 +331,13 @@ public class StandardSSLContextService extends 
AbstractControllerService impleme
         return getKeyStoreFile() != null && getKeyStorePassword() != null && 
getKeyStoreType() != null;
     }
 
+    @Override
+    public String getSslAlgorithm() {
+        return configContext.getProperty(SSL_ALGORITHM).getValue();
+    }
+
     private static Collection<ValidationResult> validateStore(final 
Map<PropertyDescriptor, String> properties,
-            final KeystoreValidationGroup keyStoreOrTrustStore) {
+                                                              final 
KeystoreValidationGroup keyStoreOrTrustStore) {
         final Collection<ValidationResult> results = new ArrayList<>();
 
         final String filename;
@@ -382,6 +409,36 @@ public class StandardSSLContextService extends 
AbstractControllerService impleme
         KEYSTORE, TRUSTSTORE
     }
 
+    private 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("SSL");
+        supportedProtocols.add("TLS");
+
+        // 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
+        }
+
+        final int numProtocols = supportedProtocols.size();
+
+        // Sort for consistent presentation in configuraiton views
+        final List<String> supportedProtocolList = new 
ArrayList<>(supportedProtocols);
+        Collections.sort(supportedProtocolList);
+
+        final List<AllowableValue> protocolAllowableValues = new ArrayList<>();
+        for (final String protocol : supportedProtocolList) {
+            protocolAllowableValues.add(new AllowableValue(protocol));
+        }
+        return protocolAllowableValues.toArray(new 
AllowableValue[numProtocols]);
+    }
+
     @Override
     public String toString() {
         return "SSLContextService[id=" + getIdentifier() + "]";

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/64502d0e/nifi/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-service-api/src/main/java/org/apache/nifi/ssl/SSLContextService.java
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-service-api/src/main/java/org/apache/nifi/ssl/SSLContextService.java
 
b/nifi/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-service-api/src/main/java/org/apache/nifi/ssl/SSLContextService.java
index b2e3b76..13bab4c 100644
--- 
a/nifi/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-service-api/src/main/java/org/apache/nifi/ssl/SSLContextService.java
+++ 
b/nifi/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-service-api/src/main/java/org/apache/nifi/ssl/SSLContextService.java
@@ -57,4 +57,5 @@ public interface SSLContextService extends ControllerService {
 
     public boolean isKeyStoreConfigured();
 
+    String getSslAlgorithm();
 }

Reply via email to