diff --git a/nifi-bootstrap/src/test/java/org/apache/nifi/bootstrap/http/HttpNotificationServiceTest.java b/nifi-bootstrap/src/test/java/org/apache/nifi/bootstrap/http/HttpNotificationServiceTest.java index fa1108e965..27cbd737d8 100644 --- a/nifi-bootstrap/src/test/java/org/apache/nifi/bootstrap/http/HttpNotificationServiceTest.java +++ b/nifi-bootstrap/src/test/java/org/apache/nifi/bootstrap/http/HttpNotificationServiceTest.java @@ -28,8 +28,8 @@ import org.apache.nifi.bootstrap.notification.NotificationType; import org.apache.nifi.bootstrap.notification.http.HttpNotificationService; import org.apache.nifi.components.PropertyDescriptor; import org.apache.nifi.components.PropertyValue; -import org.apache.nifi.security.util.KeyStoreUtils; import org.apache.nifi.security.util.SslContextFactory; +import org.apache.nifi.security.util.TemporaryKeyStoreBuilder; import org.apache.nifi.security.util.TlsConfiguration; import org.junit.After; import org.junit.Before; @@ -38,8 +38,6 @@ import org.junit.Test; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; import java.security.GeneralSecurityException; import java.util.HashMap; import java.util.Map; @@ -133,34 +131,29 @@ public class HttpNotificationServiceTest { } @Test - public void testStartNotificationHttps() throws GeneralSecurityException, NotificationFailedException, InterruptedException, IOException { - final TlsConfiguration tlsConfiguration = KeyStoreUtils.createTlsConfigAndNewKeystoreTruststore(); + public void testStartNotificationHttps() throws GeneralSecurityException, NotificationFailedException, InterruptedException { + final TlsConfiguration tlsConfiguration = new TemporaryKeyStoreBuilder().build(); - try { - final SSLContext sslContext = SslContextFactory.createSslContext(tlsConfiguration); - final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory(); - mockWebServer.useHttps(sslSocketFactory, false); + final SSLContext sslContext = SslContextFactory.createSslContext(tlsConfiguration); + final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory(); + mockWebServer.useHttps(sslSocketFactory, false); - enqueueResponseCode(200); + enqueueResponseCode(200); - final Map properties = getProperties(); + final Map properties = getProperties(); - properties.put(PROP_KEYSTORE, createPropertyValue(tlsConfiguration.getKeystorePath())); - properties.put(PROP_KEYSTORE_PASSWORD, createPropertyValue(tlsConfiguration.getKeystorePassword())); - properties.put(PROP_KEY_PASSWORD, createPropertyValue(tlsConfiguration.getKeyPassword())); - properties.put(PROP_KEYSTORE_TYPE, createPropertyValue(tlsConfiguration.getKeystoreType().getType())); - properties.put(PROP_TRUSTSTORE, createPropertyValue(tlsConfiguration.getTruststorePath())); - properties.put(PROP_TRUSTSTORE_PASSWORD, createPropertyValue(tlsConfiguration.getTruststorePassword())); - properties.put(PROP_TRUSTSTORE_TYPE, createPropertyValue(tlsConfiguration.getTruststoreType().getType())); + properties.put(PROP_KEYSTORE, createPropertyValue(tlsConfiguration.getKeystorePath())); + properties.put(PROP_KEYSTORE_PASSWORD, createPropertyValue(tlsConfiguration.getKeystorePassword())); + properties.put(PROP_KEY_PASSWORD, createPropertyValue(tlsConfiguration.getKeyPassword())); + properties.put(PROP_KEYSTORE_TYPE, createPropertyValue(tlsConfiguration.getKeystoreType().getType())); + properties.put(PROP_TRUSTSTORE, createPropertyValue(tlsConfiguration.getTruststorePath())); + properties.put(PROP_TRUSTSTORE_PASSWORD, createPropertyValue(tlsConfiguration.getTruststorePassword())); + properties.put(PROP_TRUSTSTORE_TYPE, createPropertyValue(tlsConfiguration.getTruststoreType().getType())); - final HttpNotificationService service = getHttpNotificationService(properties); - service.notify(getNotificationContext(), NotificationType.NIFI_STARTED, SUBJECT, MESSAGE); + final HttpNotificationService service = getHttpNotificationService(properties); + service.notify(getNotificationContext(), NotificationType.NIFI_STARTED, SUBJECT, MESSAGE); - assertRequestMatches(NotificationType.NIFI_STARTED); - } finally { - Files.deleteIfExists(Paths.get(tlsConfiguration.getKeystorePath())); - Files.deleteIfExists(Paths.get(tlsConfiguration.getTruststorePath())); - } + assertRequestMatches(NotificationType.NIFI_STARTED); } private void assertRequestMatches(final NotificationType notificationType) throws InterruptedException { diff --git a/nifi-bootstrap/src/test/java/org/apache/nifi/bootstrap/util/TestSecureNiFiConfigUtil.java b/nifi-bootstrap/src/test/java/org/apache/nifi/bootstrap/util/TestSecureNiFiConfigUtil.java index c11c293a2b..82cfdd3ec9 100644 --- a/nifi-bootstrap/src/test/java/org/apache/nifi/bootstrap/util/TestSecureNiFiConfigUtil.java +++ b/nifi-bootstrap/src/test/java/org/apache/nifi/bootstrap/util/TestSecureNiFiConfigUtil.java @@ -19,7 +19,7 @@ package org.apache.nifi.bootstrap.util; import org.apache.commons.codec.digest.DigestUtils; import org.apache.nifi.properties.NiFiPropertiesLoader; import org.apache.nifi.security.util.KeyStoreUtils; -import org.apache.nifi.security.util.StandardTlsConfiguration; +import org.apache.nifi.security.util.TemporaryKeyStoreBuilder; import org.apache.nifi.security.util.TlsConfiguration; import org.apache.nifi.util.NiFiProperties; import org.apache.nifi.util.StringUtils; @@ -52,7 +52,7 @@ import java.util.Set; public class TestSecureNiFiConfigUtil { public static final String TEST_RESOURCE_DIR = "src/test/resources/"; - private Logger logger = LoggerFactory.getLogger("org.apache.nifi.bootstrap.util.TestSecureNiFiConfigUtil"); + private final Logger logger = LoggerFactory.getLogger("org.apache.nifi.bootstrap.util.TestSecureNiFiConfigUtil"); private static final String PROPERTIES_PREFIX = "nifi-properties"; private static final boolean EXPECT_STORES_TO_EXIST = true; @@ -60,8 +60,8 @@ public class TestSecureNiFiConfigUtil { private Path nifiPropertiesFile; private Path keystorePath; private Path truststorePath; - private Path existingKeystorePath = getTestFilePath("existing-keystore.p12"); - private Path existingTruststorePath = getTestFilePath("existing-truststore.p12"); + private final Path existingKeystorePath = getTestFilePath("existing-keystore.p12"); + private final Path existingTruststorePath = getTestFilePath("existing-truststore.p12"); private NiFiProperties configureSecureNiFiProperties(Path testPropertiesFile) throws IOException { Files.copy(testPropertiesFile, nifiPropertiesFile, StandardCopyOption.REPLACE_EXISTING); @@ -87,9 +87,9 @@ public class TestSecureNiFiConfigUtil { } @Before - public void init() throws IOException, GeneralSecurityException { + public void init() throws IOException { nifiPropertiesFile = Files.createTempFile(PROPERTIES_PREFIX, ".properties"); - TlsConfiguration tlsConfig = KeyStoreUtils.createTlsConfigAndNewKeystoreTruststore(new StandardTlsConfiguration()); + TlsConfiguration tlsConfig = new TemporaryKeyStoreBuilder().build(); Files.move(Paths.get(tlsConfig.getKeystorePath()), existingKeystorePath, StandardCopyOption.REPLACE_EXISTING); Files.move(Paths.get(tlsConfig.getTruststorePath()), existingTruststorePath, StandardCopyOption.REPLACE_EXISTING); } @@ -159,12 +159,12 @@ public class TestSecureNiFiConfigUtil { } } - private void runTestWithNoExpectedUpdates(String testPropertiesFile, boolean expectBothStoresToExist) throws IOException, GeneralSecurityException { + private void runTestWithNoExpectedUpdates(String testPropertiesFile, boolean expectBothStoresToExist) throws IOException { this.runTestWithNoExpectedUpdates(testPropertiesFile, expectBothStoresToExist, expectBothStoresToExist); } private void runTestWithNoExpectedUpdates(String testPropertiesFile, boolean expectKeystoreToExist, boolean expectTruststoreToExist) - throws IOException, GeneralSecurityException { + throws IOException { Path testPropertiesFilePath = getPathFromClasspath(testPropertiesFile); NiFiProperties niFiProperties = this.configureSecureNiFiProperties(testPropertiesFilePath); keystorePath = Paths.get(niFiProperties.getProperty(NiFiProperties.SECURITY_KEYSTORE)); @@ -179,52 +179,52 @@ public class TestSecureNiFiConfigUtil { @Test public void testSuccessfulConfiguration() throws IOException, GeneralSecurityException { - runTestWithExpectedSuccess("nifi.properties.success", Collections.EMPTY_LIST); + runTestWithExpectedSuccess("nifi.properties.success", Collections.emptyList()); } @Test public void testSuccessfulDNSSANs() throws IOException, GeneralSecurityException { runTestWithExpectedSuccess("nifi.properties.dns-sans", - Arrays.asList(new String[] {"test-host", "remote-host", "proxy-host", "cluster-host"})); + Arrays.asList("test-host", "remote-host", "proxy-host", "cluster-host")); } @Test - public void testNoHttps() throws IOException, GeneralSecurityException { + public void testNoHttps() throws IOException { runTestWithNoExpectedUpdates("nifi.properties.no-https", !EXPECT_STORES_TO_EXIST); } @Test - public void testNoKeystores() throws IOException, GeneralSecurityException { + public void testNoKeystores() throws IOException { runTestWithNoExpectedUpdates("nifi.properties.no-keystores", !EXPECT_STORES_TO_EXIST); } @Test - public void testTruststorePasswordSet() throws IOException, GeneralSecurityException { + public void testTruststorePasswordSet() throws IOException { runTestWithNoExpectedUpdates("nifi.properties.truststore-password", !EXPECT_STORES_TO_EXIST); } @Test - public void testKeystorePasswordSet() throws IOException, GeneralSecurityException { + public void testKeystorePasswordSet() throws IOException { runTestWithNoExpectedUpdates("nifi.properties.keystore-password", !EXPECT_STORES_TO_EXIST); } @Test - public void test_keystoreAndTruststoreAlreadyExist() throws IOException, GeneralSecurityException { + public void test_keystoreAndTruststoreAlreadyExist() throws IOException { runTestWithNoExpectedUpdates("nifi.properties.stores-exist", EXPECT_STORES_TO_EXIST); } @Test public void testNoKeystoresTypes() throws IOException, GeneralSecurityException { - runTestWithExpectedSuccess("nifi.properties.no-keystore-types", Collections.EMPTY_LIST); + runTestWithExpectedSuccess("nifi.properties.no-keystore-types", Collections.emptyList()); } @Test - public void testFailure_onlyTruststoreExists() throws IOException, GeneralSecurityException { + public void testFailure_onlyTruststoreExists() throws IOException { runTestWithNoExpectedUpdates("nifi.properties.only-truststore", !EXPECT_STORES_TO_EXIST, EXPECT_STORES_TO_EXIST); } @Test - public void testFailure_onlyKeystoreExists() throws IOException, GeneralSecurityException { + public void testFailure_onlyKeystoreExists() throws IOException { runTestWithNoExpectedUpdates("nifi.properties.only-keystore", EXPECT_STORES_TO_EXIST, !EXPECT_STORES_TO_EXIST); } } diff --git a/nifi-commons/nifi-security-socket-ssl/src/test/java/org/apache/nifi/remote/io/socket/ssl/SSLSocketChannelTest.java b/nifi-commons/nifi-security-socket-ssl/src/test/java/org/apache/nifi/remote/io/socket/ssl/SSLSocketChannelTest.java index aa9dde595f..d770dd972d 100644 --- a/nifi-commons/nifi-security-socket-ssl/src/test/java/org/apache/nifi/remote/io/socket/ssl/SSLSocketChannelTest.java +++ b/nifi-commons/nifi-security-socket-ssl/src/test/java/org/apache/nifi/remote/io/socket/ssl/SSLSocketChannelTest.java @@ -34,8 +34,8 @@ import io.netty.handler.codec.string.StringDecoder; import io.netty.handler.codec.string.StringEncoder; import io.netty.handler.ssl.SslHandler; import org.apache.nifi.remote.io.socket.NetworkUtils; -import org.apache.nifi.security.util.KeyStoreUtils; import org.apache.nifi.security.util.SslContextFactory; +import org.apache.nifi.security.util.TemporaryKeyStoreBuilder; import org.apache.nifi.security.util.TlsConfiguration; import org.apache.nifi.security.util.TlsPlatform; import org.junit.Assume; @@ -45,7 +45,6 @@ import org.junit.Test; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLException; -import java.io.File; import java.io.IOException; import java.io.UncheckedIOException; import java.net.InetSocketAddress; @@ -101,10 +100,8 @@ public class SSLSocketChannelTest { private static SSLContext sslContext; @BeforeClass - public static void setConfiguration() throws GeneralSecurityException, IOException { - final TlsConfiguration tlsConfiguration = KeyStoreUtils.createTlsConfigAndNewKeystoreTruststore(); - new File(tlsConfiguration.getKeystorePath()).deleteOnExit(); - new File(tlsConfiguration.getTruststorePath()).deleteOnExit(); + public static void setConfiguration() throws GeneralSecurityException { + final TlsConfiguration tlsConfiguration = new TemporaryKeyStoreBuilder().build(); sslContext = SslContextFactory.createSslContext(tlsConfiguration); } diff --git a/nifi-commons/nifi-security-utils/pom.xml b/nifi-commons/nifi-security-utils/pom.xml index 5f70115547..6e61d7ddb2 100644 --- a/nifi-commons/nifi-security-utils/pom.xml +++ b/nifi-commons/nifi-security-utils/pom.xml @@ -47,15 +47,10 @@ nifi-security-kms 1.15.0-SNAPSHOT - - ch.qos.logback - logback-classic - provided - org.apache.commons commons-lang3 - 3.9 + 3.12.0 commons-codec @@ -80,18 +75,6 @@ bcrypt 0.9.0 - - - org.apache.hadoop - hadoop-minikdc - 3.1.0 - test - - - org.spockframework - spock-core - test - org.apache.commons commons-configuration2 diff --git a/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/configuration/KeyStoreConfiguration.java b/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/configuration/KeyStoreConfiguration.java new file mode 100644 index 0000000000..46f63fa49f --- /dev/null +++ b/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/configuration/KeyStoreConfiguration.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.security.configuration; + +import java.util.Objects; + +/** + * KeyStore Configuration properties + */ +public class KeyStoreConfiguration { + private final String location; + + private final String password; + + private final String keyStoreType; + + public KeyStoreConfiguration(final String location, final String password, final String keyStoreType) { + this.location = Objects.requireNonNull(location, "Location required"); + this.password = Objects.requireNonNull(password, "Password required"); + this.keyStoreType = Objects.requireNonNull(keyStoreType, "KeyStore Type required"); + } + + public String getLocation() { + return location; + } + + public String getPassword() { + return password; + } + + public String getKeyStoreType() { + return keyStoreType; + } +} diff --git a/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/util/KeyStoreUtils.java b/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/util/KeyStoreUtils.java index 278265b819..4def6e2f94 100644 --- a/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/util/KeyStoreUtils.java +++ b/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/util/KeyStoreUtils.java @@ -190,26 +190,6 @@ public class KeyStoreUtils { } } - /** - * Creates a temporary default Keystore and Truststore and returns it wrapped in a TLS configuration. - * - * @return a {@link org.apache.nifi.security.util.TlsConfiguration} - */ - public static TlsConfiguration createTlsConfigAndNewKeystoreTruststore() throws IOException, GeneralSecurityException { - return createTlsConfigAndNewKeystoreTruststore(new StandardTlsConfiguration()); - } - - /** - * Creates a temporary Keystore and Truststore and returns it wrapped in a new TLS configuration with the given values. - * Specifies an expiration duration of 365 days. - * - * @param tlsConfiguration a {@link org.apache.nifi.security.util.TlsConfiguration} - * @return a {@link org.apache.nifi.security.util.TlsConfiguration} - */ - public static TlsConfiguration createTlsConfigAndNewKeystoreTruststore(final TlsConfiguration tlsConfiguration) throws IOException, GeneralSecurityException { - return createTlsConfigAndNewKeystoreTruststore(tlsConfiguration, CERT_DURATION_DAYS, null); - } - /** * Creates a temporary Keystore and Truststore and returns it wrapped in a new TLS configuration with the given values. * diff --git a/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/util/SslContextFactory.java b/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/util/SslContextFactory.java index de81f14a56..5e4fa145da 100644 --- a/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/util/SslContextFactory.java +++ b/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/util/SslContextFactory.java @@ -20,6 +20,7 @@ import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.util.Arrays; +import java.util.Objects; import java.util.Optional; import javax.net.ssl.KeyManager; import javax.net.ssl.KeyManagerFactory; @@ -138,7 +139,6 @@ public final class SslContextFactory { * @return an array of KeyManagers (can be {@code null}) * @throws TlsException if there is a problem reading the keystore to create the key managers */ - @SuppressWarnings("RedundantCast") protected static KeyManager[] getKeyManagers(TlsConfiguration tlsConfiguration) throws TlsException { KeyManager[] keyManagers = null; if (tlsConfiguration.isKeystoreValid()) { @@ -168,8 +168,8 @@ public final class SslContextFactory { * @return the loaded trust managers * @throws TlsException if there is a problem reading from the truststore */ - @SuppressWarnings("RedundantCast") - public static TrustManager[] getTrustManagers(TlsConfiguration tlsConfiguration) throws TlsException { + public static TrustManager[] getTrustManagers(final TlsConfiguration tlsConfiguration) throws TlsException { + Objects.requireNonNull(tlsConfiguration, "TLS Configuration required"); TrustManager[] trustManagers = null; if (tlsConfiguration.isTruststoreValid()) { TrustManagerFactory trustManagerFactory = KeyStoreUtils.loadTrustManagerFactory(tlsConfiguration); @@ -193,7 +193,7 @@ public final class SslContextFactory { sslContext.init(keyManagers, trustManagers, new SecureRandom()); return sslContext; } catch (final NoSuchAlgorithmException | KeyManagementException e) { - logger.error("Encountered an error creating SSLContext from TLS configuration ({}): {}", tlsConfiguration.toString(), e.getLocalizedMessage()); + logger.error("Encountered an error creating SSLContext from TLS configuration ({}): {}", tlsConfiguration, e.getLocalizedMessage()); throw new TlsException("Error creating SSL context", e); } } diff --git a/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/util/TemporaryKeyStoreBuilder.java b/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/util/TemporaryKeyStoreBuilder.java new file mode 100644 index 0000000000..ebf7c3643b --- /dev/null +++ b/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/util/TemporaryKeyStoreBuilder.java @@ -0,0 +1,206 @@ +/* + * 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.security.util; + +import org.apache.nifi.security.configuration.KeyStoreConfiguration; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.SecureRandom; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.Base64; +import java.util.Objects; +import java.util.UUID; + +/** + * KeyStore Factory for creating temporary files primarily used for testing + */ +public class TemporaryKeyStoreBuilder { + private static final String KEY_PAIR_ALGORITHM = "RSA"; + + private static final int KEY_SIZE = 2048; + + private static final int RANDOM_BYTES_LENGTH = 16; + + private static final Base64.Encoder ENCODER = Base64.getEncoder().withoutPadding(); + + private static final String SIGNING_ALGORITHM = "SHA256withRSA"; + + private static final String DISTINGUISHED_NAME_FORMAT = "CN=%s"; + + private static final int CERTIFICATE_VALID_DAYS = 1; + + private static final KeystoreType KEYSTORE_TYPE = KeystoreType.PKCS12; + + private static final String KEY_STORE_EXTENSION = ".p12"; + + private static final String KEY_STORE_PREFIX = "TemporaryKeyStore-"; + + private static final String DEFAULT_HOSTNAME = "localhost"; + + private String hostname = DEFAULT_HOSTNAME; + + private String trustStorePassword = generateSecureRandomPassword(); + + private String trustStoreType = KEYSTORE_TYPE.getType(); + + /** + * Set Hostname used for Certificate Common Name and DNS Subject Alternative Names + * + * @param hostname Hostname is required + * @return Builder + */ + public TemporaryKeyStoreBuilder hostname(final String hostname) { + this.hostname = Objects.requireNonNull(hostname, "Hostname required"); + return this; + } + + /** + * Set Trust Store Password used for protected generated Trust Store file + * + * @param trustStorePassword Trust Store Password is required + * @return Builder + */ + public TemporaryKeyStoreBuilder trustStorePassword(final String trustStorePassword) { + this.trustStorePassword = Objects.requireNonNull(trustStorePassword, "TrustStore Password required"); + return this; + } + + /** + * Set Trust Store Type used for storing Trust Store files + * + * @param trustStoreType Trust Store type must be a supported value for KeyStore.getInstance() + * @return Builder + */ + public TemporaryKeyStoreBuilder trustStoreType(final String trustStoreType) { + this.trustStoreType = Objects.requireNonNull(trustStoreType, "TrustStore Type required"); + return this; + } + + /** + * Build Temporary KeyStore and TrustStore with configured values and set files with File.deleteOnExit() + * + * @return TLS Configuration with KeyStore and TrustStore properties + */ + public TlsConfiguration build() { + final KeyPair keyPair = generateKeyPair(); + final X509Certificate certificate = generateCertificate(hostname, keyPair); + + final KeyStoreConfiguration keyStoreConfiguration = setKeyStore(keyPair.getPrivate(), certificate); + final KeyStoreConfiguration trustStoreConfiguration = setTrustStore(certificate); + + return new StandardTlsConfiguration( + keyStoreConfiguration.getLocation(), + keyStoreConfiguration.getPassword(), + keyStoreConfiguration.getPassword(), + keyStoreConfiguration.getKeyStoreType(), + trustStoreConfiguration.getLocation(), + trustStoreConfiguration.getPassword(), + trustStoreConfiguration.getKeyStoreType(), + TlsPlatform.getLatestProtocol() + ); + } + + private KeyStoreConfiguration setKeyStore(final PrivateKey privateKey, final X509Certificate certificate) { + final KeyStore keyStore = getNewKeyStore(KEYSTORE_TYPE.getType()); + + final String password = generateSecureRandomPassword(); + final String alias = UUID.randomUUID().toString(); + try { + keyStore.setKeyEntry(alias, privateKey, password.toCharArray(), new Certificate[]{certificate}); + } catch (final KeyStoreException e) { + throw new RuntimeException("Set Key Entry Failed", e); + } + + final File keyStoreFile = storeKeyStore(keyStore, password.toCharArray()); + return new KeyStoreConfiguration(keyStoreFile.getAbsolutePath(), password, KEYSTORE_TYPE.getType()); + } + + private KeyStoreConfiguration setTrustStore(final X509Certificate certificate) { + final KeyStore keyStore = getNewKeyStore(trustStoreType); + + final String alias = UUID.randomUUID().toString(); + try { + keyStore.setCertificateEntry(alias, certificate); + } catch (final KeyStoreException e) { + throw new RuntimeException("Set Certificate Entry Failed", e); + } + + final File trustStoreFile = storeKeyStore(keyStore, trustStorePassword.toCharArray()); + return new KeyStoreConfiguration(trustStoreFile.getAbsolutePath(), trustStorePassword, trustStoreType); + } + + private File storeKeyStore(final KeyStore keyStore, final char[] password) { + try { + final File keyStoreFile = File.createTempFile(KEY_STORE_PREFIX, KEY_STORE_EXTENSION); + keyStoreFile.deleteOnExit(); + try (final OutputStream outputStream = new FileOutputStream(keyStoreFile)) { + keyStore.store(outputStream, password); + } + return keyStoreFile; + } catch (final IOException | KeyStoreException | NoSuchAlgorithmException | CertificateException e) { + throw new RuntimeException("Store KeyStore Failed", e); + } + } + + private KeyStore getNewKeyStore(final String newKeyStoreType) { + try { + final KeyStore keyStore = KeyStoreUtils.getKeyStore(newKeyStoreType); + keyStore.load(null); + return keyStore; + } catch (final KeyStoreException | IOException | NoSuchAlgorithmException | CertificateException e) { + throw new RuntimeException(String.format("Create KeyStore [%s] Failed", KEYSTORE_TYPE), e); + } + } + + private X509Certificate generateCertificate(final String hostname, final KeyPair keyPair) { + final String distinguishedName = String.format(DISTINGUISHED_NAME_FORMAT, hostname); + final String[] dnsNames = new String[] {hostname}; + try { + return CertificateUtils.generateSelfSignedX509Certificate(keyPair, distinguishedName, SIGNING_ALGORITHM, CERTIFICATE_VALID_DAYS, dnsNames); + } catch (final CertificateException e) { + throw new RuntimeException("Certificate Generated Failed", e); + } + } + + private KeyPair generateKeyPair() { + try { + final KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_PAIR_ALGORITHM); + keyPairGenerator.initialize(KEY_SIZE); + return keyPairGenerator.generateKeyPair(); + } catch (final NoSuchAlgorithmException e) { + throw new IllegalArgumentException(String.format("[%s] Algorithm not found", KEY_PAIR_ALGORITHM), e); + } + } + + private String generateSecureRandomPassword() { + final SecureRandom secureRandom = new SecureRandom(); + final byte[] randomBytes = new byte[RANDOM_BYTES_LENGTH]; + secureRandom.nextBytes(randomBytes); + return ENCODER.encodeToString(randomBytes); + } +} diff --git a/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/SslContextFactoryTest.groovy b/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/SslContextFactoryTest.groovy deleted file mode 100644 index 990f439c22..0000000000 --- a/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/SslContextFactoryTest.groovy +++ /dev/null @@ -1,267 +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.security.util - -import org.apache.nifi.util.NiFiProperties -import org.bouncycastle.jce.provider.BouncyCastleProvider -import org.junit.After -import org.junit.Before -import org.junit.BeforeClass -import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.JUnit4 -import org.slf4j.Logger -import org.slf4j.LoggerFactory - -import javax.net.ssl.SSLContext -import javax.net.ssl.SSLServerSocket -import java.security.Security - -@RunWith(JUnit4.class) -class SslContextFactoryTest extends GroovyTestCase { - private static final Logger logger = LoggerFactory.getLogger(SslContextFactoryTest.class) - - private static final String KEYSTORE_PATH = "src/test/resources/TlsConfigurationKeystore.jks" - private static final String KEYSTORE_PASSWORD = "keystorepassword" - private static final String KEY_PASSWORD = "keypassword" - private static final KeystoreType KEYSTORE_TYPE = KeystoreType.JKS - - private static final String TRUSTSTORE_PATH = "src/test/resources/TlsConfigurationTruststore.jks" - private static final String TRUSTSTORE_PASSWORD = "truststorepassword" - private static final KeystoreType TRUSTSTORE_TYPE = KeystoreType.JKS - - private static final String CONFIGURED_TLS_PROTOCOL = "TLSv1.2" - - private static final Map DEFAULT_PROPS = [ - (NiFiProperties.SECURITY_KEYSTORE) : KEYSTORE_PATH, - (NiFiProperties.SECURITY_KEYSTORE_PASSWD) : KEYSTORE_PASSWORD, - (NiFiProperties.SECURITY_KEY_PASSWD) : KEY_PASSWORD, - (NiFiProperties.SECURITY_KEYSTORE_TYPE) : KEYSTORE_TYPE.getType(), - (NiFiProperties.SECURITY_TRUSTSTORE) : TRUSTSTORE_PATH, - (NiFiProperties.SECURITY_TRUSTSTORE_PASSWD): TRUSTSTORE_PASSWORD, - (NiFiProperties.SECURITY_TRUSTSTORE_TYPE) : TRUSTSTORE_TYPE.getType(), - ] - - private NiFiProperties mockNiFiProperties = NiFiProperties.createBasicNiFiProperties("", DEFAULT_PROPS) - - private TlsConfiguration tlsConfiguration - - @BeforeClass - static void setUpOnce() throws Exception { - Security.addProvider(new BouncyCastleProvider()) - - logger.metaClass.methodMissing = { String name, args -> - logger.info("[${name?.toUpperCase()}] ${(args as List).join(" ")}") - } - } - - @Before - void setUp() { - tlsConfiguration = new StandardTlsConfiguration(KEYSTORE_PATH, KEYSTORE_PASSWORD, KEY_PASSWORD, KEYSTORE_TYPE, TRUSTSTORE_PATH, TRUSTSTORE_PASSWORD, TRUSTSTORE_TYPE) - } - - @After - void tearDown() { - - } - - /** - * Asserts that the protocol versions are correct. In recent versions of Java, this enforces order as well, but in older versions, it just enforces presence. - * - * @param enabledProtocols the actual protocols, either in {@code String[]} or {@code Collection} form - * @param expectedProtocols the specific protocol versions to be present (ordered as desired) - */ - void assertProtocolVersions(def enabledProtocols, def expectedProtocols) { - if (TlsConfiguration.getJavaVersion() > 8) { - assert enabledProtocols == expectedProtocols as String[] - } else { - assert enabledProtocols as Set == expectedProtocols as Set - } - } - - @Test - void testShouldCreateSslContextFromTlsConfiguration() { - // Arrange - logger.info("Creating SSL Context from TLS Configuration: ${tlsConfiguration}") - - // Act - SSLContext sslContext = SslContextFactory.createSslContext(tlsConfiguration) - logger.info("Created SSL Context: ${KeyStoreUtils.sslContextToString(sslContext)}") - - // Assert - assert sslContext.protocol == tlsConfiguration.protocol - - // Check a socket created from this context - assertSocketProtocols(sslContext) - } - - @Test - void testCreateSslContextFromTlsConfigurationShouldHandleEmptyKeyPassword() { - // Arrange - - // Change the keystore to one with the same keystore and key password, but don't provide the key password - Map missingKeyPasswordProps = DEFAULT_PROPS + [ - (NiFiProperties.SECURITY_KEYSTORE) : "src/test/resources/samepassword.jks", - (NiFiProperties.SECURITY_KEY_PASSWD): "", - ] - NiFiProperties propertiesWithoutKeyPassword = NiFiProperties.createBasicNiFiProperties("", missingKeyPasswordProps) - TlsConfiguration configWithoutKeyPassword = StandardTlsConfiguration.fromNiFiProperties(propertiesWithoutKeyPassword) - logger.info("Creating SSL Context from TLS Configuration: ${configWithoutKeyPassword}") - - // Act - SSLContext sslContext = SslContextFactory.createSslContext(configWithoutKeyPassword) - logger.info("Created SSL Context: ${KeyStoreUtils.sslContextToString(sslContext)}") - - // Assert - assert sslContext.protocol == configWithoutKeyPassword.protocol - - // Check a socket created from this context - assertSocketProtocols(sslContext) - } - - /** - * This test ensures that silent failures don't occur -- if some keystore/truststore properties - * are populated but not enough to be valid, throw an exception on failure. - */ - @Test - void testCreateSslContextFromTlsConfigurationShouldFailOnInvalidProperties() { - // Arrange - - // Set up configurations missing the keystore path and truststore path - Map missingKeystorePathProps = DEFAULT_PROPS + [ - (NiFiProperties.SECURITY_KEYSTORE): "", - ] - NiFiProperties propsNoKeystorePath = NiFiProperties.createBasicNiFiProperties("", missingKeystorePathProps) - TlsConfiguration configNoKeystorePath = StandardTlsConfiguration.fromNiFiProperties(propsNoKeystorePath) - logger.info("Creating SSL Context from TLS Configuration: ${configNoKeystorePath}") - - Map missingTruststorePathProps = DEFAULT_PROPS + [ - (NiFiProperties.SECURITY_TRUSTSTORE) : "", - // Remove the keystore properties to ensure the right conditional is tested - (NiFiProperties.SECURITY_KEYSTORE) : "", - (NiFiProperties.SECURITY_KEYSTORE_PASSWD): "", - (NiFiProperties.SECURITY_KEY_PASSWD) : "", - (NiFiProperties.SECURITY_KEYSTORE_TYPE) : "", - ] - NiFiProperties propsNoTruststorePath = NiFiProperties.createBasicNiFiProperties("", missingTruststorePathProps) - TlsConfiguration configNoTruststorePath = StandardTlsConfiguration.fromNiFiProperties(propsNoTruststorePath) - logger.info("Creating SSL Context from TLS Configuration: ${configNoTruststorePath}") - - // Act - def noKeystorePathMsg = shouldFail(TlsException) { - SSLContext sslContext = SslContextFactory.createSslContext(configNoKeystorePath) - logger.info("Created SSL Context missing keystore path: ${KeyStoreUtils.sslContextToString(sslContext)}") - } - - def noTruststorePathMsg = shouldFail(TlsException) { - SSLContext sslContext = SslContextFactory.createSslContext(configNoTruststorePath) - logger.info("Created SSL Context missing truststore path: ${KeyStoreUtils.sslContextToString(sslContext)}") - } - - // Assert - assert noKeystorePathMsg =~ "The keystore properties are not valid" - assert noTruststorePathMsg =~ "The truststore properties are not valid" - } - - /** - * This is a regression test to ensure that a truststore without a password is allowed (legacy truststores did not require a password). - */ - @Test - void testCreateSslContextFromTlsConfigurationShouldHandleEmptyTruststorePassword() { - // Arrange - - // Change the truststore to one with no password - Map truststoreNoPasswordProps = DEFAULT_PROPS + [ - (NiFiProperties.SECURITY_TRUSTSTORE) : "src/test/resources/no-password-truststore.jks", - (NiFiProperties.SECURITY_TRUSTSTORE_PASSWD): "", - ] - NiFiProperties propertiesNoTruststorePassword = NiFiProperties.createBasicNiFiProperties("", truststoreNoPasswordProps) - TlsConfiguration configNoTruststorePassword = StandardTlsConfiguration.fromNiFiProperties(propertiesNoTruststorePassword) - logger.info("Creating SSL Context from TLS Configuration: ${configNoTruststorePassword}") - - // Act - SSLContext sslContext = SslContextFactory.createSslContext(configNoTruststorePassword) - logger.info("Created SSL Context: ${KeyStoreUtils.sslContextToString(sslContext)}") - - // Assert - assert sslContext.protocol == configNoTruststorePassword.protocol - - // Check a socket created from this context - assertSocketProtocols(sslContext) - } - - /** - * This test is for legacy expectations in nifi-framework-core. That {@code SslContextFactory} - * implementation threw an exception if the keystore properties were present and the truststore - * properties were not. - */ - @Test - void testCreateSslContextFromTlsConfigurationShouldHandleKeystorePropsWithoutTruststoreProps() { - // Arrange - - // Change the keystore to one with the same keystore and key password, but don't provide the key password - Map keystoreOnlyProps = DEFAULT_PROPS.findAll { k, v -> k.contains("keystore") } - NiFiProperties keystoreNiFiProperties = NiFiProperties.createBasicNiFiProperties("", keystoreOnlyProps) - TlsConfiguration keystoreOnlyConfig = StandardTlsConfiguration.fromNiFiProperties(keystoreNiFiProperties) - logger.info("Creating SSL Context from TLS Configuration: ${keystoreOnlyConfig}") - - // Act - def msg = shouldFail(TlsException) { - SSLContext sslContext = SslContextFactory.createSslContext(keystoreOnlyConfig) - logger.info("Created SSL Context: ${KeyStoreUtils.sslContextToString(sslContext)}") - } - logger.expected(msg) - - // Assert - assert msg =~ "Truststore properties are required if keystore properties are present" - } - - /** - * This test is for legacy expectations in nifi-framework-core. That {@code SslContextFactory} - * implementation returned {@code null} if none of the properties were populated. - */ - @Test - void testCreateSslContextFromTlsConfigurationShouldHandleEmptyConfiguration() { - // Arrange - TlsConfiguration emptyConfig = new StandardTlsConfiguration() - logger.info("Creating SSL Context from TLS Configuration: ${emptyConfig}") - - // Act - SSLContext sslContext = SslContextFactory.createSslContext(emptyConfig) - - // Assert - assert !sslContext - } - - /** - * Asserts an {@link SSLServerSocket} from the provided {@link SSLContext} has the proper TLS protocols set. - * - * @param sslContext the context under test - */ - void assertSocketProtocols(SSLContext sslContext) { - SSLServerSocket sslSocket = sslContext.serverSocketFactory.createServerSocket() as SSLServerSocket - logger.info("Created SSL (server) socket: ${sslSocket}") - assert sslSocket.enabledProtocols.contains(CONFIGURED_TLS_PROTOCOL) - - // Override the SSL parameters protocol version - SSLServerSocket customSslSocket = sslContext.serverSocketFactory.createServerSocket() as SSLServerSocket - def customParameters = customSslSocket.getSSLParameters() - customParameters.setProtocols([CONFIGURED_TLS_PROTOCOL] as String[]) - customSslSocket.setSSLParameters(customParameters) - assertProtocolVersions(customSslSocket.enabledProtocols, [CONFIGURED_TLS_PROTOCOL]) - } -} \ No newline at end of file diff --git a/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/StandardTlsConfigurationTest.groovy b/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/StandardTlsConfigurationTest.groovy deleted file mode 100644 index aea74a2389..0000000000 --- a/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/StandardTlsConfigurationTest.groovy +++ /dev/null @@ -1,257 +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.security.util - - -import org.apache.nifi.util.NiFiProperties -import org.bouncycastle.jce.provider.BouncyCastleProvider -import org.junit.After -import org.junit.Before -import org.junit.BeforeClass -import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.JUnit4 -import org.slf4j.Logger -import org.slf4j.LoggerFactory - -import java.security.Security - -@RunWith(JUnit4.class) -class StandardTlsConfigurationTest extends GroovyTestCase { - private static final Logger logger = LoggerFactory.getLogger(StandardTlsConfigurationTest.class) - - private static final String KEYSTORE_PATH = "src/test/resources/TlsConfigurationKeystore.jks" - private static final String KEYSTORE_PASSWORD = "keystorepassword" - private static final String KEY_PASSWORD = "keypassword" - private static final KeystoreType KEYSTORE_TYPE = KeystoreType.JKS - - private static final String TRUSTSTORE_PATH = "src/test/resources/TlsConfigurationTruststore.jks" - private static final String TRUSTSTORE_PASSWORD = "truststorepassword" - private static final KeystoreType TRUSTSTORE_TYPE = KeystoreType.JKS - - private static final Map DEFAULT_PROPS = [ - (NiFiProperties.SECURITY_KEYSTORE) : KEYSTORE_PATH, - (NiFiProperties.SECURITY_KEYSTORE_PASSWD) : KEYSTORE_PASSWORD, - (NiFiProperties.SECURITY_KEY_PASSWD) : KEY_PASSWORD, - (NiFiProperties.SECURITY_KEYSTORE_TYPE) : KEYSTORE_TYPE.getType(), - (NiFiProperties.SECURITY_TRUSTSTORE) : TRUSTSTORE_PATH, - (NiFiProperties.SECURITY_TRUSTSTORE_PASSWD): TRUSTSTORE_PASSWORD, - (NiFiProperties.SECURITY_TRUSTSTORE_TYPE) : TRUSTSTORE_TYPE.getType(), - ] - - private NiFiProperties mockNiFiProperties = NiFiProperties.createBasicNiFiProperties("", DEFAULT_PROPS) - - private TlsConfiguration tlsConfiguration - - @BeforeClass - static void setUpOnce() throws Exception { - Security.addProvider(new BouncyCastleProvider()) - - logger.metaClass.methodMissing = { String name, args -> - logger.info("[${name?.toUpperCase()}] ${(args as List).join(" ")}") - } - } - - @Before - void setUp() throws Exception { - tlsConfiguration = new StandardTlsConfiguration(KEYSTORE_PATH, KEYSTORE_PASSWORD, KEY_PASSWORD, KEYSTORE_TYPE, TRUSTSTORE_PATH, TRUSTSTORE_PASSWORD, TRUSTSTORE_TYPE) - } - - @After - void tearDown() throws Exception { - } - - @Test - void testShouldCreateFromNiFiProperties() { - // Arrange - - // Act - TlsConfiguration fromProperties = StandardTlsConfiguration.fromNiFiProperties(mockNiFiProperties) - logger.info("Created TlsConfiguration: ${fromProperties}") - - // Assert - assert fromProperties == tlsConfiguration - } - - @Test - void testCreateFromNiFiPropertiesShouldHandleNullKeystoreTypes() { - // Arrange - def noKeystoreTypesProps = NiFiProperties.createBasicNiFiProperties("", DEFAULT_PROPS + - [(NiFiProperties.SECURITY_KEYSTORE_TYPE) : "", - (NiFiProperties.SECURITY_TRUSTSTORE_TYPE): "" - ]) - - // Act - TlsConfiguration fromProperties = StandardTlsConfiguration.fromNiFiProperties(noKeystoreTypesProps) - logger.info("Created TlsConfiguration: ${fromProperties}") - - // Assert - assert fromProperties.keystoreType == null - assert fromProperties.truststoreType == null - } - - @Test - void testShouldGetFunctionalKeyPassword() { - // Arrange - TlsConfiguration withKeyPassword = tlsConfiguration - - // A container where the keystore password is explicitly set as the key password as well - TlsConfiguration withoutKeyPassword = new StandardTlsConfiguration(KEYSTORE_PATH, KEYSTORE_PASSWORD, KEYSTORE_TYPE, TRUSTSTORE_PATH, TRUSTSTORE_PASSWORD, TRUSTSTORE_TYPE) - - // A container where null is explicitly set as the key password - TlsConfiguration withNullPassword = new StandardTlsConfiguration(KEYSTORE_PATH, KEYSTORE_PASSWORD, null, KEYSTORE_TYPE, TRUSTSTORE_PATH, TRUSTSTORE_PASSWORD, TRUSTSTORE_TYPE) - - // Act - String actualKeyPassword = withKeyPassword.getKeyPassword() - String functionalKeyPassword = withKeyPassword.getFunctionalKeyPassword() - - String duplicateKeystorePassword = withoutKeyPassword.getKeyPassword() - String duplicateFunctionalKeyPassword = withoutKeyPassword.getFunctionalKeyPassword() - - String missingKeyPassword = withNullPassword.getKeyPassword() - String keystorePassword = withNullPassword.getFunctionalKeyPassword() - - // Assert - assert actualKeyPassword == KEY_PASSWORD - assert functionalKeyPassword == KEY_PASSWORD - - assert duplicateKeystorePassword == KEYSTORE_PASSWORD - assert duplicateFunctionalKeyPassword == KEYSTORE_PASSWORD - - assert missingKeyPassword == null - assert keystorePassword == KEYSTORE_PASSWORD - } - - @Test - void testShouldCheckKeystorePopulation() { - // Arrange - TlsConfiguration empty = new StandardTlsConfiguration() - TlsConfiguration noKeystorePassword = new StandardTlsConfiguration(KEYSTORE_PATH, "", KEY_PASSWORD, KEYSTORE_TYPE, TRUSTSTORE_PATH, TRUSTSTORE_PASSWORD, TRUSTSTORE_TYPE) - - // Act - boolean normalIsPopulated = tlsConfiguration.isKeystorePopulated() - boolean emptyIsPopulated = empty.isKeystorePopulated() - boolean noPasswordIsPopulated = noKeystorePassword.isKeystorePopulated() - - // Assert - assert normalIsPopulated - assert !emptyIsPopulated - assert !noPasswordIsPopulated - } - - @Test - void testShouldCheckTruststorePopulation() { - // Arrange - TlsConfiguration empty = new StandardTlsConfiguration() - TlsConfiguration noTruststorePassword = new StandardTlsConfiguration(KEYSTORE_PATH, KEYSTORE_PASSWORD, KEY_PASSWORD, KEYSTORE_TYPE, TRUSTSTORE_PATH, "", TRUSTSTORE_TYPE) - - // Act - boolean normalIsPopulated = tlsConfiguration.isTruststorePopulated() - boolean emptyIsPopulated = empty.isTruststorePopulated() - boolean noPasswordIsPopulated = noTruststorePassword.isTruststorePopulated() - - // Assert - assert normalIsPopulated - assert !emptyIsPopulated - assert noPasswordIsPopulated - } - - @Test - void testIsKeystoreValidFalseNullKeystorePassword() { - TlsConfiguration configuration = new StandardTlsConfiguration(KEYSTORE_PATH, null, KEY_PASSWORD, KEYSTORE_TYPE, TRUSTSTORE_PATH, TRUSTSTORE_PASSWORD, TRUSTSTORE_TYPE) - assert !configuration.isKeystoreValid() - } - - @Test - void testShouldValidateKeystoreConfiguration() { - // Arrange - TlsConfiguration empty = new StandardTlsConfiguration() - TlsConfiguration wrongPassword = new StandardTlsConfiguration(KEYSTORE_PATH, KEYSTORE_PASSWORD.reverse(), KEY_PASSWORD.reverse(), KEYSTORE_TYPE, TRUSTSTORE_PATH, TRUSTSTORE_PASSWORD.reverse(), TRUSTSTORE_TYPE) - TlsConfiguration invalid = new StandardTlsConfiguration(KEYSTORE_PATH.reverse(), KEYSTORE_PASSWORD.reverse(), KEY_PASSWORD.reverse(), KEYSTORE_TYPE, TRUSTSTORE_PATH.reverse(), TRUSTSTORE_PASSWORD.reverse(), TRUSTSTORE_TYPE) - - // Act - boolean normalIsValid = tlsConfiguration.isKeystoreValid() - boolean emptyIsValid = empty.isKeystoreValid() - boolean wrongPasswordIsValid = wrongPassword.isKeystoreValid() - boolean invalidIsValid = invalid.isKeystoreValid() - - // Assert - assert normalIsValid - assert !emptyIsValid - assert !wrongPasswordIsValid - assert !invalidIsValid - } - - @Test - void testShouldValidateTruststoreConfiguration() { - // Arrange - TlsConfiguration empty = new StandardTlsConfiguration() - TlsConfiguration wrongPassword = new StandardTlsConfiguration(KEYSTORE_PATH, KEYSTORE_PASSWORD.reverse(), KEY_PASSWORD.reverse(), KEYSTORE_TYPE, TRUSTSTORE_PATH, TRUSTSTORE_PASSWORD.reverse(), TRUSTSTORE_TYPE) - TlsConfiguration invalid = new StandardTlsConfiguration(KEYSTORE_PATH.reverse(), KEYSTORE_PASSWORD.reverse(), KEY_PASSWORD.reverse(), KEYSTORE_TYPE, TRUSTSTORE_PATH.reverse(), TRUSTSTORE_PASSWORD.reverse(), TRUSTSTORE_TYPE) - - // Act - boolean normalIsValid = tlsConfiguration.isTruststoreValid() - boolean emptyIsValid = empty.isTruststoreValid() - boolean wrongPasswordIsValid = wrongPassword.isTruststoreValid() - boolean invalidIsValid = invalid.isTruststoreValid() - - // Assert - assert normalIsValid - assert !emptyIsValid - assert !wrongPasswordIsValid - assert !invalidIsValid - } - - @Test - void testShouldReturnLegacyAndCurrentEnabledProtocolsForSsl() { - TlsConfiguration configuration = getTlsConfiguration(TlsConfiguration.SSL_PROTOCOL) - - String[] enabledProtocols = configuration.enabledProtocols - assert enabledProtocols.toList().containsAll(TlsConfiguration.LEGACY_TLS_PROTOCOL_VERSIONS) - assert enabledProtocols.toList().containsAll(TlsConfiguration.getCurrentSupportedTlsProtocolVersions()) - } - - @Test - void testShouldReturnCurrentEnabledProtocolsForTls() { - TlsConfiguration configuration = getTlsConfiguration(TlsConfiguration.TLS_PROTOCOL) - - String[] enabledProtocols = configuration.enabledProtocols - assert !enabledProtocols.toList().containsAll(TlsConfiguration.LEGACY_TLS_PROTOCOL_VERSIONS) - assert enabledProtocols.toList().containsAll(TlsConfiguration.getCurrentSupportedTlsProtocolVersions()) - } - - @Test - void testShouldReturnConfiguredEnabledProtocols() { - String currentProtocol = TlsConfiguration.getHighestCurrentSupportedTlsProtocolVersion() - TlsConfiguration configuration = getTlsConfiguration(currentProtocol) - - String[] enabledProtocols = configuration.enabledProtocols - assert enabledProtocols == [currentProtocol] as String[] - } - - @Test - void testShouldReturnEmptyEnabledProtocolsForNullProtocol() { - TlsConfiguration configuration = getTlsConfiguration(null) - - String[] enabledProtocols = configuration.enabledProtocols - assert enabledProtocols.toList().isEmpty() - } - - TlsConfiguration getTlsConfiguration(String protocol) { - new StandardTlsConfiguration(KEYSTORE_PATH, KEYSTORE_PASSWORD, KEY_PASSWORD, KEYSTORE_TYPE, TRUSTSTORE_PATH, TRUSTSTORE_PASSWORD, TRUSTSTORE_TYPE, protocol) - } -} diff --git a/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/crypto/Argon2SecureHasherTest.groovy b/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/crypto/Argon2SecureHasherTest.groovy index c445ac0e29..7c802815ef 100644 --- a/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/crypto/Argon2SecureHasherTest.groovy +++ b/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/crypto/Argon2SecureHasherTest.groovy @@ -16,10 +16,8 @@ */ package org.apache.nifi.security.util.crypto -import org.apache.kerby.util.Hex import org.bouncycastle.jce.provider.BouncyCastleProvider -import org.junit.After -import org.junit.Before +import org.bouncycastle.util.encoders.Hex import org.junit.BeforeClass import org.junit.Ignore import org.junit.Test @@ -44,14 +42,6 @@ class Argon2SecureHasherTest extends GroovyTestCase { } } - @Before - void setUp() throws Exception { - } - - @After - void tearDown() throws Exception { - } - private static byte[] decodeHex(String hex) { Hex.decode(hex?.replaceAll("[^0-9a-fA-F]", "")) } @@ -103,7 +93,7 @@ class Argon2SecureHasherTest extends GroovyTestCase { // Act testIterations.times { int i -> byte[] hash = a2sh.hashRaw(inputBytes) - String hashHex = Hex.encode(hash) + String hashHex = new String(Hex.encode(hash)) logger.info("Generated hash: ${hashHex}") results << hashHex } diff --git a/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/crypto/BcryptSecureHasherTest.groovy b/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/crypto/BcryptSecureHasherTest.groovy index 68bd973719..b01a17be2e 100644 --- a/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/crypto/BcryptSecureHasherTest.groovy +++ b/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/crypto/BcryptSecureHasherTest.groovy @@ -17,8 +17,7 @@ package org.apache.nifi.security.util.crypto import at.favre.lib.crypto.bcrypt.Radix64Encoder -import org.apache.kerby.util.Hex -import org.bouncycastle.jce.provider.BouncyCastleProvider +import org.bouncycastle.util.encoders.Hex import org.junit.After import org.junit.Before import org.junit.BeforeClass @@ -30,7 +29,6 @@ import org.slf4j.Logger import org.slf4j.LoggerFactory import java.nio.charset.StandardCharsets -import java.security.Security @RunWith(JUnit4.class) class BcryptSecureHasherTest extends GroovyTestCase { @@ -38,8 +36,6 @@ class BcryptSecureHasherTest extends GroovyTestCase { @BeforeClass static void setupOnce() throws Exception { - Security.addProvider(new BouncyCastleProvider()) - logger.metaClass.methodMissing = { String name, args -> logger.info("[${name?.toUpperCase()}] ${(args as List).join(" ")}") } @@ -53,10 +49,6 @@ class BcryptSecureHasherTest extends GroovyTestCase { void tearDown() throws Exception { } - private static byte[] decodeHex(String hex) { - Hex.decode(hex?.replaceAll("[^0-9a-fA-F]", "")) - } - @Test void testShouldBeDeterministicWithStaticSalt() { // Arrange @@ -75,7 +67,7 @@ class BcryptSecureHasherTest extends GroovyTestCase { // Act testIterations.times { int i -> byte[] hash = bcryptSH.hashRaw(inputBytes) - String hashHex = Hex.encode(hash) + String hashHex = new String(Hex.encode(hash)) logger.info("Generated hash: ${hashHex}") results << hashHex } diff --git a/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/crypto/PBKDF2SecureHasherTest.groovy b/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/crypto/PBKDF2SecureHasherTest.groovy index 2e5b10b2f1..27799aca20 100644 --- a/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/crypto/PBKDF2SecureHasherTest.groovy +++ b/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/crypto/PBKDF2SecureHasherTest.groovy @@ -16,36 +16,20 @@ */ package org.apache.nifi.security.util.crypto -import org.apache.kerby.util.Hex import org.bouncycastle.jce.provider.BouncyCastleProvider +import org.bouncycastle.util.encoders.Hex import org.junit.* import org.junit.runner.RunWith import org.junit.runners.JUnit4 -import org.slf4j.Logger -import org.slf4j.LoggerFactory import java.nio.charset.StandardCharsets import java.security.Security @RunWith(JUnit4.class) class PBKDF2SecureHasherTest extends GroovyTestCase { - private static final Logger logger = LoggerFactory.getLogger(PBKDF2SecureHasherTest) - @BeforeClass static void setupOnce() throws Exception { Security.addProvider(new BouncyCastleProvider()) - - logger.metaClass.methodMissing = { String name, args -> - logger.info("[${name?.toUpperCase()}] ${(args as List).join(" ")}") - } - } - - @Before - void setUp() throws Exception { - } - - @After - void tearDown() throws Exception { } @Test @@ -53,7 +37,6 @@ class PBKDF2SecureHasherTest extends GroovyTestCase { // Arrange int cost = 10_000 int dkLength = 32 - logger.info("Generating PBKDF2 hash for iterations: ${cost}, desired key length: ${dkLength} bytes (${dkLength * 8} bits)") int testIterations = 10 byte[] inputBytes = "This is a sensitive value".bytes @@ -67,8 +50,7 @@ class PBKDF2SecureHasherTest extends GroovyTestCase { // Act testIterations.times { int i -> byte[] hash = pbkdf2SecureHasher.hashRaw(inputBytes) - String hashHex = Hex.encode(hash) - logger.info("Generated hash: ${hashHex}") + String hashHex = new String(Hex.encode(hash)) results << hashHex } @@ -83,7 +65,6 @@ class PBKDF2SecureHasherTest extends GroovyTestCase { int cost = 10_000 int saltLength = 16 int dkLength = 32 - logger.info("Generating PBKDF2 hash for prf: ${prf}, iterations: ${cost}, salt length: ${saltLength} bytes, desired key length: ${dkLength} bytes (${dkLength * 8} bits)") int testIterations = 10 byte[] inputBytes = "This is a sensitive value".bytes @@ -98,7 +79,6 @@ class PBKDF2SecureHasherTest extends GroovyTestCase { testIterations.times { int i -> byte[] hash = pbkdf2SecureHasher.hashRaw(inputBytes) String hashHex = Hex.encode(hash) - logger.info("Generated hash: ${hashHex}") results << hashHex } @@ -114,7 +94,6 @@ class PBKDF2SecureHasherTest extends GroovyTestCase { int cost = 10_000 int saltLength = 16 int dkLength = 32 - logger.info("Generating PBKDF2 hash for prf: ${prf}, iterations: ${cost}, salt length: ${saltLength} bytes, desired key length: ${dkLength} bytes (${dkLength * 8} bits)") def input = "This is a sensitive value" byte[] inputBytes = input.bytes @@ -169,7 +148,6 @@ class PBKDF2SecureHasherTest extends GroovyTestCase { int cost = 10_000 int saltLength = 16 int dkLength = 32 - logger.info("Generating PBKDF2 hash for prf: ${prf}, iterations: ${cost}, salt length: ${saltLength} bytes, desired key length: ${dkLength} bytes (${dkLength * 8} bits)") def input = "This is a sensitive value" byte[] inputBytes = input.bytes @@ -182,7 +160,6 @@ class PBKDF2SecureHasherTest extends GroovyTestCase { def initializeMsg = shouldFail(IllegalArgumentException) { PBKDF2SecureHasher invalidSaltLengthHasher = new PBKDF2SecureHasher(prf, cost, 7, dkLength) } - logger.expected(initializeMsg) def arbitrarySaltRawMsg = shouldFail { byte[] arbitrarySaltRaw = secureHasher.hashRaw(inputBytes, STATIC_SALT) @@ -213,7 +190,6 @@ class PBKDF2SecureHasherTest extends GroovyTestCase { // Act String hashHex = pbkdf2SecureHasher.hashHex(input) - logger.info("Generated hash: ${hashHex}") // Assert assert hashHex == EXPECTED_HASH_HEX @@ -230,7 +206,6 @@ class PBKDF2SecureHasherTest extends GroovyTestCase { // Act String hashB64 = pbkdf2SecureHasher.hashBase64(input) - logger.info("Generated hash: ${hashB64}") // Assert assert hashB64 == EXPECTED_HASH_BASE64 @@ -252,11 +227,9 @@ class PBKDF2SecureHasherTest extends GroovyTestCase { // Act inputs.each { String input -> String hashHex = pbkdf2SecureHasher.hashHex(input) - logger.info("Generated hex-encoded hash: ${hashHex}") hexResults << hashHex String hashB64 = pbkdf2SecureHasher.hashBase64(input) - logger.info("Generated B64-encoded hash: ${hashB64}") B64Results << hashB64 } @@ -289,7 +262,6 @@ class PBKDF2SecureHasherTest extends GroovyTestCase { long durationNanos = endNanos - startNanos String hashHex = Hex.encode(hash) - logger.info("Generated hash: ${hashHex} in ${durationNanos} ns") results << hashHex resultDurations << durationNanos @@ -309,7 +281,6 @@ class PBKDF2SecureHasherTest extends GroovyTestCase { // Act def results = validIterationCounts.collect { int i -> boolean valid = PBKDF2SecureHasher.isIterationCountValid(i) - logger.info("Iteration count ${i} is valid: ${valid}") valid } @@ -325,7 +296,6 @@ class PBKDF2SecureHasherTest extends GroovyTestCase { // Act def results = invalidIterationCounts.collect { i -> boolean valid = PBKDF2SecureHasher.isIterationCountValid(i) - logger.info("Iteration count ${i} is valid: ${valid}") valid } @@ -347,7 +317,6 @@ class PBKDF2SecureHasherTest extends GroovyTestCase { def results = validHLengths.collectEntries { int hLen -> def dkResults = validDKLengths.collect { int dkLength -> boolean valid = PBKDF2SecureHasher.isDKLengthValid(hLen, dkLength) - logger.info("Derived key length ${dkLength} bytes (${dkLength * 8} bits) with hLen ${hLen} bytes (${hLen * 8} bits) is valid: ${valid}") valid } [hLen, dkResults] @@ -371,7 +340,6 @@ class PBKDF2SecureHasherTest extends GroovyTestCase { def results = validHLengths.collectEntries { int hLen -> def dkResults = invalidDKLengths.collect { int dkLength -> boolean valid = PBKDF2SecureHasher.isDKLengthValid(hLen, dkLength) - logger.info("Derived key length ${dkLength} bytes (${dkLength * 8} bits) with hLen ${hLen} bytes (${hLen * 8} bits) is valid: ${valid}") valid } [hLen, dkResults] @@ -391,7 +359,6 @@ class PBKDF2SecureHasherTest extends GroovyTestCase { // Act def results = saltLengths.collect { saltLength -> def isValid = new PBKDF2SecureHasher().isSaltLengthValid(saltLength) - logger.info("Salt length ${saltLength} bytes is valid: ${isValid}") isValid } @@ -407,7 +374,6 @@ class PBKDF2SecureHasherTest extends GroovyTestCase { // Act def results = saltLengths.collect { saltLength -> def isValid = new PBKDF2SecureHasher().isSaltLengthValid(saltLength) - logger.info("Salt length ${saltLength} bytes is valid: ${isValid}") isValid } diff --git a/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/crypto/ScryptSecureHasherTest.groovy b/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/crypto/ScryptSecureHasherTest.groovy index 46b02499e0..6dda22d06b 100644 --- a/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/crypto/ScryptSecureHasherTest.groovy +++ b/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/crypto/ScryptSecureHasherTest.groovy @@ -16,41 +16,15 @@ */ package org.apache.nifi.security.util.crypto -import org.apache.kerby.util.Hex -import org.bouncycastle.jce.provider.BouncyCastleProvider +import org.bouncycastle.util.encoders.Hex import org.junit.* import org.junit.runner.RunWith import org.junit.runners.JUnit4 -import org.slf4j.Logger -import org.slf4j.LoggerFactory import java.nio.charset.StandardCharsets -import java.security.Security @RunWith(JUnit4.class) class ScryptSecureHasherTest extends GroovyTestCase { - private static final Logger logger = LoggerFactory.getLogger(ScryptSecureHasherTest) - - @BeforeClass - static void setupOnce() throws Exception { - Security.addProvider(new BouncyCastleProvider()) - - logger.metaClass.methodMissing = { String name, args -> - logger.info("[${name?.toUpperCase()}] ${(args as List).join(" ")}") - } - } - - @Before - void setUp() throws Exception { - } - - @After - void tearDown() throws Exception { - } - - private static byte[] decodeHex(String hex) { - Hex.decode(hex?.replaceAll("[^0-9a-fA-F]", "")) - } @Test void testShouldBeDeterministicWithStaticSalt() { @@ -59,7 +33,6 @@ class ScryptSecureHasherTest extends GroovyTestCase { int r = 8 int p = 2 int dkLength = 32 - logger.info("Generating Scrypt hash for iterations: ${n}, mem: ${r} B, parallelism: ${p}, desired key length: ${dkLength}") int testIterations = 10 byte[] inputBytes = "This is a sensitive value".bytes @@ -73,8 +46,7 @@ class ScryptSecureHasherTest extends GroovyTestCase { // Act testIterations.times { int i -> byte[] hash = scryptSH.hashRaw(inputBytes) - String hashHex = Hex.encode(hash) - logger.info("Generated hash: ${hashHex}") + String hashHex = new String(Hex.encode(hash)) results << hashHex } @@ -89,7 +61,6 @@ class ScryptSecureHasherTest extends GroovyTestCase { int r = 8 int p = 2 int dkLength = 128 - logger.info("Generating Scrypt hash for iterations: ${n}, mem: ${r} B, parallelism: ${p}, desired key length: ${dkLength}") int testIterations = 10 byte[] inputBytes = "This is a sensitive value".bytes @@ -103,8 +74,7 @@ class ScryptSecureHasherTest extends GroovyTestCase { // Act testIterations.times { int i -> byte[] hash = scryptSH.hashRaw(inputBytes) - String hashHex = Hex.encode(hash) - logger.info("Generated hash: ${hashHex}") + String hashHex = new String(Hex.encode(hash)) results << hashHex } @@ -120,7 +90,6 @@ class ScryptSecureHasherTest extends GroovyTestCase { int r = 8 int p = 2 int dkLength = 32 - logger.info("Generating Scrypt hash for iterations: ${n}, mem: ${r} B, parallelism: ${p}, desired key length: ${dkLength}") def input = "This is a sensitive value" byte[] inputBytes = input.bytes @@ -176,35 +145,29 @@ class ScryptSecureHasherTest extends GroovyTestCase { int r = 8 int p = 2 int dkLength = 32 - logger.info("Generating Scrypt hash for iterations: ${n}, mem: ${r} B, parallelism: ${p}, desired key length: ${dkLength}") def input = "This is a sensitive value" byte[] inputBytes = input.bytes - final String EXPECTED_HASH_HEX = "a67fd2f4b3aa577b8ecdb682e60b4451a84611dcbbc534bce17616056ef8965d" - final String EXPECTED_HASH_BASE64 = "pn/S9LOqV3uOzbaC5gtEUahGEdy7xTS84XYWBW74ll0=" - final byte[] EXPECTED_HASH_BYTES = Hex.decode(EXPECTED_HASH_HEX) - // Static salt instance ScryptSecureHasher secureHasher = new ScryptSecureHasher(n, r, p, dkLength, 16) final byte[] STATIC_SALT = "bad_sal".bytes // Act - def initializationMsg = shouldFail(IllegalArgumentException) { - ScryptSecureHasher invalidSaltLengthHasher = new ScryptSecureHasher(n, r, p, dkLength, 7) + shouldFail(IllegalArgumentException) { + new ScryptSecureHasher(n, r, p, dkLength, 7) } - logger.expected(initializationMsg) def arbitrarySaltRawMsg = shouldFail { - byte[] arbitrarySaltHash = secureHasher.hashRaw(inputBytes, STATIC_SALT) + secureHasher.hashRaw(inputBytes, STATIC_SALT) } def arbitrarySaltHexMsg = shouldFail { - String arbitrarySaltHashHex = secureHasher.hashHex(input, new String(STATIC_SALT, StandardCharsets.UTF_8)) + secureHasher.hashHex(input, new String(STATIC_SALT, StandardCharsets.UTF_8)) } def arbitrarySaltB64Msg = shouldFail { - String arbitrarySaltHashBase64 = secureHasher.hashBase64(input, new String(STATIC_SALT, StandardCharsets.UTF_8)) + secureHasher.hashBase64(input, new String(STATIC_SALT, StandardCharsets.UTF_8)) } def results = [arbitrarySaltRawMsg, arbitrarySaltHexMsg, arbitrarySaltB64Msg] @@ -224,7 +187,6 @@ class ScryptSecureHasherTest extends GroovyTestCase { // Act String hashHex = scryptSH.hashHex(input) - logger.info("Generated hash: ${hashHex}") // Assert assert hashHex == EXPECTED_HASH_HEX @@ -241,7 +203,6 @@ class ScryptSecureHasherTest extends GroovyTestCase { // Act String hashB64 = scryptSH.hashBase64(input) - logger.info("Generated hash: ${hashB64}") // Assert assert hashB64 == EXPECTED_HASH_BASE64 @@ -263,11 +224,9 @@ class ScryptSecureHasherTest extends GroovyTestCase { // Act inputs.each { String input -> String hashHex = scryptSH.hashHex(input) - logger.info("Generated hex-encoded hash: ${hashHex}") hexResults << hashHex String hashB64 = scryptSH.hashBase64(input) - logger.info("Generated B64-encoded hash: ${hashB64}") B64Results << hashB64 } @@ -300,7 +259,6 @@ class ScryptSecureHasherTest extends GroovyTestCase { long durationNanos = endNanos - startNanos String hashHex = Hex.encode(hash) - logger.info("Generated hash: ${hashHex} in ${durationNanos} ns") results << hashHex resultDurations << durationNanos @@ -337,7 +295,6 @@ class ScryptSecureHasherTest extends GroovyTestCase { // Assert results.each { rValue, isRValid -> - logger.info("For R value ${rValue}, R is ${isRValid ? "valid" : "invalid"}") assert !isRValid } } @@ -368,7 +325,6 @@ class ScryptSecureHasherTest extends GroovyTestCase { // Assert results.each { n, isNValid -> - logger.info("For N value ${n}, N is ${isNValid ? "valid" : "invalid"}") assert !isNValid } } @@ -383,7 +339,6 @@ class ScryptSecureHasherTest extends GroovyTestCase { def pResults = ps.collectEntries { int p -> def rResults = rs.collectEntries { int r -> boolean valid = ScryptSecureHasher.isPValid(p, r) - logger.info("p ${p} is valid for r ${r}: ${valid}") [r, valid] } [p, rResults] @@ -405,7 +360,6 @@ class ScryptSecureHasherTest extends GroovyTestCase { def pResults = ps.collectEntries { int p -> def rResults = rs.collectEntries { int r -> boolean valid = ScryptSecureHasher.isPValid(p, r) - logger.info("p ${p} is valid for r ${r}: ${valid}") [r, valid] } [p, rResults] @@ -442,7 +396,6 @@ class ScryptSecureHasherTest extends GroovyTestCase { // Assert results.each { dKLength, isDKLengthValid -> - logger.info("For Desired Key Length value ${dKLength}, dkLength is ${isDKLengthValid ? "valid" : "invalid"}") assert !isDKLengthValid } } @@ -477,7 +430,6 @@ class ScryptSecureHasherTest extends GroovyTestCase { // Assert results.each { saltLength, isSaltLengthValid -> - logger.info("For Salt Length value ${saltLength}, saltLength is ${isSaltLengthValid ? "valid" : "invalid"}") assert !isSaltLengthValid } } diff --git a/nifi-commons/nifi-security-utils/src/test/java/org/apache/nifi/security/util/KeyStoreUtilsTest.java b/nifi-commons/nifi-security-utils/src/test/java/org/apache/nifi/security/util/KeyStoreUtilsTest.java index 12d76dd487..f41d5970d6 100644 --- a/nifi-commons/nifi-security-utils/src/test/java/org/apache/nifi/security/util/KeyStoreUtilsTest.java +++ b/nifi-commons/nifi-security-utils/src/test/java/org/apache/nifi/security/util/KeyStoreUtilsTest.java @@ -50,7 +50,8 @@ public class KeyStoreUtilsTest { private static final char[] STORE_PASSWORD = UUID.randomUUID().toString().toCharArray(); private static final String ALIAS = "alias"; private static final String KEY_ALGORITHM = "RSA"; - private static final String SUBJECT_DN = "CN=localhost"; + private static final String HOSTNAME = "localhost"; + private static final String SUBJECT_DN = String.format("CN=%s", HOSTNAME); private static final String SECRET_KEY_ALGORITHM = "AES"; private static final String KEY_PROTECTION_ALGORITHM = "PBEWithHmacSHA256AndAES_256"; private static final String HYPHEN_SEPARATOR = "-"; @@ -69,7 +70,25 @@ public class KeyStoreUtilsTest { @Test public void testCreateTlsConfigAndNewKeystoreTruststore() throws GeneralSecurityException, IOException { - final TlsConfiguration configuration = KeyStoreUtils.createTlsConfigAndNewKeystoreTruststore(); + final File keyStoreFile = File.createTempFile(KeyStoreUtilsTest.class.getSimpleName(), ".keystore.p12"); + keyStoreFile.deleteOnExit(); + final File trustStoreFile = File.createTempFile(KeyStoreUtilsTest.class.getSimpleName(), ".truststore.p12"); + trustStoreFile.deleteOnExit(); + + final String password = UUID.randomUUID().toString(); + final String keyStoreType = KeystoreType.PKCS12.getType(); + + final TlsConfiguration requested = new StandardTlsConfiguration( + keyStoreFile.getAbsolutePath(), + password, + password, + keyStoreType, + trustStoreFile.getAbsolutePath(), + password, + keyStoreType, + TlsConfiguration.TLS_PROTOCOL + ); + final TlsConfiguration configuration = KeyStoreUtils.createTlsConfigAndNewKeystoreTruststore(requested, 1, new String[] { HOSTNAME }); final File keystoreFile = new File(configuration.getKeystorePath()); assertTrue("Keystore File not found", keystoreFile.exists()); keystoreFile.deleteOnExit(); diff --git a/nifi-commons/nifi-security-utils/src/test/java/org/apache/nifi/security/util/SslSocketFactoryTest.java b/nifi-commons/nifi-security-utils/src/test/java/org/apache/nifi/security/util/SslSocketFactoryTest.java new file mode 100644 index 0000000000..9400a95e99 --- /dev/null +++ b/nifi-commons/nifi-security-utils/src/test/java/org/apache/nifi/security/util/SslSocketFactoryTest.java @@ -0,0 +1,105 @@ +/* + * 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.security.util; + +import org.apache.nifi.util.StringUtils; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; + +public class SslSocketFactoryTest { + private static TlsConfiguration tlsConfiguration; + + @BeforeAll + public static void setTlsConfiguration() { + tlsConfiguration = new TemporaryKeyStoreBuilder().build(); + } + + @Test + public void testCreateSslContextNullTlsConfiguration() throws TlsException { + final SSLContext sslContext = SslContextFactory.createSslContext(null); + assertNull(sslContext); + } + + @Test + public void testCreateSslContextEmptyTlsConfiguration() throws TlsException { + final SSLContext sslContext = SslContextFactory.createSslContext(new StandardTlsConfiguration()); + assertNull(sslContext); + } + + @Test + public void testCreateSslContextEmptyKeyPassword() throws TlsException { + final TlsConfiguration customTlsConfiguration = new StandardTlsConfiguration( + tlsConfiguration.getKeystorePath(), + tlsConfiguration.getKeystorePassword(), + StringUtils.EMPTY, + tlsConfiguration.getKeystoreType(), + tlsConfiguration.getTruststorePath(), + tlsConfiguration.getTruststorePassword(), + tlsConfiguration.getTruststoreType(), + tlsConfiguration.getProtocol() + ); + final SSLContext sslContext = SslContextFactory.createSslContext(customTlsConfiguration); + assertNotNull(sslContext); + assertEquals(customTlsConfiguration.getProtocol(), sslContext.getProtocol()); + } + + @Test + public void testCreateSslContextEmptyTrustStorePasswordJks() throws TlsException { + final TlsConfiguration customTlsConfiguration = new TemporaryKeyStoreBuilder() + .trustStorePassword(StringUtils.EMPTY) + .trustStoreType(KeystoreType.JKS.getType()) + .build(); + final SSLContext sslContext = SslContextFactory.createSslContext(customTlsConfiguration); + assertNotNull(sslContext); + assertEquals(customTlsConfiguration.getProtocol(), sslContext.getProtocol()); + } + + @Test + public void testCreateSslContext() throws TlsException { + final SSLContext sslContext = SslContextFactory.createSslContext(tlsConfiguration); + assertNotNull(sslContext); + assertEquals(tlsConfiguration.getProtocol(), sslContext.getProtocol()); + } + + @Test + public void testGetTrustManager() throws TlsException { + final X509TrustManager trustManager = SslContextFactory.getX509TrustManager(tlsConfiguration); + assertNotNull(trustManager); + assertEquals(1, trustManager.getAcceptedIssuers().length); + } + + @Test + public void testGetTrustManagers() throws TlsException { + final TrustManager[] trustManagers = SslContextFactory.getTrustManagers(tlsConfiguration); + assertNotNull(trustManagers); + assertEquals(1, trustManagers.length); + } + + @Test + public void testGetTrustManagersEmptyTlsConfiguration() throws TlsException { + final TrustManager[] trustManagers = SslContextFactory.getTrustManagers(new StandardTlsConfiguration()); + assertNull(trustManagers); + } +} diff --git a/nifi-commons/nifi-security-utils/src/test/java/org/apache/nifi/security/util/StandardTlsConfigurationTest.java b/nifi-commons/nifi-security-utils/src/test/java/org/apache/nifi/security/util/StandardTlsConfigurationTest.java new file mode 100644 index 0000000000..9b78726c55 --- /dev/null +++ b/nifi-commons/nifi-security-utils/src/test/java/org/apache/nifi/security/util/StandardTlsConfigurationTest.java @@ -0,0 +1,265 @@ +/* + * 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.security.util; + +import org.apache.nifi.util.NiFiProperties; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class StandardTlsConfigurationTest { + private static final String KEY_STORE_PATH = UUID.randomUUID().toString(); + + private static final String KEY_STORE_PASSWORD = UUID.randomUUID().toString(); + + private static final String KEY_PASSWORD = UUID.randomUUID().toString(); + + private static final String KEY_STORE_TYPE = KeystoreType.PKCS12.getType(); + + private static final String TRUST_STORE_PATH = UUID.randomUUID().toString(); + + private static final String TRUST_STORE_PASSWORD = UUID.randomUUID().toString(); + + private static final String TRUST_STORE_TYPE = KeystoreType.JKS.getType(); + + private static final String PROTOCOL = TlsConfiguration.getHighestCurrentSupportedTlsProtocolVersion(); + + private static TlsConfiguration tlsConfiguration; + + @BeforeAll + public static void setTlsConfiguration() { + tlsConfiguration = new TemporaryKeyStoreBuilder().build(); + } + + @Test + public void testIsKeyStoreValid() { + assertTrue(tlsConfiguration.isKeystoreValid()); + } + + @Test + public void testIsTrustStoreValid() { + assertTrue(tlsConfiguration.isTruststoreValid()); + } + + @Test + public void testEqualsNullProperties() { + final StandardTlsConfiguration configuration = new StandardTlsConfiguration(); + assertEquals(new StandardTlsConfiguration(), configuration); + } + + @Test + public void testHashCodeNullProperties() { + final StandardTlsConfiguration configuration = new StandardTlsConfiguration(); + assertEquals(new StandardTlsConfiguration().hashCode(), configuration.hashCode()); + } + + @Test + public void testFromNiFiPropertiesEmptyProperties() { + final NiFiProperties niFiProperties = NiFiProperties.createBasicNiFiProperties(null); + final TlsConfiguration configuration = StandardTlsConfiguration.fromNiFiProperties(niFiProperties); + assertNotNull(configuration); + assertEquals(PROTOCOL, configuration.getProtocol()); + } + + @Test + public void testFromNiFiProperties() { + final Map properties = new HashMap<>(); + properties.put(NiFiProperties.SECURITY_KEYSTORE, KEY_STORE_PATH); + properties.put(NiFiProperties.SECURITY_KEYSTORE_PASSWD, KEY_STORE_PASSWORD); + properties.put(NiFiProperties.SECURITY_KEY_PASSWD, KEY_PASSWORD); + properties.put(NiFiProperties.SECURITY_KEYSTORE_TYPE, KEY_STORE_TYPE); + properties.put(NiFiProperties.SECURITY_TRUSTSTORE, TRUST_STORE_PATH); + properties.put(NiFiProperties.SECURITY_TRUSTSTORE_PASSWD, TRUST_STORE_PASSWORD); + properties.put(NiFiProperties.SECURITY_TRUSTSTORE_TYPE, TRUST_STORE_TYPE); + final NiFiProperties niFiProperties = NiFiProperties.createBasicNiFiProperties(null, properties); + + final TlsConfiguration configuration = StandardTlsConfiguration.fromNiFiProperties(niFiProperties); + assertNotNull(configuration); + assertEquals(PROTOCOL, configuration.getProtocol()); + assertEquals(KEY_STORE_PATH, configuration.getKeystorePath()); + assertEquals(KEY_STORE_PASSWORD, configuration.getKeystorePassword()); + assertEquals(KEY_PASSWORD, configuration.getKeyPassword()); + assertEquals(KEY_STORE_TYPE, configuration.getKeystoreType().getType()); + assertEquals(TRUST_STORE_PATH, configuration.getTruststorePath()); + assertEquals(TRUST_STORE_PASSWORD, configuration.getTruststorePassword()); + assertEquals(TRUST_STORE_TYPE, configuration.getTruststoreType().getType()); + } + + @Test + public void testFromNiFiPropertiesTrustStoreProperties() { + final Map properties = new HashMap<>(); + properties.put(NiFiProperties.SECURITY_TRUSTSTORE, TRUST_STORE_PATH); + properties.put(NiFiProperties.SECURITY_TRUSTSTORE_PASSWD, TRUST_STORE_PASSWORD); + properties.put(NiFiProperties.SECURITY_TRUSTSTORE_TYPE, TRUST_STORE_TYPE); + final NiFiProperties niFiProperties = NiFiProperties.createBasicNiFiProperties(null, properties); + + final TlsConfiguration configuration = StandardTlsConfiguration.fromNiFiPropertiesTruststoreOnly(niFiProperties); + assertNotNull(configuration); + assertNull(configuration.getKeystorePath()); + assertEquals(PROTOCOL, configuration.getProtocol()); + assertEquals(TRUST_STORE_PATH, configuration.getTruststorePath()); + assertEquals(TRUST_STORE_PASSWORD, configuration.getTruststorePassword()); + assertEquals(TRUST_STORE_TYPE, configuration.getTruststoreType().getType()); + } + + @Test + public void testFunctionalKeyPasswordFromKeyStorePassword() { + final TlsConfiguration configuration = new StandardTlsConfiguration( + KEY_STORE_PATH, + KEY_STORE_PASSWORD, + null, + KEY_STORE_TYPE, + TRUST_STORE_PATH, + TRUST_STORE_PASSWORD, + TRUST_STORE_TYPE, + PROTOCOL + ); + assertEquals(KEY_STORE_PASSWORD, configuration.getFunctionalKeyPassword()); + } + + @Test + public void testIsKeyStorePopulated() { + final TlsConfiguration configuration = new StandardTlsConfiguration( + KEY_STORE_PATH, + KEY_STORE_PASSWORD, + KEY_PASSWORD, + KEY_STORE_TYPE, + null, + null, + null, + PROTOCOL + ); + assertTrue(configuration.isKeystorePopulated()); + assertTrue(configuration.isAnyKeystorePopulated()); + } + + @Test + public void testIsKeyStorePopulatedMissingProperties() { + final TlsConfiguration configuration = new StandardTlsConfiguration( + null, + null, + null, + null, + TRUST_STORE_PATH, + TRUST_STORE_PASSWORD, + TRUST_STORE_TYPE, + PROTOCOL + ); + assertFalse(configuration.isKeystorePopulated()); + assertFalse(configuration.isAnyKeystorePopulated()); + } + + @Test + public void testIsTrustStorePopulated() { + final TlsConfiguration configuration = new StandardTlsConfiguration( + null, + null, + null, + null, + TRUST_STORE_PATH, + TRUST_STORE_PASSWORD, + TRUST_STORE_TYPE, + PROTOCOL + ); + assertTrue(configuration.isTruststorePopulated()); + assertTrue(configuration.isAnyTruststorePopulated()); + } + + @Test + public void testIsTrustStorePopulatedMissingProperties() { + final TlsConfiguration configuration = new StandardTlsConfiguration( + KEY_STORE_PATH, + KEY_STORE_PASSWORD, + KEY_PASSWORD, + KEY_STORE_TYPE, + null, + null, + null, + PROTOCOL + ); + assertFalse(configuration.isTruststorePopulated()); + assertFalse(configuration.isAnyTruststorePopulated()); + } + + @Test + public void testGetEnabledProtocolsVersionMatched() { + final TlsConfiguration configuration = new StandardTlsConfiguration( + KEY_STORE_PATH, + KEY_STORE_PASSWORD, + KEY_PASSWORD, + KEY_STORE_TYPE, + TRUST_STORE_PATH, + TRUST_STORE_PASSWORD, + TRUST_STORE_TYPE, + PROTOCOL + ); + + final String[] enabledProtocols = configuration.getEnabledProtocols(); + assertArrayEquals(new String[]{PROTOCOL}, enabledProtocols); + } + + @Test + public void testGetEnabledProtocolsTlsProtocol() { + final TlsConfiguration configuration = new StandardTlsConfiguration( + KEY_STORE_PATH, + KEY_STORE_PASSWORD, + KEY_PASSWORD, + KEY_STORE_TYPE, + TRUST_STORE_PATH, + TRUST_STORE_PASSWORD, + TRUST_STORE_TYPE, + TlsConfiguration.TLS_PROTOCOL + ); + + final String[] enabledProtocols = configuration.getEnabledProtocols(); + assertArrayEquals(TlsConfiguration.getCurrentSupportedTlsProtocolVersions(), enabledProtocols); + } + + @Test + public void testGetEnabledProtocolsSslProtocol() { + final TlsConfiguration configuration = new StandardTlsConfiguration( + KEY_STORE_PATH, + KEY_STORE_PASSWORD, + KEY_PASSWORD, + KEY_STORE_TYPE, + TRUST_STORE_PATH, + TRUST_STORE_PASSWORD, + TRUST_STORE_TYPE, + TlsConfiguration.SSL_PROTOCOL + ); + + final String[] enabledProtocols = configuration.getEnabledProtocols(); + + final List expectedProtocols = new ArrayList<>(); + expectedProtocols.addAll(Arrays.asList(TlsConfiguration.LEGACY_TLS_PROTOCOL_VERSIONS)); + expectedProtocols.addAll(Arrays.asList(TlsConfiguration.getCurrentSupportedTlsProtocolVersions())); + assertArrayEquals(expectedProtocols.toArray(), enabledProtocols); + } +} diff --git a/nifi-commons/nifi-security-utils/src/test/resources/TlsConfigurationKeystore.jks b/nifi-commons/nifi-security-utils/src/test/resources/TlsConfigurationKeystore.jks deleted file mode 100644 index 5dd2609b6d..0000000000 Binary files a/nifi-commons/nifi-security-utils/src/test/resources/TlsConfigurationKeystore.jks and /dev/null differ diff --git a/nifi-commons/nifi-security-utils/src/test/resources/TlsConfigurationTruststore.jks b/nifi-commons/nifi-security-utils/src/test/resources/TlsConfigurationTruststore.jks deleted file mode 100644 index 4946966164..0000000000 Binary files a/nifi-commons/nifi-security-utils/src/test/resources/TlsConfigurationTruststore.jks and /dev/null differ diff --git a/nifi-commons/nifi-security-utils/src/test/resources/keystore.jks b/nifi-commons/nifi-security-utils/src/test/resources/keystore.jks deleted file mode 100644 index 246fe888ef..0000000000 Binary files a/nifi-commons/nifi-security-utils/src/test/resources/keystore.jks and /dev/null differ diff --git a/nifi-commons/nifi-security-utils/src/test/resources/logback-test.xml b/nifi-commons/nifi-security-utils/src/test/resources/logback-test.xml deleted file mode 100644 index b771380dec..0000000000 --- a/nifi-commons/nifi-security-utils/src/test/resources/logback-test.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - %-4r [%t] %-5p %c{3} - %m%n - - - - - ./target/log - - %date %level [%thread] %logger{40} %msg%n - - - - - - - - - - - - - diff --git a/nifi-commons/nifi-security-utils/src/test/resources/no-password-truststore.jks b/nifi-commons/nifi-security-utils/src/test/resources/no-password-truststore.jks deleted file mode 100644 index aa1ce5d17e..0000000000 Binary files a/nifi-commons/nifi-security-utils/src/test/resources/no-password-truststore.jks and /dev/null differ diff --git a/nifi-commons/nifi-security-utils/src/test/resources/samepassword.jks b/nifi-commons/nifi-security-utils/src/test/resources/samepassword.jks deleted file mode 100644 index 4f1084048a..0000000000 Binary files a/nifi-commons/nifi-security-utils/src/test/resources/samepassword.jks and /dev/null differ diff --git a/nifi-commons/nifi-site-to-site-client/src/test/java/org/apache/nifi/remote/client/http/TestHttpClient.java b/nifi-commons/nifi-site-to-site-client/src/test/java/org/apache/nifi/remote/client/http/TestHttpClient.java index 4701679154..d72662f7bf 100644 --- a/nifi-commons/nifi-site-to-site-client/src/test/java/org/apache/nifi/remote/client/http/TestHttpClient.java +++ b/nifi-commons/nifi-site-to-site-client/src/test/java/org/apache/nifi/remote/client/http/TestHttpClient.java @@ -32,14 +32,12 @@ import static org.junit.Assume.assumeFalse; import com.fasterxml.jackson.databind.ObjectMapper; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; -import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.SocketTimeoutException; import java.net.URI; -import java.security.GeneralSecurityException; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashSet; @@ -68,7 +66,7 @@ import org.apache.nifi.remote.protocol.SiteToSiteTransportProtocol; import org.apache.nifi.remote.protocol.http.HttpHeaders; import org.apache.nifi.remote.protocol.http.HttpProxy; import org.apache.nifi.remote.util.StandardDataPacket; -import org.apache.nifi.security.util.KeyStoreUtils; +import org.apache.nifi.security.util.TemporaryKeyStoreBuilder; import org.apache.nifi.security.util.TlsConfiguration; import org.apache.nifi.stream.io.StreamUtils; import org.apache.nifi.web.api.dto.ControllerDTO; @@ -1402,9 +1400,7 @@ public class TestHttpClient { } } - private static void setTlsConfiguration() throws GeneralSecurityException, IOException { - tlsConfiguration = KeyStoreUtils.createTlsConfigAndNewKeystoreTruststore(); - new File(tlsConfiguration.getKeystorePath()).deleteOnExit(); - new File(tlsConfiguration.getTruststorePath()).deleteOnExit(); + private static void setTlsConfiguration() { + tlsConfiguration = new TemporaryKeyStoreBuilder().build(); } } diff --git a/nifi-commons/nifi-vault-utils/src/test/java/org/apache/nifi/vault/hashicorp/TestStandardHashiCorpVaultCommunicationService.java b/nifi-commons/nifi-vault-utils/src/test/java/org/apache/nifi/vault/hashicorp/TestStandardHashiCorpVaultCommunicationService.java index 6527ca2748..785c5dc893 100644 --- a/nifi-commons/nifi-vault-utils/src/test/java/org/apache/nifi/vault/hashicorp/TestStandardHashiCorpVaultCommunicationService.java +++ b/nifi-commons/nifi-vault-utils/src/test/java/org/apache/nifi/vault/hashicorp/TestStandardHashiCorpVaultCommunicationService.java @@ -16,7 +16,7 @@ */ package org.apache.nifi.vault.hashicorp; -import org.apache.nifi.security.util.KeyStoreUtils; +import org.apache.nifi.security.util.TemporaryKeyStoreBuilder; import org.apache.nifi.security.util.TlsConfiguration; import org.apache.nifi.vault.hashicorp.config.HashiCorpVaultProperties; import org.apache.nifi.vault.hashicorp.config.HashiCorpVaultSslProperties; @@ -28,8 +28,6 @@ import org.mockito.Mockito; import java.io.File; import java.io.IOException; import java.nio.file.Files; -import java.nio.file.Paths; -import java.security.GeneralSecurityException; import java.util.Arrays; import java.util.Optional; import java.util.stream.Collectors; @@ -96,26 +94,22 @@ public class TestStandardHashiCorpVaultCommunicationService { } @Test - public void testTLS() throws GeneralSecurityException, IOException { - TlsConfiguration tlsConfiguration = KeyStoreUtils.createTlsConfigAndNewKeystoreTruststore(); - try { - Mockito.when(sslProperties.getKeyStore()).thenReturn(tlsConfiguration.getKeystorePath()); - Mockito.when(sslProperties.getKeyStorePassword()).thenReturn(tlsConfiguration.getKeystorePassword()); - Mockito.when(sslProperties.getKeyStoreType()).thenReturn(tlsConfiguration.getKeystoreType().getType()); - Mockito.when(sslProperties.getTrustStore()).thenReturn(tlsConfiguration.getTruststorePath()); - Mockito.when(sslProperties.getTrustStorePassword()).thenReturn(tlsConfiguration.getTruststorePassword()); - Mockito.when(sslProperties.getTrustStoreType()).thenReturn(tlsConfiguration.getTruststoreType().getType()); - Mockito.when(sslProperties.getEnabledProtocols()).thenReturn(Arrays.stream(tlsConfiguration.getEnabledProtocols()) - .collect(Collectors.joining(","))); - Mockito.when(sslProperties.getEnabledCipherSuites()).thenReturn(CIPHER_SUITE_VALUE); + public void testTLS() { + TlsConfiguration tlsConfiguration = new TemporaryKeyStoreBuilder().build(); - Mockito.when(properties.getUri()).thenReturn(URI_VALUE.replace("http", "https")); - this.configureService(); + Mockito.when(sslProperties.getKeyStore()).thenReturn(tlsConfiguration.getKeystorePath()); + Mockito.when(sslProperties.getKeyStorePassword()).thenReturn(tlsConfiguration.getKeystorePassword()); + Mockito.when(sslProperties.getKeyStoreType()).thenReturn(tlsConfiguration.getKeystoreType().getType()); + Mockito.when(sslProperties.getTrustStore()).thenReturn(tlsConfiguration.getTruststorePath()); + Mockito.when(sslProperties.getTrustStorePassword()).thenReturn(tlsConfiguration.getTruststorePassword()); + Mockito.when(sslProperties.getTrustStoreType()).thenReturn(tlsConfiguration.getTruststoreType().getType()); + Mockito.when(sslProperties.getEnabledProtocols()).thenReturn(Arrays.stream(tlsConfiguration.getEnabledProtocols()) + .collect(Collectors.joining(","))); + Mockito.when(sslProperties.getEnabledCipherSuites()).thenReturn(CIPHER_SUITE_VALUE); - this.ensureTlsPropertiesAccessed(1); - } finally { - Files.deleteIfExists(Paths.get(tlsConfiguration.getKeystorePath())); - Files.deleteIfExists(Paths.get(tlsConfiguration.getTruststorePath())); - } + Mockito.when(properties.getUri()).thenReturn(URI_VALUE.replace("http", "https")); + this.configureService(); + + this.ensureTlsPropertiesAccessed(1); } } diff --git a/nifi-nar-bundles/nifi-email-bundle/nifi-email-processors/src/test/java/org/apache/nifi/processors/email/TestListenSMTP.java b/nifi-nar-bundles/nifi-email-bundle/nifi-email-processors/src/test/java/org/apache/nifi/processors/email/TestListenSMTP.java index 09bb6c4df3..63b1cf4252 100644 --- a/nifi-nar-bundles/nifi-email-bundle/nifi-email-processors/src/test/java/org/apache/nifi/processors/email/TestListenSMTP.java +++ b/nifi-nar-bundles/nifi-email-bundle/nifi-email-processors/src/test/java/org/apache/nifi/processors/email/TestListenSMTP.java @@ -22,8 +22,6 @@ import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import java.io.File; -import java.io.IOException; import java.security.GeneralSecurityException; import java.util.Properties; import javax.mail.Message; @@ -37,9 +35,9 @@ import javax.net.ssl.SSLContext; import org.apache.nifi.remote.io.socket.NetworkUtils; import org.apache.nifi.reporting.InitializationException; import org.apache.nifi.security.util.ClientAuth; -import org.apache.nifi.security.util.KeyStoreUtils; import org.apache.nifi.security.util.SslContextFactory; import org.apache.nifi.security.util.StandardTlsConfiguration; +import org.apache.nifi.security.util.TemporaryKeyStoreBuilder; import org.apache.nifi.security.util.TlsConfiguration; import org.apache.nifi.ssl.RestrictedSSLContextService; import org.apache.nifi.ssl.SSLContextService; @@ -58,10 +56,8 @@ public class TestListenSMTP { private static final int MESSAGES = 2; @BeforeClass - public static void setTlsConfiguration() throws IOException, GeneralSecurityException { - final TlsConfiguration testTlsConfiguration = KeyStoreUtils.createTlsConfigAndNewKeystoreTruststore(); - new File(testTlsConfiguration.getKeystorePath()).deleteOnExit(); - new File(testTlsConfiguration.getTruststorePath()).deleteOnExit(); + public static void setTlsConfiguration() throws GeneralSecurityException { + final TlsConfiguration testTlsConfiguration = new TemporaryKeyStoreBuilder().build(); tlsConfiguration = new StandardTlsConfiguration( testTlsConfiguration.getKeystorePath(), diff --git a/nifi-nar-bundles/nifi-extension-utils/nifi-event-transport/src/test/java/org/apache/nifi/event/transport/netty/StringNettyEventSenderFactoryTest.java b/nifi-nar-bundles/nifi-extension-utils/nifi-event-transport/src/test/java/org/apache/nifi/event/transport/netty/StringNettyEventSenderFactoryTest.java index c316ce81db..abf5456783 100644 --- a/nifi-nar-bundles/nifi-extension-utils/nifi-event-transport/src/test/java/org/apache/nifi/event/transport/netty/StringNettyEventSenderFactoryTest.java +++ b/nifi-nar-bundles/nifi-extension-utils/nifi-event-transport/src/test/java/org/apache/nifi/event/transport/netty/StringNettyEventSenderFactoryTest.java @@ -27,8 +27,8 @@ import org.apache.nifi.event.transport.message.ByteArrayMessage; import org.apache.nifi.logging.ComponentLog; import org.apache.nifi.remote.io.socket.NetworkUtils; import org.apache.nifi.security.util.ClientAuth; -import org.apache.nifi.security.util.KeyStoreUtils; import org.apache.nifi.security.util.SslContextFactory; +import org.apache.nifi.security.util.TemporaryKeyStoreBuilder; import org.apache.nifi.security.util.TlsConfiguration; import org.junit.Test; import org.junit.runner.RunWith; @@ -36,8 +36,6 @@ import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import javax.net.ssl.SSLContext; -import java.io.File; -import java.io.IOException; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.security.GeneralSecurityException; @@ -153,12 +151,8 @@ public class StringNettyEventSenderFactoryTest { return factory; } - private SSLContext getSslContext() throws GeneralSecurityException, IOException { - final TlsConfiguration tlsConfiguration = KeyStoreUtils.createTlsConfigAndNewKeystoreTruststore(); - final File keystoreFile = new File(tlsConfiguration.getKeystorePath()); - keystoreFile.deleteOnExit(); - final File truststoreFile = new File(tlsConfiguration.getTruststorePath()); - truststoreFile.deleteOnExit(); + private SSLContext getSslContext() throws GeneralSecurityException { + final TlsConfiguration tlsConfiguration = new TemporaryKeyStoreBuilder().build(); return SslContextFactory.createSslContext(tlsConfiguration); } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/test/groovy/org/apache/nifi/cluster/coordination/http/replication/okhttp/OkHttpReplicationClientTest.groovy b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/test/groovy/org/apache/nifi/cluster/coordination/http/replication/okhttp/OkHttpReplicationClientTest.groovy index fc5d43420c..2390fc7a96 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/test/groovy/org/apache/nifi/cluster/coordination/http/replication/okhttp/OkHttpReplicationClientTest.groovy +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/test/groovy/org/apache/nifi/cluster/coordination/http/replication/okhttp/OkHttpReplicationClientTest.groovy @@ -18,7 +18,7 @@ package org.apache.nifi.cluster.coordination.http.replication.okhttp -import org.apache.nifi.security.util.KeyStoreUtils +import org.apache.nifi.security.util.TemporaryKeyStoreBuilder import org.apache.nifi.security.util.TlsConfiguration import org.apache.nifi.util.NiFiProperties import org.junit.BeforeClass @@ -32,9 +32,7 @@ class OkHttpReplicationClientTest extends GroovyTestCase { @BeforeClass static void setUpOnce() throws Exception { - tlsConfiguration = KeyStoreUtils.createTlsConfigAndNewKeystoreTruststore() - new File(tlsConfiguration.keystorePath).deleteOnExit() - new File(tlsConfiguration.truststorePath).deleteOnExit() + tlsConfiguration = new TemporaryKeyStoreBuilder().build() } private static NiFiProperties mockNiFiProperties() { 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 ea5dec5552..3a1c3039b2 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 @@ -18,8 +18,8 @@ package org.apache.nifi.controller.queue.clustered.server import org.apache.nifi.events.EventReporter import org.apache.nifi.reporting.Severity -import org.apache.nifi.security.util.KeyStoreUtils import org.apache.nifi.security.util.SslContextFactory +import org.apache.nifi.security.util.TemporaryKeyStoreBuilder import org.apache.nifi.security.util.TlsConfiguration import org.junit.After import org.junit.Before @@ -46,9 +46,7 @@ class ConnectionLoadBalanceServerTest extends GroovyTestCase { @BeforeClass static void setUpOnce() throws Exception { - tlsConfiguration = KeyStoreUtils.createTlsConfigAndNewKeystoreTruststore() - new File(tlsConfiguration.keystorePath).deleteOnExit() - new File(tlsConfiguration.truststorePath).deleteOnExit() + tlsConfiguration = new TemporaryKeyStoreBuilder().build() sslContext = SslContextFactory.createSslContext(tlsConfiguration) } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/queue/clustered/LoadBalancedQueueIT.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/queue/clustered/LoadBalancedQueueIT.java index 0a6a37e005..c07ced2392 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/queue/clustered/LoadBalancedQueueIT.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/queue/clustered/LoadBalancedQueueIT.java @@ -56,8 +56,8 @@ import org.apache.nifi.controller.repository.claim.ResourceClaimManager; import org.apache.nifi.controller.repository.claim.StandardResourceClaimManager; import org.apache.nifi.events.EventReporter; import org.apache.nifi.provenance.ProvenanceRepository; -import org.apache.nifi.security.util.KeyStoreUtils; import org.apache.nifi.security.util.SslContextFactory; +import org.apache.nifi.security.util.TemporaryKeyStoreBuilder; import org.apache.nifi.security.util.TlsConfiguration; import org.junit.Before; import org.junit.Test; @@ -68,7 +68,6 @@ import org.mockito.stubbing.Answer; import javax.net.ssl.SSLContext; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; -import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -190,9 +189,7 @@ public class LoadBalancedQueueIT { clientRepoRecords = Collections.synchronizedList(new ArrayList<>()); clientFlowFileRepo = createFlowFileRepository(clientRepoRecords); - TlsConfiguration tlsConfiguration = KeyStoreUtils.createTlsConfigAndNewKeystoreTruststore(); - new File(tlsConfiguration.getKeystorePath()).deleteOnExit(); - new File(tlsConfiguration.getTruststorePath()).deleteOnExit(); + final TlsConfiguration tlsConfiguration = new TemporaryKeyStoreBuilder().build(); sslContext = SslContextFactory.createSslContext(tlsConfiguration); } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/state/providers/zookeeper/ITZooKeeperStateProvider.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/state/providers/zookeeper/ITZooKeeperStateProvider.java index f9bcf22703..d134bce802 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/state/providers/zookeeper/ITZooKeeperStateProvider.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/state/providers/zookeeper/ITZooKeeperStateProvider.java @@ -28,7 +28,7 @@ import org.apache.nifi.controller.state.providers.AbstractTestStateProvider; import org.apache.nifi.logging.ComponentLog; import org.apache.nifi.mock.MockComponentLogger; import org.apache.nifi.parameter.ParameterLookup; -import org.apache.nifi.security.util.KeyStoreUtils; +import org.apache.nifi.security.util.TemporaryKeyStoreBuilder; import org.apache.nifi.security.util.TlsConfiguration; import org.apache.nifi.util.NiFiProperties; import org.apache.zookeeper.server.ServerCnxnFactory; @@ -47,7 +47,6 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.security.GeneralSecurityException; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; @@ -71,10 +70,8 @@ public class ITZooKeeperStateProvider extends AbstractTestStateProvider { private static TlsConfiguration tlsConfiguration; @BeforeClass - public static void setTlsConfiguration() throws GeneralSecurityException, IOException { - tlsConfiguration = KeyStoreUtils.createTlsConfigAndNewKeystoreTruststore(); - new File(tlsConfiguration.getTruststorePath()).deleteOnExit(); - new File(tlsConfiguration.getKeystorePath()).deleteOnExit(); + public static void setTlsConfiguration() { + tlsConfiguration = new TemporaryKeyStoreBuilder().build(); } @Before diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/state/server/ITZooKeeperStateServerTLS.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/state/server/ITZooKeeperStateServerTLS.java index 2725c768be..296edaa0bf 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/state/server/ITZooKeeperStateServerTLS.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/state/server/ITZooKeeperStateServerTLS.java @@ -24,7 +24,7 @@ import org.apache.curator.utils.DefaultZookeeperFactory; import org.apache.curator.utils.ZookeeperFactory; import org.apache.nifi.controller.cluster.SecureClientZooKeeperFactory; import org.apache.nifi.controller.cluster.ZooKeeperClientConfig; -import org.apache.nifi.security.util.KeyStoreUtils; +import org.apache.nifi.security.util.TemporaryKeyStoreBuilder; import org.apache.nifi.security.util.TlsConfiguration; import org.apache.nifi.util.NiFiProperties; import org.apache.zookeeper.KeeperException; @@ -42,7 +42,6 @@ import org.junit.rules.ExpectedException; import java.io.File; import java.io.IOException; import java.nio.file.Paths; -import java.security.GeneralSecurityException; import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -70,10 +69,8 @@ public class ITZooKeeperStateServerTLS { public ExpectedException expectedException = ExpectedException.none(); @BeforeClass - public static void setTlsConfiguration() throws GeneralSecurityException, IOException { - tlsConfiguration = KeyStoreUtils.createTlsConfigAndNewKeystoreTruststore(); - new File(tlsConfiguration.getTruststorePath()).deleteOnExit(); - new File(tlsConfiguration.getKeystorePath()).deleteOnExit(); + public static void setTlsConfiguration() { + tlsConfiguration = new TemporaryKeyStoreBuilder().build(); SECURE_NIFI_PROPS.put(NiFiProperties.STATE_MANAGEMENT_ZOOKEEPER_PROPERTIES, SECURE_ZOOKEEPER_PROPS); SECURE_NIFI_PROPS.put(NiFiProperties.WEB_HTTPS_PORT, "8443"); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/state/server/TestZooKeeperStateServerConfigurations.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/state/server/TestZooKeeperStateServerConfigurations.java index a321f1798c..3abf23ac40 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/state/server/TestZooKeeperStateServerConfigurations.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/state/server/TestZooKeeperStateServerConfigurations.java @@ -17,7 +17,7 @@ package org.apache.nifi.controller.state.server; import org.apache.commons.io.FileUtils; -import org.apache.nifi.security.util.KeyStoreUtils; +import org.apache.nifi.security.util.TemporaryKeyStoreBuilder; import org.apache.nifi.security.util.TlsConfiguration; import org.apache.nifi.util.NiFiProperties; import org.apache.zookeeper.server.ServerCnxnFactory; @@ -30,7 +30,6 @@ import org.junit.Test; import java.io.File; import java.io.IOException; -import java.security.GeneralSecurityException; import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -66,10 +65,8 @@ public class TestZooKeeperStateServerConfigurations { private static TlsConfiguration tlsConfiguration; @BeforeClass - public static void setTlsConfiguration() throws GeneralSecurityException, IOException { - tlsConfiguration = KeyStoreUtils.createTlsConfigAndNewKeystoreTruststore(); - new File(tlsConfiguration.getTruststorePath()).deleteOnExit(); - new File(tlsConfiguration.getKeystorePath()).deleteOnExit(); + public static void setTlsConfiguration() { + tlsConfiguration = new TemporaryKeyStoreBuilder().build(); SECURE_NIFI_PROPS.put(NiFiProperties.STATE_MANAGEMENT_ZOOKEEPER_PROPERTIES, SECURE_ZOOKEEPER_PROPS); SECURE_NIFI_PROPS.put(NiFiProperties.WEB_HTTPS_PORT, "8443"); 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 452210d1b0..e7804d7e70 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 @@ -20,8 +20,8 @@ import org.apache.nifi.bundle.Bundle import org.apache.nifi.nar.ExtensionManagerHolder import org.apache.nifi.processor.DataUnit import org.apache.nifi.remote.io.socket.NetworkUtils -import org.apache.nifi.security.util.KeyStoreUtils import org.apache.nifi.security.util.StandardTlsConfiguration +import org.apache.nifi.security.util.TemporaryKeyStoreBuilder import org.apache.nifi.security.util.TlsConfiguration import org.apache.nifi.security.util.TlsPlatform import org.apache.nifi.util.NiFiProperties @@ -81,7 +81,7 @@ class JettyServerGroovyTest extends GroovyTestCase { private static final String TLS_1_3_PROTOCOL = "TLSv1.3" private static final List TLS_1_3_CIPHER_SUITES = ["TLS_AES_128_GCM_SHA256"] - private static final TlsConfiguration TLS_CONFIGURATION = KeyStoreUtils.createTlsConfigAndNewKeystoreTruststore() + private static final TlsConfiguration TLS_CONFIGURATION = new TemporaryKeyStoreBuilder().build() // These protocol versions should not ever be supported static private final List LEGACY_TLS_PROTOCOLS = ["TLS", "TLSv1", "TLSv1.1", "SSL", "SSLv2", "SSLv2Hello", "SSLv3"] diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/java/org/apache/nifi/web/server/util/TrustStoreScannerTest.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/java/org/apache/nifi/web/server/util/TrustStoreScannerTest.java index fe7e0218df..c221caf190 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/java/org/apache/nifi/web/server/util/TrustStoreScannerTest.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/java/org/apache/nifi/web/server/util/TrustStoreScannerTest.java @@ -16,11 +16,10 @@ */ package org.apache.nifi.web.server.util; -import org.apache.nifi.security.util.KeyStoreUtils; +import org.apache.nifi.security.util.TemporaryKeyStoreBuilder; import org.apache.nifi.security.util.TlsConfiguration; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.util.ssl.SslContextFactory; -import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; @@ -29,9 +28,7 @@ import org.mockito.Mockito; import java.io.File; import java.io.IOException; -import java.nio.file.Files; import java.nio.file.Paths; -import java.security.GeneralSecurityException; import java.util.function.Consumer; public class TrustStoreScannerTest { @@ -42,8 +39,8 @@ public class TrustStoreScannerTest { private static File trustStoreFile; @BeforeClass - public static void initClass() throws GeneralSecurityException, IOException { - TlsConfiguration tlsConfiguration = KeyStoreUtils.createTlsConfigAndNewKeystoreTruststore(); + public static void initClass() { + TlsConfiguration tlsConfiguration = new TemporaryKeyStoreBuilder().build(); keyStoreFile = Paths.get(tlsConfiguration.getKeystorePath()).toFile(); trustStoreFile = Paths.get(tlsConfiguration.getTruststorePath()).toFile(); } @@ -85,10 +82,4 @@ public class TrustStoreScannerTest { Mockito.verify(sslContextFactory).reload(ArgumentMatchers.any(Consumer.class)); } - - @AfterClass - public static void tearDown() throws IOException { - Files.deleteIfExists(keyStoreFile.toPath()); - Files.deleteIfExists(trustStoreFile.toPath()); - } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/saml/impl/TestStandardSAMLService.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/saml/impl/TestStandardSAMLService.java index b33d756d14..2bb0df2cc0 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/saml/impl/TestStandardSAMLService.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/saml/impl/TestStandardSAMLService.java @@ -17,7 +17,7 @@ package org.apache.nifi.web.security.saml.impl; import org.apache.commons.lang3.SystemUtils; -import org.apache.nifi.security.util.KeyStoreUtils; +import org.apache.nifi.security.util.TemporaryKeyStoreBuilder; import org.apache.nifi.security.util.TlsConfiguration; import org.apache.nifi.util.NiFiProperties; import org.apache.nifi.web.security.saml.SAMLConfigurationFactory; @@ -70,9 +70,7 @@ public class TestStandardSAMLService { final File idpMetadataFile = new File("src/test/resources/saml/sso-circle-meta.xml"); final String baseUrl = "https://localhost:8443/nifi-api"; - final TlsConfiguration tlsConfiguration = KeyStoreUtils.createTlsConfigAndNewKeystoreTruststore(); - new File(tlsConfiguration.getKeystorePath()).deleteOnExit(); - new File(tlsConfiguration.getTruststorePath()).deleteOnExit(); + final TlsConfiguration tlsConfiguration = new TemporaryKeyStoreBuilder().build(); when(properties.getProperty(NiFiProperties.SECURITY_KEYSTORE)).thenReturn(tlsConfiguration.getKeystorePath()); when(properties.getProperty(NiFiProperties.SECURITY_KEYSTORE_PASSWD)).thenReturn(tlsConfiguration.getKeystorePassword()); diff --git a/nifi-nar-bundles/nifi-mqtt-bundle/nifi-mqtt-processors/src/test/java/org/apache/nifi/processors/mqtt/TestConsumeMQTT.java b/nifi-nar-bundles/nifi-mqtt-bundle/nifi-mqtt-processors/src/test/java/org/apache/nifi/processors/mqtt/TestConsumeMQTT.java index 3d7edb0f3e..861a60689b 100644 --- a/nifi-nar-bundles/nifi-mqtt-bundle/nifi-mqtt-processors/src/test/java/org/apache/nifi/processors/mqtt/TestConsumeMQTT.java +++ b/nifi-nar-bundles/nifi-mqtt-bundle/nifi-mqtt-processors/src/test/java/org/apache/nifi/processors/mqtt/TestConsumeMQTT.java @@ -23,8 +23,8 @@ import org.apache.nifi.processors.mqtt.common.MQTTQueueMessage; import org.apache.nifi.processors.mqtt.common.MqttTestClient; import org.apache.nifi.processors.mqtt.common.TestConsumeMqttCommon; import org.apache.nifi.reporting.InitializationException; -import org.apache.nifi.security.util.KeyStoreUtils; import org.apache.nifi.security.util.SslContextFactory; +import org.apache.nifi.security.util.TemporaryKeyStoreBuilder; import org.apache.nifi.security.util.TlsConfiguration; import org.apache.nifi.security.util.TlsException; import org.apache.nifi.ssl.SSLContextService; @@ -42,10 +42,8 @@ import org.junit.Test; import javax.net.ssl.SSLContext; import java.io.File; import java.io.FilenameFilter; -import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Proxy; -import java.security.GeneralSecurityException; import java.util.concurrent.BlockingQueue; import static org.junit.Assert.assertTrue; @@ -53,7 +51,6 @@ import static org.junit.Assert.fail; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; - public class TestConsumeMQTT extends TestConsumeMqttCommon { private static TlsConfiguration tlsConfiguration; @@ -73,10 +70,8 @@ public class TestConsumeMQTT extends TestConsumeMqttCommon { } @BeforeClass - public static void setTlsConfiguration() throws IOException, GeneralSecurityException { - tlsConfiguration = KeyStoreUtils.createTlsConfigAndNewKeystoreTruststore(); - new File(tlsConfiguration.getKeystorePath()).deleteOnExit(); - new File(tlsConfiguration.getTruststorePath()).deleteOnExit(); + public static void setTlsConfiguration() { + tlsConfiguration = new TemporaryKeyStoreBuilder().build(); } @Before diff --git a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/InvokeHTTPTest.java b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/InvokeHTTPTest.java index ddc2279f5e..387c2e8a5a 100644 --- a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/InvokeHTTPTest.java +++ b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/InvokeHTTPTest.java @@ -23,8 +23,8 @@ import org.apache.commons.lang3.StringUtils; import org.apache.nifi.flowfile.attributes.CoreAttributes; import org.apache.nifi.processor.Relationship; import org.apache.nifi.reporting.InitializationException; -import org.apache.nifi.security.util.KeyStoreUtils; import org.apache.nifi.security.util.StandardTlsConfiguration; +import org.apache.nifi.security.util.TemporaryKeyStoreBuilder; import org.apache.nifi.security.util.TlsConfiguration; import org.apache.nifi.security.util.TlsException; import org.apache.nifi.ssl.SSLContextService; @@ -34,7 +34,6 @@ import org.apache.nifi.util.TestRunner; import org.apache.nifi.util.TestRunners; import org.apache.nifi.web.util.ssl.SslContextUtils; import org.junit.After; -import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; @@ -44,8 +43,6 @@ import javax.net.ssl.SSLSocketFactory; import java.io.IOException; import java.net.MalformedURLException; import java.net.URI; -import java.nio.file.Files; -import java.nio.file.Paths; import java.security.GeneralSecurityException; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; @@ -130,8 +127,8 @@ public class InvokeHTTPTest { private TestRunner runner; @BeforeClass - public static void setStores() throws IOException, GeneralSecurityException { - generatedTlsConfiguration = KeyStoreUtils.createTlsConfigAndNewKeystoreTruststore(); + public static void setStores() { + generatedTlsConfiguration = new TemporaryKeyStoreBuilder().build(); truststoreTlsConfiguration = new StandardTlsConfiguration( null, null, @@ -142,12 +139,6 @@ public class InvokeHTTPTest { ); } - @AfterClass - public static void deleteStores() throws IOException { - Files.deleteIfExists(Paths.get(generatedTlsConfiguration.getKeystorePath())); - Files.deleteIfExists(Paths.get(generatedTlsConfiguration.getTruststorePath())); - } - @Before public void setRunner() { mockWebServer = new MockWebServer(); diff --git a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestListenHTTP.java b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestListenHTTP.java index 48d911ec82..7d3006014e 100644 --- a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestListenHTTP.java +++ b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestListenHTTP.java @@ -44,14 +44,13 @@ import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; -import org.apache.commons.lang3.StringUtils; import org.apache.nifi.processor.ProcessContext; import org.apache.nifi.processor.ProcessSessionFactory; import org.apache.nifi.remote.io.socket.NetworkUtils; import org.apache.nifi.reporting.InitializationException; -import org.apache.nifi.security.util.KeyStoreUtils; import org.apache.nifi.security.util.SslContextFactory; import org.apache.nifi.security.util.StandardTlsConfiguration; +import org.apache.nifi.security.util.TemporaryKeyStoreBuilder; import org.apache.nifi.security.util.TlsConfiguration; import org.apache.nifi.ssl.RestrictedSSLContextService; import org.apache.nifi.ssl.SSLContextService; @@ -62,7 +61,6 @@ import org.apache.nifi.web.util.ssl.SslContextUtils; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.util.thread.ThreadPool; import org.junit.After; -import org.junit.AfterClass; import org.junit.Assert; import org.junit.Assume; import org.junit.Before; @@ -113,9 +111,9 @@ public class TestListenHTTP { private int availablePort; @BeforeClass - public static void setUpSuite() throws GeneralSecurityException, IOException { + public static void setUpSuite() throws GeneralSecurityException { // generate new keystore and truststore - tlsConfiguration = KeyStoreUtils.createTlsConfigAndNewKeystoreTruststore(); + tlsConfiguration = new TemporaryKeyStoreBuilder().build(); serverConfiguration = new StandardTlsConfiguration( tlsConfiguration.getKeystorePath(), @@ -170,27 +168,6 @@ public class TestListenHTTP { ); } - @AfterClass - public static void afterClass() throws Exception { - if (tlsConfiguration != null) { - try { - if (StringUtils.isNotBlank(tlsConfiguration.getKeystorePath())) { - Files.deleteIfExists(Paths.get(tlsConfiguration.getKeystorePath())); - } - } catch (IOException e) { - throw new IOException("There was an error deleting a keystore: " + e.getMessage(), e); - } - - try { - if (StringUtils.isNotBlank(tlsConfiguration.getTruststorePath())) { - Files.deleteIfExists(Paths.get(tlsConfiguration.getTruststorePath())); - } - } catch (IOException e) { - throw new IOException("There was an error deleting a truststore: " + e.getMessage(), e); - } - } - } - @Before public void setup() throws IOException { proc = new ListenHTTP(); diff --git a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestPutTCP.java b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestPutTCP.java index 246ff57b47..aa52f1b57c 100644 --- a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestPutTCP.java +++ b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestPutTCP.java @@ -25,7 +25,7 @@ import org.apache.nifi.event.transport.message.ByteArrayMessage; import org.apache.nifi.event.transport.netty.ByteArrayMessageNettyEventServerFactory; import org.apache.nifi.event.transport.netty.NettyEventServerFactory; import org.apache.nifi.remote.io.socket.NetworkUtils; -import org.apache.nifi.security.util.KeyStoreUtils; +import org.apache.nifi.security.util.TemporaryKeyStoreBuilder; import org.apache.nifi.security.util.TlsConfiguration; import org.apache.nifi.ssl.SSLContextService; import org.apache.nifi.util.TestRunner; @@ -114,7 +114,7 @@ public class TestPutTCP { @Test public void testRunSuccessSslContextService() throws Exception { - final TlsConfiguration tlsConfiguration = KeyStoreUtils.createTlsConfigAndNewKeystoreTruststore(); + final TlsConfiguration tlsConfiguration = new TemporaryKeyStoreBuilder().build(); final SSLContext sslContext = SslContextUtils.createSslContext(tlsConfiguration); assertNotNull("SSLContext not found", sslContext); diff --git a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-web-test-utils/src/main/java/org/apache/nifi/web/util/ssl/SslContextUtils.java b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-web-test-utils/src/main/java/org/apache/nifi/web/util/ssl/SslContextUtils.java index 71a0a1f790..f3f09fa0c7 100644 --- a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-web-test-utils/src/main/java/org/apache/nifi/web/util/ssl/SslContextUtils.java +++ b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-web-test-utils/src/main/java/org/apache/nifi/web/util/ssl/SslContextUtils.java @@ -17,9 +17,9 @@ package org.apache.nifi.web.util.ssl; import org.apache.commons.lang3.StringUtils; -import org.apache.nifi.security.util.KeyStoreUtils; import org.apache.nifi.security.util.SslContextFactory; import org.apache.nifi.security.util.StandardTlsConfiguration; +import org.apache.nifi.security.util.TemporaryKeyStoreBuilder; import org.apache.nifi.security.util.TlsConfiguration; import org.apache.nifi.security.util.TlsException; @@ -35,9 +35,7 @@ public class SslContextUtils { static { try { - TLS_CONFIGURATION = KeyStoreUtils.createTlsConfigAndNewKeystoreTruststore(); - new File(TLS_CONFIGURATION.getKeystorePath()).deleteOnExit(); - new File(TLS_CONFIGURATION.getTruststorePath()).deleteOnExit(); + TLS_CONFIGURATION = new TemporaryKeyStoreBuilder().build(); KEYSTORE_TLS_CONFIGURATION = new StandardTlsConfiguration( TLS_CONFIGURATION.getKeystorePath(), 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 0c986fa769..ae32e01c00 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 @@ -23,14 +23,13 @@ import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.StandardCopyOption; -import java.security.GeneralSecurityException; import java.util.Collection; import java.util.HashMap; import java.util.Map; import org.apache.nifi.components.ValidationContext; import org.apache.nifi.components.ValidationResult; import org.apache.nifi.reporting.InitializationException; -import org.apache.nifi.security.util.KeyStoreUtils; +import org.apache.nifi.security.util.TemporaryKeyStoreBuilder; import org.apache.nifi.security.util.TlsConfiguration; import org.apache.nifi.util.MockProcessContext; import org.apache.nifi.util.MockValidationContext; @@ -44,10 +43,8 @@ public class SSLContextServiceTest { private static TlsConfiguration tlsConfiguration; @BeforeClass - public static void setTlsConfiguration() throws GeneralSecurityException, IOException { - tlsConfiguration = KeyStoreUtils.createTlsConfigAndNewKeystoreTruststore(); - new File(tlsConfiguration.getKeystorePath()).deleteOnExit(); - new File(tlsConfiguration.getTruststorePath()).deleteOnExit(); + public static void setTlsConfiguration() { + tlsConfiguration = new TemporaryKeyStoreBuilder().build(); } @Test 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 index 135d99373c..e889cc835a 100644 --- 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 @@ -18,12 +18,11 @@ 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.TemporaryKeyStoreBuilder; 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; @@ -32,10 +31,6 @@ 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; @@ -54,14 +49,8 @@ public class StandardRestrictedSSLContextServiceTest { 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())); + public static void setConfiguration() { + tlsConfiguration = new TemporaryKeyStoreBuilder().build(); } @Before