NIFI-12556 Updated nifi-cipher-bundle using current API methods

This closes #8195

Signed-off-by: David Handermann <exceptionfactory@apache.org>
This commit is contained in:
EndzeitBegins 2023-12-30 14:03:34 +01:00 committed by exceptionfactory
parent 0592735cb8
commit 0a1f1bb6f1
No known key found for this signature in database
20 changed files with 110 additions and 192 deletions

View File

@ -53,9 +53,6 @@ import java.security.GeneralSecurityException;
import java.security.Key;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.KeySpec;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@ -78,7 +75,7 @@ public class DecryptContent extends AbstractProcessor {
.description("Block cipher mode of operation for decryption using the Advanced Encryption Standard")
.required(true)
.allowableValues(CipherAlgorithmMode.class)
.defaultValue(CipherAlgorithmMode.GCM.getValue())
.defaultValue(CipherAlgorithmMode.GCM)
.build();
static final PropertyDescriptor CIPHER_ALGORITHM_PADDING = new PropertyDescriptor.Builder()
@ -87,7 +84,7 @@ public class DecryptContent extends AbstractProcessor {
.description("Padding specification used in cipher operation for decryption using the Advanced Encryption Standard")
.required(true)
.allowableValues(CipherAlgorithmPadding.class)
.defaultValue(CipherAlgorithmPadding.NO_PADDING.getValue())
.defaultValue(CipherAlgorithmPadding.NO_PADDING)
.build();
static final PropertyDescriptor KEY_SPECIFICATION_FORMAT = new PropertyDescriptor.Builder()
@ -96,7 +93,7 @@ public class DecryptContent extends AbstractProcessor {
.description("Format describing the configured Key Specification")
.required(true)
.allowableValues(KeySpecificationFormat.class)
.defaultValue(KeySpecificationFormat.PASSWORD.getValue())
.defaultValue(KeySpecificationFormat.PASSWORD)
.build();
static final PropertyDescriptor KEY_SPECIFICATION = new PropertyDescriptor.Builder()
@ -118,17 +115,14 @@ public class DecryptContent extends AbstractProcessor {
.description("Decryption failed")
.build();
private static final List<PropertyDescriptor> DESCRIPTORS = Collections.unmodifiableList(Arrays.asList(
private static final List<PropertyDescriptor> DESCRIPTORS = List.of(
CIPHER_ALGORITHM_MODE,
CIPHER_ALGORITHM_PADDING,
KEY_SPECIFICATION_FORMAT,
KEY_SPECIFICATION
));
);
private static final Set<Relationship> RELATIONSHIPS = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
SUCCESS,
FAILURE
)));
private static final Set<Relationship> RELATIONSHIPS = Set.of(SUCCESS, FAILURE);
private static final SymmetricCipher SYMMETRIC_CIPHER = SymmetricCipher.AES;
@ -167,13 +161,11 @@ public class DecryptContent extends AbstractProcessor {
return;
}
final String specificationFormat = context.getProperty(KEY_SPECIFICATION_FORMAT).getValue();
final KeySpecificationFormat keySpecificationFormat = KeySpecificationFormat.valueOf(specificationFormat);
final KeySpecificationFormat keySpecificationFormat = context.getProperty(KEY_SPECIFICATION_FORMAT).asDescribedValue(KeySpecificationFormat.class);
final String cipherTransformation = getCipherTransformation(context);
final Cipher cipher = getCipher(cipherTransformation);
final String algorithmMode = context.getProperty(CIPHER_ALGORITHM_MODE).getValue();
final CipherAlgorithmMode cipherAlgorithmMode = CipherAlgorithmMode.valueOf(algorithmMode);
final CipherAlgorithmMode cipherAlgorithmMode = context.getProperty(CIPHER_ALGORITHM_MODE).asDescribedValue(CipherAlgorithmMode.class);
final KeySpec keySpec = getKeySpec(context, keySpecificationFormat);
final StreamCallback callback = new DecryptCallback(cipher, cipherAlgorithmMode, keySpec);
@ -314,8 +306,7 @@ public class DecryptContent extends AbstractProcessor {
if (keySpec instanceof SecretKeySpec) {
key = (SecretKeySpec) keySpec;
} else if (algorithmParameterSpec instanceof SerializedParameterSpec) {
final SerializedParameterSpec serializedParameterSpec = (SerializedParameterSpec) algorithmParameterSpec;
} else if (algorithmParameterSpec instanceof SerializedParameterSpec serializedParameterSpec) {
final byte[] parameters = serializedParameterSpec.getParameters();
key = getDerivedKey(parameters);
} else {

View File

@ -20,7 +20,6 @@ import com.exceptionfactory.jagged.DecryptingChannelFactory;
import com.exceptionfactory.jagged.RecipientStanzaReader;
import com.exceptionfactory.jagged.framework.armor.ArmoredDecryptingChannelFactory;
import com.exceptionfactory.jagged.framework.stream.StandardDecryptingChannelFactory;
import org.apache.nifi.annotation.behavior.InputRequirement;
import org.apache.nifi.annotation.behavior.SupportsBatching;
import org.apache.nifi.annotation.documentation.CapabilityDescription;
@ -31,7 +30,6 @@ import org.apache.nifi.components.ConfigVerificationResult;
import org.apache.nifi.components.PropertyDescriptor;
import org.apache.nifi.components.resource.ResourceCardinality;
import org.apache.nifi.components.resource.ResourceReference;
import org.apache.nifi.components.resource.ResourceReferences;
import org.apache.nifi.components.resource.ResourceType;
import org.apache.nifi.context.PropertyContext;
import org.apache.nifi.flowfile.FlowFile;
@ -61,7 +59,6 @@ import java.security.Provider;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -93,7 +90,7 @@ public class DecryptContentAge extends AbstractProcessor implements VerifiablePr
.displayName("Private Key Source")
.description("Source of information determines the loading strategy for X25519 Private Key Identities")
.required(true)
.defaultValue(KeySource.PROPERTIES.getValue())
.defaultValue(KeySource.PROPERTIES)
.allowableValues(KeySource.class)
.build();
@ -118,9 +115,9 @@ public class DecryptContentAge extends AbstractProcessor implements VerifiablePr
.dependsOn(PRIVATE_KEY_SOURCE, KeySource.RESOURCES)
.build();
private static final Set<Relationship> RELATIONSHIPS = new LinkedHashSet<>(Arrays.asList(SUCCESS, FAILURE));
private static final Set<Relationship> RELATIONSHIPS = Set.of(SUCCESS, FAILURE);
private static final List<PropertyDescriptor> DESCRIPTORS = Arrays.asList(
private static final List<PropertyDescriptor> DESCRIPTORS = List.of(
PRIVATE_KEY_SOURCE,
PRIVATE_KEY_IDENTITIES,
PRIVATE_KEY_IDENTITY_RESOURCES
@ -227,20 +224,13 @@ public class DecryptContentAge extends AbstractProcessor implements VerifiablePr
}
private List<RecipientStanzaReader> getRecipientStanzaReaders(final PropertyContext context) throws IOException {
final KeySource keySource = KeySource.valueOf(context.getProperty(PRIVATE_KEY_SOURCE).getValue());
final List<ResourceReference> resources = new ArrayList<>();
if (KeySource.PROPERTIES == keySource) {
final ResourceReference resource = context.getProperty(PRIVATE_KEY_IDENTITIES).asResource();
resources.add(resource);
} else {
final ResourceReferences resourceReferences = context.getProperty(PRIVATE_KEY_IDENTITY_RESOURCES).asResources();
resources.addAll(resourceReferences.asList());
}
final KeySource keySource = context.getProperty(PRIVATE_KEY_SOURCE).asDescribedValue(KeySource.class);
final List<ResourceReference> resources = switch (keySource) {
case PROPERTIES -> List.of(context.getProperty(PRIVATE_KEY_IDENTITIES).asResource());
case RESOURCES -> context.getProperty(PRIVATE_KEY_IDENTITY_RESOURCES).asResources().asList();
};
final List<RecipientStanzaReader> recipientStanzaReaders = new ArrayList<>();
for (final ResourceReference resource : resources) {
try (final InputStream inputStream = resource.read()) {
final List<RecipientStanzaReader> readers = PRIVATE_KEY_READER.read(inputStream);
@ -285,15 +275,11 @@ public class DecryptContentAge extends AbstractProcessor implements VerifiablePr
}
private DecryptingChannelFactory getDecryptingChannelFactory(final byte[] versionIndicator) {
final DecryptingChannelFactory decryptingChannelFactory;
if (Arrays.equals(BINARY_VERSION_INDICATOR, versionIndicator)) {
decryptingChannelFactory = new StandardDecryptingChannelFactory(CIPHER_PROVIDER);
return new StandardDecryptingChannelFactory(CIPHER_PROVIDER);
} else {
decryptingChannelFactory = new ArmoredDecryptingChannelFactory(CIPHER_PROVIDER);
return new ArmoredDecryptingChannelFactory(CIPHER_PROVIDER);
}
return decryptingChannelFactory;
}
}
}

View File

@ -23,8 +23,6 @@ import org.apache.nifi.annotation.behavior.WritesAttribute;
import org.apache.nifi.annotation.behavior.WritesAttributes;
import org.apache.nifi.annotation.documentation.CapabilityDescription;
import org.apache.nifi.annotation.documentation.Tags;
import org.apache.nifi.processors.cipher.compatibility.CompatibilityModeEncryptionScheme;
import org.apache.nifi.processors.cipher.compatibility.CompatibilityModeKeyDerivationStrategy;
import org.apache.nifi.components.PropertyDescriptor;
import org.apache.nifi.flowfile.FlowFile;
import org.apache.nifi.processor.AbstractProcessor;
@ -33,6 +31,8 @@ import org.apache.nifi.processor.ProcessSession;
import org.apache.nifi.processor.Relationship;
import org.apache.nifi.processor.io.StreamCallback;
import org.apache.nifi.processor.util.StandardValidators;
import org.apache.nifi.processors.cipher.compatibility.CompatibilityModeEncryptionScheme;
import org.apache.nifi.processors.cipher.compatibility.CompatibilityModeKeyDerivationStrategy;
import org.apache.nifi.processors.cipher.io.DecryptStreamCallback;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
@ -47,13 +47,9 @@ import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.InvalidKeySpecException;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
@SideEffectFree
@ -103,16 +99,13 @@ public class DecryptContentCompatibility extends AbstractProcessor {
.description("Decryption failed")
.build();
private static final List<PropertyDescriptor> DESCRIPTORS = Collections.unmodifiableList(Arrays.asList(
private static final List<PropertyDescriptor> DESCRIPTORS = List.of(
ENCRYPTION_SCHEME,
KEY_DERIVATION_STRATEGY,
PASSWORD
));
);
private static final Set<Relationship> RELATIONSHIPS = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
SUCCESS,
FAILURE
)));
private static final Set<Relationship> RELATIONSHIPS = Set.of(SUCCESS, FAILURE);
private static final BouncyCastleProvider BOUNCY_CASTLE_PROVIDER = new BouncyCastleProvider();
@ -149,15 +142,16 @@ public class DecryptContentCompatibility extends AbstractProcessor {
return;
}
final String scheme = context.getProperty(ENCRYPTION_SCHEME).getValue();
final CompatibilityModeEncryptionScheme encryptionScheme = getEncryptionScheme(scheme);
final CompatibilityModeEncryptionScheme encryptionScheme =
context.getProperty(ENCRYPTION_SCHEME).asDescribedValue(CompatibilityModeEncryptionScheme.class);
final String scheme = encryptionScheme.getValue();
final Cipher cipher = getCipher(scheme);
final char[] password = context.getProperty(PASSWORD).getValue().toCharArray();
final PBEKeySpec keySpec = new PBEKeySpec(password);
final String strategy = context.getProperty(KEY_DERIVATION_STRATEGY).getValue();
final CompatibilityModeKeyDerivationStrategy keyDerivationStrategy = CompatibilityModeKeyDerivationStrategy.valueOf(strategy);
final CompatibilityModeKeyDerivationStrategy keyDerivationStrategy =
context.getProperty(KEY_DERIVATION_STRATEGY).asDescribedValue(CompatibilityModeKeyDerivationStrategy.class);
final StreamCallback callback = new DecryptCallback(cipher, keySpec, keyDerivationStrategy);
final Map<String, String> attributes = new LinkedHashMap<>();
@ -176,13 +170,6 @@ public class DecryptContentCompatibility extends AbstractProcessor {
}
}
private CompatibilityModeEncryptionScheme getEncryptionScheme(final String scheme) {
final Optional<CompatibilityModeEncryptionScheme> encryptionSchemeFound = Arrays.stream(CompatibilityModeEncryptionScheme.values())
.filter(encryptionScheme -> encryptionScheme.getValue().equals(scheme))
.findFirst();
return encryptionSchemeFound.orElseThrow(() -> new IllegalArgumentException(String.format("Encryption Scheme [%s] not found", scheme)));
}
private Cipher getCipher(final String transformation) {
try {
return Cipher.getInstance(transformation, BOUNCY_CASTLE_PROVIDER);

View File

@ -20,7 +20,6 @@ import com.exceptionfactory.jagged.EncryptingChannelFactory;
import com.exceptionfactory.jagged.RecipientStanzaWriter;
import com.exceptionfactory.jagged.framework.armor.ArmoredEncryptingChannelFactory;
import com.exceptionfactory.jagged.framework.stream.StandardEncryptingChannelFactory;
import org.apache.nifi.annotation.behavior.InputRequirement;
import org.apache.nifi.annotation.behavior.SupportsBatching;
import org.apache.nifi.annotation.documentation.CapabilityDescription;
@ -31,7 +30,6 @@ import org.apache.nifi.components.ConfigVerificationResult;
import org.apache.nifi.components.PropertyDescriptor;
import org.apache.nifi.components.resource.ResourceCardinality;
import org.apache.nifi.components.resource.ResourceReference;
import org.apache.nifi.components.resource.ResourceReferences;
import org.apache.nifi.components.resource.ResourceType;
import org.apache.nifi.context.PropertyContext;
import org.apache.nifi.flowfile.FlowFile;
@ -45,11 +43,11 @@ import org.apache.nifi.processor.io.StreamCallback;
import org.apache.nifi.processors.cipher.age.AgeKeyIndicator;
import org.apache.nifi.processors.cipher.age.AgeKeyReader;
import org.apache.nifi.processors.cipher.age.AgeKeyValidator;
import org.apache.nifi.processors.cipher.age.AgeProviderResolver;
import org.apache.nifi.processors.cipher.age.AgePublicKeyReader;
import org.apache.nifi.processors.cipher.age.FileEncoding;
import org.apache.nifi.processors.cipher.age.KeySource;
import org.apache.nifi.processors.cipher.io.ChannelStreamCallback;
import org.apache.nifi.processors.cipher.age.FileEncoding;
import org.apache.nifi.processors.cipher.age.AgeProviderResolver;
import java.io.IOException;
import java.io.InputStream;
@ -58,9 +56,7 @@ import java.nio.channels.WritableByteChannel;
import java.security.GeneralSecurityException;
import java.security.Provider;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -92,7 +88,7 @@ public class EncryptContentAge extends AbstractProcessor implements VerifiablePr
.displayName("File Encoding")
.description("Output encoding for encrypted files. Binary encoding provides optimal processing performance.")
.required(true)
.defaultValue(FileEncoding.BINARY.getValue())
.defaultValue(FileEncoding.BINARY)
.allowableValues(FileEncoding.class)
.build();
@ -101,7 +97,7 @@ public class EncryptContentAge extends AbstractProcessor implements VerifiablePr
.displayName("Public Key Source")
.description("Source of information determines the loading strategy for X25519 Public Key Recipients")
.required(true)
.defaultValue(KeySource.PROPERTIES.getValue())
.defaultValue(KeySource.PROPERTIES)
.allowableValues(KeySource.class)
.build();
@ -126,9 +122,9 @@ public class EncryptContentAge extends AbstractProcessor implements VerifiablePr
.dependsOn(PUBLIC_KEY_SOURCE, KeySource.RESOURCES)
.build();
private static final Set<Relationship> RELATIONSHIPS = new LinkedHashSet<>(Arrays.asList(SUCCESS, FAILURE));
private static final Set<Relationship> RELATIONSHIPS = Set.of(SUCCESS, FAILURE);
private static final List<PropertyDescriptor> DESCRIPTORS = Arrays.asList(
private static final List<PropertyDescriptor> DESCRIPTORS = List.of(
FILE_ENCODING,
PUBLIC_KEY_SOURCE,
PUBLIC_KEY_RECIPIENTS,
@ -218,8 +214,7 @@ public class EncryptContentAge extends AbstractProcessor implements VerifiablePr
}
try {
final String fileEncodingValue = context.getProperty(FILE_ENCODING).getValue();
final FileEncoding fileEncoding = FileEncoding.valueOf(fileEncodingValue);
final FileEncoding fileEncoding = context.getProperty(FILE_ENCODING).asDescribedValue(FileEncoding.class);
final EncryptingChannelFactory encryptingChannelFactory = getEncryptingChannelFactory(fileEncoding);
final StreamCallback streamCallback = new EncryptingStreamCallback(configuredRecipientStanzaWriters, encryptingChannelFactory);
flowFile = session.write(flowFile, streamCallback);
@ -232,32 +227,20 @@ public class EncryptContentAge extends AbstractProcessor implements VerifiablePr
}
private EncryptingChannelFactory getEncryptingChannelFactory(final FileEncoding fileEncoding) {
final EncryptingChannelFactory encryptingChannelFactory;
if (FileEncoding.ASCII == fileEncoding) {
encryptingChannelFactory = new ArmoredEncryptingChannelFactory(CIPHER_PROVIDER);
} else {
encryptingChannelFactory = new StandardEncryptingChannelFactory(CIPHER_PROVIDER);
}
return encryptingChannelFactory;
return switch (fileEncoding) {
case ASCII -> new ArmoredEncryptingChannelFactory(CIPHER_PROVIDER);
case BINARY -> new StandardEncryptingChannelFactory(CIPHER_PROVIDER);
};
}
private List<RecipientStanzaWriter> getRecipientStanzaWriters(final PropertyContext context) throws IOException {
final KeySource keySource = KeySource.valueOf(context.getProperty(PUBLIC_KEY_SOURCE).getValue());
final List<ResourceReference> resources = new ArrayList<>();
if (KeySource.PROPERTIES == keySource) {
final ResourceReference resource = context.getProperty(PUBLIC_KEY_RECIPIENTS).asResource();
resources.add(resource);
} else {
final ResourceReferences resourceReferences = context.getProperty(PUBLIC_KEY_RECIPIENT_RESOURCES).asResources();
resources.addAll(resourceReferences.asList());
}
final KeySource keySource = context.getProperty(PUBLIC_KEY_SOURCE).asDescribedValue(KeySource.class);
final List<ResourceReference> resources = switch (keySource) {
case PROPERTIES -> List.of(context.getProperty(PUBLIC_KEY_RECIPIENTS).asResource());
case RESOURCES -> context.getProperty(PUBLIC_KEY_RECIPIENT_RESOURCES).asResources().asList();
};
final List<RecipientStanzaWriter> recipientStanzaWriters = new ArrayList<>();
for (final ResourceReference resource : resources) {
try (final InputStream inputStream = resource.read()) {
final List<RecipientStanzaWriter> writers = PUBLIC_KEY_READER.read(inputStream);

View File

@ -125,7 +125,7 @@ public class AgeKeyValidator implements Validator {
.filter(Predicate.not(Matcher::matches))
.count();
if (prefixedLines.size() == 0) {
if (prefixedLines.isEmpty()) {
builder.explanation(NOT_FOUND_EXPLANATION).valid(false);
} else if (invalid == 0) {
builder.explanation(VALID_EXPLANATION).valid(true);

View File

@ -23,7 +23,6 @@ import org.apache.nifi.components.DescribedValue;
*/
public enum FileEncoding implements DescribedValue {
BINARY("Binary encoding"),
ASCII("ASCII Armor encoding");
private final String description;

View File

@ -23,7 +23,6 @@ import org.apache.nifi.components.DescribedValue;
*/
public enum KeySource implements DescribedValue {
PROPERTIES("Load one or more keys from configured properties"),
RESOURCES("Load one or more keys from files or URLs");
private final String description;

View File

@ -23,9 +23,7 @@ import org.apache.nifi.components.DescribedValue;
*/
public enum CipherAlgorithmMode implements DescribedValue {
CBC("Cipher Blocking Chaining Mode"),
CTR("Counter Mode"),
GCM("Galois/Counter Mode supporting Authenticated Encryption with Associated Data");
private final String description;

View File

@ -24,7 +24,6 @@ import org.apache.nifi.components.DescribedValue;
public enum CipherAlgorithmPadding implements DescribedValue {
/** No Padding */
NO_PADDING("NoPadding"),
/** PKCS5 Padding described in RFC 8018 */
PKCS5_PADDING("PKCS5Padding");

View File

@ -23,14 +23,11 @@ import org.apache.nifi.components.DescribedValue;
*/
public enum DigestAlgorithm implements DescribedValue {
MD5("MD5", "Message Digest Algorithm 5"),
SHA1("SHA-1", "Secure Hash Algorithm 1"),
SHA256("SHA-256", "Secure Hash Algorithm 2 with 256 bits");
private String name;
private String description;
private final String name;
private final String description;
DigestAlgorithm(final String name, final String description) {
this.name = name;
@ -49,6 +46,6 @@ public enum DigestAlgorithm implements DescribedValue {
@Override
public String getDescription() {
return name;
return description;
}
}

View File

@ -23,19 +23,13 @@ import org.apache.nifi.components.DescribedValue;
*/
public enum SymmetricCipher implements DescribedValue {
AES("AES", "Advanced Encryption Standard defined in FIPS 197"),
DES("DES", "Data Encryption Standard defined in FIPS 46-3 and withdrawn in 2005"),
DESEDE("DESede", "Triple Data Encryption Standard also known as 3DES and deprecated in 2023"),
RC2("RC2", "RSA Rivest Cipher 2 defined in RFC 2268"),
RC4("RC4", "RSA Rivest Cipher 4"),
TWOFISH("TWOFISH", "Twofish Block Cipher");
private final String name;
private final String description;
SymmetricCipher(final String name, final String description) {

View File

@ -172,11 +172,8 @@ public enum CompatibilityModeEncryptionScheme implements DescribedValue {
);
private final String algorithm;
private final String description;
private final DigestAlgorithm digestAlgorithm;
private final SymmetricCipher symmetricCipher;
CompatibilityModeEncryptionScheme(

View File

@ -43,13 +43,9 @@ public enum CompatibilityModeKeyDerivationStrategy implements DescribedValue {
);
private final String description;
private final int iterations;
private final byte[] saltHeader;
private final int saltStandardLength;
private final int saltBufferLength;
CompatibilityModeKeyDerivationStrategy(

View File

@ -25,11 +25,9 @@ import java.nio.charset.StandardCharsets;
*/
public enum EncodedDelimiter implements DescribedValue {
SALT("NiFiSALT", "Eight bytes appended to a stream after the salt bytes according to NiFi 0.5.0 conventions"),
IV("NiFiIV", "Six bytes appended to a stream after the initialization vector bytes according to NiFi 0.5.0 conventions");
private final byte[] delimiter;
private final String description;
EncodedDelimiter(

View File

@ -23,7 +23,6 @@ import org.apache.nifi.components.DescribedValue;
*/
public enum KeySpecificationFormat implements DescribedValue {
RAW("Raw secret key provided as a hexadecimal string"),
PASSWORD("Password string for use with a Key Derivation Function to produce a secret key");
private final String description;

View File

@ -95,7 +95,7 @@ class DecryptContentAgeTest {
@Test
void testVerifySuccessful() {
runner.setProperty(DecryptContentAge.PRIVATE_KEY_IDENTITIES, PRIVATE_KEY_ENCODED);
runner.setProperty(DecryptContentAge.PRIVATE_KEY_SOURCE, KeySource.PROPERTIES.getValue());
runner.setProperty(DecryptContentAge.PRIVATE_KEY_SOURCE, KeySource.PROPERTIES);
assertVerificationResultOutcomeEquals(ConfigVerificationResult.Outcome.SUCCESSFUL);
}
@ -103,14 +103,14 @@ class DecryptContentAgeTest {
@Test
void testVerifyFailedChecksumInvalid() {
runner.setProperty(DecryptContentAge.PRIVATE_KEY_IDENTITIES, PRIVATE_KEY_CHECKSUM_INVALID);
runner.setProperty(DecryptContentAge.PRIVATE_KEY_SOURCE, KeySource.PROPERTIES.getValue());
runner.setProperty(DecryptContentAge.PRIVATE_KEY_SOURCE, KeySource.PROPERTIES);
assertVerificationResultOutcomeEquals(ConfigVerificationResult.Outcome.FAILED);
}
@Test
void testVerifyFailedResourcesNotConfigured() {
runner.setProperty(DecryptContentAge.PRIVATE_KEY_SOURCE, KeySource.RESOURCES.getValue());
runner.setProperty(DecryptContentAge.PRIVATE_KEY_SOURCE, KeySource.RESOURCES);
assertVerificationResultOutcomeEquals(ConfigVerificationResult.Outcome.FAILED);
}
@ -118,7 +118,7 @@ class DecryptContentAgeTest {
@Test
void testRunSuccessAscii() throws GeneralSecurityException, IOException {
runner.setProperty(DecryptContentAge.PRIVATE_KEY_IDENTITIES, PRIVATE_KEY_ENCODED);
runner.setProperty(DecryptContentAge.PRIVATE_KEY_SOURCE, KeySource.PROPERTIES.getValue());
runner.setProperty(DecryptContentAge.PRIVATE_KEY_SOURCE, KeySource.PROPERTIES);
assertSuccess(FileEncoding.ASCII);
}
@ -126,7 +126,7 @@ class DecryptContentAgeTest {
@Test
void testRunSuccessBinary() throws GeneralSecurityException, IOException {
runner.setProperty(DecryptContentAge.PRIVATE_KEY_IDENTITIES, PRIVATE_KEY_ENCODED);
runner.setProperty(DecryptContentAge.PRIVATE_KEY_SOURCE, KeySource.PROPERTIES.getValue());
runner.setProperty(DecryptContentAge.PRIVATE_KEY_SOURCE, KeySource.PROPERTIES);
assertSuccess(FileEncoding.BINARY);
}
@ -135,7 +135,7 @@ class DecryptContentAgeTest {
void testRunSuccessBinaryMultiplePrivateKeys() throws GeneralSecurityException, IOException {
final String multiplePrivateKeys = String.format("%s%n%s", PRIVATE_KEY_ENCODED, PRIVATE_KEY_SECOND);
runner.setProperty(DecryptContentAge.PRIVATE_KEY_IDENTITIES, multiplePrivateKeys);
runner.setProperty(DecryptContentAge.PRIVATE_KEY_SOURCE, KeySource.PROPERTIES.getValue());
runner.setProperty(DecryptContentAge.PRIVATE_KEY_SOURCE, KeySource.PROPERTIES);
assertSuccess(FileEncoding.BINARY);
}
@ -146,7 +146,7 @@ class DecryptContentAgeTest {
Files.writeString(tempFile, PRIVATE_KEY_ENCODED);
runner.setProperty(DecryptContentAge.PRIVATE_KEY_IDENTITY_RESOURCES, tempFile.toString());
runner.setProperty(DecryptContentAge.PRIVATE_KEY_SOURCE, KeySource.RESOURCES.getValue());
runner.setProperty(DecryptContentAge.PRIVATE_KEY_SOURCE, KeySource.RESOURCES);
assertSuccess(FileEncoding.BINARY);
}
@ -156,7 +156,7 @@ class DecryptContentAgeTest {
final Path tempFile = createTempFile(tempDir);
runner.setProperty(DecryptContentAge.PRIVATE_KEY_IDENTITY_RESOURCES, tempFile.toString());
runner.setProperty(DecryptContentAge.PRIVATE_KEY_SOURCE, KeySource.RESOURCES.getValue());
runner.setProperty(DecryptContentAge.PRIVATE_KEY_SOURCE, KeySource.RESOURCES);
final byte[] encrypted = getEncrypted(FileEncoding.BINARY);
runner.enqueue(encrypted);
@ -167,7 +167,7 @@ class DecryptContentAgeTest {
@Test
void testRunFailure() {
runner.setProperty(DecryptContentAge.PRIVATE_KEY_IDENTITIES, PRIVATE_KEY_ENCODED);
runner.setProperty(DecryptContentAge.PRIVATE_KEY_SOURCE, KeySource.PROPERTIES.getValue());
runner.setProperty(DecryptContentAge.PRIVATE_KEY_SOURCE, KeySource.PROPERTIES);
runner.enqueue(WORD);
runner.run();
@ -217,13 +217,11 @@ class DecryptContentAgeTest {
private EncryptingChannelFactory getEncryptingChannelFactory(final FileEncoding fileEncoding) {
final Provider provider = AgeProviderResolver.getCipherProvider();
final EncryptingChannelFactory encryptingChannelFactory;
if (FileEncoding.ASCII == fileEncoding) {
encryptingChannelFactory = new ArmoredEncryptingChannelFactory(provider);
} else {
encryptingChannelFactory = new StandardEncryptingChannelFactory(provider);
}
return encryptingChannelFactory;
return switch (fileEncoding) {
case ASCII -> new ArmoredEncryptingChannelFactory(provider);
case BINARY -> new StandardEncryptingChannelFactory(provider);
};
}
private Path createTempFile(final Path tempDir) throws IOException {

View File

@ -32,7 +32,6 @@ import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
@ -76,8 +75,8 @@ class DecryptContentCompatibilityTest {
@EnumSource(CompatibilityModeEncryptionScheme.class)
void testRunKeyDerivationOpenSslUnsalted(final CompatibilityModeEncryptionScheme encryptionScheme) throws Exception {
final CompatibilityModeKeyDerivationStrategy keyDerivationStrategy = CompatibilityModeKeyDerivationStrategy.OPENSSL_EVP_BYTES_TO_KEY;
runner.setProperty(DecryptContentCompatibility.KEY_DERIVATION_STRATEGY, keyDerivationStrategy.getValue());
runner.setProperty(DecryptContentCompatibility.ENCRYPTION_SCHEME, encryptionScheme.getValue());
runner.setProperty(DecryptContentCompatibility.KEY_DERIVATION_STRATEGY, keyDerivationStrategy);
runner.setProperty(DecryptContentCompatibility.ENCRYPTION_SCHEME, encryptionScheme);
runner.setProperty(DecryptContentCompatibility.PASSWORD, PASSWORD);
final Cipher cipher = getCipher(encryptionScheme);
@ -89,7 +88,7 @@ class DecryptContentCompatibilityTest {
@EnumSource(CompatibilityModeEncryptionScheme.class)
void testRunKeyDerivationOpenSslSalted(final CompatibilityModeEncryptionScheme encryptionScheme) throws Exception {
final CompatibilityModeKeyDerivationStrategy keyDerivationStrategy = CompatibilityModeKeyDerivationStrategy.OPENSSL_EVP_BYTES_TO_KEY;
runner.setProperty(DecryptContentCompatibility.KEY_DERIVATION_STRATEGY, keyDerivationStrategy.getValue());
runner.setProperty(DecryptContentCompatibility.KEY_DERIVATION_STRATEGY, keyDerivationStrategy);
runner.setProperty(DecryptContentCompatibility.ENCRYPTION_SCHEME, encryptionScheme.getValue());
runner.setProperty(DecryptContentCompatibility.PASSWORD, PASSWORD);
@ -101,8 +100,8 @@ class DecryptContentCompatibilityTest {
@Test
void testRunKeyDerivationOpenSslSaltedStream() throws Exception {
final CompatibilityModeKeyDerivationStrategy keyDerivationStrategy = CompatibilityModeKeyDerivationStrategy.OPENSSL_EVP_BYTES_TO_KEY;
runner.setProperty(DecryptContentCompatibility.KEY_DERIVATION_STRATEGY, keyDerivationStrategy.getValue());
runner.setProperty(DecryptContentCompatibility.ENCRYPTION_SCHEME, SIMPLE_ENCRYPTION_SCHEME.getValue());
runner.setProperty(DecryptContentCompatibility.KEY_DERIVATION_STRATEGY, keyDerivationStrategy);
runner.setProperty(DecryptContentCompatibility.ENCRYPTION_SCHEME, SIMPLE_ENCRYPTION_SCHEME);
runner.setProperty(DecryptContentCompatibility.PASSWORD, PASSWORD);
final Cipher cipher = getCipher(SIMPLE_ENCRYPTION_SCHEME);
@ -116,8 +115,8 @@ class DecryptContentCompatibilityTest {
@EnumSource(CompatibilityModeEncryptionScheme.class)
void testRunKeyDerivationJasyptStandard(final CompatibilityModeEncryptionScheme encryptionScheme) throws Exception {
final CompatibilityModeKeyDerivationStrategy keyDerivationStrategy = CompatibilityModeKeyDerivationStrategy.JASYPT_STANDARD;
runner.setProperty(DecryptContentCompatibility.KEY_DERIVATION_STRATEGY, keyDerivationStrategy.getValue());
runner.setProperty(DecryptContentCompatibility.ENCRYPTION_SCHEME, encryptionScheme.getValue());
runner.setProperty(DecryptContentCompatibility.KEY_DERIVATION_STRATEGY, keyDerivationStrategy);
runner.setProperty(DecryptContentCompatibility.ENCRYPTION_SCHEME, encryptionScheme);
runner.setProperty(DecryptContentCompatibility.PASSWORD, PASSWORD);
final Cipher cipher = getCipher(encryptionScheme);
@ -166,8 +165,8 @@ class DecryptContentCompatibilityTest {
}
private void setSimpleEncryptionScheme() {
runner.setProperty(DecryptContentCompatibility.KEY_DERIVATION_STRATEGY, CompatibilityModeKeyDerivationStrategy.JASYPT_STANDARD.getValue());
runner.setProperty(DecryptContentCompatibility.ENCRYPTION_SCHEME, SIMPLE_ENCRYPTION_SCHEME.getValue());
runner.setProperty(DecryptContentCompatibility.KEY_DERIVATION_STRATEGY, CompatibilityModeKeyDerivationStrategy.JASYPT_STANDARD);
runner.setProperty(DecryptContentCompatibility.ENCRYPTION_SCHEME, SIMPLE_ENCRYPTION_SCHEME);
runner.setProperty(DecryptContentCompatibility.PASSWORD, PASSWORD);
}

View File

@ -88,7 +88,7 @@ class DecryptContentTest {
@Test
void testRunInitializationVectorNotFound() {
runner.setProperty(DecryptContent.KEY_SPECIFICATION_FORMAT, KeySpecificationFormat.PASSWORD.getValue());
runner.setProperty(DecryptContent.KEY_SPECIFICATION_FORMAT, KeySpecificationFormat.PASSWORD);
runner.setProperty(DecryptContent.KEY_SPECIFICATION, SECRET_KEY_SPECIFICATION);
runner.enqueue(WORD);
@ -100,7 +100,7 @@ class DecryptContentTest {
@Test
void testRunInputNotFound() {
runner.setProperty(DecryptContent.KEY_SPECIFICATION_FORMAT, KeySpecificationFormat.RAW.getValue());
runner.setProperty(DecryptContent.KEY_SPECIFICATION_FORMAT, KeySpecificationFormat.RAW);
runner.setProperty(DecryptContent.KEY_SPECIFICATION, HEXADECIMAL_KEY_SPECIFICATION);
final byte[] bytes = Arrays.concatenate(INITIALIZATION_VECTOR, EncodedDelimiter.IV.getDelimiter());
@ -113,7 +113,7 @@ class DecryptContentTest {
@Test
void testRunInputInvalid() {
runner.setProperty(DecryptContent.KEY_SPECIFICATION_FORMAT, KeySpecificationFormat.RAW.getValue());
runner.setProperty(DecryptContent.KEY_SPECIFICATION_FORMAT, KeySpecificationFormat.RAW);
runner.setProperty(DecryptContent.KEY_SPECIFICATION, HEXADECIMAL_KEY_SPECIFICATION);
final byte[] bytes = Arrays.concatenate(INITIALIZATION_VECTOR, EncodedDelimiter.IV.getDelimiter(), INITIALIZATION_VECTOR);
@ -170,10 +170,10 @@ class DecryptContentTest {
@Test
void testRunAesCtrNoPaddingRaw() throws IOException {
runner.setProperty(DecryptContent.KEY_SPECIFICATION_FORMAT, KeySpecificationFormat.RAW.getValue());
runner.setProperty(DecryptContent.KEY_SPECIFICATION_FORMAT, KeySpecificationFormat.RAW);
runner.setProperty(DecryptContent.KEY_SPECIFICATION, HEXADECIMAL_KEY_SPECIFICATION);
runner.setProperty(DecryptContent.CIPHER_ALGORITHM_MODE, CipherAlgorithmMode.CTR.getValue());
runner.setProperty(DecryptContent.CIPHER_ALGORITHM_PADDING, CipherAlgorithmPadding.NO_PADDING.getValue());
runner.setProperty(DecryptContent.CIPHER_ALGORITHM_MODE, CipherAlgorithmMode.CTR);
runner.setProperty(DecryptContent.CIPHER_ALGORITHM_PADDING, CipherAlgorithmPadding.NO_PADDING);
final byte[] encryptedBytes = getHexadecimalKeyEncryptedBytes();
runner.enqueue(encryptedBytes);
@ -183,15 +183,15 @@ class DecryptContentTest {
}
private void setGcmNoPaddingPassword() {
runner.setProperty(DecryptContent.KEY_SPECIFICATION_FORMAT, KeySpecificationFormat.PASSWORD.getValue());
runner.setProperty(DecryptContent.KEY_SPECIFICATION_FORMAT, KeySpecificationFormat.PASSWORD);
runner.setProperty(DecryptContent.KEY_SPECIFICATION, SECRET_KEY_SPECIFICATION);
runner.setProperty(DecryptContent.CIPHER_ALGORITHM_MODE, CipherAlgorithmMode.GCM.getValue());
runner.setProperty(DecryptContent.CIPHER_ALGORITHM_PADDING, CipherAlgorithmPadding.NO_PADDING.getValue());
runner.setProperty(DecryptContent.CIPHER_ALGORITHM_MODE, CipherAlgorithmMode.GCM);
runner.setProperty(DecryptContent.CIPHER_ALGORITHM_PADDING, CipherAlgorithmPadding.NO_PADDING);
}
private void assertDecryptedSuccess() {
runner.assertAllFlowFilesTransferred(DecryptContent.SUCCESS);
final MockFlowFile flowFile = runner.getFlowFilesForRelationship(DecryptContent.SUCCESS).get(0);
final MockFlowFile flowFile = runner.getFlowFilesForRelationship(DecryptContent.SUCCESS).getFirst();
flowFile.assertContentEquals(UNENCRYPTED);
}

View File

@ -100,7 +100,7 @@ class EncryptContentAgeTest {
@Test
void testVerifySuccessful() {
runner.setProperty(EncryptContentAge.PUBLIC_KEY_RECIPIENTS, PUBLIC_KEY_ENCODED);
runner.setProperty(EncryptContentAge.PUBLIC_KEY_SOURCE, KeySource.PROPERTIES.getValue());
runner.setProperty(EncryptContentAge.PUBLIC_KEY_SOURCE, KeySource.PROPERTIES);
assertVerificationResultOutcomeEquals(ConfigVerificationResult.Outcome.SUCCESSFUL);
}
@ -108,14 +108,14 @@ class EncryptContentAgeTest {
@Test
void testVerifyFailedChecksumInvalid() {
runner.setProperty(EncryptContentAge.PUBLIC_KEY_RECIPIENTS, PUBLIC_KEY_CHECKSUM_INVALID);
runner.setProperty(EncryptContentAge.PUBLIC_KEY_SOURCE, KeySource.PROPERTIES.getValue());
runner.setProperty(EncryptContentAge.PUBLIC_KEY_SOURCE, KeySource.PROPERTIES);
assertVerificationResultOutcomeEquals(ConfigVerificationResult.Outcome.FAILED);
}
@Test
void testVerifyFailedResourcesNotFound() {
runner.setProperty(EncryptContentAge.PUBLIC_KEY_SOURCE, KeySource.RESOURCES.getValue());
runner.setProperty(EncryptContentAge.PUBLIC_KEY_SOURCE, KeySource.RESOURCES);
assertVerificationResultOutcomeEquals(ConfigVerificationResult.Outcome.FAILED);
}
@ -123,8 +123,8 @@ class EncryptContentAgeTest {
@Test
void testRunSuccessAscii() throws GeneralSecurityException, IOException {
runner.setProperty(EncryptContentAge.PUBLIC_KEY_RECIPIENTS, PUBLIC_KEY_ENCODED);
runner.setProperty(EncryptContentAge.PUBLIC_KEY_SOURCE, KeySource.PROPERTIES.getValue());
runner.setProperty(EncryptContentAge.FILE_ENCODING, FileEncoding.ASCII.getValue());
runner.setProperty(EncryptContentAge.PUBLIC_KEY_SOURCE, KeySource.PROPERTIES);
runner.setProperty(EncryptContentAge.FILE_ENCODING, FileEncoding.ASCII);
runner.enqueue(WORD);
runner.run();
@ -136,8 +136,8 @@ class EncryptContentAgeTest {
@Test
void testRunSuccessBinary() throws GeneralSecurityException, IOException {
runner.setProperty(EncryptContentAge.PUBLIC_KEY_RECIPIENTS, PUBLIC_KEY_ENCODED);
runner.setProperty(EncryptContentAge.PUBLIC_KEY_SOURCE, KeySource.PROPERTIES.getValue());
runner.setProperty(EncryptContentAge.FILE_ENCODING, FileEncoding.BINARY.getValue());
runner.setProperty(EncryptContentAge.PUBLIC_KEY_SOURCE, KeySource.PROPERTIES);
runner.setProperty(EncryptContentAge.FILE_ENCODING, FileEncoding.BINARY);
runner.enqueue(WORD);
runner.run();
@ -152,8 +152,8 @@ class EncryptContentAgeTest {
Files.writeString(tempFile, PUBLIC_KEY_ENCODED);
runner.setProperty(EncryptContentAge.PUBLIC_KEY_RECIPIENT_RESOURCES, tempFile.toString());
runner.setProperty(EncryptContentAge.PUBLIC_KEY_SOURCE, KeySource.RESOURCES.getValue());
runner.setProperty(EncryptContentAge.FILE_ENCODING, FileEncoding.BINARY.getValue());
runner.setProperty(EncryptContentAge.PUBLIC_KEY_SOURCE, KeySource.RESOURCES);
runner.setProperty(EncryptContentAge.FILE_ENCODING, FileEncoding.BINARY);
runner.enqueue(WORD);
runner.run();
@ -167,7 +167,7 @@ class EncryptContentAgeTest {
final Path tempFile = createTempFile(tempDir);
runner.setProperty(EncryptContentAge.PUBLIC_KEY_RECIPIENT_RESOURCES, tempFile.toString());
runner.setProperty(EncryptContentAge.PUBLIC_KEY_SOURCE, KeySource.RESOURCES.getValue());
runner.setProperty(EncryptContentAge.PUBLIC_KEY_SOURCE, KeySource.RESOURCES);
runner.enqueue(WORD);
@ -231,13 +231,11 @@ class EncryptContentAgeTest {
private DecryptingChannelFactory getDecryptingChannelFactory(final FileEncoding fileEncoding) {
final Provider provider = AgeProviderResolver.getCipherProvider();
final DecryptingChannelFactory decryptingChannelFactory;
if (FileEncoding.ASCII == fileEncoding) {
decryptingChannelFactory = new ArmoredDecryptingChannelFactory(provider);
} else {
decryptingChannelFactory = new StandardDecryptingChannelFactory(provider);
}
return decryptingChannelFactory;
return switch (fileEncoding) {
case ASCII -> new ArmoredDecryptingChannelFactory(provider);
case BINARY -> new StandardDecryptingChannelFactory(provider);
};
}
private Path createTempFile(final Path tempDir) throws IOException {

View File

@ -17,18 +17,6 @@
package org.apache.nifi.processors.cipher;
import static org.apache.nifi.processors.cipher.VerifyContentMAC.FAILURE;
import static org.apache.nifi.processors.cipher.VerifyContentMAC.HMAC_SHA256;
import static org.apache.nifi.processors.cipher.VerifyContentMAC.HMAC_SHA512;
import static org.apache.nifi.processors.cipher.VerifyContentMAC.MAC_ALGORITHM_ATTRIBUTE;
import static org.apache.nifi.processors.cipher.VerifyContentMAC.MAC_CALCULATED_ATTRIBUTE;
import static org.apache.nifi.processors.cipher.VerifyContentMAC.MAC_ENCODING_ATTRIBUTE;
import static org.apache.nifi.processors.cipher.VerifyContentMAC.SUCCESS;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;
import org.apache.nifi.processors.cipher.VerifyContentMAC.Encoding;
import org.apache.nifi.util.TestRunner;
import org.apache.nifi.util.TestRunners;
@ -38,6 +26,19 @@ import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;
import static org.apache.nifi.processors.cipher.VerifyContentMAC.FAILURE;
import static org.apache.nifi.processors.cipher.VerifyContentMAC.HMAC_SHA256;
import static org.apache.nifi.processors.cipher.VerifyContentMAC.HMAC_SHA512;
import static org.apache.nifi.processors.cipher.VerifyContentMAC.MAC_ALGORITHM_ATTRIBUTE;
import static org.apache.nifi.processors.cipher.VerifyContentMAC.MAC_CALCULATED_ATTRIBUTE;
import static org.apache.nifi.processors.cipher.VerifyContentMAC.MAC_ENCODING_ATTRIBUTE;
import static org.apache.nifi.processors.cipher.VerifyContentMAC.SUCCESS;
class VerifyContentMACTest {
private static final String INVALID = "invalid";
@ -175,5 +176,4 @@ class VerifyContentMACTest {
runner.assertAllFlowFilesTransferred(FAILURE);
}
}