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:
Bryan Rosander 2016-10-27 10:27:06 -04:00 committed by Andy LoPresto
parent fa13832a9c
commit e5eda63705
No known key found for this signature in database
GPG Key ID: 3C6EF65B2F7DEF69
28 changed files with 403 additions and 101 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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) {

View File

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

View File

@ -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)) {

View 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());

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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