blob: aea74a238910859c5e5fa85eb0bdf81e971c4b4a [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.nifi.security.util
import org.apache.nifi.util.NiFiProperties
import org.bouncycastle.jce.provider.BouncyCastleProvider
import org.junit.After
import org.junit.Before
import org.junit.BeforeClass
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import java.security.Security
@RunWith(JUnit4.class)
class StandardTlsConfigurationTest extends GroovyTestCase {
private static final Logger logger = LoggerFactory.getLogger(StandardTlsConfigurationTest.class)
private static final String KEYSTORE_PATH = "src/test/resources/TlsConfigurationKeystore.jks"
private static final String KEYSTORE_PASSWORD = "keystorepassword"
private static final String KEY_PASSWORD = "keypassword"
private static final KeystoreType KEYSTORE_TYPE = KeystoreType.JKS
private static final String TRUSTSTORE_PATH = "src/test/resources/TlsConfigurationTruststore.jks"
private static final String TRUSTSTORE_PASSWORD = "truststorepassword"
private static final KeystoreType TRUSTSTORE_TYPE = KeystoreType.JKS
private static final Map<String, String> DEFAULT_PROPS = [
(NiFiProperties.SECURITY_KEYSTORE) : KEYSTORE_PATH,
(NiFiProperties.SECURITY_KEYSTORE_PASSWD) : KEYSTORE_PASSWORD,
(NiFiProperties.SECURITY_KEY_PASSWD) : KEY_PASSWORD,
(NiFiProperties.SECURITY_KEYSTORE_TYPE) : KEYSTORE_TYPE.getType(),
(NiFiProperties.SECURITY_TRUSTSTORE) : TRUSTSTORE_PATH,
(NiFiProperties.SECURITY_TRUSTSTORE_PASSWD): TRUSTSTORE_PASSWORD,
(NiFiProperties.SECURITY_TRUSTSTORE_TYPE) : TRUSTSTORE_TYPE.getType(),
]
private NiFiProperties mockNiFiProperties = NiFiProperties.createBasicNiFiProperties("", DEFAULT_PROPS)
private TlsConfiguration tlsConfiguration
@BeforeClass
static void setUpOnce() throws Exception {
Security.addProvider(new BouncyCastleProvider())
logger.metaClass.methodMissing = { String name, args ->
logger.info("[${name?.toUpperCase()}] ${(args as List).join(" ")}")
}
}
@Before
void setUp() throws Exception {
tlsConfiguration = new StandardTlsConfiguration(KEYSTORE_PATH, KEYSTORE_PASSWORD, KEY_PASSWORD, KEYSTORE_TYPE, TRUSTSTORE_PATH, TRUSTSTORE_PASSWORD, TRUSTSTORE_TYPE)
}
@After
void tearDown() throws Exception {
}
@Test
void testShouldCreateFromNiFiProperties() {
// Arrange
// Act
TlsConfiguration fromProperties = StandardTlsConfiguration.fromNiFiProperties(mockNiFiProperties)
logger.info("Created TlsConfiguration: ${fromProperties}")
// Assert
assert fromProperties == tlsConfiguration
}
@Test
void testCreateFromNiFiPropertiesShouldHandleNullKeystoreTypes() {
// Arrange
def noKeystoreTypesProps = NiFiProperties.createBasicNiFiProperties("", DEFAULT_PROPS +
[(NiFiProperties.SECURITY_KEYSTORE_TYPE) : "",
(NiFiProperties.SECURITY_TRUSTSTORE_TYPE): ""
])
// Act
TlsConfiguration fromProperties = StandardTlsConfiguration.fromNiFiProperties(noKeystoreTypesProps)
logger.info("Created TlsConfiguration: ${fromProperties}")
// Assert
assert fromProperties.keystoreType == null
assert fromProperties.truststoreType == null
}
@Test
void testShouldGetFunctionalKeyPassword() {
// Arrange
TlsConfiguration withKeyPassword = tlsConfiguration
// A container where the keystore password is explicitly set as the key password as well
TlsConfiguration withoutKeyPassword = new StandardTlsConfiguration(KEYSTORE_PATH, KEYSTORE_PASSWORD, KEYSTORE_TYPE, TRUSTSTORE_PATH, TRUSTSTORE_PASSWORD, TRUSTSTORE_TYPE)
// A container where null is explicitly set as the key password
TlsConfiguration withNullPassword = new StandardTlsConfiguration(KEYSTORE_PATH, KEYSTORE_PASSWORD, null, KEYSTORE_TYPE, TRUSTSTORE_PATH, TRUSTSTORE_PASSWORD, TRUSTSTORE_TYPE)
// Act
String actualKeyPassword = withKeyPassword.getKeyPassword()
String functionalKeyPassword = withKeyPassword.getFunctionalKeyPassword()
String duplicateKeystorePassword = withoutKeyPassword.getKeyPassword()
String duplicateFunctionalKeyPassword = withoutKeyPassword.getFunctionalKeyPassword()
String missingKeyPassword = withNullPassword.getKeyPassword()
String keystorePassword = withNullPassword.getFunctionalKeyPassword()
// Assert
assert actualKeyPassword == KEY_PASSWORD
assert functionalKeyPassword == KEY_PASSWORD
assert duplicateKeystorePassword == KEYSTORE_PASSWORD
assert duplicateFunctionalKeyPassword == KEYSTORE_PASSWORD
assert missingKeyPassword == null
assert keystorePassword == KEYSTORE_PASSWORD
}
@Test
void testShouldCheckKeystorePopulation() {
// Arrange
TlsConfiguration empty = new StandardTlsConfiguration()
TlsConfiguration noKeystorePassword = new StandardTlsConfiguration(KEYSTORE_PATH, "", KEY_PASSWORD, KEYSTORE_TYPE, TRUSTSTORE_PATH, TRUSTSTORE_PASSWORD, TRUSTSTORE_TYPE)
// Act
boolean normalIsPopulated = tlsConfiguration.isKeystorePopulated()
boolean emptyIsPopulated = empty.isKeystorePopulated()
boolean noPasswordIsPopulated = noKeystorePassword.isKeystorePopulated()
// Assert
assert normalIsPopulated
assert !emptyIsPopulated
assert !noPasswordIsPopulated
}
@Test
void testShouldCheckTruststorePopulation() {
// Arrange
TlsConfiguration empty = new StandardTlsConfiguration()
TlsConfiguration noTruststorePassword = new StandardTlsConfiguration(KEYSTORE_PATH, KEYSTORE_PASSWORD, KEY_PASSWORD, KEYSTORE_TYPE, TRUSTSTORE_PATH, "", TRUSTSTORE_TYPE)
// Act
boolean normalIsPopulated = tlsConfiguration.isTruststorePopulated()
boolean emptyIsPopulated = empty.isTruststorePopulated()
boolean noPasswordIsPopulated = noTruststorePassword.isTruststorePopulated()
// Assert
assert normalIsPopulated
assert !emptyIsPopulated
assert noPasswordIsPopulated
}
@Test
void testIsKeystoreValidFalseNullKeystorePassword() {
TlsConfiguration configuration = new StandardTlsConfiguration(KEYSTORE_PATH, null, KEY_PASSWORD, KEYSTORE_TYPE, TRUSTSTORE_PATH, TRUSTSTORE_PASSWORD, TRUSTSTORE_TYPE)
assert !configuration.isKeystoreValid()
}
@Test
void testShouldValidateKeystoreConfiguration() {
// Arrange
TlsConfiguration empty = new StandardTlsConfiguration()
TlsConfiguration wrongPassword = new StandardTlsConfiguration(KEYSTORE_PATH, KEYSTORE_PASSWORD.reverse(), KEY_PASSWORD.reverse(), KEYSTORE_TYPE, TRUSTSTORE_PATH, TRUSTSTORE_PASSWORD.reverse(), TRUSTSTORE_TYPE)
TlsConfiguration invalid = new StandardTlsConfiguration(KEYSTORE_PATH.reverse(), KEYSTORE_PASSWORD.reverse(), KEY_PASSWORD.reverse(), KEYSTORE_TYPE, TRUSTSTORE_PATH.reverse(), TRUSTSTORE_PASSWORD.reverse(), TRUSTSTORE_TYPE)
// Act
boolean normalIsValid = tlsConfiguration.isKeystoreValid()
boolean emptyIsValid = empty.isKeystoreValid()
boolean wrongPasswordIsValid = wrongPassword.isKeystoreValid()
boolean invalidIsValid = invalid.isKeystoreValid()
// Assert
assert normalIsValid
assert !emptyIsValid
assert !wrongPasswordIsValid
assert !invalidIsValid
}
@Test
void testShouldValidateTruststoreConfiguration() {
// Arrange
TlsConfiguration empty = new StandardTlsConfiguration()
TlsConfiguration wrongPassword = new StandardTlsConfiguration(KEYSTORE_PATH, KEYSTORE_PASSWORD.reverse(), KEY_PASSWORD.reverse(), KEYSTORE_TYPE, TRUSTSTORE_PATH, TRUSTSTORE_PASSWORD.reverse(), TRUSTSTORE_TYPE)
TlsConfiguration invalid = new StandardTlsConfiguration(KEYSTORE_PATH.reverse(), KEYSTORE_PASSWORD.reverse(), KEY_PASSWORD.reverse(), KEYSTORE_TYPE, TRUSTSTORE_PATH.reverse(), TRUSTSTORE_PASSWORD.reverse(), TRUSTSTORE_TYPE)
// Act
boolean normalIsValid = tlsConfiguration.isTruststoreValid()
boolean emptyIsValid = empty.isTruststoreValid()
boolean wrongPasswordIsValid = wrongPassword.isTruststoreValid()
boolean invalidIsValid = invalid.isTruststoreValid()
// Assert
assert normalIsValid
assert !emptyIsValid
assert !wrongPasswordIsValid
assert !invalidIsValid
}
@Test
void testShouldReturnLegacyAndCurrentEnabledProtocolsForSsl() {
TlsConfiguration configuration = getTlsConfiguration(TlsConfiguration.SSL_PROTOCOL)
String[] enabledProtocols = configuration.enabledProtocols
assert enabledProtocols.toList().containsAll(TlsConfiguration.LEGACY_TLS_PROTOCOL_VERSIONS)
assert enabledProtocols.toList().containsAll(TlsConfiguration.getCurrentSupportedTlsProtocolVersions())
}
@Test
void testShouldReturnCurrentEnabledProtocolsForTls() {
TlsConfiguration configuration = getTlsConfiguration(TlsConfiguration.TLS_PROTOCOL)
String[] enabledProtocols = configuration.enabledProtocols
assert !enabledProtocols.toList().containsAll(TlsConfiguration.LEGACY_TLS_PROTOCOL_VERSIONS)
assert enabledProtocols.toList().containsAll(TlsConfiguration.getCurrentSupportedTlsProtocolVersions())
}
@Test
void testShouldReturnConfiguredEnabledProtocols() {
String currentProtocol = TlsConfiguration.getHighestCurrentSupportedTlsProtocolVersion()
TlsConfiguration configuration = getTlsConfiguration(currentProtocol)
String[] enabledProtocols = configuration.enabledProtocols
assert enabledProtocols == [currentProtocol] as String[]
}
@Test
void testShouldReturnEmptyEnabledProtocolsForNullProtocol() {
TlsConfiguration configuration = getTlsConfiguration(null)
String[] enabledProtocols = configuration.enabledProtocols
assert enabledProtocols.toList().isEmpty()
}
TlsConfiguration getTlsConfiguration(String protocol) {
new StandardTlsConfiguration(KEYSTORE_PATH, KEYSTORE_PASSWORD, KEY_PASSWORD, KEYSTORE_TYPE, TRUSTSTORE_PATH, TRUSTSTORE_PASSWORD, TRUSTSTORE_TYPE, protocol)
}
}