NIFIREG-434 Added support for BCFKS Keystore Type

Signed-off-by: Nathan Gough <thenatog@gmail.com>

This closes #314.
diff --git a/nifi-registry-core/nifi-registry-client/src/main/java/org/apache/nifi/registry/client/NiFiRegistryClientConfig.java b/nifi-registry-core/nifi-registry-client/src/main/java/org/apache/nifi/registry/client/NiFiRegistryClientConfig.java
index 0c1b21b..784f77f 100644
--- a/nifi-registry-core/nifi-registry-client/src/main/java/org/apache/nifi/registry/client/NiFiRegistryClientConfig.java
+++ b/nifi-registry-core/nifi-registry-client/src/main/java/org/apache/nifi/registry/client/NiFiRegistryClientConfig.java
@@ -105,7 +105,7 @@
         if (truststoreFilename != null && truststorePass != null && truststoreType != null) {
             try {
                 // prepare the truststore
-                final KeyStore trustStore = KeyStoreUtils.getTrustStore(truststoreType.name());
+                final KeyStore trustStore = KeyStoreUtils.getKeyStore(truststoreType.name());
                 try (final InputStream trustStoreStream = new FileInputStream(new File(truststoreFilename))) {
                     trustStore.load(trustStoreStream, truststorePass.toCharArray());
                 }
diff --git a/nifi-registry-core/nifi-registry-docs/src/main/asciidoc/administration-guide.adoc b/nifi-registry-core/nifi-registry-docs/src/main/asciidoc/administration-guide.adoc
index 0276693..5e960d9 100644
--- a/nifi-registry-core/nifi-registry-docs/src/main/asciidoc/administration-guide.adoc
+++ b/nifi-registry-core/nifi-registry-docs/src/main/asciidoc/administration-guide.adoc
@@ -86,11 +86,11 @@
 |==================================================================================================================================================
 | Property Name | Description
 |`nifi.registry.security.keystore` | Filename of the Keystore that contains the server's private key.
-|`nifi.registry.security.keystoreType` | The type of Keystore. Must be either `PKCS12` or `JKS`.  JKS is the preferred type, PKCS12 files will be loaded with BouncyCastle provider.
+|`nifi.registry.security.keystoreType` | The type of Keystore. Must be `PKCS12` or `JKS` or `BCFKS`.  JKS is the preferred type, BCFKS and PKCS12 files will be loaded with BouncyCastle provider.
 |`nifi.registry.security.keystorePasswd` | The password for the Keystore.
 |`nifi.registry.security.keyPasswd` | The password for the certificate in the Keystore. If not set, the value of `nifi.registry.security.keystorePasswd` will be used.
 |`nifi.registry.security.truststore` | Filename of the Truststore that will be used to authorize those connecting to NiFi Registry.  A secured instance with no Truststore will refuse all incoming connections.
-|`nifi.registry.security.truststoreType` | The type of the Truststore. Must be either `PKCS12` or `JKS`.  JKS is the preferred type, PKCS12 files will be loaded with BouncyCastle provider.
+|`nifi.registry.security.truststoreType` | The type of the Truststore. Must be `PKCS12` or `JKS` or `BCFKS`.  JKS is the preferred type, BCFKS and PKCS12 files will be loaded with BouncyCastle provider.
 |`nifi.registry.security.truststorePasswd` | The password for the Truststore.
 |`nifi.registry.security.needClientAuth` | This specifies that connecting clients must authenticate with a client cert. Setting this to `false` will specify that connecting clients may optionally authenticate with a client cert, but may also login with a username and password against a configured identity provider. The default value is `true`.
 |==================================================================================================================================================
diff --git a/nifi-registry-core/nifi-registry-security-utils/src/main/java/org/apache/nifi/registry/security/util/KeyStoreUtils.java b/nifi-registry-core/nifi-registry-security-utils/src/main/java/org/apache/nifi/registry/security/util/KeyStoreUtils.java
index 71f1ce0..952419d 100644
--- a/nifi-registry-core/nifi-registry-security-utils/src/main/java/org/apache/nifi/registry/security/util/KeyStoreUtils.java
+++ b/nifi-registry-core/nifi-registry-security-utils/src/main/java/org/apache/nifi/registry/security/util/KeyStoreUtils.java
@@ -25,12 +25,22 @@
 import java.security.KeyStore;
 import java.security.KeyStoreException;
 import java.security.Security;
+import java.util.HashMap;
+import java.util.Map;
 
 public class KeyStoreUtils {
     private static final Logger logger = LoggerFactory.getLogger(KeyStoreUtils.class);
 
+    private static final String SUN_SECURITY_PROVIDER = "SUN";
+
+    private static final Map<String, String> KEY_STORE_TYPE_PROVIDERS = new HashMap<>();
+
     static {
         Security.addProvider(new BouncyCastleProvider());
+
+        KEY_STORE_TYPE_PROVIDERS.put(KeystoreType.JKS.toString(), SUN_SECURITY_PROVIDER);
+        KEY_STORE_TYPE_PROVIDERS.put(KeystoreType.PKCS12.toString(), BouncyCastleProvider.PROVIDER_NAME);
+        KEY_STORE_TYPE_PROVIDERS.put(KeystoreType.BCFKS.toString(), BouncyCastleProvider.PROVIDER_NAME);
     }
 
     /**
@@ -39,11 +49,9 @@
      * @param keyStoreType the keyStoreType
      * @return the provider that will be used
      */
-    public static String getKeyStoreProvider(String keyStoreType) {
-        if (KeystoreType.PKCS12.toString().equalsIgnoreCase(keyStoreType)) {
-            return BouncyCastleProvider.PROVIDER_NAME;
-        }
-        return null;
+    public static String getKeyStoreProvider(final String keyStoreType) {
+        final String storeType = StringUtils.upperCase(keyStoreType);
+        return KEY_STORE_TYPE_PROVIDERS.get(storeType);
     }
 
     /**
@@ -53,8 +61,8 @@
      * @return an empty KeyStore
      * @throws KeyStoreException if a KeyStore of the given type cannot be instantiated
      */
-    public static KeyStore getKeyStore(String keyStoreType) throws KeyStoreException {
-        String keyStoreProvider = getKeyStoreProvider(keyStoreType);
+    public static KeyStore getKeyStore(final String keyStoreType) throws KeyStoreException {
+        final String keyStoreProvider = getKeyStoreProvider(keyStoreType);
         if (StringUtils.isNotEmpty(keyStoreProvider)) {
             try {
                 return KeyStore.getInstance(keyStoreType, keyStoreProvider);
@@ -65,18 +73,4 @@
         }
         return KeyStore.getInstance(keyStoreType);
     }
-
-    /**
-     * Returns an empty KeyStore intended for use as a TrustStore backed by the appropriate provider
-     *
-     * @param trustStoreType the trustStoreType
-     * @return an empty KeyStore
-     * @throws KeyStoreException if a KeyStore of the given type cannot be instantiated
-     */
-    public static KeyStore getTrustStore(String trustStoreType) throws KeyStoreException {
-        if (KeystoreType.PKCS12.toString().equalsIgnoreCase(trustStoreType)) {
-            logger.warn(trustStoreType + " truststores are deprecated.  " + KeystoreType.JKS.toString() + " is preferred.");
-        }
-        return getKeyStore(trustStoreType);
-    }
 }
diff --git a/nifi-registry-core/nifi-registry-security-utils/src/main/java/org/apache/nifi/registry/security/util/KeystoreType.java b/nifi-registry-core/nifi-registry-security-utils/src/main/java/org/apache/nifi/registry/security/util/KeystoreType.java
index f143e5a..d785610 100644
--- a/nifi-registry-core/nifi-registry-security-utils/src/main/java/org/apache/nifi/registry/security/util/KeystoreType.java
+++ b/nifi-registry-core/nifi-registry-security-utils/src/main/java/org/apache/nifi/registry/security/util/KeystoreType.java
@@ -20,6 +20,7 @@
  * Keystore types.
  */
 public enum KeystoreType {
+    BCFKS,
     PKCS12,
-    JKS;
+    JKS
 }
diff --git a/nifi-registry-core/nifi-registry-security-utils/src/main/java/org/apache/nifi/registry/security/util/SslContextFactory.java b/nifi-registry-core/nifi-registry-security-utils/src/main/java/org/apache/nifi/registry/security/util/SslContextFactory.java
index 9ed8ace..e107499 100644
--- a/nifi-registry-core/nifi-registry-security-utils/src/main/java/org/apache/nifi/registry/security/util/SslContextFactory.java
+++ b/nifi-registry-core/nifi-registry-security-utils/src/main/java/org/apache/nifi/registry/security/util/SslContextFactory.java
@@ -119,7 +119,7 @@
         }
 
         // prepare the truststore
-        final KeyStore trustStore = KeyStoreUtils.getTrustStore(truststoreType);
+        final KeyStore trustStore = KeyStoreUtils.getKeyStore(truststoreType);
         try (final InputStream trustStoreStream = new FileInputStream(truststore)) {
             trustStore.load(trustStoreStream, truststorePasswd);
         }
@@ -231,7 +231,7 @@
             UnrecoverableKeyException, KeyManagementException {
 
         // prepare the truststore
-        final KeyStore trustStore = KeyStoreUtils.getTrustStore(truststoreType);
+        final KeyStore trustStore = KeyStoreUtils.getKeyStore(truststoreType);
         try (final InputStream trustStoreStream = new FileInputStream(truststore)) {
             trustStore.load(trustStoreStream, truststorePasswd);
         }
diff --git a/nifi-registry-core/nifi-registry-security-utils/src/test/java/org/apache/nifi/registry/security/util/KeyStoreUtilsTest.java b/nifi-registry-core/nifi-registry-security-utils/src/test/java/org/apache/nifi/registry/security/util/KeyStoreUtilsTest.java
new file mode 100644
index 0000000..c0fb63c
--- /dev/null
+++ b/nifi-registry-core/nifi-registry-security-utils/src/test/java/org/apache/nifi/registry/security/util/KeyStoreUtilsTest.java
@@ -0,0 +1,48 @@
+/*
+ * 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.registry.security.util;
+
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+
+public class KeyStoreUtilsTest {
+
+    @Test
+    public void testGetKeyStore() throws KeyStoreException {
+        for (final KeystoreType keystoreType : KeystoreType.values()) {
+            final KeyStore keyStore = KeyStoreUtils.getKeyStore(keystoreType.toString());
+            Assert.assertNotNull(String.format("KeyStore not found for Keystore Type [%s]", keystoreType), keyStore);
+            Assert.assertEquals(keystoreType.name(), keyStore.getType());
+        }
+    }
+
+    @Test
+    public void testGetKeyStoreProviderNullType() {
+        final String keyStoreProvider = KeyStoreUtils.getKeyStoreProvider(null);
+        Assert.assertNull(keyStoreProvider);
+    }
+
+    @Test
+    public void testGetKeyStoreProviderBouncyCastleProvider() {
+        final String keyStoreProvider = KeyStoreUtils.getKeyStoreProvider(KeystoreType.PKCS12.name());
+        Assert.assertEquals(BouncyCastleProvider.PROVIDER_NAME, keyStoreProvider);
+    }
+}