You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by gr...@apache.org on 2022/04/01 20:11:04 UTC

[nifi] branch main updated: NIFI-9858 Refactored nifi-system-test-suite using generated certificates

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

greyp 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 f57facd  NIFI-9858 Refactored nifi-system-test-suite using generated certificates
f57facd is described below

commit f57facdbcf53ae44a52c0b67e442caebf17c64eb
Author: exceptionfactory <ex...@apache.org>
AuthorDate: Thu Mar 31 19:06:23 2022 -0500

    NIFI-9858 Refactored nifi-system-test-suite using generated certificates
    
    - Added NiFiSystemKeyStoreProvider for configuration of Key Pair and self-signed Certificate
    - Updated standalone and clustered instance configuration properties
    - Removed expiring keystore.jks and truststore.jks
    
    This closes #5922
    Signed-off-by: Paul Grey <gr...@apache.org>
---
 .../tests/system/NiFiSystemKeyStoreProvider.java   | 143 +++++++++++++++++++++
 .../SpawnedStandaloneNiFiInstanceFactory.java      |  13 +-
 .../resources/conf/clustered/node1/nifi.properties |  14 +-
 .../resources/conf/clustered/node2/nifi.properties |  14 +-
 .../test/resources/conf/default/nifi.properties    |  14 +-
 .../src/test/resources/keystore.jks                | Bin 3095 -> 0 bytes
 .../src/test/resources/truststore.jks              | Bin 911 -> 0 bytes
 7 files changed, 166 insertions(+), 32 deletions(-)

diff --git a/nifi-system-tests/nifi-system-test-suite/src/test/java/org/apache/nifi/tests/system/NiFiSystemKeyStoreProvider.java b/nifi-system-tests/nifi-system-test-suite/src/test/java/org/apache/nifi/tests/system/NiFiSystemKeyStoreProvider.java
new file mode 100644
index 0000000..2a80103
--- /dev/null
+++ b/nifi-system-tests/nifi-system-test-suite/src/test/java/org/apache/nifi/tests/system/NiFiSystemKeyStoreProvider.java
@@ -0,0 +1,143 @@
+/*
+ * 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.tests.system;
+
+import org.apache.nifi.security.util.CertificateUtils;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.UncheckedIOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.KeyStore;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.cert.X509Certificate;
+
+/**
+ * System Key Store Provider generates a Key Pair and Certificate for KeyStore and TrustStore files
+ */
+public class NiFiSystemKeyStoreProvider {
+    private static final String HOSTNAME = "localhost";
+
+    private static final String[] DNS_NAMES = new String[]{HOSTNAME};
+
+    private static final String DISTINGUISHED_NAME = String.format("CN=%s", HOSTNAME);
+
+    private static final String PASSWORD = NiFiSystemKeyStoreProvider.class.getSimpleName();
+
+    private static final int VALID_DURATION_DAYS = 1;
+
+    private static final String KEY_ALGORITHM = "RSA";
+
+    private static final int KEY_SIZE = 4096;
+
+    private static final String SIGNING_ALGORITHM = "SHA256withRSA";
+
+    private static final String KEYSTORE_FILE = "keystore.p12";
+
+    private static final String TRUSTSTORE_FILE = "truststore.p12";
+
+    private static final String KEYSTORE_TYPE = "PKCS12";
+
+    private static Path persistentKeyStorePath;
+
+    private static Path persistentTrustStorePath;
+
+    /**
+     * Configure KeyStores in provided directory and reuse existing files after initial generation
+     *
+     * @param keyStoreDirectory Directory where KeyStore and TrustStore should be stored
+     */
+    public synchronized static void configureKeyStores(final File keyStoreDirectory) {
+        if (persistentKeyStorePath == null) {
+            createKeyStores();
+        }
+
+        if (persistentKeyStorePath == null) {
+            throw new IllegalStateException("KeyStore not provisioned");
+        }
+        if (persistentTrustStorePath == null) {
+            throw new IllegalStateException("TrustStore not provisioned");
+        }
+
+        try {
+            Files.copy(persistentKeyStorePath, Paths.get(keyStoreDirectory.getAbsolutePath(), KEYSTORE_FILE));
+            Files.copy(persistentTrustStorePath, Paths.get(keyStoreDirectory.getAbsolutePath(), TRUSTSTORE_FILE));
+        } catch (final IOException e) {
+            throw new UncheckedIOException("KeyStore configuration failed", e);
+        }
+    }
+
+    private static void createKeyStores() {
+        try {
+            final KeyPair keyPair = getKeyPair();
+            final X509Certificate certificate = CertificateUtils.generateSelfSignedX509Certificate(
+                    keyPair,
+                    DISTINGUISHED_NAME,
+                    SIGNING_ALGORITHM,
+                    VALID_DURATION_DAYS,
+                    DNS_NAMES
+            );
+
+            persistentTrustStorePath = writeTrustStore(certificate);
+            persistentTrustStorePath.toFile().deleteOnExit();
+
+            persistentKeyStorePath = writeKeyStore(certificate, keyPair.getPrivate());
+            persistentKeyStorePath.toFile().deleteOnExit();
+        } catch (final Exception e) {
+            throw new RuntimeException("KeyStore Creation Failed", e);
+        }
+    }
+
+    private static Path writeKeyStore(final X509Certificate certificate, final PrivateKey privateKey) throws Exception {
+        final KeyStore keyStore = KeyStore.getInstance(KEYSTORE_TYPE);
+        keyStore.load(null);
+
+        final X509Certificate[] certificates = new X509Certificate[]{certificate};
+        keyStore.setKeyEntry(HOSTNAME, privateKey, PASSWORD.toCharArray(), certificates);
+
+        final Path keyStorePath = Files.createTempFile(KEYSTORE_FILE, KEYSTORE_TYPE);
+        try (final OutputStream outputStream = new FileOutputStream(keyStorePath.toFile())) {
+            keyStore.store(outputStream, PASSWORD.toCharArray());
+        }
+        return keyStorePath;
+    }
+
+    private static Path writeTrustStore(final X509Certificate certificate) throws Exception {
+        final KeyStore trustStore = KeyStore.getInstance(KEYSTORE_TYPE);
+        trustStore.load(null);
+        trustStore.setCertificateEntry(HOSTNAME, certificate);
+
+        final Path trustStorePath = Files.createTempFile(TRUSTSTORE_FILE, KEYSTORE_TYPE);
+        try (final OutputStream outputStream = new FileOutputStream(trustStorePath.toFile())) {
+            trustStore.store(outputStream, PASSWORD.toCharArray());
+        }
+        return trustStorePath;
+    }
+
+    private static KeyPair getKeyPair() throws NoSuchAlgorithmException {
+        final KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM);
+        keyPairGenerator.initialize(KEY_SIZE);
+        return keyPairGenerator.generateKeyPair();
+    }
+}
diff --git a/nifi-system-tests/nifi-system-test-suite/src/test/java/org/apache/nifi/tests/system/SpawnedStandaloneNiFiInstanceFactory.java b/nifi-system-tests/nifi-system-test-suite/src/test/java/org/apache/nifi/tests/system/SpawnedStandaloneNiFiInstanceFactory.java
index f14e4d3..6bb1ee4 100644
--- a/nifi-system-tests/nifi-system-test-suite/src/test/java/org/apache/nifi/tests/system/SpawnedStandaloneNiFiInstanceFactory.java
+++ b/nifi-system-tests/nifi-system-test-suite/src/test/java/org/apache/nifi/tests/system/SpawnedStandaloneNiFiInstanceFactory.java
@@ -33,7 +33,6 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.PrintWriter;
 import java.nio.file.Files;
-import java.nio.file.Paths;
 import java.util.Collections;
 import java.util.Map;
 import java.util.Properties;
@@ -127,14 +126,7 @@ public class SpawnedStandaloneNiFiInstanceFactory implements NiFiInstanceFactory
             if (!destinationCertsDir.exists()) {
                 assertTrue(destinationCertsDir.mkdirs());
             }
-
-            // Copy keystore
-            final File destinationKeystore = new File(destinationCertsDir, "keystore.jks");
-            Files.copy(Paths.get("src/test/resources/keystore.jks"), destinationKeystore.toPath());
-
-            // Copy truststore
-            final File destinationTruststore = new File(destinationCertsDir, "truststore.jks");
-            Files.copy(Paths.get("src/test/resources/truststore.jks"), destinationTruststore.toPath());
+            NiFiSystemKeyStoreProvider.configureKeyStores(destinationCertsDir);
 
             final File flowXmlGz = instanceConfiguration.getFlowXmlGz();
             if (flowXmlGz != null) {
@@ -203,9 +195,8 @@ public class SpawnedStandaloneNiFiInstanceFactory implements NiFiInstanceFactory
                     try {
                         Thread.sleep(1000L);
                     } catch (InterruptedException ex) {
+                        logger.debug("NiFi Startup sleep interrupted", ex);
                     }
-
-                    continue;
                 }
             }
         }
diff --git a/nifi-system-tests/nifi-system-test-suite/src/test/resources/conf/clustered/node1/nifi.properties b/nifi-system-tests/nifi-system-test-suite/src/test/resources/conf/clustered/node1/nifi.properties
index 7066fba..071f863 100644
--- a/nifi-system-tests/nifi-system-test-suite/src/test/resources/conf/clustered/node1/nifi.properties
+++ b/nifi-system-tests/nifi-system-test-suite/src/test/resources/conf/clustered/node1/nifi.properties
@@ -146,13 +146,13 @@ nifi.sensitive.props.key.protected=
 nifi.sensitive.props.algorithm=PBEWITHMD5AND256BITAES-CBC-OPENSSL
 nifi.sensitive.props.additional.keys=
 
-nifi.security.keystore=certs/keystore.jks
-nifi.security.keystoreType=JKS
-nifi.security.keystorePasswd=passwordpassword
-nifi.security.keyPasswd=
-nifi.security.truststore=certs/truststore.jks
-nifi.security.truststoreType=JKS
-nifi.security.truststorePasswd=passwordpassword
+nifi.security.keystore=certs/keystore.p12
+nifi.security.keystoreType=PKCS12
+nifi.security.keystorePasswd=NiFiSystemKeyStoreProvider
+nifi.security.keyPasswd=NiFiSystemKeyStoreProvider
+nifi.security.truststore=certs/truststore.p12
+nifi.security.truststoreType=PKCS12
+nifi.security.truststorePasswd=NiFiSystemKeyStoreProvider
 nifi.security.user.authorizer=managed-authorizer
 nifi.security.user.login.identity.provider=
 nifi.security.ocsp.responder.url=
diff --git a/nifi-system-tests/nifi-system-test-suite/src/test/resources/conf/clustered/node2/nifi.properties b/nifi-system-tests/nifi-system-test-suite/src/test/resources/conf/clustered/node2/nifi.properties
index 2d6f751..4420403 100644
--- a/nifi-system-tests/nifi-system-test-suite/src/test/resources/conf/clustered/node2/nifi.properties
+++ b/nifi-system-tests/nifi-system-test-suite/src/test/resources/conf/clustered/node2/nifi.properties
@@ -146,13 +146,13 @@ nifi.sensitive.props.key.protected=
 nifi.sensitive.props.algorithm=PBEWITHMD5AND256BITAES-CBC-OPENSSL
 nifi.sensitive.props.additional.keys=
 
-nifi.security.keystore=certs/keystore.jks
-nifi.security.keystoreType=JKS
-nifi.security.keystorePasswd=passwordpassword
-nifi.security.keyPasswd=
-nifi.security.truststore=certs/truststore.jks
-nifi.security.truststoreType=JKS
-nifi.security.truststorePasswd=passwordpassword
+nifi.security.keystore=certs/keystore.p12
+nifi.security.keystoreType=PKCS12
+nifi.security.keystorePasswd=NiFiSystemKeyStoreProvider
+nifi.security.keyPasswd=NiFiSystemKeyStoreProvider
+nifi.security.truststore=certs/truststore.p12
+nifi.security.truststoreType=PKCS12
+nifi.security.truststorePasswd=NiFiSystemKeyStoreProvider
 nifi.security.user.authorizer=managed-authorizer
 nifi.security.user.login.identity.provider=
 nifi.security.ocsp.responder.url=
diff --git a/nifi-system-tests/nifi-system-test-suite/src/test/resources/conf/default/nifi.properties b/nifi-system-tests/nifi-system-test-suite/src/test/resources/conf/default/nifi.properties
index e9c0035..27ad177 100644
--- a/nifi-system-tests/nifi-system-test-suite/src/test/resources/conf/default/nifi.properties
+++ b/nifi-system-tests/nifi-system-test-suite/src/test/resources/conf/default/nifi.properties
@@ -147,13 +147,13 @@ nifi.sensitive.props.key.protected=
 nifi.sensitive.props.algorithm=PBEWITHMD5AND256BITAES-CBC-OPENSSL
 nifi.sensitive.props.additional.keys=
 
-nifi.security.keystore=certs/keystore.jks
-nifi.security.keystoreType=JKS
-nifi.security.keystorePasswd=passwordpassword
-nifi.security.keyPasswd=
-nifi.security.truststore=certs/truststore.jks
-nifi.security.truststoreType=JKS
-nifi.security.truststorePasswd=passwordpassword
+nifi.security.keystore=certs/keystore.p12
+nifi.security.keystoreType=PKCS12
+nifi.security.keystorePasswd=NiFiSystemKeyStoreProvider
+nifi.security.keyPasswd=NiFiSystemKeyStoreProvider
+nifi.security.truststore=certs/truststore.p12
+nifi.security.truststoreType=PKCS12
+nifi.security.truststorePasswd=NiFiSystemKeyStoreProvider
 nifi.security.user.authorizer=managed-authorizer
 nifi.security.user.login.identity.provider=
 nifi.security.ocsp.responder.url=
diff --git a/nifi-system-tests/nifi-system-test-suite/src/test/resources/keystore.jks b/nifi-system-tests/nifi-system-test-suite/src/test/resources/keystore.jks
deleted file mode 100644
index 34a197f..0000000
Binary files a/nifi-system-tests/nifi-system-test-suite/src/test/resources/keystore.jks and /dev/null differ
diff --git a/nifi-system-tests/nifi-system-test-suite/src/test/resources/truststore.jks b/nifi-system-tests/nifi-system-test-suite/src/test/resources/truststore.jks
deleted file mode 100644
index 4bc1b20..0000000
Binary files a/nifi-system-tests/nifi-system-test-suite/src/test/resources/truststore.jks and /dev/null differ