From 88bdeee219a5809329bd0597a21538a4d9fedb6d Mon Sep 17 00:00:00 2001 From: Paul Grey Date: Wed, 11 Oct 2023 16:11:25 -0400 Subject: [PATCH] NIFI-12200 Removed module nifi-toolkit-tls This closes #7879 Signed-off-by: David Handermann --- .github/workflows/ci-workflow.yml | 1 - .../minifi-c2-integration-tests/README.md | 12 +- .../minifi-c2-integration-tests/pom.xml | 9 +- .../integration/test/AbstractTestSecure.java | 212 --------- ...gatingConfigurationProviderSecureTest.java | 79 ---- .../FileSystemCacheProviderSecureTest.java | 69 --- minifi/minifi-integration-tests/README.md | 10 +- minifi/minifi-integration-tests/pom.xml | 11 - .../c2/C2ProtocolIntegrationTest.java | 123 ----- .../c2/HierarchicalC2IntegrationTest.java | 134 ------ minifi/pom.xml | 5 - nifi-docs/src/main/asciidoc/walkthroughs.adoc | 2 +- .../src/test/resources/keys/README.md | 39 +- .../nifi-toolkit-assembly/docker/Dockerfile | 3 - .../docker/Dockerfile.hub | 3 - .../docker/tests/exit-codes.sh | 3 - .../docker/tests/tls-toolkit.sh | 17 - nifi-toolkit/nifi-toolkit-assembly/pom.xml | 27 -- .../src/main/resources/bin/tls-toolkit.bat | 41 -- .../src/main/resources/bin/tls-toolkit.sh | 119 ----- .../nifi-toolkit-encrypt-config/pom.xml | 11 - .../properties/ConfigEncryptionTool.groovy | 4 +- .../CommandLineParseException.java | 2 +- .../nifi/toolkit/commandline}/ExitCode.java | 2 +- .../ConfigEncryptionToolTest.groovy | 1 - nifi-toolkit/nifi-toolkit-tls/pom.xml | 141 ------ .../nifi/toolkit/tls/TlsToolkitMain.java | 117 ----- .../tls/commandLine/BaseCommandLine.java | 112 ----- .../BaseTlsToolkitCommandLine.java | 157 ------- .../tls/configuration/GetStatusConfig.java | 41 -- .../tls/configuration/InstanceDefinition.java | 118 ----- .../tls/configuration/InstanceIdentifier.java | 176 ------- .../tls/configuration/StandaloneConfig.java | 102 ---- .../tls/configuration/TlsClientConfig.java | 85 ---- .../toolkit/tls/configuration/TlsConfig.java | 237 ---------- .../toolkit/tls/manager/BaseTlsManager.java | 177 ------- .../TlsCertificateAuthorityManager.java | 65 --- .../toolkit/tls/manager/TlsClientManager.java | 118 ----- .../manager/writer/ConfigurationWriter.java | 38 -- .../writer/JsonConfigurationWriter.java | 48 -- .../NifiPropertiesTlsClientConfigWriter.java | 127 ----- .../tls/properties/NiFiPropertiesWriter.java | 93 ---- .../NiFiPropertiesWriterFactory.java | 59 --- .../BaseCertificateAuthorityCommandLine.java | 117 ----- .../client/TlsCertificateAuthorityClient.java | 90 ---- ...CertificateAuthorityClientCommandLine.java | 173 ------- ...rtificateAuthorityClientSocketFactory.java | 77 --- ...TlsCertificateSigningRequestPerformer.java | 161 ------- .../dto/TlsCertificateAuthorityRequest.java | 57 --- .../dto/TlsCertificateAuthorityResponse.java | 70 --- .../TlsCertificateAuthorityService.java | 129 ------ ...ertificateAuthorityServiceCommandLine.java | 111 ----- ...TlsCertificateAuthorityServiceHandler.java | 149 ------ .../tls/standalone/TlsToolkitStandalone.java | 339 -------------- .../TlsToolkitStandaloneCommandLine.java | 301 ------------ .../tls/status/TlsToolkitGetStatus.java | 50 -- .../TlsToolkitGetStatusCommandLine.java | 142 ------ .../toolkit/tls/util/InputStreamFactory.java | 26 -- .../toolkit/tls/util/OutputStreamFactory.java | 26 -- .../nifi/toolkit/tls/util/PasswordUtil.java | 65 --- .../tls/util/PasswordsExhaustedException.java | 24 - .../nifi/toolkit/tls/util/TlsHelper.java | 437 ------------------ .../configuration/InstanceDefinitionTest.java | 133 ------ .../configuration/InstanceIdentifierTest.java | 164 ------- ...fiPropertiesTlsClientConfigWriterTest.java | 148 ------ .../properties/NifiPropertiesWriterTest.java | 77 --- .../service/TlsCertificateAuthorityTest.java | 282 ----------- ...ificateAuthorityClientCommandLineTest.java | 178 ------- ...ertificateSigningRequestPerformerTest.java | 218 --------- ...ficateAuthorityServiceCommandLineTest.java | 152 ------ ...ertificateAuthorityServiceHandlerTest.java | 203 -------- .../toolkit/tls/util/PasswordUtilTest.java | 44 -- .../nifi/toolkit/tls/util/TlsHelperTest.java | 376 --------------- .../src/test/resources/empty-keystore.jks | Bin 32 -> 0 bytes .../src/test/resources/keystore.jks | Bin 3975 -> 0 bytes .../test/resources/localhost/nifi.properties | 172 ------- .../test/resources/localhost/truststore.jks | Bin 911 -> 0 bytes .../src/test/resources/overlay.properties | 41 -- .../src/test/resources/rootCert-pkcs8.key | 28 -- .../src/test/resources/rootCert.crt | 20 - .../src/test/resources/rootCert.key | 27 -- nifi-toolkit/pom.xml | 1 - 82 files changed, 27 insertions(+), 7731 deletions(-) delete mode 100644 minifi/minifi-c2/minifi-c2-integration-tests/src/test/java/org/apache/nifi/minifi/c2/integration/test/AbstractTestSecure.java delete mode 100644 minifi/minifi-c2/minifi-c2-integration-tests/src/test/java/org/apache/nifi/minifi/c2/integration/test/DelegatingConfigurationProviderSecureTest.java delete mode 100644 minifi/minifi-c2/minifi-c2-integration-tests/src/test/java/org/apache/nifi/minifi/c2/integration/test/FileSystemCacheProviderSecureTest.java delete mode 100644 minifi/minifi-integration-tests/src/test/java/org/apache/nifi/minifi/integration/c2/C2ProtocolIntegrationTest.java delete mode 100644 minifi/minifi-integration-tests/src/test/java/org/apache/nifi/minifi/integration/c2/HierarchicalC2IntegrationTest.java delete mode 100755 nifi-toolkit/nifi-toolkit-assembly/docker/tests/tls-toolkit.sh delete mode 100644 nifi-toolkit/nifi-toolkit-assembly/src/main/resources/bin/tls-toolkit.bat delete mode 100644 nifi-toolkit/nifi-toolkit-assembly/src/main/resources/bin/tls-toolkit.sh rename nifi-toolkit/{nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/commandLine => nifi-toolkit-encrypt-config/src/main/java/org/apache/nifi/toolkit/commandline}/CommandLineParseException.java (96%) rename nifi-toolkit/{nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/commandLine => nifi-toolkit-encrypt-config/src/main/java/org/apache/nifi/toolkit/commandline}/ExitCode.java (97%) delete mode 100644 nifi-toolkit/nifi-toolkit-tls/pom.xml delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/TlsToolkitMain.java delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/commandLine/BaseCommandLine.java delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/commandLine/BaseTlsToolkitCommandLine.java delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/configuration/GetStatusConfig.java delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/configuration/InstanceDefinition.java delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/configuration/InstanceIdentifier.java delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/configuration/StandaloneConfig.java delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/configuration/TlsClientConfig.java delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/configuration/TlsConfig.java delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/manager/BaseTlsManager.java delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/manager/TlsCertificateAuthorityManager.java delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/manager/TlsClientManager.java delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/manager/writer/ConfigurationWriter.java delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/manager/writer/JsonConfigurationWriter.java delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/manager/writer/NifiPropertiesTlsClientConfigWriter.java delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/properties/NiFiPropertiesWriter.java delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/properties/NiFiPropertiesWriterFactory.java delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/BaseCertificateAuthorityCommandLine.java delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/client/TlsCertificateAuthorityClient.java delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/client/TlsCertificateAuthorityClientCommandLine.java delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/client/TlsCertificateAuthorityClientSocketFactory.java delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/client/TlsCertificateSigningRequestPerformer.java delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/dto/TlsCertificateAuthorityRequest.java delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/dto/TlsCertificateAuthorityResponse.java delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/server/TlsCertificateAuthorityService.java delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/server/TlsCertificateAuthorityServiceCommandLine.java delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/server/TlsCertificateAuthorityServiceHandler.java delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/standalone/TlsToolkitStandalone.java delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/standalone/TlsToolkitStandaloneCommandLine.java delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/status/TlsToolkitGetStatus.java delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/status/TlsToolkitGetStatusCommandLine.java delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/util/InputStreamFactory.java delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/util/OutputStreamFactory.java delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/util/PasswordUtil.java delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/util/PasswordsExhaustedException.java delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/util/TlsHelper.java delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/configuration/InstanceDefinitionTest.java delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/configuration/InstanceIdentifierTest.java delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/manager/writer/NifiPropertiesTlsClientConfigWriterTest.java delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/properties/NifiPropertiesWriterTest.java delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/service/TlsCertificateAuthorityTest.java delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/service/client/TlsCertificateAuthorityClientCommandLineTest.java delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/service/client/TlsCertificateSigningRequestPerformerTest.java delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/service/server/TlsCertificateAuthorityServiceCommandLineTest.java delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/service/server/TlsCertificateAuthorityServiceHandlerTest.java delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/util/PasswordUtilTest.java delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/util/TlsHelperTest.java delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/test/resources/empty-keystore.jks delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/test/resources/keystore.jks delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/test/resources/localhost/nifi.properties delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/test/resources/localhost/truststore.jks delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/test/resources/overlay.properties delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/test/resources/rootCert-pkcs8.key delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/test/resources/rootCert.crt delete mode 100644 nifi-toolkit/nifi-toolkit-tls/src/test/resources/rootCert.key diff --git a/.github/workflows/ci-workflow.yml b/.github/workflows/ci-workflow.yml index 439fdff8b6..71ed5d6d6e 100644 --- a/.github/workflows/ci-workflow.yml +++ b/.github/workflows/ci-workflow.yml @@ -44,7 +44,6 @@ env: -pl -:nifi-kafka-connector-assembly -pl -:nifi-kafka-connector-tests -pl -:nifi-toolkit-encrypt-config - -pl -:nifi-toolkit-tls -pl -:nifi-toolkit-assembly -pl -:nifi-registry-assembly -pl -:nifi-registry-toolkit-assembly diff --git a/minifi/minifi-c2/minifi-c2-integration-tests/README.md b/minifi/minifi-c2/minifi-c2-integration-tests/README.md index 3fad96200a..cf5d005bb7 100644 --- a/minifi/minifi-c2/minifi-c2-integration-tests/README.md +++ b/minifi/minifi-c2/minifi-c2-integration-tests/README.md @@ -17,11 +17,11 @@ ## How to execute minifi-c2-integration-tests ### Build required modules -mvn -pl minifi/minifi-assembly -am install -T1C -DskipTests -mvn -pl minifi/minifi-docker -am install -T1C -DskipTests -P docker -mvn -pl minifi/minifi-c2/minifi-c2-assembly -am install -T1C -DskipTests -mvn -pl minifi/minifi-c2/minifi-c2-docker -am install -T1C -DskipTests -P docker -mvn -pl nifi-toolkit/nifi-toolkit-assembly -am install -T1C -DskipTests +- mvn -pl minifi/minifi-assembly -am install -T1C -DskipTests +- mvn -pl minifi/minifi-docker -am install -T1C -DskipTests -P docker +- mvn -pl minifi/minifi-c2/minifi-c2-assembly -am install -T1C -DskipTests +- mvn -pl minifi/minifi-c2/minifi-c2-docker -am install -T1C -DskipTests -P docker +- mvn -pl nifi-toolkit/nifi-toolkit-assembly -am install -T1C -DskipTests ### Execute integration tests -mvn verify -Pdocker -f minifi/minifi-c2/minifi-c2-integration-tests/pom.xml \ No newline at end of file +- mvn verify -Pdocker -f minifi/minifi-c2/minifi-c2-integration-tests/pom.xml \ No newline at end of file diff --git a/minifi/minifi-c2/minifi-c2-integration-tests/pom.xml b/minifi/minifi-c2/minifi-c2-integration-tests/pom.xml index 32755c4dea..494f1be861 100644 --- a/minifi/minifi-c2/minifi-c2-integration-tests/pom.xml +++ b/minifi/minifi-c2/minifi-c2-integration-tests/pom.xml @@ -38,14 +38,9 @@ limitations under the License. org.apache.nifi - nifi-toolkit-tls + nifi-security-utils + ${project.version} test - - - org.slf4j - slf4j-log4j12 - - com.palantir.docker.compose diff --git a/minifi/minifi-c2/minifi-c2-integration-tests/src/test/java/org/apache/nifi/minifi/c2/integration/test/AbstractTestSecure.java b/minifi/minifi-c2/minifi-c2-integration-tests/src/test/java/org/apache/nifi/minifi/c2/integration/test/AbstractTestSecure.java deleted file mode 100644 index db6635f39f..0000000000 --- a/minifi/minifi-c2/minifi-c2-integration-tests/src/test/java/org/apache/nifi/minifi/c2/integration/test/AbstractTestSecure.java +++ /dev/null @@ -1,212 +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.minifi.c2.integration.test; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import com.palantir.docker.compose.DockerComposeExtension; -import com.palantir.docker.compose.connection.DockerPort; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.InetSocketAddress; -import java.net.Proxy; -import java.net.URI; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.security.GeneralSecurityException; -import java.security.KeyStore; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.SSLContext; -import javax.net.ssl.TrustManagerFactory; -import org.apache.commons.io.IOUtils; -import org.apache.nifi.controller.flow.VersionedDataflow; -import org.apache.nifi.security.util.KeyStoreUtils; -import org.apache.nifi.security.util.KeystoreType; -import org.apache.nifi.security.util.SslContextFactory; -import org.apache.nifi.security.util.StandardTlsConfiguration; -import org.apache.nifi.security.util.TlsConfiguration; -import org.apache.nifi.toolkit.tls.standalone.TlsToolkitStandalone; -import org.apache.nifi.toolkit.tls.standalone.TlsToolkitStandaloneCommandLine; -import org.junit.jupiter.api.Test; - -public abstract class AbstractTestSecure extends AbstractTestUnsecure { - public static final String C2_URL = "https://c2:10443/c2/config"; - - private final DockerComposeExtension docker; - private final Path certificatesDirectory; - private final SSLContext trustSslContext; - - protected AbstractTestSecure(DockerComposeExtension docker, Path certificatesDirectory, SSLContext trustSslContext) { - this.docker = docker; - this.certificatesDirectory = certificatesDirectory; - this.trustSslContext = trustSslContext; - } - - @Override - protected String getConfigUrl(DockerComposeExtension docker) { - return C2_URL; - } - - public static SSLContext initCertificates(Path certificatesDirectory, List serverHostnames) throws Exception { - List toolkitCommandLine = new ArrayList<>(Arrays.asList("-O", "-o", certificatesDirectory.toFile().getAbsolutePath(), - "-C", "CN=user1", "-C", "CN=user2", "-C", "CN=user3", "-C", "CN=user4", "-S", "badKeystorePass", "-K", "badKeyPass", "-P", "badTrustPass")); - for (String serverHostname : serverHostnames) { - toolkitCommandLine.add("-n"); - toolkitCommandLine.add(serverHostname); - } - Files.createDirectories(certificatesDirectory); - TlsToolkitStandaloneCommandLine tlsToolkitStandaloneCommandLine = new TlsToolkitStandaloneCommandLine(); - tlsToolkitStandaloneCommandLine.parse(toolkitCommandLine.toArray(new String[0])); - new TlsToolkitStandalone().createNifiKeystoresAndTrustStores(tlsToolkitStandaloneCommandLine.createConfig()); - - tlsToolkitStandaloneCommandLine = new TlsToolkitStandaloneCommandLine(); - tlsToolkitStandaloneCommandLine.parse("-O", "-o", certificatesDirectory.getParent().resolve("badCert").toFile().getAbsolutePath(), "-C", "CN=user3"); - new TlsToolkitStandalone().createNifiKeystoresAndTrustStores(tlsToolkitStandaloneCommandLine.createConfig()); - - final KeyStore trustStore = KeyStoreUtils.getKeyStore("jks"); - try (final InputStream trustStoreStream = new FileInputStream(certificatesDirectory.resolve("c2").resolve("truststore.jks").toFile().getAbsolutePath())) { - trustStore.load(trustStoreStream, "badTrustPass".toCharArray()); - } - final TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); - trustManagerFactory.init(trustStore); - - TlsConfiguration tlsConfiguration = new StandardTlsConfiguration( - null, null, null, - certificatesDirectory.resolve("c2").resolve("truststore.jks").toFile().getAbsolutePath(), "badTrustPass", KeystoreType.JKS); - - - return SslContextFactory.createSslContext(tlsConfiguration); - } - - @Test - public void testNoClientCert() throws Exception { - assertReturnCode("", trustSslContext, 403); - assertReturnCode("?class=raspi2", trustSslContext, 403); - assertReturnCode("?class=raspi3", trustSslContext, 403); - } - - @Test - public void testUser1() throws Exception { - SSLContext sslContext = loadSslContext("user1"); - - assertReturnCode("", sslContext, 403); - - VersionedDataflow versionedDataflow = assertReturnCode("?class=raspi2", sslContext, 200); - assertEquals("raspi2.v1", versionedDataflow.getRootGroup().getName()); - - assertReturnCode("?class=raspi3", sslContext, 403); - } - - @Test - public void testUser2() throws Exception { - SSLContext sslContext = loadSslContext("user2"); - - assertReturnCode("", sslContext, 403); - assertReturnCode("?class=raspi2", sslContext, 403); - - VersionedDataflow versionedDataflow = assertReturnCode("?class=raspi3", sslContext, 200); - assertEquals("raspi3.v2", versionedDataflow.getRootGroup().getName()); - } - - @Test - public void testUser3() throws Exception { - SSLContext sslContext = loadSslContext("user3"); - - assertReturnCode("", sslContext, 400); - - VersionedDataflow dataflowRaspi2 = assertReturnCode("?class=raspi2", sslContext, 200); - assertEquals("raspi2.v1", dataflowRaspi2.getRootGroup().getName()); - - VersionedDataflow dataflowRaspi3 = assertReturnCode("?class=raspi3", sslContext, 200); - assertEquals("raspi3.v2", dataflowRaspi3.getRootGroup().getName()); - } - - @Test - public void testUser3WrongCA() { - assertThrows(IOException.class, () -> assertReturnCode("?class=raspi3", loadSslContext("user3", certificatesDirectory.getParent().resolve("badCert")), 403)); - } - - @Test - public void testUser4() throws Exception { - SSLContext sslContext = loadSslContext("user4"); - - assertReturnCode("", sslContext, 403); - assertReturnCode("?class=raspi2", sslContext, 403); - assertReturnCode("?class=raspi3", sslContext, 403); - } - - protected SSLContext loadSslContext(String username) throws GeneralSecurityException, IOException { - return loadSslContext(username, certificatesDirectory); - } - - protected SSLContext loadSslContext(String username, Path directory) throws GeneralSecurityException, IOException { - String keystorePasswd; - try (InputStream inputStream = Files.newInputStream(directory.resolve("CN=" + username + ".password"))) { - keystorePasswd = IOUtils.toString(inputStream, StandardCharsets.UTF_8); - } - TlsConfiguration tlsConfiguration = new StandardTlsConfiguration( - directory.resolve("CN=" + username + ".p12").toFile().getAbsolutePath(), - keystorePasswd, - KeystoreType.PKCS12, - certificatesDirectory.resolve("c2").resolve("truststore.jks").toFile().getAbsolutePath(), - "badTrustPass", - KeystoreType.JKS); - - return SslContextFactory.createSslContext(tlsConfiguration); - } - - protected VersionedDataflow assertReturnCode(String query, SSLContext sslContext, int expectedReturnCode) throws Exception { - HttpsURLConnection httpsURLConnection = openUrlConnection(C2_URL + query, sslContext); - httpsURLConnection.setRequestProperty("Accept", "application/json"); - try { - assertEquals(expectedReturnCode, httpsURLConnection.getResponseCode()); - if (expectedReturnCode == 200) { - try (InputStream inputStream = httpsURLConnection.getInputStream()) { - return toVersionedDataFlow(inputStream); - } - } - } finally { - httpsURLConnection.disconnect(); - } - return null; - } - - protected HttpsURLConnection openUrlConnection(String url, SSLContext sslContext) throws IOException { - DockerPort dockerPort = docker.containers().container("squid").port(3128); - HttpsURLConnection httpURLConnection = (HttpsURLConnection) URI.create(url).toURL().openConnection( - new Proxy(Proxy.Type.HTTP, new InetSocketAddress(dockerPort.getIp(), dockerPort.getExternalPort()))); - httpURLConnection.setSSLSocketFactory(sslContext.getSocketFactory()); - return httpURLConnection; - } - - @Override - protected HttpURLConnection openSuperUserUrlConnection(String url) throws IOException { - try { - return openUrlConnection(url, loadSslContext("user3")); - } catch (GeneralSecurityException e) { - throw new IOException(e); - } - } -} diff --git a/minifi/minifi-c2/minifi-c2-integration-tests/src/test/java/org/apache/nifi/minifi/c2/integration/test/DelegatingConfigurationProviderSecureTest.java b/minifi/minifi-c2/minifi-c2-integration-tests/src/test/java/org/apache/nifi/minifi/c2/integration/test/DelegatingConfigurationProviderSecureTest.java deleted file mode 100644 index e86a2ca7bf..0000000000 --- a/minifi/minifi-c2/minifi-c2-integration-tests/src/test/java/org/apache/nifi/minifi/c2/integration/test/DelegatingConfigurationProviderSecureTest.java +++ /dev/null @@ -1,79 +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.minifi.c2.integration.test; - -import com.palantir.docker.compose.DockerComposeExtension; -import org.apache.nifi.minifi.c2.integration.test.health.HttpsStatusCodeHealthCheck; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSocketFactory; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Arrays; - -public class DelegatingConfigurationProviderSecureTest extends AbstractTestSecure { - public static final String C2_UPSTREAM_URL = "https://c2:10443/c2/config"; - private static SSLSocketFactory healthCheckSocketFactory; - private static Path certificatesDirectory; - private static SSLContext trustSslContext; - - // Not annotated as rule because we need to generate certificatesDirectory first - public static DockerComposeExtension docker = DockerComposeExtension.builder() - .file("target/test-classes/docker-compose-DelegatingProviderSecureTest.yml") - .waitingForServices(Arrays.asList("squid", "c2-upstream"), - new HttpsStatusCodeHealthCheck(container -> C2_UPSTREAM_URL, containers -> containers.get(0), containers -> containers.get(1), () -> healthCheckSocketFactory, 403)) - .waitingForServices(Arrays.asList("squid", "c2"), - new HttpsStatusCodeHealthCheck(container -> C2_URL, containers -> containers.get(0), containers -> containers.get(1), () -> healthCheckSocketFactory, 403)) - .build(); - - public DelegatingConfigurationProviderSecureTest() { - super(docker, certificatesDirectory, trustSslContext); - } - - /** - * Generates certificates with the tls-toolkit and then starts up the docker compose file - */ - @BeforeAll - public static void initCertificates() throws Exception { - certificatesDirectory = Paths.get(DelegatingConfigurationProviderSecureTest.class.getClassLoader() - .getResource("docker-compose-DelegatingProviderSecureTest.yml").getFile()).getParent().toAbsolutePath().resolve("certificates-DelegatingConfigurationProviderSecureTest"); - trustSslContext = initCertificates(certificatesDirectory, Arrays.asList("c2", "c2-upstream")); - healthCheckSocketFactory = trustSslContext.getSocketFactory(); - - docker.before(); - } - - @AfterAll - public static void cleanup() { - docker.after(); - } - - @BeforeEach - public void setup() { - super.setup(docker); - } - - @Test - public void testUpstreamPermissionDenied() throws Exception { - assertReturnCode("?class=raspi4", loadSslContext("user3"), 403); - } -} diff --git a/minifi/minifi-c2/minifi-c2-integration-tests/src/test/java/org/apache/nifi/minifi/c2/integration/test/FileSystemCacheProviderSecureTest.java b/minifi/minifi-c2/minifi-c2-integration-tests/src/test/java/org/apache/nifi/minifi/c2/integration/test/FileSystemCacheProviderSecureTest.java deleted file mode 100644 index 689c2cb89a..0000000000 --- a/minifi/minifi-c2/minifi-c2-integration-tests/src/test/java/org/apache/nifi/minifi/c2/integration/test/FileSystemCacheProviderSecureTest.java +++ /dev/null @@ -1,69 +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.minifi.c2.integration.test; - -import com.palantir.docker.compose.DockerComposeExtension; -import org.apache.nifi.minifi.c2.integration.test.health.HttpsStatusCodeHealthCheck; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.BeforeAll; - -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSocketFactory; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Arrays; - -public class FileSystemCacheProviderSecureTest extends AbstractTestSecure { - private static SSLSocketFactory healthCheckSocketFactory; - - // Not annotated as rule because we need to generate certificatesDirectory first - public static DockerComposeExtension docker = DockerComposeExtension.builder() - .file("target/test-classes/docker-compose-FileSystemCacheProviderSecureTest.yml") - .waitingForServices(Arrays.asList("squid", "c2"), - new HttpsStatusCodeHealthCheck(container -> C2_URL, containers -> containers.get(0), containers -> containers.get(1), () -> healthCheckSocketFactory, 403)) - .build(); - private static Path certificatesDirectory; - private static SSLContext trustSslContext; - - public FileSystemCacheProviderSecureTest() { - super(docker, certificatesDirectory, trustSslContext); - } - - /** - * Generates certificates with the tls-toolkit and then starts up the docker compose file - */ - @BeforeAll - public static void initCertificates() throws Exception { - certificatesDirectory = Paths.get(FileSystemCacheProviderSecureTest.class.getClassLoader() - .getResource("docker-compose-FileSystemCacheProviderSecureTest.yml").getFile()).getParent().toAbsolutePath().resolve("certificates-FileSystemCacheProviderSecureTest"); - trustSslContext = initCertificates(certificatesDirectory, Arrays.asList("c2")); - healthCheckSocketFactory = trustSslContext.getSocketFactory(); - docker.before(); - } - - @AfterAll - public static void cleanup() { - docker.after(); - } - - @BeforeEach - public void setup() { - super.setup(docker); - } -} diff --git a/minifi/minifi-integration-tests/README.md b/minifi/minifi-integration-tests/README.md index 6ba4866ab0..40fefb8d20 100644 --- a/minifi/minifi-integration-tests/README.md +++ b/minifi/minifi-integration-tests/README.md @@ -17,10 +17,10 @@ ## How to execute minifi-integration-tests ### Build required modules -mvn -pl minifi/minifi-assembly -am install -T1C -DskipTests -mvn -pl minifi/minifi-docker -am install -T1C -DskipTests -P docker -mvn -pl nifi-toolkit/nifi-toolkit-assembly -am install -T1C -DskipTests -mvn -pl minifi/minifi-integration-tests -am install -T1C -DskipTests +- mvn -pl minifi/minifi-assembly -am install -T1C -DskipTests +- mvn -pl minifi/minifi-docker -am install -T1C -DskipTests -P docker +- mvn -pl nifi-toolkit/nifi-toolkit-assembly -am install -T1C -DskipTests +- mvn -pl minifi/minifi-integration-tests -am install -T1C -DskipTests ### Execute integration tests -mvn verify -Pdocker -f minifi/minifi-integration-tests/pom.xml \ No newline at end of file +- mvn verify -Pdocker -f minifi/minifi-integration-tests/pom.xml \ No newline at end of file diff --git a/minifi/minifi-integration-tests/pom.xml b/minifi/minifi-integration-tests/pom.xml index b09608309e..b13268e24c 100644 --- a/minifi/minifi-integration-tests/pom.xml +++ b/minifi/minifi-integration-tests/pom.xml @@ -50,17 +50,6 @@ limitations under the License. test-jar test - - org.apache.nifi - nifi-toolkit-tls - test - - - org.slf4j - slf4j-log4j12 - - - org.apache.nifi.minifi minifi-toolkit-configuration diff --git a/minifi/minifi-integration-tests/src/test/java/org/apache/nifi/minifi/integration/c2/C2ProtocolIntegrationTest.java b/minifi/minifi-integration-tests/src/test/java/org/apache/nifi/minifi/integration/c2/C2ProtocolIntegrationTest.java deleted file mode 100644 index ba1d191b3a..0000000000 --- a/minifi/minifi-integration-tests/src/test/java/org/apache/nifi/minifi/integration/c2/C2ProtocolIntegrationTest.java +++ /dev/null @@ -1,123 +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.minifi.integration.c2; - -import com.palantir.docker.compose.DockerComposeExtension; -import com.palantir.docker.compose.connection.waiting.HealthChecks; -import org.apache.nifi.minifi.integration.util.LogUtil; -import org.apache.nifi.security.util.KeystoreType; -import org.apache.nifi.security.util.SslContextFactory; -import org.apache.nifi.security.util.StandardTlsConfiguration; -import org.apache.nifi.security.util.TlsConfiguration; -import org.apache.nifi.toolkit.tls.standalone.TlsToolkitStandalone; -import org.apache.nifi.toolkit.tls.standalone.TlsToolkitStandaloneCommandLine; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.Timeout; - -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSocketFactory; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -@Timeout(60) -public class C2ProtocolIntegrationTest { - private static final String AGENT_1 = "minifi-edge1"; - private static final String AGENT_2 = "minifi-edge2"; - private static final String AGENT_3 = "minifi-edge3"; - private static final String AGENT_CLASS_1 = "raspi3"; - private static final String AGENT_CLASS_2 = "raspi4"; - private static final String SERVICE = "c2-authoritative"; - private static final String FLOW_JSON = "config.application.json.v2"; - private static Path certificatesDirectory; - private static SSLContext trustSslContext; - private static SSLSocketFactory healthCheckSocketFactory; - public static DockerComposeExtension docker = DockerComposeExtension.builder() - .file("target/test-classes/docker-compose-c2-protocol.yml") - .waitingForService(AGENT_1, HealthChecks.toRespond2xxOverHttp(8000, dockerPort -> "http://" + dockerPort.getIp() + ":" + dockerPort.getExternalPort())) - .waitingForService(AGENT_2, HealthChecks.toRespond2xxOverHttp(8000, dockerPort -> "http://" + dockerPort.getIp() + ":" + dockerPort.getExternalPort())) - .waitingForService(AGENT_3, HealthChecks.toRespond2xxOverHttp(8000, dockerPort -> "http://" + dockerPort.getIp() + ":" + dockerPort.getExternalPort())) - .build(); - - private static Path resourceDirectory; - private static Path authoritativeFiles; - private static Path minifiEdge1Version2; - private static Path minifiEdge2Version2; - private static Path minifiEdge3Version2; - - /** - * Generates certificates with the tls-toolkit and then starts up the docker compose file - */ - @BeforeAll - public static void init() throws Exception { - resourceDirectory = Paths.get(C2ProtocolIntegrationTest.class.getClassLoader() - .getResource("docker-compose-c2-protocol.yml").getFile()).getParent(); - certificatesDirectory = resourceDirectory.toAbsolutePath().resolve("certificates-c2-protocol"); - authoritativeFiles = resourceDirectory.resolve("c2").resolve("protocol").resolve(SERVICE).resolve("files"); - minifiEdge1Version2 = authoritativeFiles.resolve("edge1").resolve(AGENT_CLASS_1).resolve(FLOW_JSON); - minifiEdge2Version2 = authoritativeFiles.resolve("edge2").resolve(AGENT_CLASS_1).resolve(FLOW_JSON); - minifiEdge3Version2 = authoritativeFiles.resolve("edge3").resolve(AGENT_CLASS_2).resolve(FLOW_JSON); - - if (Files.exists(minifiEdge1Version2)) { - Files.delete(minifiEdge1Version2); - } - if (Files.exists(minifiEdge2Version2)) { - Files.delete(minifiEdge2Version2); - } - if (Files.exists(minifiEdge3Version2)) { - Files.delete(minifiEdge3Version2); - } - - List toolkitCommandLine = new ArrayList<>(Arrays.asList("-O", "-o", certificatesDirectory.toFile().getAbsolutePath(), "-S", "badKeystorePass", "-P", "badTrustPass")); - for (String serverHostname : Arrays.asList(SERVICE, AGENT_1, AGENT_2, AGENT_3)) { - toolkitCommandLine.add("-n"); - toolkitCommandLine.add(serverHostname); - } - Files.createDirectories(certificatesDirectory); - TlsToolkitStandaloneCommandLine tlsToolkitStandaloneCommandLine = new TlsToolkitStandaloneCommandLine(); - tlsToolkitStandaloneCommandLine.parse(toolkitCommandLine.toArray(new String[toolkitCommandLine.size()])); - new TlsToolkitStandalone().createNifiKeystoresAndTrustStores(tlsToolkitStandaloneCommandLine.createConfig()); - - TlsConfiguration tlsConfiguration = new StandardTlsConfiguration( - null,null,null, - certificatesDirectory.resolve(SERVICE).resolve("truststore.jks").toFile().getAbsolutePath(), - "badTrustPass", - KeystoreType.JKS); - trustSslContext = SslContextFactory.createSslContext(tlsConfiguration); - healthCheckSocketFactory = trustSslContext.getSocketFactory(); - - docker.before(); - } - - @AfterAll - public static void stopDocker() { - docker.after(); - } - - @Test - public void testFlowPublishThroughC2Protocol() throws Exception { - LogUtil.verifyLogEntries("c2/protocol/minifi-edge1/expected.json", docker.containers().container(AGENT_1)); - LogUtil.verifyLogEntries("c2/protocol/minifi-edge2/expected.json", docker.containers().container(AGENT_2)); - LogUtil.verifyLogEntries("c2/protocol/minifi-edge3/expected.json", docker.containers().container(AGENT_3)); - } -} diff --git a/minifi/minifi-integration-tests/src/test/java/org/apache/nifi/minifi/integration/c2/HierarchicalC2IntegrationTest.java b/minifi/minifi-integration-tests/src/test/java/org/apache/nifi/minifi/integration/c2/HierarchicalC2IntegrationTest.java deleted file mode 100644 index f08cc2995a..0000000000 --- a/minifi/minifi-integration-tests/src/test/java/org/apache/nifi/minifi/integration/c2/HierarchicalC2IntegrationTest.java +++ /dev/null @@ -1,134 +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.minifi.integration.c2; - -import com.palantir.docker.compose.DockerComposeExtension; -import org.apache.nifi.minifi.c2.integration.test.health.HttpsStatusCodeHealthCheck; -import org.apache.nifi.minifi.integration.util.LogUtil; -import org.apache.nifi.security.util.KeystoreType; -import org.apache.nifi.security.util.SslContextFactory; -import org.apache.nifi.security.util.StandardTlsConfiguration; -import org.apache.nifi.security.util.TlsConfiguration; -import org.apache.nifi.toolkit.tls.standalone.TlsToolkitStandalone; -import org.apache.nifi.toolkit.tls.standalone.TlsToolkitStandaloneCommandLine; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.Timeout; - -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSocketFactory; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -@Timeout(180) -public class HierarchicalC2IntegrationTest { - private static Path certificatesDirectory; - private static SSLContext trustSslContext; - private static SSLSocketFactory healthCheckSocketFactory; - - // Not annotated as rule because we need to generate certificatesDirectory first - public static DockerComposeExtension docker = DockerComposeExtension.builder() - .file("target/test-classes/docker-compose-c2-hierarchical.yml") - .waitingForServices(Arrays.asList("squid-edge3", "c2"), - new HttpsStatusCodeHealthCheck(container -> "https://c2-authoritative:10443/c2/config", - containers -> containers.get(0), containers -> containers.get(1), () -> healthCheckSocketFactory, 403)) - .build(); - private static Path resourceDirectory; - private static Path authoritativeFiles; - private static Path minifiEdge1Version2; - private static Path minifiEdge2Version2; - private static Path minifiEdge3Version2; - - /** - * Generates certificates with the tls-toolkit and then starts up the docker compose file - */ - @BeforeAll - public static void initCertificates() throws Exception { - resourceDirectory = Paths.get(HierarchicalC2IntegrationTest.class.getClassLoader() - .getResource("docker-compose-c2-hierarchical.yml").getFile()).getParent(); - certificatesDirectory = resourceDirectory.toAbsolutePath().resolve("certificates-c2-hierarchical"); - authoritativeFiles = resourceDirectory.resolve("c2").resolve("hierarchical").resolve("c2-authoritative").resolve("files"); - minifiEdge1Version2 = authoritativeFiles.resolve("edge1").resolve("raspi3").resolve("config.application.json.v2"); - minifiEdge2Version2 = authoritativeFiles.resolve("edge2").resolve("raspi2").resolve("config.application.json.v2"); - minifiEdge3Version2 = authoritativeFiles.resolve("edge3").resolve("raspi3").resolve("config.application.json.v2"); - - if (Files.exists(minifiEdge1Version2)) { - Files.delete(minifiEdge1Version2); - } - if (Files.exists(minifiEdge2Version2)) { - Files.delete(minifiEdge2Version2); - } - if (Files.exists(minifiEdge3Version2)) { - Files.delete(minifiEdge3Version2); - } - - List toolkitCommandLine = new ArrayList<>(Arrays.asList("-O", "-o", certificatesDirectory.toFile().getAbsolutePath(), "-S", "badKeystorePass", "-P", "badTrustPass")); - for (String serverHostname : Arrays.asList("c2-authoritative", "minifi-edge1", "c2-edge2", "minifi-edge3")) { - toolkitCommandLine.add("-n"); - toolkitCommandLine.add(serverHostname); - } - Files.createDirectories(certificatesDirectory); - TlsToolkitStandaloneCommandLine tlsToolkitStandaloneCommandLine = new TlsToolkitStandaloneCommandLine(); - tlsToolkitStandaloneCommandLine.parse(toolkitCommandLine.toArray(new String[toolkitCommandLine.size()])); - new TlsToolkitStandalone().createNifiKeystoresAndTrustStores(tlsToolkitStandaloneCommandLine.createConfig()); - - TlsConfiguration tlsConfiguration = new StandardTlsConfiguration( - null,null,null, - certificatesDirectory.resolve("c2-authoritative").resolve("truststore.jks").toFile().getAbsolutePath(), - "badTrustPass", - KeystoreType.JKS); - trustSslContext = SslContextFactory.createSslContext(tlsConfiguration); - healthCheckSocketFactory = trustSslContext.getSocketFactory(); - - docker.before(); - } - - @AfterAll - public static void stopDocker() { - docker.after(); - } - - @Test - public void testMiNiFiEdge1() throws Exception { - LogUtil.verifyLogEntries("c2/hierarchical/minifi-edge1/expected.json", docker.containers().container("minifi-edge1")); - Path csvToJsonDir = resourceDirectory.resolve("standalone").resolve("CsvToJson"); - Files.copy(csvToJsonDir.resolve("CsvToJson.json"), minifiEdge1Version2); - LogUtil.verifyLogEntries("standalone/CsvToJson/expected.json", docker.containers().container("minifi-edge1")); - } - - @Test - public void testMiNiFiEdge2() throws Exception { - LogUtil.verifyLogEntries("c2/hierarchical/minifi-edge2/expected.json", docker.containers().container("minifi-edge2")); - Path csvToJsonDir = resourceDirectory.resolve("standalone").resolve("CsvToJson"); - Files.copy(csvToJsonDir.resolve("CsvToJson.json"), minifiEdge2Version2); - LogUtil.verifyLogEntries("standalone/CsvToJson/expected.json", docker.containers().container("minifi-edge2")); - } - - @Test - public void testMiNiFiEdge3() throws Exception { - LogUtil.verifyLogEntries("c2/hierarchical/minifi-edge3/expected.json", docker.containers().container("minifi-edge3")); - Path csvToJsonDir = resourceDirectory.resolve("standalone").resolve("CsvToJson"); - Files.copy(csvToJsonDir.resolve("CsvToJson.json"), minifiEdge3Version2); - LogUtil.verifyLogEntries("standalone/CsvToJson/expected.json", docker.containers().container("minifi-edge3")); - } -} diff --git a/minifi/pom.xml b/minifi/pom.xml index 8121282e03..8bdb78b72c 100644 --- a/minifi/pom.xml +++ b/minifi/pom.xml @@ -207,11 +207,6 @@ limitations under the License. nifi-runtime 2.0.0-SNAPSHOT - - org.apache.nifi - nifi-toolkit-tls - 2.0.0-SNAPSHOT - org.apache.nifi nifi-jetty-configuration diff --git a/nifi-docs/src/main/asciidoc/walkthroughs.adoc b/nifi-docs/src/main/asciidoc/walkthroughs.adoc index 5f45132c80..dee39ea11d 100644 --- a/nifi-docs/src/main/asciidoc/walkthroughs.adoc +++ b/nifi-docs/src/main/asciidoc/walkthroughs.adoc @@ -30,7 +30,7 @@ NOTE: This document is provided with no warranty. All steps have been evaluated == Installing Apache NiFi -Apache NiFi is an easy to use, powerful, and reliable system to process and distribute data. It supports powerful and scalable directed graphs of data routing, transformation, and system mediation logic. In addition to NiFi, there is the NiFi Toolkit, a collection of command-line tools which help perform administrative tasks such as interacting with remote services, generating TLS certificates, managing nodes in a cluster, and encrypting sensitive configuration values. +Apache NiFi is an easy to use, powerful, and reliable system to process and distribute data. It supports powerful and scalable directed graphs of data routing, transformation, and system mediation logic. In addition to NiFi, there is the NiFi Toolkit, a collection of command-line tools which help perform administrative tasks such as interacting with remote services, managing nodes in a cluster, and encrypting sensitive configuration values. |======================================================================================================================= |Description | Instructions on downloading the Apache NiFi application and Toolkit diff --git a/nifi-registry/nifi-registry-core/nifi-registry-web-api/src/test/resources/keys/README.md b/nifi-registry/nifi-registry-core/nifi-registry-web-api/src/test/resources/keys/README.md index 129b504ec7..52ebb74604 100644 --- a/nifi-registry/nifi-registry-core/nifi-registry-web-api/src/test/resources/keys/README.md +++ b/nifi-registry/nifi-registry-core/nifi-registry-web-api/src/test/resources/keys/README.md @@ -72,19 +72,12 @@ WD="/tmp/test-keys-$(date +"%Y%m%d-%H%M%S")" mkdir "$WD" cd "$WD" -# copy existing CA key/cert pair to working directory, rename to default tls-toolkit names +# copy existing CA key/cert pair to working directory, rename to default names cp /path/to/nifi-registry/nifi-registry-core/nifi-registry-web-api/src/test/resources/keys/ca-key.pem ./nifi-key.key cp /path/to/nifi-registry/nifi-registry-core/nifi-registry-web-api/src/test/resources/keys/ca-cert.pem ./nifi-cert.pem -# use NiFi Toolkit Docker image to generate new keys/certs -docker run -v "$WD":/tmp -w /tmp apache/nifi-toolkit:latest tls-toolkit standalone \ - --hostnames proxy \ - --subjectAlternativeNames localhost \ - --nifiDnSuffix ", OU=nifi" \ - --keyStorePassword password \ - --trustStorePassword password \ - --days 9999 \ - -O +# place new keystores / truststores +# for more info, see the [walkthrough for securing NiFi with mTLS](https://nifi.apache.org/docs/nifi-docs/html/walkthroughs.html#securing-nifi-with-mtls) # switch to output directory, create final output directory cd "$WD" @@ -124,22 +117,18 @@ WD="/tmp/test-keys-$(date +"%Y%m%d-%H%M%S")" mkdir "$WD" cd "$WD" -# copy existing CA key/cert pair to working directory, rename to default tls-toolkit names +# copy existing CA key/cert pair to working directory, rename to default names cp /path/to/nifi-registry/nifi-registry-core/nifi-registry-web-api/src/test/resources/keys/ca-key.pem ./nifi-key.key cp /path/to/nifi-registry/nifi-registry-core/nifi-registry-web-api/src/test/resources/keys/ca-cert.pem ./nifi-cert.pem -# use NiFi Toolkit Docker image to generate new keys/certs -docker run -v "$WD":/tmp -w /tmp apache/nifi-toolkit:latest tls-toolkit standalone \ - --clientCertDn "CN=user2, OU=nifi" \ - --clientCertPassword password \ - --days 9999 \ - -O +# place new keystores / truststores +# for more info, see the [walkthrough for securing NiFi with mTLS](https://nifi.apache.org/docs/nifi-docs/html/walkthroughs.html#securing-nifi-with-mtls) # switch to output directory, create final output directory cd "$WD" mkdir keys -# transform tls-toolkit output to final output +# transform keystores to final output keytool -importkeystore \ -srckeystore CN=user2_OU=nifi.p12 -srcstoretype PKCS12 -srcstorepass password -srcalias nifi-key \ -destkeystore keys/user2-ks.jks -deststoretype JKS -deststorepass password -destalias user2-key @@ -185,18 +174,8 @@ WD="/tmp/test-keys-$(date +"%Y%m%d-%H%M%S")" mkdir "$WD" cd "$WD" -# use NiFi Toolkit Docker image to generate new keys/certs -docker run -v "$WD":/tmp -w /tmp apache/nifi-toolkit:latest tls-toolkit standalone \ - --certificateAuthorityHostname "Test CA (Do Not Trust)" \ - --hostnames registry \ - --subjectAlternativeNames localhost \ - --nifiDnSuffix ", OU=nifi" \ - --keyStorePassword password \ - --trustStorePassword password \ - --clientCertDn "CN=user1, OU=nifi" \ - --clientCertPassword password \ - --days 9999 \ - -O +# place new keystores / truststores +# for more info, see the [walkthrough for securing NiFi with mTLS](https://nifi.apache.org/docs/nifi-docs/html/walkthroughs.html#securing-nifi-with-mtls) # switch to output directory, create final output directory cd "$WD" diff --git a/nifi-toolkit/nifi-toolkit-assembly/docker/Dockerfile b/nifi-toolkit/nifi-toolkit-assembly/docker/Dockerfile index 0ec3baf32e..3ebbaa238d 100644 --- a/nifi-toolkit/nifi-toolkit-assembly/docker/Dockerfile +++ b/nifi-toolkit/nifi-toolkit-assembly/docker/Dockerfile @@ -48,9 +48,6 @@ RUN chmod -R +x ${NIFI_TOOLKIT_BASE_DIR}/scripts/*.sh \ USER nifi -# Default port for TLS Toolkit CA Server -EXPOSE 9443 - WORKDIR ${NIFI_TOOLKIT_HOME} # Startup NiFi diff --git a/nifi-toolkit/nifi-toolkit-assembly/docker/Dockerfile.hub b/nifi-toolkit/nifi-toolkit-assembly/docker/Dockerfile.hub index 7e38983400..8485381095 100644 --- a/nifi-toolkit/nifi-toolkit-assembly/docker/Dockerfile.hub +++ b/nifi-toolkit/nifi-toolkit-assembly/docker/Dockerfile.hub @@ -53,9 +53,6 @@ RUN chmod -R +x ${NIFI_TOOLKIT_BASE_DIR}/scripts/*.sh \ USER nifi -# Default port for TLS Toolkit CA Server -EXPOSE 9443 - WORKDIR ${NIFI_TOOLKIT_HOME} # Startup NiFi diff --git a/nifi-toolkit/nifi-toolkit-assembly/docker/tests/exit-codes.sh b/nifi-toolkit/nifi-toolkit-assembly/docker/tests/exit-codes.sh index 22181c1823..ffe08dbeea 100755 --- a/nifi-toolkit/nifi-toolkit-assembly/docker/tests/exit-codes.sh +++ b/nifi-toolkit/nifi-toolkit-assembly/docker/tests/exit-codes.sh @@ -15,6 +15,3 @@ test 2 -eq $? || exit 1 docker run --rm $IMAGE cli invalid 1>/dev/null 2>&1 test 255 -eq $? || exit 1 - -docker run --rm $IMAGE tls-toolkit invalid 1>/dev/null 2>&1 -test 2 -eq $? || exit 1 diff --git a/nifi-toolkit/nifi-toolkit-assembly/docker/tests/tls-toolkit.sh b/nifi-toolkit/nifi-toolkit-assembly/docker/tests/tls-toolkit.sh deleted file mode 100755 index d58d2b7dcd..0000000000 --- a/nifi-toolkit/nifi-toolkit-assembly/docker/tests/tls-toolkit.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash - -set -exuo pipefail - -VERSION=$1 -IMAGE=apache/nifi-toolkit:${VERSION} -CONTAINER=nifi-toolkit-$VERSION-tls-toolkit-integration-test - -TOKEN=D40F6B95-801F-4800-A1E1-A9FCC712E0BD - -trap " { docker rm -f $CONTAINER ; } " EXIT - -echo "Starting CA server using the tls-toolkit server command" -docker run -d --name $CONTAINER $IMAGE tls-toolkit server -t $TOKEN -c $CONTAINER - -echo "Requesting client certificate using the tls-toolkit client command" -docker run --rm --link $CONTAINER $IMAGE tls-toolkit client -t $TOKEN -c $CONTAINER diff --git a/nifi-toolkit/nifi-toolkit-assembly/pom.xml b/nifi-toolkit/nifi-toolkit-assembly/pom.xml index e9b9dc802a..3c48abb434 100644 --- a/nifi-toolkit/nifi-toolkit-assembly/pom.xml +++ b/nifi-toolkit/nifi-toolkit-assembly/pom.xml @@ -28,7 +28,6 @@ language governing permissions and limitations under the License. --> src/main/resources/conf/config-client.json src/main/resources/conf/config-server.json - docker/tests/tls-toolkit.sh docker/tests/exit-codes.sh @@ -63,11 +62,6 @@ language governing permissions and limitations under the License. --> - - org.apache.nifi - nifi-toolkit-tls - 2.0.0-SNAPSHOT - org.apache.nifi nifi-toolkit-encrypt-config @@ -199,19 +193,6 @@ language governing permissions and limitations under the License. --> ${project.basedir}/docker/tests/exit-codes.sh - - Docker integration tests - tls-toolkit - integration-test - - exec - - - - ${project.version}-maven - - ${project.basedir}/docker/tests/tls-toolkit.sh - - @@ -234,10 +215,6 @@ language governing permissions and limitations under the License. --> Docker integration tests - exit codes none - - Docker integration tests - tls-toolkit - none - @@ -261,10 +238,6 @@ language governing permissions and limitations under the License. --> Docker integration tests - exit codes none - - Docker integration tests - tls-toolkit - none - diff --git a/nifi-toolkit/nifi-toolkit-assembly/src/main/resources/bin/tls-toolkit.bat b/nifi-toolkit/nifi-toolkit-assembly/src/main/resources/bin/tls-toolkit.bat deleted file mode 100644 index ddf35c71bf..0000000000 --- a/nifi-toolkit/nifi-toolkit-assembly/src/main/resources/bin/tls-toolkit.bat +++ /dev/null @@ -1,41 +0,0 @@ -@echo off -rem -rem Licensed to the Apache Software Foundation (ASF) under one or more -rem contributor license agreements. See the NOTICE file distributed with -rem this work for additional information regarding copyright ownership. -rem The ASF licenses this file to You under the Apache License, Version 2.0 -rem (the "License"); you may not use this file except in compliance with -rem the License. You may obtain a copy of the License at -rem -rem http://www.apache.org/licenses/LICENSE-2.0 -rem -rem Unless required by applicable law or agreed to in writing, software -rem distributed under the License is distributed on an "AS IS" BASIS, -rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -rem See the License for the specific language governing permissions and -rem limitations under the License. -rem - -rem Use JAVA_HOME if it's set; otherwise, just use java - -if "%JAVA_HOME%" == "" goto noJavaHome -if not exist "%JAVA_HOME%\bin\java.exe" goto noJavaHome -set JAVA_EXE=%JAVA_HOME%\bin\java.exe -goto startConfig - -:noJavaHome -echo The JAVA_HOME environment variable is not defined correctly. -echo Instead the PATH will be used to find the java executable. -echo. -set JAVA_EXE=java -goto startConfig - -:startConfig -set LIB_DIR=%~dp0..\classpath;%~dp0..\lib - -if "%JAVA_OPTS%" == "" set JAVA_OPTS=-Xms128m -Xmx256m - -SET JAVA_PARAMS=-cp %LIB_DIR%\* %JAVA_OPTS% org.apache.nifi.toolkit.tls.TlsToolkitMain - -cmd.exe /C ""%JAVA_EXE%" %JAVA_PARAMS% %* "" - diff --git a/nifi-toolkit/nifi-toolkit-assembly/src/main/resources/bin/tls-toolkit.sh b/nifi-toolkit/nifi-toolkit-assembly/src/main/resources/bin/tls-toolkit.sh deleted file mode 100644 index 8da9716292..0000000000 --- a/nifi-toolkit/nifi-toolkit-assembly/src/main/resources/bin/tls-toolkit.sh +++ /dev/null @@ -1,119 +0,0 @@ -#!/bin/sh -# -# 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. -# -# - -# Script structure inspired from Apache Karaf and other Apache projects with similar startup approaches - -SCRIPT_DIR=$(dirname "$0") -SCRIPT_NAME=$(basename "$0") -NIFI_TOOLKIT_HOME=$(cd "${SCRIPT_DIR}" && cd .. && pwd) -PROGNAME=$(basename "$0") - - -warn() { - echo "${PROGNAME}: $*" -} - -die() { - warn "$*" - exit 1 -} - -detectOS() { - # OS specific support (must be 'true' or 'false'). - cygwin=false; - aix=false; - os400=false; - darwin=false; - case "$(uname)" in - CYGWIN*) - cygwin=true - ;; - AIX*) - aix=true - ;; - OS400*) - os400=true - ;; - Darwin) - darwin=true - ;; - esac - # For AIX, set an environment variable - if ${aix}; then - export LDR_CNTRL=MAXDATA=0xB0000000@DSA - echo ${LDR_CNTRL} - fi -} - -locateJava() { - # Setup the Java Virtual Machine - if $cygwin ; then - [ -n "${JAVA}" ] && JAVA=$(cygpath --unix "${JAVA}") - [ -n "${JAVA_HOME}" ] && JAVA_HOME=$(cygpath --unix "${JAVA_HOME}") - fi - - if [ "x${JAVA}" = "x" ] && [ -r /etc/gentoo-release ] ; then - JAVA_HOME=$(java-config --jre-home) - fi - if [ "x${JAVA}" = "x" ]; then - if [ "x${JAVA_HOME}" != "x" ]; then - if [ ! -d "${JAVA_HOME}" ]; then - die "JAVA_HOME is not valid: ${JAVA_HOME}" - fi - JAVA="${JAVA_HOME}/bin/java" - else - warn "JAVA_HOME not set; results may vary" - JAVA=$(type java) - JAVA=$(expr "${JAVA}" : '.* \(/.*\)$') - if [ "x${JAVA}" = "x" ]; then - die "java command not found" - fi - fi - fi -} - -init() { - # Determine if there is special OS handling we must perform - detectOS - - # Locate the Java VM to execute - locateJava "$1" -} - -run() { - LIBS="${NIFI_TOOLKIT_HOME}/lib/*" - - sudo_cmd_prefix="" - if $cygwin; then - NIFI_TOOLKIT_HOME=$(cygpath --path --windows "${NIFI_TOOLKIT_HOME}") - CLASSPATH="$NIFI_TOOLKIT_HOME/classpath;$(cygpath --path --windows "${LIBS}")" - else - CLASSPATH="$NIFI_TOOLKIT_HOME/classpath:${LIBS}" - fi - - export JAVA_HOME="$JAVA_HOME" - export NIFI_TOOLKIT_HOME="$NIFI_TOOLKIT_HOME" - - umask 0077 - exec "${JAVA}" -cp "${CLASSPATH}" ${JAVA_OPTS:--Xms128m -Xmx256m} org.apache.nifi.toolkit.tls.TlsToolkitMain "$@" -} - - -init "$1" -run "$@" diff --git a/nifi-toolkit/nifi-toolkit-encrypt-config/pom.xml b/nifi-toolkit/nifi-toolkit-encrypt-config/pom.xml index 2d3a6c9809..283e33e9ff 100644 --- a/nifi-toolkit/nifi-toolkit-encrypt-config/pom.xml +++ b/nifi-toolkit/nifi-toolkit-encrypt-config/pom.xml @@ -65,17 +65,6 @@ - - org.apache.nifi - nifi-toolkit-tls - 2.0.0-SNAPSHOT - - - commons-logging - commons-logging - - - commons-cli commons-cli diff --git a/nifi-toolkit/nifi-toolkit-encrypt-config/src/main/groovy/org/apache/nifi/properties/ConfigEncryptionTool.groovy b/nifi-toolkit/nifi-toolkit-encrypt-config/src/main/groovy/org/apache/nifi/properties/ConfigEncryptionTool.groovy index 4f4717bc8a..10cc223165 100644 --- a/nifi-toolkit/nifi-toolkit-encrypt-config/src/main/groovy/org/apache/nifi/properties/ConfigEncryptionTool.groovy +++ b/nifi-toolkit/nifi-toolkit-encrypt-config/src/main/groovy/org/apache/nifi/properties/ConfigEncryptionTool.groovy @@ -35,8 +35,8 @@ import org.apache.nifi.flow.encryptor.JsonFlowEncryptor import org.apache.nifi.properties.scheme.ProtectionScheme import org.apache.nifi.properties.scheme.StandardProtectionScheme import org.apache.nifi.properties.scheme.StandardProtectionSchemeResolver -import org.apache.nifi.toolkit.tls.commandLine.CommandLineParseException -import org.apache.nifi.toolkit.tls.commandLine.ExitCode +import org.apache.nifi.toolkit.commandline.CommandLineParseException +import org.apache.nifi.toolkit.commandline.ExitCode import org.apache.nifi.util.NiFiBootstrapUtils import org.apache.nifi.util.NiFiProperties import org.apache.nifi.util.console.TextDevice diff --git a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/commandLine/CommandLineParseException.java b/nifi-toolkit/nifi-toolkit-encrypt-config/src/main/java/org/apache/nifi/toolkit/commandline/CommandLineParseException.java similarity index 96% rename from nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/commandLine/CommandLineParseException.java rename to nifi-toolkit/nifi-toolkit-encrypt-config/src/main/java/org/apache/nifi/toolkit/commandline/CommandLineParseException.java index 21d70831b3..ca6e68a8c3 100644 --- a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/commandLine/CommandLineParseException.java +++ b/nifi-toolkit/nifi-toolkit-encrypt-config/src/main/java/org/apache/nifi/toolkit/commandline/CommandLineParseException.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.nifi.toolkit.tls.commandLine; +package org.apache.nifi.toolkit.commandline; /** * Exception for errors while parsing the command line diff --git a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/commandLine/ExitCode.java b/nifi-toolkit/nifi-toolkit-encrypt-config/src/main/java/org/apache/nifi/toolkit/commandline/ExitCode.java similarity index 97% rename from nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/commandLine/ExitCode.java rename to nifi-toolkit/nifi-toolkit-encrypt-config/src/main/java/org/apache/nifi/toolkit/commandline/ExitCode.java index 753cf184a9..b394c46397 100644 --- a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/commandLine/ExitCode.java +++ b/nifi-toolkit/nifi-toolkit-encrypt-config/src/main/java/org/apache/nifi/toolkit/commandline/ExitCode.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.nifi.toolkit.tls.commandLine; +package org.apache.nifi.toolkit.commandline; /** * Possible exit codes diff --git a/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/groovy/org/apache/nifi/properties/ConfigEncryptionToolTest.groovy b/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/groovy/org/apache/nifi/properties/ConfigEncryptionToolTest.groovy index 89568e9256..0083b27386 100644 --- a/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/groovy/org/apache/nifi/properties/ConfigEncryptionToolTest.groovy +++ b/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/groovy/org/apache/nifi/properties/ConfigEncryptionToolTest.groovy @@ -21,7 +21,6 @@ import org.apache.commons.cli.CommandLineParser import org.apache.commons.cli.DefaultParser import org.apache.commons.io.IOUtils import org.apache.commons.lang3.SystemUtils -import org.apache.nifi.toolkit.tls.commandLine.CommandLineParseException import org.apache.nifi.util.NiFiProperties import org.apache.nifi.util.console.TextDevice import org.apache.nifi.util.console.TextDevices diff --git a/nifi-toolkit/nifi-toolkit-tls/pom.xml b/nifi-toolkit/nifi-toolkit-tls/pom.xml deleted file mode 100644 index b33a5d23b4..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/pom.xml +++ /dev/null @@ -1,141 +0,0 @@ - - - - 4.0.0 - - org.apache.nifi - nifi-toolkit - 2.0.0-SNAPSHOT - - nifi-toolkit-tls - Tooling to make tls configuration easier - - - org.apache.nifi - nifi-properties - 2.0.0-SNAPSHOT - - - org.apache.nifi - nifi-utils - 2.0.0-SNAPSHOT - - - org.apache.nifi - nifi-security-utils - 2.0.0-SNAPSHOT - - - org.apache.nifi - nifi-security-cert-builder - 2.0.0-SNAPSHOT - - - org.apache.nifi - nifi-resources - provided - 2.0.0-SNAPSHOT - resources - zip - - - org.slf4j - slf4j-api - - - org.bouncycastle - bcpkix-jdk18on - - - org.bouncycastle - bcprov-jdk18on - - - commons-cli - commons-cli - - - commons-io - commons-io - - - org.eclipse.jetty - jetty-server - - - org.glassfish.jersey.core - jersey-client - - - org.glassfish.jersey.inject - jersey-hk2 - - - com.fasterxml.jackson.core - jackson-databind - - - org.apache.httpcomponents - httpclient - - - org.slf4j - jcl-over-slf4j - - - - - - org.apache.maven.plugins - maven-dependency-plugin - - - unpack - process-resources - - unpack - - - - - org.apache.nifi - nifi-resources - zip - ${project.version} - resources - true - ${project.build.directory}/classes - **/nifi.properties - - - - - - - - org.apache.rat - apache-rat-plugin - - - src/test/resources/rootCert.crt - src/test/resources/rootCert.key - src/test/resources/rootCert-pkcs8.key - - - - - - diff --git a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/TlsToolkitMain.java b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/TlsToolkitMain.java deleted file mode 100644 index 2e6b8d1e8a..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/TlsToolkitMain.java +++ /dev/null @@ -1,117 +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.toolkit.tls; - -import org.apache.nifi.toolkit.tls.commandLine.ExitCode; -import org.apache.nifi.toolkit.tls.service.client.TlsCertificateAuthorityClientCommandLine; -import org.apache.nifi.toolkit.tls.service.server.TlsCertificateAuthorityServiceCommandLine; -import org.apache.nifi.toolkit.tls.standalone.TlsToolkitStandaloneCommandLine; -import org.apache.nifi.toolkit.tls.status.TlsToolkitGetStatusCommandLine; - -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.Arrays; -import java.util.LinkedHashMap; -import java.util.Map; - -/** - * Command line entry point that looks through a map of possible services to delegate to - */ -public class TlsToolkitMain { - public static final String DESCRIPTION = "DESCRIPTION"; - public static final String UNABLE_TO_GET_DESCRIPTION = "Unable to get description. ("; - private final Map> mainMap; - - public TlsToolkitMain() { - mainMap = new LinkedHashMap<>(); - mainMap.put("standalone", TlsToolkitStandaloneCommandLine.class); - mainMap.put("server", TlsCertificateAuthorityServiceCommandLine.class); - mainMap.put("client", TlsCertificateAuthorityClientCommandLine.class); - mainMap.put("status", TlsToolkitGetStatusCommandLine.class); - } - - /** - * Callthrough to doMain - * - * @param args the command line arguments - */ - public static void main(String[] args) { - new TlsToolkitMain().doMain(args); - } - - private T printUsageAndExit(String message, ExitCode exitCode) { - System.out.println(message); - System.out.println(); - System.out.println("Usage: tls-toolkit service [-h] [args]"); - System.out.println(); - System.out.println("Services:"); - mainMap.forEach((s, aClass) -> System.out.println(" " + s + ": " + getDescription(aClass))); - System.out.println(); - System.exit(exitCode.ordinal()); - return null; - } - - protected String getDescription(Class clazz) { - try { - Field declaredField = clazz.getDeclaredField(DESCRIPTION); - return String.valueOf(declaredField.get(null)); - } catch (Exception e) { - return UNABLE_TO_GET_DESCRIPTION + e.getMessage() + ")"; - } - } - - protected Map> getMainMap() { - return mainMap; - } - - protected Method getMain(String service) { - Class mainClass = mainMap.get(service); - if (mainClass == null) { - printUsageAndExit("Unknown service: " + service, ExitCode.INVALID_ARGS); - } - - try { - return mainClass.getDeclaredMethod("main", String[].class); - } catch (NoSuchMethodException e) { - return printUsageAndExit("Service " + service + " is missing main method.", ExitCode.SERVICE_ERROR); - } - } - - /** - * Invokes the main of the relevant service - * - * @param args the command line arguments - */ - public void doMain(String[] args) { - if (args.length < 1) { - printUsageAndExit("Expected at least a service argument.", ExitCode.INVALID_ARGS); - } - - String service = args[0].toLowerCase(); - - try { - getMain(service).invoke(null, (Object) Arrays.copyOfRange(args, 1, args.length, String[].class)); - } catch (IllegalAccessException e) { - printUsageAndExit("Service " + service + " has invalid main method.", ExitCode.SERVICE_ERROR); - } catch (InvocationTargetException e) { - printUsageAndExit("Service " + service + " error: " + e.getCause().getMessage(), ExitCode.SERVICE_ERROR); - } - return; - } -} \ No newline at end of file diff --git a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/commandLine/BaseCommandLine.java b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/commandLine/BaseCommandLine.java deleted file mode 100644 index a75b7b894f..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/commandLine/BaseCommandLine.java +++ /dev/null @@ -1,112 +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.toolkit.tls.commandLine; - -import org.apache.commons.cli.CommandLine; -import org.apache.commons.cli.CommandLineParser; -import org.apache.commons.cli.DefaultParser; -import org.apache.commons.cli.HelpFormatter; -import org.apache.commons.cli.Options; -import org.apache.commons.cli.ParseException; -import org.apache.nifi.toolkit.tls.TlsToolkitMain; - -public abstract class BaseCommandLine { - - public static final String HELP_ARG = "help"; - public static final String JAVA_HOME = "JAVA_HOME"; - public static final String NIFI_TOOLKIT_HOME = "NIFI_TOOLKIT_HOME"; - public static final String FOOTER = new StringBuilder(System.lineSeparator()).append("Java home: ") - .append(System.getenv(JAVA_HOME)).append(System.lineSeparator()).append("NiFi Toolkit home: ").append(System.getenv(NIFI_TOOLKIT_HOME)).toString(); - - private final Options options; - private final String header; - - public BaseCommandLine(String header) { - this.header = System.lineSeparator() + header + System.lineSeparator() + System.lineSeparator(); - this.options = new Options(); - this.options.addOption("h", HELP_ARG, false, "Print help and exit."); - } - - protected void addOptionWithArg(String arg, String longArg, String description) { - addOptionWithArg(arg, longArg, description, null); - } - - protected void addOptionNoArg(String arg, String longArg, String description) { - options.addOption(arg, longArg, false, description); - } - - protected void addOptionWithArg(String arg, String longArg, String description, Object defaultVal) { - String fullDescription = description; - if (defaultVal != null) { - fullDescription += " (default: " + defaultVal + ")"; - } - options.addOption(arg, longArg, true, fullDescription); - } - - public void printUsage(String errorMessage) { - if (errorMessage != null) { - System.out.println(errorMessage); - System.out.println(); - } - HelpFormatter helpFormatter = new HelpFormatter(); - helpFormatter.setWidth(160); - helpFormatter.printHelp(TlsToolkitMain.class.getCanonicalName(), header, options, FOOTER, true); - } - - protected T printUsageAndThrow(String errorMessage, ExitCode exitCode) throws CommandLineParseException { - printUsage(errorMessage); - throw new CommandLineParseException(errorMessage, exitCode); - } - - protected int getIntValue(CommandLine commandLine, String arg, int defaultVal) throws CommandLineParseException { - try { - return Integer.parseInt(commandLine.getOptionValue(arg, Integer.toString(defaultVal))); - } catch (NumberFormatException e) { - return printUsageAndThrow("Expected integer for " + arg + " argument. (" + e.getMessage() + ")", ExitCode.ERROR_PARSING_INT_ARG); - } - } - - protected CommandLine doParse(String[] args) throws CommandLineParseException { - CommandLineParser parser = new DefaultParser(); - CommandLine commandLine; - try { - commandLine = parser.parse(options, args); - if (commandLine.hasOption(HELP_ARG)) { - return printUsageAndThrow(null, ExitCode.HELP); - } - postParse(commandLine); - } catch (ParseException e) { - return printUsageAndThrow("Error parsing command line. (" + e.getMessage() + ")", ExitCode.ERROR_PARSING_COMMAND_LINE); - } - return commandLine; - } - - protected void postParse(CommandLine commandLine) throws CommandLineParseException { - - } - - /** - * Parses the command line arguments - * - * @param args the command line arguments - * @throws CommandLineParseException if the arguments cannot be parsed - */ - public void parse(String... args) throws CommandLineParseException { - doParse(args); - } - -} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/commandLine/BaseTlsToolkitCommandLine.java b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/commandLine/BaseTlsToolkitCommandLine.java deleted file mode 100644 index 656bb196c4..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/commandLine/BaseTlsToolkitCommandLine.java +++ /dev/null @@ -1,157 +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.toolkit.tls.commandLine; - -import org.apache.commons.cli.CommandLine; -import org.apache.nifi.security.util.KeystoreType; -import org.apache.nifi.toolkit.tls.configuration.TlsConfig; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Base class with common CLI parsing functionality as well as arguments shared by multiple entry points - */ -public abstract class BaseTlsToolkitCommandLine extends BaseCommandLine { - private static final Logger logger = LoggerFactory.getLogger(BaseTlsToolkitCommandLine.class); - - public static final String KEY_SIZE_ARG = "keySize"; - public static final String KEY_ALGORITHM_ARG = "keyAlgorithm"; - public static final String CERTIFICATE_AUTHORITY_HOSTNAME_ARG = "certificateAuthorityHostname"; - public static final String DAYS_ARG = "days"; - public static final String KEY_STORE_TYPE_ARG = "keyStoreType"; - public static final String SIGNING_ALGORITHM_ARG = "signingAlgorithm"; - public static final String DN_ARG = "dn"; - public static final String DIFFERENT_KEY_AND_KEYSTORE_PASSWORDS_ARG = "differentKeyAndKeystorePasswords"; - - public static final String KEYSTORE = "keystore."; - public static final String TRUSTSTORE = "truststore."; - - private int keySize; - private String keyAlgorithm; - private String certificateAuthorityHostname; - private String keyStoreType; - private int days; - private String signingAlgorithm; - private boolean differentPasswordForKeyAndKeystore; - - public BaseTlsToolkitCommandLine(String header) { - super(header); - if (shouldAddDaysArg()) { - addOptionWithArg("d", DAYS_ARG, "Number of days issued certificate should be valid for.", TlsConfig.DEFAULT_DAYS); - } - addOptionWithArg("T", KEY_STORE_TYPE_ARG, "The type of keyStores to generate.", getKeyStoreTypeDefault()); - addOptionWithArg("c", CERTIFICATE_AUTHORITY_HOSTNAME_ARG, "Hostname of NiFi Certificate Authority", TlsConfig.DEFAULT_HOSTNAME); - addOptionWithArg("a", KEY_ALGORITHM_ARG, "Algorithm to use for generated keys.", TlsConfig.DEFAULT_KEY_PAIR_ALGORITHM); - addOptionWithArg("k", KEY_SIZE_ARG, "Number of bits for generated keys.", TlsConfig.DEFAULT_KEY_SIZE); - if (shouldAddSigningAlgorithmArg()) { - addOptionWithArg("s", SIGNING_ALGORITHM_ARG, "Algorithm to use for signing certificates.", TlsConfig.DEFAULT_SIGNING_ALGORITHM); - } - addOptionNoArg("g", DIFFERENT_KEY_AND_KEYSTORE_PASSWORDS_ARG, "Use different generated password for the key and the keyStore."); - } - - protected String getKeyStoreTypeDefault() { - return TlsConfig.DEFAULT_KEY_STORE_TYPE; - } - - protected boolean shouldAddSigningAlgorithmArg() { - return true; - } - - protected boolean shouldAddDaysArg() { - return true; - } - - /** - * Returns the number of bits used when generating KeyPairs - * - * @return the number of bits used when generating KeyPairs - */ - public int getKeySize() { - return keySize; - } - - /** - * Returns the algorithm used when generating KeyPairs - * - * @return the algorithm used when generating KeyPairs - */ - public String getKeyAlgorithm() { - return keyAlgorithm; - } - - /** - * Returns the CA Hostname - * - * @return the CA Hostname - */ - public String getCertificateAuthorityHostname() { - return certificateAuthorityHostname; - } - - /** - * Returns the type to use for KeyStores - * - * @return the type to use for KeyStores - */ - public String getKeyStoreType() { - return keyStoreType; - } - - /** - * Returns the number of Certificates should be valid for - * - * @return the number of Certificates should be valid for - */ - public int getDays() { - return days; - } - - /** - * Returns the signing algorithm to use for cryptographic operations - * - * @return the signing algorithm to use for cryptographic operations - */ - public String getSigningAlgorithm() { - return signingAlgorithm; - } - - /** - * Returns true if different passwords should be used for KeyStore and individual Key entries - * - * @return true if different passwords should be used for KeyStore and individual Key entries - */ - public boolean differentPasswordForKeyAndKeystore() { - return differentPasswordForKeyAndKeystore; - } - - @Override - protected void postParse(CommandLine commandLine) throws CommandLineParseException { - certificateAuthorityHostname = commandLine.getOptionValue(CERTIFICATE_AUTHORITY_HOSTNAME_ARG, TlsConfig.DEFAULT_HOSTNAME); - days = getIntValue(commandLine, DAYS_ARG, TlsConfig.DEFAULT_DAYS); - keySize = getIntValue(commandLine, KEY_SIZE_ARG, TlsConfig.DEFAULT_KEY_SIZE); - keyAlgorithm = commandLine.getOptionValue(KEY_ALGORITHM_ARG, TlsConfig.DEFAULT_KEY_PAIR_ALGORITHM); - keyStoreType = commandLine.getOptionValue(KEY_STORE_TYPE_ARG, getKeyStoreTypeDefault()); - if (KeystoreType.PKCS12.toString().equalsIgnoreCase(keyStoreType)) { - logger.info("Command line argument --" + KEY_STORE_TYPE_ARG + "=" + keyStoreType + " only applies to keystore, recommended truststore type of " + KeystoreType.JKS.toString() + - " unaffected."); - } - signingAlgorithm = commandLine.getOptionValue(SIGNING_ALGORITHM_ARG, TlsConfig.DEFAULT_SIGNING_ALGORITHM); - differentPasswordForKeyAndKeystore = commandLine.hasOption(DIFFERENT_KEY_AND_KEYSTORE_PASSWORDS_ARG); - } - -} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/configuration/GetStatusConfig.java b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/configuration/GetStatusConfig.java deleted file mode 100644 index eab6f14b1d..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/configuration/GetStatusConfig.java +++ /dev/null @@ -1,41 +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.toolkit.tls.configuration; - -import javax.net.ssl.SSLContext; -import java.net.URI; - -public class GetStatusConfig { - - private final URI url; - - private final SSLContext sslContext; - - public GetStatusConfig(final URI url, final SSLContext sslContext) { - this.url = url; - this.sslContext = sslContext; - } - - public URI getUrl() { - return url; - } - - public SSLContext getSslContext() { - return sslContext; - } - -} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/configuration/InstanceDefinition.java b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/configuration/InstanceDefinition.java deleted file mode 100644 index e05b78d2c0..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/configuration/InstanceDefinition.java +++ /dev/null @@ -1,118 +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.toolkit.tls.configuration; - -import org.apache.nifi.toolkit.tls.standalone.TlsToolkitStandaloneCommandLine; - -import java.util.List; -import java.util.Map; -import java.util.function.Supplier; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -/** - * Contains an instance identifier, a number that either corresponds to the instance identifier or to the global order and relevant passwords - */ -public class InstanceDefinition { - private final InstanceIdentifier instanceIdentifier; - private final int number; - private final String keyStorePassword; - private final String keyPassword; - private final String trustStorePassword; - - public InstanceDefinition(InstanceIdentifier instanceIdentifier, int number, String keyStorePassword, String keyPassword, String trustStorePassword) { - this.number = number; - this.instanceIdentifier = instanceIdentifier; - this.keyStorePassword = keyStorePassword; - this.keyPassword = keyPassword; - this.trustStorePassword = trustStorePassword; - } - - /** - * Creates a list of instance definitions - * - * @param fullHostNameExpressions the host expressions defining the global order (null if not relevant) - * @param currentHostnameExpressions the host expressions to create instance definitions for - * @param keyStorePasswords a supplier for keyStorePasswords - * @param keyPasswords a supplier for keyPasswords - * @param trustStorePasswords a supplier for trustStorePasswords - * @return a list of instance definitions - */ - public static List createDefinitions(Stream fullHostNameExpressions, Stream currentHostnameExpressions, Supplier keyStorePasswords, - Supplier keyPasswords, Supplier trustStorePasswords) { - if (fullHostNameExpressions == null) { - return InstanceIdentifier.createIdentifiers(currentHostnameExpressions).map(id -> createDefinition(id, id.getNumber(), keyStorePasswords, keyPasswords, trustStorePasswords)) - .collect(Collectors.toList()); - } else { - Map orderMap = InstanceIdentifier.createOrderMap(fullHostNameExpressions); - return InstanceIdentifier.createIdentifiers(currentHostnameExpressions).map(id -> { - Integer number = orderMap.get(id); - if (number == null) { - throw new IllegalArgumentException("Unable to find " + id.getHostname() + " in specified " + TlsToolkitStandaloneCommandLine.GLOBAL_PORT_SEQUENCE_ARG + " expression(s)."); - } - return createDefinition(id, number, keyStorePasswords, keyPasswords, trustStorePasswords); - }).collect(Collectors.toList()); - } - } - - protected static InstanceDefinition createDefinition(InstanceIdentifier instanceIdentifier, int number, Supplier keyStorePasswords, Supplier keyPasswords, - Supplier trustStorePasswords) { - String keyStorePassword = null; - if (keyStorePasswords != null) { - keyStorePassword = keyStorePasswords.get(); - } - - String keyPassword; - if (keyPasswords == null) { - keyPassword = keyStorePassword; - } else { - keyPassword = keyPasswords.get(); - } - - String trustStorePassword = null; - if (trustStorePasswords != null) { - trustStorePassword = trustStorePasswords.get(); - } - - return new InstanceDefinition(instanceIdentifier, number, keyStorePassword, keyPassword, trustStorePassword); - } - - public String getHostname() { - return instanceIdentifier.getHostname(); - } - - public int getNumber() { - return number; - } - - public String getKeyStorePassword() { - return keyStorePassword; - } - - public String getKeyPassword() { - return keyPassword; - } - - public String getTrustStorePassword() { - return trustStorePassword; - } - - public InstanceIdentifier getInstanceIdentifier() { - return instanceIdentifier; - } -} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/configuration/InstanceIdentifier.java b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/configuration/InstanceIdentifier.java deleted file mode 100644 index 7b15636976..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/configuration/InstanceIdentifier.java +++ /dev/null @@ -1,176 +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.toolkit.tls.configuration; - -import org.apache.nifi.util.StringUtils; - -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.regex.Pattern; -import java.util.stream.Collectors; -import java.util.stream.IntStream; -import java.util.stream.Stream; - -/** - * Each instance is uniquely identified by its hostname and instance number - */ -public class InstanceIdentifier { - public static final Comparator HOST_IDENTIFIER_COMPARATOR = (o1, o2) -> { - int i = o1.getHostname().compareTo(o2.getHostname()); - if (i == 0) { - return o1.getNumber() - o2.getNumber(); - } - return i; - }; - private static final Pattern RANGE_PATTERN = Pattern.compile("^[0-9]+(-[0-9]+)?$"); - private final String hostname; - private final int number; - - public InstanceIdentifier(String hostname, int number) { - this.hostname = hostname; - this.number = number; - } - - /** - * Creates a map that can be used to deterministically assign global instance numbers - * - * @param hostnameExpressions the hostname expressions to expand - * @return a map that can be used to deterministically assign global instance numbers - */ - public static Map createOrderMap(Stream hostnameExpressions) { - List instanceIdentifiers = createIdentifiers(hostnameExpressions).sorted(HOST_IDENTIFIER_COMPARATOR).collect(Collectors.toList()); - Map result = new HashMap<>(); - for (int i = 0; i < instanceIdentifiers.size(); i++) { - result.put(instanceIdentifiers.get(i), i + 1); - } - return result; - } - - /** - * Creates a stream of hostname identifiers from a stream of hostname expressions - * - * @param hostnameExpressions the hostname expressions - * @return the hostname identifiers - */ - public static Stream createIdentifiers(Stream hostnameExpressions) { - return hostnameExpressions.flatMap(hostnameExpression -> extractHostnames(hostnameExpression).flatMap(hostname -> { - ExtractedRange extractedRange = new ExtractedRange(hostname, '(', ')'); - if (extractedRange.range == null) { - return Stream.of(new InstanceIdentifier(hostname, 1)); - } - if (!StringUtils.isEmpty(extractedRange.afterClose)) { - throw new IllegalArgumentException("No characters expected after )"); - } - return extractedRange.range.map(numString -> new InstanceIdentifier(extractedRange.beforeOpen, Integer.parseInt(numString))); - })); - } - - protected static Stream extractHostnames(String hostname) { - ExtractedRange extractedRange = new ExtractedRange(hostname, '[', ']'); - if (extractedRange.range == null) { - return Stream.of(hostname); - } - return extractedRange.range.map(s -> extractedRange.beforeOpen + s + extractedRange.afterClose).flatMap(InstanceIdentifier::extractHostnames); - } - - private static Stream extractRange(String range) { - if (!RANGE_PATTERN.matcher(range).matches()) { - throw new IllegalArgumentException("Expected either one number or two separated by a single hyphen"); - } - String[] split = range.split("-"); - if (split.length == 1) { - String prefix = "1-"; - if (split[0].charAt(0) == '0') { - prefix = String.format("%0" + split[0].length() + "d-", 1); - } - return extractRange(prefix + split[0]); - } else { - int baseLength = split[0].length(); - int low = Integer.parseInt(split[0]); - String padding = split[0].substring(0, split[0].length() - Integer.toString(low).length()); - int high = Integer.parseInt(split[1]); - IntStream intRange = IntStream.range(Math.min(low, high), Math.max(low, high) + 1) - .map(i -> high < low ? high - i + low : i); - return intRange.mapToObj(i -> { - String s = Integer.toString(i); - int length = s.length(); - if (length >= baseLength) { - return s; - } else { - return padding.substring(0, baseLength - length) + s; - } - }); - } - } - - public String getHostname() { - return hostname; - } - - public int getNumber() { - return number; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - InstanceIdentifier that = (InstanceIdentifier) o; - - if (number != that.number) return false; - return hostname != null ? hostname.equals(that.hostname) : that.hostname == null; - - } - - @Override - public int hashCode() { - int result = hostname != null ? hostname.hashCode() : 0; - result = 31 * result + number; - return result; - } - - private static class ExtractedRange { - private final String beforeOpen; - private final Stream range; - private final String afterClose; - - public ExtractedRange(String string, char rangeOpen, char rangeClose) { - int openBracket = string.indexOf(rangeOpen); - if (openBracket >= 0) { - int closeBracket = string.indexOf(rangeClose, openBracket); - if (closeBracket < 0) { - throw new IllegalArgumentException("Unable to find matching " + rangeClose + " for " + rangeOpen + " in " + string); - } - beforeOpen = string.substring(0, openBracket); - if (closeBracket + 1 < string.length()) { - afterClose = string.substring(closeBracket + 1); - } else { - afterClose = ""; - } - range = extractRange(string.substring(openBracket + 1, closeBracket)); - } else { - beforeOpen = string; - range = null; - afterClose = ""; - } - } - } -} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/configuration/StandaloneConfig.java b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/configuration/StandaloneConfig.java deleted file mode 100644 index 4fd6af5960..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/configuration/StandaloneConfig.java +++ /dev/null @@ -1,102 +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.toolkit.tls.configuration; - -import java.io.File; -import java.util.List; -import org.apache.nifi.toolkit.tls.properties.NiFiPropertiesWriterFactory; - -/** - * Configuration object of the standalone service - */ -public class StandaloneConfig extends TlsConfig { - private File baseDir; - private NiFiPropertiesWriterFactory niFiPropertiesWriterFactory; - private List instanceDefinitions; - private List clientDns; - private List clientPasswords; - private boolean clientPasswordsGenerated; - private boolean overwrite; - private boolean splitKeystore; - - // TODO: A lot of these fields are null and cause NPEs in {@link TlsToolkitStandalone} when not executed with expected input - - public List getClientDns() { - return clientDns; - } - - public void setClientDns(List clientDns) { - this.clientDns = clientDns; - } - - public boolean isOverwrite() { - return overwrite; - } - - public void setOverwrite(boolean overwrite) { - this.overwrite = overwrite; - } - - public File getBaseDir() { - return baseDir; - } - - public void setBaseDir(File baseDir) { - this.baseDir = baseDir; - } - - public NiFiPropertiesWriterFactory getNiFiPropertiesWriterFactory() { - return niFiPropertiesWriterFactory; - } - - public void setNiFiPropertiesWriterFactory(NiFiPropertiesWriterFactory niFiPropertiesWriterFactory) { - this.niFiPropertiesWriterFactory = niFiPropertiesWriterFactory; - } - - public List getClientPasswords() { - return clientPasswords; - } - - public void setClientPasswords(List clientPasswords) { - this.clientPasswords = clientPasswords; - } - - public boolean isClientPasswordsGenerated() { - return clientPasswordsGenerated; - } - - public void setClientPasswordsGenerated(boolean clientPasswordsGenerated) { - this.clientPasswordsGenerated = clientPasswordsGenerated; - } - - public List getInstanceDefinitions() { - return instanceDefinitions; - } - - public void setInstanceDefinitions(List instanceDefinitions) { - this.instanceDefinitions = instanceDefinitions; - } - - public void setSplitKeystore(boolean splitKeystore) { - this.splitKeystore = splitKeystore; - } - - public boolean isSplitKeystore() { - return this.splitKeystore; - } -} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/configuration/TlsClientConfig.java b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/configuration/TlsClientConfig.java deleted file mode 100644 index 4ed3177b97..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/configuration/TlsClientConfig.java +++ /dev/null @@ -1,85 +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.toolkit.tls.configuration; - -import org.apache.nifi.toolkit.tls.service.client.TlsCertificateSigningRequestPerformer; -import org.apache.nifi.util.StringUtils; - -import java.security.NoSuchAlgorithmException; - -/** - * Configuration object for CA client - */ -public class TlsClientConfig extends TlsConfig { - private String trustStore; - private String trustStorePassword; - private String trustStoreType = DEFAULT_KEY_STORE_TYPE; - - public TlsClientConfig() { - } - - public TlsClientConfig(TlsConfig tlsConfig) { - setToken(tlsConfig.getToken()); - setCaHostname(tlsConfig.getCaHostname()); - setPort(tlsConfig.getPort()); - setKeyStoreType(tlsConfig.getKeyStoreType()); - setKeyPairAlgorithm(tlsConfig.getKeyPairAlgorithm()); - setKeySize(tlsConfig.getKeySize()); - setSigningAlgorithm(tlsConfig.getSigningAlgorithm()); - setDnPrefix(tlsConfig.getDnPrefix()); - setDnSuffix(tlsConfig.getDnSuffix()); - setDomainAlternativeNames(tlsConfig.getDomainAlternativeNames()); - } - - - public String getTrustStoreType() { - return trustStoreType; - } - - public void setTrustStoreType(String trustStoreType) { - this.trustStoreType = trustStoreType; - } - - public String getTrustStore() { - return trustStore; - } - - public void setTrustStore(String trustStore) { - this.trustStore = trustStore; - } - - public String getTrustStorePassword() { - return trustStorePassword; - } - - public void setTrustStorePassword(String trustStorePassword) { - this.trustStorePassword = trustStorePassword; - } - - public TlsCertificateSigningRequestPerformer createCertificateSigningRequestPerformer() throws NoSuchAlgorithmException { - return new TlsCertificateSigningRequestPerformer(this); - } - - @Override - public void initDefaults() { - super.initDefaults(); - if (StringUtils.isEmpty(trustStoreType)) { - trustStoreType = DEFAULT_KEY_STORE_TYPE; - } - } -} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/configuration/TlsConfig.java b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/configuration/TlsConfig.java deleted file mode 100644 index c32029a7b2..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/configuration/TlsConfig.java +++ /dev/null @@ -1,237 +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.toolkit.tls.configuration; - -import java.util.List; -import org.apache.nifi.util.StringUtils; - -/** - * Configuration object for CA server - */ -public class TlsConfig { - public static final String DEFAULT_HOSTNAME = "localhost"; - public static final String DEFAULT_KEY_STORE_TYPE = "jks"; - public static final int DEFAULT_PORT = 9443; - public static final int DEFAULT_DAYS = 825; - public static final int DEFAULT_KEY_SIZE = 2048; - public static final String DEFAULT_KEY_PAIR_ALGORITHM = "RSA"; - public static final String DEFAULT_SIGNING_ALGORITHM = "SHA256WITHRSA"; - public static final String DEFAULT_DN_PREFIX = "CN="; - public static final String DEFAULT_DN_SUFFIX = ", OU=NIFI"; - - private int days = DEFAULT_DAYS; - private int keySize = DEFAULT_KEY_SIZE; - private String keyPairAlgorithm = DEFAULT_KEY_PAIR_ALGORITHM; - private String signingAlgorithm = DEFAULT_SIGNING_ALGORITHM; - - private String dn; - private String keyStore; - private String keyStoreType = DEFAULT_KEY_STORE_TYPE; - private String keyStorePassword; - private String keyPassword; - private String token; - private String caHostname = DEFAULT_HOSTNAME; - private int port = DEFAULT_PORT; - private String dnPrefix = DEFAULT_DN_PREFIX; - private String dnSuffix = DEFAULT_DN_SUFFIX; - private String additionalCACertificate = ""; - private List domainAlternativeNames; - - public String calcDefaultDn(String hostname) { - return dnPrefix + hostname + dnSuffix; - } - - public int getPort() { - return port; - } - - public void setPort(int port) { - this.port = port; - } - - public String getKeyStore() { - return keyStore; - } - - public void setKeyStore(String keyStore) { - this.keyStore = keyStore; - } - - public String getKeyStoreType() { - return keyStoreType; - } - - public void setKeyStoreType(String keyStoreType) { - this.keyStoreType = keyStoreType; - } - - public String getKeyStorePassword() { - return keyStorePassword; - } - - public void setKeyStorePassword(String keyStorePassword) { - this.keyStorePassword = keyStorePassword; - } - - public String getKeyPassword() { - return keyPassword; - } - - public void setKeyPassword(String keyPassword) { - this.keyPassword = keyPassword; - } - - public String getToken() { - return token; - } - - public void setToken(String token) { - this.token = token; - } - - public String getCaHostname() { - return caHostname; - } - - public void setCaHostname(String caHostname) { - this.caHostname = caHostname; - } - - public String getDn() { - return dn; - } - - public void setDn(String dn) { - this.dn = dn; - } - - public int getDays() { - return days; - } - - public void setDays(int days) { - this.days = days; - } - - public int getKeySize() { - return keySize; - } - - public void setKeySize(int keySize) { - this.keySize = keySize; - } - - public String getKeyPairAlgorithm() { - return keyPairAlgorithm; - } - - public void setKeyPairAlgorithm(String keyPairAlgorithm) { - this.keyPairAlgorithm = keyPairAlgorithm; - } - - public String getSigningAlgorithm() { - return signingAlgorithm; - } - - public void setSigningAlgorithm(String signingAlgorithm) { - this.signingAlgorithm = signingAlgorithm; - } - - public String getDnPrefix() { - return dnPrefix; - } - - public void setDnPrefix(String dnPrefix) { - this.dnPrefix = dnPrefix; - } - - public String getDnSuffix() { - return dnSuffix; - } - - public void setDnSuffix(String dnSuffix) { - this.dnSuffix = dnSuffix; - } - - public void initDefaults() { - if (days == 0) { - days = DEFAULT_DAYS; - } - if (keySize == 0) { - keySize = DEFAULT_KEY_SIZE; - } - if (StringUtils.isEmpty(keyPairAlgorithm)) { - keyPairAlgorithm = DEFAULT_KEY_PAIR_ALGORITHM; - } - if (StringUtils.isEmpty(signingAlgorithm)) { - signingAlgorithm = DEFAULT_SIGNING_ALGORITHM; - } - if (port == 0) { - port = DEFAULT_PORT; - } - if (StringUtils.isEmpty(keyStoreType)) { - keyStoreType = DEFAULT_KEY_STORE_TYPE; - } - if (StringUtils.isEmpty(caHostname)) { - caHostname = DEFAULT_HOSTNAME; - } - if (StringUtils.isEmpty(dn)) { - dn = calcDefaultDn(caHostname); - } - } - - public List getDomainAlternativeNames() { - return domainAlternativeNames; - } - - public void setDomainAlternativeNames(List domainAlternativeNames) { - this.domainAlternativeNames = domainAlternativeNames; - } - - /** - * Returns the path to an additional CA certificate file in PEM format which has been used to sign the CA certificate the toolkit will use. - * - * Example: - * - * nifi-cert.pem [existing PEM file for intermediate CA generated by Org's IT team and signed by org-ca.pem] - * org-ca.pem [PEM file for root CA owned by Org's IT team] - * - * {@code getAdditionalCACertificate() == "/path/to/org-ca.pem"} - * - * @return the path to this file - */ - public String getAdditionalCACertificate() { - return additionalCACertificate; - } - - /** - * Sets the path to an additional CA certificate file in PEM format which has been used to sign the CA certificate the toolkit will use. - * - * Example: - * - * nifi-cert.pem [existing PEM file for intermediate CA generated by Org's IT team and signed by org-ca.pem] - * org-ca.pem [PEM file for root CA owned by Org's IT team] - * - * {@code setAdditionalCACertificate("/path/to/org-ca.pem");} - * - * @param additionalCACertificate the path to this file - */ - public void setAdditionalCACertificate(String additionalCACertificate) { - this.additionalCACertificate = additionalCACertificate; - } -} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/manager/BaseTlsManager.java b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/manager/BaseTlsManager.java deleted file mode 100644 index a5a5d1c082..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/manager/BaseTlsManager.java +++ /dev/null @@ -1,177 +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.toolkit.tls.manager; - -import org.apache.nifi.security.util.KeyStoreUtils; -import org.apache.nifi.toolkit.tls.configuration.TlsConfig; -import org.apache.nifi.toolkit.tls.manager.writer.ConfigurationWriter; -import org.apache.nifi.toolkit.tls.util.InputStreamFactory; -import org.apache.nifi.toolkit.tls.util.OutputStreamFactory; -import org.apache.nifi.toolkit.tls.util.PasswordUtil; -import org.apache.nifi.toolkit.tls.util.TlsHelper; -import org.apache.nifi.util.StringUtils; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.security.GeneralSecurityException; -import java.security.KeyPair; -import java.security.KeyStore; -import java.security.cert.Certificate; -import java.util.ArrayList; -import java.util.List; - -/** - * Base class for managing KeyStores and Certificates - */ -public class BaseTlsManager { - private final TlsConfig tlsConfig; - private final PasswordUtil passwordUtil; - private final InputStreamFactory inputStreamFactory; - private final KeyStore keyStore; - private final List> configurationWriters; - private boolean differentKeyAndKeyStorePassword = false; - private boolean keyStorePasswordGenerated = false; - - public BaseTlsManager(TlsConfig tlsConfig) throws GeneralSecurityException, IOException { - this(tlsConfig, new PasswordUtil(), FileInputStream::new); - } - - public BaseTlsManager(TlsConfig tlsConfig, PasswordUtil passwordUtil, InputStreamFactory inputStreamFactory) throws GeneralSecurityException, IOException { - this.tlsConfig = tlsConfig; - this.passwordUtil = passwordUtil; - this.inputStreamFactory = inputStreamFactory; - this.keyStore = loadKeystore(tlsConfig.getKeyStore(), tlsConfig.getKeyStoreType(), getKeyStorePassword()); - this.configurationWriters = new ArrayList<>(); - } - - /** - * Returns the KeyStore - * - * @return the KeyStore - */ - public KeyStore getKeyStore() { - return keyStore; - } - - /** - * Returns an entry from the KeyStore with the given alias - * - * @param alias the alias - * @return an entry from the KeyStore with the given alias - * @throws GeneralSecurityException if there is a problem retrieving the entry - */ - public KeyStore.Entry getEntry(String alias) throws GeneralSecurityException { - String keyPassword = getKeyPassword(); - return keyStore.getEntry(alias, new KeyStore.PasswordProtection(keyPassword == null ? null : keyPassword.toCharArray())); - } - - /** - * Adds the private key of the KeyPair to the KeyStore and returns the entry - * - * @param keyPair the KeyPair - * @param alias the alias - * @param certificates the certificate chain - * @return the entry - * @throws GeneralSecurityException if there is a problem performing the operation - */ - public KeyStore.Entry addPrivateKeyToKeyStore(KeyPair keyPair, String alias, Certificate... certificates) throws GeneralSecurityException { - String passphrase = getKeyPassword(); - keyStore.setKeyEntry(alias, keyPair.getPrivate(), passphrase == null ? null : passphrase.toCharArray(), certificates); - return getEntry(alias); - } - - /** - * Sets a flag indicating whether to use a different key and keystore password - * - * @param differentKeyAndKeyStorePassword a flag indicating whether to use a different key and keystore password - */ - public void setDifferentKeyAndKeyStorePassword(boolean differentKeyAndKeyStorePassword) { - this.differentKeyAndKeyStorePassword = differentKeyAndKeyStorePassword; - } - - private String getKeyPassword() { - String result = tlsConfig.getKeyPassword(); - if (StringUtils.isEmpty(result)) { - if (differentKeyAndKeyStorePassword) { - result = passwordUtil.generatePassword(); - } else { - result = getKeyStorePassword(); - } - tlsConfig.setKeyPassword(result); - } - return result; - } - - private String getKeyStorePassword() { - String result = tlsConfig.getKeyStorePassword(); - if (StringUtils.isEmpty(result)) { - result = passwordUtil.generatePassword(); - keyStorePasswordGenerated = true; - tlsConfig.setKeyStorePassword(result); - } - return result; - } - - protected KeyStore loadKeystore(String keyStore, String keyStoreType, String keyStorePassword) throws GeneralSecurityException, IOException { - KeyStore result = KeyStoreUtils.getKeyStore(keyStoreType); - File file = new File(keyStore); - if (file.exists()) { - try (InputStream stream = inputStreamFactory.create(file)) { - result.load(stream, keyStorePassword.toCharArray()); - } - return result; - } - result.load(null, null); - return result; - } - - /** - * Writes the KeyStore and configuration information - * - * @param outputStreamFactory factory interface for creating output streams - * @throws IOException if there is an IO problem while writing - * @throws GeneralSecurityException if there is a security problem while writing - */ - public void write(OutputStreamFactory outputStreamFactory) throws IOException, GeneralSecurityException { - String keyStorePassword = getKeyStorePassword(); - tlsConfig.setKeyStorePassword(TlsHelper.writeKeyStore(keyStore, outputStreamFactory, new File(tlsConfig.getKeyStore()), keyStorePassword, keyStorePasswordGenerated)); - - for (ConfigurationWriter configurationWriter : configurationWriters) { - configurationWriter.write(tlsConfig, outputStreamFactory); - } - } - - protected PasswordUtil getPasswordUtil() { - return passwordUtil; - } - - /** - * Adds a ConfigurationWriter which will have an opportunity to write configuration information - * - * @param configurationWriter a ConfigurationWriter which will have an opportunity to write configuration information - */ - public void addConfigurationWriter(ConfigurationWriter configurationWriter) { - configurationWriters.add(configurationWriter); - } - - protected TlsConfig getTlsConfig() { - return tlsConfig; - } -} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/manager/TlsCertificateAuthorityManager.java b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/manager/TlsCertificateAuthorityManager.java deleted file mode 100644 index 9d2f7e1f37..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/manager/TlsCertificateAuthorityManager.java +++ /dev/null @@ -1,65 +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.toolkit.tls.manager; - -import org.apache.nifi.security.cert.builder.StandardCertificateBuilder; -import org.apache.nifi.toolkit.tls.configuration.TlsConfig; -import org.apache.nifi.toolkit.tls.standalone.TlsToolkitStandalone; -import org.apache.nifi.toolkit.tls.util.TlsHelper; - -import javax.security.auth.x500.X500Principal; -import java.io.IOException; -import java.security.GeneralSecurityException; -import java.security.KeyPair; -import java.security.KeyStore; -import java.security.cert.X509Certificate; -import java.time.Duration; - -/** - * KeyStore manager capable of reading or instantiating a CA Certificate - */ -public class TlsCertificateAuthorityManager extends BaseTlsManager { - public TlsCertificateAuthorityManager(TlsConfig tlsConfig) throws GeneralSecurityException, IOException { - super(tlsConfig); - } - - /** - * Reads the CA from the KeyStore, creating one and putting it into the KeyStore if not present - * - * @return the PrivateKeyEntry for the CA - * - * @throws GeneralSecurityException if there is a security problem - * @throws IOException if there is an IO problem - */ - public KeyStore.PrivateKeyEntry getOrGenerateCertificateAuthority() throws GeneralSecurityException, IOException { - KeyStore.Entry entry = getEntry(TlsToolkitStandalone.NIFI_KEY); - if (entry == null) { - TlsConfig tlsConfig = getTlsConfig(); - KeyPair keyPair = TlsHelper.generateKeyPair(tlsConfig.getKeyPairAlgorithm(), tlsConfig.getKeySize()); - final X500Principal issuer = new X500Principal(tlsConfig.getDn()); - final Duration validityPeriod = Duration.ofDays(tlsConfig.getDays()); - final StandardCertificateBuilder certificateBuilder = new StandardCertificateBuilder(keyPair, issuer, validityPeriod); - X509Certificate caCert = certificateBuilder.build(); - entry = addPrivateKeyToKeyStore(keyPair, TlsToolkitStandalone.NIFI_KEY, caCert); - } else if (!KeyStore.PrivateKeyEntry.class.isInstance(entry)) { - throw new IOException("Expected " + TlsToolkitStandalone.NIFI_KEY + " alias to contain a private key entry"); - } - - return (KeyStore.PrivateKeyEntry) entry; - } -} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/manager/TlsClientManager.java b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/manager/TlsClientManager.java deleted file mode 100644 index ff11d14b9f..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/manager/TlsClientManager.java +++ /dev/null @@ -1,118 +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.toolkit.tls.manager; - -import org.apache.nifi.toolkit.tls.configuration.TlsClientConfig; -import org.apache.nifi.toolkit.tls.manager.writer.ConfigurationWriter; -import org.apache.nifi.toolkit.tls.util.InputStreamFactory; -import org.apache.nifi.toolkit.tls.util.OutputStreamFactory; -import org.apache.nifi.toolkit.tls.util.PasswordUtil; -import org.apache.nifi.toolkit.tls.util.TlsHelper; -import org.apache.nifi.util.StringUtils; -import org.bouncycastle.openssl.jcajce.JcaMiscPEMGenerator; -import org.bouncycastle.util.io.pem.PemWriter; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.security.GeneralSecurityException; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.UnrecoverableEntryException; -import java.security.cert.Certificate; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -public class TlsClientManager extends BaseTlsManager { - private final TlsClientConfig tlsClientConfig; - private final KeyStore trustStore; - private final List> configurationWriters; - private final Set certificateAliases; - private File certificateAuthorityDirectory; - - public TlsClientManager(TlsClientConfig tlsClientConfig) throws GeneralSecurityException, IOException { - this(tlsClientConfig, new PasswordUtil(), FileInputStream::new); - } - - public TlsClientManager(TlsClientConfig tlsClientConfig, PasswordUtil passwordUtil, InputStreamFactory inputStreamFactory) throws GeneralSecurityException, IOException { - super(tlsClientConfig, passwordUtil, inputStreamFactory); - this.trustStore = loadKeystore(tlsClientConfig.getTrustStore(), tlsClientConfig.getTrustStoreType(), tlsClientConfig.getTrustStorePassword()); - this.tlsClientConfig = tlsClientConfig; - this.configurationWriters = new ArrayList<>(); - this.certificateAliases = new HashSet<>(); - } - - public void setCertificateEntry(String alias, Certificate cert) throws KeyStoreException { - trustStore.setCertificateEntry(alias, cert); - certificateAliases.add(alias); - } - - public void setCertificateAuthorityDirectory(File certificateAuthorityDirectory) { - this.certificateAuthorityDirectory = certificateAuthorityDirectory; - } - - @Override - public void write(OutputStreamFactory outputStreamFactory) throws IOException, GeneralSecurityException { - super.write(outputStreamFactory); - - String trustStorePassword = tlsClientConfig.getTrustStorePassword(); - boolean trustStorePasswordGenerated = false; - if (StringUtils.isEmpty(trustStorePassword)) { - trustStorePassword = getPasswordUtil().generatePassword(); - trustStorePasswordGenerated = true; - } - - trustStorePassword = TlsHelper.writeKeyStore(trustStore, outputStreamFactory, new File(tlsClientConfig.getTrustStore()), trustStorePassword, trustStorePasswordGenerated); - tlsClientConfig.setTrustStorePassword(trustStorePassword); - - for (ConfigurationWriter configurationWriter : configurationWriters) { - configurationWriter.write(tlsClientConfig, outputStreamFactory); - } - - if (certificateAuthorityDirectory != null) { - // Write out all trusted certificates from truststore - for (String alias : Collections.list(trustStore.aliases())) { - try { - KeyStore.Entry trustStoreEntry = trustStore.getEntry(alias, null); - if (trustStoreEntry instanceof KeyStore.TrustedCertificateEntry) { - Certificate trustedCertificate = ((KeyStore.TrustedCertificateEntry) trustStoreEntry).getTrustedCertificate(); - try (OutputStream outputStream = outputStreamFactory.create(new File(certificateAuthorityDirectory, TlsHelper.escapeFilename(alias) + ".pem")); - OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream); - PemWriter pemWriter = new PemWriter(outputStreamWriter)) { - pemWriter.writeObject(new JcaMiscPEMGenerator(trustedCertificate)); - } - } - } catch (UnrecoverableEntryException e) { - // Ignore, not a trusted cert - } - } - } - } - - public void addClientConfigurationWriter(ConfigurationWriter configurationWriter) { - configurationWriters.add(configurationWriter); - } - - - -} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/manager/writer/ConfigurationWriter.java b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/manager/writer/ConfigurationWriter.java deleted file mode 100644 index 435bfd5bf5..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/manager/writer/ConfigurationWriter.java +++ /dev/null @@ -1,38 +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.toolkit.tls.manager.writer; - -import org.apache.nifi.toolkit.tls.util.OutputStreamFactory; - -import java.io.IOException; - -/** - * Class that can write out configuration information on the given object - * - * @param the type of Object to write information about - */ -public interface ConfigurationWriter { - /** - * Writes configuration information about the given object - * - * @param t the object - * @param outputStreamFactory an OutputStreamFactory - * @throws IOException if there is an IO problem - */ - void write(T t, OutputStreamFactory outputStreamFactory) throws IOException; -} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/manager/writer/JsonConfigurationWriter.java b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/manager/writer/JsonConfigurationWriter.java deleted file mode 100644 index 77bdc34acb..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/manager/writer/JsonConfigurationWriter.java +++ /dev/null @@ -1,48 +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.toolkit.tls.manager.writer; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.ObjectWriter; -import org.apache.nifi.toolkit.tls.util.OutputStreamFactory; - -import java.io.File; -import java.io.IOException; -import java.io.OutputStream; - -/** - * Will write the object in JSON format - * - * @param the type of object - */ -public class JsonConfigurationWriter implements ConfigurationWriter { - private final ObjectWriter objectWriter; - private final File file; - - public JsonConfigurationWriter(ObjectMapper objectMapper, File file) { - this.objectWriter = objectMapper.writerWithDefaultPrettyPrinter(); - this.file = file; - } - - @Override - public void write(T tlsConfig, OutputStreamFactory outputStreamFactory) throws IOException { - try (OutputStream stream = outputStreamFactory.create(file)) { - objectWriter.writeValue(stream, tlsConfig); - } - } -} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/manager/writer/NifiPropertiesTlsClientConfigWriter.java b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/manager/writer/NifiPropertiesTlsClientConfigWriter.java deleted file mode 100644 index 9d24c5a838..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/manager/writer/NifiPropertiesTlsClientConfigWriter.java +++ /dev/null @@ -1,127 +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.toolkit.tls.manager.writer; - -import org.apache.nifi.toolkit.tls.configuration.TlsClientConfig; -import org.apache.nifi.toolkit.tls.properties.NiFiPropertiesWriter; -import org.apache.nifi.toolkit.tls.properties.NiFiPropertiesWriterFactory; -import org.apache.nifi.toolkit.tls.util.OutputStreamFactory; -import org.apache.nifi.util.NiFiProperties; -import org.apache.nifi.util.StringUtils; - -import java.io.File; -import java.io.IOException; -import java.io.OutputStream; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.Map; -import java.util.Properties; -import java.util.Set; -import java.util.function.Function; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -/** - * Will write a nifi.properties file appropriate for the given client config - */ -public class NifiPropertiesTlsClientConfigWriter implements ConfigurationWriter { - public static final String HOSTNAME_PROPERTIES = "hostname.properties"; - public static final String OVERLAY_PROPERTIES = "overlay.properties"; - public static final String INCREMENTING_PROPERTIES = "incrementing.properties"; - public static final String CONF = "./conf/"; - private final NiFiPropertiesWriterFactory niFiPropertiesWriterFactory; - private final File outputFile; - private final String hostname; - private final int hostNum; - private final Properties overlayProperties; - private final Set metaProperties; - - public NifiPropertiesTlsClientConfigWriter(NiFiPropertiesWriterFactory niFiPropertiesWriterFactory, File outputFile, String hostname, int hostNum) throws IOException { - this.niFiPropertiesWriterFactory = niFiPropertiesWriterFactory; - this.outputFile = outputFile; - this.hostname = hostname; - this.hostNum = hostNum; - this.overlayProperties = new Properties(); - this.overlayProperties.load(getClass().getClassLoader().getResourceAsStream(OVERLAY_PROPERTIES)); - HashSet metaProperties = new HashSet<>(); - metaProperties.add(HOSTNAME_PROPERTIES); - metaProperties.add(INCREMENTING_PROPERTIES); - getIncrementingPropertiesStream().forEach(metaProperties::add); - this.metaProperties = Collections.unmodifiableSet(metaProperties); - } - - @Override - public void write(TlsClientConfig tlsClientConfig, OutputStreamFactory outputStreamFactory) throws IOException { - NiFiPropertiesWriter niFiPropertiesWriter = niFiPropertiesWriterFactory.create(); - updateProperties(niFiPropertiesWriter, tlsClientConfig); - try (OutputStream stream = outputStreamFactory.create(outputFile)) { - niFiPropertiesWriter.writeNiFiProperties(stream); - } - } - - protected void updateProperties(NiFiPropertiesWriter niFiPropertiesWriter, TlsClientConfig tlsClientConfig) throws IOException { - niFiPropertiesWriter.setPropertyValue(NiFiProperties.SECURITY_KEYSTORE, CONF + new File(tlsClientConfig.getKeyStore()).getName()); - niFiPropertiesWriter.setPropertyValue(NiFiProperties.SECURITY_KEYSTORE_TYPE, tlsClientConfig.getKeyStoreType()); - niFiPropertiesWriter.setPropertyValue(NiFiProperties.SECURITY_KEYSTORE_PASSWD, tlsClientConfig.getKeyStorePassword()); - niFiPropertiesWriter.setPropertyValue(NiFiProperties.SECURITY_KEY_PASSWD, tlsClientConfig.getKeyPassword()); - - niFiPropertiesWriter.setPropertyValue(NiFiProperties.SECURITY_TRUSTSTORE, CONF + new File(tlsClientConfig.getTrustStore()).getName()); - niFiPropertiesWriter.setPropertyValue(NiFiProperties.SECURITY_TRUSTSTORE_TYPE, tlsClientConfig.getTrustStoreType()); - niFiPropertiesWriter.setPropertyValue(NiFiProperties.SECURITY_TRUSTSTORE_PASSWD, tlsClientConfig.getTrustStorePassword()); - - getHostnamePropertyStream().forEach(s -> niFiPropertiesWriter.setPropertyValue(s, hostname)); - - overlayProperties.stringPropertyNames().stream().filter(s -> !metaProperties.contains(s)).forEach(s -> niFiPropertiesWriter.setPropertyValue(s, overlayProperties.getProperty(s))); - - getIncrementingPropertyMap().entrySet().forEach(nameToIntegerEntry -> niFiPropertiesWriter.setPropertyValue(nameToIntegerEntry.getKey(), Integer.toString(nameToIntegerEntry.getValue()))); - } - - protected Properties getOverlayProperties() { - return overlayProperties; - } - - protected Map getIncrementingPropertyMap() { - return getIncrementingPropertiesStream().collect(Collectors.toMap(Function.identity(), portProperty -> { - String portVal = overlayProperties.getProperty(portProperty); - int startingPort; - try { - startingPort = Integer.parseInt(portVal); - } catch (NumberFormatException e) { - throw new NumberFormatException("Expected numeric values in " + OVERLAY_PROPERTIES + " (" + portProperty + " was " + portVal + ")"); - } - return startingPort + hostNum - 1; - })); - } - - protected Stream getIncrementingPropertiesStream() { - return getCommaSeparatedPropertyStream(INCREMENTING_PROPERTIES); - } - - protected Stream getHostnamePropertyStream() { - return getCommaSeparatedPropertyStream(HOSTNAME_PROPERTIES); - } - - private Stream getCommaSeparatedPropertyStream(String property) { - String hostnamePropertyString = overlayProperties.getProperty(property); - if (!StringUtils.isEmpty(hostnamePropertyString)) { - return Arrays.stream(hostnamePropertyString.split(",")).map(String::trim); - } - return Stream.of(); - } -} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/properties/NiFiPropertiesWriter.java b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/properties/NiFiPropertiesWriter.java deleted file mode 100644 index 19084617f3..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/properties/NiFiPropertiesWriter.java +++ /dev/null @@ -1,93 +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.toolkit.tls.properties; - -import java.io.BufferedWriter; -import java.io.IOException; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * Class capable of writing out updated NiFi properties. It keeps a list of original lines and a map of updates to apply. - * - * It first writes all the original properties (with updated values if they exist) and then adds any new properties at the end. - */ -public class NiFiPropertiesWriter { - private final List lines; - private final Map updatedValues; - - public NiFiPropertiesWriter(List lines) { - this.lines = new ArrayList<>(lines); - this.updatedValues = new HashMap<>(); - } - - /** - * Sets a property value - * - * @param key the property key - * @param value the property value - */ - public void setPropertyValue(String key, String value) { - updatedValues.put(key, value); - } - - /** - * Write an updated nifi.properties to the given OutputStream - * - * @param outputStream the output stream - * @throws IOException if there is an IO error - */ - public void writeNiFiProperties(OutputStream outputStream) throws IOException { - try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream))) { - Map remainingValues = new HashMap<>(updatedValues); - Set keysSeen = new HashSet<>(); - for (String line : lines) { - String key = line.split("=")[0].trim(); - boolean outputLine = true; - if (!key.isEmpty() && !key.startsWith("#")) { - if (!keysSeen.add(key)) { - throw new IOException("Found key more than once in nifi.properties: " + key); - } - String value = remainingValues.remove(key); - if (value != null) { - writer.write(key); - writer.write("="); - writer.write(value); - outputLine = false; - } - } - if (outputLine) { - writer.write(line); - } - writer.newLine(); - } - for (Map.Entry keyValueEntry : remainingValues.entrySet()) { - writer.write(keyValueEntry.getKey()); - writer.write("="); - writer.write(keyValueEntry.getValue()); - writer.newLine(); - } - } - } -} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/properties/NiFiPropertiesWriterFactory.java b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/properties/NiFiPropertiesWriterFactory.java deleted file mode 100644 index cf2383c0b6..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/properties/NiFiPropertiesWriterFactory.java +++ /dev/null @@ -1,59 +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.toolkit.tls.properties; - -import org.apache.nifi.toolkit.tls.TlsToolkitMain; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * Factory for creating NifiPropertiesWriters so that the lines only have to be read once - */ -public class NiFiPropertiesWriterFactory { - private final List lines; - - public NiFiPropertiesWriterFactory() throws IOException { - this(TlsToolkitMain.class.getClassLoader().getResourceAsStream("conf/nifi.properties")); - } - - public NiFiPropertiesWriterFactory(InputStream inputStream) throws IOException { - List lines = new ArrayList<>(); - try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream))) { - String line; - while ((line = bufferedReader.readLine()) != null) { - lines.add(line.trim()); - } - } - this.lines = Collections.unmodifiableList(lines); - } - - /** - * Returns a NifiPropertiesWriter with based on the read nifi.properties - * - * @return a NifiPropertiesWriter with based on the read nifi.properties - */ - public NiFiPropertiesWriter create() { - return new NiFiPropertiesWriter(lines); - } -} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/BaseCertificateAuthorityCommandLine.java b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/BaseCertificateAuthorityCommandLine.java deleted file mode 100644 index 8f56533466..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/BaseCertificateAuthorityCommandLine.java +++ /dev/null @@ -1,117 +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.toolkit.tls.service; - -import org.apache.commons.cli.CommandLine; -import org.apache.nifi.toolkit.tls.commandLine.BaseTlsToolkitCommandLine; -import org.apache.nifi.toolkit.tls.commandLine.CommandLineParseException; -import org.apache.nifi.toolkit.tls.commandLine.ExitCode; -import org.apache.nifi.toolkit.tls.configuration.TlsConfig; -import org.apache.nifi.util.StringUtils; - -import java.io.File; -import java.nio.charset.StandardCharsets; - -/** - * Common base argument logic for the CA server and client - */ -public abstract class BaseCertificateAuthorityCommandLine extends BaseTlsToolkitCommandLine { - public static final String TOKEN_ARG = "token"; - public static final String CONFIG_JSON_ARG = "configJson"; - public static final String READ_CONFIG_JSON_ARG = "configJsonIn"; - public static final String USE_CONFIG_JSON_ARG = "useConfigJson"; - - public static final String PORT_ARG = "PORT"; - public static final String DEFAULT_CONFIG_JSON = new File("config.json").getPath(); - - private String token; - private String configJsonOut; - private String configJsonIn; - private int port; - private String dn; - - public BaseCertificateAuthorityCommandLine(String header) { - super(header); - addOptionWithArg("t", TOKEN_ARG, getTokenDescription()); - addOptionWithArg("f", CONFIG_JSON_ARG, "The place to write configuration info", DEFAULT_CONFIG_JSON); - addOptionWithArg(null, READ_CONFIG_JSON_ARG, "The place to read configuration info from (defaults to the value of " + CONFIG_JSON_ARG + "), implies " - + USE_CONFIG_JSON_ARG + " if set.", CONFIG_JSON_ARG + " value"); - addOptionNoArg("F", USE_CONFIG_JSON_ARG, "Flag specifying that all configuration is read from " + CONFIG_JSON_ARG + " to facilitate automated use (otherwise " - + CONFIG_JSON_ARG + " will only be written to."); - addOptionWithArg("p", PORT_ARG, getPortDescription(), TlsConfig.DEFAULT_PORT); - addOptionWithArg("D", DN_ARG, getDnDescription(), new TlsConfig().calcDefaultDn(getDnHostname())); - } - - protected abstract String getTokenDescription(); - - protected abstract String getDnDescription(); - - protected abstract String getPortDescription(); - - protected abstract String getDnHostname(); - - @Override - protected CommandLine doParse(String[] args) throws CommandLineParseException { - CommandLine commandLine = super.doParse(args); - - token = commandLine.getOptionValue(TOKEN_ARG); - - boolean useConfigJson = commandLine.hasOption(USE_CONFIG_JSON_ARG); - - configJsonOut = commandLine.getOptionValue(CONFIG_JSON_ARG, DEFAULT_CONFIG_JSON); - configJsonIn = commandLine.getOptionValue(READ_CONFIG_JSON_ARG); - if (StringUtils.isEmpty(configJsonIn) && useConfigJson) { - configJsonIn = configJsonOut; - } - - if (StringUtils.isEmpty(token) && StringUtils.isEmpty(configJsonIn)) { - printUsageAndThrow(TOKEN_ARG + " argument must not be empty unless " + USE_CONFIG_JSON_ARG + " or " + READ_CONFIG_JSON_ARG+ " set", ExitCode.ERROR_TOKEN_ARG_EMPTY); - } - - if (!StringUtils.isEmpty(token)) { - byte[] tokenBytes = token.getBytes(StandardCharsets.UTF_8); - if (tokenBytes.length < 16) { - printUsageAndThrow(TOKEN_ARG + " does not meet minimum size of 16 bytes", ExitCode.ERROR_TOKEN_ARG_TOO_SHORT); - } - } - - port = getIntValue(commandLine, PORT_ARG, TlsConfig.DEFAULT_PORT); - dn = commandLine.getOptionValue(DN_ARG, new TlsConfig().calcDefaultDn(getDnHostname())); - return commandLine; - } - - public String getToken() { - return token; - } - - public String getConfigJsonOut() { - return configJsonOut; - } - - public String getConfigJsonIn() { - return configJsonIn; - } - - public int getPort() { - return port; - } - - public String getDn() { - return dn; - } -} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/client/TlsCertificateAuthorityClient.java b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/client/TlsCertificateAuthorityClient.java deleted file mode 100644 index 2068c98dd1..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/client/TlsCertificateAuthorityClient.java +++ /dev/null @@ -1,90 +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.toolkit.tls.service.client; - -import com.fasterxml.jackson.databind.ObjectMapper; -import org.apache.nifi.toolkit.tls.configuration.TlsClientConfig; -import org.apache.nifi.toolkit.tls.manager.TlsClientManager; -import org.apache.nifi.toolkit.tls.manager.writer.JsonConfigurationWriter; -import org.apache.nifi.toolkit.tls.service.BaseCertificateAuthorityCommandLine; -import org.apache.nifi.toolkit.tls.standalone.TlsToolkitStandalone; -import org.apache.nifi.toolkit.tls.util.OutputStreamFactory; -import org.apache.nifi.toolkit.tls.util.TlsHelper; -import org.apache.nifi.util.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.security.KeyPair; -import java.security.cert.X509Certificate; - -/** - * Client that will generate a CSR and submit to a CA, writing out the results to a keystore and truststore along with a config file if successful - */ -public class TlsCertificateAuthorityClient { - private final Logger logger = LoggerFactory.getLogger(TlsCertificateAuthorityClient.class); - private final OutputStreamFactory outputStreamFactory; - - public TlsCertificateAuthorityClient() { - this(FileOutputStream::new); - } - - public TlsCertificateAuthorityClient(OutputStreamFactory outputStreamFactory) { - this.outputStreamFactory = outputStreamFactory; - } - - public void generateCertificateAndGetItSigned(TlsClientConfig tlsClientConfig, String certificateDirectory, String configJson, boolean differentKeyAndKeyStorePassword) throws Exception { - TlsClientManager tlsClientManager; - try { - tlsClientManager = new TlsClientManager(tlsClientConfig); - } catch (IOException e) { - logger.error("Unable to open existing keystore, it can be reused by specifiying both " + BaseCertificateAuthorityCommandLine.CONFIG_JSON_ARG + " and " + - BaseCertificateAuthorityCommandLine.USE_CONFIG_JSON_ARG); - throw e; - } - tlsClientManager.setDifferentKeyAndKeyStorePassword(differentKeyAndKeyStorePassword); - - if (!StringUtils.isEmpty(certificateDirectory)) { - tlsClientManager.setCertificateAuthorityDirectory(new File(certificateDirectory)); - } - - if (!StringUtils.isEmpty(configJson)) { - tlsClientManager.addClientConfigurationWriter(new JsonConfigurationWriter<>(new ObjectMapper(), new File(configJson))); - } - - if (tlsClientManager.getEntry(TlsToolkitStandalone.NIFI_KEY) == null) { - if (logger.isInfoEnabled()) { - logger.info("Requesting new certificate from " + tlsClientConfig.getCaHostname() + ":" + tlsClientConfig.getPort()); - } - KeyPair keyPair = TlsHelper.generateKeyPair(tlsClientConfig.getKeyPairAlgorithm(), tlsClientConfig.getKeySize()); - - X509Certificate[] certificates = tlsClientConfig.createCertificateSigningRequestPerformer().perform(keyPair); - - tlsClientManager.addPrivateKeyToKeyStore(keyPair, TlsToolkitStandalone.NIFI_KEY, certificates); - tlsClientManager.setCertificateEntry(TlsToolkitStandalone.NIFI_CERT, certificates[certificates.length - 1]); - } else { - if (logger.isInfoEnabled()) { - logger.info("Already had entry for " + TlsToolkitStandalone.NIFI_KEY + " not requesting new certificate."); - } - } - - tlsClientManager.write(outputStreamFactory); - } -} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/client/TlsCertificateAuthorityClientCommandLine.java b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/client/TlsCertificateAuthorityClientCommandLine.java deleted file mode 100644 index 194418afe6..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/client/TlsCertificateAuthorityClientCommandLine.java +++ /dev/null @@ -1,173 +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.toolkit.tls.service.client; - -import com.fasterxml.jackson.databind.ObjectMapper; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; -import org.apache.commons.cli.CommandLine; -import org.apache.nifi.toolkit.tls.commandLine.CommandLineParseException; -import org.apache.nifi.toolkit.tls.commandLine.ExitCode; -import org.apache.nifi.toolkit.tls.configuration.InstanceDefinition; -import org.apache.nifi.toolkit.tls.configuration.TlsClientConfig; -import org.apache.nifi.toolkit.tls.service.BaseCertificateAuthorityCommandLine; -import org.apache.nifi.toolkit.tls.util.InputStreamFactory; -import org.apache.nifi.util.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Command line parser for a TlsClientConfig object and a main entry point to invoke the parser and run the CA client - */ -public class TlsCertificateAuthorityClientCommandLine extends BaseCertificateAuthorityCommandLine { - public static final String DESCRIPTION = "Generates a private key and gets it signed by the certificate authority."; - public static final String CERTIFICATE_DIRECTORY = "certificateDirectory"; - public static final String SUBJECT_ALTERNATIVE_NAMES = "subjectAlternativeNames"; - public static final String DEFAULT_CERTIFICATE_DIRECTORY = "."; - - private final Logger logger = LoggerFactory.getLogger(TlsCertificateAuthorityClientCommandLine.class); - private final InputStreamFactory inputStreamFactory; - - private String certificateDirectory; - private List domainAlternativeNames; - - public TlsCertificateAuthorityClientCommandLine() { - this(FileInputStream::new); - } - - public TlsCertificateAuthorityClientCommandLine(InputStreamFactory inputStreamFactory) { - super(DESCRIPTION); - this.inputStreamFactory = inputStreamFactory; - addOptionWithArg("C", CERTIFICATE_DIRECTORY, "The file to write the CA certificate to", DEFAULT_CERTIFICATE_DIRECTORY); - addOptionWithArg(null, SUBJECT_ALTERNATIVE_NAMES, "Comma-separated list of domains to use as Subject Alternative Names in the certificate"); - } - - public static void main(String[] args) throws Exception { - TlsCertificateAuthorityClientCommandLine tlsCertificateAuthorityClientCommandLine = new TlsCertificateAuthorityClientCommandLine(); - try { - tlsCertificateAuthorityClientCommandLine.parse(args); - } catch (CommandLineParseException e) { - System.exit(e.getExitCode().ordinal()); - } - new TlsCertificateAuthorityClient().generateCertificateAndGetItSigned(tlsCertificateAuthorityClientCommandLine.createClientConfig(), - tlsCertificateAuthorityClientCommandLine.getCertificateDirectory(), tlsCertificateAuthorityClientCommandLine.getConfigJsonOut(), - tlsCertificateAuthorityClientCommandLine.differentPasswordForKeyAndKeystore()); - System.exit(ExitCode.SUCCESS.ordinal()); - } - - @Override - protected boolean shouldAddDaysArg() { - return false; - } - - @Override - protected boolean shouldAddSigningAlgorithmArg() { - return false; - } - - @Override - protected String getTokenDescription() { - return "The token to use to prevent MITM (required and must be same as one used by CA)"; - } - - @Override - protected String getDnDescription() { - return "The dn to use for the client certificate"; - } - - @Override - protected String getPortDescription() { - return "The port to use to communicate with the Certificate Authority"; - } - - @Override - protected String getDnHostname() { - try { - return InetAddress.getLocalHost().getHostName(); - } catch (UnknownHostException e) { - logger.warn("Unable to determine hostname", e); - return "localhost"; - } - } - - @Override - protected CommandLine doParse(String[] args) throws CommandLineParseException { - CommandLine commandLine = super.doParse(args); - certificateDirectory = commandLine.getOptionValue(CERTIFICATE_DIRECTORY, DEFAULT_CERTIFICATE_DIRECTORY); - - if (commandLine.hasOption(SUBJECT_ALTERNATIVE_NAMES)) { - domainAlternativeNames = Collections.unmodifiableList( - InstanceDefinition.createDefinitions( - null, - Arrays.stream(commandLine.getOptionValues(SUBJECT_ALTERNATIVE_NAMES)).flatMap(s -> Arrays.stream(s.split(",")).map(String::trim)), - null, - null, - null - )); - } else { - domainAlternativeNames = Collections.EMPTY_LIST; - } - - return commandLine; - } - - public String getCertificateDirectory() { - return certificateDirectory; - } - - public List getDomainAlternativeNames() { - if (domainAlternativeNames == null) { - domainAlternativeNames = Collections.EMPTY_LIST; - } - return domainAlternativeNames.stream().map(InstanceDefinition::getHostname).collect(Collectors.toList()); - } - - public TlsClientConfig createClientConfig() throws IOException { - String configJsonIn = getConfigJsonIn(); - if (!StringUtils.isEmpty(configJsonIn)) { - try (InputStream inputStream = inputStreamFactory.create(new File(configJsonIn))) { - TlsClientConfig tlsClientConfig = new ObjectMapper().readValue(inputStream, TlsClientConfig.class); - tlsClientConfig.initDefaults(); - return tlsClientConfig; - } - } else { - TlsClientConfig tlsClientConfig = new TlsClientConfig(); - tlsClientConfig.setCaHostname(getCertificateAuthorityHostname()); - tlsClientConfig.setDn(getDn()); - tlsClientConfig.setDomainAlternativeNames(getDomainAlternativeNames()); - tlsClientConfig.setToken(getToken()); - tlsClientConfig.setPort(getPort()); - tlsClientConfig.setKeyStore(KEYSTORE + getKeyStoreType().toLowerCase()); - tlsClientConfig.setKeyStoreType(getKeyStoreType()); - tlsClientConfig.setTrustStore(TRUSTSTORE + tlsClientConfig.getTrustStoreType().toLowerCase()); - tlsClientConfig.setKeySize(getKeySize()); - tlsClientConfig.setKeyPairAlgorithm(getKeyAlgorithm()); - tlsClientConfig.setSigningAlgorithm(getSigningAlgorithm()); - return tlsClientConfig; - } - } - -} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/client/TlsCertificateAuthorityClientSocketFactory.java b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/client/TlsCertificateAuthorityClientSocketFactory.java deleted file mode 100644 index e5000c8e40..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/client/TlsCertificateAuthorityClientSocketFactory.java +++ /dev/null @@ -1,77 +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.toolkit.tls.service.client; - -import org.apache.http.HttpHost; -import org.apache.http.conn.ssl.SSLConnectionSocketFactory; -import org.apache.http.protocol.HttpContext; -import org.bouncycastle.asn1.x500.style.BCStyle; -import org.bouncycastle.asn1.x500.style.IETFUtils; -import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder; - -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSocket; -import java.io.IOException; -import java.net.InetSocketAddress; -import java.net.Socket; -import java.security.cert.X509Certificate; -import java.util.List; - -/** - * Socket Factory validates that it is talking to a RootCa claiming to have the given hostname. It adds the certificate - * to a list for later validation against the payload's hmac - */ -public class TlsCertificateAuthorityClientSocketFactory extends SSLConnectionSocketFactory { - private final String caHostname; - private final List certificates; - - public TlsCertificateAuthorityClientSocketFactory(SSLContext sslContext, String caHostname, List certificates) { - super(sslContext); - this.caHostname = caHostname; - this.certificates = certificates; - } - - @Override - public synchronized Socket connectSocket(int connectTimeout, Socket socket, HttpHost host, InetSocketAddress remoteAddress, - InetSocketAddress localAddress, HttpContext context) throws IOException { - Socket result = super.connectSocket(connectTimeout, socket, host, remoteAddress, localAddress, context); - if (!SSLSocket.class.isInstance(result)) { - throw new IOException("Expected tls socket"); - } - SSLSocket sslSocket = (SSLSocket) result; - java.security.cert.Certificate[] peerCertificateChain = sslSocket.getSession().getPeerCertificates(); - if (peerCertificateChain.length != 1) { - throw new IOException("Expected root ca cert"); - } - if (!X509Certificate.class.isInstance(peerCertificateChain[0])) { - throw new IOException("Expected root ca cert in X509 format"); - } - String cn; - try { - X509Certificate certificate = (X509Certificate) peerCertificateChain[0]; - cn = IETFUtils.valueToString(new JcaX509CertificateHolder(certificate).getSubject().getRDNs(BCStyle.CN)[0].getFirst().getValue()); - certificates.add(certificate); - } catch (Exception e) { - throw new IOException(e); - } - if (!caHostname.equals(cn)) { - throw new IOException("Expected cn of " + caHostname + " but got " + cn); - } - return result; - } -} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/client/TlsCertificateSigningRequestPerformer.java b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/client/TlsCertificateSigningRequestPerformer.java deleted file mode 100644 index 12530c15a5..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/client/TlsCertificateSigningRequestPerformer.java +++ /dev/null @@ -1,161 +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.toolkit.tls.service.client; - -import com.fasterxml.jackson.databind.ObjectMapper; -import java.io.IOException; -import java.io.StringReader; -import java.nio.charset.StandardCharsets; -import java.security.KeyPair; -import java.security.MessageDigest; -import java.security.cert.X509Certificate; -import java.util.ArrayList; -import java.util.List; -import java.util.function.Supplier; -import org.apache.commons.io.IOUtils; -import org.apache.commons.io.input.BoundedInputStream; -import org.apache.http.HttpHost; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.conn.ssl.TrustSelfSignedStrategy; -import org.apache.http.entity.ByteArrayEntity; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClientBuilder; -import org.apache.http.ssl.SSLContextBuilder; -import org.apache.nifi.security.util.TlsPlatform; -import org.apache.nifi.toolkit.tls.configuration.TlsClientConfig; -import org.apache.nifi.toolkit.tls.service.dto.TlsCertificateAuthorityRequest; -import org.apache.nifi.toolkit.tls.service.dto.TlsCertificateAuthorityResponse; -import org.apache.nifi.toolkit.tls.util.TlsHelper; -import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest; -import org.eclipse.jetty.server.Response; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class TlsCertificateSigningRequestPerformer { - public static final String RECEIVED_RESPONSE_CODE = "Received response code "; - public static final String EXPECTED_ONE_CERTIFICATE = "Expected one certificate"; - public static final String EXPECTED_RESPONSE_TO_CONTAIN_HMAC = "Expected response to contain hmac"; - public static final String UNEXPECTED_HMAC_RECEIVED_POSSIBLE_MAN_IN_THE_MIDDLE = "Unexpected hmac received, possible man in the middle"; - public static final String EXPECTED_RESPONSE_TO_CONTAIN_CERTIFICATE = "Expected response to contain certificate"; - private final Logger logger = LoggerFactory.getLogger(TlsCertificateSigningRequestPerformer.class); - private final Supplier httpClientBuilderSupplier; - private final String caHostname; - private final String dn; - private final List domainAlternativeNames; - private final String token; - private final int port; - private final ObjectMapper objectMapper; - private final String signingAlgorithm; - - public TlsCertificateSigningRequestPerformer(TlsClientConfig tlsClientConfig) { - this(HttpClientBuilder::create, tlsClientConfig.getCaHostname(), tlsClientConfig.getDn(), tlsClientConfig.getDomainAlternativeNames(), - tlsClientConfig.getToken(), tlsClientConfig.getPort(), tlsClientConfig.getSigningAlgorithm()); - } - - protected TlsCertificateSigningRequestPerformer(Supplier httpClientBuilderSupplier, TlsClientConfig tlsClientConfig) { - this(httpClientBuilderSupplier, tlsClientConfig.getCaHostname(), tlsClientConfig.getDn(), tlsClientConfig.getDomainAlternativeNames(), - tlsClientConfig.getToken(), tlsClientConfig.getPort(), tlsClientConfig.getSigningAlgorithm()); - } - - private TlsCertificateSigningRequestPerformer(Supplier httpClientBuilderSupplier, String caHostname, - String dn, List domainAlternativeNames, String token, int port, String signingAlgorithm) { - this.httpClientBuilderSupplier = httpClientBuilderSupplier; - this.caHostname = caHostname; - this.dn = dn; - this.domainAlternativeNames = domainAlternativeNames; - this.token = token; - this.port = port; - this.objectMapper = new ObjectMapper(); - this.signingAlgorithm = signingAlgorithm; - } - - /** - * Submits a CSR to the Certificate authority, checks the resulting hmac, and returns the chain if everything succeeds - * - * @param keyPair the keypair to generate the csr for - * @throws IOException if there is a problem during the process - * @return the resulting certificate chain - */ - public X509Certificate[] perform(KeyPair keyPair) throws IOException { - try { - List certificates = new ArrayList<>(); - - HttpClientBuilder httpClientBuilder = httpClientBuilderSupplier.get(); - SSLContextBuilder sslContextBuilder = SSLContextBuilder.create(); - sslContextBuilder.setProtocol(TlsPlatform.getLatestProtocol()); - - // We will be validating that we are talking to the correct host once we get the response's hmac of the token and public key of the ca - sslContextBuilder.loadTrustMaterial(null, new TrustSelfSignedStrategy()); - httpClientBuilder.setSSLSocketFactory(new TlsCertificateAuthorityClientSocketFactory(sslContextBuilder.build(), caHostname, certificates)); - - String jsonResponseString; - int responseCode; - try (CloseableHttpClient client = httpClientBuilder.build()) { - JcaPKCS10CertificationRequest request = TlsHelper.generateCertificationRequest(dn, domainAlternativeNames, keyPair, signingAlgorithm); - TlsCertificateAuthorityRequest tlsCertificateAuthorityRequest = new TlsCertificateAuthorityRequest(TlsHelper.calculateHMac(token, request.getPublicKey()), - TlsHelper.pemEncodeJcaObject(request)); - - HttpPost httpPost = new HttpPost(); - httpPost.setEntity(new ByteArrayEntity(objectMapper.writeValueAsBytes(tlsCertificateAuthorityRequest))); - - if (logger.isInfoEnabled()) { - logger.info("Requesting certificate with dn " + dn + " from " + caHostname + ":" + port); - } - try (CloseableHttpResponse response = client.execute(new HttpHost(caHostname, port, "https"), httpPost)) { - jsonResponseString = IOUtils.toString(new BoundedInputStream(response.getEntity().getContent(), 1024 * 1024), StandardCharsets.UTF_8); - responseCode = response.getStatusLine().getStatusCode(); - } - } - - if (responseCode != Response.SC_OK) { - throw new IOException(RECEIVED_RESPONSE_CODE + responseCode + " with payload " + jsonResponseString); - } - - if (certificates.size() != 1) { - throw new IOException(EXPECTED_ONE_CERTIFICATE); - } - - TlsCertificateAuthorityResponse tlsCertificateAuthorityResponse = objectMapper.readValue(jsonResponseString, TlsCertificateAuthorityResponse.class); - if (!tlsCertificateAuthorityResponse.hasHmac()) { - throw new IOException(EXPECTED_RESPONSE_TO_CONTAIN_HMAC); - } - - X509Certificate caCertificate = certificates.get(0); - byte[] expectedHmac = TlsHelper.calculateHMac(token, caCertificate.getPublicKey()); - - if (!MessageDigest.isEqual(expectedHmac, tlsCertificateAuthorityResponse.getHmac())) { - throw new IOException(UNEXPECTED_HMAC_RECEIVED_POSSIBLE_MAN_IN_THE_MIDDLE); - } - - if (!tlsCertificateAuthorityResponse.hasCertificate()) { - throw new IOException(EXPECTED_RESPONSE_TO_CONTAIN_CERTIFICATE); - } - X509Certificate x509Certificate = TlsHelper.parseCertificate(new StringReader(tlsCertificateAuthorityResponse.getPemEncodedCertificate())); - x509Certificate.verify(caCertificate.getPublicKey()); - if (logger.isInfoEnabled()) { - logger.info("Got certificate with dn " + x509Certificate.getSubjectX500Principal()); - } - return new X509Certificate[]{x509Certificate, caCertificate}; - } catch (IOException e) { - throw e; - } catch (Exception e) { - throw new IOException(e); - } - } -} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/dto/TlsCertificateAuthorityRequest.java b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/dto/TlsCertificateAuthorityRequest.java deleted file mode 100644 index ca6f0ce023..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/dto/TlsCertificateAuthorityRequest.java +++ /dev/null @@ -1,57 +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.toolkit.tls.service.dto; - -import org.apache.nifi.util.StringUtils; - -public class TlsCertificateAuthorityRequest { - private byte[] hmac; - private String csr; - - public TlsCertificateAuthorityRequest() { - } - - public TlsCertificateAuthorityRequest(byte[] hmac, String csr) { - this.hmac = hmac; - this.csr = csr; - } - - public byte[] getHmac() { - return hmac; - } - - public void setHmac(byte[] hmac) { - this.hmac = hmac; - } - - public boolean hasHmac() { - return hmac != null && hmac.length > 0; - } - - public String getCsr() { - return csr; - } - - public void setCsr(String csr) { - this.csr = csr; - } - - public boolean hasCsr() { - return !StringUtils.isEmpty(csr); - } -} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/dto/TlsCertificateAuthorityResponse.java b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/dto/TlsCertificateAuthorityResponse.java deleted file mode 100644 index 3a7c238249..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/dto/TlsCertificateAuthorityResponse.java +++ /dev/null @@ -1,70 +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.toolkit.tls.service.dto; - -import org.apache.nifi.util.StringUtils; - -public class TlsCertificateAuthorityResponse { - private byte[] hmac; - private String pemEncodedCertificate; - private String error; - - public TlsCertificateAuthorityResponse() { - } - - public TlsCertificateAuthorityResponse(byte[] hmac, String pemEncodedCertificate) { - this.hmac = hmac; - this.pemEncodedCertificate = pemEncodedCertificate; - } - - public TlsCertificateAuthorityResponse(String error) { - this.error = error; - } - - public String getError() { - return error; - } - - public void setError(String error) { - this.error = error; - } - - public byte[] getHmac() { - return hmac; - } - - public void setHmac(byte[] hmac) { - this.hmac = hmac; - } - - public String getPemEncodedCertificate() { - return pemEncodedCertificate; - } - - public void setPemEncodedCertificate(String pemEncodedCertificate) { - this.pemEncodedCertificate = pemEncodedCertificate; - } - - public boolean hasCertificate() { - return !StringUtils.isEmpty(pemEncodedCertificate); - } - - public boolean hasHmac() { - return hmac != null && hmac.length > 0; - } -} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/server/TlsCertificateAuthorityService.java b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/server/TlsCertificateAuthorityService.java deleted file mode 100644 index 921400feb2..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/server/TlsCertificateAuthorityService.java +++ /dev/null @@ -1,129 +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.toolkit.tls.service.server; - -import com.fasterxml.jackson.databind.ObjectMapper; -import org.apache.nifi.security.util.TlsPlatform; -import org.apache.nifi.toolkit.tls.configuration.TlsConfig; -import org.apache.nifi.toolkit.tls.manager.TlsCertificateAuthorityManager; -import org.apache.nifi.toolkit.tls.manager.writer.JsonConfigurationWriter; -import org.apache.nifi.toolkit.tls.service.BaseCertificateAuthorityCommandLine; -import org.apache.nifi.toolkit.tls.util.OutputStreamFactory; -import org.eclipse.jetty.http.HttpVersion; -import org.eclipse.jetty.server.HttpConfiguration; -import org.eclipse.jetty.server.HttpConnectionFactory; -import org.eclipse.jetty.server.SecureRequestCustomizer; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.ServerConnector; -import org.eclipse.jetty.server.SslConnectionFactory; -import org.eclipse.jetty.util.ssl.SslContextFactory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.security.KeyPair; -import java.security.KeyStore; -import java.security.cert.Certificate; -import java.security.cert.X509Certificate; - -/** - * Starts a Jetty server that will either load an existing CA or create one and use it to sign CSRs - */ -public class TlsCertificateAuthorityService { - private final Logger logger = LoggerFactory.getLogger(TlsCertificateAuthorityService.class); - private final OutputStreamFactory outputStreamFactory; - private Server server; - - private ServerConnector serverConnector; - - public TlsCertificateAuthorityService() { - this(FileOutputStream::new); - } - - public TlsCertificateAuthorityService(OutputStreamFactory outputStreamFactory) { - this.outputStreamFactory = outputStreamFactory; - } - - private static ServerConnector createSSLConnector(Server server, int port, KeyStore keyStore, String keyPassword) { - SslContextFactory.Server sslContextFactory = new SslContextFactory.Server(); - sslContextFactory.setIncludeProtocols(TlsPlatform.getLatestProtocol()); - sslContextFactory.setKeyStore(keyStore); - sslContextFactory.setKeyManagerPassword(keyPassword); - - HttpConfiguration httpsConfig = new HttpConfiguration(); - httpsConfig.addCustomizer(new SecureRequestCustomizer()); - - ServerConnector sslConnector = new ServerConnector(server, new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.asString()), new HttpConnectionFactory(httpsConfig)); - sslConnector.setPort(port); - - return sslConnector; - } - - public synchronized void start(TlsConfig tlsConfig, String configJson, boolean differentPasswordsForKeyAndKeystore) throws Exception { - if (server != null) { - throw new IllegalStateException("Server already started"); - } - ObjectMapper objectMapper = new ObjectMapper(); - TlsCertificateAuthorityManager tlsManager; - try { - tlsManager = new TlsCertificateAuthorityManager(tlsConfig); - tlsManager.setDifferentKeyAndKeyStorePassword(differentPasswordsForKeyAndKeystore); - } catch (IOException e) { - logger.error("Unable to open existing keystore, it can be reused by specifiying both " + BaseCertificateAuthorityCommandLine.CONFIG_JSON_ARG + " and " + - BaseCertificateAuthorityCommandLine.USE_CONFIG_JSON_ARG); - throw e; - } - tlsManager.addConfigurationWriter(new JsonConfigurationWriter<>(objectMapper, new File(configJson))); - - KeyStore.PrivateKeyEntry privateKeyEntry = tlsManager.getOrGenerateCertificateAuthority(); - KeyPair keyPair = new KeyPair(privateKeyEntry.getCertificate().getPublicKey(), privateKeyEntry.getPrivateKey()); - Certificate[] certificateChain = privateKeyEntry.getCertificateChain(); - if (certificateChain.length != 1) { - throw new IOException("Expected root ca cert to be only certificate in chain"); - } - Certificate certificate = certificateChain[0]; - X509Certificate caCert; - if (certificate instanceof X509Certificate) { - caCert = (X509Certificate) certificate; - } else { - throw new IOException("Expected " + X509Certificate.class + " as root ca cert"); - } - tlsManager.write(outputStreamFactory); - String signingAlgorithm = tlsConfig.getSigningAlgorithm(); - int days = tlsConfig.getDays(); - server = new Server(); - serverConnector = createSSLConnector(server, tlsConfig.getPort(), tlsManager.getKeyStore(), tlsConfig.getKeyPassword()); - server.addConnector(serverConnector); - server.setHandler(new TlsCertificateAuthorityServiceHandler(signingAlgorithm, days, tlsConfig.getToken(), caCert, keyPair, objectMapper)); - server.start(); - } - - public synchronized void shutdown() throws Exception { - if (server == null) { - throw new IllegalStateException("Server already shutdown"); - } - server.stop(); - server.join(); - } - - public int getPort() { - return serverConnector.getLocalPort(); - } -} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/server/TlsCertificateAuthorityServiceCommandLine.java b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/server/TlsCertificateAuthorityServiceCommandLine.java deleted file mode 100644 index 4031ffd1ec..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/server/TlsCertificateAuthorityServiceCommandLine.java +++ /dev/null @@ -1,111 +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.toolkit.tls.service.server; - -import com.fasterxml.jackson.databind.ObjectMapper; -import org.apache.nifi.toolkit.tls.commandLine.CommandLineParseException; -import org.apache.nifi.toolkit.tls.configuration.TlsConfig; -import org.apache.nifi.toolkit.tls.service.BaseCertificateAuthorityCommandLine; -import org.apache.nifi.toolkit.tls.util.InputStreamFactory; -import org.apache.nifi.util.StringUtils; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; - -/** - * Command line parser for a TlsConfig object and a main entry point to invoke the parser and run the CA server - */ -public class TlsCertificateAuthorityServiceCommandLine extends BaseCertificateAuthorityCommandLine { - public static final String DESCRIPTION = "Acts as a Certificate Authority that can be used by clients to get Certificates"; - public static final String NIFI_CA_KEYSTORE = "nifi-ca-" + KEYSTORE; - - private final InputStreamFactory inputStreamFactory; - - public TlsCertificateAuthorityServiceCommandLine() { - this(FileInputStream::new); - } - - public TlsCertificateAuthorityServiceCommandLine(InputStreamFactory inputStreamFactory) { - super(DESCRIPTION); - this.inputStreamFactory = inputStreamFactory; - } - - public static void main(String[] args) throws Exception { - TlsCertificateAuthorityServiceCommandLine tlsCertificateAuthorityServiceCommandLine = new TlsCertificateAuthorityServiceCommandLine(); - try { - tlsCertificateAuthorityServiceCommandLine.parse(args); - } catch (CommandLineParseException e) { - System.exit(e.getExitCode().ordinal()); - } - TlsCertificateAuthorityService tlsCertificateAuthorityService = new TlsCertificateAuthorityService(); - tlsCertificateAuthorityService.start(tlsCertificateAuthorityServiceCommandLine.createConfig(), tlsCertificateAuthorityServiceCommandLine.getConfigJsonOut(), - tlsCertificateAuthorityServiceCommandLine.differentPasswordForKeyAndKeystore()); - System.out.println("Server Started"); - System.out.flush(); - } - - public TlsConfig createConfig() throws IOException { - String configJsonIn = getConfigJsonIn(); - if (!StringUtils.isEmpty(configJsonIn)) { - try (InputStream inputStream = inputStreamFactory.create(new File(configJsonIn))) { - TlsConfig tlsConfig = new ObjectMapper().readValue(inputStream, TlsConfig.class); - tlsConfig.initDefaults(); - return tlsConfig; - } - } else { - TlsConfig tlsConfig = new TlsConfig(); - tlsConfig.setCaHostname(getCertificateAuthorityHostname()); - tlsConfig.setDn(getDn()); - tlsConfig.setToken(getToken()); - tlsConfig.setPort(getPort()); - tlsConfig.setKeyStore(NIFI_CA_KEYSTORE + getKeyStoreType().toLowerCase()); - tlsConfig.setKeyStoreType(getKeyStoreType()); - tlsConfig.setKeySize(getKeySize()); - tlsConfig.setKeyPairAlgorithm(getKeyAlgorithm()); - tlsConfig.setSigningAlgorithm(getSigningAlgorithm()); - tlsConfig.setDays(getDays()); - return tlsConfig; - } - } - - @Override - protected String getTokenDescription() { - return "The token to use to prevent MITM (required and must be same as one used by clients)"; - } - - @Override - protected String getDnDescription() { - return "The dn to use for the CA certificate"; - } - - @Override - protected String getPortDescription() { - return "The port for the Certificate Authority to listen on"; - } - - @Override - protected String getDnHostname() { - String dnHostname = getCertificateAuthorityHostname(); - if (StringUtils.isEmpty(dnHostname)) { - return "YOUR_CA_HOSTNAME"; - } - return dnHostname; - } -} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/server/TlsCertificateAuthorityServiceHandler.java b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/server/TlsCertificateAuthorityServiceHandler.java deleted file mode 100644 index 9d54246949..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/server/TlsCertificateAuthorityServiceHandler.java +++ /dev/null @@ -1,149 +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.toolkit.tls.service.server; - -import com.fasterxml.jackson.databind.ObjectMapper; -import org.apache.commons.io.input.BoundedReader; -import org.apache.nifi.security.cert.builder.StandardCertificateBuilder; -import org.apache.nifi.toolkit.tls.service.dto.TlsCertificateAuthorityRequest; -import org.apache.nifi.toolkit.tls.service.dto.TlsCertificateAuthorityResponse; -import org.apache.nifi.toolkit.tls.util.TlsHelper; -import org.bouncycastle.asn1.ASN1Encodable; -import org.bouncycastle.asn1.x500.style.IETFUtils; -import org.bouncycastle.asn1.x509.Extension; -import org.bouncycastle.asn1.x509.Extensions; -import org.bouncycastle.asn1.x509.GeneralName; -import org.bouncycastle.asn1.x509.GeneralNames; -import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest; -import org.eclipse.jetty.server.Request; -import org.eclipse.jetty.server.Response; -import org.eclipse.jetty.server.handler.AbstractHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.security.auth.x500.X500Principal; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.security.KeyPair; -import java.security.MessageDigest; -import java.security.cert.X509Certificate; -import java.time.Duration; -import java.util.ArrayList; -import java.util.List; - -/** - * Jetty service handler that validates the hmac of a CSR and issues a certificate if it checks out - */ -public class TlsCertificateAuthorityServiceHandler extends AbstractHandler { - public static final String CSR_FIELD_MUST_BE_SET = "csr field must be set"; - public static final String HMAC_FIELD_MUST_BE_SET = "hmac field must be set"; - public static final String FORBIDDEN = "forbidden"; - private final Logger logger = LoggerFactory.getLogger(TlsCertificateAuthorityServiceHandler.class); - private final String signingAlgorithm; - private final int days; - private final String token; - private final X509Certificate caCert; - private final KeyPair keyPair; - private final ObjectMapper objectMapper; - - public TlsCertificateAuthorityServiceHandler(String signingAlgorithm, int days, String token, X509Certificate caCert, KeyPair keyPair, ObjectMapper objectMapper) { - this.signingAlgorithm = signingAlgorithm; - this.days = days; - this.token = token; - this.caCert = caCert; - this.keyPair = keyPair; - this.objectMapper = objectMapper; - } - - @Override - public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws ServletException { - try { - TlsCertificateAuthorityRequest tlsCertificateAuthorityRequest = objectMapper.readValue(new BoundedReader(request.getReader(), 1024 * 1024), TlsCertificateAuthorityRequest.class); - - if (!tlsCertificateAuthorityRequest.hasHmac()) { - writeResponse(objectMapper, request, response, new TlsCertificateAuthorityResponse(HMAC_FIELD_MUST_BE_SET), Response.SC_BAD_REQUEST); - return; - } - - if (!tlsCertificateAuthorityRequest.hasCsr()) { - writeResponse(objectMapper, request, response, new TlsCertificateAuthorityResponse(CSR_FIELD_MUST_BE_SET), Response.SC_BAD_REQUEST); - return; - } - - JcaPKCS10CertificationRequest jcaPKCS10CertificationRequest = TlsHelper.parseCsr(tlsCertificateAuthorityRequest.getCsr()); - byte[] expectedHmac = TlsHelper.calculateHMac(token, jcaPKCS10CertificationRequest.getPublicKey()); - - if (MessageDigest.isEqual(expectedHmac, tlsCertificateAuthorityRequest.getHmac())) { - String dn = jcaPKCS10CertificationRequest.getSubject().toString(); - if (logger.isInfoEnabled()) { - logger.info("Received CSR with DN " + dn); - } - - final List dnsNames = getDnsNames(jcaPKCS10CertificationRequest); - X509Certificate x509Certificate = new StandardCertificateBuilder(keyPair, caCert.getSubjectX500Principal(), Duration.ofDays(days)) - .setSubject(new X500Principal(dn)) - .setSubjectPublicKey(jcaPKCS10CertificationRequest.getPublicKey()) - .setDnsSubjectAlternativeNames(dnsNames) - .build(); - - writeResponse(objectMapper, request, response, new TlsCertificateAuthorityResponse(TlsHelper.calculateHMac(token, caCert.getPublicKey()), - TlsHelper.pemEncodeJcaObject(x509Certificate)), Response.SC_OK); - } else { - writeResponse(objectMapper, request, response, new TlsCertificateAuthorityResponse(FORBIDDEN), Response.SC_FORBIDDEN); - } - } catch (Exception e) { - throw new ServletException("Server error"); - } finally { - baseRequest.setHandled(true); - } - } - - private void writeResponse(ObjectMapper objectMapper, HttpServletRequest request, HttpServletResponse response, TlsCertificateAuthorityResponse tlsCertificateAuthorityResponse, - int responseCode) throws IOException { - if (logger.isInfoEnabled()) { - logger.info(new StringBuilder("Returning code:").append(responseCode).append(" payload ").append(objectMapper.writeValueAsString(tlsCertificateAuthorityResponse)) - .append(" to ").append(request.getRemoteHost()).toString()); - } - if (responseCode == Response.SC_OK) { - objectMapper.writeValue(response.getWriter(), tlsCertificateAuthorityResponse); - response.setStatus(responseCode); - } else { - response.setStatus(responseCode); - response.setContentType("application/json"); - response.setCharacterEncoding(StandardCharsets.UTF_8.name()); - objectMapper.writeValue(response.getWriter(), tlsCertificateAuthorityResponse); - } - } - - private List getDnsNames(final JcaPKCS10CertificationRequest request) { - final Extensions extensions = request.getRequestedExtensions(); - final GeneralNames generalNames = GeneralNames.fromExtensions(extensions, Extension.subjectAlternativeName); - - final List dnsNames = new ArrayList<>(); - for (final GeneralName generalName : generalNames.getNames()) { - final ASN1Encodable nameEncoded = generalName.getName(); - final String name = IETFUtils.valueToString(nameEncoded); - dnsNames.add(name); - } - - return dnsNames; - } -} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/standalone/TlsToolkitStandalone.java b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/standalone/TlsToolkitStandalone.java deleted file mode 100644 index 799edf1f0c..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/standalone/TlsToolkitStandalone.java +++ /dev/null @@ -1,339 +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.toolkit.tls.standalone; - -import org.apache.nifi.security.cert.builder.StandardCertificateBuilder; -import org.apache.nifi.security.util.KeyStoreUtils; -import org.apache.nifi.security.util.KeystoreType; -import org.apache.nifi.toolkit.tls.configuration.InstanceDefinition; -import org.apache.nifi.toolkit.tls.configuration.StandaloneConfig; -import org.apache.nifi.toolkit.tls.configuration.TlsClientConfig; -import org.apache.nifi.toolkit.tls.manager.TlsCertificateAuthorityManager; -import org.apache.nifi.toolkit.tls.manager.TlsClientManager; -import org.apache.nifi.toolkit.tls.manager.writer.NifiPropertiesTlsClientConfigWriter; -import org.apache.nifi.toolkit.tls.properties.NiFiPropertiesWriterFactory; -import org.apache.nifi.toolkit.tls.util.OutputStreamFactory; -import org.apache.nifi.toolkit.tls.util.TlsHelper; -import org.apache.nifi.util.StringUtils; -import org.bouncycastle.openssl.jcajce.JcaMiscPEMGenerator; -import org.bouncycastle.util.io.pem.PemWriter; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.security.auth.x500.X500Principal; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; -import java.io.OutputStreamWriter; -import java.security.GeneralSecurityException; -import java.security.Key; -import java.security.KeyPair; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.PrivateKey; -import java.security.SignatureException; -import java.security.UnrecoverableKeyException; -import java.security.cert.Certificate; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; -import java.time.Duration; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.IntStream; - -public class TlsToolkitStandalone { - public static final String NIFI_KEY = "nifi-key"; - public static final String NIFI_CERT = "nifi-cert"; - public static final String NIFI_PROPERTIES = "nifi.properties"; - - private final Logger logger = LoggerFactory.getLogger(TlsToolkitStandalone.class); - private final OutputStreamFactory outputStreamFactory; - - public TlsToolkitStandalone() { - this(FileOutputStream::new); - } - - public TlsToolkitStandalone(OutputStreamFactory outputStreamFactory) { - this.outputStreamFactory = outputStreamFactory; - } - - public void splitKeystore(StandaloneConfig standaloneConfig) throws IOException, KeyStoreException, CertificateException, NoSuchAlgorithmException, UnrecoverableKeyException { - KeyStore keyStore = KeyStore.getInstance("JKS"); - keyStore.load(new FileInputStream(standaloneConfig.getKeyStore()), standaloneConfig.getKeyStorePassword().toCharArray()); - - if(keyStore.size() == 0) { - throw new KeyStoreException("Provided keystore " + standaloneConfig.getKeyStore() + " was empty. No cert/key pairs to output to file."); - } - - if(standaloneConfig.getKeyPassword() == null || standaloneConfig.getKeyPassword().isEmpty()) { - splitKeystore(keyStore, standaloneConfig.getKeyStorePassword().toCharArray(), standaloneConfig.getBaseDir()); - } else { - splitKeystore(keyStore, standaloneConfig.getKeyPassword().toCharArray(), standaloneConfig.getBaseDir()); - } - } - - private void splitKeystore(KeyStore keyStore, char[] keyPassphrase, File outputDirectory) throws KeyStoreException, UnrecoverableKeyException, NoSuchAlgorithmException { - HashMap certificates = TlsHelper.extractCerts(keyStore); - HashMap keys = TlsHelper.extractKeys(keyStore, keyPassphrase); - TlsHelper.outputCertsAsPem(certificates, outputDirectory, ".crt"); - TlsHelper.outputKeysAsPem(keys, outputDirectory, ".key"); - } - - public void createNifiKeystoresAndTrustStores(StandaloneConfig standaloneConfig) throws GeneralSecurityException, IOException { - // TODO: This 200 line method should be refactored, as it is difficult to test the various validations separately from the filesystem interaction and generation logic - File baseDir = standaloneConfig.getBaseDir(); - if (!baseDir.exists() && !baseDir.mkdirs()) { - throw new IOException(baseDir + " doesn't exist and unable to create it."); - } - - if (!baseDir.isDirectory()) { - throw new IOException("Expected directory to output to"); - } - - int days = standaloneConfig.getDays(); - String keyPairAlgorithm = standaloneConfig.getKeyPairAlgorithm(); - int keySize = standaloneConfig.getKeySize(); - - File nifiCert = new File(baseDir, NIFI_CERT + ".pem"); - File nifiKey = new File(baseDir, NIFI_KEY + ".key"); - - X509Certificate certificate; - KeyPair caKeyPair; - - if (logger.isInfoEnabled()) { - logger.info("Running standalone certificate generation with output directory " + baseDir); - } - if (nifiCert.exists()) { - if (!nifiKey.exists()) { - throw new IOException(nifiCert + " exists already, but " + nifiKey + " does not, we need both certificate and key to continue with an existing CA."); - } - try (FileReader pemEncodedCertificate = new FileReader(nifiCert)) { - certificate = TlsHelper.parseCertificate(pemEncodedCertificate); - } - try (FileReader pemEncodedKeyPair = new FileReader(nifiKey)) { - caKeyPair = TlsHelper.parseKeyPairFromReader(pemEncodedKeyPair); - } - - // TODO: Do same in client/server - // Load additional signing certificates from config - List signingCertificates = new ArrayList<>(); - - // Read the provided additional CA certificate if it exists and extract the certificate - if (!StringUtils.isBlank(standaloneConfig.getAdditionalCACertificate())) { - X509Certificate signingCertificate; - final File additionalCACertFile = new File(standaloneConfig.getAdditionalCACertificate()); - if (!additionalCACertFile.exists()) { - throw new IOException("The additional CA certificate does not exist at " + additionalCACertFile.getAbsolutePath()); - } - try (FileReader pemEncodedCACertificate = new FileReader(additionalCACertFile)) { - signingCertificate = TlsHelper.parseCertificate(pemEncodedCACertificate); - } - signingCertificates.add(signingCertificate); - } - - // Support self-signed CA certificates - signingCertificates.add(certificate); - - boolean signatureValid = TlsHelper.verifyCertificateSignature(certificate, signingCertificates); - - if (!signatureValid) { - throw new SignatureException("The signing certificate was not signed by any known certificates"); - } - - if (!caKeyPair.getPublic().equals(certificate.getPublicKey())) { - throw new IOException("Expected " + nifiKey + " to correspond to CA certificate at " + nifiCert); - } - - if (logger.isInfoEnabled()) { - logger.info("Using existing CA certificate " + nifiCert + " and key " + nifiKey); - } - } else if (nifiKey.exists()) { - throw new IOException(nifiKey + " exists already, but " + nifiCert + " does not, we need both certificate and key to continue with an existing CA."); - } else { - TlsCertificateAuthorityManager tlsCertificateAuthorityManager = new TlsCertificateAuthorityManager(standaloneConfig); - KeyStore.PrivateKeyEntry privateKeyEntry = tlsCertificateAuthorityManager.getOrGenerateCertificateAuthority(); - certificate = (X509Certificate) privateKeyEntry.getCertificateChain()[0]; - caKeyPair = new KeyPair(certificate.getPublicKey(), privateKeyEntry.getPrivateKey()); - - try (PemWriter pemWriter = new PemWriter(new OutputStreamWriter(outputStreamFactory.create(nifiCert)))) { - pemWriter.writeObject(new JcaMiscPEMGenerator(certificate)); - } - - try (PemWriter pemWriter = new PemWriter(new OutputStreamWriter(outputStreamFactory.create(nifiKey)))) { - pemWriter.writeObject(new JcaMiscPEMGenerator(caKeyPair)); - } - - if (logger.isInfoEnabled()) { - logger.info("Generated new CA certificate " + nifiCert + " and key " + nifiKey); - } - } - - NiFiPropertiesWriterFactory niFiPropertiesWriterFactory = standaloneConfig.getNiFiPropertiesWriterFactory(); - boolean overwrite = standaloneConfig.isOverwrite(); - - List instanceDefinitions = standaloneConfig.getInstanceDefinitions(); - if (instanceDefinitions.isEmpty() && logger.isInfoEnabled()) { - logger.info("No " + TlsToolkitStandaloneCommandLine.HOSTNAMES_ARG + " specified, not generating any host certificates or configuration."); - } - - List domainAlternativeNames = standaloneConfig.getDomainAlternativeNames(); - - for (Integer instanceIndex : IntStream.range(0, instanceDefinitions.size()).boxed().collect(Collectors.toList())) { - InstanceDefinition instanceDefinition = instanceDefinitions.get(instanceIndex); - String hostname = instanceDefinition.getHostname(); - File hostDir; - int hostIdentifierNumber = instanceDefinition.getInstanceIdentifier().getNumber(); - if (hostIdentifierNumber == 1) { - hostDir = new File(baseDir, hostname); - } else { - hostDir = new File(baseDir, hostname + "_" + hostIdentifierNumber); - } - - TlsClientConfig tlsClientConfig = new TlsClientConfig(standaloneConfig); - File keystore = new File(hostDir, "keystore." + tlsClientConfig.getKeyStoreType().toLowerCase()); - File truststore = new File(hostDir, "truststore." + tlsClientConfig.getTrustStoreType().toLowerCase()); - - // Adjust the SANs when ranges match. - if (domainAlternativeNames.size() == 1) { - tlsClientConfig.setDomainAlternativeNames(Collections.singletonList(domainAlternativeNames.get(0))); - } else if (domainAlternativeNames.size() == instanceDefinitions.size()) { - tlsClientConfig.setDomainAlternativeNames(Collections.singletonList(domainAlternativeNames.get(instanceIndex))); - logger.info("Using alternate name " + domainAlternativeNames.get(instanceIndex) + " with hostname " + hostname + "."); - } else if (domainAlternativeNames.size() > 0) { - logger.warn("Hostname count does not match given alternate name count. Verify names in resulting certificate."); - } - - if (hostDir.exists()) { - if (!hostDir.isDirectory()) { - throw new IOException(hostDir + " exists but is not a directory."); - } else if (overwrite) { - if (logger.isInfoEnabled()) { - logger.info("Overwriting any existing ssl configuration in " + hostDir); - } - keystore.delete(); - if (keystore.exists()) { - throw new IOException("Keystore " + keystore + " already exists and couldn't be deleted."); - } - truststore.delete(); - if (truststore.exists()) { - throw new IOException("Truststore " + truststore + " already exists and couldn't be deleted."); - } - } else { - throw new IOException(hostDir + " exists and overwrite is not set."); - } - } else if (!hostDir.mkdirs()) { - throw new IOException("Unable to make directory: " + hostDir.getAbsolutePath()); - } else if (logger.isInfoEnabled()) { - logger.info("Writing new ssl configuration to " + hostDir); - } - - tlsClientConfig.setKeyStore(keystore.getAbsolutePath()); - tlsClientConfig.setKeyStorePassword(instanceDefinition.getKeyStorePassword()); - tlsClientConfig.setKeyPassword(instanceDefinition.getKeyPassword()); - tlsClientConfig.setTrustStore(truststore.getAbsolutePath()); - tlsClientConfig.setTrustStorePassword(instanceDefinition.getTrustStorePassword()); - TlsClientManager tlsClientManager = new TlsClientManager(tlsClientConfig); - KeyPair keyPair = TlsHelper.generateKeyPair(keyPairAlgorithm, keySize); - - final List dnsNames = new ArrayList<>(tlsClientConfig.getDomainAlternativeNames()); - final String defaultDn = tlsClientConfig.calcDefaultDn(hostname); - dnsNames.add(hostname); - - final X509Certificate clientCertificate = new StandardCertificateBuilder(caKeyPair, certificate.getSubjectX500Principal(), Duration.ofDays(days)) - .setSubject(new X500Principal(defaultDn)) - .setSubjectPublicKey(keyPair.getPublic()) - .setDnsSubjectAlternativeNames(dnsNames) - .build(); - - tlsClientManager.addPrivateKeyToKeyStore(keyPair, NIFI_KEY, clientCertificate, certificate); - tlsClientManager.setCertificateEntry(NIFI_CERT, certificate); - tlsClientManager.addClientConfigurationWriter(new NifiPropertiesTlsClientConfigWriter(niFiPropertiesWriterFactory, new File(hostDir, "nifi.properties"), - hostname, instanceDefinition.getNumber())); - tlsClientManager.write(outputStreamFactory); - - if (logger.isInfoEnabled()) { - logger.info("Successfully generated TLS configuration for " + hostname + " " + hostIdentifierNumber + " in " + hostDir); - } - } - - List clientDns = standaloneConfig.getClientDns(); - if (standaloneConfig.getClientDns().isEmpty() && logger.isInfoEnabled()) { - logger.info("No " + TlsToolkitStandaloneCommandLine.CLIENT_CERT_DN_ARG + " specified, not generating any client certificates."); - } - - List clientPasswords = standaloneConfig.getClientPasswords(); - for (int i = 0; i < clientDns.size(); i++) { - String clientDn = clientDns.get(i); - String clientDnFile = TlsHelper.escapeFilename(clientDn); - File clientCertFile = new File(baseDir, clientDnFile + ".p12"); - - if (clientCertFile.exists()) { - if (overwrite) { - if (logger.isInfoEnabled()) { - logger.info("Overwriting existing client cert " + clientCertFile); - } - } else { - throw new IOException(clientCertFile + " exists and overwrite is not set."); - } - } else if (logger.isInfoEnabled()) { - logger.info("Generating new client certificate " + clientCertFile); - } - KeyPair keyPair = TlsHelper.generateKeyPair(keyPairAlgorithm, keySize); - X509Certificate clientCert = new StandardCertificateBuilder(caKeyPair, certificate.getIssuerX500Principal(), Duration.ofDays(days)) - .setSubject(new X500Principal(clientDn)) - .setSubjectPublicKey(keyPair.getPublic()) - .build(); - final String keyStorePassword = clientPasswords.get(i); - final KeyStore keyStore = setClientKeyStore(keyStorePassword, keyPair.getPrivate(), clientCert, certificate); - String password = TlsHelper.writeKeyStore(keyStore, outputStreamFactory, clientCertFile, keyStorePassword, standaloneConfig.isClientPasswordsGenerated()); - - try (FileWriter fileWriter = new FileWriter(new File(baseDir, clientDnFile + ".password"))) { - fileWriter.write(password); - } - - if (logger.isInfoEnabled()) { - logger.info("Successfully generated client certificate " + clientCertFile); - } - } - - if (logger.isInfoEnabled()) { - logger.info("tls-toolkit standalone completed successfully"); - } - } - - protected KeyStore setClientKeyStore( - final String keyStorePassword, - final PrivateKey privateKey, - final X509Certificate clientCertificate, - final X509Certificate issuerCertificate - ) throws IOException, GeneralSecurityException { - final KeyStore keyStore = KeyStoreUtils.getKeyStore(KeystoreType.PKCS12.toString()); - keyStore.load(null, null); - final char[] keyPassword = keyStorePassword.toCharArray(); - final X509Certificate[] certificates = {clientCertificate, issuerCertificate}; - keyStore.setKeyEntry(NIFI_KEY, privateKey, keyPassword, certificates); - return keyStore; - } -} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/standalone/TlsToolkitStandaloneCommandLine.java b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/standalone/TlsToolkitStandaloneCommandLine.java deleted file mode 100644 index 9919528ff8..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/standalone/TlsToolkitStandaloneCommandLine.java +++ /dev/null @@ -1,301 +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.toolkit.tls.standalone; - -import org.apache.commons.cli.CommandLine; -import org.apache.nifi.toolkit.tls.commandLine.BaseTlsToolkitCommandLine; -import org.apache.nifi.toolkit.tls.commandLine.CommandLineParseException; -import org.apache.nifi.toolkit.tls.commandLine.ExitCode; -import org.apache.nifi.toolkit.tls.configuration.InstanceDefinition; -import org.apache.nifi.toolkit.tls.configuration.StandaloneConfig; -import org.apache.nifi.toolkit.tls.configuration.TlsConfig; -import org.apache.nifi.toolkit.tls.properties.NiFiPropertiesWriterFactory; -import org.apache.nifi.toolkit.tls.util.PasswordUtil; -import org.apache.nifi.util.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.function.Supplier; -import java.util.stream.Collectors; -import java.util.stream.IntStream; -import java.util.stream.Stream; - -/** - * Command line parser for a StandaloneConfig object and a main entry point to invoke the parser and run the standalone generator - */ -public class TlsToolkitStandaloneCommandLine extends BaseTlsToolkitCommandLine { - public static final String OUTPUT_DIRECTORY_ARG = "outputDirectory"; - public static final String NIFI_PROPERTIES_FILE_ARG = "nifiPropertiesFile"; - public static final String KEY_STORE_PASSWORD_ARG = "keyStorePassword"; - public static final String TRUST_STORE_PASSWORD_ARG = "trustStorePassword"; - public static final String KEY_PASSWORD_ARG = "keyPassword"; - public static final String HOSTNAMES_ARG = "hostnames"; - public static final String OVERWRITE_ARG = "isOverwrite"; - public static final String CLIENT_CERT_DN_ARG = "clientCertDn"; - public static final String CLIENT_CERT_PASSWORD_ARG = "clientCertPassword"; - public static final String GLOBAL_PORT_SEQUENCE_ARG = "globalPortSequence"; - public static final String NIFI_DN_PREFIX_ARG = "nifiDnPrefix"; - public static final String NIFI_DN_SUFFIX_ARG = "nifiDnSuffix"; - public static final String SUBJECT_ALTERNATIVE_NAMES_ARG = "subjectAlternativeNames"; - public static final String ADDITIONAL_CA_CERTIFICATE_ARG = "additionalCACertificate"; - public static final String SPLIT_KEYSTORE_ARG = "splitKeystore"; - - public static final String DEFAULT_OUTPUT_DIRECTORY = calculateDefaultOutputDirectory(Paths.get(".")); - - protected static String calculateDefaultOutputDirectory(Path currentPath) { - Path currentAbsolutePath = currentPath.toAbsolutePath(); - Path parent = currentAbsolutePath.getParent(); - if (currentAbsolutePath.getRoot().equals(parent)) { - return parent.toString(); - } else { - Path currentNormalizedPath = currentAbsolutePath.normalize(); - return "../" + currentNormalizedPath.getFileName().toString(); - } - } - - public static final String DESCRIPTION = "Creates certificates and config files for nifi cluster."; - - private final Logger logger = LoggerFactory.getLogger(TlsToolkitStandaloneCommandLine.class); - - private final PasswordUtil passwordUtil; - private File baseDir; - private List instanceDefinitions; - private NiFiPropertiesWriterFactory niFiPropertiesWriterFactory; - private List clientDns; - private List clientPasswords; - private boolean clientPasswordsGenerated; - private boolean overwrite; - private boolean splitKeystore = false; - private String splitKeystoreFile; - private String dnPrefix; - private String dnSuffix; - private List domainAlternativeNames; - private String additionalCACertificatePath; - private String keyPassword; - private String keyStorePassword; - - public TlsToolkitStandaloneCommandLine() { - this(new PasswordUtil()); - } - - protected TlsToolkitStandaloneCommandLine(PasswordUtil passwordUtil) { - super(DESCRIPTION); - this.passwordUtil = passwordUtil; - addOptionWithArg("o", OUTPUT_DIRECTORY_ARG, "The directory to output keystores, truststore, config files.", DEFAULT_OUTPUT_DIRECTORY); - addOptionWithArg("n", HOSTNAMES_ARG, "Comma separated list of hostnames."); - addOptionWithArg("f", NIFI_PROPERTIES_FILE_ARG, "Base nifi.properties file to update. (Embedded file identical to the one in a default NiFi install will be used if not specified.)"); - addOptionWithArg("S", KEY_STORE_PASSWORD_ARG, "Keystore password to use. Must either be one value or one for each host. (autogenerate if not specified)"); - addOptionWithArg("K", KEY_PASSWORD_ARG, "Key password to use. Must either be one value or one for each host. (autogenerate if not specified)"); - addOptionWithArg("P", TRUST_STORE_PASSWORD_ARG, "Keystore password to use. Must either be one value or one for each host. (autogenerate if not specified)"); - addOptionWithArg("C", CLIENT_CERT_DN_ARG, "Generate client certificate suitable for use in browser with specified DN. (Can be specified multiple times.)"); - addOptionWithArg("B", CLIENT_CERT_PASSWORD_ARG, "Password for client certificate. Must either be one value or one for each client DN. (autogenerate if not specified)"); - addOptionWithArg("G", GLOBAL_PORT_SEQUENCE_ARG, "Use sequential ports that are calculated for all hosts according to the provided hostname expressions. " + - "(Can be specified multiple times, MUST BE SAME FROM RUN TO RUN.)"); - addOptionWithArg(null, SUBJECT_ALTERNATIVE_NAMES_ARG, "Comma-separated list of domains to use as Subject Alternative Names in the certificate"); - addOptionWithArg(null, NIFI_DN_PREFIX_ARG, "String to prepend to hostname(s) when determining DN.", TlsConfig.DEFAULT_DN_PREFIX); - addOptionWithArg(null, NIFI_DN_SUFFIX_ARG, "String to append to hostname(s) when determining DN.", TlsConfig.DEFAULT_DN_SUFFIX); - addOptionNoArg("O", OVERWRITE_ARG, "Overwrite existing host output."); - addOptionWithArg(null, ADDITIONAL_CA_CERTIFICATE_ARG, "Path to additional CA certificate (used to sign toolkit CA certificate) in PEM format if necessary"); - addOptionWithArg(null, SPLIT_KEYSTORE_ARG, "Split out a given keystore into its unencrypted key and certificates. Use -S and -K to specify the keystore and key passwords."); - - } - - public static void main(String[] args) { - TlsToolkitStandaloneCommandLine tlsToolkitStandaloneCommandLine = new TlsToolkitStandaloneCommandLine(); - try { - tlsToolkitStandaloneCommandLine.parse(args); - } catch (CommandLineParseException e) { - System.exit(e.getExitCode().ordinal()); - } catch (IllegalArgumentException e) { - tlsToolkitStandaloneCommandLine.printUsage("Error parsing command line. (" + e.getMessage() + ")"); - System.exit(ExitCode.ERROR_PARSING_INT_ARG.ordinal()); - } - - if(tlsToolkitStandaloneCommandLine.splitKeystore) { - StandaloneConfig conf = tlsToolkitStandaloneCommandLine.createSplitKeystoreConfig(); - try { - new TlsToolkitStandalone().splitKeystore(conf); - } catch (Exception e) { - tlsToolkitStandaloneCommandLine.printUsage("Error splitting keystore. (" + e.getMessage() + ")"); - System.exit(ExitCode.ERROR_GENERATING_CONFIG.ordinal()); - } - } else { - try { - new TlsToolkitStandalone().createNifiKeystoresAndTrustStores(tlsToolkitStandaloneCommandLine.createConfig()); - } catch (Exception e) { - tlsToolkitStandaloneCommandLine.printUsage("Error generating TLS configuration. (" + e.getMessage() + ")"); - System.exit(ExitCode.ERROR_GENERATING_CONFIG.ordinal()); - } - } - - System.exit(ExitCode.SUCCESS.ordinal()); - } - - @Override - protected CommandLine doParse(String... args) throws CommandLineParseException { - CommandLine commandLine = super.doParse(args); - String outputDirectory = commandLine.getOptionValue(OUTPUT_DIRECTORY_ARG, DEFAULT_OUTPUT_DIRECTORY); - baseDir = new File(outputDirectory); - - dnPrefix = commandLine.getOptionValue(NIFI_DN_PREFIX_ARG, TlsConfig.DEFAULT_DN_PREFIX); - dnSuffix = commandLine.getOptionValue(NIFI_DN_SUFFIX_ARG, TlsConfig.DEFAULT_DN_SUFFIX); - - Stream globalOrderExpressions = null; - if (commandLine.hasOption(GLOBAL_PORT_SEQUENCE_ARG)) { - globalOrderExpressions = Arrays.stream(commandLine.getOptionValues(GLOBAL_PORT_SEQUENCE_ARG)).flatMap(s -> Arrays.stream(s.split(","))).map(String::trim); - } - - if (commandLine.hasOption(HOSTNAMES_ARG)) { - instanceDefinitions = Collections.unmodifiableList( - InstanceDefinition.createDefinitions(globalOrderExpressions, - Arrays.stream(commandLine.getOptionValues(HOSTNAMES_ARG)).flatMap(s -> Arrays.stream(s.split(",")).map(String::trim)), - parsePasswordSupplier(commandLine, KEY_STORE_PASSWORD_ARG, passwordUtil.passwordSupplier()), - parsePasswordSupplier(commandLine, KEY_PASSWORD_ARG, commandLine.hasOption(DIFFERENT_KEY_AND_KEYSTORE_PASSWORDS_ARG) ? passwordUtil.passwordSupplier() : null), - parsePasswordSupplier(commandLine, TRUST_STORE_PASSWORD_ARG, passwordUtil.passwordSupplier()))); - } else { - instanceDefinitions = Collections.emptyList(); - } - - if (commandLine.hasOption(SUBJECT_ALTERNATIVE_NAMES_ARG)) { - domainAlternativeNames = Collections.unmodifiableList( - InstanceDefinition.createDefinitions(globalOrderExpressions, - Arrays.stream(commandLine.getOptionValues(SUBJECT_ALTERNATIVE_NAMES_ARG)).flatMap(s -> Arrays.stream(s.split(",")).map(String::trim)), - parsePasswordSupplier(commandLine, KEY_STORE_PASSWORD_ARG, passwordUtil.passwordSupplier()), - parsePasswordSupplier(commandLine, KEY_PASSWORD_ARG, commandLine.hasOption(DIFFERENT_KEY_AND_KEYSTORE_PASSWORDS_ARG) ? passwordUtil.passwordSupplier() : null), - parsePasswordSupplier(commandLine, TRUST_STORE_PASSWORD_ARG, passwordUtil.passwordSupplier()))); - } else { - domainAlternativeNames = Collections.emptyList(); - } - - String[] clientDnValues = commandLine.getOptionValues(CLIENT_CERT_DN_ARG); - if (clientDnValues != null) { - clientDns = Collections.unmodifiableList(Arrays.stream(clientDnValues).collect(Collectors.toList())); - } else { - clientDns = Collections.emptyList(); - } - - clientPasswords = Collections.unmodifiableList(getPasswords(CLIENT_CERT_PASSWORD_ARG, commandLine, clientDns.size(), CLIENT_CERT_DN_ARG)); - clientPasswordsGenerated = commandLine.getOptionValues(CLIENT_CERT_PASSWORD_ARG) == null; - overwrite = commandLine.hasOption(OVERWRITE_ARG); - - if(commandLine.hasOption(SPLIT_KEYSTORE_ARG)) { - if(commandLine.hasOption(KEY_STORE_PASSWORD_ARG)) { - splitKeystoreFile = commandLine.getOptionValue(SPLIT_KEYSTORE_ARG); - keyStorePassword = commandLine.getOptionValue(KEY_STORE_PASSWORD_ARG); - keyPassword = commandLine.getOptionValue(KEY_PASSWORD_ARG); - splitKeystore = true; - } else { - printUsageAndThrow("-splitKeystore specified but no keyStorePassword supplied.", ExitCode.ERROR_INCORRECT_NUMBER_OF_PASSWORDS); - } - } - - additionalCACertificatePath = commandLine.getOptionValue(ADDITIONAL_CA_CERTIFICATE_ARG); - - String nifiPropertiesFile = commandLine.getOptionValue(NIFI_PROPERTIES_FILE_ARG, ""); - try { - if (StringUtils.isEmpty(nifiPropertiesFile)) { - logger.info("No " + NIFI_PROPERTIES_FILE_ARG + " specified, using embedded one."); - niFiPropertiesWriterFactory = new NiFiPropertiesWriterFactory(); - } else { - logger.info("Using " + nifiPropertiesFile + " as template."); - niFiPropertiesWriterFactory = new NiFiPropertiesWriterFactory(new FileInputStream(nifiPropertiesFile)); - } - } catch (IOException e) { - printUsageAndThrow("Unable to read nifi.properties from " + (StringUtils.isEmpty(nifiPropertiesFile) ? "classpath" : nifiPropertiesFile), ExitCode.ERROR_READING_NIFI_PROPERTIES); - } - return commandLine; - } - - private List getPasswords(String arg, CommandLine commandLine, int num, String numArg) throws CommandLineParseException { - String[] optionValues = commandLine.getOptionValues(arg); - if (optionValues == null) { - return IntStream.range(0, num).mapToObj(operand -> passwordUtil.generatePassword()).collect(Collectors.toList()); - } - if (optionValues.length == 1) { - return IntStream.range(0, num).mapToObj(value -> optionValues[0]).collect(Collectors.toList()); - } else if (optionValues.length == num) { - return Arrays.stream(optionValues).collect(Collectors.toList()); - } - return printUsageAndThrow("Expected either 1 value or " + num + " (the number of " + numArg + ") values for " + arg, ExitCode.ERROR_INCORRECT_NUMBER_OF_PASSWORDS); - } - - private Supplier parsePasswordSupplier(CommandLine commandLine, String option, Supplier defaultSupplier) { - if (commandLine.hasOption(option)) { - String[] values = commandLine.getOptionValues(option); - if (values.length == 1) { - return PasswordUtil.passwordSupplier(values[0]); - } else { - return PasswordUtil.passwordSupplier("Provided " + option + " exhausted, please don't specify " + option - + ", specify one value to be used for all NiFi instances, or specify one value for each NiFi instance.", values); - } - } else { - return defaultSupplier; - } - } - - /** - * Creates the StandaloneConfig for use in running TlsToolkitStandalone - * - * @return the StandaloneConfig for use in running TlsToolkitStandalone - */ - public StandaloneConfig createConfig() { - StandaloneConfig standaloneConfig = new StandaloneConfig(); - - standaloneConfig.setBaseDir(baseDir); - standaloneConfig.setNiFiPropertiesWriterFactory(niFiPropertiesWriterFactory); - standaloneConfig.setInstanceDefinitions(instanceDefinitions); - standaloneConfig.setOverwrite(overwrite); - standaloneConfig.setClientDns(clientDns); - standaloneConfig.setClientPasswords(clientPasswords); - standaloneConfig.setClientPasswordsGenerated(clientPasswordsGenerated); - - standaloneConfig.setCaHostname(getCertificateAuthorityHostname()); - standaloneConfig.setKeyStore("nifi-ca-" + KEYSTORE + getKeyStoreType().toLowerCase()); - standaloneConfig.setKeyStoreType(getKeyStoreType()); - standaloneConfig.setKeySize(getKeySize()); - standaloneConfig.setKeyPairAlgorithm(getKeyAlgorithm()); - standaloneConfig.setSigningAlgorithm(getSigningAlgorithm()); - standaloneConfig.setDays(getDays()); - standaloneConfig.setDnPrefix(dnPrefix); - standaloneConfig.setDnSuffix(dnSuffix); - standaloneConfig.setDomainAlternativeNames(domainAlternativeNames.stream().map(InstanceDefinition::getHostname).collect(Collectors.toList())); - standaloneConfig.setAdditionalCACertificate(additionalCACertificatePath); - standaloneConfig.initDefaults(); - - return standaloneConfig; - } - - public StandaloneConfig createSplitKeystoreConfig() { - StandaloneConfig splitKeystoreConfig = new StandaloneConfig(); - splitKeystoreConfig.setBaseDir(baseDir); - splitKeystoreConfig.setKeyPassword(keyPassword); - splitKeystoreConfig.setKeyStorePassword(keyStorePassword); - splitKeystoreConfig.setKeyStore(splitKeystoreFile); - splitKeystoreConfig.setSplitKeystore(splitKeystore); - - return splitKeystoreConfig; - } -} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/status/TlsToolkitGetStatus.java b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/status/TlsToolkitGetStatus.java deleted file mode 100644 index da48f74eeb..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/status/TlsToolkitGetStatus.java +++ /dev/null @@ -1,50 +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.toolkit.tls.status; - -import org.apache.nifi.toolkit.tls.configuration.GetStatusConfig; -import org.glassfish.jersey.client.ClientConfig; -import org.glassfish.jersey.client.ClientProperties; - -import javax.net.ssl.SSLContext; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.Response; - -public class TlsToolkitGetStatus { - - public void get(final GetStatusConfig config) { - final SSLContext sslContext = config.getSslContext(); - - final ClientBuilder clientBuilder = ClientBuilder.newBuilder(); - if (sslContext != null) { - clientBuilder.sslContext(sslContext); - } - - final ClientConfig clientConfig = new ClientConfig(); - clientConfig.property(ClientProperties.CONNECT_TIMEOUT, 10000); - clientConfig.property(ClientProperties.READ_TIMEOUT, 10000); - clientBuilder.withConfig(clientConfig); - - final Client client = clientBuilder.build(); - final WebTarget target = client.target(config.getUrl()); - final Response response = target.request().get(); - System.out.println("Response Code - " + response.getStatus()); - } - -} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/status/TlsToolkitGetStatusCommandLine.java b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/status/TlsToolkitGetStatusCommandLine.java deleted file mode 100644 index 4ae971d23c..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/status/TlsToolkitGetStatusCommandLine.java +++ /dev/null @@ -1,142 +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.toolkit.tls.status; - -import java.net.URI; -import java.net.URISyntaxException; -import javax.net.ssl.SSLContext; -import org.apache.commons.cli.CommandLine; -import org.apache.nifi.security.util.SslContextFactory; -import org.apache.nifi.security.util.StandardTlsConfiguration; -import org.apache.nifi.security.util.TlsConfiguration; -import org.apache.nifi.security.util.TlsPlatform; -import org.apache.nifi.toolkit.tls.commandLine.BaseCommandLine; -import org.apache.nifi.toolkit.tls.commandLine.CommandLineParseException; -import org.apache.nifi.toolkit.tls.commandLine.ExitCode; -import org.apache.nifi.toolkit.tls.configuration.GetStatusConfig; -import org.apache.nifi.util.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class TlsToolkitGetStatusCommandLine extends BaseCommandLine { - - private final Logger logger = LoggerFactory.getLogger(TlsToolkitGetStatusCommandLine.class); - - public static final String URL_ARG = "url"; - public static final String KEYSTORE_ARG = "keyStore"; - public static final String KEYSTORE_TYPE_ARG = "keyStoreType"; - public static final String KEYSTORE_PASSWORD_ARG = "keyStorePassword"; - public static final String KEY_PASSWORD_ARG = "keyPassword"; - public static final String TRUSTSTORE_ARG = "trustStore"; - public static final String TRUSTSTORE_TYPE_ARG = "trustStoreType"; - public static final String TRUSTSTORE_PASSWORD_ARG = "trustStorePassword"; - public static final String PROTOCOL_ARG = "protocol"; - - public static final String DEFAULT_PROTOCOL = TlsPlatform.getLatestProtocol(); - public static final String DEFAULT_KEYSTORE_TYPE = "JKS"; - - public static final String DESCRIPTION = "Checks the status of an HTTPS endpoint by making a GET request using a supplied keystore and truststore."; - - - private URI url; - private SSLContext sslContext; - - public TlsToolkitGetStatusCommandLine() { - super(DESCRIPTION); - addOptionWithArg("u", URL_ARG, "The full url to connect to, for example: https://localhost:9443/v1/api"); - addOptionWithArg("ks", KEYSTORE_ARG, "The key store to use"); - addOptionWithArg("kst", KEYSTORE_TYPE_ARG, "The type of key store being used (PKCS12 or JKS)", DEFAULT_KEYSTORE_TYPE); - addOptionWithArg("ksp", KEYSTORE_PASSWORD_ARG, "The password of the key store being used"); - addOptionWithArg("kp", KEY_PASSWORD_ARG, "The key password of the key store being used"); - addOptionWithArg("ts", TRUSTSTORE_ARG, "The trust store being used"); - addOptionWithArg("tst", TRUSTSTORE_TYPE_ARG, "The type of trust store being used (PKCS12 or JKS)", DEFAULT_KEYSTORE_TYPE); - addOptionWithArg("tsp", TRUSTSTORE_PASSWORD_ARG, "The password of the trust store being used"); - addOptionWithArg("p", PROTOCOL_ARG, "The protocol to use", DEFAULT_PROTOCOL); - } - - public static void main(String[] args) { - TlsToolkitGetStatusCommandLine commandLine = new TlsToolkitGetStatusCommandLine(); - try { - commandLine.parse(args); - } catch (CommandLineParseException e) { - System.exit(e.getExitCode().ordinal()); - } - - final GetStatusConfig config = commandLine.createConfig(); - try { - final TlsToolkitGetStatus tlsToolkitGetStatus = new TlsToolkitGetStatus(); - tlsToolkitGetStatus.get(config); - } catch (Exception e) { - commandLine.printUsage("Error communicating with " + config.getUrl().toString() + " (" + e.getMessage() + ")"); - System.exit(ExitCode.SERVICE_ERROR.ordinal()); - } - System.exit(ExitCode.SUCCESS.ordinal()); - } - - - @Override - protected void postParse(CommandLine commandLine) throws CommandLineParseException { - super.postParse(commandLine); - - final String urlValue = commandLine.getOptionValue(URL_ARG); - if (StringUtils.isBlank(urlValue)) { - printUsageAndThrow("Url was missing or blank", ExitCode.INVALID_ARGS); - } - - try { - this.url = new URI(urlValue); - } catch (URISyntaxException e) { - printUsageAndThrow("Invalid Url", ExitCode.INVALID_ARGS); - } - - // TODO: Refactor this whole thing - final String keystoreFilename = commandLine.getOptionValue(KEYSTORE_ARG); - String keystoreTypeStr = commandLine.getOptionValue(KEYSTORE_TYPE_ARG, DEFAULT_KEYSTORE_TYPE); - final String keystorePassword = commandLine.getOptionValue(KEYSTORE_PASSWORD_ARG); - final String keyPassword = commandLine.getOptionValue(KEY_PASSWORD_ARG); - - final String truststoreFilename = commandLine.getOptionValue(TRUSTSTORE_ARG); - final String truststoreTypeStr = commandLine.getOptionValue(TRUSTSTORE_TYPE_ARG, DEFAULT_KEYSTORE_TYPE); - final String truststorePassword = commandLine.getOptionValue(TRUSTSTORE_PASSWORD_ARG); - - final String protocol = commandLine.getOptionValue(PROTOCOL_ARG, DEFAULT_PROTOCOL); - - // This use case specifically allows truststore configuration without keystore configuration, but attempts to default the keystore type value - if (StringUtils.isBlank(keystoreFilename)) { - keystoreTypeStr = null; - } - - try { - TlsConfiguration tlsConfiguration = new StandardTlsConfiguration(keystoreFilename, keystorePassword, keyPassword, keystoreTypeStr, - truststoreFilename, truststorePassword, truststoreTypeStr, protocol); - - if (tlsConfiguration.isAnyTruststorePopulated()) { - this.sslContext = SslContextFactory.createSslContext(tlsConfiguration); - } else { - printUsageAndThrow("No truststore was provided", ExitCode.INVALID_ARGS); - } - } catch (Exception e) { - logger.error(e.getMessage(), e); - printUsageAndThrow("Failed to create SSL Context: " + e.getMessage(), ExitCode.INVALID_ARGS); - } - } - - public GetStatusConfig createConfig() { - return new GetStatusConfig(url, sslContext); - } - -} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/util/InputStreamFactory.java b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/util/InputStreamFactory.java deleted file mode 100644 index 50104f46d4..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/util/InputStreamFactory.java +++ /dev/null @@ -1,26 +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.toolkit.tls.util; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.InputStream; - -public interface InputStreamFactory { - InputStream create(File file) throws FileNotFoundException; -} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/util/OutputStreamFactory.java b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/util/OutputStreamFactory.java deleted file mode 100644 index 759e34ff34..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/util/OutputStreamFactory.java +++ /dev/null @@ -1,26 +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.toolkit.tls.util; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.OutputStream; - -public interface OutputStreamFactory { - OutputStream create(File file) throws FileNotFoundException; -} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/util/PasswordUtil.java b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/util/PasswordUtil.java deleted file mode 100644 index fb4945508c..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/util/PasswordUtil.java +++ /dev/null @@ -1,65 +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.toolkit.tls.util; - -import java.security.SecureRandom; -import java.util.Base64; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Supplier; - -public class PasswordUtil { - private final SecureRandom secureRandom; - - public PasswordUtil() { - this(new SecureRandom()); - } - - public PasswordUtil(SecureRandom secureRandom) { - this.secureRandom = secureRandom; - } - - public String generatePassword() { - byte[] bytes = new byte[32]; - secureRandom.nextBytes(bytes); - String string = Base64.getEncoder().encodeToString(bytes); - while (string.endsWith("=")) { - string = string.substring(0, string.length() - 1); - } - return string; - } - - public Supplier passwordSupplier() { - return () -> generatePassword(); - } - - public static Supplier passwordSupplier(String password) { - return () -> password; - } - - public static Supplier passwordSupplier(String exhaustedMessage, String[] passwords) { - AtomicInteger index = new AtomicInteger(0); - return () -> { - int i = index.getAndIncrement(); - if (i < passwords.length) { - return passwords[i]; - } else { - throw new PasswordsExhaustedException(exhaustedMessage); - } - }; - } -} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/util/PasswordsExhaustedException.java b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/util/PasswordsExhaustedException.java deleted file mode 100644 index 6d26a1987d..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/util/PasswordsExhaustedException.java +++ /dev/null @@ -1,24 +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.toolkit.tls.util; - -public class PasswordsExhaustedException extends RuntimeException { - public PasswordsExhaustedException(String message) { - super(message); - } -} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/util/TlsHelper.java b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/util/TlsHelper.java deleted file mode 100644 index 35cdb1dbfe..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/util/TlsHelper.java +++ /dev/null @@ -1,437 +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.toolkit.tls.util; - -import org.bouncycastle.asn1.ASN1Encodable; -import org.bouncycastle.asn1.DERNull; -import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; -import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; -import org.bouncycastle.asn1.pkcs.RSAPrivateKey; -import org.bouncycastle.asn1.pkcs.RSAPublicKey; -import org.bouncycastle.asn1.x500.X500Name; -import org.bouncycastle.asn1.x500.style.BCStyle; -import org.bouncycastle.asn1.x500.style.IETFUtils; -import org.bouncycastle.asn1.x509.AlgorithmIdentifier; -import org.bouncycastle.asn1.x509.Extension; -import org.bouncycastle.asn1.x509.Extensions; -import org.bouncycastle.asn1.x509.ExtensionsGenerator; -import org.bouncycastle.asn1.x509.GeneralName; -import org.bouncycastle.asn1.x509.GeneralNames; -import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; -import org.bouncycastle.cert.X509CertificateHolder; -import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; -import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils; -import org.bouncycastle.openssl.PEMException; -import org.bouncycastle.openssl.PEMKeyPair; -import org.bouncycastle.openssl.PEMParser; -import org.bouncycastle.openssl.jcajce.JcaMiscPEMGenerator; -import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter; -import org.bouncycastle.openssl.jcajce.JcaPEMWriter; -import org.bouncycastle.operator.OperatorCreationException; -import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; -import org.bouncycastle.pkcs.PKCS10CertificationRequest; -import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest; -import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder; -import org.bouncycastle.util.IPAddress; -import org.bouncycastle.util.io.pem.PemWriter; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.crypto.Cipher; -import javax.crypto.Mac; -import javax.crypto.spec.SecretKeySpec; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.Reader; -import java.io.StringReader; -import java.io.StringWriter; -import java.nio.charset.StandardCharsets; -import java.security.GeneralSecurityException; -import java.security.Key; -import java.security.KeyPair; -import java.security.KeyPairGenerator; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.PublicKey; -import java.security.UnrecoverableKeyException; -import java.security.cert.Certificate; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.List; - -public class TlsHelper { - private static final Logger logger = LoggerFactory.getLogger(TlsHelper.class); - private static final int DEFAULT_MAX_ALLOWED_KEY_LENGTH = 128; - public static final String JCE_URL = "http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html"; - public static final String ILLEGAL_KEY_SIZE = "illegal key size"; - private static boolean isUnlimitedStrengthCryptographyEnabled; - private static boolean isVerbose = true; - - // Evaluate an unlimited strength algorithm to determine if we support the capability we have on the system - static { - try { - isUnlimitedStrengthCryptographyEnabled = (Cipher.getMaxAllowedKeyLength("AES") > DEFAULT_MAX_ALLOWED_KEY_LENGTH); - } catch (NoSuchAlgorithmException e) { - // if there are issues with this, we default back to the value established - isUnlimitedStrengthCryptographyEnabled = false; - } - } - - private static void logTruncationWarning(File file) { - String fileToString = file.toString(); - String fileName = file.getName(); - logger.warn("**********************************************************************************"); - logger.warn(" WARNING!!!!"); - logger.warn("**********************************************************************************"); - logger.warn("Unlimited JCE Policy is not installed which means we cannot utilize a"); - logger.warn("PKCS12 password longer than 7 characters."); - logger.warn("Autogenerated password has been reduced to 7 characters."); - logger.warn(""); - logger.warn("Please strongly consider installing Unlimited JCE Policy at"); - logger.warn(JCE_URL); - logger.warn(""); - logger.warn("Another alternative is to add a stronger password with the openssl tool to the"); - logger.warn("resulting client certificate: " + fileToString); - logger.warn(""); - logger.warn("openssl pkcs12 -in '" + fileToString + "' -out '/tmp/" + fileName + "'"); - logger.warn("openssl pkcs12 -export -in '/tmp/" + fileName + "' -out '" + fileToString + "'"); - logger.warn("rm -f '/tmp/" + fileName + "'"); - logger.warn(""); - logger.warn("**********************************************************************************"); - - } - - private TlsHelper() { - - } - - public static boolean isUnlimitedStrengthCryptographyEnabled() { - return isUnlimitedStrengthCryptographyEnabled; - } - - public static String writeKeyStore(KeyStore keyStore, OutputStreamFactory outputStreamFactory, File file, String password, boolean generatedPassword) throws IOException, GeneralSecurityException { - try (OutputStream fileOutputStream = outputStreamFactory.create(file)) { - keyStore.store(fileOutputStream, password.toCharArray()); - } catch (IOException e) { - if (e.getMessage().toLowerCase().contains(ILLEGAL_KEY_SIZE) && !isUnlimitedStrengthCryptographyEnabled()) { - if (generatedPassword) { - file.delete(); - String truncatedPassword = password.substring(0, 7); - try (OutputStream fileOutputStream = outputStreamFactory.create(file)) { - keyStore.store(fileOutputStream, truncatedPassword.toCharArray()); - } - logTruncationWarning(file); - return truncatedPassword; - } else { - throw new GeneralSecurityException("Specified password for " + file + " too long to work without unlimited JCE policy installed." - + System.lineSeparator() + "Please see " + JCE_URL); - } - } else { - throw e; - } - } - return password; - } - - public static HashMap extractCerts(KeyStore keyStore) throws KeyStoreException { - HashMap certs = new HashMap<>(); - Enumeration certAliases = keyStore.aliases(); - while(certAliases.hasMoreElements()) { - String alias = certAliases.nextElement(); - certs.put(alias, keyStore.getCertificate(alias)); - } - return certs; - } - - public static HashMap extractKeys(KeyStore keyStore, char[] privKeyPass) throws KeyStoreException, UnrecoverableKeyException, NoSuchAlgorithmException { - HashMap keys = new HashMap<>(); - Enumeration keyAliases = keyStore.aliases(); - while(keyAliases.hasMoreElements()) { - String alias = keyAliases.nextElement(); - Key key = keyStore.getKey(alias, privKeyPass); - if(key != null) { - keys.put(alias, key); - } else { - logger.warn("Key does not exist: Certificate with alias '" + alias + "' had no private key."); - } - } - return keys; - } - - public static void outputCertsAsPem(HashMap certs, File directory, String extension) { - certs.forEach((String alias, Certificate cert)->{ - try { - TlsHelper.outputAsPem(cert, alias, directory, extension); - } catch (IOException e) { - e.printStackTrace(); - } - }); - } - - public static void outputKeysAsPem(HashMap keys, File directory, String extension) { - keys.forEach((String alias, Key key) -> { - try { - TlsHelper.outputAsPem(key, alias, directory, extension); - } catch (IOException e) { - e.printStackTrace(); - } - }); - } - - private static void outputAsPem(Object pemObj, String filename, File directory, String extension) throws IOException { - try (OutputStream outputStream = new FileOutputStream(new File(directory, TlsHelper.escapeFilename(filename) + extension))) { - OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream); - JcaPEMWriter pemWriter = new JcaPEMWriter(outputStreamWriter); - JcaMiscPEMGenerator pemGen = new JcaMiscPEMGenerator(pemObj); - pemWriter.writeObject(pemGen); - pemWriter.close(); - } - } - - private static KeyPairGenerator createKeyPairGenerator(String algorithm, int keySize) throws NoSuchAlgorithmException { - KeyPairGenerator instance = KeyPairGenerator.getInstance(algorithm); - instance.initialize(keySize); - return instance; - } - - public static byte[] calculateHMac(String token, PublicKey publicKey) throws GeneralSecurityException { - if (token == null) { - throw new IllegalArgumentException("Token cannot be null"); - } - byte[] tokenBytes = token.getBytes(StandardCharsets.UTF_8); - if (tokenBytes.length < 16) { - throw new GeneralSecurityException("Token does not meet minimum size of 16 bytes."); - } - SecretKeySpec keySpec = new SecretKeySpec(tokenBytes, "RAW"); - Mac mac = Mac.getInstance("HmacSHA256"); - mac.init(keySpec); - return mac.doFinal(getKeyIdentifier(publicKey)); - } - - public static byte[] getKeyIdentifier(PublicKey publicKey) throws NoSuchAlgorithmException { - return new JcaX509ExtensionUtils().createSubjectKeyIdentifier(publicKey).getKeyIdentifier(); - } - - public static String pemEncodeJcaObject(Object object) throws IOException { - StringWriter writer = new StringWriter(); - try (PemWriter pemWriter = new PemWriter(writer)) { - pemWriter.writeObject(new JcaMiscPEMGenerator(object)); - } - return writer.toString(); - } - - public static JcaPKCS10CertificationRequest parseCsr(String pemEncodedCsr) throws IOException { - try (PEMParser pemParser = new PEMParser(new StringReader(pemEncodedCsr))) { - Object o = pemParser.readObject(); - if (!PKCS10CertificationRequest.class.isInstance(o)) { - throw new IOException("Expecting instance of " + PKCS10CertificationRequest.class + " but got " + o); - } - return new JcaPKCS10CertificationRequest((PKCS10CertificationRequest) o); - } - } - - public static X509Certificate parseCertificate(Reader pemEncodedCertificate) throws IOException, CertificateException { - return new JcaX509CertificateConverter().getCertificate(parsePem(X509CertificateHolder.class, pemEncodedCertificate)); - } - - /** - * Returns the parsed {@link KeyPair} from the provided {@link Reader}. The incoming format can be PKCS #8 or PKCS #1. - * - * @param pemKeyPairReader a reader with access to the serialized key pair - * @return the key pair - * @throws IOException if there is an error reading the key pair - */ - public static KeyPair parseKeyPairFromReader(Reader pemKeyPairReader) throws IOException { - // Instantiate PEMParser from Reader - try (PEMParser pemParser = new PEMParser(pemKeyPairReader)) { - // Read the object (deserialize) - Object parsedObject = pemParser.readObject(); - - // If this is an ASN.1 private key, it's in PKCS #8 format and wraps the actual RSA private key - if (PrivateKeyInfo.class.isInstance(parsedObject)) { - if (isVerbose()) { - logger.info("Provided private key is in PKCS #8 format"); - } - PEMKeyPair keyPair = convertPrivateKeyFromPKCS8ToPKCS1((PrivateKeyInfo) parsedObject); - return getKeyPair(keyPair); - } else if (PEMKeyPair.class.isInstance(parsedObject)) { - // Already in PKCS #1 format - return getKeyPair((PEMKeyPair)parsedObject); - } else { - logger.warn("Expected one of {} or {} but got {}", PrivateKeyInfo.class, PEMKeyPair.class, parsedObject.getClass()); - throw new IOException("Expected private key in PKCS #1 or PKCS #8 unencrypted format"); - } - } - } - - /** - * Returns a {@link KeyPair} instance containing the {@link X509Certificate} public key and the {@link java.security.spec.PKCS8EncodedKeySpec} private key from the PEM-encoded {@link PEMKeyPair}. - * - * @param keyPair the key pair in PEM format - * @return the key pair in a format which provides for direct access to the keys - * @throws PEMException if there is an error converting the key pair - */ - private static KeyPair getKeyPair(PEMKeyPair keyPair) throws PEMException { - return new JcaPEMKeyConverter().getKeyPair(keyPair); - } - - /** - * Returns a {@link PEMKeyPair} object with direct access to the public and private keys given a PKCS #8 private key. - * - * @param privateKeyInfo the PKCS #8 private key info - * @return the PKCS #1 public and private key pair - * @throws IOException if there is an error converting the key pair - */ - private static PEMKeyPair convertPrivateKeyFromPKCS8ToPKCS1(PrivateKeyInfo privateKeyInfo) throws IOException { - // Parse the key wrapping to determine the internal key structure - ASN1Encodable asn1PrivateKey = privateKeyInfo.parsePrivateKey(); - - // Convert the parsed key to an RSA private key - RSAPrivateKey keyStruct = RSAPrivateKey.getInstance(asn1PrivateKey); - - // Create the RSA public key from the modulus and exponent - RSAPublicKey pubSpec = new RSAPublicKey( - keyStruct.getModulus(), keyStruct.getPublicExponent()); - - // Create an algorithm identifier for forming the key pair - AlgorithmIdentifier algId = new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE); - if (isVerbose()) { - logger.info("Converted private key from PKCS #8 to PKCS #1 RSA private key"); - } - - // Create the key pair container - return new PEMKeyPair(new SubjectPublicKeyInfo(algId, pubSpec), new PrivateKeyInfo(algId, keyStruct)); - } - - public static T parsePem(Class clazz, Reader pemReader) throws IOException { - try (PEMParser pemParser = new PEMParser(pemReader)) { - Object object = pemParser.readObject(); - if (!clazz.isInstance(object)) { - throw new IOException("Expected " + clazz + " but got " + object.getClass()); - } - return (T) object; - } - } - - public static KeyPair generateKeyPair(String algorithm, int keySize) throws NoSuchAlgorithmException { - return createKeyPairGenerator(algorithm, keySize).generateKeyPair(); - } - - public static JcaPKCS10CertificationRequest generateCertificationRequest(String requestedDn, List domainAlternativeNames, - KeyPair keyPair, String signingAlgorithm) throws OperatorCreationException { - JcaPKCS10CertificationRequestBuilder jcaPKCS10CertificationRequestBuilder = new JcaPKCS10CertificationRequestBuilder(new X500Name(requestedDn), keyPair.getPublic()); - - // add Subject Alternative Name(s) - try { - jcaPKCS10CertificationRequestBuilder.addAttribute(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest, createDomainAlternativeNamesExtensions(domainAlternativeNames, requestedDn)); - } catch (IOException e) { - throw new OperatorCreationException("Error while adding " + domainAlternativeNames + " as Subject Alternative Name.", e); - } - - JcaContentSignerBuilder jcaContentSignerBuilder = new JcaContentSignerBuilder(signingAlgorithm); - return new JcaPKCS10CertificationRequest(jcaPKCS10CertificationRequestBuilder.build(jcaContentSignerBuilder.build(keyPair.getPrivate()))); - } - - public static Extensions createDomainAlternativeNamesExtensions(List domainAlternativeNames, String requestedDn) throws IOException { - List namesList = new ArrayList<>(); - - try { - final String cn = IETFUtils.valueToString(new X500Name(requestedDn).getRDNs(BCStyle.CN)[0].getFirst().getValue()); - namesList.add(new GeneralName(GeneralName.dNSName, cn)); - } catch (Exception e) { - throw new IOException("Failed to extract CN from request DN: " + requestedDn, e); - } - - if (domainAlternativeNames != null) { - for (String alternativeName : domainAlternativeNames) { - namesList.add(new GeneralName(IPAddress.isValid(alternativeName) ? GeneralName.iPAddress : GeneralName.dNSName, alternativeName)); - } - } - - GeneralNames subjectAltNames = new GeneralNames(namesList.toArray(new GeneralName[]{})); - ExtensionsGenerator extGen = new ExtensionsGenerator(); - extGen.addExtension(Extension.subjectAlternativeName, false, subjectAltNames); - return extGen.generate(); - } - - - /** - * Removes special characters (particularly forward and back slashes) from strings that become file names. - * - * @param filename A filename you plan to write to disk which needs to be escaped. - * @return String with special characters converted to underscores. - */ - public static final String escapeFilename(String filename) { - return filename.replaceAll("[^\\w\\.\\-\\=]+", "_"); - } - - /** - * Returns true if the {@code certificate} is signed by one of the {@code signingCertificates}. The list should - * include the certificate itself to allow for self-signed certificates. If it does not, a self-signed certificate - * will return {@code false}. - * - * @param certificate the certificate containing the signature being verified - * @param signingCertificates a list of certificates which may have signed the certificate - * @return true if one of the signing certificates did sign the certificate - */ - public static boolean verifyCertificateSignature(X509Certificate certificate, List signingCertificates) { - String certificateDisplayInfo = getCertificateDisplayInfo(certificate); - if (isVerbose()) { - logger.info("Verifying the certificate signature for " + certificateDisplayInfo); - } - boolean signatureMatches = false; - for (X509Certificate signingCert : signingCertificates) { - final String signingCertDisplayInfo = getCertificateDisplayInfo(signingCert); - try { - if (isVerbose()) { - logger.info("Attempting to verify certificate " + certificateDisplayInfo + " signature with " + signingCertDisplayInfo); - } - PublicKey pub = signingCert.getPublicKey(); - certificate.verify(pub); - if (isVerbose()) { - logger.info("Certificate was signed by " + signingCertDisplayInfo); - } - signatureMatches = true; - break; - } catch (Exception e) { - // Expected if the signature does not match - if (isVerbose()) { - logger.warn("Certificate " + certificateDisplayInfo + " not signed by " + signingCertDisplayInfo + " [" + e.getLocalizedMessage() + "]"); - } - } - } - return signatureMatches; - } - - private static String getCertificateDisplayInfo(X509Certificate certificate) { - return certificate.getSubjectX500Principal().getName(); - } - - private static boolean isVerbose() { - // TODO: When verbose mode is enabled via command-line flag, this will read the variable - return isVerbose; - } - -} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/configuration/InstanceDefinitionTest.java b/nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/configuration/InstanceDefinitionTest.java deleted file mode 100644 index 57bc112355..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/configuration/InstanceDefinitionTest.java +++ /dev/null @@ -1,133 +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.toolkit.tls.configuration; - -import org.junit.jupiter.api.Test; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.function.Supplier; -import java.util.stream.Collectors; -import java.util.stream.IntStream; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class InstanceDefinitionTest { - - @Test - public void testCreateDefinitionKeyPassword() { - testCreateDefinition("testHostname", 4, "keyStorePassword", "keyPassword", "trustStorePassword"); - } - - @Test - public void testCreateDefinitionNoKeyPassword() { - testCreateDefinition("testHostname", 5, "keyStorePassword", null, "trustStorePassword"); - } - - @Test - public void testCreateDefinitionsSingleHostSingleName() { - testCreateDefinitions(Collections.singletonList("hostname"), Collections.singletonList("hostname"), Collections.singletonList(1), false); - } - - @Test - public void testCreateDefinitionsSingleHostnameOneNumberInParens() { - testCreateDefinitions(Collections.singletonList("hostname(20)"), - IntStream.range(1, 21).mapToObj(operand -> "hostname").collect(Collectors.toList()), - integerRange(1, 20).collect(Collectors.toList()), false); - } - - @Test - public void testCreateDefinitionsSingleHostnameTwoNumbersInParens() { - testCreateDefinitions(Collections.singletonList("hostname(5-20)"), - IntStream.range(5, 21).mapToObj(operand -> "hostname").collect(Collectors.toList()), - integerRange(5, 20).collect(Collectors.toList()), false); - } - - @Test - public void testCreateDefinitionsMultipleHostnamesWithMultipleNumbers() { - testCreateDefinitions(Collections.singletonList("host[10]name[02-5](20)"), - integerRange(1, 10).flatMap(v -> integerRange(2, 5).flatMap(v2 -> integerRange(1, 20).map(v3 -> "host" + v + "name" + String.format("%02d", v2)))).collect(Collectors.toList()), - integerRange(1, 10).flatMap(val -> integerRange(2, 5).flatMap(val2 -> integerRange(1, 20))).collect(Collectors.toList()), false); - } - - @Test - public void testCreateDefinitionsStream() { - testCreateDefinitions(Arrays.asList("host", "name"), Arrays.asList("host", "name"), Arrays.asList(1, 1), true); - } - - @Test - public void testCreateDefinitionsStreamNonNullKeyPasswords() { - testCreateDefinitions(Arrays.asList("host", "name"), Arrays.asList("host", "name"), Arrays.asList(1, 1), false); - } - - private Stream integerRange(int start, int endInclusive) { - return IntStream.range(start, endInclusive + 1).mapToObj(value -> value); - } - - private void testCreateDefinitions(List hostnameExpressions, List expectedHostnames, List expectedNumbers, boolean nullForKeyPasswords) { - List keyStorePasswords = IntStream.range(0, expectedHostnames.size()).mapToObj(value -> "testKeyStorePassword" + value).collect(Collectors.toList()); - List keyPasswords; - if (nullForKeyPasswords) { - keyPasswords = null; - } else { - keyPasswords = IntStream.range(0, expectedHostnames.size()).mapToObj(value -> "testKeyPassword" + value).collect(Collectors.toList()); - } - List trustStorePasswords = IntStream.range(0, expectedHostnames.size()).mapToObj(value -> "testTrustStorePassword" + value).collect(Collectors.toList()); - List instanceDefinitions = InstanceDefinition.createDefinitions(null, hostnameExpressions.stream(), - mockSupplier(keyStorePasswords.toArray(new String[0])), keyPasswords == null ? null : mockSupplier(keyPasswords.toArray(new String[0])), - mockSupplier(trustStorePasswords.toArray(new String[0]))); - testCreateDefinitionsOutput(instanceDefinitions, expectedHostnames, expectedNumbers, keyStorePasswords, keyPasswords, trustStorePasswords); - } - - private void testCreateDefinitionsOutput(List instanceDefinitions, List expectedHostnames, List expectedNumbers, List keyStorePasswords, - List keyPasswords, List trustStorePasswords) { - assertEquals(instanceDefinitions.size(), expectedHostnames.size()); - for (int i = 0; i < instanceDefinitions.size(); i++) { - assertDefinitionEquals(instanceDefinitions.get(i), expectedHostnames.get(i), expectedNumbers.get(i), keyStorePasswords.get(i), - keyPasswords == null ? null : keyPasswords.get(i), trustStorePasswords.get(i)); - } - } - - private void testCreateDefinition(String hostname, int num, String keyStorePassword, String keyPassword, String trustStorePassword) { - InstanceDefinition definition = InstanceDefinition.createDefinition(new InstanceIdentifier(hostname, num), num, mockSupplier(keyStorePassword), - keyPassword == null ? null : mockSupplier(keyPassword), mockSupplier(trustStorePassword)); - assertDefinitionEquals(definition, hostname, num, keyStorePassword, keyPassword, trustStorePassword); - } - - private void assertDefinitionEquals(InstanceDefinition definition, String hostname, int num, String keyStorePassword, String keyPassword, String trustStorePassword) { - assertEquals(hostname, definition.getHostname()); - assertEquals(num, definition.getNumber()); - assertEquals(keyStorePassword, definition.getKeyStorePassword()); - assertEquals(keyPassword == null ? keyStorePassword : keyPassword, definition.getKeyPassword()); - assertEquals(trustStorePassword, definition.getTrustStorePassword()); - } - - private Supplier mockSupplier(T... values) { - Supplier supplier = mock(Supplier.class); - if (values.length == 1) { - when(supplier.get()).thenReturn(values[0]); - } else if (values.length > 1) { - when(supplier.get()).thenReturn(values[0], Arrays.copyOfRange(values, 1, values.length)); - } - return supplier; - } -} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/configuration/InstanceIdentifierTest.java b/nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/configuration/InstanceIdentifierTest.java deleted file mode 100644 index 6340fea2a3..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/configuration/InstanceIdentifierTest.java +++ /dev/null @@ -1,164 +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.toolkit.tls.configuration; - -import org.junit.jupiter.api.Test; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Consumer; -import java.util.stream.Collectors; -import java.util.stream.IntStream; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - -public class InstanceIdentifierTest { - - @Test - public void testExtractHostnamesSingle() { - testExtractHostnames("test[1-3]", "test1", "test2", "test3"); - } - - @Test - public void testExtractHostnamesPadding() { - testExtractHostnames("test[0001-3]", "test0001", "test0002", "test0003"); - } - - @Test - public void testExtractHostnamesLowGreaterThanHigh() { - testExtractHostnames("test[3-1]", "test3", "test2", "test1"); - } - - @Test - public void testExtractHostnamesLowEqualToHigh() { - testExtractHostnames("test[3-3]", "test3"); - } - - @Test - public void testExtractHostnamesSingleNumber() { - testExtractHostnames("test[2]", "test1", "test2"); - } - - @Test - public void testExtractHostnamesSingleNumberPadding() { - testExtractHostnames("test[002]", "test001", "test002"); - } - - @Test - public void testExtractHostnamesNoNumber() { - assertThrows(IllegalArgumentException.class, () -> testExtractHostnames("test[]", "test")); - } - - @Test - public void testExtractHostnamesMultiple() { - testExtractHostnames("test[1-3]name[1-3]", "test1name1", "test1name2", "test1name3", "test2name1", "test2name2", "test2name3", "test3name1", "test3name2", "test3name3"); - } - - @Test - public void testExtractHostnamesUnmatched() { - assertThrows(IllegalArgumentException.class, () -> testExtractHostnames("test[")); - } - - @Test - public void testExtractHostnamesSpace() { - assertThrows(IllegalArgumentException.class, () -> testExtractHostnames("test[ 1-2]")); - } - - @Test - public void testExtractHostnamesMultipleHyphens() { - assertThrows(IllegalArgumentException.class, () -> testExtractHostnames("test[1-2-3]")); - } - - @Test - public void testCreateDefinitionsSingleHostSingleName() { - testCreateIdentifiers(Collections.singletonList("hostname"), Collections.singletonList("hostname"), Collections.singletonList(1)); - } - - @Test - public void testCreateDefinitionsSingleHostnameOneNumberInParens() { - testCreateIdentifiers(Collections.singletonList("hostname(20)"), - IntStream.range(1, 21).mapToObj(operand -> "hostname").collect(Collectors.toList()), - integerRange(1, 20).collect(Collectors.toList())); - } - - @Test - public void testCreateDefinitionsSingleHostnameTwoNumbersInParens() { - testCreateIdentifiers(Collections.singletonList("hostname(5-20)"), - IntStream.range(5, 21).mapToObj(operand -> "hostname").collect(Collectors.toList()), - integerRange(5, 20).collect(Collectors.toList())); - } - - @Test - public void testCreateDefinitionsMultipleHostnamesWithMultipleNumbers() { - testCreateIdentifiers(Collections.singletonList("host[10]name[02-5](20)"), - integerRange(1, 10).flatMap(v -> integerRange(2, 5).flatMap(v2 -> integerRange(1, 20).map(v3 -> "host" + v + "name" + String.format("%02d", v2)))).collect(Collectors.toList()), - integerRange(1, 10).flatMap(val -> integerRange(2, 5).flatMap(val2 -> integerRange(1, 20))).collect(Collectors.toList())); - } - - @Test - public void testCreateDefinitionsStream() { - testCreateIdentifiers(Arrays.asList("host", "name"), Arrays.asList("host", "name"), Arrays.asList(1, 1)); - } - - @Test - public void testCreateOrderMap() { - String abc123 = "abc[1-3]"; - String abc0123 = "abc[01-3]"; - String b = "b"; - - Map orderMap = InstanceIdentifier.createOrderMap(Stream.of(abc123, abc0123 + "(2)", b)); - - AtomicInteger num = new AtomicInteger(1); - Consumer action = id -> { - int i = num.getAndIncrement(); - assertEquals(i, orderMap.get(id).intValue()); - }; - - InstanceIdentifier.extractHostnames(abc0123).flatMap(s -> Stream.of(new InstanceIdentifier(s, 1), new InstanceIdentifier(s, 2))).forEach(action); - InstanceIdentifier.extractHostnames(abc123).map(s -> new InstanceIdentifier(s, 1)).forEach(action); - InstanceIdentifier.extractHostnames(b).map(s -> new InstanceIdentifier(s, 1)).forEach(action); - } - - @Test - public void testCreateIdentifiersCharactersAfterNumber() { - assertThrows(IllegalArgumentException.class, () -> InstanceIdentifier.createIdentifiers(Stream.of("test(2)a")).count()); - } - - private Stream integerRange(int start, int endInclusive) { - return IntStream.range(start, endInclusive + 1).mapToObj(value -> value); - } - - private void testExtractHostnames(String hostnameWithRange, String... expectedHostnames) { - assertEquals(Stream.of(expectedHostnames).collect(Collectors.toList()), InstanceIdentifier.extractHostnames(hostnameWithRange).collect(Collectors.toList())); - } - - private void testCreateIdentifiers(List hostnameExpressions, List expectedHostnames, List expectedNumbers) { - List instanceIdentifiers = InstanceIdentifier.createIdentifiers(hostnameExpressions.stream()).collect(Collectors.toList()); - assertEquals(instanceIdentifiers.size(), expectedHostnames.size()); - for (int i = 0; i < instanceIdentifiers.size(); i++) { - InstanceIdentifier identifier = instanceIdentifiers.get(i); - assertEquals(expectedHostnames.get(i), identifier.getHostname()); - assertEquals((int) expectedNumbers.get(i), identifier.getNumber()); - } - } -} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/manager/writer/NifiPropertiesTlsClientConfigWriterTest.java b/nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/manager/writer/NifiPropertiesTlsClientConfigWriterTest.java deleted file mode 100644 index 8d48157817..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/manager/writer/NifiPropertiesTlsClientConfigWriterTest.java +++ /dev/null @@ -1,148 +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.toolkit.tls.manager.writer; - -import org.apache.nifi.toolkit.tls.configuration.TlsClientConfig; -import org.apache.nifi.toolkit.tls.configuration.TlsConfig; -import org.apache.nifi.toolkit.tls.properties.NiFiPropertiesWriter; -import org.apache.nifi.toolkit.tls.properties.NiFiPropertiesWriterFactory; -import org.apache.nifi.toolkit.tls.util.OutputStreamFactory; -import org.apache.nifi.util.NiFiProperties; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Properties; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.mockito.Mockito.when; - -@ExtendWith(MockitoExtension.class) -public class NifiPropertiesTlsClientConfigWriterTest { - @Mock - NiFiPropertiesWriterFactory niFiPropertiesWriterFactory; - @Mock - OutputStreamFactory outputStreamFactory; - private NiFiPropertiesWriter niFiPropertiesWriter; - private int hostNum; - private String testHostname; - private File outputFile; - private NifiPropertiesTlsClientConfigWriter nifiPropertiesTlsClientConfigWriter; - private TlsClientConfig tlsClientConfig; - private ByteArrayOutputStream outputStream; - private String keyStore; - private String keyStorePassword; - private String trustStore; - private String trustStorePassword; - private Properties overlayProperties; - private String keyPassword; - private String keyStoreType; - private String trustStoreType; - - @BeforeEach - public void setup() throws IOException { - testHostname = "testHostname"; - hostNum = 22; - - keyStore = "testKeyStore.jks"; - keyStoreType = TlsConfig.DEFAULT_KEY_STORE_TYPE; - keyStorePassword = "badKeyStorePassword"; - keyPassword = "badKeyPassword"; - - trustStore = "testTrustStore.jks"; - trustStoreType = TlsConfig.DEFAULT_KEY_STORE_TYPE; - trustStorePassword = "badTrustStorePassword"; - - outputFile = File.createTempFile("temp", "nifi"); - outputStream = new ByteArrayOutputStream(); - when(outputStreamFactory.create(outputFile)).thenReturn(outputStream); - - tlsClientConfig = new TlsClientConfig(); - tlsClientConfig.setKeyStore(keyStore); - tlsClientConfig.setKeyStoreType(keyStoreType); - tlsClientConfig.setKeyStorePassword(keyStorePassword); - tlsClientConfig.setKeyPassword(keyPassword); - - tlsClientConfig.setTrustStore(trustStore); - tlsClientConfig.setTrustStoreType(trustStoreType); - tlsClientConfig.setTrustStorePassword(trustStorePassword); - - niFiPropertiesWriter = new NiFiPropertiesWriter(new ArrayList<>()); - when(niFiPropertiesWriterFactory.create()).thenReturn(niFiPropertiesWriter); - nifiPropertiesTlsClientConfigWriter = new NifiPropertiesTlsClientConfigWriter(niFiPropertiesWriterFactory, outputFile, testHostname, hostNum); - overlayProperties = nifiPropertiesTlsClientConfigWriter.getOverlayProperties(); - } - - @Test - public void testDefaults() throws IOException { - nifiPropertiesTlsClientConfigWriter.write(tlsClientConfig, outputStreamFactory); - testHostnamesAndPorts(); - assertNotEquals(0, nifiPropertiesTlsClientConfigWriter.getIncrementingPropertyMap().size()); - } - - @Test - public void testNoHostnameProperties() throws IOException { - nifiPropertiesTlsClientConfigWriter.getOverlayProperties().setProperty(NifiPropertiesTlsClientConfigWriter.HOSTNAME_PROPERTIES, ""); - nifiPropertiesTlsClientConfigWriter.write(tlsClientConfig, outputStreamFactory); - testHostnamesAndPorts(); - Properties nifiProperties = getNifiProperties(); - nifiProperties.stringPropertyNames().forEach(s -> assertNotEquals(testHostname, nifiProperties.getProperty(s))); - } - - private void testHostnamesAndPorts() { - Properties nifiProperties = getNifiProperties(); - - assertEquals(NifiPropertiesTlsClientConfigWriter.CONF + keyStore, nifiProperties.getProperty(NiFiProperties.SECURITY_KEYSTORE)); - assertEquals(keyStoreType, nifiProperties.getProperty(NiFiProperties.SECURITY_KEYSTORE_TYPE)); - assertEquals(keyStorePassword, nifiProperties.getProperty(NiFiProperties.SECURITY_KEYSTORE_PASSWD)); - assertEquals(keyPassword, nifiProperties.getProperty(NiFiProperties.SECURITY_KEY_PASSWD)); - - assertEquals(NifiPropertiesTlsClientConfigWriter.CONF + trustStore, nifiProperties.getProperty(NiFiProperties.SECURITY_TRUSTSTORE)); - assertEquals(trustStoreType, nifiProperties.getProperty(NiFiProperties.SECURITY_TRUSTSTORE_TYPE)); - assertEquals(trustStorePassword, nifiProperties.getProperty(NiFiProperties.SECURITY_TRUSTSTORE_PASSWD)); - - assertEquals("", nifiProperties.getProperty(NiFiProperties.WEB_HTTP_HOST)); - assertEquals("", nifiProperties.getProperty(NiFiProperties.WEB_HTTP_PORT)); - assertEquals(Boolean.toString(true), nifiProperties.getProperty(NiFiProperties.SITE_TO_SITE_SECURE)); - assertEquals(Boolean.toString(true), nifiProperties.getProperty(NiFiProperties.CLUSTER_PROTOCOL_IS_SECURE)); - - nifiPropertiesTlsClientConfigWriter.getHostnamePropertyStream().forEach(s -> assertEquals(testHostname, nifiProperties.getProperty(s))); - nifiPropertiesTlsClientConfigWriter.getIncrementingPropertyMap().entrySet().forEach(propertyToPortEntry -> { - assertEquals(Integer.toString(propertyToPortEntry.getValue()), nifiProperties.getProperty(propertyToPortEntry.getKey())); - assertEquals(Integer.parseInt(overlayProperties.getProperty(propertyToPortEntry.getKey())) + hostNum - 1, propertyToPortEntry.getValue().intValue()); - }); - } - - private Properties getNifiProperties() { - Properties properties = new Properties(); - try { - properties.load(new ByteArrayInputStream(outputStream.toByteArray())); - } catch (IOException e) { - throw new RuntimeException(e); - } - return properties; - } -} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/properties/NifiPropertiesWriterTest.java b/nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/properties/NifiPropertiesWriterTest.java deleted file mode 100644 index 5f51f4da5c..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/properties/NifiPropertiesWriterTest.java +++ /dev/null @@ -1,77 +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.toolkit.tls.properties; - -import org.apache.nifi.util.NiFiProperties; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.BeforeAll; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.HashSet; -import java.util.Properties; -import java.util.Set; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -public class NifiPropertiesWriterTest { - private static NiFiPropertiesWriterFactory nifiPropertiesWriterFactory; - private NiFiPropertiesWriter niFiPropertiesWriter; - - @BeforeAll - public static void setFactory() throws IOException { - nifiPropertiesWriterFactory = new NiFiPropertiesWriterFactory(); - } - - @BeforeEach - public void setup() throws IOException { - niFiPropertiesWriter = nifiPropertiesWriterFactory.create(); - } - - @Test - public void testCanUpdateAllKeys() throws IllegalAccessException, IOException { - String testValue = NifiPropertiesWriterTest.class.getCanonicalName(); - - // Get all property keys from NiFiProperties and set them to testValue - Set propertyKeys = new HashSet<>(); - for (Field field : NiFiProperties.class.getDeclaredFields()) { - int modifiers = field.getModifiers(); - if (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers) && field.getType() == String.class) { - if (!field.getName().toLowerCase().startsWith("default")) { - String fieldName = (String) field.get(null); - propertyKeys.add(fieldName); - niFiPropertiesWriter.setPropertyValue(fieldName, testValue); - } - } - } - - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - niFiPropertiesWriter.writeNiFiProperties(outputStream); - - // Verify operation worked - Properties properties = new Properties(); - properties.load(new ByteArrayInputStream(outputStream.toByteArray())); - for (String propertyKey : propertyKeys) { - assertEquals(testValue, properties.getProperty(propertyKey)); - } - } -} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/service/TlsCertificateAuthorityTest.java b/nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/service/TlsCertificateAuthorityTest.java deleted file mode 100644 index 8af81c43e7..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/service/TlsCertificateAuthorityTest.java +++ /dev/null @@ -1,282 +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.toolkit.tls.service; - -import com.fasterxml.jackson.databind.ObjectMapper; -import org.apache.nifi.security.util.KeyStoreUtils; -import org.apache.nifi.security.util.KeystoreType; -import org.apache.nifi.toolkit.tls.configuration.TlsClientConfig; -import org.apache.nifi.toolkit.tls.configuration.TlsConfig; -import org.apache.nifi.toolkit.tls.service.client.TlsCertificateAuthorityClient; -import org.apache.nifi.toolkit.tls.service.server.TlsCertificateAuthorityService; -import org.apache.nifi.toolkit.tls.standalone.TlsToolkitStandalone; -import org.apache.nifi.toolkit.tls.util.InputStreamFactory; -import org.apache.nifi.toolkit.tls.util.OutputStreamFactory; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.OutputStream; -import java.nio.charset.StandardCharsets; -import java.security.InvalidKeyException; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.NoSuchProviderException; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.Signature; -import java.security.SignatureException; -import java.security.UnrecoverableEntryException; -import java.security.cert.Certificate; -import java.security.cert.CertificateException; -import java.security.cert.CertificateParsingException; -import java.security.cert.X509Certificate; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.AdditionalMatchers.or; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class TlsCertificateAuthorityTest { - private File serverConfigFile; - private File clientConfigFile; - private OutputStreamFactory outputStreamFactory; - private InputStreamFactory inputStreamFactory; - private TlsConfig serverConfig; - private TlsClientConfig clientConfig; - private ObjectMapper objectMapper; - private ByteArrayOutputStream serverKeyStoreOutputStream; - private ByteArrayOutputStream clientKeyStoreOutputStream; - private ByteArrayOutputStream clientTrustStoreOutputStream; - private ByteArrayOutputStream serverConfigFileOutputStream; - private ByteArrayOutputStream clientConfigFileOutputStream; - private String subjectAlternativeName; - - @BeforeEach - public void setup() throws FileNotFoundException { - objectMapper = new ObjectMapper(); - serverConfigFile = new File("fake.server.config"); - clientConfigFile = new File("fake.client.config"); - String serverKeyStore = "serverKeyStore"; - String clientKeyStore = "clientKeyStore"; - String clientTrustStore = "clientTrustStore"; - serverKeyStoreOutputStream = new ByteArrayOutputStream(); - clientKeyStoreOutputStream = new ByteArrayOutputStream(); - clientTrustStoreOutputStream = new ByteArrayOutputStream(); - serverConfigFileOutputStream = new ByteArrayOutputStream(); - clientConfigFileOutputStream = new ByteArrayOutputStream(); - subjectAlternativeName = "nifi.apache.org"; - - String myTestTokenUseSomethingStronger = "myTestTokenUseSomethingStronger"; - - serverConfig = new TlsConfig(); - serverConfig.setCaHostname("localhost"); - serverConfig.setToken(myTestTokenUseSomethingStronger); - serverConfig.setKeyStore(serverKeyStore); - serverConfig.setDays(5); - serverConfig.setKeySize(2048); - serverConfig.initDefaults(); - - // set port back to 0, so Jetty will allocate a free port - serverConfig.setPort(0); - - clientConfig = new TlsClientConfig(); - clientConfig.setCaHostname("localhost"); - clientConfig.setDn("OU=NIFI,CN=otherHostname"); - clientConfig.setKeyStore(clientKeyStore); - clientConfig.setTrustStore(clientTrustStore); - clientConfig.setToken(myTestTokenUseSomethingStronger); - clientConfig.setDomainAlternativeNames(Collections.singletonList(subjectAlternativeName)); - clientConfig.setKeySize(2048); - clientConfig.initDefaults(); - - outputStreamFactory = mock(OutputStreamFactory.class); - mockReturnOutputStream(outputStreamFactory, new File(serverKeyStore), serverKeyStoreOutputStream); - mockReturnOutputStream(outputStreamFactory, new File(clientKeyStore), clientKeyStoreOutputStream); - mockReturnOutputStream(outputStreamFactory, new File(clientTrustStore), clientTrustStoreOutputStream); - mockReturnOutputStream(outputStreamFactory, serverConfigFile, serverConfigFileOutputStream); - mockReturnOutputStream(outputStreamFactory, clientConfigFile, clientConfigFileOutputStream); - - inputStreamFactory = mock(InputStreamFactory.class); - mockReturnProperties(inputStreamFactory, serverConfigFile, serverConfig); - mockReturnProperties(inputStreamFactory, clientConfigFile, clientConfig); - } - - private void mockReturnProperties(InputStreamFactory inputStreamFactory, File file, TlsConfig tlsConfig) throws FileNotFoundException { - when(inputStreamFactory.create(eq(file))).thenAnswer(invocation -> { - ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); - objectMapper.writeValue(byteArrayOutputStream, tlsConfig); - return new ByteArrayInputStream(byteArrayOutputStream.toByteArray()); - }); - } - - private void mockReturnOutputStream(OutputStreamFactory outputStreamFactory, File file, OutputStream outputStream) throws FileNotFoundException { - when(outputStreamFactory.create(or(eq(file), eq(new File(file.getAbsolutePath()))))).thenReturn(outputStream); - } - - @Test - public void testClientGetCertDifferentPasswordsForKeyAndKeyStore() throws Exception { - TlsCertificateAuthorityService tlsCertificateAuthorityService = null; - try { - tlsCertificateAuthorityService = new TlsCertificateAuthorityService(outputStreamFactory); - tlsCertificateAuthorityService.start(serverConfig, serverConfigFile.getAbsolutePath(), true); - clientConfig.setPort(tlsCertificateAuthorityService.getPort()); - TlsCertificateAuthorityClient tlsCertificateAuthorityClient = new TlsCertificateAuthorityClient(outputStreamFactory); - tlsCertificateAuthorityClient.generateCertificateAndGetItSigned(clientConfig, null, clientConfigFile.getAbsolutePath(), true); - validate(); - } finally { - if (tlsCertificateAuthorityService != null) { - tlsCertificateAuthorityService.shutdown(); - } - } - } - - @Test - public void testClientGetCertSamePasswordsForKeyAndKeyStore() throws Exception { - TlsCertificateAuthorityService tlsCertificateAuthorityService = null; - try { - tlsCertificateAuthorityService = new TlsCertificateAuthorityService(outputStreamFactory); - tlsCertificateAuthorityService.start(serverConfig, serverConfigFile.getAbsolutePath(), false); - clientConfig.setPort(tlsCertificateAuthorityService.getPort()); - TlsCertificateAuthorityClient tlsCertificateAuthorityClient = new TlsCertificateAuthorityClient(outputStreamFactory); - tlsCertificateAuthorityClient.generateCertificateAndGetItSigned(clientConfig, null, clientConfigFile.getAbsolutePath(), false); - validate(); - } finally { - if (tlsCertificateAuthorityService != null) { - tlsCertificateAuthorityService.shutdown(); - } - } - } - - @Test - public void testClientPkcs12() throws Exception { - serverConfig.setKeyStoreType(KeystoreType.PKCS12.toString()); - clientConfig.setKeyStoreType(KeystoreType.PKCS12.toString()); - TlsCertificateAuthorityService tlsCertificateAuthorityService = null; - try { - tlsCertificateAuthorityService = new TlsCertificateAuthorityService(outputStreamFactory); - tlsCertificateAuthorityService.start(serverConfig, serverConfigFile.getAbsolutePath(), false); - clientConfig.setPort(tlsCertificateAuthorityService.getPort()); - TlsCertificateAuthorityClient tlsCertificateAuthorityClient = new TlsCertificateAuthorityClient(outputStreamFactory); - tlsCertificateAuthorityClient.generateCertificateAndGetItSigned(clientConfig, null, clientConfigFile.getAbsolutePath(), true); - validate(); - } finally { - if (tlsCertificateAuthorityService != null) { - tlsCertificateAuthorityService.shutdown(); - } - } - } - - @Test - public void testTokenMismatch() { - serverConfig.setToken("a different token..."); - - assertThrows(IOException.class, () -> testClientGetCertSamePasswordsForKeyAndKeyStore()); - } - - private void validate() throws CertificateException, InvalidKeyException, NoSuchAlgorithmException, KeyStoreException, SignatureException, - NoSuchProviderException, UnrecoverableEntryException, IOException { - Certificate caCertificate = validateServerKeyStore(); - validateClient(caCertificate); - } - - private Certificate validateServerKeyStore() throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException, UnrecoverableEntryException, - InvalidKeyException, NoSuchProviderException, SignatureException { - serverConfig = objectMapper.readValue(new ByteArrayInputStream(serverConfigFileOutputStream.toByteArray()), TlsConfig.class); - - KeyStore serverKeyStore = KeyStoreUtils.getKeyStore(serverConfig.getKeyStoreType()); - serverKeyStore.load(new ByteArrayInputStream(serverKeyStoreOutputStream.toByteArray()), serverConfig.getKeyStorePassword().toCharArray()); - String keyPassword = serverConfig.getKeyPassword(); - KeyStore.Entry serverKeyEntry = serverKeyStore.getEntry(TlsToolkitStandalone.NIFI_KEY, - new KeyStore.PasswordProtection(keyPassword == null ? serverConfig.getKeyStorePassword().toCharArray() : keyPassword.toCharArray())); - - assertTrue(serverKeyEntry instanceof KeyStore.PrivateKeyEntry); - KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) serverKeyEntry; - Certificate[] certificateChain = privateKeyEntry.getCertificateChain(); - assertEquals(1, certificateChain.length); - Certificate caCertificate = certificateChain[0]; - caCertificate.verify(caCertificate.getPublicKey()); - assertPrivateAndPublicKeyMatch(privateKeyEntry.getPrivateKey(), caCertificate.getPublicKey()); - return caCertificate; - } - - private void validateClient(Certificate caCertificate) throws IOException, KeyStoreException, CertificateException, NoSuchAlgorithmException, - UnrecoverableEntryException, InvalidKeyException, NoSuchProviderException, SignatureException { - clientConfig = objectMapper.readValue(new ByteArrayInputStream(clientConfigFileOutputStream.toByteArray()), TlsClientConfig.class); - - KeyStore clientKeyStore = KeyStoreUtils.getKeyStore(clientConfig.getKeyStoreType()); - clientKeyStore.load(new ByteArrayInputStream(clientKeyStoreOutputStream.toByteArray()), clientConfig.getKeyStorePassword().toCharArray()); - String keyPassword = clientConfig.getKeyPassword(); - KeyStore.Entry clientKeyStoreEntry = clientKeyStore.getEntry(TlsToolkitStandalone.NIFI_KEY, - new KeyStore.PasswordProtection(keyPassword == null ? clientConfig.getKeyStorePassword().toCharArray() : keyPassword.toCharArray())); - - assertTrue(clientKeyStoreEntry instanceof KeyStore.PrivateKeyEntry); - KeyStore.PrivateKeyEntry clientPrivateKeyEntry = (KeyStore.PrivateKeyEntry) clientKeyStoreEntry; - Certificate[] certificateChain = clientPrivateKeyEntry.getCertificateChain(); - assertEquals(2, certificateChain.length); - assertEquals(caCertificate, certificateChain[1]); - certificateChain[0].verify(caCertificate.getPublicKey()); - assertPrivateAndPublicKeyMatch(clientPrivateKeyEntry.getPrivateKey(), certificateChain[0].getPublicKey()); - - // Does the certificate contain the SAN we defined in the client config? - assert(isSANPresent(certificateChain[0])); - - KeyStore clientTrustStore = KeyStoreUtils.getKeyStore(KeystoreType.JKS.toString()); - clientTrustStore.load(new ByteArrayInputStream(clientTrustStoreOutputStream.toByteArray()), clientConfig.getTrustStorePassword().toCharArray()); - assertEquals(caCertificate, clientTrustStore.getCertificate(TlsToolkitStandalone.NIFI_CERT)); - } - - public static void assertPrivateAndPublicKeyMatch(PrivateKey privateKey, PublicKey publicKey) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException { - Signature signature = Signature.getInstance(TlsConfig.DEFAULT_SIGNING_ALGORITHM); - signature.initSign(privateKey); - byte[] bytes = "test string".getBytes(StandardCharsets.UTF_8); - signature.update(bytes); - - Signature verify = Signature.getInstance(TlsConfig.DEFAULT_SIGNING_ALGORITHM); - verify.initVerify(publicKey); - verify.update(bytes); - verify.verify(signature.sign()); - } - - private boolean isSANPresent(Certificate cert) { - Iterator> iterator = null; - try { - iterator = ((X509Certificate) cert).getSubjectAlternativeNames().iterator(); - } catch (CertificateParsingException e) { - e.printStackTrace(); - } - boolean containsSAN = false; - while(iterator.hasNext()) { - if(iterator.next().contains(subjectAlternativeName)) { - containsSAN = true; - } - } - return containsSAN; - } -} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/service/client/TlsCertificateAuthorityClientCommandLineTest.java b/nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/service/client/TlsCertificateAuthorityClientCommandLineTest.java deleted file mode 100644 index f8ac6b8f1f..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/service/client/TlsCertificateAuthorityClientCommandLineTest.java +++ /dev/null @@ -1,178 +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.toolkit.tls.service.client; - -import org.apache.nifi.security.util.KeystoreType; -import org.apache.nifi.toolkit.tls.commandLine.CommandLineParseException; -import org.apache.nifi.toolkit.tls.commandLine.ExitCode; -import org.apache.nifi.toolkit.tls.configuration.TlsClientConfig; -import org.apache.nifi.toolkit.tls.configuration.TlsConfig; -import org.apache.nifi.toolkit.tls.service.BaseCertificateAuthorityCommandLine; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import java.io.IOException; -import java.net.InetAddress; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertThrows; - -public class TlsCertificateAuthorityClientCommandLineTest { - - private TlsCertificateAuthorityClientCommandLine tlsCertificateAuthorityClientCommandLine; - private String testToken; - - @BeforeEach - public void setup() { - tlsCertificateAuthorityClientCommandLine = new TlsCertificateAuthorityClientCommandLine(); - testToken = "testToken16bytes"; - } - - @Test - public void testNoToken() { - final CommandLineParseException e = assertThrows(CommandLineParseException.class, () -> tlsCertificateAuthorityClientCommandLine.parse()); - - assertEquals(ExitCode.ERROR_TOKEN_ARG_EMPTY, e.getExitCode()); - } - - @Test - public void testDefaults() throws CommandLineParseException, IOException { - tlsCertificateAuthorityClientCommandLine.parse("-t", testToken); - TlsClientConfig clientConfig = tlsCertificateAuthorityClientCommandLine.createClientConfig(); - - assertEquals(TlsConfig.DEFAULT_HOSTNAME, clientConfig.getCaHostname()); - assertEquals(new TlsConfig().calcDefaultDn(InetAddress.getLocalHost().getHostName()), clientConfig.getDn()); - assertEquals(TlsCertificateAuthorityClientCommandLine.KEYSTORE + TlsConfig.DEFAULT_KEY_STORE_TYPE.toLowerCase(), clientConfig.getKeyStore()); - assertEquals(TlsConfig.DEFAULT_KEY_STORE_TYPE, clientConfig.getKeyStoreType()); - assertNull(clientConfig.getKeyStorePassword()); - assertNull(clientConfig.getKeyPassword()); - assertEquals(TlsCertificateAuthorityClientCommandLine.TRUSTSTORE + TlsConfig.DEFAULT_KEY_STORE_TYPE.toLowerCase(), clientConfig.getTrustStore()); - assertEquals(TlsConfig.DEFAULT_KEY_STORE_TYPE, clientConfig.getTrustStoreType()); - assertNull(clientConfig.getTrustStorePassword()); - assertEquals(TlsConfig.DEFAULT_KEY_SIZE, clientConfig.getKeySize()); - assertEquals(TlsConfig.DEFAULT_KEY_PAIR_ALGORITHM, clientConfig.getKeyPairAlgorithm()); - assertEquals(testToken, clientConfig.getToken()); - assertEquals(TlsConfig.DEFAULT_PORT, clientConfig.getPort()); - assertEquals(TlsCertificateAuthorityClientCommandLine.DEFAULT_CONFIG_JSON, tlsCertificateAuthorityClientCommandLine.getConfigJsonOut()); - assertNull(tlsCertificateAuthorityClientCommandLine.getConfigJsonIn()); - assertEquals(TlsCertificateAuthorityClientCommandLine.DEFAULT_CERTIFICATE_DIRECTORY, tlsCertificateAuthorityClientCommandLine.getCertificateDirectory()); - } - - @Test - public void testKeySize() throws CommandLineParseException { - int keySize = 1234; - tlsCertificateAuthorityClientCommandLine.parse("-t", testToken, "-k", Integer.toString(keySize)); - assertEquals(keySize, tlsCertificateAuthorityClientCommandLine.getKeySize()); - } - - @Test - public void testKeyPairAlgorithm() throws CommandLineParseException { - String testAlgorithm = "testAlgorithm"; - tlsCertificateAuthorityClientCommandLine.parse("-t", testToken, "-a", testAlgorithm); - assertEquals(testAlgorithm, tlsCertificateAuthorityClientCommandLine.getKeyAlgorithm()); - } - - @Test - public void testHelp() { - final CommandLineParseException e = assertThrows(CommandLineParseException.class, () -> tlsCertificateAuthorityClientCommandLine.parse("-h")); - - assertEquals(ExitCode.HELP, e.getExitCode()); - } - - @Test - public void testCaHostname() throws CommandLineParseException, IOException { - String testCaHostname = "testCaHostname"; - tlsCertificateAuthorityClientCommandLine.parse("-t", testToken, "-c", testCaHostname); - assertEquals(testCaHostname, tlsCertificateAuthorityClientCommandLine.createClientConfig().getCaHostname()); - } - - @Test - public void testDn() throws CommandLineParseException, IOException { - String testDn = "testDn"; - tlsCertificateAuthorityClientCommandLine.parse("-t", testToken, "-D", testDn); - assertEquals(testDn, tlsCertificateAuthorityClientCommandLine.createClientConfig().getDn()); - } - - @Test - public void testPort() throws CommandLineParseException, IOException { - int testPort = 2345; - tlsCertificateAuthorityClientCommandLine.parse("-t", testToken, "-p", Integer.toString(testPort)); - assertEquals(testPort, tlsCertificateAuthorityClientCommandLine.createClientConfig().getPort()); - } - - @Test - public void testKeyStoreType() throws CommandLineParseException, IOException { - String testType = "testType"; - tlsCertificateAuthorityClientCommandLine.parse("-t", testToken, "-T", testType); - - TlsClientConfig clientConfig = tlsCertificateAuthorityClientCommandLine.createClientConfig(); - assertEquals(testType, clientConfig.getKeyStoreType()); - String trustStoreType = KeystoreType.JKS.toString().toLowerCase(); - assertEquals(trustStoreType, clientConfig.getTrustStoreType()); - assertEquals(TlsCertificateAuthorityClientCommandLine.KEYSTORE + testType.toLowerCase(), clientConfig.getKeyStore()); - assertEquals(TlsCertificateAuthorityClientCommandLine.TRUSTSTORE + trustStoreType, clientConfig.getTrustStore()); - } - - @Test - public void testConfigJsonOut() throws CommandLineParseException { - String testPath = "/1/2/3/4"; - tlsCertificateAuthorityClientCommandLine.parse("-t", testToken, "-f", testPath); - assertEquals(testPath, tlsCertificateAuthorityClientCommandLine.getConfigJsonOut()); - assertNull(tlsCertificateAuthorityClientCommandLine.getConfigJsonIn()); - } - - @Test - public void testConfigJsonOutAndUseForBoth() throws CommandLineParseException { - String testPath = "/1/2/3/4"; - tlsCertificateAuthorityClientCommandLine.parse("-t", testToken, "-f", testPath, "-F"); - assertEquals(testPath, tlsCertificateAuthorityClientCommandLine.getConfigJsonOut()); - assertEquals(testPath, tlsCertificateAuthorityClientCommandLine.getConfigJsonIn()); - } - - @Test - public void testConfigJsonIn() throws CommandLineParseException { - String testPath = "/1/2/3/4"; - tlsCertificateAuthorityClientCommandLine.parse("-t", testToken, "--" + BaseCertificateAuthorityCommandLine.READ_CONFIG_JSON_ARG, testPath); - assertEquals(BaseCertificateAuthorityCommandLine.DEFAULT_CONFIG_JSON, tlsCertificateAuthorityClientCommandLine.getConfigJsonOut()); - assertEquals(testPath, tlsCertificateAuthorityClientCommandLine.getConfigJsonIn()); - } - - @Test - public void testConfigJsonInAndOut() throws CommandLineParseException { - String testPath = "/1/2/3/4"; - String testIn = "/2/3/4/5"; - tlsCertificateAuthorityClientCommandLine.parse("-t", testToken, "-f", testPath, "--" + BaseCertificateAuthorityCommandLine.READ_CONFIG_JSON_ARG, testIn); - assertEquals(testPath, tlsCertificateAuthorityClientCommandLine.getConfigJsonOut()); - assertEquals(testIn, tlsCertificateAuthorityClientCommandLine.getConfigJsonIn()); - } - - @Test - public void testCertificateFile() throws CommandLineParseException { - String testCertificateFile = "testCertificateFile"; - tlsCertificateAuthorityClientCommandLine.parse("-t", testToken, "-C", testCertificateFile); - assertEquals(testCertificateFile, tlsCertificateAuthorityClientCommandLine.getCertificateDirectory()); - } - - @Test - public void testConfigClientSAN() throws CommandLineParseException { - tlsCertificateAuthorityClientCommandLine.parse("-t", testToken, "--" + TlsCertificateAuthorityClientCommandLine.SUBJECT_ALTERNATIVE_NAMES, "nifi.apache.org,minifi.apache.org"); - assertEquals("nifi.apache.org", tlsCertificateAuthorityClientCommandLine.getDomainAlternativeNames().get(0)); - assertEquals("minifi.apache.org", tlsCertificateAuthorityClientCommandLine.getDomainAlternativeNames().get(1)); - } -} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/service/client/TlsCertificateSigningRequestPerformerTest.java b/nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/service/client/TlsCertificateSigningRequestPerformerTest.java deleted file mode 100644 index c66b19c2eb..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/service/client/TlsCertificateSigningRequestPerformerTest.java +++ /dev/null @@ -1,218 +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.toolkit.tls.service.client; - -import com.fasterxml.jackson.databind.ObjectMapper; -import org.apache.http.HttpHost; -import org.apache.http.StatusLine; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.ByteArrayEntity; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClientBuilder; -import org.apache.nifi.security.cert.builder.StandardCertificateBuilder; -import org.apache.nifi.toolkit.tls.configuration.TlsClientConfig; -import org.apache.nifi.toolkit.tls.configuration.TlsConfig; -import org.apache.nifi.toolkit.tls.service.dto.TlsCertificateAuthorityRequest; -import org.apache.nifi.toolkit.tls.service.dto.TlsCertificateAuthorityResponse; -import org.apache.nifi.toolkit.tls.util.TlsHelper; -import org.bouncycastle.operator.OperatorCreationException; -import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest; -import org.eclipse.jetty.server.Response; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.Spy; -import org.mockito.junit.jupiter.MockitoExtension; - -import javax.security.auth.x500.X500Principal; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.lang.reflect.Field; -import java.nio.charset.StandardCharsets; -import java.security.GeneralSecurityException; -import java.security.KeyPair; -import java.security.cert.X509Certificate; -import java.time.Duration; -import java.util.ArrayList; -import java.util.List; -import java.util.function.Supplier; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -@ExtendWith(MockitoExtension.class) -public class TlsCertificateSigningRequestPerformerTest { - @Mock - Supplier httpClientBuilderSupplier; - - @Spy - HttpClientBuilder httpClientBuilder; - - @Mock - CloseableHttpClient closeableHttpClient; - - @Mock - TlsClientConfig tlsClientConfig; - - X509Certificate caCertificate; - - X509Certificate signedCsr; - - ObjectMapper objectMapper; - KeyPair keyPair; - TlsCertificateSigningRequestPerformer tlsCertificateSigningRequestPerformer; - String testToken; - String testCaHostname; - int testPort; - List certificates; - - TlsCertificateAuthorityResponse tlsCertificateAuthorityResponse; - int statusCode; - private byte[] testHmac; - private String testSignedCsr; - - @BeforeEach - public void setup() throws GeneralSecurityException, OperatorCreationException, IOException { - objectMapper = new ObjectMapper(); - keyPair = TlsHelper.generateKeyPair(TlsConfig.DEFAULT_KEY_PAIR_ALGORITHM, TlsConfig.DEFAULT_KEY_SIZE); - - testToken = "testTokenTestToken"; - testCaHostname = "testCaHostname"; - testPort = 8993; - certificates = new ArrayList<>(); - - when(tlsClientConfig.getToken()).thenReturn(testToken); - when(tlsClientConfig.getCaHostname()).thenReturn(testCaHostname); - when(tlsClientConfig.getDn()).thenReturn(new TlsConfig().calcDefaultDn(testCaHostname)); - when(tlsClientConfig.getPort()).thenReturn(testPort); - when(tlsClientConfig.getSigningAlgorithm()).thenReturn(TlsConfig.DEFAULT_SIGNING_ALGORITHM); - JcaPKCS10CertificationRequest jcaPKCS10CertificationRequest = TlsHelper.generateCertificationRequest(tlsClientConfig.getDn(), null, keyPair, TlsConfig.DEFAULT_SIGNING_ALGORITHM); - String testCsrPem = TlsHelper.pemEncodeJcaObject(jcaPKCS10CertificationRequest); - when(httpClientBuilderSupplier.get()).thenReturn(httpClientBuilder); - when(httpClientBuilder.build()).thenAnswer(invocation -> { - Field sslSocketFactory = HttpClientBuilder.class.getDeclaredField("sslSocketFactory"); - sslSocketFactory.setAccessible(true); - Object o = sslSocketFactory.get(httpClientBuilder); - if( o != null) { - Field field = TlsCertificateAuthorityClientSocketFactory.class.getDeclaredField("certificates"); - field.setAccessible(true); - ((List) field.get(o)).addAll(certificates); - } - return closeableHttpClient; - }); - StatusLine statusLine = mock(StatusLine.class); - when(statusLine.getStatusCode()).thenAnswer(i -> statusCode); - when(closeableHttpClient.execute(eq(new HttpHost(testCaHostname, testPort, "https")), any(HttpPost.class))).thenAnswer(invocation -> { - HttpPost httpPost = (HttpPost) invocation.getArguments()[1]; - TlsCertificateAuthorityRequest tlsCertificateAuthorityRequest = objectMapper.readValue(httpPost.getEntity().getContent(), TlsCertificateAuthorityRequest.class); - assertEquals(tlsCertificateAuthorityRequest.getCsr(), testCsrPem); - CloseableHttpResponse closeableHttpResponse = mock(CloseableHttpResponse.class); - when(closeableHttpResponse.getEntity()).thenAnswer(i -> { - ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); - objectMapper.writeValue(byteArrayOutputStream, tlsCertificateAuthorityResponse); - return new ByteArrayEntity(byteArrayOutputStream.toByteArray()); - }); - when(closeableHttpResponse.getStatusLine()).thenReturn(statusLine); - return closeableHttpResponse; - }); - KeyPair caKeyPair = TlsHelper.generateKeyPair(TlsConfig.DEFAULT_KEY_PAIR_ALGORITHM, TlsConfig.DEFAULT_KEY_SIZE); - caCertificate = new StandardCertificateBuilder(caKeyPair, new X500Principal("CN=fakeCa"), Duration.ofDays(TlsConfig.DEFAULT_DAYS)).build(); - testHmac = TlsHelper.calculateHMac(testToken, caCertificate.getPublicKey()); - signedCsr = new StandardCertificateBuilder(caKeyPair, caCertificate.getIssuerX500Principal(), Duration.ofDays(TlsConfig.DEFAULT_DAYS)) - .setSubject(new X500Principal(jcaPKCS10CertificationRequest.getSubject().toString())) - .setSubjectPublicKey(jcaPKCS10CertificationRequest.getPublicKey()) - .build(); - testSignedCsr = TlsHelper.pemEncodeJcaObject(signedCsr); - - tlsCertificateSigningRequestPerformer = new TlsCertificateSigningRequestPerformer(httpClientBuilderSupplier, tlsClientConfig); - } - - @Test - public void testOk() throws Exception { - certificates.add(caCertificate); - statusCode = Response.SC_OK; - tlsCertificateAuthorityResponse = new TlsCertificateAuthorityResponse(testHmac, testSignedCsr); - tlsCertificateSigningRequestPerformer.perform(keyPair); - } - - @Test - public void testBadStatusCode() { - statusCode = Response.SC_FORBIDDEN; - tlsCertificateAuthorityResponse = new TlsCertificateAuthorityResponse(); - - final IOException e = assertThrows(IOException.class, () -> tlsCertificateSigningRequestPerformer.perform(keyPair)); - assertTrue(e.getMessage().startsWith(TlsCertificateSigningRequestPerformer.RECEIVED_RESPONSE_CODE + statusCode)); - } - - @Test - public void test0CertSize() { - statusCode = Response.SC_OK; - tlsCertificateAuthorityResponse = new TlsCertificateAuthorityResponse(); - - final IOException e = assertThrows(IOException.class, () -> tlsCertificateSigningRequestPerformer.perform(keyPair)); - assertEquals(TlsCertificateSigningRequestPerformer.EXPECTED_ONE_CERTIFICATE, e.getMessage()); - } - - @Test - public void test2CertSize() { - certificates.add(caCertificate); - certificates.add(caCertificate); - statusCode = Response.SC_OK; - tlsCertificateAuthorityResponse = new TlsCertificateAuthorityResponse(); - - final IOException e = assertThrows(IOException.class, () -> tlsCertificateSigningRequestPerformer.perform(keyPair)); - assertEquals(TlsCertificateSigningRequestPerformer.EXPECTED_ONE_CERTIFICATE, e.getMessage()); - } - - @Test - public void testNoHmac() { - certificates.add(caCertificate); - statusCode = Response.SC_OK; - tlsCertificateAuthorityResponse = new TlsCertificateAuthorityResponse(null, testSignedCsr); - - final IOException e = assertThrows(IOException.class, () -> tlsCertificateSigningRequestPerformer.perform(keyPair)); - assertEquals(TlsCertificateSigningRequestPerformer.EXPECTED_RESPONSE_TO_CONTAIN_HMAC, e.getMessage()); - } - - @Test - public void testBadHmac() { - certificates.add(caCertificate); - statusCode = Response.SC_OK; - tlsCertificateAuthorityResponse = new TlsCertificateAuthorityResponse("badHmac".getBytes(StandardCharsets.UTF_8), testSignedCsr); - - final IOException e = assertThrows(IOException.class, () -> tlsCertificateSigningRequestPerformer.perform(keyPair)); - assertEquals(TlsCertificateSigningRequestPerformer.UNEXPECTED_HMAC_RECEIVED_POSSIBLE_MAN_IN_THE_MIDDLE, e.getMessage()); - } - - @Test - public void testNoCertificate() { - certificates.add(caCertificate); - statusCode = Response.SC_OK; - tlsCertificateAuthorityResponse = new TlsCertificateAuthorityResponse(testHmac, null); - - final IOException e = assertThrows(IOException.class, () -> tlsCertificateSigningRequestPerformer.perform(keyPair)); - assertEquals(TlsCertificateSigningRequestPerformer.EXPECTED_RESPONSE_TO_CONTAIN_CERTIFICATE, e.getMessage()); - } -} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/service/server/TlsCertificateAuthorityServiceCommandLineTest.java b/nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/service/server/TlsCertificateAuthorityServiceCommandLineTest.java deleted file mode 100644 index 9102f1757f..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/service/server/TlsCertificateAuthorityServiceCommandLineTest.java +++ /dev/null @@ -1,152 +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.toolkit.tls.service.server; - -import org.apache.nifi.toolkit.tls.commandLine.CommandLineParseException; -import org.apache.nifi.toolkit.tls.configuration.TlsConfig; -import org.apache.nifi.toolkit.tls.service.BaseCertificateAuthorityCommandLine; -import org.apache.nifi.toolkit.tls.util.InputStreamFactory; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -import java.io.IOException; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; - -@ExtendWith(MockitoExtension.class) -public class TlsCertificateAuthorityServiceCommandLineTest { - @Mock - InputStreamFactory inputStreamFactory; - - TlsCertificateAuthorityServiceCommandLine tlsCertificateAuthorityServiceCommandLine; - - String testToken; - - @BeforeEach - public void setup() { - tlsCertificateAuthorityServiceCommandLine = new TlsCertificateAuthorityServiceCommandLine(inputStreamFactory); - testToken = "testToken16bytes"; - } - - @Test - public void testDefaults() throws CommandLineParseException, IOException { - tlsCertificateAuthorityServiceCommandLine.parse("-t", testToken); - assertEquals(BaseCertificateAuthorityCommandLine.DEFAULT_CONFIG_JSON, tlsCertificateAuthorityServiceCommandLine.getConfigJsonOut()); - assertNull(tlsCertificateAuthorityServiceCommandLine.getConfigJsonIn()); - TlsConfig tlsConfig = tlsCertificateAuthorityServiceCommandLine.createConfig(); - assertEquals(TlsConfig.DEFAULT_HOSTNAME, tlsConfig.getCaHostname()); - assertEquals(testToken, tlsConfig.getToken()); - assertEquals(TlsConfig.DEFAULT_PORT, tlsConfig.getPort()); - assertEquals(TlsConfig.DEFAULT_KEY_STORE_TYPE, tlsConfig.getKeyStoreType()); - assertEquals(TlsCertificateAuthorityServiceCommandLine.NIFI_CA_KEYSTORE + tlsConfig.getKeyStoreType().toLowerCase(), tlsConfig.getKeyStore()); - assertNull(tlsConfig.getKeyStorePassword()); - assertNull(tlsConfig.getKeyPassword()); - assertEquals(TlsConfig.DEFAULT_KEY_SIZE, tlsConfig.getKeySize()); - assertEquals(TlsConfig.DEFAULT_KEY_PAIR_ALGORITHM, tlsConfig.getKeyPairAlgorithm()); - assertEquals(TlsConfig.DEFAULT_SIGNING_ALGORITHM, tlsConfig.getSigningAlgorithm()); - assertEquals(TlsConfig.DEFAULT_DAYS, tlsConfig.getDays()); - } - - @Test - public void testCaHostname() throws CommandLineParseException, IOException { - String testCaHostname = "testCaHostname"; - tlsCertificateAuthorityServiceCommandLine.parse("-t", testToken, "-c", testCaHostname); - assertEquals(testCaHostname, tlsCertificateAuthorityServiceCommandLine.createConfig().getCaHostname()); - } - - @Test - public void testPort() throws CommandLineParseException, IOException { - int testPort = 4321; - tlsCertificateAuthorityServiceCommandLine.parse("-t", testToken, "-p", Integer.toString(testPort)); - assertEquals(testPort, tlsCertificateAuthorityServiceCommandLine.createConfig().getPort()); - } - - @Test - public void testKeyStoreType() throws CommandLineParseException, IOException { - String testKeyStoreType = "testKeyStoreType"; - tlsCertificateAuthorityServiceCommandLine.parse("-t", testToken, "-T", testKeyStoreType); - TlsConfig tlsConfig = tlsCertificateAuthorityServiceCommandLine.createConfig(); - assertEquals(testKeyStoreType, tlsConfig.getKeyStoreType()); - assertEquals(TlsCertificateAuthorityServiceCommandLine.NIFI_CA_KEYSTORE + tlsConfig.getKeyStoreType().toLowerCase(), tlsConfig.getKeyStore()); - } - - @Test - public void testKeySize() throws CommandLineParseException, IOException { - int testKeySize = 8192; - tlsCertificateAuthorityServiceCommandLine.parse("-t", testToken, "-k", Integer.toString(testKeySize)); - assertEquals(testKeySize, tlsCertificateAuthorityServiceCommandLine.createConfig().getKeySize()); - } - - @Test - public void testKeyPairAlgorithm() throws CommandLineParseException, IOException { - String testAlgorithm = "testAlgorithm"; - tlsCertificateAuthorityServiceCommandLine.parse("-t", testToken, "-a", testAlgorithm); - assertEquals(testAlgorithm, tlsCertificateAuthorityServiceCommandLine.createConfig().getKeyPairAlgorithm()); - } - - @Test - public void testSigningAlgorithm() throws CommandLineParseException, IOException { - String testSigningAlgorithm = "testSigningAlgorithm"; - tlsCertificateAuthorityServiceCommandLine.parse("-t", testToken, "-s", testSigningAlgorithm); - assertEquals(testSigningAlgorithm, tlsCertificateAuthorityServiceCommandLine.createConfig().getSigningAlgorithm()); - } - - @Test - public void testDays() throws CommandLineParseException, IOException { - int days = 1234; - tlsCertificateAuthorityServiceCommandLine.parse("-t", testToken, "-d", Integer.toString(days)); - assertEquals(days, tlsCertificateAuthorityServiceCommandLine.createConfig().getDays()); - } - - @Test - public void testConfigJsonOut() throws CommandLineParseException { - String out = "testJson.out"; - tlsCertificateAuthorityServiceCommandLine.parse("-t", testToken, "-f", out); - assertEquals(out, tlsCertificateAuthorityServiceCommandLine.getConfigJsonOut()); - assertNull(tlsCertificateAuthorityServiceCommandLine.getConfigJsonIn()); - } - - @Test - public void testConfigJsonOutAndUseForBoth() throws CommandLineParseException { - String out = "testJson.out"; - tlsCertificateAuthorityServiceCommandLine.parse("-t", testToken, "-f", out, "-F"); - assertEquals(out, tlsCertificateAuthorityServiceCommandLine.getConfigJsonOut()); - assertEquals(out, tlsCertificateAuthorityServiceCommandLine.getConfigJsonIn()); - } - - @Test - public void testConfigJsonIn() throws CommandLineParseException { - String in = "testJson.in"; - tlsCertificateAuthorityServiceCommandLine.parse("-t", testToken, "--" + BaseCertificateAuthorityCommandLine.READ_CONFIG_JSON_ARG, in); - assertEquals(BaseCertificateAuthorityCommandLine.DEFAULT_CONFIG_JSON, tlsCertificateAuthorityServiceCommandLine.getConfigJsonOut()); - assertEquals(in, tlsCertificateAuthorityServiceCommandLine.getConfigJsonIn()); - } - - @Test - public void testConfigJsonInAndOut() throws CommandLineParseException { - String out = "testJson.out"; - String in = "testJson.in"; - tlsCertificateAuthorityServiceCommandLine.parse("-t", testToken, "-f", out, "--" + BaseCertificateAuthorityCommandLine.READ_CONFIG_JSON_ARG, in); - assertEquals(out, tlsCertificateAuthorityServiceCommandLine.getConfigJsonOut()); - assertEquals(in, tlsCertificateAuthorityServiceCommandLine.getConfigJsonIn()); - } -} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/service/server/TlsCertificateAuthorityServiceHandlerTest.java b/nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/service/server/TlsCertificateAuthorityServiceHandlerTest.java deleted file mode 100644 index accca70228..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/service/server/TlsCertificateAuthorityServiceHandlerTest.java +++ /dev/null @@ -1,203 +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.toolkit.tls.service.server; - -import com.fasterxml.jackson.databind.ObjectMapper; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.PrintWriter; -import java.io.StringReader; -import java.io.StringWriter; -import java.nio.charset.StandardCharsets; -import java.security.GeneralSecurityException; -import java.security.KeyPair; -import java.security.KeyPairGenerator; -import java.security.cert.X509Certificate; -import java.time.Duration; -import java.util.Arrays; -import java.util.List; -import javax.security.auth.x500.X500Principal; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.apache.nifi.security.cert.builder.StandardCertificateBuilder; -import org.apache.nifi.toolkit.tls.configuration.TlsConfig; -import org.apache.nifi.toolkit.tls.service.dto.TlsCertificateAuthorityRequest; -import org.apache.nifi.toolkit.tls.service.dto.TlsCertificateAuthorityResponse; -import org.apache.nifi.toolkit.tls.util.TlsHelper; -import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; -import org.bouncycastle.asn1.x500.X500Name; -import org.bouncycastle.asn1.x509.Extension; -import org.bouncycastle.asn1.x509.Extensions; -import org.bouncycastle.operator.OperatorCreationException; -import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; -import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest; -import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder; -import org.eclipse.jetty.server.Request; -import org.eclipse.jetty.server.Response; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertArrayEquals; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class TlsCertificateAuthorityServiceHandlerTest { - X509Certificate caCert; - - private final Request baseRequest = mock(Request.class); - private final HttpServletRequest httpServletRequest = mock(HttpServletRequest.class); - private final HttpServletResponse httpServletResponse = mock(HttpServletResponse.class); - - JcaPKCS10CertificationRequest jcaPKCS10CertificationRequest; - - KeyPair keyPair; - - String testToken; - - String testPemEncodedCsr; - - String testPemEncodedSignedCertificate; - - ObjectMapper objectMapper; - - TlsCertificateAuthorityServiceHandler tlsCertificateAuthorityServiceHandler; - - TlsCertificateAuthorityRequest tlsCertificateAuthorityRequest; - - int statusCode; - - StringWriter response; - private byte[] testCaHmac; - private byte[] testHmac; - private String requestedDn; - private KeyPair certificateKeyPair; - - private static final String SUBJECT_DN = "CN=NiFi Test Server,OU=Security,O=Apache,ST=CA,C=US"; - private static final List SUBJECT_ALT_NAMES = Arrays.asList("127.0.0.1", "nifi.nifi.apache.org"); - - @BeforeEach - public void setup() throws Exception { - testToken = "testTokenTestToken"; - testPemEncodedSignedCertificate = "testPemEncodedSignedCertificate"; - keyPair = TlsHelper.generateKeyPair(TlsConfig.DEFAULT_KEY_PAIR_ALGORITHM, TlsConfig.DEFAULT_KEY_SIZE); - objectMapper = new ObjectMapper(); - when(httpServletRequest.getReader()).thenAnswer(invocation -> { - StringWriter stringWriter = new StringWriter(); - objectMapper.writeValue(stringWriter, tlsCertificateAuthorityRequest); - return new BufferedReader(new StringReader(stringWriter.toString())); - }); - doAnswer(invocation -> statusCode = (int) invocation.getArguments()[0]).when(httpServletResponse).setStatus(anyInt()); - when(httpServletResponse.getWriter()).thenAnswer(invocation -> { - response = new StringWriter(); - return new PrintWriter(response); - }); - caCert = new StandardCertificateBuilder(keyPair, new X500Principal("CN=fakeCa"), Duration.ofDays(TlsConfig.DEFAULT_DAYS)).build(); - requestedDn = new TlsConfig().calcDefaultDn(TlsConfig.DEFAULT_HOSTNAME); - certificateKeyPair = TlsHelper.generateKeyPair(TlsConfig.DEFAULT_KEY_PAIR_ALGORITHM, TlsConfig.DEFAULT_KEY_SIZE); - jcaPKCS10CertificationRequest = TlsHelper.generateCertificationRequest(requestedDn, null, certificateKeyPair, TlsConfig.DEFAULT_SIGNING_ALGORITHM); - testPemEncodedCsr = TlsHelper.pemEncodeJcaObject(jcaPKCS10CertificationRequest); - tlsCertificateAuthorityServiceHandler = new TlsCertificateAuthorityServiceHandler(TlsConfig.DEFAULT_SIGNING_ALGORITHM, TlsConfig.DEFAULT_DAYS, testToken, caCert, keyPair, objectMapper); - testHmac = TlsHelper.calculateHMac(testToken, jcaPKCS10CertificationRequest.getPublicKey()); - testCaHmac = TlsHelper.calculateHMac(testToken, caCert.getPublicKey()); - } - - private TlsCertificateAuthorityResponse getResponse() throws IOException { - return objectMapper.readValue(new StringReader(response.toString()), TlsCertificateAuthorityResponse.class); - } - - @Test - public void testSuccess() throws IOException, ServletException, GeneralSecurityException { - tlsCertificateAuthorityRequest = new TlsCertificateAuthorityRequest(testHmac, testPemEncodedCsr); - tlsCertificateAuthorityServiceHandler.handle(null, baseRequest, httpServletRequest, httpServletResponse); - assertEquals(Response.SC_OK, statusCode); - assertArrayEquals(testCaHmac, getResponse().getHmac()); - X509Certificate certificate = TlsHelper.parseCertificate(new StringReader(getResponse().getPemEncodedCertificate())); - assertEquals(certificateKeyPair.getPublic(), certificate.getPublicKey()); - assertEquals(new X500Name(requestedDn), new X500Name(certificate.getSubjectX500Principal().toString())); - certificate.verify(caCert.getPublicKey()); - } - - @Test - public void testNoCsr() throws IOException, ServletException { - tlsCertificateAuthorityRequest = new TlsCertificateAuthorityRequest(testHmac, null); - tlsCertificateAuthorityServiceHandler.handle(null, baseRequest, httpServletRequest, httpServletResponse); - assertEquals(Response.SC_BAD_REQUEST, statusCode); - assertEquals(TlsCertificateAuthorityServiceHandler.CSR_FIELD_MUST_BE_SET, getResponse().getError()); - } - - @Test - public void testNoHmac() throws IOException, ServletException { - tlsCertificateAuthorityRequest = new TlsCertificateAuthorityRequest(null, testPemEncodedCsr); - tlsCertificateAuthorityServiceHandler.handle(null, baseRequest, httpServletRequest, httpServletResponse); - assertEquals(Response.SC_BAD_REQUEST, statusCode); - assertEquals(TlsCertificateAuthorityServiceHandler.HMAC_FIELD_MUST_BE_SET, getResponse().getError()); - } - - @Test - public void testForbidden() throws IOException, ServletException { - tlsCertificateAuthorityRequest = new TlsCertificateAuthorityRequest("badHmac".getBytes(StandardCharsets.UTF_8), testPemEncodedCsr); - tlsCertificateAuthorityServiceHandler.handle(null, baseRequest, httpServletRequest, httpServletResponse); - assertEquals(Response.SC_FORBIDDEN, statusCode); - assertEquals(TlsCertificateAuthorityServiceHandler.FORBIDDEN, getResponse().getError()); - } - - @Test - public void testServletException() { - assertThrows(ServletException.class, () -> tlsCertificateAuthorityServiceHandler.handle(null, baseRequest, httpServletRequest, httpServletResponse)); - } - - @Test - public void testSANAgainUsingCertificationRequestMethod() throws GeneralSecurityException, IOException, OperatorCreationException { - KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA"); - KeyPair keyPair = generator.generateKeyPair(); - Extensions exts = TlsHelper.createDomainAlternativeNamesExtensions(SUBJECT_ALT_NAMES, SUBJECT_DN); - String token = "someTokenData16B"; - - JcaPKCS10CertificationRequestBuilder jcaPKCS10CertificationRequestBuilder = new JcaPKCS10CertificationRequestBuilder(new X500Name(SUBJECT_DN), keyPair.getPublic()); - jcaPKCS10CertificationRequestBuilder.addAttribute(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest, exts); - JcaContentSignerBuilder jcaContentSignerBuilder = new JcaContentSignerBuilder("SHA256WITHRSA"); - JcaPKCS10CertificationRequest jcaPKCS10CertificationRequest = new JcaPKCS10CertificationRequest( - jcaPKCS10CertificationRequestBuilder.build(jcaContentSignerBuilder.build(keyPair.getPrivate()))); - TlsCertificateAuthorityRequest tlsCertificateAuthorityRequest = new TlsCertificateAuthorityRequest( - TlsHelper.calculateHMac(token, jcaPKCS10CertificationRequest.getPublicKey()), TlsHelper.pemEncodeJcaObject(jcaPKCS10CertificationRequest)); - - JcaPKCS10CertificationRequest jcaPKCS10CertificationDecoded = TlsHelper.parseCsr(tlsCertificateAuthorityRequest.getCsr()); - - Extensions extensions = jcaPKCS10CertificationDecoded.getRequestedExtensions(); - // Satisfy @After requirement - baseRequest.setHandled(true); - - assertNotNull(extensions, "The extensions parsed from the CSR were found to be null when they should have been present."); - assertNotNull(extensions.getExtension(Extension.subjectAlternativeName), "The Subject Alternate Name parsed from the CSR was found to be null when it should have been present."); - assertTrue(extensions.equivalent(exts)); - } - - @AfterEach - public void verifyHandled() { - verify(baseRequest).setHandled(true); - } -} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/util/PasswordUtilTest.java b/nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/util/PasswordUtilTest.java deleted file mode 100644 index 073b1ce4c3..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/util/PasswordUtilTest.java +++ /dev/null @@ -1,44 +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.toolkit.tls.util; - -import org.junit.jupiter.api.Test; - -import java.security.SecureRandom; -import java.util.function.Supplier; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - -public class PasswordUtilTest { - @Test - public void testGeneratePassword() { - SecureRandom secureRandom = new SecureRandom(); - PasswordUtil passwordUtil = new PasswordUtil(secureRandom); - String generated = passwordUtil.generatePassword(); - assertEquals(43, generated.length()); - } - - @Test - public void testPasswordExhausted() { - Supplier supplier = PasswordUtil.passwordSupplier("exhausted", new String[]{"a", "b"}); - supplier.get(); - supplier.get(); - assertThrows(PasswordsExhaustedException.class, supplier::get); - } -} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/util/TlsHelperTest.java b/nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/util/TlsHelperTest.java deleted file mode 100644 index 285f7775e0..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/util/TlsHelperTest.java +++ /dev/null @@ -1,376 +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.toolkit.tls.util; - -import org.apache.nifi.security.cert.builder.StandardCertificateBuilder; -import org.apache.nifi.toolkit.tls.configuration.TlsConfig; -import org.apache.nifi.util.file.FileUtils; -import org.bouncycastle.asn1.pkcs.Attribute; -import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; -import org.bouncycastle.asn1.x509.Extension; -import org.bouncycastle.asn1.x509.Extensions; -import org.bouncycastle.asn1.x509.GeneralName; -import org.bouncycastle.asn1.x509.GeneralNames; -import org.bouncycastle.cert.X509CertificateHolder; -import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; -import org.bouncycastle.openssl.PEMKeyPair; -import org.bouncycastle.openssl.PEMParser; -import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest; -import org.bouncycastle.util.IPAddress; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.junit.jupiter.api.io.TempDir; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -import javax.security.auth.x500.X500Principal; -import java.io.BufferedReader; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.Reader; -import java.security.GeneralSecurityException; -import java.security.Key; -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.PublicKey; -import java.security.UnrecoverableKeyException; -import java.security.cert.Certificate; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; -import java.time.Duration; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; - -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.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; -import static org.mockito.Mockito.when; - -@ExtendWith(MockitoExtension.class) -public class TlsHelperTest { - private static final String PASSWORD = "changeit"; - private static X509Certificate rootCert; - private int days; - private int keySize; - private String keyPairAlgorithm; - - public static X509Certificate loadCertificate(final Reader reader) throws IOException, CertificateException { - try (PEMParser pemParser = new PEMParser(reader)) { - Object object = pemParser.readObject(); - assertEquals(X509CertificateHolder.class, object.getClass()); - return new JcaX509CertificateConverter().getCertificate((X509CertificateHolder) object); - } - } - - public static X509Certificate loadCertificate(final File file) throws IOException, CertificateException { - try (FileReader fileReader = new FileReader(file)) { - return loadCertificate(fileReader); - } - } - - @BeforeAll - static void setUpBeforeAll() throws Exception { - rootCert = TlsHelper.parseCertificate(new FileReader("src/test/resources/rootCert.crt")); - } - - @BeforeEach - public void setup() throws Exception { - days = 360; - keySize = 2048; - keyPairAlgorithm = "RSA"; - } - - private Date inFuture(int days) { - return new Date(System.currentTimeMillis() + TimeUnit.DAYS.toMillis(days)); - } - - @Test - public void testTokenLengthInCalculateHmac() throws GeneralSecurityException { - List badTokens = Arrays.asList(null, "", "123"); - List goodTokens = Arrays.asList("0123456789abcdefghijklm", "0123456789abcdef"); - - String dn = "CN=testDN,O=testOrg"; - X509Certificate x509Certificate = new StandardCertificateBuilder(TlsHelper.generateKeyPair(keyPairAlgorithm, keySize), new X500Principal(dn), Duration.ofDays(days)).build(); - PublicKey pubKey = x509Certificate.getPublicKey(); - - for (String token : badTokens) { - try { - TlsHelper.calculateHMac(token, pubKey); - fail("HMAC was calculated with a token that was too short."); - } catch (GeneralSecurityException e) { - assertEquals("Token does not meet minimum size of 16 bytes.", e.getMessage()); - } catch (IllegalArgumentException e) { - assertEquals("Token cannot be null", e.getMessage()); - } - } - - for (String token : goodTokens) { - byte[] hmac = TlsHelper.calculateHMac(token, pubKey); - assertTrue(hmac.length > 0, "HMAC length OK"); - } - } - - @Test - public void testGenerateSelfSignedCert() throws GeneralSecurityException { - String dn = "CN=testDN,O=testOrg"; - - X509Certificate x509Certificate = new StandardCertificateBuilder(TlsHelper.generateKeyPair(keyPairAlgorithm, keySize), new X500Principal(dn), Duration.ofDays(days)).build(); - - Date notAfter = x509Certificate.getNotAfter(); - assertTrue(notAfter.after(inFuture(days - 1))); - assertTrue(notAfter.before(inFuture(days + 1))); - - Date notBefore = x509Certificate.getNotBefore(); - assertTrue(notBefore.after(inFuture(-1))); - assertTrue(notBefore.before(inFuture(1))); - - assertEquals(dn, x509Certificate.getIssuerX500Principal().getName()); - assertEquals("SHA256withRSA", x509Certificate.getSigAlgName()); - assertEquals(keyPairAlgorithm, x509Certificate.getPublicKey().getAlgorithm()); - - x509Certificate.checkValidity(); - } - - @Test - public void testWriteKeyStoreSuccess(@Mock OutputStreamFactory outputStreamFactory, @TempDir File file) throws IOException, GeneralSecurityException { - when(outputStreamFactory.create(file)).thenReturn(new ByteArrayOutputStream()); - String testPassword = "testPassword"; - final KeyStore keyStore = setupKeystore(); - assertEquals(testPassword, TlsHelper.writeKeyStore(keyStore, outputStreamFactory, file, testPassword, false)); - } - - @Test - public void testShouldIncludeSANFromCSR() throws Exception { - // Arrange - final List sanEntries = Arrays.asList("127.0.0.1", "nifi.nifi.apache.org"); - final int sanCount = sanEntries.size(); - final String dn = "CN=localhost"; - KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(keyPairAlgorithm); - keyPairGenerator.initialize(keySize); - KeyPair keyPair = keyPairGenerator.generateKeyPair(); - - // Act - JcaPKCS10CertificationRequest csrWithSan = TlsHelper.generateCertificationRequest(dn, sanEntries, keyPair, TlsConfig.DEFAULT_SIGNING_ALGORITHM); - - // Assert - String subjectName = csrWithSan.getSubject().toString(); - assertEquals(dn, subjectName); - - List extractedSans = extractSanFromCsr(csrWithSan); - assertEquals(sanCount + 1, extractedSans.size()); - List formattedSans = sanEntries.stream() - .map(s -> (IPAddress.isValid(s) ? "IP Address: " + new GeneralName(GeneralName.iPAddress, s).getName() : "DNS: " + s)) - .collect(Collectors.toList()); - assertTrue(extractedSans.containsAll(formattedSans)); - - // We check that the SANs also contain the CN - assertTrue(extractedSans.contains("DNS: localhost")); - } - - private List extractSanFromCsr(JcaPKCS10CertificationRequest csr) { - List sans = new ArrayList<>(); - Attribute[] certAttributes = csr.getAttributes(); - for (Attribute attribute : certAttributes) { - if (attribute.getAttrType().equals(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest)) { - Extensions extensions = Extensions.getInstance(attribute.getAttrValues().getObjectAt(0)); - GeneralNames gns = GeneralNames.fromExtensions(extensions, Extension.subjectAlternativeName); - GeneralName[] names = gns.getNames(); - for (GeneralName name : names) { - String title = ""; - if (name.getTagNo() == GeneralName.dNSName) { - title = "DNS"; - } else if (name.getTagNo() == GeneralName.iPAddress) { - title = "IP Address"; - // name.toASN1Primitive(); - } else if (name.getTagNo() == GeneralName.otherName) { - title = "Other Name"; - } - sans.add(title + ": " + name.getName()); - } - } - } - - return sans; - } - - @Test - public void testEscapeAliasFilenameWithForwardSlashes() { - String result = TlsHelper.escapeFilename("my/silly/filename.pem"); - assertEquals("my_silly_filename.pem", result); - } - - @Test - public void testEscapeAliasFilenameWithBackSlashes() { - String result = TlsHelper.escapeFilename("my\\silly\\filename.pem"); - assertEquals("my_silly_filename.pem", result); - } - - @Test - public void testEscapeAliasFilenameWithDollarSign() { - String result = TlsHelper.escapeFilename("my$illyfilename.pem"); - assertEquals("my_illyfilename.pem", result); - } - - @Test - public void testEscapeAliasFilenameTwoSymbolsInARow() { - String result = TlsHelper.escapeFilename("my!?sillyfilename.pem"); - assertEquals("my_sillyfilename.pem", result); - } - - @Test - public void testEscapeAliasFilenameKeepHyphens() { - String result = TlsHelper.escapeFilename("my-silly-filename.pem"); - assertEquals("my-silly-filename.pem", result); - } - - @Test - public void testEscapeAliasFilenameDoubleSpaces() { - String result = TlsHelper.escapeFilename("my silly filename.pem"); - assertEquals("my_silly_filename.pem", result); - } - - @Test - public void testEscapeAliasFilenameSymbols() { - String result = TlsHelper.escapeFilename("./\\!@#$%^&*()_-+=.pem"); - assertEquals(".__-_=.pem", result); - } - - @Test - public void testClientDnFilenameSlashes() { - String clientDn = "CN=testuser,OU=NiFi/Organisation"; - String escapedClientDn = TlsHelper.escapeFilename(clientDn); - - assertEquals("CN=testuser_OU=NiFi_Organisation", escapedClientDn); - } - - @Test - public void testClientDnFilenameSpecialChars() { - String clientDn = "CN=testuser,OU=NiFi#!Organisation"; - String escapedClientDn = TlsHelper.escapeFilename(clientDn); - - assertEquals("CN=testuser_OU=NiFi_Organisation", escapedClientDn); - } - - private KeyStore setupKeystore() throws CertificateException, NoSuchAlgorithmException, IOException, KeyStoreException { - KeyStore ks = KeyStore.getInstance("JKS"); - try (InputStream readStream = getClass().getClassLoader().getResourceAsStream("keystore.jks")) { - ks.load(readStream, PASSWORD.toCharArray()); - } - return ks; - } - - @Test - public void testOutputToFileTwoCertsAsPem(@TempDir final File folder) throws IOException, CertificateException, NoSuchAlgorithmException, KeyStoreException { - KeyStore keyStore = setupKeystore(); - HashMap certs = TlsHelper.extractCerts(keyStore); - TlsHelper.outputCertsAsPem(certs, folder,".crt"); - - assertEquals(2, folder.listFiles().length); - - for (File file : folder.listFiles()) { - X509Certificate certFromFile = loadCertificate(file); - assertTrue(certs.containsValue(certFromFile)); - X509Certificate originalCert = (X509Certificate) certs.get(file.getName().split("\\.")[0]); - assertEquals(originalCert, certFromFile); - assertArrayEquals(originalCert.getSignature(), certFromFile.getSignature()); - FileUtils.deleteFile(file, false); - } - } - - // Keystore contains two certificates, but one key. This is to test the edge case where a certificate does not have a key. - @Test - public void testOutputToFileOneKeyAsPem(@TempDir final File folder) throws IOException, CertificateException, NoSuchAlgorithmException, KeyStoreException, UnrecoverableKeyException { - KeyStore keyStore = setupKeystore(); - HashMap keys = TlsHelper.extractKeys(keyStore, PASSWORD.toCharArray()); - TlsHelper.outputKeysAsPem(keys, folder, ".key"); - - for (File file : folder.listFiles()) { - try (BufferedReader br = new BufferedReader(new FileReader(file))) { - PEMParser pemParser = new PEMParser(br); - PEMKeyPair key = (PEMKeyPair) pemParser.readObject(); - assertArrayEquals(keys.get(file.getName().split("\\.")[0]).getEncoded(), key.getPrivateKeyInfo().getEncoded()); - } finally { - FileUtils.deleteFile(file, false); - } - } - } - - @Test - public void testExtractCerts() throws IOException, CertificateException, NoSuchAlgorithmException, KeyStoreException { - KeyStore keyStore = setupKeystore(); - HashMap certs = TlsHelper.extractCerts(keyStore); - assertEquals(2, certs.size()); - certs.forEach((String p, Certificate q) -> assertEquals("X.509", q.getType())); - } - - @Test - public void testExtractKeys() throws IOException, CertificateException, NoSuchAlgorithmException, KeyStoreException, UnrecoverableKeyException { - KeyStore keyStore = setupKeystore(); - HashMap keys = TlsHelper.extractKeys(keyStore, PASSWORD.toCharArray()); - assertEquals(1, keys.size()); - keys.forEach((String alias, Key key) -> assertEquals("PKCS#8", key.getFormat())); - } - - @Test - public void testShouldVerifyCertificateSignatureWhenSelfSigned() { - assertTrue(TlsHelper.verifyCertificateSignature(rootCert, Collections.singletonList(rootCert))); - } - - @Test - public void testShouldVerifyCertificateSignatureWithMultipleSigningCerts(@Mock X509Certificate mockCertificate) { - when(mockCertificate.getSubjectX500Principal()).thenReturn(new X500Principal("CN=Mock Certificate")); - assertTrue(TlsHelper.verifyCertificateSignature(rootCert, Arrays.asList(mockCertificate, rootCert))); - } - - @Test - public void testShouldNotVerifyCertificateSignatureWithNoSigningCerts() { - assertFalse(TlsHelper.verifyCertificateSignature(rootCert, new ArrayList<>())); - } - - @Test - public void testShouldNotVerifyCertificateSignatureWithWrongSigningCert(@Mock X509Certificate mockCertificate) { - when(mockCertificate.getSubjectX500Principal()).thenReturn(new X500Principal("CN=Mock Certificate")); - assertFalse(TlsHelper.verifyCertificateSignature(rootCert, Collections.singletonList(mockCertificate))); - } - - @Test - public void testParseKeyPairFromReaderShouldHandlePKCS8PrivateKey() throws Exception { - final KeyPair expectedKeyPair = TlsHelper.parseKeyPairFromReader(new FileReader("src/test/resources/rootCert.key")); - final PrivateKey expectedPrivateKey = expectedKeyPair.getPrivate(); - final KeyPair keyPair = TlsHelper.parseKeyPairFromReader(new FileReader("src/test/resources/rootCert-pkcs8.key")); - - assertEquals(expectedPrivateKey, keyPair.getPrivate()); - } -} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/test/resources/empty-keystore.jks b/nifi-toolkit/nifi-toolkit-tls/src/test/resources/empty-keystore.jks deleted file mode 100644 index c408465500cb0af9cfd1f7371422ef8899ae6725..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32 ncmezO_TO6u1_mY|W_Xm5=la|E{*s%M?mC{^wn--0;QAy0^AQhj diff --git a/nifi-toolkit/nifi-toolkit-tls/src/test/resources/keystore.jks b/nifi-toolkit/nifi-toolkit-tls/src/test/resources/keystore.jks deleted file mode 100644 index 1eed4dd9d594fee176061cd61dfb1acbc6bcdafd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3975 zcmeH}XHb*r7RU3ZQIdc(X+{vF7zn~uIlDOvfk2>t z900=V>E`T)cXtYcKmgbFa@he01Ob2%@C}dy$u5Hg-~bNF1po*LJOVzMHKFO$5v&KD zz*!69PZLagMr}&3s|JmBbB$Dd;fsf|I*)oLMbdk;QH`pdHp_z+buO>!utKihM3;{yt=os z(=N}u57PWw2m|&ET{CJYZz^B56G~Y#(#WEVuR>n)CP$pM!y3obO#I>LS>c|_6X{_X z+94zT*={n26*pPv@-9%cb@6=JiCiXUV5vT2vZ#j$F&FU9#6z&I9%CBM%M2T@Fk`~} z=tVC4k)>mwazZA-$XP^3PLKzc7 zsKEr9EL;BWGNB${B?Sr62Z@-crD4WGHsknI&q+6eS&R6psL~Yk+2AXph==!{DQcau zh*Vl{$Cppu8k&xTilqu%MP+Bf-t^ay$(doRm-DQ_@A2fQ3}-rm$k`aY+#ol;rL#9y zBDV#iW<1DJatsM#kGyrrn$kQ2bgVs%n;6i)a_a{E;A<{5gx6S}ia8MYy1x zwuE}-s}{Mau&4xezLnYS0 zO^|+1Y4Y-$+XN{J`1>YUnbVd<7V*vUl@Eh{@xW2N_CpHxJH)*WG!L;Y@RG<|oPW4N z1bX*e|5KB9?|t#?N21T8mq zraM;k@^VUePFqPZRMjS4YVLb>@kY)`Ra*=$sb#54ve177o}oNRQB)-{oF5?1W$5cZ zRckVQ{88s5`MFy6RUNU5sV?F{apQeOr^PBR!b~KMo;%N(U^9!4`k#N~D&T{#Wl1O9 z8OVDr9ukmzSWCO+5Y0^Rdi-1ejG42S1DP&*PZWqp=&USvj_QaXs}9DEP+E@lJR<3p zRn$g@OV=I@lm>?9b4}_n%3&e~O>;6+A53RIwfe;`agOdjZGqYyhc?P!Wsd<%nOD+g zdSxcNx$0kL1pLA3Ja*Lz+1mkw4(NO!^ zaB19xff~&ndWEH;LF{v%v*;QwdNl#xAm_O+hPA$~N$K$D+mvFH@BWvT{jcG<-sEr` zzq@l+{0iv|K1JhMrmI$BhG@NzpY1%Rz4}=J7rFH*^7Pu1hv3OY8Npo1Lia(vJ)1U~ z^vqW-^V4koBNHobjZ@xCY*j`uE~qOu|3F)j$(PW+kPW??ABfIdBs7PxP3vK>_SYl|NqLGolzVD;ZC+z(hbEmpt&Upg6Y$W?7748lj zDVK%tb1hq#4oEWE`%?yKJ7u1c;K-mVT9g)h-w=YJrw`g_b%Gf8J2dVoL1 zBjS{t5~v1&z|MgYFgq{;s#^eq0#GRX_Mj{z8*PtJ2#7(l;iC1TzhVFYg@AzK@)!_> zgq?(=&~OudU440OaK~>h49!OJayUzJ^}65(?&inHtAPrjiUO#hsH9}Yk5SmRK;=K& z|1L=cAola;+XEUF0dPXV2!I_L0RWKejqbhYlJEj;xt7(kR{Q}#oMV=%<<;EOe1FS{le6T zUuI!hy38jVzif?N)o$XB;P}#22EG{V%Q9`|-kCczm2BC0 zajx{$Ns-ad4MaCCv;HC>iL8r`c1h^AJcl+8${VJju3?VwXSPCnsp& zTR6?1rv3WK;3?JdrEe{R4o*hCl|5H^tF}gvmlTy7g83E{gG@)==*X?{wP*X*6%4B+ zPoe?{Wp)ddf+`d8vuOx%m?Gj));5*^G{@kfIr*wr<>9>d^ zRB&RIcF7?jP~^8~akv1uGo062>y2x5EB0C9y}+`W)wwf~{5GuHO1K@s2>@GgI1CC~ z1=)V{dEihG@*}kbd?(0@WZhOv1cC(y{nG-rZ?_}4;M+|R@lyl*wQ08N20*NwtEE;f znp7&UuP1XDiG|Bq?}!mwr=7BE`9xh?h`C?jm<>Pb(|aqC&rYj0aHrqgY*Sav2K{>W zU9*KkoR92MLOWc*;$B0k1us+z%_j6f;f5WIh9bNuhWZSb*VLz58))(gjrxobAykcz zv&BP-!V&J8OZ~V;ae-r(@(xCqgnEIaXyl6zd$4cI&Ha7qH|=Di-@jNvEAhyN`VEN7 z?860X&_XTpUYC#@)*eZ{drDX-JJe9_W@v-C-F>u+(U`mZzUqGOmwXE#+_e2B`9J6`WHWDMZ+I_qoXHbwoVKd%_O@A9U z`JZ4*js5?IEk0W6>MhjfLgiUT$<(mi3AiPg2$LLNm@iRH$wHY5mwCOdOn!;$nye#F zXD6pTslU`uzgn`13_FBz=U+}wYp^OkMG-NHy2^QL zq5Fi@i_SYHj$)VUD>y!Ql1??hSPU|#N*u|uKQU80iJ?{{(2y+VR9(H!Gcuvp!^M1T zd8-4XPI&~4DaqNVVij*?dpuw{A-&0-JurBLA%yR*X$OE zzE{i&qJF>@244OvD!?X){(%Ytgl*&V6NrDy*?$D_caZ-*ZGXen{^uUYQ>9PLrae|X z?z=h6u$(`3pg8DFEnpJ(9wFvtF?7dvqf$qH2g>soZii%KH{RdgU@GhA@y{wG-B@)5 zRh%HXY#DkQqg!{(X~D{<0oswDXBf4@r?P5SpXYRUU6Cgj`8{BbZ@gCc9IM70(-7Ou zzVMySD1V`|?q@YN0#{m=jnqz;&R2gz^gTz1)I_Zkugm9f&+=9qwxY+r$0yW(`@VsjCI^G#>m*Nv!^ is set to true -nifi.state.management.embedded.zookeeper.properties=./conf/zookeeper.properties - - -# Database Settings -nifi.database.directory=./database_repository - -# FlowFile Repository -nifi.flowfile.repository.implementation=org.apache.nifi.controller.repository.WriteAheadFlowFileRepository -nifi.flowfile.repository.directory=./flowfile_repository -nifi.flowfile.repository.partitions=256 -nifi.flowfile.repository.checkpoint.interval=2 mins -nifi.flowfile.repository.always.sync=false - -nifi.swap.manager.implementation=org.apache.nifi.controller.FileSystemSwapManager -nifi.queue.swap.threshold=20000 -nifi.swap.in.period=5 sec -nifi.swap.in.threads=1 -nifi.swap.out.period=5 sec -nifi.swap.out.threads=4 - -# Content Repository -nifi.content.repository.implementation=org.apache.nifi.controller.repository.FileSystemRepository -nifi.content.claim.max.appendable.size=10 MB -nifi.content.claim.max.flow.files=100 -nifi.content.repository.directory.default=./content_repository -nifi.content.repository.archive.max.retention.period=12 hours -nifi.content.repository.archive.max.usage.percentage=50% -nifi.content.repository.archive.enabled=true -nifi.content.repository.always.sync=false -nifi.content.viewer.url=/nifi-content-viewer/ - -# Provenance Repository Properties -nifi.provenance.repository.implementation=org.apache.nifi.provenance.WriteAheadProvenanceRepository - -# Persistent Provenance Repository Properties -nifi.provenance.repository.directory.default=./provenance_repository -nifi.provenance.repository.max.storage.time=24 hours -nifi.provenance.repository.max.storage.size=1 GB -nifi.provenance.repository.rollover.time=30 secs -nifi.provenance.repository.rollover.size=100 MB -nifi.provenance.repository.query.threads=2 -nifi.provenance.repository.index.threads=1 -nifi.provenance.repository.compress.on.rollover=true -nifi.provenance.repository.always.sync=false -nifi.provenance.repository.journal.count=16 -# Comma-separated list of fields. Fields that are not indexed will not be searchable. Valid fields are: -# EventType, FlowFileUUID, Filename, TransitURI, ProcessorID, AlternateIdentifierURI, Relationship, Details -nifi.provenance.repository.indexed.fields=EventType, FlowFileUUID, Filename, ProcessorID, Relationship -# FlowFile Attributes that should be indexed and made searchable. Some examples to consider are filename, uuid, mime.type -nifi.provenance.repository.indexed.attributes= -# Large values for the shard size will result in more Java heap usage when searching the Provenance Repository -# but should provide better performance -nifi.provenance.repository.index.shard.size=500 MB -# Indicates the maximum length that a FlowFile attribute can be when retrieving a Provenance Event from -# the repository. If the length of any attribute exceeds this value, it will be truncated when the event is retrieved. -nifi.provenance.repository.max.attribute.length=65536 - -# Volatile Provenance Respository Properties -nifi.provenance.repository.buffer.size=100000 - -# Component Status Repository -nifi.components.status.repository.implementation=org.apache.nifi.controller.status.history.VolatileComponentStatusRepository -nifi.components.status.repository.buffer.size=1440 -nifi.components.status.snapshot.frequency=1 min - -# Site to Site properties -nifi.remote.input.host= -nifi.remote.input.secure=false -nifi.remote.input.socket.port= -nifi.remote.input.http.enabled=true -nifi.remote.input.http.transaction.ttl=30 sec - -# web properties # -nifi.web.war.directory=./lib -nifi.web.http.host= -nifi.web.http.port=8080 -nifi.web.https.host= -nifi.web.https.port= -nifi.web.jetty.working.directory=./work/jetty -nifi.web.jetty.threads=200 - -# security properties # -nifi.sensitive.props.key= -nifi.sensitive.props.algorithm=NIFI_PBKDF2_AES_GCM_256 - -nifi.security.keystore=./conf/localhost.jks -nifi.security.keystoreType=jks -nifi.security.keystorePasswd=vidmcgplvih3dn2fqjnckns77g -nifi.security.keyPasswd=qgs57rmnot6p8gm97pfjutnu5g -nifi.security.truststore=./conf/truststore.jks -nifi.security.truststoreType=jks -nifi.security.truststorePasswd=t7rmn1fg8np2ck1sduqdd85opv -nifi.security.user.authorizer=file-provider -nifi.security.user.login.identity.provider= -nifi.security.ocsp.responder.url= -nifi.security.ocsp.responder.pemEncodedCertificate= - -# cluster common properties (all nodes must have same values) # -nifi.cluster.protocol.heartbeat.interval=5 sec -nifi.cluster.protocol.is.secure=false - -# cluster node properties (only configure for cluster nodes) # -nifi.cluster.is.node=false -nifi.cluster.node.address= -nifi.cluster.node.protocol.port= -nifi.cluster.node.protocol.threads=10 -nifi.cluster.node.event.history.size=25 -nifi.cluster.node.connection.timeout=5 sec -nifi.cluster.node.read.timeout=5 sec -nifi.cluster.firewall.file= - -# zookeeper properties, used for cluster management # -nifi.zookeeper.connect.string= -nifi.zookeeper.connect.timeout=3 secs -nifi.zookeeper.session.timeout=3 secs -nifi.zookeeper.root.node=/nifi - -# kerberos # -nifi.kerberos.krb5.file= -nifi.kerberos.service.principal= -nifi.kerberos.service.keytab.location= - -nifi.kerberos.spnego.principal= -nifi.kerberos.spnego.keytab.location= -nifi.kerberos.spnego.authentication.expiration=12 hours \ No newline at end of file diff --git a/nifi-toolkit/nifi-toolkit-tls/src/test/resources/localhost/truststore.jks b/nifi-toolkit/nifi-toolkit-tls/src/test/resources/localhost/truststore.jks deleted file mode 100644 index 87f4be1cb74419252a6dd4a8cb8ed6063e7ade2f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 911 zcmezO_TO6u1_mY|W(3omd6{XMy2+_UB|wqXzwHA57+53pObsj<7?^zxnwUKenwSh1 zFf%bSF>!(9`2~U67z}vXIJMe5+P?ELGIFyr7$_U^8gR2Qhq7?`|G6{iVN=9$4_qR+voW1o`bX1kq_?@ zm7?Yu-O|hoDsa9N@MUVyrd<=O*InmV-0wL}LeXNm*vwgmI&)i2xoutU%O^gq+-#-h zgcU!vCxtetZirTB`cPrNOwe`BjfgY1S)#*|1p91Qo|habzwWRw{qs>-^K}Z`hO4)3 zSIUzY)UVZ%QmoRgXzEd9>P=X}&%!9YU~gQOux6db!Fj1Vv2}&_t)uD|R&4O>6_I{d zsCSIx%+#5m7tCg~+3?%uOvdTe*F$Rt zebbjM$oo^i)iz_A4D$trP*WymMh3>k^#-*De832h{z<6{wH5fM3WFu8l*4Bb6fbc?q7ui3Ma?czxTd62X+i-dt#19k;q{i-Zt1|n=6 z+H8!htnAE8a26wS6amu*Fp3x%;$M|c<$Br5aA-Zh`^uo~Wl`!k!$N+rAKm}gt?NVV zYn6)fmHTq0T%UdUsC(tf>wh-zugDkvQkKrV&wNr*Y-2X-|KIB@^>$R5GBG*(lon0! zZ;^?AbUT{i$=9D(FVwb7kUOEi+Gn#X+u0bI3n5nobT4k-BQr_T{`T_6SwEI~yi@Kw zFTeN0R^RvQOEeC9N z9oJ^^ymM}2j4=Bzl|5_bntl+HlHs5ImG#RU$C=4?=Kr%5`)8e9xTbMSRd_+e)hDMV z{$6UT4g6+eRVVNyVx3Chngx@VtPkMaA?X>r^jGNWKqZspMPe?;zuNh^J${uwG4xsu E0JdaNg#Z8m diff --git a/nifi-toolkit/nifi-toolkit-tls/src/test/resources/overlay.properties b/nifi-toolkit/nifi-toolkit-tls/src/test/resources/overlay.properties deleted file mode 100644 index 00c04a4b25..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/test/resources/overlay.properties +++ /dev/null @@ -1,41 +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. -# - -# This properties file specifies how to update the provided nifi.properties - -# Comma separated list of properties to put the hostname into -hostname.properties= \ - nifi.remote.input.host, \ - nifi.web.https.host, \ - nifi.cluster.node.address - -# Comma separated list of properties to increment (must also be defined in this file) -incrementing.properties= \ - nifi.web.https.port, \ - nifi.remote.input.socket.port, \ - nifi.cluster.node.protocol.port - -nifi.web.https.port=8443 -nifi.remote.input.socket.port=10443 -nifi.cluster.node.protocol.port=11443 - -# Properties to set verbatim -nifi.remote.input.secure=true -nifi.cluster.protocol.is.secure=true - -nifi.web.http.host= -nifi.web.http.port= \ No newline at end of file diff --git a/nifi-toolkit/nifi-toolkit-tls/src/test/resources/rootCert-pkcs8.key b/nifi-toolkit/nifi-toolkit-tls/src/test/resources/rootCert-pkcs8.key deleted file mode 100644 index fc7faefb7e..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/test/resources/rootCert-pkcs8.key +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC6+OcU6ijl9hqr -q8yI/ZyahKPenOkuO9U+xAY/g4fu/LV/cLoilaStePL+Sy2w/XXpYLg92csnQUXi -iBH/hvlel4W4teuawaTd1ZBpzfO6dnUA68kp+VCoKI58gbz24yScl7R6cerh+GPL -ipmvA6YyjMZrJZrmJGMZ9juZLjiW5hC+f13P0bggigZWnEmuW0cOuXR8xxWpjop/ -Fv//qO+jviZbQTzmGO7jkkex4RQwcyxlokBh8qDZ1FCvITVQhbkZqLYijXseNYip -ZSeG3n8K8kbcwqj/dedW7DJWdue3lt7L4341VWwwpOKDebs8YrZHp/Jwq6kgwxVn -rQVuwujvAgMBAAECggEADOpKlBBEuPXSC8+3NjNGkQneg+8U0GPDrC1APTzps+Fy -7BWuVds+X9k998DbrCEl9vP+Zg9YUCLbH/XEQIFjUlxnGUY/uxXrPIOXESfv0Q6D -sIeZArQ9FRCQHxubIPa5vbNg/SBHWEqfIh011ngLD+zXe+lCFOmois+OeFtP/2RQ -wzF1as3fr+j9MvXxVkwPYTdYYzNf6Vso0uxC98AZSlt9s+2ZQ8V7NsOgvk+qSPgp -nj/mXVF+pCJqY2KPDHGb+gZsOHwC7LG+ehHLENz05YSh6kRvvZB15zgsmdpg1dS0 -jauDVABtxfO5Eu2/yjQnSClV2qbZE7J/e0Voj4WTqQKBgQDeNkzlW1rsEcFPUeZg -ZlA65Adb5YPsJCAt5cIIHg7jGr/uXuIbaEzem3rlMZp7vwoe0nYtyJaspG41Ou4G -gprHowXDXpl9JBIWLQqef4RtzFyY9DaL9U7Gl05UA/0vIQooZOAfYVMTtGSIa3+g -rR4mtgekcykCzSNHIIhgY+a3XQKBgQDXZuB+4wCGLLeS/8hi2Xdbt2gYVXO7YLn1 -VbGaSn9a8ZDKtVQJRGnk82OVvQsgzgNmcpH/MLGg/RJ/VO5WY5E7Vn5nQ0omijBj -K95JxOef5GorDuyzH0qAZFdce5aUNwG/mUgw/m9iz/knjtqtl1uMjc1uKu+/zLiQ -e3UuSs9YuwKBgHSpX2+eqbp8i9e/8Mo1jPOOGgr2EW+de8N894RZe4lh1tgnul+X -P5wzVq8Tfr5vCrop1l+tCuXyoeWSXbrPQMGE5havCLg5gsFfvk5+NiGLBCZNOIH8 -NPJwJ3BWc8sVdobEhyISb5JNx+YTQfsySD0cniCJUUOmPVovS0oHyO4FAoGAEQPu -bfeOngrAQZt0/+H/3L3jOjDd4IpmhivLyM1jvBJjBrBGQCkoWE6lqjlxvJipihk4 -0TjOf1IeePKDlU1uNorBl3SoUd0Or3bSq28jgOzxOg+GwSuSngvPHt4gafriZ3k7 -S6t9rweQvgA55AaV08eL180KfVM1rSwjeJGuSWsCgYEAuOeoNAUG5PeKjSWhxc8f -DpRsgBsPo+bxnX4eAr+GyTJf/1uacmfejLOPHOImGnL3pGgu7SzEHGjl+McZznhC -foJyK+7igz7iuS18AuEu4VR+J7y2vqdmWeabFHI2onEPwvlO1vrpOIL2yd/3wxgC -qwoPTd89hQB2k+Uhuf7FLjg= ------END PRIVATE KEY----- diff --git a/nifi-toolkit/nifi-toolkit-tls/src/test/resources/rootCert.crt b/nifi-toolkit/nifi-toolkit-tls/src/test/resources/rootCert.crt deleted file mode 100644 index 98bb577bf0..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/test/resources/rootCert.crt +++ /dev/null @@ -1,20 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDWTCCAkGgAwIBAgIGAVXgcI3oMA0GCSqGSIb3DQEBCwUAMC0xFTATBgNVBAMM -DG5pZmkucm9vdC5jYTEUMBIGA1UECwwLYXBhY2hlLm5pZmkwHhcNMTYwNzEyMTg0 -ODQwWhcNMTcwNzEyMTg0ODQwWjAtMRUwEwYDVQQDDAxuaWZpLnJvb3QuY2ExFDAS -BgNVBAsMC2FwYWNoZS5uaWZpMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC -AQEAuvjnFOoo5fYaq6vMiP2cmoSj3pzpLjvVPsQGP4OH7vy1f3C6IpWkrXjy/kst -sP116WC4PdnLJ0FF4ogR/4b5XpeFuLXrmsGk3dWQac3zunZ1AOvJKflQqCiOfIG8 -9uMknJe0enHq4fhjy4qZrwOmMozGayWa5iRjGfY7mS44luYQvn9dz9G4IIoGVpxJ -rltHDrl0fMcVqY6Kfxb//6jvo74mW0E85hju45JHseEUMHMsZaJAYfKg2dRQryE1 -UIW5Gai2Io17HjWIqWUnht5/CvJG3MKo/3XnVuwyVnbnt5bey+N+NVVsMKTig3m7 -PGK2R6fycKupIMMVZ60FbsLo7wIDAQABo38wfTAOBgNVHQ8BAf8EBAMCAf4wDAYD -VR0TBAUwAwEB/zAdBgNVHQ4EFgQUxPKyo9LTvN7jTJ1x2jVUe4nNz1swHwYDVR0j -BBgwFoAUxPKyo9LTvN7jTJ1x2jVUe4nNz1swHQYDVR0lBBYwFAYIKwYBBQUHAwIG -CCsGAQUFBwMBMA0GCSqGSIb3DQEBCwUAA4IBAQBcMRAlnWDco5WbjTV0uSxmS7Dh -RxYgt7YguqA/tdfcn6hhJZ2ZZm5By6nwP4aGFY45tOv2NsjHgchgfJ6Osl3ZxGmF -+JrXW7mveOwZIfZzM2yFCusgkzrGOAWNL2G+lbXpRCnsTuJL6jUbRE1cFwU+iUYo -E8Xfo6XZVNlzeab4WNerAPGssftV9C+0ya9+5+hFmBhzpGkpn5EVicxLAX6fI4K6 -N4ZCBU8DYQilYkE0xgxySSz7Ia1vo8D7Tr30CxoXGsqRLXanW0Jw1wVsLVheTLZw -W3gp2XKOaP/BMFbIFw2iB7REeCao14u9pRAKEodpH+fpUosbFlpd8ysRvFJP ------END CERTIFICATE----- diff --git a/nifi-toolkit/nifi-toolkit-tls/src/test/resources/rootCert.key b/nifi-toolkit/nifi-toolkit-tls/src/test/resources/rootCert.key deleted file mode 100644 index 64f9bb722c..0000000000 --- a/nifi-toolkit/nifi-toolkit-tls/src/test/resources/rootCert.key +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEowIBAAKCAQEAuvjnFOoo5fYaq6vMiP2cmoSj3pzpLjvVPsQGP4OH7vy1f3C6 -IpWkrXjy/kstsP116WC4PdnLJ0FF4ogR/4b5XpeFuLXrmsGk3dWQac3zunZ1AOvJ -KflQqCiOfIG89uMknJe0enHq4fhjy4qZrwOmMozGayWa5iRjGfY7mS44luYQvn9d -z9G4IIoGVpxJrltHDrl0fMcVqY6Kfxb//6jvo74mW0E85hju45JHseEUMHMsZaJA -YfKg2dRQryE1UIW5Gai2Io17HjWIqWUnht5/CvJG3MKo/3XnVuwyVnbnt5bey+N+ -NVVsMKTig3m7PGK2R6fycKupIMMVZ60FbsLo7wIDAQABAoIBAAzqSpQQRLj10gvP -tzYzRpEJ3oPvFNBjw6wtQD086bPhcuwVrlXbPl/ZPffA26whJfbz/mYPWFAi2x/1 -xECBY1JcZxlGP7sV6zyDlxEn79EOg7CHmQK0PRUQkB8bmyD2ub2zYP0gR1hKnyId -NdZ4Cw/s13vpQhTpqIrPjnhbT/9kUMMxdWrN36/o/TL18VZMD2E3WGMzX+lbKNLs -QvfAGUpbfbPtmUPFezbDoL5Pqkj4KZ4/5l1RfqQiamNijwxxm/oGbDh8AuyxvnoR -yxDc9OWEoepEb72Qdec4LJnaYNXUtI2rg1QAbcXzuRLtv8o0J0gpVdqm2ROyf3tF -aI+Fk6kCgYEA3jZM5Vta7BHBT1HmYGZQOuQHW+WD7CQgLeXCCB4O4xq/7l7iG2hM -3pt65TGae78KHtJ2LciWrKRuNTruBoKax6MFw16ZfSQSFi0Knn+EbcxcmPQ2i/VO -xpdOVAP9LyEKKGTgH2FTE7RkiGt/oK0eJrYHpHMpAs0jRyCIYGPmt10CgYEA12bg -fuMAhiy3kv/IYtl3W7doGFVzu2C59VWxmkp/WvGQyrVUCURp5PNjlb0LIM4DZnKR -/zCxoP0Sf1TuVmORO1Z+Z0NKJoowYyveScTnn+RqKw7ssx9KgGRXXHuWlDcBv5lI -MP5vYs/5J47arZdbjI3Nbirvv8y4kHt1LkrPWLsCgYB0qV9vnqm6fIvXv/DKNYzz -jhoK9hFvnXvDfPeEWXuJYdbYJ7pflz+cM1avE36+bwq6KdZfrQrl8qHlkl26z0DB -hOYWrwi4OYLBX75OfjYhiwQmTTiB/DTycCdwVnPLFXaGxIciEm+STcfmE0H7Mkg9 -HJ4giVFDpj1aL0tKB8juBQKBgBED7m33jp4KwEGbdP/h/9y94zow3eCKZoYry8jN -Y7wSYwawRkApKFhOpao5cbyYqYoZONE4zn9SHnjyg5VNbjaKwZd0qFHdDq920qtv -I4Ds8ToPhsErkp4Lzx7eIGn64md5O0urfa8HkL4AOeQGldPHi9fNCn1TNa0sI3iR -rklrAoGBALjnqDQFBuT3io0locXPHw6UbIAbD6Pm8Z1+HgK/hskyX/9bmnJn3oyz -jxziJhpy96RoLu0sxBxo5fjHGc54Qn6Ccivu4oM+4rktfALhLuFUfie8tr6nZlnm -mxRyNqJxD8L5Ttb66TiC9snf98MYAqsKD03fPYUAdpPlIbn+xS44 ------END RSA PRIVATE KEY----- diff --git a/nifi-toolkit/pom.xml b/nifi-toolkit/pom.xml index 825122b995..d993b79f88 100644 --- a/nifi-toolkit/pom.xml +++ b/nifi-toolkit/pom.xml @@ -23,7 +23,6 @@ nifi-toolkit pom - nifi-toolkit-tls nifi-toolkit-encrypt-config nifi-toolkit-flowfile-repo nifi-toolkit-assembly