blob: 95ab3ca90caaab5c7f4ef53966ba424a9d79bf6a [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.repository.encryption.configuration.kms;
import org.apache.nifi.repository.encryption.configuration.EncryptedRepositoryType;
import org.apache.nifi.security.kms.KeyProvider;
import org.apache.nifi.security.kms.KeyStoreKeyProvider;
import org.apache.nifi.security.kms.StaticKeyProvider;
import org.apache.nifi.util.NiFiProperties;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class StandardRepositoryKeyProviderFactoryTest {
private static final String KEY = "1234567812345678";
private static final String KEY_ID = "1";
private static final char[] PASSWORD = UUID.randomUUID().toString().toCharArray();
private static final String KEY_STORE_TYPE = "PKCS12";
private static final String TYPE_EXTENSION = ".p12";
private static final SecretKey SECRET_KEY = new SecretKeySpec(KEY.getBytes(StandardCharsets.UTF_8), "AES");
private static final String KEY_PROTECTION_ALGORITHM = "PBEWithHmacSHA256AndAES_256";
private RepositoryKeyProviderFactory factory;
@BeforeEach
public void setProvider() {
factory = new StandardRepositoryKeyProviderFactory();
}
@Test
public void testGetKeyProviderPropertyNotConfiguredException() {
final NiFiProperties niFiProperties = NiFiProperties.createBasicNiFiProperties(null);
final EncryptedRepositoryType encryptedRepositoryType = EncryptedRepositoryType.CONTENT;
final EncryptedConfigurationException exception = assertThrows(EncryptedConfigurationException.class, () ->
factory.getKeyProvider(encryptedRepositoryType, niFiProperties));
assertTrue(exception.getMessage().contains(NiFiProperties.CONTENT_REPOSITORY_ENCRYPTION_KEY_PROVIDER_IMPLEMENTATION_CLASS));
}
@Test
public void testGetKeyProviderNotFound() {
final String notFoundProvider = "OTHER";
final Map<String, String> properties = Collections.singletonMap(NiFiProperties.REPOSITORY_ENCRYPTION_KEY_PROVIDER, notFoundProvider);
final NiFiProperties niFiProperties = NiFiProperties.createBasicNiFiProperties(null, properties);
final EncryptedRepositoryType encryptedRepositoryType = EncryptedRepositoryType.CONTENT;
final EncryptedConfigurationException exception = assertThrows(EncryptedConfigurationException.class, () ->
factory.getKeyProvider(encryptedRepositoryType, niFiProperties));
assertTrue(exception.getMessage().contains(notFoundProvider));
}
@Test
public void testGetKeyProviderContentKeyStoreKeyProvider() throws IOException, GeneralSecurityException {
final Map<String, String> properties = new HashMap<>();
properties.put(NiFiProperties.REPOSITORY_ENCRYPTION_KEY_PROVIDER, EncryptionKeyProvider.KEYSTORE.toString());
properties.put(NiFiProperties.REPOSITORY_ENCRYPTION_KEY_ID, KEY_ID);
properties.put(NiFiProperties.REPOSITORY_ENCRYPTION_KEY_PROVIDER_KEYSTORE_PASSWORD, new String(PASSWORD));
final File keyStoreFile = File.createTempFile(getClass().getSimpleName(), TYPE_EXTENSION);
keyStoreFile.deleteOnExit();
try (final FileOutputStream fileOutputStream = new FileOutputStream(keyStoreFile)) {
setKeyStore(fileOutputStream);
}
properties.put(NiFiProperties.REPOSITORY_ENCRYPTION_KEY_PROVIDER_KEYSTORE_LOCATION, keyStoreFile.getAbsolutePath());
final NiFiProperties niFiProperties = NiFiProperties.createBasicNiFiProperties(null, properties);
assertKeyProviderConfigured(KeyStoreKeyProvider.class, EncryptedRepositoryType.CONTENT, niFiProperties);
}
@Test
public void testGetKeyProviderContentStaticKeyProvider() {
final Map<String, String> properties = new HashMap<>();
final Class<?> providerClass = StaticKeyProvider.class;
properties.put(NiFiProperties.CONTENT_REPOSITORY_ENCRYPTION_KEY_PROVIDER_IMPLEMENTATION_CLASS, providerClass.getName());
properties.put(NiFiProperties.CONTENT_REPOSITORY_ENCRYPTION_KEY, KEY);
properties.put(NiFiProperties.CONTENT_REPOSITORY_ENCRYPTION_KEY_ID, KEY_ID);
final NiFiProperties niFiProperties = NiFiProperties.createBasicNiFiProperties(null, properties);
assertKeyProviderConfigured(providerClass, EncryptedRepositoryType.CONTENT, niFiProperties);
}
@Test
public void testGetKeyProviderFlowFileStaticKeyProvider() {
final Map<String, String> properties = new HashMap<>();
final Class<?> providerClass = StaticKeyProvider.class;
properties.put(NiFiProperties.FLOWFILE_REPOSITORY_ENCRYPTION_KEY_PROVIDER_IMPLEMENTATION_CLASS, providerClass.getName());
properties.put(NiFiProperties.FLOWFILE_REPOSITORY_ENCRYPTION_KEY, KEY);
properties.put(NiFiProperties.FLOWFILE_REPOSITORY_ENCRYPTION_KEY_ID, KEY_ID);
final NiFiProperties niFiProperties = NiFiProperties.createBasicNiFiProperties(null, properties);
assertKeyProviderConfigured(providerClass, EncryptedRepositoryType.FLOWFILE, niFiProperties);
}
@Test
public void testGetKeyProviderProvenanceStaticKeyProvider() {
final Map<String, String> properties = new HashMap<>();
final Class<?> providerClass = StaticKeyProvider.class;
properties.put(NiFiProperties.PROVENANCE_REPO_ENCRYPTION_KEY_PROVIDER_IMPLEMENTATION_CLASS, providerClass.getName());
properties.put(NiFiProperties.PROVENANCE_REPO_ENCRYPTION_KEY, KEY);
properties.put(NiFiProperties.PROVENANCE_REPO_ENCRYPTION_KEY_ID, KEY_ID);
final NiFiProperties niFiProperties = NiFiProperties.createBasicNiFiProperties(null, properties);
assertKeyProviderConfigured(providerClass, EncryptedRepositoryType.PROVENANCE, niFiProperties);
}
private void assertKeyProviderConfigured(final Class<?> providerClass, final EncryptedRepositoryType encryptedRepositoryType, final NiFiProperties niFiProperties) {
final KeyProvider keyProvider = factory.getKeyProvider(encryptedRepositoryType, niFiProperties);
assertNotNull(keyProvider);
assertEquals(providerClass, keyProvider.getClass());
assertTrue(keyProvider.keyExists(KEY_ID));
}
private void setKeyStore(final OutputStream outputStream) throws GeneralSecurityException, IOException {
KeyStore keyStore = KeyStore.getInstance(KEY_STORE_TYPE);
keyStore.load(null, null);
keyStore.setEntry(KEY_ID, new KeyStore.SecretKeyEntry(SECRET_KEY), new KeyStore.PasswordProtection(PASSWORD, KEY_PROTECTION_ALGORITHM, null));
keyStore.store(outputStream, PASSWORD);
}
}