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 <greyp@apache.org>
This commit is contained in:
exceptionfactory 2022-03-31 19:06:23 -05:00 committed by Paul Grey
parent a4087f32bb
commit f57facdbcf
No known key found for this signature in database
GPG Key ID: 8DDF32B9C7EE39D0
7 changed files with 166 additions and 32 deletions

View File

@ -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();
}
}

View File

@ -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;
}
}
}

View File

@ -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=

View File

@ -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=

View File

@ -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=