mirror of https://github.com/apache/nifi.git
NIFI-2943 - Toolkit uses JKS type over PKCS12 when creating truststore because non-Bouncy Castle providers cannot read certificates from PKCS12 truststore.
Peer review feedback (+2 squashed commits) Squashed commits: [0102c8e] NIFI-2943 - Peer review feedback [9bcd495] NIFI-2943 - pkcs12 keystore improvements 1. loading pkcs12 keystores with bouncy castle everywhere 2. tls-toolkit client using jks truststore when keystore type is specified differently 3. tests This closes #1165. Signed-off-by: Andy LoPresto <alopresto@apache.org>
This commit is contained in:
parent
fa13832a9c
commit
e5eda63705
|
@ -55,6 +55,7 @@ import java.security.KeyPair;
|
|||
import java.security.KeyStore;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PublicKey;
|
||||
import java.security.Security;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertificateFactory;
|
||||
|
@ -76,6 +77,10 @@ public final class CertificateUtils {
|
|||
private static final String PEER_NOT_AUTHENTICATED_MSG = "peer not authenticated";
|
||||
private static final Map<ASN1ObjectIdentifier, Integer> dnOrderMap = createDnOrderMap();
|
||||
|
||||
static {
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
}
|
||||
|
||||
/**
|
||||
* The time in milliseconds that the last unique serial number was generated
|
||||
*/
|
||||
|
@ -148,7 +153,7 @@ public final class CertificateUtils {
|
|||
|
||||
// load the keystore
|
||||
bis = new BufferedInputStream(keystore.openStream());
|
||||
ks = KeyStore.getInstance(keystoreType.name());
|
||||
ks = KeyStoreUtils.getKeyStore(keystoreType.name());
|
||||
ks.load(bis, password);
|
||||
|
||||
return true;
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.nifi.security.util;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.security.KeyStore;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.Security;
|
||||
|
||||
public class KeyStoreUtils {
|
||||
private static final Logger logger = LoggerFactory.getLogger(KeyStoreUtils.class);
|
||||
|
||||
static {
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the provider that will be used for the given keyStoreType
|
||||
*
|
||||
* @param keyStoreType the keyStoreType
|
||||
* @return the provider that will be used
|
||||
*/
|
||||
public static String getKeyStoreProvider(String keyStoreType) {
|
||||
if (KeystoreType.PKCS12.toString().equalsIgnoreCase(keyStoreType)) {
|
||||
return BouncyCastleProvider.PROVIDER_NAME;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an empty KeyStore backed by the appropriate provider
|
||||
*
|
||||
* @param keyStoreType the keyStoreType
|
||||
* @return an empty KeyStore
|
||||
* @throws KeyStoreException if a KeyStore of the given type cannot be instantiated
|
||||
*/
|
||||
public static KeyStore getKeyStore(String keyStoreType) throws KeyStoreException {
|
||||
String keyStoreProvider = getKeyStoreProvider(keyStoreType);
|
||||
if (StringUtils.isNotEmpty(keyStoreProvider)) {
|
||||
try {
|
||||
return KeyStore.getInstance(keyStoreType, keyStoreProvider);
|
||||
} catch (Exception e) {
|
||||
logger.error("Unable to load " + keyStoreProvider + " " + keyStoreType
|
||||
+ " keystore. This may cause issues getting trusted CA certificates as well as Certificate Chains for use in TLS.", e);
|
||||
}
|
||||
}
|
||||
return KeyStore.getInstance(keyStoreType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an empty KeyStore intended for use as a TrustStore backed by the appropriate provider
|
||||
*
|
||||
* @param trustStoreType the trustStoreType
|
||||
* @return an empty KeyStore
|
||||
* @throws KeyStoreException if a KeyStore of the given type cannot be instantiated
|
||||
*/
|
||||
public static KeyStore getTrustStore(String trustStoreType) throws KeyStoreException {
|
||||
if (KeystoreType.PKCS12.toString().equalsIgnoreCase(trustStoreType)) {
|
||||
logger.warn(trustStoreType + " truststores are deprecated. " + KeystoreType.JKS.toString() + " is preferred.");
|
||||
}
|
||||
return getKeyStore(trustStoreType);
|
||||
}
|
||||
}
|
|
@ -108,7 +108,7 @@ public final class SslContextFactory {
|
|||
UnrecoverableKeyException, KeyManagementException {
|
||||
|
||||
// prepare the keystore
|
||||
final KeyStore keyStore = KeyStore.getInstance(keystoreType);
|
||||
final KeyStore keyStore = KeyStoreUtils.getKeyStore(keystoreType);
|
||||
try (final InputStream keyStoreStream = new FileInputStream(keystore)) {
|
||||
keyStore.load(keyStoreStream, keystorePasswd);
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ public final class SslContextFactory {
|
|||
}
|
||||
|
||||
// prepare the truststore
|
||||
final KeyStore trustStore = KeyStore.getInstance(truststoreType);
|
||||
final KeyStore trustStore = KeyStoreUtils.getTrustStore(truststoreType);
|
||||
try (final InputStream trustStoreStream = new FileInputStream(truststore)) {
|
||||
trustStore.load(trustStoreStream, truststorePasswd);
|
||||
}
|
||||
|
@ -191,7 +191,7 @@ public final class SslContextFactory {
|
|||
UnrecoverableKeyException, KeyManagementException {
|
||||
|
||||
// prepare the keystore
|
||||
final KeyStore keyStore = KeyStore.getInstance(keystoreType);
|
||||
final KeyStore keyStore = KeyStoreUtils.getKeyStore(keystoreType);
|
||||
try (final InputStream keyStoreStream = new FileInputStream(keystore)) {
|
||||
keyStore.load(keyStoreStream, keystorePasswd);
|
||||
}
|
||||
|
@ -232,7 +232,7 @@ public final class SslContextFactory {
|
|||
UnrecoverableKeyException, KeyManagementException {
|
||||
|
||||
// prepare the truststore
|
||||
final KeyStore trustStore = KeyStore.getInstance(truststoreType);
|
||||
final KeyStore trustStore = KeyStoreUtils.getTrustStore(truststoreType);
|
||||
try (final InputStream trustStoreStream = new FileInputStream(truststore)) {
|
||||
trustStore.load(trustStoreStream, truststorePasswd);
|
||||
}
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
*/
|
||||
package org.apache.nifi.security.util
|
||||
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider
|
||||
import org.bouncycastle.operator.OperatorCreationException
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
|
@ -35,7 +34,6 @@ import java.security.KeyPair
|
|||
import java.security.KeyPairGenerator
|
||||
import java.security.NoSuchAlgorithmException
|
||||
import java.security.NoSuchProviderException
|
||||
import java.security.Security
|
||||
import java.security.SignatureException
|
||||
import java.security.cert.Certificate
|
||||
import java.security.cert.CertificateException
|
||||
|
@ -67,8 +65,6 @@ class CertificateUtilsTest extends GroovyTestCase {
|
|||
|
||||
@BeforeClass
|
||||
static void setUpOnce() {
|
||||
Security.addProvider(new BouncyCastleProvider())
|
||||
|
||||
logger.metaClass.methodMissing = { String name, args ->
|
||||
logger.info("[${name?.toUpperCase()}] ${(args as List).join(" ")}")
|
||||
}
|
||||
|
|
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.nifi.security.util;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.KeyStore;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class KeyStoreUtilsTest {
|
||||
public static final String SIGNING_ALGORITHM = "SHA256withRSA";
|
||||
public static final int DURATION_DAYS = 365;
|
||||
public static final char[] BAD_TEST_PASSWORD_DONT_USE_THIS = "changek".toCharArray();
|
||||
public static final char[] BAD_KEY_STORE_TEST_PASSWORD_DONT_USE_THIS = "changes".toCharArray();
|
||||
public static final String ALIAS = "alias";
|
||||
|
||||
private static KeyPair caCertKeyPair;
|
||||
private static X509Certificate caCertificate;
|
||||
|
||||
private static KeyPair issuedCertificateKeyPair;
|
||||
private static X509Certificate issuedCertificate;
|
||||
|
||||
@BeforeClass
|
||||
public static void generateKeysAndCertificates() throws NoSuchAlgorithmException, CertificateException {
|
||||
caCertKeyPair = KeyPairGenerator.getInstance("RSA").generateKeyPair();
|
||||
issuedCertificateKeyPair = KeyPairGenerator.getInstance("RSA").generateKeyPair();
|
||||
|
||||
caCertificate = CertificateUtils.generateSelfSignedX509Certificate(caCertKeyPair, "CN=testca,O=Apache,OU=NiFi", SIGNING_ALGORITHM, DURATION_DAYS);
|
||||
issuedCertificate = CertificateUtils.generateIssuedCertificate("CN=testcert,O=Apache,OU=NiFi", issuedCertificateKeyPair.getPublic(), caCertificate, caCertKeyPair, SIGNING_ALGORITHM,
|
||||
DURATION_DAYS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJksKeyStoreRoundTrip() throws GeneralSecurityException, IOException {
|
||||
testKeyStoreRoundTrip(() -> KeyStoreUtils.getKeyStore(KeystoreType.JKS.toString().toLowerCase()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPkcs12KeyStoreBcRoundTrip() throws GeneralSecurityException, IOException {
|
||||
testKeyStoreRoundTrip(() -> KeyStoreUtils.getKeyStore(KeystoreType.PKCS12.toString().toLowerCase()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPkcs12KeyStoreRoundTripBcReload() throws GeneralSecurityException, IOException {
|
||||
// Pkcs12 Bouncy Castle needs same key and keystore password to interoperate with Java provider
|
||||
testKeyStoreRoundTrip(() -> KeyStore.getInstance(KeystoreType.PKCS12.toString().toLowerCase()),
|
||||
() -> KeyStoreUtils.getKeyStore(KeystoreType.PKCS12.toString().toLowerCase()), BAD_KEY_STORE_TEST_PASSWORD_DONT_USE_THIS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJksTrustStoreRoundTrip() throws GeneralSecurityException, IOException {
|
||||
testTrustStoreRoundTrip(() -> KeyStoreUtils.getTrustStore(KeystoreType.JKS.toString().toLowerCase()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPkcs12TrustStoreBcRoundTrip() throws GeneralSecurityException, IOException {
|
||||
testTrustStoreRoundTrip(() -> KeyStoreUtils.getTrustStore(KeystoreType.PKCS12.toString().toLowerCase()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPkcs12TrustStoreRoundTripBcReload() throws GeneralSecurityException, IOException {
|
||||
testTrustStoreRoundTrip(() -> KeyStore.getInstance(KeystoreType.PKCS12.toString().toLowerCase()), () -> KeyStoreUtils.getTrustStore(KeystoreType.PKCS12.toString().toLowerCase()));
|
||||
}
|
||||
|
||||
private void testTrustStoreRoundTrip(KeyStoreSupplier keyStoreSupplier) throws GeneralSecurityException, IOException {
|
||||
testTrustStoreRoundTrip(keyStoreSupplier, keyStoreSupplier);
|
||||
}
|
||||
|
||||
private void testTrustStoreRoundTrip(KeyStoreSupplier initialKeyStoreSupplier, KeyStoreSupplier reloadKeyStoreSupplier) throws GeneralSecurityException, IOException {
|
||||
KeyStore trustStore = initialKeyStoreSupplier.get();
|
||||
trustStore.load(null, null);
|
||||
trustStore.setCertificateEntry(ALIAS, caCertificate);
|
||||
|
||||
KeyStore roundTrip = roundTrip(trustStore, reloadKeyStoreSupplier);
|
||||
assertEquals(caCertificate, roundTrip.getCertificate(ALIAS));
|
||||
}
|
||||
|
||||
private void testKeyStoreRoundTrip(KeyStoreSupplier keyStoreSupplier) throws GeneralSecurityException, IOException {
|
||||
testKeyStoreRoundTrip(keyStoreSupplier, keyStoreSupplier, BAD_TEST_PASSWORD_DONT_USE_THIS);
|
||||
}
|
||||
|
||||
private void testKeyStoreRoundTrip(KeyStoreSupplier initialKeyStoreSupplier, KeyStoreSupplier reloadKeyStoreSupplier, char[] keyPassword) throws GeneralSecurityException, IOException {
|
||||
KeyStore keyStore = initialKeyStoreSupplier.get();
|
||||
keyStore.load(null, null);
|
||||
keyStore.setKeyEntry(ALIAS, issuedCertificateKeyPair.getPrivate(), keyPassword, new Certificate[]{issuedCertificate, caCertificate});
|
||||
|
||||
KeyStore roundTrip = roundTrip(keyStore, reloadKeyStoreSupplier);
|
||||
KeyStore.Entry entry = roundTrip.getEntry(ALIAS, new KeyStore.PasswordProtection(keyPassword));
|
||||
assertTrue(entry instanceof KeyStore.PrivateKeyEntry);
|
||||
KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) entry;
|
||||
|
||||
Certificate[] certificateChain = privateKeyEntry.getCertificateChain();
|
||||
assertArrayEquals(new Certificate[]{issuedCertificate, caCertificate}, certificateChain);
|
||||
assertEquals(issuedCertificateKeyPair.getPrivate(), privateKeyEntry.getPrivateKey());
|
||||
assertEquals(issuedCertificateKeyPair.getPublic(), certificateChain[0].getPublicKey());
|
||||
}
|
||||
|
||||
private KeyStore roundTrip(KeyStore keyStore, KeyStoreSupplier keyStoreSupplier) throws GeneralSecurityException, IOException {
|
||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||
keyStore.store(byteArrayOutputStream, BAD_KEY_STORE_TEST_PASSWORD_DONT_USE_THIS);
|
||||
|
||||
KeyStore result = keyStoreSupplier.get();
|
||||
result.load(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()), BAD_KEY_STORE_TEST_PASSWORD_DONT_USE_THIS);
|
||||
return result;
|
||||
}
|
||||
|
||||
private interface KeyStoreSupplier {
|
||||
KeyStore get() throws GeneralSecurityException;
|
||||
}
|
||||
}
|
|
@ -28,6 +28,7 @@ import org.apache.nifi.remote.exception.UnknownPortException;
|
|||
import org.apache.nifi.remote.protocol.DataPacket;
|
||||
import org.apache.nifi.remote.protocol.SiteToSiteTransportProtocol;
|
||||
import org.apache.nifi.remote.protocol.http.HttpProxy;
|
||||
import org.apache.nifi.security.util.KeyStoreUtils;
|
||||
|
||||
import javax.net.ssl.KeyManagerFactory;
|
||||
import javax.net.ssl.SSLContext;
|
||||
|
@ -768,7 +769,7 @@ public interface SiteToSiteClient extends Closeable {
|
|||
if (keystoreFilename != null && keystorePass != null && keystoreType != null) {
|
||||
try {
|
||||
// prepare the keystore
|
||||
final KeyStore keyStore = KeyStore.getInstance(getKeystoreType().name());
|
||||
final KeyStore keyStore = KeyStoreUtils.getKeyStore(getKeystoreType().name());
|
||||
try (final InputStream keyStoreStream = new FileInputStream(new File(getKeystoreFilename()))) {
|
||||
keyStore.load(keyStoreStream, keystorePass.toCharArray());
|
||||
}
|
||||
|
@ -785,7 +786,7 @@ public interface SiteToSiteClient extends Closeable {
|
|||
if (truststoreFilename != null && truststorePass != null && truststoreType != null) {
|
||||
try {
|
||||
// prepare the truststore
|
||||
final KeyStore trustStore = KeyStore.getInstance(getTruststoreType().name());
|
||||
final KeyStore trustStore = KeyStoreUtils.getTrustStore(getTruststoreType().name());
|
||||
try (final InputStream trustStoreStream = new FileInputStream(new File(getTruststoreFilename()))) {
|
||||
trustStore.load(trustStoreStream, truststorePass.toCharArray());
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ import javax.net.ssl.SSLContext;
|
|||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.TrustManagerFactory;
|
||||
|
||||
import org.apache.nifi.security.util.KeyStoreUtils;
|
||||
import org.apache.nifi.util.NiFiProperties;
|
||||
import org.apache.nifi.util.file.FileUtils;
|
||||
|
||||
|
@ -58,7 +59,7 @@ public class SSLContextFactory {
|
|||
truststoreType = properties.getProperty(NiFiProperties.SECURITY_TRUSTSTORE_TYPE);
|
||||
|
||||
// prepare the keystore
|
||||
final KeyStore keyStore = KeyStore.getInstance(keystoreType);
|
||||
final KeyStore keyStore = KeyStoreUtils.getKeyStore(keystoreType);
|
||||
final FileInputStream keyStoreStream = new FileInputStream(keystore);
|
||||
try {
|
||||
keyStore.load(keyStoreStream, keystorePass);
|
||||
|
@ -69,7 +70,7 @@ public class SSLContextFactory {
|
|||
keyManagerFactory.init(keyStore, keystorePass);
|
||||
|
||||
// prepare the truststore
|
||||
final KeyStore trustStore = KeyStore.getInstance(truststoreType);
|
||||
final KeyStore trustStore = KeyStoreUtils.getTrustStore(truststoreType);
|
||||
final FileInputStream trustStoreStream = new FileInputStream(truststore);
|
||||
try {
|
||||
trustStore.load(trustStoreStream, truststorePass);
|
||||
|
|
|
@ -139,12 +139,12 @@ NiFi provides several different configuration options for security purposes. The
|
|||
|==================================================================================================================================================
|
||||
| Property Name | Description
|
||||
|`nifi.security.keystore` | Filename of the Keystore that contains the server's private key.
|
||||
|`nifi.security.keystoreType` | The type of Keystore. Must be either `PKCS12` or `JKS`.
|
||||
|`nifi.security.keystoreType` | The type of Keystore. Must be either `PKCS12` or `JKS`. JKS is the preferred type, PKCS12 files will be loaded with BouncyCastle provider.
|
||||
|`nifi.security.keystorePasswd` | The password for the Keystore.
|
||||
|`nifi.security.keyPasswd` | The password for the certificate in the Keystore. If not set, the value of `nifi.security.keystorePasswd` will be used.
|
||||
|`nifi.security.truststore` | Filename of the Truststore that will be used to authorize those connecting to NiFi. If not set, all who
|
||||
attempt to connect will be provided access as the 'Anonymous' user.
|
||||
|`nifi.security.truststoreType` | The type of the Truststore. Must be either `PKCS12` or `JKS`.
|
||||
|`nifi.security.truststoreType` | The type of the Truststore. Must be either `PKCS12` or `JKS`. JKS is the preferred type, PKCS12 files will be loaded with BouncyCastle provider.
|
||||
|`nifi.security.truststorePasswd` | The password for the Truststore.
|
||||
|`nifi.security.needClientAuth` | Specifies whether or not connecting clients must authenticate themselves. Specifically this property is used
|
||||
by the NiFi cluster protocol. If the Truststore properties are not set, this must be `false`. Otherwise, a value
|
||||
|
@ -174,6 +174,8 @@ TLS Generation Toolkit
|
|||
|
||||
In order to facilitate the secure setup of NiFi, you can use the `tls-toolkit` command line utility to automatically generate the required keystores, truststore, and relevant configuration files. This is especially useful for securing multiple NiFi nodes, which can be a tedious and error-prone process.
|
||||
|
||||
Note: JKS keystores and truststores are recommended for NiFi. This tool allows the specification of other keystore types on the command line but will ignore a type of PKCS12 for use as the truststore because that format has some compatibility issues between BouncyCastle and Oracle implementations.
|
||||
|
||||
The `tls-toolkit` command line tool has two primary modes of operation:
|
||||
|
||||
1. Standalone -- generates the certificate authority, keystores, truststores, and nifi.properties files in one command.
|
||||
|
|
|
@ -28,6 +28,8 @@ import java.security.cert.CertificateException;
|
|||
import javax.net.ssl.KeyManagerFactory;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.TrustManagerFactory;
|
||||
|
||||
import org.apache.nifi.security.util.KeyStoreUtils;
|
||||
import org.apache.nifi.util.NiFiProperties;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
|
@ -65,11 +67,10 @@ public final class SslContextFactory {
|
|||
}
|
||||
|
||||
try {
|
||||
|
||||
// prepare the trust store
|
||||
final KeyStore trustStore;
|
||||
if (hasTruststoreProperties(props)) {
|
||||
trustStore = KeyStore.getInstance(props.getProperty(NiFiProperties.SECURITY_TRUSTSTORE_TYPE));
|
||||
trustStore = KeyStoreUtils.getTrustStore(props.getProperty(NiFiProperties.SECURITY_TRUSTSTORE_TYPE));
|
||||
try (final InputStream trustStoreStream = new FileInputStream(props.getProperty(NiFiProperties.SECURITY_TRUSTSTORE))) {
|
||||
trustStore.load(trustStoreStream, props.getProperty(NiFiProperties.SECURITY_TRUSTSTORE_PASSWD).toCharArray());
|
||||
}
|
||||
|
@ -80,7 +81,7 @@ public final class SslContextFactory {
|
|||
trustManagerFactory.init(trustStore);
|
||||
|
||||
// prepare the key store
|
||||
final KeyStore keyStore = KeyStore.getInstance(props.getProperty(NiFiProperties.SECURITY_KEYSTORE_TYPE));
|
||||
final KeyStore keyStore = KeyStoreUtils.getKeyStore(props.getProperty(NiFiProperties.SECURITY_KEYSTORE_TYPE));
|
||||
try (final InputStream keyStoreStream = new FileInputStream(props.getProperty(NiFiProperties.SECURITY_KEYSTORE))) {
|
||||
keyStore.load(keyStoreStream, props.getProperty(NiFiProperties.SECURITY_KEYSTORE_PASSWD).toCharArray());
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import org.apache.nifi.controller.serialization.FlowSynchronizationException;
|
|||
import org.apache.nifi.lifecycle.LifeCycleStartException;
|
||||
import org.apache.nifi.nar.ExtensionMapping;
|
||||
import org.apache.nifi.nar.NarClassLoaders;
|
||||
import org.apache.nifi.security.util.KeyStoreUtils;
|
||||
import org.apache.nifi.services.FlowService;
|
||||
import org.apache.nifi.ui.extension.UiExtension;
|
||||
import org.apache.nifi.ui.extension.UiExtensionMapping;
|
||||
|
@ -630,8 +631,13 @@ public class JettyServer implements NiFiServer {
|
|||
if (StringUtils.isNotBlank(props.getProperty(NiFiProperties.SECURITY_KEYSTORE))) {
|
||||
contextFactory.setKeyStorePath(props.getProperty(NiFiProperties.SECURITY_KEYSTORE));
|
||||
}
|
||||
if (StringUtils.isNotBlank(props.getProperty(NiFiProperties.SECURITY_KEYSTORE_TYPE))) {
|
||||
contextFactory.setKeyStoreType(props.getProperty(NiFiProperties.SECURITY_KEYSTORE_TYPE));
|
||||
String keyStoreType = props.getProperty(NiFiProperties.SECURITY_KEYSTORE_TYPE);
|
||||
if (StringUtils.isNotBlank(keyStoreType)) {
|
||||
contextFactory.setKeyStoreType(keyStoreType);
|
||||
String keyStoreProvider = KeyStoreUtils.getKeyStoreProvider(keyStoreType);
|
||||
if (StringUtils.isNoneEmpty(keyStoreProvider)) {
|
||||
contextFactory.setKeyStoreProvider(keyStoreProvider);
|
||||
}
|
||||
}
|
||||
final String keystorePassword = props.getProperty(NiFiProperties.SECURITY_KEYSTORE_PASSWD);
|
||||
final String keyPassword = props.getProperty(NiFiProperties.SECURITY_KEY_PASSWD);
|
||||
|
@ -649,8 +655,13 @@ public class JettyServer implements NiFiServer {
|
|||
if (StringUtils.isNotBlank(props.getProperty(NiFiProperties.SECURITY_TRUSTSTORE))) {
|
||||
contextFactory.setTrustStorePath(props.getProperty(NiFiProperties.SECURITY_TRUSTSTORE));
|
||||
}
|
||||
if (StringUtils.isNotBlank(props.getProperty(NiFiProperties.SECURITY_TRUSTSTORE_TYPE))) {
|
||||
contextFactory.setTrustStoreType(props.getProperty(NiFiProperties.SECURITY_TRUSTSTORE_TYPE));
|
||||
String trustStoreType = props.getProperty(NiFiProperties.SECURITY_TRUSTSTORE_TYPE);
|
||||
if (StringUtils.isNotBlank(trustStoreType)) {
|
||||
contextFactory.setTrustStoreType(trustStoreType);
|
||||
String trustStoreProvider = KeyStoreUtils.getKeyStoreProvider(trustStoreType);
|
||||
if (StringUtils.isNoneEmpty(trustStoreProvider)) {
|
||||
contextFactory.setTrustStoreProvider(trustStoreProvider);
|
||||
}
|
||||
}
|
||||
if (StringUtils.isNotBlank(props.getProperty(NiFiProperties.SECURITY_TRUSTSTORE_PASSWD))) {
|
||||
contextFactory.setTrustStorePassword(props.getProperty(NiFiProperties.SECURITY_TRUSTSTORE_PASSWD));
|
||||
|
|
|
@ -20,6 +20,9 @@ package org.apache.nifi.web.server;
|
|||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.nifi.security.util.KeystoreType;
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||
import org.apache.nifi.util.NiFiProperties;
|
||||
import org.junit.Test;
|
||||
|
@ -80,4 +83,63 @@ public class JettyServerTest {
|
|||
verify(contextFactory).setKeyManagerPassword(testKeystorePassword);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConfigureSslContextFactoryWithJksKeyStore() {
|
||||
// Expect that we will not set provider for jks keystore
|
||||
final Map<String, String> addProps = new HashMap<>();
|
||||
String keyStoreType = KeystoreType.JKS.toString();
|
||||
addProps.put(NiFiProperties.SECURITY_KEYSTORE_TYPE, keyStoreType);
|
||||
NiFiProperties nifiProperties = NiFiProperties.createBasicNiFiProperties(null, addProps);
|
||||
SslContextFactory contextFactory = mock(SslContextFactory.class);
|
||||
|
||||
JettyServer.configureSslContextFactory(contextFactory, nifiProperties);
|
||||
|
||||
verify(contextFactory).setKeyStoreType(keyStoreType);
|
||||
verify(contextFactory, never()).setKeyStoreProvider(anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConfigureSslContextFactoryWithPkcsKeyStore() {
|
||||
// Expect that we will set Bouncy Castle provider for pkcs12 keystore
|
||||
final Map<String, String> addProps = new HashMap<>();
|
||||
String keyStoreType = KeystoreType.PKCS12.toString();
|
||||
addProps.put(NiFiProperties.SECURITY_KEYSTORE_TYPE, keyStoreType);
|
||||
NiFiProperties nifiProperties = NiFiProperties.createBasicNiFiProperties(null, addProps);
|
||||
SslContextFactory contextFactory = mock(SslContextFactory.class);
|
||||
|
||||
JettyServer.configureSslContextFactory(contextFactory, nifiProperties);
|
||||
|
||||
verify(contextFactory).setKeyStoreType(keyStoreType);
|
||||
verify(contextFactory).setKeyStoreProvider(BouncyCastleProvider.PROVIDER_NAME);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConfigureSslContextFactoryWithJksTrustStore() {
|
||||
// Expect that we will not set provider for jks truststore
|
||||
final Map<String, String> addProps = new HashMap<>();
|
||||
String trustStoreType = KeystoreType.JKS.toString();
|
||||
addProps.put(NiFiProperties.SECURITY_TRUSTSTORE_TYPE, trustStoreType);
|
||||
NiFiProperties nifiProperties = NiFiProperties.createBasicNiFiProperties(null, addProps);
|
||||
SslContextFactory contextFactory = mock(SslContextFactory.class);
|
||||
|
||||
JettyServer.configureSslContextFactory(contextFactory, nifiProperties);
|
||||
|
||||
verify(contextFactory).setTrustStoreType(trustStoreType);
|
||||
verify(contextFactory, never()).setTrustStoreProvider(anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConfigureSslContextFactoryWithPkcsTrustStore() {
|
||||
// Expect that we will set Bouncy Castle provider for pkcs12 truststore
|
||||
final Map<String, String> addProps = new HashMap<>();
|
||||
String trustStoreType = KeystoreType.PKCS12.toString();
|
||||
addProps.put(NiFiProperties.SECURITY_TRUSTSTORE_TYPE, trustStoreType);
|
||||
NiFiProperties nifiProperties = NiFiProperties.createBasicNiFiProperties(null, addProps);
|
||||
SslContextFactory contextFactory = mock(SslContextFactory.class);
|
||||
|
||||
JettyServer.configureSslContextFactory(contextFactory, nifiProperties);
|
||||
|
||||
verify(contextFactory).setTrustStoreType(trustStoreType);
|
||||
verify(contextFactory).setTrustStoreProvider(BouncyCastleProvider.PROVIDER_NAME);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ import com.sun.jersey.api.client.config.ClientConfig;
|
|||
import com.sun.jersey.api.client.config.DefaultClientConfig;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.nifi.framework.security.util.SslContextFactory;
|
||||
import org.apache.nifi.security.util.KeyStoreUtils;
|
||||
import org.apache.nifi.util.FormatUtils;
|
||||
import org.apache.nifi.util.NiFiProperties;
|
||||
import org.apache.nifi.web.security.x509.ocsp.OcspStatus.ValidationStatus;
|
||||
|
@ -192,7 +193,7 @@ public class OcspCertificateValidator {
|
|||
|
||||
// load the configured truststore
|
||||
try (final FileInputStream fis = new FileInputStream(truststorePath)) {
|
||||
final KeyStore truststore = KeyStore.getInstance(KeyStore.getDefaultType());
|
||||
final KeyStore truststore = KeyStoreUtils.getTrustStore(KeyStore.getDefaultType());
|
||||
truststore.load(fis, truststorePassword);
|
||||
|
||||
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
|
||||
|
|
|
@ -89,6 +89,7 @@ import org.apache.nifi.processor.ProcessorInitializationContext;
|
|||
import org.apache.nifi.processor.Relationship;
|
||||
import org.apache.nifi.processor.exception.ProcessException;
|
||||
import org.apache.nifi.processor.util.StandardValidators;
|
||||
import org.apache.nifi.security.util.KeyStoreUtils;
|
||||
import org.apache.nifi.ssl.SSLContextService;
|
||||
import org.apache.nifi.ssl.SSLContextService.ClientAuth;
|
||||
import org.apache.nifi.util.StopWatch;
|
||||
|
@ -311,7 +312,7 @@ public class GetHTTP extends AbstractSessionFactoryProcessor {
|
|||
final SSLContextBuilder sslContextBuilder = new SSLContextBuilder();
|
||||
|
||||
if (StringUtils.isNotBlank(service.getTrustStoreFile())) {
|
||||
final KeyStore truststore = KeyStore.getInstance(service.getTrustStoreType());
|
||||
final KeyStore truststore = KeyStoreUtils.getTrustStore(service.getTrustStoreType());
|
||||
try (final InputStream in = new FileInputStream(new File(service.getTrustStoreFile()))) {
|
||||
truststore.load(in, service.getTrustStorePassword().toCharArray());
|
||||
}
|
||||
|
@ -319,7 +320,7 @@ public class GetHTTP extends AbstractSessionFactoryProcessor {
|
|||
}
|
||||
|
||||
if (StringUtils.isNotBlank(service.getKeyStoreFile())){
|
||||
final KeyStore keystore = KeyStore.getInstance(service.getKeyStoreType());
|
||||
final KeyStore keystore = KeyStoreUtils.getKeyStore(service.getKeyStoreType());
|
||||
try (final InputStream in = new FileInputStream(new File(service.getKeyStoreFile()))) {
|
||||
keystore.load(in, service.getKeyStorePassword().toCharArray());
|
||||
}
|
||||
|
|
|
@ -106,6 +106,7 @@ import org.apache.nifi.processor.exception.ProcessException;
|
|||
import org.apache.nifi.processor.io.InputStreamCallback;
|
||||
import org.apache.nifi.processor.util.StandardValidators;
|
||||
import org.apache.nifi.security.util.CertificateUtils;
|
||||
import org.apache.nifi.security.util.KeyStoreUtils;
|
||||
import org.apache.nifi.ssl.SSLContextService;
|
||||
import org.apache.nifi.stream.io.BufferedInputStream;
|
||||
import org.apache.nifi.stream.io.BufferedOutputStream;
|
||||
|
@ -422,7 +423,7 @@ public class PostHTTP extends AbstractProcessor {
|
|||
SSLContextBuilder builder = SSLContexts.custom();
|
||||
final String trustFilename = service.getTrustStoreFile();
|
||||
if (trustFilename != null) {
|
||||
final KeyStore truststore = KeyStore.getInstance(service.getTrustStoreType());
|
||||
final KeyStore truststore = KeyStoreUtils.getTrustStore(service.getTrustStoreType());
|
||||
try (final InputStream in = new FileInputStream(new File(service.getTrustStoreFile()))) {
|
||||
truststore.load(in, service.getTrustStorePassword().toCharArray());
|
||||
}
|
||||
|
@ -431,7 +432,7 @@ public class PostHTTP extends AbstractProcessor {
|
|||
|
||||
final String keyFilename = service.getKeyStoreFile();
|
||||
if (keyFilename != null) {
|
||||
final KeyStore keystore = KeyStore.getInstance(service.getKeyStoreType());
|
||||
final KeyStore keystore = KeyStoreUtils.getKeyStore(service.getKeyStoreType());
|
||||
try (final InputStream in = new FileInputStream(new File(service.getKeyStoreFile()))) {
|
||||
keystore.load(in, service.getKeyStorePassword().toCharArray());
|
||||
}
|
||||
|
|
|
@ -23,13 +23,17 @@ 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.security.util.KeystoreType;
|
||||
import org.apache.nifi.toolkit.tls.TlsToolkitMain;
|
||||
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 BaseCommandLine {
|
||||
private static final Logger logger = LoggerFactory.getLogger(BaseCommandLine.class);
|
||||
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";
|
||||
|
@ -202,6 +206,10 @@ public abstract class BaseCommandLine {
|
|||
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);
|
||||
} catch (ParseException e) {
|
||||
|
|
|
@ -38,7 +38,6 @@ public class TlsClientConfig extends TlsConfig {
|
|||
setCaHostname(tlsConfig.getCaHostname());
|
||||
setPort(tlsConfig.getPort());
|
||||
setKeyStoreType(tlsConfig.getKeyStoreType());
|
||||
setTrustStoreType(tlsConfig.getKeyStoreType());
|
||||
setKeyPairAlgorithm(tlsConfig.getKeyPairAlgorithm());
|
||||
setKeySize(tlsConfig.getKeySize());
|
||||
setSigningAlgorithm(tlsConfig.getSigningAlgorithm());
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
|
||||
package org.apache.nifi.toolkit.tls.manager;
|
||||
|
||||
import org.apache.nifi.security.util.KeystoreType;
|
||||
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;
|
||||
|
@ -24,7 +26,6 @@ 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.jce.provider.BouncyCastleProvider;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
|
@ -33,8 +34,6 @@ import java.io.InputStream;
|
|||
import java.security.GeneralSecurityException;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyStore;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.NoSuchProviderException;
|
||||
import java.security.cert.Certificate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -43,7 +42,6 @@ import java.util.List;
|
|||
* Base class for managing KeyStores and Certificates
|
||||
*/
|
||||
public class BaseTlsManager {
|
||||
public static final String PKCS_12 = "PKCS12";
|
||||
private final TlsConfig tlsConfig;
|
||||
private final PasswordUtil passwordUtil;
|
||||
private final InputStreamFactory inputStreamFactory;
|
||||
|
@ -110,7 +108,7 @@ public class BaseTlsManager {
|
|||
}
|
||||
|
||||
private String getKeyPassword() {
|
||||
if (keyStore.getType().equalsIgnoreCase(PKCS_12)) {
|
||||
if (keyStore.getType().equalsIgnoreCase(KeystoreType.PKCS12.toString())) {
|
||||
tlsConfig.setKeyPassword(null);
|
||||
return null;
|
||||
} else {
|
||||
|
@ -137,16 +135,8 @@ public class BaseTlsManager {
|
|||
return result;
|
||||
}
|
||||
|
||||
private KeyStore getInstance(String keyStoreType) throws KeyStoreException, NoSuchProviderException {
|
||||
if (PKCS_12.equalsIgnoreCase(keyStoreType)) {
|
||||
return KeyStore.getInstance(keyStoreType, BouncyCastleProvider.PROVIDER_NAME);
|
||||
} else {
|
||||
return KeyStore.getInstance(keyStoreType);
|
||||
}
|
||||
}
|
||||
|
||||
protected KeyStore loadKeystore(String keyStore, String keyStoreType, String keyStorePassword) throws GeneralSecurityException, IOException {
|
||||
KeyStore result = getInstance(keyStoreType);
|
||||
KeyStore result = KeyStoreUtils.getKeyStore(keyStoreType);
|
||||
File file = new File(keyStore);
|
||||
if (file.exists()) {
|
||||
try (InputStream stream = inputStreamFactory.create(file)) {
|
||||
|
|
|
@ -24,7 +24,6 @@ import org.apache.nifi.toolkit.tls.commandLine.ExitCode;
|
|||
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.toolkit.tls.util.TlsHelper;
|
||||
import org.apache.nifi.util.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -60,7 +59,6 @@ public class TlsCertificateAuthorityClientCommandLine extends BaseCertificateAut
|
|||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
TlsHelper.addBouncyCastleProvider();
|
||||
TlsCertificateAuthorityClientCommandLine tlsCertificateAuthorityClientCommandLine = new TlsCertificateAuthorityClientCommandLine();
|
||||
try {
|
||||
tlsCertificateAuthorityClientCommandLine.parse(args);
|
||||
|
@ -135,8 +133,7 @@ public class TlsCertificateAuthorityClientCommandLine extends BaseCertificateAut
|
|||
tlsClientConfig.setPort(getPort());
|
||||
tlsClientConfig.setKeyStore(KEYSTORE + getKeyStoreType().toLowerCase());
|
||||
tlsClientConfig.setKeyStoreType(getKeyStoreType());
|
||||
tlsClientConfig.setTrustStore(TRUSTSTORE + getKeyStoreType().toLowerCase());
|
||||
tlsClientConfig.setTrustStoreType(getKeyStoreType());
|
||||
tlsClientConfig.setTrustStore(TRUSTSTORE + tlsClientConfig.getTrustStoreType().toLowerCase());
|
||||
tlsClientConfig.setKeySize(getKeySize());
|
||||
tlsClientConfig.setKeyPairAlgorithm(getKeyAlgorithm());
|
||||
tlsClientConfig.setSigningAlgorithm(getSigningAlgorithm());
|
||||
|
|
|
@ -22,7 +22,6 @@ 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.toolkit.tls.util.TlsHelper;
|
||||
import org.apache.nifi.util.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
|
@ -49,7 +48,6 @@ public class TlsCertificateAuthorityServiceCommandLine extends BaseCertificateAu
|
|||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
TlsHelper.addBouncyCastleProvider();
|
||||
TlsCertificateAuthorityServiceCommandLine tlsCertificateAuthorityServiceCommandLine = new TlsCertificateAuthorityServiceCommandLine();
|
||||
try {
|
||||
tlsCertificateAuthorityServiceCommandLine.parse(args);
|
||||
|
|
|
@ -18,17 +18,17 @@
|
|||
package org.apache.nifi.toolkit.tls.standalone;
|
||||
|
||||
import org.apache.nifi.security.util.CertificateUtils;
|
||||
import org.apache.nifi.security.util.KeystoreType;
|
||||
import org.apache.nifi.security.util.KeyStoreUtils;
|
||||
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.BaseTlsManager;
|
||||
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.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.bouncycastle.openssl.jcajce.JcaMiscPEMGenerator;
|
||||
import org.bouncycastle.util.io.pem.PemWriter;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -214,7 +214,7 @@ public class TlsToolkitStandalone {
|
|||
}
|
||||
KeyPair keyPair = TlsHelper.generateKeyPair(keyPairAlgorithm, keySize);
|
||||
X509Certificate clientCert = CertificateUtils.generateIssuedCertificate(reorderedDn, keyPair.getPublic(), certificate, caKeyPair, signingAlgorithm, days);
|
||||
KeyStore keyStore = KeyStore.getInstance(BaseTlsManager.PKCS_12, BouncyCastleProvider.PROVIDER_NAME);
|
||||
KeyStore keyStore = KeyStoreUtils.getKeyStore(KeystoreType.PKCS12.toString());
|
||||
keyStore.load(null, null);
|
||||
keyStore.setKeyEntry(NIFI_KEY, keyPair.getPrivate(), null, new Certificate[]{clientCert, certificate});
|
||||
String password = TlsHelper.writeKeyStore(keyStore, outputStreamFactory, clientCertFile, clientPasswords.get(i), standaloneConfig.isClientPasswordsGenerated());
|
||||
|
|
|
@ -26,7 +26,6 @@ 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.toolkit.tls.util.TlsHelper;
|
||||
import org.apache.nifi.util.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -100,7 +99,6 @@ public class TlsToolkitStandaloneCommandLine extends BaseCommandLine {
|
|||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
TlsHelper.addBouncyCastleProvider();
|
||||
TlsToolkitStandaloneCommandLine tlsToolkitStandaloneCommandLine = new TlsToolkitStandaloneCommandLine();
|
||||
try {
|
||||
tlsToolkitStandaloneCommandLine.parse(args);
|
||||
|
|
|
@ -51,7 +51,6 @@ import java.security.KeyPairGenerator;
|
|||
import java.security.KeyStore;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PublicKey;
|
||||
import java.security.Security;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
|
@ -128,10 +127,6 @@ public class TlsHelper {
|
|||
return password;
|
||||
}
|
||||
|
||||
public static void addBouncyCastleProvider() {
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
}
|
||||
|
||||
private static KeyPairGenerator createKeyPairGenerator(String algorithm, int keySize) throws NoSuchAlgorithmException {
|
||||
KeyPairGenerator instance = KeyPairGenerator.getInstance(algorithm);
|
||||
instance.initialize(keySize);
|
||||
|
|
|
@ -18,16 +18,17 @@
|
|||
package org.apache.nifi.toolkit.tls.service;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.apache.nifi.security.util.KeystoreType;
|
||||
import org.apache.nifi.security.util.KeyStoreUtils;
|
||||
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.client.TlsCertificateAuthorityClientCommandLine;
|
||||
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.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
|
@ -45,7 +46,6 @@ import java.security.NoSuchAlgorithmException;
|
|||
import java.security.NoSuchProviderException;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.Security;
|
||||
import java.security.Signature;
|
||||
import java.security.SignatureException;
|
||||
import java.security.UnrecoverableEntryException;
|
||||
|
@ -74,11 +74,6 @@ public class TlsCertificateAuthorityTest {
|
|||
private ByteArrayOutputStream serverConfigFileOutputStream;
|
||||
private ByteArrayOutputStream clientConfigFileOutputStream;
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() {
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setup() throws FileNotFoundException {
|
||||
objectMapper = new ObjectMapper();
|
||||
|
@ -136,7 +131,7 @@ public class TlsCertificateAuthorityTest {
|
|||
}
|
||||
|
||||
private void mockReturnOutputStream(OutputStreamFactory outputStreamFactory, File file, OutputStream outputStream) throws FileNotFoundException {
|
||||
when(outputStreamFactory.create(or(eq(file), eq(new File(file.getAbsolutePath()))))).thenReturn(outputStream).thenReturn(null);
|
||||
when(outputStreamFactory.create(or(eq(file), eq(new File(file.getAbsolutePath()))))).thenReturn(outputStream);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -171,6 +166,25 @@ public class TlsCertificateAuthorityTest {
|
|||
}
|
||||
}
|
||||
|
||||
@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);
|
||||
TlsCertificateAuthorityClient tlsCertificateAuthorityClient = new TlsCertificateAuthorityClient(outputStreamFactory);
|
||||
new TlsCertificateAuthorityClientCommandLine(inputStreamFactory);
|
||||
tlsCertificateAuthorityClient.generateCertificateAndGetItSigned(clientConfig, null, clientConfigFile.getAbsolutePath(), true);
|
||||
validate();
|
||||
} finally {
|
||||
if (tlsCertificateAuthorityService != null) {
|
||||
tlsCertificateAuthorityService.shutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTokenMismatch() throws Exception {
|
||||
serverConfig.setToken("a different token...");
|
||||
|
@ -192,9 +206,11 @@ public class TlsCertificateAuthorityTest {
|
|||
InvalidKeyException, NoSuchProviderException, SignatureException {
|
||||
serverConfig = objectMapper.readValue(new ByteArrayInputStream(serverConfigFileOutputStream.toByteArray()), TlsConfig.class);
|
||||
|
||||
KeyStore serverKeyStore = KeyStore.getInstance(serverConfig.getKeyStoreType());
|
||||
KeyStore serverKeyStore = KeyStoreUtils.getKeyStore(serverConfig.getKeyStoreType());
|
||||
serverKeyStore.load(new ByteArrayInputStream(serverKeyStoreOutputStream.toByteArray()), serverConfig.getKeyStorePassword().toCharArray());
|
||||
KeyStore.Entry serverKeyEntry = serverKeyStore.getEntry(TlsToolkitStandalone.NIFI_KEY, new KeyStore.PasswordProtection(serverConfig.getKeyPassword().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;
|
||||
|
@ -210,9 +226,11 @@ public class TlsCertificateAuthorityTest {
|
|||
UnrecoverableEntryException, InvalidKeyException, NoSuchProviderException, SignatureException {
|
||||
clientConfig = objectMapper.readValue(new ByteArrayInputStream(clientConfigFileOutputStream.toByteArray()), TlsClientConfig.class);
|
||||
|
||||
KeyStore clientKeyStore = KeyStore.getInstance(clientConfig.getKeyStoreType());
|
||||
KeyStore clientKeyStore = KeyStoreUtils.getKeyStore(clientConfig.getKeyStoreType());
|
||||
clientKeyStore.load(new ByteArrayInputStream(clientKeyStoreOutputStream.toByteArray()), clientConfig.getKeyStorePassword().toCharArray());
|
||||
KeyStore.Entry clientKeyStoreEntry = clientKeyStore.getEntry(TlsToolkitStandalone.NIFI_KEY, new KeyStore.PasswordProtection(clientConfig.getKeyPassword().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;
|
||||
|
@ -222,7 +240,7 @@ public class TlsCertificateAuthorityTest {
|
|||
certificateChain[0].verify(caCertificate.getPublicKey());
|
||||
assertPrivateAndPublicKeyMatch(clientPrivateKeyEntry.getPrivateKey(), certificateChain[0].getPublicKey());
|
||||
|
||||
KeyStore clientTrustStore = KeyStore.getInstance(clientConfig.getTrustStoreType());
|
||||
KeyStore clientTrustStore = KeyStoreUtils.getTrustStore(KeystoreType.JKS.toString());
|
||||
clientTrustStore.load(new ByteArrayInputStream(clientTrustStoreOutputStream.toByteArray()), clientConfig.getTrustStorePassword().toCharArray());
|
||||
assertEquals(caCertificate, clientTrustStore.getCertificate(TlsToolkitStandalone.NIFI_CERT));
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
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;
|
||||
|
@ -129,9 +130,10 @@ public class TlsCertificateAuthorityClientCommandLineTest {
|
|||
|
||||
TlsClientConfig clientConfig = tlsCertificateAuthorityClientCommandLine.createClientConfig();
|
||||
assertEquals(testType, clientConfig.getKeyStoreType());
|
||||
assertEquals(testType, clientConfig.getTrustStoreType());
|
||||
String trustStoreType = KeystoreType.JKS.toString().toLowerCase();
|
||||
assertEquals(trustStoreType, clientConfig.getTrustStoreType());
|
||||
assertEquals(TlsCertificateAuthorityClientCommandLine.KEYSTORE + testType.toLowerCase(), clientConfig.getKeyStore());
|
||||
assertEquals(TlsCertificateAuthorityClientCommandLine.TRUSTSTORE + testType.toLowerCase(), clientConfig.getTrustStore());
|
||||
assertEquals(TlsCertificateAuthorityClientCommandLine.TRUSTSTORE + trustStoreType, clientConfig.getTrustStore());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -35,7 +35,6 @@ import org.bouncycastle.operator.OperatorCreationException;
|
|||
import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest;
|
||||
import org.eclipse.jetty.server.Response;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
|
@ -91,11 +90,6 @@ public class TlsCertificateSigningRequestPerformerTest {
|
|||
private byte[] testHmac;
|
||||
private String testSignedCsr;
|
||||
|
||||
@BeforeClass
|
||||
public static void before() {
|
||||
TlsHelper.addBouncyCastleProvider();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setup() throws GeneralSecurityException, OperatorCreationException, IOException {
|
||||
objectMapper = new ObjectMapper();
|
||||
|
|
|
@ -30,7 +30,6 @@ import org.eclipse.jetty.server.Request;
|
|||
import org.eclipse.jetty.server.Response;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
|
@ -97,11 +96,6 @@ public class TlsCertificateAuthorityServiceHandlerTest {
|
|||
private String requestedDn;
|
||||
private KeyPair certificateKeyPair;
|
||||
|
||||
@BeforeClass
|
||||
public static void before() {
|
||||
TlsHelper.addBouncyCastleProvider();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
testToken = "testToken";
|
||||
|
|
|
@ -20,15 +20,15 @@ package org.apache.nifi.toolkit.tls.standalone;
|
|||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.nifi.security.util.CertificateUtils;
|
||||
import org.apache.nifi.security.util.KeystoreType;
|
||||
import org.apache.nifi.security.util.KeyStoreUtils;
|
||||
import org.apache.nifi.toolkit.tls.SystemExitCapturer;
|
||||
import org.apache.nifi.toolkit.tls.commandLine.BaseCommandLine;
|
||||
import org.apache.nifi.toolkit.tls.commandLine.ExitCode;
|
||||
import org.apache.nifi.toolkit.tls.configuration.TlsConfig;
|
||||
import org.apache.nifi.toolkit.tls.manager.BaseTlsManager;
|
||||
import org.apache.nifi.toolkit.tls.service.TlsCertificateAuthorityTest;
|
||||
import org.apache.nifi.toolkit.tls.util.TlsHelperTest;
|
||||
import org.apache.nifi.util.NiFiProperties;
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
@ -189,6 +189,14 @@ public class TlsToolkitStandaloneTest {
|
|||
checkHostDirAndReturnNifiProperties(TlsConfig.DEFAULT_HOSTNAME, nifiDnPrefix, nifiDnSuffix, x509Certificate);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testKeyStoreTypeArg() throws Exception {
|
||||
runAndAssertExitCode(ExitCode.SUCCESS, "-o", tempDir.getAbsolutePath(), "-n", TlsConfig.DEFAULT_HOSTNAME, "-T", KeystoreType.PKCS12.toString().toLowerCase(),
|
||||
"-K", "change", "-S", "change", "-P", "change");
|
||||
X509Certificate x509Certificate = checkLoadCertPrivateKey(TlsConfig.DEFAULT_KEY_PAIR_ALGORITHM);
|
||||
checkHostDirAndReturnNifiProperties(TlsConfig.DEFAULT_HOSTNAME, x509Certificate);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClientDnsArg() throws Exception {
|
||||
String clientDn = "OU=NIFI,CN=testuser";
|
||||
|
@ -237,13 +245,14 @@ public class TlsToolkitStandaloneTest {
|
|||
}
|
||||
|
||||
String trustStoreType = nifiProperties.getProperty(NiFiProperties.SECURITY_TRUSTSTORE_TYPE);
|
||||
KeyStore trustStore = KeyStore.getInstance(trustStoreType);
|
||||
assertEquals(KeystoreType.JKS.toString().toLowerCase(), trustStoreType.toLowerCase());
|
||||
KeyStore trustStore = KeyStoreUtils.getTrustStore(trustStoreType);
|
||||
try (InputStream inputStream = new FileInputStream(new File(hostDir, "truststore." + trustStoreType))) {
|
||||
trustStore.load(inputStream, nifiProperties.getProperty(NiFiProperties.SECURITY_TRUSTSTORE_PASSWD).toCharArray());
|
||||
}
|
||||
|
||||
String trustStoreFilename = BaseCommandLine.KEYSTORE + trustStoreType;
|
||||
assertEquals("./conf/" + trustStoreFilename, nifiProperties.getProperty(NiFiProperties.SECURITY_KEYSTORE));
|
||||
String trustStoreFilename = BaseCommandLine.TRUSTSTORE + trustStoreType;
|
||||
assertEquals("./conf/" + trustStoreFilename, nifiProperties.getProperty(NiFiProperties.SECURITY_TRUSTSTORE));
|
||||
|
||||
Certificate certificate = trustStore.getCertificate(TlsToolkitStandalone.NIFI_CERT);
|
||||
assertEquals(rootCert, certificate);
|
||||
|
@ -253,12 +262,16 @@ public class TlsToolkitStandaloneTest {
|
|||
File keyStoreFile = new File(hostDir, keyStoreFilename);
|
||||
assertEquals("./conf/" + keyStoreFilename, nifiProperties.getProperty(NiFiProperties.SECURITY_KEYSTORE));
|
||||
|
||||
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
|
||||
KeyStore keyStore = KeyStoreUtils.getKeyStore(keyStoreType);
|
||||
char[] keyStorePassword = nifiProperties.getProperty(NiFiProperties.SECURITY_KEYSTORE_PASSWD).toCharArray();
|
||||
try (InputStream inputStream = new FileInputStream(keyStoreFile)) {
|
||||
keyStore.load(inputStream, nifiProperties.getProperty(NiFiProperties.SECURITY_KEYSTORE_PASSWD).toCharArray());
|
||||
keyStore.load(inputStream, keyStorePassword);
|
||||
}
|
||||
|
||||
char[] keyPassword = nifiProperties.getProperty(NiFiProperties.SECURITY_KEY_PASSWD).toCharArray();
|
||||
if (keyPassword == null || keyPassword.length == 0) {
|
||||
keyPassword = keyStorePassword;
|
||||
}
|
||||
|
||||
KeyStore.Entry entry = keyStore.getEntry(TlsToolkitStandalone.NIFI_KEY, new KeyStore.PasswordProtection(keyPassword));
|
||||
assertEquals(KeyStore.PrivateKeyEntry.class, entry.getClass());
|
||||
|
@ -288,7 +301,7 @@ public class TlsToolkitStandaloneTest {
|
|||
password = lines.get(0);
|
||||
}
|
||||
|
||||
KeyStore keyStore = KeyStore.getInstance(BaseTlsManager.PKCS_12, BouncyCastleProvider.PROVIDER_NAME);
|
||||
KeyStore keyStore = KeyStoreUtils.getKeyStore(KeystoreType.PKCS12.toString());
|
||||
try (FileInputStream fileInputStream = new FileInputStream(new File(tempDir, clientDnFile + ".p12"))) {
|
||||
keyStore.load(fileInputStream, password.toCharArray());
|
||||
}
|
||||
|
|
|
@ -27,7 +27,6 @@ import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
|
|||
import org.bouncycastle.operator.OperatorCreationException;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.AdditionalMatchers;
|
||||
|
@ -51,7 +50,6 @@ import java.security.KeyStoreSpi;
|
|||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchProviderException;
|
||||
import java.security.Provider;
|
||||
import java.security.Security;
|
||||
import java.security.SignatureException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
@ -130,11 +128,6 @@ public class TlsHelperTest {
|
|||
return loadCertificate(new FileReader(file));
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() {
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
days = 360;
|
||||
|
|
Loading…
Reference in New Issue