NIFI-12764 Removed Commons Codec and Lang3 from security-utils (#8380)

This commit is contained in:
David Handermann 2024-02-09 15:00:06 -06:00 committed by GitHub
parent 7dc696ecdc
commit 2ea4838157
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 72 additions and 62 deletions

View File

@ -44,14 +44,6 @@
<artifactId>nifi-security-cert-builder</artifactId> <artifactId>nifi-security-cert-builder</artifactId>
<version>2.0.0-SNAPSHOT</version> <version>2.0.0-SNAPSHOT</version>
</dependency> </dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
<dependency> <dependency>
<groupId>org.bouncycastle</groupId> <groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk18on</artifactId> <artifactId>bcprov-jdk18on</artifactId>

View File

@ -41,6 +41,7 @@ import java.time.Duration;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HexFormat;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
@ -48,8 +49,6 @@ import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.TrustManagerFactory;
import javax.security.auth.x500.X500Principal; import javax.security.auth.x500.X500Principal;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang3.StringUtils;
import org.apache.nifi.security.cert.builder.StandardCertificateBuilder; import org.apache.nifi.security.cert.builder.StandardCertificateBuilder;
import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -171,11 +170,11 @@ public class KeyStoreUtils {
public static TlsConfiguration createTlsConfigAndNewKeystoreTruststore(final TlsConfiguration tlsConfiguration, int certDurationDays, public static TlsConfiguration createTlsConfigAndNewKeystoreTruststore(final TlsConfiguration tlsConfiguration, int certDurationDays,
String[] dnsSubjectAlternativeNames) throws IOException, GeneralSecurityException { String[] dnsSubjectAlternativeNames) throws IOException, GeneralSecurityException {
final Path keyStorePath; final Path keyStorePath;
final String keystorePassword = StringUtils.isNotBlank(tlsConfiguration.getKeystorePassword()) ? tlsConfiguration.getKeystorePassword() : generatePassword(); final String keystorePassword = isNotBlank(tlsConfiguration.getKeystorePassword()) ? tlsConfiguration.getKeystorePassword() : generatePassword();
final KeystoreType keystoreType = tlsConfiguration.getKeystoreType() != null ? tlsConfiguration.getKeystoreType() : KeystoreType.PKCS12; final KeystoreType keystoreType = tlsConfiguration.getKeystoreType() != null ? tlsConfiguration.getKeystoreType() : KeystoreType.PKCS12;
final String keyPassword = StringUtils.isNotBlank(tlsConfiguration.getKeyPassword()) ? tlsConfiguration.getKeyPassword() : keystorePassword; final String keyPassword = isNotBlank(tlsConfiguration.getKeyPassword()) ? tlsConfiguration.getKeyPassword() : keystorePassword;
final Path trustStorePath; final Path trustStorePath;
final String truststorePassword = StringUtils.isNotBlank(tlsConfiguration.getTruststorePassword()) ? tlsConfiguration.getTruststorePassword() : generatePassword(); final String truststorePassword = isNotBlank(tlsConfiguration.getTruststorePassword()) ? tlsConfiguration.getTruststorePassword() : generatePassword();
final KeystoreType truststoreType = tlsConfiguration.getTruststoreType() != null ? tlsConfiguration.getTruststoreType() : KeystoreType.PKCS12; final KeystoreType truststoreType = tlsConfiguration.getTruststoreType() != null ? tlsConfiguration.getTruststoreType() : KeystoreType.PKCS12;
// Create temporary Keystore file // Create temporary Keystore file
@ -259,11 +258,11 @@ public class KeyStoreUtils {
* @throws TlsException if there is a problem initializing or reading from the keystore * @throws TlsException if there is a problem initializing or reading from the keystore
*/ */
public static KeyManagerFactory loadKeyManagerFactory(String keystorePath, String keystorePassword, String keyPassword, String keystoreType) throws TlsException { public static KeyManagerFactory loadKeyManagerFactory(String keystorePath, String keystorePassword, String keyPassword, String keystoreType) throws TlsException {
if (StringUtils.isEmpty(keystorePassword)) { if (keystorePassword == null || keystorePassword.isEmpty()) {
throw new IllegalArgumentException("The keystore password cannot be null or empty"); throw new IllegalArgumentException("The keystore password cannot be null or empty");
} }
final char[] keystorePasswordChars = keystorePassword.toCharArray(); final char[] keystorePasswordChars = keystorePassword.toCharArray();
final char[] keyPasswordChars = (StringUtils.isNotEmpty(keyPassword)) ? keyPassword.toCharArray() : keystorePasswordChars; final char[] keyPasswordChars = isNotBlank(keyPassword) ? keyPassword.toCharArray() : keystorePasswordChars;
KeyStore keyStore = loadKeyStore(keystorePath, keystorePasswordChars, keystoreType); KeyStore keyStore = loadKeyStore(keystorePath, keystorePasswordChars, keystoreType);
return getKeyManagerFactoryFromKeyStore(keyStore, keystorePasswordChars, keyPasswordChars); return getKeyManagerFactoryFromKeyStore(keyStore, keystorePasswordChars, keyPasswordChars);
} }
@ -331,12 +330,12 @@ public class KeyStoreUtils {
*/ */
public static TrustManagerFactory loadTrustManagerFactory(String truststorePath, String truststorePassword, String truststoreType) throws TlsException { public static TrustManagerFactory loadTrustManagerFactory(String truststorePath, String truststorePassword, String truststoreType) throws TlsException {
// Bouncy Castle PKCS12 type requires a password // Bouncy Castle PKCS12 type requires a password
if (truststoreType.equalsIgnoreCase(KeystoreType.PKCS12.getType()) && StringUtils.isBlank(truststorePassword)) { if (truststoreType.equalsIgnoreCase(KeystoreType.PKCS12.getType()) && (truststorePassword == null || truststorePassword.isBlank())) {
throw new IllegalArgumentException("A PKCS12 Truststore Type requires a password"); throw new IllegalArgumentException("A PKCS12 Truststore Type requires a password");
} }
// Legacy truststore passwords can be empty // Legacy truststore passwords can be empty
final char[] truststorePasswordChars = StringUtils.isNotBlank(truststorePassword) ? truststorePassword.toCharArray() : null; final char[] truststorePasswordChars = isNotBlank(truststorePassword) ? truststorePassword.toCharArray() : null;
KeyStore trustStore = loadTrustStore(truststorePath, truststorePasswordChars, truststoreType); KeyStore trustStore = loadTrustStore(truststorePath, truststorePasswordChars, truststoreType);
return getTrustManagerFactoryFromTrustStore(trustStore); return getTrustManagerFactoryFromTrustStore(trustStore);
} }
@ -445,8 +444,8 @@ public class KeyStoreUtils {
KeystoreType keystoreType = KeystoreType.PKCS12; KeystoreType keystoreType = KeystoreType.PKCS12;
for (final Map.Entry<KeystoreType, String> keystoreTypeEntry : KEY_STORE_EXTENSIONS.entrySet()) { for (final Map.Entry<KeystoreType, String> keystoreTypeEntry : KEY_STORE_EXTENSIONS.entrySet()) {
final String extension = keystoreTypeEntry.getValue(); final String extension = keystoreTypeEntry.getValue().toLowerCase();
if (StringUtils.endsWithIgnoreCase(keystorePath, extension)) { if (keystorePath.endsWith(extension)) {
keystoreType = keystoreTypeEntry.getKey(); keystoreType = keystoreTypeEntry.getKey();
break; break;
} }
@ -574,7 +573,7 @@ public class KeyStoreUtils {
private static String generatePassword() { private static String generatePassword() {
final byte[] password = new byte[PASSWORD_LENGTH]; final byte[] password = new byte[PASSWORD_LENGTH];
new SecureRandom().nextBytes(password); new SecureRandom().nextBytes(password);
return Hex.encodeHexString(password); return HexFormat.of().formatHex(password);
} }
private static KeystoreType getKeystoreType(final String keystoreTypeName) { private static KeystoreType getKeystoreType(final String keystoreTypeName) {
@ -584,4 +583,8 @@ public class KeyStoreUtils {
.findFirst(); .findFirst();
return foundKeystoreType.orElseThrow(() -> new IllegalArgumentException(String.format("Keystore Type [%s] not found", keystoreTypeFilter))); return foundKeystoreType.orElseThrow(() -> new IllegalArgumentException(String.format("Keystore Type [%s] not found", keystoreTypeFilter)));
} }
private static boolean isNotBlank(final String string) {
return string != null && !string.isBlank();
}
} }

View File

@ -16,7 +16,6 @@
*/ */
package org.apache.nifi.security.util; package org.apache.nifi.security.util;
import org.apache.commons.lang3.StringUtils;
import org.apache.nifi.util.NiFiProperties; import org.apache.nifi.util.NiFiProperties;
import java.io.File; import java.io.File;
@ -267,7 +266,7 @@ public class StandardTlsConfiguration implements TlsConfiguration {
*/ */
@Override @Override
public String getFunctionalKeyPassword() { public String getFunctionalKeyPassword() {
return StringUtils.isNotBlank(keyPassword) ? keyPassword : keystorePassword; return isNotBlank(keyPassword) ? keyPassword : keystorePassword;
} }
/** /**
@ -346,7 +345,7 @@ public class StandardTlsConfiguration implements TlsConfiguration {
public boolean isKeystoreValid() { public boolean isKeystoreValid() {
if (isStoreValid(keystorePath, keystorePassword, keystoreType, StoreType.KEY_STORE)) { if (isStoreValid(keystorePath, keystorePassword, keystoreType, StoreType.KEY_STORE)) {
return true; return true;
} else if (StringUtils.isNotBlank(keyPassword) && !keyPassword.equals(keystorePassword)) { } else if (isNotBlank(keyPassword) && !keyPassword.equals(keystorePassword)) {
return isKeystorePopulated() return isKeystorePopulated()
&& KeyStoreUtils.isKeyPasswordCorrect(getFileUrl(keystorePath), keystoreType, keystorePassword.toCharArray(), && KeyStoreUtils.isKeyPasswordCorrect(getFileUrl(keystorePath), keystoreType, keystorePassword.toCharArray(),
getFunctionalKeyPassword().toCharArray()); getFunctionalKeyPassword().toCharArray());
@ -464,20 +463,20 @@ public class StandardTlsConfiguration implements TlsConfiguration {
} }
private static String maskPasswordForLog(String password) { private static String maskPasswordForLog(String password) {
return StringUtils.isNotBlank(password) ? MASKED_PASSWORD_LOG : NULL_LOG; return isNotBlank(password) ? MASKED_PASSWORD_LOG : NULL_LOG;
} }
private boolean isAnyPopulated(String path, String password, KeystoreType type) { private boolean isAnyPopulated(String path, String password, KeystoreType type) {
return StringUtils.isNotBlank(path) || StringUtils.isNotBlank(password) || type != null; return isNotBlank(path) || isNotBlank(password) || type != null;
} }
private boolean isStorePopulated(final String path, final String password, final KeystoreType type, final StoreType storeType) { private boolean isStorePopulated(final String path, final String password, final KeystoreType type, final StoreType storeType) {
boolean populated; boolean populated;
// Legacy trust stores such as JKS can be populated without a password; only check the path and type // Legacy trust stores such as JKS can be populated without a password; only check the path and type
populated = StringUtils.isNotBlank(path) && type != null; populated = isNotBlank(path) && type != null;
if (StoreType.KEY_STORE == storeType) { if (StoreType.KEY_STORE == storeType) {
populated = populated && StringUtils.isNotBlank(password); populated = populated && isNotBlank(password);
} }
return populated; return populated;
@ -495,6 +494,10 @@ public class StandardTlsConfiguration implements TlsConfiguration {
} }
} }
private static boolean isNotBlank(final String string) {
return string != null && !string.isBlank();
}
private enum StoreType { private enum StoreType {
KEY_STORE, KEY_STORE,
TRUST_STORE TRUST_STORE

View File

@ -18,10 +18,6 @@ package org.apache.nifi.security.util.crypto;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
/** /**
* Enumeration capturing information about the cryptographic hash algorithms * Enumeration capturing information about the cryptographic hash algorithms
@ -113,12 +109,7 @@ public enum HashAlgorithm {
@Override @Override
public String toString() { public String toString() {
final ToStringBuilder builder = new ToStringBuilder(this); return "HashAlgorithm[Name=%s,Digest Length=%d bytes,Description=%s".formatted(name, digestBytesLength, description);
ToStringBuilder.setDefaultStyle(ToStringStyle.SHORT_PREFIX_STYLE);
builder.append("Algorithm Name", name);
builder.append("Digest Length", digestBytesLength + " bytes");
builder.append("Description", description);
return builder.toString();
} }
/** /**
@ -137,7 +128,7 @@ public enum HashAlgorithm {
if (!isStrongAlgorithm()) { if (!isStrongAlgorithm()) {
sb.append(" [WARNING -- Cryptographically broken]"); sb.append(" [WARNING -- Cryptographically broken]");
} }
if (StringUtils.isNotBlank(description)) { if (description != null && !description.isBlank()) {
sb.append(" ").append(description); sb.append(" ").append(description);
} }
return sb.toString(); return sb.toString();

View File

@ -21,11 +21,11 @@ import java.io.InputStream;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HexFormat;
import java.util.List; import java.util.List;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.nifi.components.AllowableValue; import org.apache.nifi.components.AllowableValue;
import org.bouncycastle.crypto.digests.Blake2bDigest; import org.bouncycastle.crypto.digests.Blake2bDigest;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -106,9 +106,9 @@ public class HashService {
} }
// The Blake2 algorithms are instantiated differently and rely on BouncyCastle // The Blake2 algorithms are instantiated differently and rely on BouncyCastle
if (algorithm.isBlake2()) { if (algorithm.isBlake2()) {
return Hex.encodeHexString(blake2HashStreaming(algorithm, value)); return HexFormat.of().formatHex(blake2HashStreaming(algorithm, value));
} else { } else {
return Hex.encodeHexString(traditionalHashStreaming(algorithm, value)); return HexFormat.of().formatHex(traditionalHashStreaming(algorithm, value));
} }
} }
@ -122,7 +122,7 @@ public class HashService {
*/ */
public static String hashValue(HashAlgorithm algorithm, String value, Charset charset) { public static String hashValue(HashAlgorithm algorithm, String value, Charset charset) {
byte[] rawHash = hashValueRaw(algorithm, value, charset); byte[] rawHash = hashValueRaw(algorithm, value, charset);
return Hex.encodeHexString(rawHash); return HexFormat.of().formatHex(rawHash);
} }
/** /**
@ -189,13 +189,28 @@ public class HashService {
} }
private static byte[] traditionalHash(HashAlgorithm algorithm, byte[] value) { private static byte[] traditionalHash(HashAlgorithm algorithm, byte[] value) {
return DigestUtils.getDigest(algorithm.getName()).digest(value); return getMessageDigest(algorithm).digest(value);
} }
private static byte[] traditionalHashStreaming(HashAlgorithm algorithm, InputStream value) throws IOException { private static byte[] traditionalHashStreaming(HashAlgorithm algorithm, InputStream value) throws IOException {
MessageDigest digest = DigestUtils.getDigest(algorithm.getName()); final MessageDigest messageDigest = getMessageDigest(algorithm);
// DigestInputStream digestInputStream = new DigestInputStream(value, digest);
return DigestUtils.digest(digest, value); final byte[] buffer = new byte[BUFFER_SIZE];
int read = value.read(buffer);
while (read != -1) {
messageDigest.update(buffer, 0 , read);
read = value.read(buffer);
}
return messageDigest.digest();
}
private static MessageDigest getMessageDigest(final HashAlgorithm algorithm) {
try {
return MessageDigest.getInstance(algorithm.getName());
} catch (final NoSuchAlgorithmException e) {
throw new IllegalArgumentException("Message Digest algorithm not found", e);
}
} }
private static byte[] blake2Hash(HashAlgorithm algorithm, byte[] value) { private static byte[] blake2Hash(HashAlgorithm algorithm, byte[] value) {

View File

@ -17,7 +17,6 @@
package org.apache.nifi.security.util; package org.apache.nifi.security.util;
import org.apache.commons.lang3.StringUtils;
import org.apache.nifi.security.cert.builder.StandardCertificateBuilder; import org.apache.nifi.security.cert.builder.StandardCertificateBuilder;
import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -56,6 +55,7 @@ public class KeyStoreUtilsTest {
private static final String SECRET_KEY_ALGORITHM = "AES"; private static final String SECRET_KEY_ALGORITHM = "AES";
private static final String KEY_PROTECTION_ALGORITHM = "PBEWithHmacSHA256AndAES_256"; private static final String KEY_PROTECTION_ALGORITHM = "PBEWithHmacSHA256AndAES_256";
private static final String HYPHEN_SEPARATOR = "-"; private static final String HYPHEN_SEPARATOR = "-";
private static final String EMPTY = "";
private static KeyPair keyPair; private static KeyPair keyPair;
private static X509Certificate certificate; private static X509Certificate certificate;
@ -65,7 +65,7 @@ public class KeyStoreUtilsTest {
public static void generateKeysAndCertificates() throws NoSuchAlgorithmException { public static void generateKeysAndCertificates() throws NoSuchAlgorithmException {
keyPair = KeyPairGenerator.getInstance(KEY_ALGORITHM).generateKeyPair(); keyPair = KeyPairGenerator.getInstance(KEY_ALGORITHM).generateKeyPair();
certificate = new StandardCertificateBuilder(keyPair, new X500Principal(SUBJECT_DN), Duration.ofDays(DURATION_DAYS)).build(); certificate = new StandardCertificateBuilder(keyPair, new X500Principal(SUBJECT_DN), Duration.ofDays(DURATION_DAYS)).build();
final byte[] encodedKey = StringUtils.remove(UUID.randomUUID().toString(), HYPHEN_SEPARATOR).getBytes(StandardCharsets.UTF_8); final byte[] encodedKey = UUID.randomUUID().toString().replaceAll(HYPHEN_SEPARATOR, EMPTY).getBytes(StandardCharsets.UTF_8);
secretKey = new SecretKeySpec(encodedKey, SECRET_KEY_ALGORITHM); secretKey = new SecretKeySpec(encodedKey, SECRET_KEY_ALGORITHM);
} }

View File

@ -16,7 +16,6 @@
*/ */
package org.apache.nifi.security.util; package org.apache.nifi.security.util;
import org.apache.nifi.util.StringUtils;
import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -29,6 +28,8 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertNull;
public class SslSocketFactoryTest { public class SslSocketFactoryTest {
private static final String EMPTY = "";
private static TlsConfiguration tlsConfiguration; private static TlsConfiguration tlsConfiguration;
@BeforeAll @BeforeAll
@ -53,7 +54,7 @@ public class SslSocketFactoryTest {
final TlsConfiguration customTlsConfiguration = new StandardTlsConfiguration( final TlsConfiguration customTlsConfiguration = new StandardTlsConfiguration(
tlsConfiguration.getKeystorePath(), tlsConfiguration.getKeystorePath(),
tlsConfiguration.getKeystorePassword(), tlsConfiguration.getKeystorePassword(),
StringUtils.EMPTY, EMPTY,
tlsConfiguration.getKeystoreType(), tlsConfiguration.getKeystoreType(),
tlsConfiguration.getTruststorePath(), tlsConfiguration.getTruststorePath(),
tlsConfiguration.getTruststorePassword(), tlsConfiguration.getTruststorePassword(),
@ -68,7 +69,7 @@ public class SslSocketFactoryTest {
@Test @Test
public void testCreateSslContextEmptyTrustStorePasswordJks() throws TlsException { public void testCreateSslContextEmptyTrustStorePasswordJks() throws TlsException {
final TlsConfiguration customTlsConfiguration = new TemporaryKeyStoreBuilder() final TlsConfiguration customTlsConfiguration = new TemporaryKeyStoreBuilder()
.trustStorePassword(StringUtils.EMPTY) .trustStorePassword(EMPTY)
.trustStoreType(KeystoreType.JKS.getType()) .trustStoreType(KeystoreType.JKS.getType())
.build(); .build();
final SSLContext sslContext = SslContextFactory.createSslContext(customTlsConfiguration); final SSLContext sslContext = SslContextFactory.createSslContext(customTlsConfiguration);

View File

@ -92,18 +92,13 @@ public class HashServiceTest {
/** /**
* This test ensures that the service properly handles UTF-16 encoded data to return it without * This test ensures that the service properly handles UTF-16 encoded data to return it without
* the Big Endian Byte Order Mark (BOM). Java treats UTF-16 encoded data without a BOM as Big Endian by default on decoding, but when <em>encoding</em>, it inserts a BE BOM in the data. * the Big Endian Byte Order Mark (BOM). Java treats UTF-16 encoded data without a BOM as Big Endian by default on decoding, but when <em>encoding</em>, it inserts a BE BOM in the data.
*
* Examples: * Examples:
*
* "apachenifi" * "apachenifi"
*
* * UTF-8: 0x61 0x70 0x61 0x63 0x68 0x65 0x6E 0x69 0x66 0x69 * * UTF-8: 0x61 0x70 0x61 0x63 0x68 0x65 0x6E 0x69 0x66 0x69
* * UTF-16: 0xFE 0xFF 0x00 0x61 0x00 0x70 0x00 0x61 0x00 0x63 0x00 0x68 0x00 0x65 0x00 0x6E 0x00 0x69 0x00 0x66 0x00 0x69 * * UTF-16: 0xFE 0xFF 0x00 0x61 0x00 0x70 0x00 0x61 0x00 0x63 0x00 0x68 0x00 0x65 0x00 0x6E 0x00 0x69 0x00 0x66 0x00 0x69
* * UTF-16LE: 0x61 0x00 0x70 0x00 0x61 0x00 0x63 0x00 0x68 0x00 0x65 0x00 0x6E 0x00 0x69 0x00 0x66 0x00 0x69 0x00 * * UTF-16LE: 0x61 0x00 0x70 0x00 0x61 0x00 0x63 0x00 0x68 0x00 0x65 0x00 0x6E 0x00 0x69 0x00 0x66 0x00 0x69 0x00
* * UTF-16BE: 0x00 0x61 0x00 0x70 0x00 0x61 0x00 0x63 0x00 0x68 0x00 0x65 0x00 0x6E 0x00 0x69 0x00 0x66 0x00 0x69 * * UTF-16BE: 0x00 0x61 0x00 0x70 0x00 0x61 0x00 0x63 0x00 0x68 0x00 0x65 0x00 0x6E 0x00 0x69 0x00 0x66 0x00 0x69
*
* The result of "UTF-16" decoding should have the 0xFE 0xFF stripped on return by encoding in UTF-16BE directly, which will not insert a BOM. * The result of "UTF-16" decoding should have the 0xFE 0xFF stripped on return by encoding in UTF-16BE directly, which will not insert a BOM.
*
* See also: <a href="https://unicode.org/faq/utf_bom.html#bom10">https://unicode.org/faq/utf_bom.html#bom10</a> * See also: <a href="https://unicode.org/faq/utf_bom.html#bom10">https://unicode.org/faq/utf_bom.html#bom10</a>
*/ */
@Test @Test
@ -191,7 +186,7 @@ public class HashServiceTest {
} }
@Test @Test
void testShouldHashConstantValue() throws Exception { void testShouldHashConstantValue() {
// Arrange // Arrange
final List<HashAlgorithm> algorithms = List.of(HashAlgorithm.values()); final List<HashAlgorithm> algorithms = List.of(HashAlgorithm.values());
@ -232,7 +227,7 @@ public class HashServiceTest {
} }
@Test @Test
void testShouldHashEmptyValue() throws Exception { void testShouldHashEmptyValue() {
// Arrange // Arrange
final List<HashAlgorithm> algorithms = List.of(HashAlgorithm.values()); final List<HashAlgorithm> algorithms = List.of(HashAlgorithm.values());
final String EMPTY_VALUE = ""; final String EMPTY_VALUE = "";
@ -274,7 +269,7 @@ public class HashServiceTest {
} }
@Test @Test
void testShouldBuildHashAlgorithmAllowableValues() throws Exception { void testShouldBuildHashAlgorithmAllowableValues() {
// Arrange // Arrange
final List<HashAlgorithm> EXPECTED_ALGORITHMS = List.of(HashAlgorithm.values()); final List<HashAlgorithm> EXPECTED_ALGORITHMS = List.of(HashAlgorithm.values());
@ -298,7 +293,7 @@ public class HashServiceTest {
} }
@Test @Test
void testShouldBuildCharacterSetAllowableValues() throws Exception { void testShouldBuildCharacterSetAllowableValues() {
// Arrange // Arrange
final List<Charset> EXPECTED_CHARACTER_SETS = Arrays.asList( final List<Charset> EXPECTED_CHARACTER_SETS = Arrays.asList(
StandardCharsets.US_ASCII, StandardCharsets.US_ASCII,
@ -336,7 +331,7 @@ public class HashServiceTest {
} }
@Test @Test
void testShouldHashValueFromStream() throws Exception { void testShouldHashValueFromStream() {
// Arrange // Arrange
// No command-line md2sum tool available // No command-line md2sum tool available

View File

@ -183,6 +183,12 @@
</exclusion> </exclusion>
</exclusions> </exclusions>
</dependency> </dependency>
<!-- Commons Codec required for OpenSAML -->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>${org.apache.commons.codec.version}</version>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.security.kerberos</groupId> <groupId>org.springframework.security.kerberos</groupId>
<artifactId>spring-security-kerberos-core</artifactId> <artifactId>spring-security-kerberos-core</artifactId>

View File

@ -189,6 +189,10 @@
<artifactId>logback-core</artifactId> <artifactId>logback-core</artifactId>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency> <dependency>
<groupId>org.apache.nifi</groupId> <groupId>org.apache.nifi</groupId>
<artifactId>nifi-api</artifactId> <artifactId>nifi-api</artifactId>