This is an automated email from the ASF dual-hosted git repository.
markt-asf pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/main by this push:
new 1ac42fa9fb Remove deprecated code - EncryptInterceptor
1ac42fa9fb is described below
commit 1ac42fa9fbfa9afa9059934970e605f079aa20e2
Author: Mark Thomas <[email protected]>
AuthorDate: Fri Oct 30 12:40:44 2026 +0000
Remove deprecated code - EncryptInterceptor
---
.../group/interceptors/EncryptInterceptor.java | 811 ---------------------
.../interceptors/EncryptInterceptorMBean.java | 110 ---
.../group/interceptors/LocalStrings.properties | 13 -
.../group/interceptors/LocalStrings_cs.properties | 2 -
.../group/interceptors/LocalStrings_de.properties | 3 -
.../group/interceptors/LocalStrings_es.properties | 2 -
.../group/interceptors/LocalStrings_fr.properties | 13 -
.../group/interceptors/LocalStrings_ja.properties | 13 -
.../group/interceptors/LocalStrings_ko.properties | 8 -
.../interceptors/LocalStrings_pt_BR.properties | 2 -
.../group/interceptors/LocalStrings_ru.properties | 2 -
.../interceptors/LocalStrings_zh_CN.properties | 8 -
.../interceptors/EncryptInterceptorBaseTest.java | 206 ------
.../group/interceptors/TestEncryptInterceptor.java | 439 -----------
.../TestEncryptInterceptorAlgorithms.java | 163 -----
.../TestEncryptInterceptorLargeHeap.java | 48 --
.../TestMessageDispatchInterceptor.java | 4 +-
webapps/docs/changelog.xml | 1 -
webapps/docs/cluster-howto.xml | 4 -
webapps/docs/config/cluster.xml | 4 -
webapps/docs/security-howto.xml | 5 +-
21 files changed, 4 insertions(+), 1857 deletions(-)
diff --git
a/java/org/apache/catalina/tribes/group/interceptors/EncryptInterceptor.java
b/java/org/apache/catalina/tribes/group/interceptors/EncryptInterceptor.java
deleted file mode 100644
index f073442657..0000000000
--- a/java/org/apache/catalina/tribes/group/interceptors/EncryptInterceptor.java
+++ /dev/null
@@ -1,811 +0,0 @@
-/*
- * 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.catalina.tribes.group.interceptors;
-
-import java.io.Serial;
-import java.security.GeneralSecurityException;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
-import java.security.SecureRandom;
-import java.security.spec.AlgorithmParameterSpec;
-import java.util.ArrayDeque;
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Map;
-import java.util.TreeMap;
-import java.util.concurrent.ConcurrentLinkedQueue;
-
-import javax.crypto.Cipher;
-import javax.crypto.NoSuchPaddingException;
-import javax.crypto.spec.GCMParameterSpec;
-import javax.crypto.spec.IvParameterSpec;
-import javax.crypto.spec.SecretKeySpec;
-
-import org.apache.catalina.tribes.Channel;
-import org.apache.catalina.tribes.ChannelException;
-import org.apache.catalina.tribes.ChannelInterceptor;
-import org.apache.catalina.tribes.ChannelMessage;
-import org.apache.catalina.tribes.Member;
-import org.apache.catalina.tribes.UniqueId;
-import org.apache.catalina.tribes.group.ChannelInterceptorBase;
-import org.apache.catalina.tribes.group.InterceptorPayload;
-import org.apache.catalina.tribes.io.XByteBuffer;
-import org.apache.catalina.tribes.util.StringManager;
-import org.apache.juli.logging.Log;
-import org.apache.juli.logging.LogFactory;
-
-/**
- * Adds encryption using a pre-shared key. The length of the key (in bytes)
must be acceptable for the encryption
- * algorithm being used. For example, for AES, you must use a key of either 16
bytes (128 bits), 24 bytes (192 bits),
- * or 32 bytes (256 bits). You can supply the raw key bytes by calling {@link
#setEncryptionKey(byte[])} or the
- * hex-encoded binary bytes by calling {@link #setEncryptionKey(String)}.
- *
- * @deprecated Configure the cluster to use TLS instead. This interceptor will
be removed in Tomcat 12.
- */
-@Deprecated
-public class EncryptInterceptor extends ChannelInterceptorBase implements
EncryptInterceptorMBean {
-
- private static final Log log = LogFactory.getLog(EncryptInterceptor.class);
- /**
- * String manager for internationalized messages.
- */
- protected static final StringManager sm =
StringManager.getManager(EncryptInterceptor.class);
-
- private static final String DEFAULT_ENCRYPTION_ALGORITHM =
"AES/GCM/NoPadding";
-
- private String providerName;
- private String encryptionAlgorithm = DEFAULT_ENCRYPTION_ALGORITHM;
- private byte[] encryptionKeyBytes;
- private String encryptionKeyString;
- // Milliseconds
- private long replayWindowTime = 10_000;
- private int replayWindowMessageCount = 8192;
-
-
- private BaseEncryptionManager encryptionManager;
-
- /**
- * Creates a new encryption interceptor with default settings.
- */
- public EncryptInterceptor() {
- }
-
- @Override
- public void start(int svc) throws ChannelException {
- validateChannelChain();
-
- if (Channel.SND_TX_SEQ == (svc & Channel.SND_TX_SEQ)) {
- try {
- encryptionManager =
createEncryptionManager(getEncryptionAlgorithm(), getEncryptionKeyInternal(),
- getProviderName(), getReplayWindowTime(),
getReplayWindowMessageCount());
- } catch (GeneralSecurityException gse) {
- throw new
ChannelException(sm.getString("encryptInterceptor.init.failed"), gse);
- }
- }
-
- super.start(svc);
- }
-
- private void validateChannelChain() throws ChannelException {
- ChannelInterceptor interceptor = getPrevious();
- while (null != interceptor) {
- if (interceptor instanceof TcpFailureDetector) {
- throw new
ChannelConfigException(sm.getString("encryptInterceptor.tcpFailureDetector.ordering"));
- }
-
- interceptor = interceptor.getPrevious();
- }
- }
-
- @Override
- public void stop(int svc) throws ChannelException {
- // The manager is null if start() failed or was never called with the
SND_TX_SEQ
- // option. Avoid an NPE at shutdown that would mask the original
configuration error.
- if (Channel.SND_TX_SEQ == (svc & Channel.SND_TX_SEQ) &&
encryptionManager != null) {
- encryptionManager.shutdown();
- }
-
- super.stop(svc);
- }
-
- @Override
- public void sendMessage(Member[] destination, ChannelMessage msg,
InterceptorPayload payload)
- throws ChannelException {
- try {
- byte[] data = msg.getMessage().getBytes();
- // Need trusted time stamp on receiving side, so add time stamp to
encrypted data.
- long timestamp = msg.getTimestamp();
- if (timestamp <= 0) {
- timestamp = System.currentTimeMillis();
- msg.setTimestamp(timestamp);
- }
- byte[] message = new byte[data.length + 8];
- XByteBuffer.toBytes(timestamp, message, 0);
- System.arraycopy(data, 0, message, 8, data.length);
-
- // See #encrypt(byte[]) for an explanation of the return value
- byte[][] bytes = encryptionManager.encrypt(message);
-
- XByteBuffer xbb = msg.getMessage();
-
- // Completely replace the message
- xbb.clear();
- xbb.append(bytes[0], 0, bytes[0].length);
- xbb.append(bytes[1], 0, bytes[1].length);
-
- super.sendMessage(destination, msg, payload);
-
- } catch (GeneralSecurityException gse) {
- log.error(sm.getString("encryptInterceptor.encrypt.failed"));
- throw new ChannelException(gse);
- }
- }
-
- @Override
- public void messageReceived(ChannelMessage msg) {
- try {
- byte[] data = msg.getMessage().getBytes();
- byte[] encryptedData = data;
-
- data = encryptionManager.decrypt(data);
- if (data.length < 8) {
- throw new
GeneralSecurityException(sm.getString("encryptInterceptor.decrypt.error.short-message"));
- }
- // Time stamp is trusted since it was encrypted.
- long trustedTimestamp = XByteBuffer.toLong(data, 0);
- if (!encryptionManager.checkIncomingMessage(encryptedData,
trustedTimestamp)) {
- log.error(sm.getString("encryptInterceptor.decrypt.replay"));
- return;
- }
-
- XByteBuffer xbb = msg.getMessage();
-
- /*
- * Completely replace the message with the decrypted one. The
ChannelData header timestamp is not part of
- * the encrypted payload and is not replaced with the trusted
timestamp. On an untampered wire it is the
- * same as the trusted timestamp.
- */
- xbb.clear();
- xbb.append(data, 8, data.length - 8);
-
- super.messageReceived(msg);
- } catch (GeneralSecurityException gse) {
- log.error(sm.getString("encryptInterceptor.decrypt.failed"), gse);
- }
- }
-
- /**
- * Sets the encryption algorithm to be used for encrypting and decrypting
channel messages. You must specify the
- * <code>algorithm/mode/padding</code>. Information on standard algorithm
names may be found in the
- * <a
href="https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html">Java
- * documentation</a>. Default is <code>AES/GCM/NoPadding</code>.
- *
- * @param algorithm The algorithm to use.
- */
- @Override
- public void setEncryptionAlgorithm(String algorithm) {
- if (algorithm == null) {
- throw new
IllegalArgumentException(sm.getString("encryptInterceptor.algorithm.required"));
- }
- int pos = algorithm.indexOf('/');
- if (pos < 0) {
- throw new
IllegalArgumentException(sm.getString("encryptInterceptor.algorithm.required"));
- }
- pos = algorithm.indexOf('/', pos + 1);
- if (pos < 0) {
- throw new
IllegalArgumentException(sm.getString("encryptInterceptor.algorithm.required"));
- }
-
- encryptionAlgorithm = algorithm;
- }
-
- /**
- * Gets the encryption algorithm being used to encrypt and decrypt channel
messages.
- *
- * @return The algorithm being used, including the algorithm mode and
padding.
- */
- @Override
- public String getEncryptionAlgorithm() {
- return encryptionAlgorithm;
- }
-
- /**
- * Sets the encryption key for encryption and decryption. The length of
the key must be appropriate for the
- * algorithm being used.
- *
- * @param key The encryption key.
- */
- @Override
- public void setEncryptionKey(byte[] key) {
- if (null == key) {
- encryptionKeyBytes = null;
- } else {
- encryptionKeyBytes = key.clone();
- }
- }
-
- /**
- * Sets the encryption key using a hex-encoded string. Each pair of hex
characters represents one byte of the key.
- *
- * @param keyBytes The hex-encoded encryption key.
- */
- public void setEncryptionKey(String keyBytes) {
- this.encryptionKeyString = keyBytes;
- if (null == keyBytes) {
- setEncryptionKey((byte[]) null);
- } else {
- setEncryptionKey(fromHexString(keyBytes.strip()));
- }
- }
-
- /**
- * Gets the encryption key being used for encryption and decryption.
- *
- * @return The encryption key.
- */
- @Override
- public byte[] getEncryptionKey() {
- byte[] key = getEncryptionKeyInternal();
-
- if (null != key) {
- key = key.clone();
- }
-
- return key;
- }
-
- private byte[] getEncryptionKeyInternal() {
- return encryptionKeyBytes;
- }
-
- /**
- * Returns the hex-encoded encryption key string.
- *
- * @return the hex-encoded encryption key, or {@code null} if not set
- */
- public String getEncryptionKeyString() {
- return encryptionKeyString;
- }
-
- /**
- * Sets the hex-encoded encryption key string.
- *
- * @param encryptionKeyString the hex-encoded encryption key
- */
- public void setEncryptionKeyString(String encryptionKeyString) {
- setEncryptionKey(encryptionKeyString);
- }
-
- /**
- * Sets the JCA provider name used for cryptographic activities. Default
is the JVM platform default.
- *
- * @param provider The name of the JCA provider.
- */
- @Override
- public void setProviderName(String provider) {
- providerName = provider;
- }
-
- /**
- * Gets the JCA provider name used for cryptographic activities. Default
is the JVM platform default.
- *
- * @return The name of the JCA provider.
- */
- @Override
- public String getProviderName() {
- return providerName;
- }
-
- /**
- * Returns the time-based replay window in milliseconds.
- *
- * @return The replay window time
- */
- @Override
- public long getReplayWindowTime() {
- return replayWindowTime;
- }
-
- /**
- * Sets the time-based replay window in milliseconds.
- *
- * @param replayWindowTime The replay window time
- */
- @Override
- public void setReplayWindowTime(long replayWindowTime) {
- if (replayWindowTime < 1) {
- throw new
IllegalArgumentException(sm.getString("encryptInterceptor.replayWindowTime.tooSmall"));
- }
- this.replayWindowTime = replayWindowTime;
- if (encryptionManager != null) {
- encryptionManager.setReplayWindowTime(replayWindowTime);
- }
- }
-
- /**
- * Returns the maximum number of replay entries to retain.
- *
- * @return The replay window message count
- */
- @Override
- public int getReplayWindowMessageCount() {
- return replayWindowMessageCount;
- }
-
- /**
- * Sets the maximum number of replay entries to retain.
- *
- * @param replayWindowMessageCount The replay window message count
- */
- @Override
- public void setReplayWindowMessageCount(int replayWindowMessageCount) {
- if (replayWindowMessageCount < 1) {
- throw new
IllegalArgumentException(sm.getString("encryptInterceptor.replayWindowMessageCount.tooSmall"));
- }
- this.replayWindowMessageCount = replayWindowMessageCount;
- if (encryptionManager != null) {
-
encryptionManager.setReplayWindowMessageCount(replayWindowMessageCount);
- }
- }
-
- // Copied from org.apache.tomcat.util.buf.HexUtils
- // @formatter:off
- private static final int[] DEC = {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
- -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 10, 11, 12, 13, 14, 15,
- };
- // @formatter:on
-
-
- private static int getDec(int index) {
- // Fast for correct values, slower for incorrect ones
- try {
- return DEC[index - '0'];
- } catch (ArrayIndexOutOfBoundsException ex) {
- return -1;
- }
- }
-
-
- private static byte[] fromHexString(String input) {
- if (input == null) {
- return null;
- }
-
- if ((input.length() & 1) == 1) {
- // Odd number of characters
- throw new
IllegalArgumentException(sm.getString("hexUtils.fromHex.oddDigits"));
- }
-
- char[] inputChars = input.toCharArray();
- byte[] result = new byte[input.length() >> 1];
- for (int i = 0; i < result.length; i++) {
- int upperNibble = getDec(inputChars[2 * i]);
- int lowerNibble = getDec(inputChars[2 * i + 1]);
- if (upperNibble < 0 || lowerNibble < 0) {
- // Non hex character
- throw new
IllegalArgumentException(sm.getString("hexUtils.fromHex.nonHex"));
- }
- result[i] = (byte) ((upperNibble << 4) + lowerNibble);
- }
- return result;
- }
-
- private static BaseEncryptionManager createEncryptionManager(String
algorithm, byte[] encryptionKey,
- String providerName, long replayWindowTime, int
replayWindowMessageCount)
- throws NoSuchAlgorithmException, NoSuchPaddingException,
NoSuchProviderException {
- if (null == encryptionKey) {
- throw new
IllegalStateException(sm.getString("encryptInterceptor.key.required"));
- }
-
- String algorithmName;
- String algorithmMode;
- String algorithmPadding;
-
- // We need to break-apart the algorithm name e.g. AES/GCM/NoPadding
- // take just the algorithm part.
- int pos = algorithm.indexOf('/');
-
- if (pos >= 0) {
- algorithmName = algorithm.substring(0,
pos).toUpperCase(Locale.ENGLISH);
- int pos2 = algorithm.indexOf('/', pos + 1);
-
- if (pos2 >= 0) {
- algorithmMode = algorithm.substring(pos + 1,
pos2).toUpperCase(Locale.ENGLISH);
- algorithmPadding = algorithm.substring(pos2 +
1).toUpperCase(Locale.ENGLISH);
- } else {
- algorithmMode = "GCM";
- algorithmPadding = "NOPADDING";
- }
- } else {
- algorithmName = algorithm;
- algorithmMode = "GCM";
- algorithmPadding = "NOPADDING";
- }
-
- /*
- * Limit the cipher algorithm modes available. The limits are based on
the cipher algorithm modes listed in the
- * Java Standard Names documentation. Those modes that are not
appropriate or provide no protection are blocked.
- * Where there are performance or security concerns regarding a mode,
a warning is logged. Unrecognised modes,
- * such as those provided by custom JCA providers are allowed but will
be rejected if there is no JCA provider
- * to support them.
- */
- if ("NONE".equals(algorithmMode) || "ECB".equals(algorithmMode) ||
"PCBC".equals(algorithmMode) ||
- "CTS".equals(algorithmMode) || "KW".equals(algorithmMode) ||
"KWP".equals(algorithmMode) ||
- "CTR".equals(algorithmMode) || ("CBC".equals(algorithmMode) &&
"NOPADDING".equals(algorithmPadding)) ||
- ("CFB".equals(algorithmMode) &&
"NOPADDING".equals(algorithmPadding)) ||
- ("GCM".equals(algorithmMode) &&
"PKCS5PADDING".equals(algorithmPadding)) ||
- ("OFB".equals(algorithmMode) &&
"NOPADDING".equals(algorithmPadding))) {
- // Insecure, unsuitable or unsupported
- throw new
IllegalArgumentException(sm.getString("encryptInterceptor.algorithm.unsupported",
algorithm));
-
- } else if (("CBC".equals(algorithmMode) &&
"PKCS5PADDING".equals(algorithmPadding)) ||
- ("CFB".equals(algorithmMode) &&
"PKCS5PADDING".equals(algorithmPadding)) ||
- ("OFB".equals(algorithmMode) &&
"PKCS5PADDING".equals(algorithmPadding))) {
- // Supported but not recommended as more secure modes are available
- log.warn(sm.getString("encryptInterceptor.algorithm.switch",
algorithm));
-
- } else if (algorithmMode.startsWith("CFB") ||
algorithmMode.startsWith("OFB")) {
- // Using a non-default block size. Not supported as insecure
and/or inefficient.
- throw new
IllegalArgumentException(sm.getString("encryptInterceptor.algorithm.unsupported",
algorithm));
-
- } else if ("GCM".equals(algorithmMode) &&
"NOPADDING".equals(algorithmPadding)) {
- // Needs a specialised encryption manager to handle the
differences between GCM and other modes
- return new GCMEncryptionManager(algorithm, new
SecretKeySpec(encryptionKey, algorithmName), providerName,
- replayWindowTime, replayWindowMessageCount);
- }
-
- // Use the default encryption manager
- try {
- return new BaseEncryptionManager(algorithm, new
SecretKeySpec(encryptionKey, algorithmName), providerName,
- replayWindowTime, replayWindowMessageCount);
- } catch (NoSuchAlgorithmException | NoSuchPaddingException |
NoSuchProviderException ex) {
- throw new
IllegalArgumentException(sm.getString("encryptInterceptor.algorithm.unsupported",
algorithm), ex);
- }
- }
-
- private static class BaseEncryptionManager {
- /**
- * The fully-specified algorithm e.g. AES/CBC/PKCS5Padding.
- */
- private final String algorithm;
-
- /**
- * The block size of the cipher.
- */
- private final int blockSize;
-
- /**
- * The cryptographic provider name.
- */
- private final String providerName;
-
- /**
- * The secret key to use for encryption and decryption operations.
- */
- private final SecretKeySpec secretKey;
-
- /**
- * A pool of Cipher objects. Ciphers are expensive to create, but not
to re-initialize, so we use a pool of them
- * which grows as necessary.
- */
- private final ConcurrentLinkedQueue<Cipher> cipherPool;
-
- /**
- * A pool of SecureRandom objects. Each encrypt operation requires
access to a source of randomness.
- * SecureRandom is thread-safe, but sharing a single instance will
likely be a bottleneck.
- */
- private final ConcurrentLinkedQueue<SecureRandom> randomPool;
- private final TreeMap<Long,ArrayDeque<UniqueId>>
receivedTimestampNonces = new TreeMap<>();
- private final Map<UniqueId,Long> receivedNonceTimestamps = new
HashMap<>();
- private long replayWindowTime;
- private volatile int replayWindowMessageCount;
- private long lastRemovedTimestamp;
- private int receivedNonceCount = 0;
-
- BaseEncryptionManager(String algorithm, SecretKeySpec secretKey,
String providerName, long replayWindowTime,
- int replayWindowMessageCount)
- throws NoSuchAlgorithmException, NoSuchPaddingException,
NoSuchProviderException {
- this.algorithm = algorithm;
- this.providerName = providerName;
- this.secretKey = secretKey;
- this.replayWindowTime = replayWindowTime;
- this.lastRemovedTimestamp = System.currentTimeMillis() -
replayWindowTime;
- this.replayWindowMessageCount = replayWindowMessageCount;
-
- cipherPool = new ConcurrentLinkedQueue<>();
- Cipher cipher = createCipher();
- blockSize = cipher.getBlockSize();
- cipherPool.offer(cipher);
- randomPool = new ConcurrentLinkedQueue<>();
- }
-
- public void shutdown() {
- // Individual Cipher and SecureRandom objects need no explicit
tear down
- cipherPool.clear();
- randomPool.clear();
- synchronized (this) {
- receivedTimestampNonces.clear();
- receivedNonceTimestamps.clear();
- lastRemovedTimestamp = Long.MIN_VALUE;
- receivedNonceCount = 0;
- }
- }
-
- public synchronized void setReplayWindowTime(long replayWindowTime) {
- this.replayWindowTime = replayWindowTime;
- // Only move the lastRemovedTimestamp forwards. Moving it
backwards could open a window for replay attacks.
- if (lastRemovedTimestamp < System.currentTimeMillis() -
replayWindowTime) {
- lastRemovedTimestamp = System.currentTimeMillis() -
replayWindowTime;
- }
- }
-
- public void setReplayWindowMessageCount(int replayWindowMessageCount) {
- this.replayWindowMessageCount = replayWindowMessageCount;
- synchronized (this) {
- while (receivedNonceCount > replayWindowMessageCount) {
- removeEldestEntry();
- }
- }
- }
-
- public synchronized boolean checkIncomingMessage(byte[] bytes, long
messageTimestamp) {
- if (messageTimestamp < (System.currentTimeMillis() -
replayWindowTime)) {
- return false;
- }
- // Shouldn't happen but provide some mitigation against excessive
clock skew.
- if (messageTimestamp > (System.currentTimeMillis() +
replayWindowTime)) {
- return false;
- }
- if (messageTimestamp <= lastRemovedTimestamp) {
- return false;
- }
-
- UniqueId nonce = new UniqueId(bytes, 0, getIVSize());
- if (receivedNonceTimestamps.containsKey(nonce)) {
- return false;
- }
-
-
receivedTimestampNonces.computeIfAbsent(Long.valueOf(messageTimestamp), k ->
new ArrayDeque<>()).addLast(nonce);
- receivedNonceTimestamps.put(nonce, Long.valueOf(messageTimestamp));
- receivedNonceCount++;
- while (receivedNonceCount > replayWindowMessageCount) {
- removeEldestEntry();
- }
-
- return true;
- }
-
- private String getAlgorithm() {
- return algorithm;
- }
-
- private SecretKeySpec getSecretKey() {
- return secretKey;
- }
-
- /**
- * Gets the size, in bytes, of the initialization vector for the
cipher being used. The IV size is often, but
- * not always, the block size for the cipher.
- *
- * @return The size of the initialization vector for this algorithm.
- */
- protected int getIVSize() {
- return blockSize;
- }
-
- private String getProviderName() {
- return providerName;
- }
-
- private Cipher createCipher() throws NoSuchAlgorithmException,
NoSuchPaddingException, NoSuchProviderException {
- String providerName = getProviderName();
-
- if (null == providerName) {
- return Cipher.getInstance(getAlgorithm());
- } else {
- return Cipher.getInstance(getAlgorithm(), providerName);
- }
- }
-
- private Cipher getCipher() throws GeneralSecurityException {
- Cipher cipher = cipherPool.poll();
-
- if (null == cipher) {
- cipher = createCipher();
- }
-
- return cipher;
- }
-
- private void returnCipher(Cipher cipher) {
- cipherPool.offer(cipher);
- }
-
- private SecureRandom getRandom() {
- SecureRandom random = randomPool.poll();
-
- if (null == random) {
- random = new SecureRandom();
- }
-
- return random;
- }
-
- private void returnRandom(SecureRandom random) {
- randomPool.offer(random);
- }
-
- /**
- * Encrypts the input <code>bytes</code> into two separate byte
arrays: one for the random initialization vector
- * (IV) used for this message, and the second one containing the
actual encrypted payload. This method returns a
- * pair of byte arrays instead of a single concatenated one to reduce
the number of byte buffers created and
- * copied during the whole operation -- including message re-building.
- *
- * @param bytes The data to encrypt.
- *
- * @return The IV in [0] and the encrypted data in [1].
- *
- * @throws GeneralSecurityException If the input data cannot be
encrypted.
- */
- private byte[][] encrypt(byte[] bytes) throws GeneralSecurityException
{
- Cipher cipher = null;
-
- // Always use a random IV For cipher setup.
- // The recipient doesn't need the (matching) IV because we will
always
- // pre-pad messages with the IV as a nonce.
- byte[] iv = generateIVBytes();
-
- try {
- cipher = getCipher();
- cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(),
generateIV(iv, 0, getIVSize()));
-
- // Prepend the IV to the beginning of the encrypted data
- byte[][] data = new byte[2][];
- data[0] = iv;
- data[1] = cipher.doFinal(bytes);
-
- return data;
- } finally {
- if (null != cipher) {
- returnCipher(cipher);
- }
- }
- }
-
- /**
- * Decrypts the input <code>bytes</code>.
- *
- * @param bytes The data to decrypt.
- *
- * @return The decrypted data.
- *
- * @throws GeneralSecurityException If the input data cannot be
decrypted.
- */
- private byte[] decrypt(byte[] bytes) throws GeneralSecurityException {
- Cipher cipher = null;
-
- int ivSize = getIVSize();
- AlgorithmParameterSpec IV = generateIV(bytes, 0, ivSize);
-
- try {
- cipher = getCipher();
-
- cipher.init(Cipher.DECRYPT_MODE, getSecretKey(), IV);
-
- // Decrypt remainder of the message.
- return cipher.doFinal(bytes, ivSize, bytes.length - ivSize);
- } finally {
- if (null != cipher) {
- returnCipher(cipher);
- }
- }
- }
-
- protected byte[] generateIVBytes() {
- byte[] ivBytes = new byte[getIVSize()];
-
- SecureRandom random = null;
-
- try {
- random = getRandom();
-
- // Always use a random IV For cipher setup.
- // The recipient doesn't need the (matching) IV because we
will always
- // pre-pad messages with the IV as a nonce.
- random.nextBytes(ivBytes);
-
- return ivBytes;
- } finally {
- if (null != random) {
- returnRandom(random);
- }
- }
- }
-
- protected AlgorithmParameterSpec generateIV(byte[] ivBytes, int
offset, int length) {
- return new IvParameterSpec(ivBytes, offset, length);
- }
-
- private void removeEldestEntry() {
- Map.Entry<Long,ArrayDeque<UniqueId>> entry =
receivedTimestampNonces.firstEntry();
- if (entry != null) {
- ArrayDeque<UniqueId> nonces = entry.getValue();
- UniqueId nonce = nonces.pollFirst();
- if (nonce != null) {
- receivedNonceTimestamps.remove(nonce);
- updateLastRemovedTimestamp(entry.getKey().longValue());
- receivedNonceCount--;
- }
- if (nonces.isEmpty()) {
- receivedTimestampNonces.pollFirstEntry();
- }
- }
- }
-
- private void updateLastRemovedTimestamp(long removedTimestamp) {
- if (removedTimestamp > lastRemovedTimestamp) {
- lastRemovedTimestamp = removedTimestamp;
- }
- }
- }
-
- /**
- * Implements an EncryptionManager for using GCM block cipher modes.
- * <p>
- * GCM works a little differently than some of the other block cipher
modes supported by EncryptInterceptor. First
- * of all, it requires a different kind of AlgorithmParameterSpec object
to be used, and second, it requires a
- * slightly different initialization vector and something called an
"authentication tag".
- * <p>
- * The choice of IV length can be somewhat arbitrary, but there is
consensus that 96-bit (12-byte) IVs for GCM are
- * the best trade-off between security and performance. For other block
cipher modes, IV length is the same as the
- * block size.
- * <p>
- * The "authentication tag" is a computed authentication value based upon
the message and the encryption process.
- * GCM defines these tags as the number of bits to use for the
authentication tag, and it's clear that the highest
- * number of bits supported 128-bit provide the best security.
- */
- private static class GCMEncryptionManager extends BaseEncryptionManager {
- GCMEncryptionManager(String algorithm, SecretKeySpec secretKey, String
providerName, long replayWindowTime,
- int replayWindowMessageCount)
- throws NoSuchAlgorithmException, NoSuchPaddingException,
NoSuchProviderException {
- super(algorithm, secretKey, providerName, replayWindowTime,
replayWindowMessageCount);
- }
-
- @Override
- protected int getIVSize() {
- return 12; // See class javadoc for explanation of this magic
number (12)
- }
-
- @Override
- protected AlgorithmParameterSpec generateIV(byte[] bytes, int offset,
int length) {
- // See class javadoc for explanation of this magic number (128)
- return new GCMParameterSpec(128, bytes, offset, length);
- }
- }
-
- static class ChannelConfigException extends ChannelException {
- @Serial
- private static final long serialVersionUID = 1L;
-
- ChannelConfigException(String message) {
- super(message);
- }
- }
-}
diff --git
a/java/org/apache/catalina/tribes/group/interceptors/EncryptInterceptorMBean.java
b/java/org/apache/catalina/tribes/group/interceptors/EncryptInterceptorMBean.java
deleted file mode 100644
index a01b5ee24f..0000000000
---
a/java/org/apache/catalina/tribes/group/interceptors/EncryptInterceptorMBean.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * 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.catalina.tribes.group.interceptors;
-
-/**
- * MBean interface for managing the {@link EncryptInterceptor} configuration
and status.
- *
- * @deprecated Configure the cluster to use TLS instead. This interceptor will
be removed in Tomcat 12.
- */
-@Deprecated
-public interface EncryptInterceptorMBean {
-
- /**
- * Returns the option flag for the encryption interceptor.
- *
- * @return the option flag value
- */
- int getOptionFlag();
-
- /**
- * Sets the option flag for the encryption interceptor.
- *
- * @param optionFlag the option flag value
- */
- void setOptionFlag(int optionFlag);
-
- /**
- * Sets the encryption algorithm to use.
- *
- * @param algorithm the encryption algorithm in algorithm/mode/padding
format
- */
- void setEncryptionAlgorithm(String algorithm);
-
- /**
- * Returns the encryption algorithm currently in use.
- *
- * @return the encryption algorithm string
- */
- String getEncryptionAlgorithm();
-
- /**
- * Sets the encryption key as raw bytes.
- *
- * @param key the encryption key bytes
- */
- void setEncryptionKey(byte[] key);
-
- /**
- * Returns the encryption key as raw bytes.
- *
- * @return the encryption key bytes
- */
- byte[] getEncryptionKey();
-
- /**
- * Sets the JCA provider name for cryptographic operations.
- *
- * @param provider the JCA provider name
- */
- void setProviderName(String provider);
-
- /**
- * Returns the JCA provider name for cryptographic operations.
- *
- * @return the JCA provider name, or {@code null} for default
- */
- String getProviderName();
-
- /**
- * Sets the time-based replay window in milliseconds.
- *
- * @param replayWindowTime the replay window time
- */
- void setReplayWindowTime(long replayWindowTime);
-
- /**
- * Returns the time-based replay window in milliseconds.
- *
- * @return the replay window time
- */
- long getReplayWindowTime();
-
- /**
- * Sets the maximum number of replay cache entries.
- *
- * @param replayWindowMessageCount the replay window message count
- */
- void setReplayWindowMessageCount(int replayWindowMessageCount);
-
- /**
- * Returns the maximum number of replay cache entries.
- *
- * @return the replay window message count
- */
- int getReplayWindowMessageCount();
-}
diff --git
a/java/org/apache/catalina/tribes/group/interceptors/LocalStrings.properties
b/java/org/apache/catalina/tribes/group/interceptors/LocalStrings.properties
index f1ab11ed18..e401421ed3 100644
--- a/java/org/apache/catalina/tribes/group/interceptors/LocalStrings.properties
+++ b/java/org/apache/catalina/tribes/group/interceptors/LocalStrings.properties
@@ -16,19 +16,6 @@
domainFilterInterceptor.member.refused=Member [{0}] was refused to join cluster
domainFilterInterceptor.message.refused=Received message from cluster [{0}]
was refused.
-encryptInterceptor.algorithm.required=Encryption algorithm is required,
fully-specified e.g. AES/GCM/NoPadding
-encryptInterceptor.algorithm.switch=The EncryptInterceptor is using the
insecure algorithm [{0}]. It is recommended to switch to using
AES/GCM/NoPadding.
-encryptInterceptor.algorithm.unsupported=EncryptInterceptor does not support
algorithm [{0}]
-encryptInterceptor.decrypt.error.short-message=Failed to decrypt message:
premature end-of-message
-encryptInterceptor.decrypt.failed=Failed to decrypt message
-encryptInterceptor.decrypt.replay=Failed to decrypt message: replay attack
detected
-encryptInterceptor.encrypt.failed=Failed to encrypt message
-encryptInterceptor.init.failed=Failed to initialize EncryptInterceptor
-encryptInterceptor.key.required=Encryption key is required
-encryptInterceptor.replayWindowMessageCount.tooSmall=Replay window message
count must be at least 1
-encryptInterceptor.replayWindowTime.tooSmall=Replay window time must be at
least 1 millisecond
-encryptInterceptor.tcpFailureDetector.ordering=EncryptInterceptor must be
upstream of TcpFailureDetector. Please re-order EncryptInterceptor to be listed
before TcpFailureDetector in your channel interceptor pipeline.
-
fragmentationInterceptor.expire.tooSmall=Expire must be at least 1 millisecond
fragmentationInterceptor.fragment.discarded=Received fragment failed
validation. The fragment is discarded.
fragmentationInterceptor.fragment.too-short=Received fragment with too little
data, length [{0}].
diff --git
a/java/org/apache/catalina/tribes/group/interceptors/LocalStrings_cs.properties
b/java/org/apache/catalina/tribes/group/interceptors/LocalStrings_cs.properties
index b49df18e87..6b0c760328 100644
---
a/java/org/apache/catalina/tribes/group/interceptors/LocalStrings_cs.properties
+++
b/java/org/apache/catalina/tribes/group/interceptors/LocalStrings_cs.properties
@@ -16,8 +16,6 @@
# Do not edit this file directly.
# To edit translations see:
https://tomcat.apache.org/getinvolved.html#Translations
-encryptInterceptor.decrypt.error.short-message=Dešifrování zprávy selhalo:
předčasný konec zprávy
-
gzipInterceptor.report=GZip Interceptor Report[\n\
\tCelkový počet zpráv: {0}\n\
\tTx zprávy - komprimované: {1}\n\
diff --git
a/java/org/apache/catalina/tribes/group/interceptors/LocalStrings_de.properties
b/java/org/apache/catalina/tribes/group/interceptors/LocalStrings_de.properties
index aa5b4c3995..7e4db32abd 100644
---
a/java/org/apache/catalina/tribes/group/interceptors/LocalStrings_de.properties
+++
b/java/org/apache/catalina/tribes/group/interceptors/LocalStrings_de.properties
@@ -18,9 +18,6 @@
domainFilterInterceptor.member.refused=Mitglied [{0}] wurde nicht zum Cluster
zugelassen
-encryptInterceptor.decrypt.error.short-message=Konnte die Nachricht nicht
entschlüsseln: Vorzeitiges Ende der Nachricht
-encryptInterceptor.decrypt.failed=Nachricht konnte nicht entschlüsselt werden
-
messageDispatchInterceptor.queue.full=Asynchrone Warteschlange ist voll. Das
Limit von [{0}] Bytes ist erreicht mit aktuell [{1}] Bytes.
nonBlockingCoordinator.memberAlive.failed=Member Alive-Check kann nicht
ausgeführt werden, down angenommen.
diff --git
a/java/org/apache/catalina/tribes/group/interceptors/LocalStrings_es.properties
b/java/org/apache/catalina/tribes/group/interceptors/LocalStrings_es.properties
index 39cd37df2d..6ac5b4505d 100644
---
a/java/org/apache/catalina/tribes/group/interceptors/LocalStrings_es.properties
+++
b/java/org/apache/catalina/tribes/group/interceptors/LocalStrings_es.properties
@@ -18,8 +18,6 @@
domainFilterInterceptor.message.refused=El mensaje [{0}] recibido del cluster
fue rechazado
-encryptInterceptor.decrypt.error.short-message=Fallo al descifrar el mensaje:
fin-de-mensaje prematuro
-
gzipInterceptor.report=Reporte del Interceptor GZip[\n\
\tTotal de Mensajes: {0}\n\
\tTx Mensajes Comprimidos: {1}\n\
diff --git
a/java/org/apache/catalina/tribes/group/interceptors/LocalStrings_fr.properties
b/java/org/apache/catalina/tribes/group/interceptors/LocalStrings_fr.properties
index 7663231091..1110452e04 100644
---
a/java/org/apache/catalina/tribes/group/interceptors/LocalStrings_fr.properties
+++
b/java/org/apache/catalina/tribes/group/interceptors/LocalStrings_fr.properties
@@ -19,19 +19,6 @@
domainFilterInterceptor.member.refused=Le membre [{0}] a été refusé dans le
cluster
domainFilterInterceptor.message.refused=Le message reçu du cluster [{0}] a été
refusé
-encryptInterceptor.algorithm.required=Un algorithme de cryptage est requis,
avec une spécification complète telle que AES/CBC/PKCS5Padding
-encryptInterceptor.algorithm.switch=EncryptInterceptor utilise l''algorithme
non sécurisé [{0}], il est recommandé de changer en AES/GCM/NoPadding
-encryptInterceptor.algorithm.unsupported=EncryptInterceptor ne supporte pas
l''algorithme [{0}]
-encryptInterceptor.decrypt.error.short-message=Echec du décryptage du message
: fin de message prématuré
-encryptInterceptor.decrypt.failed=Echec de décryptage du message
-encryptInterceptor.decrypt.replay=Impossible de décrypter le message: une
attaque par répétition a été détectée
-encryptInterceptor.encrypt.failed=Erreur de cryptage du message
-encryptInterceptor.init.failed=Echec de l'initalisation d'EncryptInterceptor
-encryptInterceptor.key.required=Une clé de cryptage est requise
-encryptInterceptor.replayWindowMessageCount.tooSmall=Le nombre de messages
dans la fenêtre de répétition doit être au minimum 1
-encryptInterceptor.replayWindowTime.tooSmall=L'intervalle de temps pour la
fenêtre de répétition doit être au moins 1 milliseconde
-encryptInterceptor.tcpFailureDetector.ordering=EncryptInterceptor doit être en
amont de TcpFailureDetector, l'EncryptInterceptor doit être repositionné pour
être listé avant TcpFailureDetector dans le pipeline d'intercepteurs du canal
-
fragmentationInterceptor.fragments.missing=Les fragments sont manquants
fragmentationInterceptor.heartbeat.failed=Impossible d'effectuer le nettoyage
périodique de l'intercepteur de fragments
diff --git
a/java/org/apache/catalina/tribes/group/interceptors/LocalStrings_ja.properties
b/java/org/apache/catalina/tribes/group/interceptors/LocalStrings_ja.properties
index c3d959d527..c7471d8540 100644
---
a/java/org/apache/catalina/tribes/group/interceptors/LocalStrings_ja.properties
+++
b/java/org/apache/catalina/tribes/group/interceptors/LocalStrings_ja.properties
@@ -19,19 +19,6 @@
domainFilterInterceptor.member.refused=メンバーはクラスター [{0}] への参加を拒否されました。
domainFilterInterceptor.message.refused=クラスター [{0}] から受信したメッセージは拒否されました。
-encryptInterceptor.algorithm.required=暗号化アルゴリズムが必要です。AES/GCM/NoPadding
のように完全な形式で指定してください
-encryptInterceptor.algorithm.switch=EncryptInterceptor は安全ではないアルゴリズム [{0}]
を使用しています。AES/GCM/NoPadding への切り替えが推奨されます。
-encryptInterceptor.algorithm.unsupported=EncryptInterceptor はアルゴリズム [{0}]
をサポートしていません
-encryptInterceptor.decrypt.error.short-message=メッセージの復号に失敗: メッセージの末尾が途切れています
-encryptInterceptor.decrypt.failed=メッセージの復号に失敗しました。
-encryptInterceptor.decrypt.replay=メッセージの復号に失敗しました: リプレイ攻撃が検出されました
-encryptInterceptor.encrypt.failed=メッセージを暗号化できません。
-encryptInterceptor.init.failed=EncryptInterceptorの初期化に失敗しました
-encryptInterceptor.key.required=暗号化キーが必要です。
-encryptInterceptor.replayWindowMessageCount.tooSmall=replayWindowMessageCount
は少なくとも1である必要があります
-encryptInterceptor.replayWindowTime.tooSmall=replayWindowTime
は、少なくとも1ミリ秒である必要があります
-encryptInterceptor.tcpFailureDetector.ordering=EncryptInterceptorはTcpFailureDetectorの上流になければなりません。
チャネルインターセプターパイプラインのTcpFailureDetectorの前にリストされるようにEncryptInterceptorを再設定してください。
-
fragmentationInterceptor.fragments.missing=フラグメントが見つかりません。
fragmentationInterceptor.heartbeat.failed=fragmentationInterceptor
でハートビートクリーンアップを実行できません
diff --git
a/java/org/apache/catalina/tribes/group/interceptors/LocalStrings_ko.properties
b/java/org/apache/catalina/tribes/group/interceptors/LocalStrings_ko.properties
index fba6444989..beeffb4da4 100644
---
a/java/org/apache/catalina/tribes/group/interceptors/LocalStrings_ko.properties
+++
b/java/org/apache/catalina/tribes/group/interceptors/LocalStrings_ko.properties
@@ -19,14 +19,6 @@
domainFilterInterceptor.member.refused=멤버 [{0}]이(가) 클러스터에 참가하는 것이 거부되었습니다.
domainFilterInterceptor.message.refused=클러스터 [{0}](으)로부터 받은 메시지가 거부되었습니다.
-encryptInterceptor.algorithm.required=암호화 알고리즘을 완전하게 지정해야 합니다. 예)
AES/CBC/PKCS5Padding.
-encryptInterceptor.decrypt.error.short-message=메시지를 해독하지 못했습니다: 메시지가 너무 일찍
끝났습니다 (premature end-of-message).
-encryptInterceptor.decrypt.failed=메시지를 해독하지 못했습니다.
-encryptInterceptor.encrypt.failed=메시지를 암호화하지 못했습니다.
-encryptInterceptor.init.failed=EncryptInterceptor를 초기화하지 못했습니다.
-encryptInterceptor.key.required=암호화 키가 필수적입니다.
-encryptInterceptor.tcpFailureDetector.ordering=EncryptInterceptor는 반드시
TcpFailureDetector 보다 먼저 위치해야 합니다. 채널 인터셉터 파이프라인 내에서, EncryptInterceptor가
TcpFailureDetector 보다 먼저 위치하도록 조정하십시오.
-
fragmentationInterceptor.fragments.missing=Fragment들이 없습니다.
fragmentationInterceptor.heartbeat.failed=FragmentationInterceptor에서
heartbeat를 clean up 할 수 없습니다.
diff --git
a/java/org/apache/catalina/tribes/group/interceptors/LocalStrings_pt_BR.properties
b/java/org/apache/catalina/tribes/group/interceptors/LocalStrings_pt_BR.properties
index 16485ddb29..62803d9de4 100644
---
a/java/org/apache/catalina/tribes/group/interceptors/LocalStrings_pt_BR.properties
+++
b/java/org/apache/catalina/tribes/group/interceptors/LocalStrings_pt_BR.properties
@@ -16,8 +16,6 @@
# Do not edit this file directly.
# To edit translations see:
https://tomcat.apache.org/getinvolved.html#Translations
-encryptInterceptor.decrypt.error.short-message=Falha ao decriptar mensagem:
fim prematuro da mensagem
-
nonBlockingCoordinator.memberAlive.failed=Impossível realizar verificação de
membros ativos, assumindo membro está down
staticMembershipInterceptor.no.pingInterceptor=Não há TcpPingInterceptor,
portanto, a verificação de "saúde" dos membros estáticos não funcionam. Por
favor, defina TcpPingInterceptor.
diff --git
a/java/org/apache/catalina/tribes/group/interceptors/LocalStrings_ru.properties
b/java/org/apache/catalina/tribes/group/interceptors/LocalStrings_ru.properties
index 276b104a20..40e359fcfd 100644
---
a/java/org/apache/catalina/tribes/group/interceptors/LocalStrings_ru.properties
+++
b/java/org/apache/catalina/tribes/group/interceptors/LocalStrings_ru.properties
@@ -19,8 +19,6 @@
domainFilterInterceptor.member.refused=Участнику [{0}] было отказано в
присоединении к кластеру
domainFilterInterceptor.message.refused=Сообщение полученое от кластера [{0}]
было отклонено.
-encryptInterceptor.decrypt.error.short-message=Невозможно расшифровать
сообщение: слишком мало символов
-
nonBlockingCoordinator.memberAlive.failed=Невозможно проверить участника,
считаем что упал
staticMembershipInterceptor.sendShutdown.failed=Не удалось сообщить об
отключении.
diff --git
a/java/org/apache/catalina/tribes/group/interceptors/LocalStrings_zh_CN.properties
b/java/org/apache/catalina/tribes/group/interceptors/LocalStrings_zh_CN.properties
index 1a44c0c1ce..22b5fac9a3 100644
---
a/java/org/apache/catalina/tribes/group/interceptors/LocalStrings_zh_CN.properties
+++
b/java/org/apache/catalina/tribes/group/interceptors/LocalStrings_zh_CN.properties
@@ -19,14 +19,6 @@
domainFilterInterceptor.member.refused=成员被拒绝加入集群 cluster[{0}]
domainFilterInterceptor.message.refused=从集群[{0}]中接收的消息被拒绝
-encryptInterceptor.algorithm.required=加密算法是必需的,充分说明,例如AES / CBC / PKCS5Padding
-encryptInterceptor.decrypt.error.short-message=解密消息失败: 结尾消息提前结束
-encryptInterceptor.decrypt.failed=无法解密信息
-encryptInterceptor.encrypt.failed=无法加密信息
-encryptInterceptor.init.failed=初始化EncryptInterceptor失败
-encryptInterceptor.key.required=需要加密密钥
-encryptInterceptor.tcpFailureDetector.ordering=加密拦截器必须位于TCP故障检测器的上游。请重新订购加密拦截器,将其列在通道拦截器管道中的TCP故障检测器之前。
-
fragmentationInterceptor.fragments.missing=碎片丢失。
fragmentationInterceptor.heartbeat.failed=无法在frag拦截器中执行心跳清除
diff --git
a/test/org/apache/catalina/tribes/group/interceptors/EncryptInterceptorBaseTest.java
b/test/org/apache/catalina/tribes/group/interceptors/EncryptInterceptorBaseTest.java
deleted file mode 100644
index b155aebbec..0000000000
---
a/test/org/apache/catalina/tribes/group/interceptors/EncryptInterceptorBaseTest.java
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * 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.catalina.tribes.group.interceptors;
-
-import java.io.File;
-import java.security.Security;
-import java.util.ArrayList;
-import java.util.Collection;
-
-import org.junit.AfterClass;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.BeforeClass;
-
-import org.apache.catalina.tribes.ChannelException;
-import org.apache.catalina.tribes.ChannelInterceptor;
-import org.apache.catalina.tribes.ChannelMessage;
-import org.apache.catalina.tribes.Member;
-import org.apache.catalina.tribes.group.ChannelInterceptorBase;
-import org.apache.catalina.tribes.group.InterceptorPayload;
-import org.apache.catalina.tribes.io.ChannelData;
-import org.apache.catalina.tribes.io.XByteBuffer;
-import org.apache.tomcat.util.ExceptionUtils;
-
-@Deprecated
-public class EncryptInterceptorBaseTest {
-
- protected static final String MESSAGE_FILE = "message.bin";
-
- protected static final String encryptionKey128 =
"cafebabedeadbeefbeefcafecafebabe";
- protected static final String encryptionKey192 =
"cafebabedeadbeefbeefcafecafebabedeadbeefbeefcafe";
- protected static final String encryptionKey256 =
"cafebabedeadbeefcafebabedeadbeefcafebabedeadbeefcafebabedeadbeef";
-
- protected EncryptInterceptor src;
- protected EncryptInterceptor dest;
-
-
- @BeforeClass
- public static void setupClass() {
- Security.setProperty("jdk.tls.disabledAlgorithms", "");
- Security.setProperty("crypto.policy", "unlimited");
- }
-
-
- @AfterClass
- public static void cleanup() {
- int attempts = 0;
- int maxAttempts = 2;
- while (attempts < maxAttempts) {
- attempts++;
- try {
- File f = new File(MESSAGE_FILE);
- if (f.isFile()) {
- Assert.assertTrue(f.delete());
- }
- } catch (Throwable t) {
- ExceptionUtils.handleThrowable(t);
- if (attempts < maxAttempts) {
- // Brief delay before re-try
- try {
- Thread.sleep(50);
- } catch (InterruptedException e) {
- // Ignore. The delay will just be shorter than
expected.
- }
- } else {
- throw t;
- }
- }
- }
- }
-
-
- @Before
- public void setup() {
- src = new EncryptInterceptor();
- src.setEncryptionKey(encryptionKey128);
-
- dest = new EncryptInterceptor();
- dest.setEncryptionKey(encryptionKey128);
-
- src.setNext(new PipedInterceptor(dest));
- dest.setPrevious(new ValueCaptureInterceptor());
- }
-
-
- /**
- * Actually go through the interceptor's send/receive message methods.
- *
- * @param input The clear text message to sent
- * @param src The interceptor to use to encrypt the message
- * @param dest The interceptor to use to decrypt the message
- *
- * @return The clear text message received
- */
- protected static String roundTrip(String input, EncryptInterceptor src,
EncryptInterceptor dest) throws Exception {
- byte[] bytes = input.getBytes("UTF-8");
-
- bytes = roundTrip(bytes, src, dest);
-
- return new String(bytes, "UTF-8");
- }
-
-
- /**
- * Actually go through the interceptor's send/receive message methods.
- *
- * @param input The clear text message to sent
- * @param src The interceptor to use to encrypt the message
- * @param dest The interceptor to use to decrypt the message
- *
- * @return The clear text message received
- */
- protected static byte[] roundTrip(byte[] input, EncryptInterceptor src,
EncryptInterceptor dest) throws Exception {
- ChannelData msg = new ChannelData(false);
- msg.setMessage(new XByteBuffer(input, false));
- src.sendMessage(null, msg, null);
-
- return ((ValueCaptureInterceptor) dest.getPrevious()).getValue();
- }
-
-
- /**
- * Interceptor that delivers directly to a destination.
- */
- protected static class PipedInterceptor extends ChannelInterceptorBase {
- private ChannelInterceptor dest;
-
- PipedInterceptor(ChannelInterceptor dest) {
- if (null == dest) {
- throw new IllegalArgumentException("Destination must not be
null");
- }
-
- this.dest = dest;
- }
-
- @Override
- public void sendMessage(Member[] destination, ChannelMessage msg,
InterceptorPayload payload)
- throws ChannelException {
- dest.messageReceived(msg);
- }
- }
-
- /**
- * Interceptor that simply captures the latest message sent to or received
by it.
- */
- protected static class ValueCaptureInterceptor extends
ChannelInterceptorBase {
- private byte[] value;
-
- @Override
- public void sendMessage(Member[] destination, ChannelMessage msg,
InterceptorPayload payload)
- throws ChannelException {
- value = msg.getMessage().getBytes();
- }
-
- @Override
- public void messageReceived(ChannelMessage msg) {
- value = msg.getMessage().getBytes();
- }
-
- public byte[] getValue() {
- return value;
- }
- }
-
- /**
- * Interceptor that simply captures all messages sent to or received by it.
- */
- protected static class ValuesCaptureInterceptor extends
ChannelInterceptorBase {
- private ArrayList<byte[]> messages = new ArrayList<>();
-
- @Override
- public void sendMessage(Member[] destination, ChannelMessage msg,
InterceptorPayload payload)
- throws ChannelException {
- synchronized (messages) {
- messages.add(msg.getMessage().getBytes());
- }
- }
-
- @Override
- public void messageReceived(ChannelMessage msg) {
- synchronized (messages) {
- messages.add(msg.getMessage().getBytes());
- }
- }
-
- @SuppressWarnings("unchecked")
- public Collection<byte[]> getValues() {
- return (Collection<byte[]>) messages.clone();
- }
- }
-
-}
diff --git
a/test/org/apache/catalina/tribes/group/interceptors/TestEncryptInterceptor.java
b/test/org/apache/catalina/tribes/group/interceptors/TestEncryptInterceptor.java
deleted file mode 100644
index ff0a888b71..0000000000
---
a/test/org/apache/catalina/tribes/group/interceptors/TestEncryptInterceptor.java
+++ /dev/null
@@ -1,439 +0,0 @@
-/*
- * 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.catalina.tribes.group.interceptors;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.util.Collection;
-
-import javax.crypto.Cipher;
-
-import org.hamcrest.MatcherAssert;
-import org.hamcrest.core.IsEqual;
-import org.hamcrest.core.IsNot;
-
-import org.junit.Assert;
-import org.junit.Assume;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-
-import org.apache.catalina.tribes.Channel;
-import org.apache.catalina.tribes.ChannelException;
-import org.apache.catalina.tribes.io.ChannelData;
-import org.apache.catalina.tribes.io.XByteBuffer;
-
-/**
- * Tests the EncryptInterceptor.
- *
- * Many of the tests in this class use strings as input and output, even
- * though the interceptor actually operates on byte arrays. This is done
- * for readability for the tests and their outputs.
- */
-@Deprecated
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-public class TestEncryptInterceptor extends EncryptInterceptorBaseTest {
-
- @Test
- public void testBasic() throws Exception {
- src.start(Channel.SND_TX_SEQ);
- dest.start(Channel.SND_TX_SEQ);
-
- String testInput = "The quick brown fox jumps over the lazy dog.";
-
- Assert.assertEquals("Basic roundtrip failed",
- testInput,
- roundTrip(testInput, src, dest));
- }
-
- @Test
- public void testMultipleMessages() throws Exception {
- src.start(Channel.SND_TX_SEQ);
- dest.start(Channel.SND_TX_SEQ);
-
- String testInput = "The quick brown fox jumps over the lazy dog.";
-
- Assert.assertEquals("Basic roundtrip failed",
- testInput,
- roundTrip(testInput, src, dest));
-
- Assert.assertEquals("Second roundtrip failed",
- testInput,
- roundTrip(testInput, src, dest));
-
- Assert.assertEquals("Third roundtrip failed",
- testInput,
- roundTrip(testInput, src, dest));
-
- Assert.assertEquals("Fourth roundtrip failed",
- testInput,
- roundTrip(testInput, src, dest));
-
- Assert.assertEquals("Fifth roundtrip failed",
- testInput,
- roundTrip(testInput, src, dest));
- }
-
- @Test
- public void testTinyPayload() throws Exception {
- src.start(Channel.SND_TX_SEQ);
- dest.start(Channel.SND_TX_SEQ);
-
- String testInput = "x";
-
- Assert.assertEquals("Tiny payload roundtrip failed",
- testInput,
- roundTrip(testInput, src, dest));
- }
-
- @Test
- public void testLargePayload() throws Exception {
- src.start(Channel.SND_TX_SEQ);
- dest.start(Channel.SND_TX_SEQ);
-
- byte[] bytes = new byte[1024*1024];
-
- Assert.assertArrayEquals("Huge payload roundtrip failed",
- bytes,
- roundTrip(bytes, src, dest));
- }
-
- @Test
- public void testCustomProvider() throws Exception {
- src.setProviderName("SunJCE"); // Explicitly set the provider name
- dest.setProviderName("SunJCE");
- src.start(Channel.SND_TX_SEQ);
- dest.start(Channel.SND_TX_SEQ);
-
- String testInput = "The quick brown fox jumps over the lazy dog.";
-
- Assert.assertEquals("Failed to set custom provider name",
- testInput,
- roundTrip(testInput, src, dest));
- }
-
- @Test
- public void test192BitKey() throws Exception {
- Assume.assumeTrue("Skipping test192BitKey because the JVM does not
support it",
- 192 <= Cipher.getMaxAllowedKeyLength("AES"));
-
- src.setEncryptionKey(encryptionKey192);
- dest.setEncryptionKey(encryptionKey192);
- src.start(Channel.SND_TX_SEQ);
- dest.start(Channel.SND_TX_SEQ);
-
- String testInput = "The quick brown fox jumps over the lazy dog.";
-
- Assert.assertEquals("Failed to set custom provider name",
- testInput,
- roundTrip(testInput, src, dest));
- }
-
- @Test
- public void test256BitKey() throws Exception {
- Assume.assumeTrue("Skipping test256BitKey because the JVM does not
support it",
- 256 <= Cipher.getMaxAllowedKeyLength("AES"));
-
- src.setEncryptionKey(encryptionKey256);
- dest.setEncryptionKey(encryptionKey256);
- src.start(Channel.SND_TX_SEQ);
- dest.start(Channel.SND_TX_SEQ);
-
- String testInput = "The quick brown fox jumps over the lazy dog.";
-
- Assert.assertEquals("Failed to set custom provider name",
- testInput,
- roundTrip(testInput, src, dest));
- }
-
- @Test
- public void testViaFile() throws Exception {
- src.start(Channel.SND_TX_SEQ);
- src.setNext(new ValueCaptureInterceptor());
-
- String testInput = "The quick brown fox jumps over the lazy dog.";
-
- ChannelData msg = new ChannelData(false);
- msg.setMessage(new XByteBuffer(testInput.getBytes("UTF-8"), false));
- src.sendMessage(null, msg, null);
-
- byte[] bytes = ((ValueCaptureInterceptor)src.getNext()).getValue();
-
- try (FileOutputStream out = new FileOutputStream(MESSAGE_FILE)) {
- out.write(bytes);
- }
-
- dest.start(Channel.SND_TX_SEQ);
-
- bytes = new byte[8192];
- int read;
-
- try (FileInputStream in = new FileInputStream(MESSAGE_FILE)) {
- read = in.read(bytes);
- }
-
- msg = new ChannelData(false);
- XByteBuffer xbb = new XByteBuffer(read, false);
- xbb.append(bytes, 0, read);
- msg.setMessage(xbb);
-
- dest.messageReceived(msg);
- }
-
- @Test
- public void testMessageUniqueness() throws Exception {
- src.start(Channel.SND_TX_SEQ);
- src.setNext(new ValueCaptureInterceptor());
-
- String testInput = "The quick brown fox jumps over the lazy dog.";
-
- ChannelData msg = new ChannelData(false);
- msg.setMessage(new XByteBuffer(testInput.getBytes("UTF-8"), false));
- src.sendMessage(null, msg, null);
-
- byte[] cipherText1 =
((ValueCaptureInterceptor)src.getNext()).getValue();
-
- msg.setMessage(new XByteBuffer(testInput.getBytes("UTF-8"), false));
- src.sendMessage(null, msg, null);
-
- byte[] cipherText2 =
((ValueCaptureInterceptor)src.getNext()).getValue();
-
- MatcherAssert.assertThat("Two identical cleartexts encrypt to the same
ciphertext",
- cipherText1, IsNot.not(IsEqual.equalTo(cipherText2)));
- }
-
- @Test
- public void testRejectReplay() throws Exception {
- src.setNext(new ValueCaptureInterceptor());
- dest.setPrevious(new ValuesCaptureInterceptor());
- src.start(Channel.SND_TX_SEQ);
- dest.start(Channel.SND_TX_SEQ);
-
- byte[] encrypted = encrypt("msg-1", System.currentTimeMillis());
-
- deliver(encrypted);
- deliver(encrypted);
-
- Collection<byte[]> messages = ((ValuesCaptureInterceptor)
dest.getPrevious()).getValues();
- Assert.assertEquals(1, messages.size());
- }
-
- @Test
- public void testReplayWindowRejectsOldMessage() throws Exception {
- src.setNext(new ValueCaptureInterceptor());
- dest.setPrevious(new ValuesCaptureInterceptor());
- dest.setReplayWindowTime(50);
- src.start(Channel.SND_TX_SEQ);
- dest.start(Channel.SND_TX_SEQ);
-
- long now = System.currentTimeMillis();
- byte[] encryptedRecent = encrypt("msg-recent", now);
- byte[] encryptedOld = encrypt("msg-old", now - 1000);
-
- deliver(encryptedRecent);
- deliver(encryptedOld);
-
- Collection<byte[]> messages = ((ValuesCaptureInterceptor)
dest.getPrevious()).getValues();
- Assert.assertEquals(1, messages.size());
- }
-
- @Test
- public void testReplayWindowRejectsOldMessageAfterCountEviction() throws
Exception {
- src.setNext(new ValueCaptureInterceptor());
- dest.setPrevious(new ValuesCaptureInterceptor());
- dest.setReplayWindowMessageCount(2);
- src.start(Channel.SND_TX_SEQ);
- dest.start(Channel.SND_TX_SEQ);
-
- long now = System.currentTimeMillis();
- byte[] encrypted1000 = encrypt("msg-1000", now);
- byte[] encrypted1001 = encrypt("msg-1001", now + 1);
- byte[] encrypted1002 = encrypt("msg-1002", now + 2);
- byte[] encrypted1003 = encrypt("msg-1003", now + 3);
-
- deliver(encrypted1000);
- deliver(encrypted1001);
- deliver(encrypted1002);
- deliver(encrypted1003);
- deliver(encrypted1000);
-
- Collection<byte[]> messages = ((ValuesCaptureInterceptor)
dest.getPrevious()).getValues();
- Assert.assertEquals(4, messages.size());
- }
-
- @Test
- public void testReplayWindowEvictsOldestTimestampFirst() throws Exception {
- src.setNext(new ValueCaptureInterceptor());
- dest.setPrevious(new ValuesCaptureInterceptor());
- dest.setReplayWindowMessageCount(2);
- src.start(Channel.SND_TX_SEQ);
- dest.start(Channel.SND_TX_SEQ);
-
- long now = System.currentTimeMillis();
- byte[] encrypted300 = encrypt("msg-300", now + 300);
- byte[] encrypted100 = encrypt("msg-100", now + 100);
- byte[] encrypted200 = encrypt("msg-200", now + 200);
- byte[] encrypted225 = encrypt("msg-225", now + 225);
- byte[] encrypted250 = encrypt("msg-250", now + 250);
-
- deliver(encrypted300);
- deliver(encrypted100);
- deliver(encrypted200);
- deliver(encrypted225);
- deliver(encrypted250);
-
- Collection<byte[]> messages = ((ValuesCaptureInterceptor)
dest.getPrevious()).getValues();
- Assert.assertEquals(5, messages.size());
- }
-
- @Test
- public void testPickup() throws Exception {
- File file = new File(MESSAGE_FILE);
- if(!file.exists()) {
- System.err.println("File message.bin does not exist. Skipping
test.");
- return;
- }
-
- dest.start(Channel.SND_TX_SEQ);
-
- byte[] bytes = new byte[8192];
- int read;
-
- try (FileInputStream in = new FileInputStream(file)) {
- read = in.read(bytes);
- }
-
- ChannelData msg = new ChannelData(false);
- XByteBuffer xbb = new XByteBuffer(read, false);
- xbb.append(bytes, 0, read);
- msg.setMessage(xbb);
-
- dest.messageReceived(msg);
- }
-
- /*
- * This test isn't guaranteed to catch any multithreaded issues, but it
- * gives a good exercise.
- */
- @Test
- public void testMultithreaded() throws Exception {
- String inputValue = "A test string to fight over.";
- final byte[] bytes = inputValue.getBytes("UTF-8");
- int numThreads = 100;
- final int messagesPerThread = 10;
-
- dest.setPrevious(new ValuesCaptureInterceptor());
-
- src.start(Channel.SND_TX_SEQ);
- dest.start(Channel.SND_TX_SEQ);
-
- Runnable job = new Runnable() {
- @Override
- public void run() {
- try {
- ChannelData msg = new ChannelData(false);
- XByteBuffer xbb = new XByteBuffer(1024, false);
- xbb.append(bytes, 0, bytes.length);
- msg.setMessage(xbb);
-
- for(int i=0; i<messagesPerThread; ++i) {
- src.sendMessage(null, msg, null);
- }
- } catch (ChannelException e) {
- Assert.fail("Encountered exception sending messages: " +
e.getMessage());
- }
- }
- };
-
- Thread[] threads = new Thread[numThreads];
- for(int i=0; i<numThreads; ++i) {
- threads[i] = new Thread(job);
- threads[i].setName("Message-Thread-" + i);
- }
-
- for(int i=0; i<numThreads; ++i) {
- threads[i].start();
- }
-
- for(int i=0; i<numThreads; ++i) {
- threads[i].join();
- }
-
- // Check all received messages to make sure they are not corrupted
- Collection<byte[]> messages =
((ValuesCaptureInterceptor)dest.getPrevious()).getValues();
-
- Assert.assertEquals("Did not receive all expected messages",
- numThreads * messagesPerThread, messages.size());
-
- for(byte[] message : messages) {
- Assert.assertArrayEquals("Message is corrupted", message, bytes);
- }
- }
-
- @Test
- public void testTcpFailureDetectorDetection() throws Exception {
- src.setPrevious(new TcpFailureDetector());
-
- try {
- src.start(Channel.SND_TX_SEQ);
- Assert.fail("EncryptInterceptor should detect TcpFailureDetector
and throw an error");
- } catch (EncryptInterceptor.ChannelConfigException cce) {
- // Expected behavior
- } catch (AssertionError ae) {
- // This is the junit assertion being thrown
- throw ae;
- } catch (Throwable t) {
- Assert.fail("EncryptionInterceptor should throw
ChannelConfigException, not " + t.getClass().getName());
- }
-
- // The failed start left the encryption manager uncreated, stop() must
cope
- src.stop(Channel.SND_TX_SEQ);
- }
-
- @Test
- public void testStopAfterFailedStart() throws Exception {
- EncryptInterceptor interceptor = new EncryptInterceptor();
-
- // No key is set, so start() fails before the encryption manager is
created
- try {
- interceptor.start(Channel.SND_TX_SEQ);
- Assert.fail("start() without a key should fail");
- } catch (IllegalStateException ise) {
- // Expected
- }
-
- // stop() must tolerate the missing encryption manager rather than
fail with an NPE
- interceptor.stop(Channel.SND_TX_SEQ);
- }
-
- private byte[] encrypt(String message, long timestamp) throws Exception {
- ChannelData msg = new ChannelData(false);
- msg.setTimestamp(timestamp);
- msg.setMessage(new XByteBuffer(message.getBytes("UTF-8"), false));
- src.sendMessage(null, msg, null);
- return ((ValueCaptureInterceptor) src.getNext()).getValue();
- }
-
- private void deliver(byte[] encrypted) {
- ChannelData incoming = new ChannelData(false);
- XByteBuffer xbb = new XByteBuffer(encrypted.length, false);
- xbb.append(encrypted, 0, encrypted.length);
- incoming.setMessage(xbb);
- dest.messageReceived(incoming);
- }
-}
diff --git
a/test/org/apache/catalina/tribes/group/interceptors/TestEncryptInterceptorAlgorithms.java
b/test/org/apache/catalina/tribes/group/interceptors/TestEncryptInterceptorAlgorithms.java
deleted file mode 100644
index cde0d0f55c..0000000000
---
a/test/org/apache/catalina/tribes/group/interceptors/TestEncryptInterceptorAlgorithms.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * 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.catalina.tribes.group.interceptors;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-import org.junit.Assert;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameter;
-import org.junit.runners.Parameterized.Parameters;
-
-import org.apache.catalina.tribes.Channel;
-
-@Deprecated
-@RunWith(Parameterized.class)
-public class TestEncryptInterceptorAlgorithms extends
EncryptInterceptorBaseTest {
-
- @Parameters(name = "{index} {0}/{1}/{2}")
- public static Collection<Object[]> inputs() {
-
- List<Object[]> result = new ArrayList<>();
- // Covers all cipher algorithm modes currently listed in Java Standard
Names
-
- // Not supported - Insecure
- result.add(new Object[] { "AES", "NONE", "NoPadding", Boolean.FALSE});
- // Not supported - Insecure - Padding makes no sense if there is no
encryption
- result.add(new Object[] { "AES", "NONE", "PKCS5Padding",
Boolean.FALSE});
-
- // Not supported - NoPadding requires fixed block size and cluster
messages are variable length
- result.add(new Object[] { "AES", "CBC", "NoPadding", Boolean.FALSE});
- // Supported but not recommended - possible security issues in some
configurations - backwards compatibility
- result.add(new Object[] { "AES", "CBC", "PKCS5Padding", Boolean.TRUE});
-
- // Not supported - JCA provider doesn't included it
- result.add(new Object[] { "AES", "CCM", "NoPadding", Boolean.FALSE});
- // Not supported - JCA provider doesn't included it - CCM doesn't need
(support?) padding
- result.add(new Object[] { "AES", "CCM", "PKCS5Padding",
Boolean.FALSE});
-
- // Not supported - NoPadding requires fixed block size and cluster
messages are variable length
- result.add(new Object[] { "AES", "CFB", "NoPadding", Boolean.FALSE});
- // Supported but not recommended - possible security issues in some
configurations - backwards compatibility
- result.add(new Object[] { "AES", "CFB", "PKCS5Padding", Boolean.TRUE});
-
- // Not supported - Insecure and/or slow
- result.add(new Object[] { "AES", "CFB8", "NoPadding", Boolean.FALSE});
- result.add(new Object[] { "AES", "CFB8", "PKCS5Padding",
Boolean.FALSE});
- result.add(new Object[] { "AES", "CFB16", "NoPadding", Boolean.FALSE});
- result.add(new Object[] { "AES", "CFB16", "PKCS5Padding",
Boolean.FALSE});
- // large block sizes not tested but will be rejected as well
-
- // Not supported - Insecure
- result.add(new Object[] { "AES", "CTR", "NoPadding", Boolean.FALSE});
- // Not supported - Configuration not recommended
- result.add(new Object[] { "AES", "CTR", "PKCS5Padding",
Boolean.FALSE});
-
- // Not supported - has minimum length
- result.add(new Object[] { "AES", "CTS", "NoPadding", Boolean.FALSE});
- result.add(new Object[] { "AES", "CTS", "PKCS5Padding",
Boolean.FALSE});
-
- // Not supported - Insecure
- result.add(new Object[] { "AES", "ECB", "NoPadding", Boolean.FALSE});
- result.add(new Object[] { "AES", "ECB", "PKCS5Padding",
Boolean.FALSE});
-
- // Default for Tomcat 12 onwards
- result.add(new Object[] { "AES", "GCM", "NoPadding", Boolean.TRUE});
- // Not supported - GCM doesn't need (support?) padding
- result.add(new Object[] { "AES", "GCM", "PKCS5Padding",
Boolean.FALSE});
-
- // Not supported - KW not appropriate for encrypting cluster messages
- result.add(new Object[] { "AES", "KW", "NoPadding", Boolean.FALSE});
- result.add(new Object[] { "AES", "KW", "PKCS5Padding", Boolean.FALSE});
-
- // Not supported - KWP not appropriate for encrypting cluster messages
- result.add(new Object[] { "AES", "KWP", "NoPadding", Boolean.FALSE});
- result.add(new Object[] { "AES", "KWP", "PKCS5Padding",
Boolean.FALSE});
-
- // Not supported - NoPadding requires fixed block size and cluster
messages are variable length
- result.add(new Object[] { "AES", "OFB", "NoPadding", Boolean.FALSE});
-
- // Supported but not recommended - possible security issues in some
configurations - backwards compatibility
- result.add(new Object[] { "AES", "OFB", "PKCS5Padding", Boolean.TRUE});
-
- // Not supported - Insecure and/or slow
- result.add(new Object[] { "AES", "OFB8", "NoPadding", Boolean.FALSE});
- result.add(new Object[] { "AES", "OFB8", "PKCS5Padding",
Boolean.FALSE});
- result.add(new Object[] { "AES", "OFB16", "NoPadding", Boolean.FALSE});
- result.add(new Object[] { "AES", "OFB16", "PKCS5Padding",
Boolean.FALSE});
- // large block sizes not tested but will be rejected as well
-
- // Not supported - Insecure
- result.add(new Object[] { "AES", "PCBC", "NoPadding", Boolean.FALSE});
- result.add(new Object[] { "AES", "PCBC", "PKCS5Padding",
Boolean.FALSE});
-
- return result;
- }
-
- @Parameter(0)
- public String algorithm;
-
- @Parameter(1)
- public String mode;
-
- @Parameter(2)
- public String padding;
-
- @Parameter(3)
- public boolean shouldSucceed;
-
- @Test
- public void testAlgorithm() throws Exception {
- if (shouldSucceed) {
- doTestShouldSucceed();
- } else {
- doTestShouldNotSucceed();
- }
- }
-
- private void doTestShouldSucceed() throws Exception {
- String transformation = String.format("%s/%s/%s", algorithm, mode,
padding);
-
- src.setEncryptionAlgorithm(transformation);
- src.start(Channel.SND_TX_SEQ);
- dest.setEncryptionAlgorithm(transformation);
- dest.start(Channel.SND_TX_SEQ);
-
- String testInput = "The quick brown fox jumps over the lazy dog.";
-
- Assert.assertEquals("Failed in " + transformation + " mode",
- testInput,
- roundTrip(testInput, src, dest));
- }
-
- private void doTestShouldNotSucceed() throws Exception {
- try {
- String transformation = String.format("%s/%s/%s", algorithm, mode,
padding);
- src.setEncryptionAlgorithm(transformation);
- src.start(Channel.SND_TX_SEQ);
-
- // start() should trigger IllegalArgumentException
- Assert.fail(transformation + " mode is not being refused");
- } catch (IllegalArgumentException iae) {
- // Expected
- }
- }
-}
diff --git
a/test/org/apache/catalina/tribes/group/interceptors/TestEncryptInterceptorLargeHeap.java
b/test/org/apache/catalina/tribes/group/interceptors/TestEncryptInterceptorLargeHeap.java
deleted file mode 100644
index 4c6da8c2c5..0000000000
---
a/test/org/apache/catalina/tribes/group/interceptors/TestEncryptInterceptorLargeHeap.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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.catalina.tribes.group.interceptors;
-
-import org.junit.Assert;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-
-import org.apache.catalina.tribes.Channel;
-
-/**
- * Tests the EncryptInterceptor using very large inputs.
- *
- * Many of the tests in this class use strings as input and output, even
- * though the interceptor actually operates on byte arrays. This is done
- * for readability for the tests and their outputs.
- */
-@Deprecated
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-public class TestEncryptInterceptorLargeHeap extends
EncryptInterceptorBaseTest {
-
- @Test
- public void testHugePayload() throws Exception {
- src.start(Channel.SND_TX_SEQ);
- dest.start(Channel.SND_TX_SEQ);
-
- byte[] bytes = new byte[1024*1024*1024];
-
- Assert.assertArrayEquals("Huge payload roundtrip failed",
- bytes,
- roundTrip(bytes, src, dest));
- }
-}
diff --git
a/test/org/apache/catalina/tribes/group/interceptors/TestMessageDispatchInterceptor.java
b/test/org/apache/catalina/tribes/group/interceptors/TestMessageDispatchInterceptor.java
index 206d90026d..db5cb15473 100644
---
a/test/org/apache/catalina/tribes/group/interceptors/TestMessageDispatchInterceptor.java
+++
b/test/org/apache/catalina/tribes/group/interceptors/TestMessageDispatchInterceptor.java
@@ -321,8 +321,8 @@ public class TestMessageDispatchInterceptor {
}
/*
- * Simulates interceptors such as EncryptInterceptor or
FragmentationInterceptor that replace or extend the message
- * payload while the message is being sent downstream.
+ * Simulates interceptors such as FragmentationInterceptor that replace or
extend the message payload while the
+ * message is being sent downstream.
*/
private static class MutatingCollector extends ChannelInterceptorBase {
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 3d74d6da74..bf8ee6ea00 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -907,7 +907,6 @@
recorded when a message is queued is now also the length used
to release the accounting when the send completes. Previously,
when a downstream interceptor like
- <code>EncryptInterceptor</code> or
<code>FragmentationInterceptor</code> replaced or extended the
message payload while the message was sent, the recorded queue
size drifted towards negative values and the
diff --git a/webapps/docs/cluster-howto.xml b/webapps/docs/cluster-howto.xml
index 1125be5734..09df59a6a7 100644
--- a/webapps/docs/cluster-howto.xml
+++ b/webapps/docs/cluster-howto.xml
@@ -136,10 +136,6 @@
amount of logging until those nodes stop attempting to join the
cluster.</li>
</ul>
- <p>
- The <code>EncryptInterceptor</code> is deprecated and should no longer be
used to secure cluster traffic.
- </p>
-
<p>
Other options for providing a secure, trusted network for use by a Tomcat
cluster include:
</p>
diff --git a/webapps/docs/config/cluster.xml b/webapps/docs/config/cluster.xml
index 3e753cb582..011aa80831 100644
--- a/webapps/docs/config/cluster.xml
+++ b/webapps/docs/config/cluster.xml
@@ -66,10 +66,6 @@
amount of logging until those nodes stop attempting to join the
cluster.</li>
</ul>
- <p>
- The <code>EncryptInterceptor</code> is deprecated and should no longer be
used to secure cluster traffic.
- </p>
-
<p>
Other options for providing a secure, trusted network for use by a Tomcat
cluster include:
</p>
diff --git a/webapps/docs/security-howto.xml b/webapps/docs/security-howto.xml
index 4b4d0bbe29..03a032bbc1 100644
--- a/webapps/docs/security-howto.xml
+++ b/webapps/docs/security-howto.xml
@@ -517,9 +517,8 @@
<subsection name="Cluster">
<p>Tomcat clustering is typically used over a secure, trusted network.
If a trusted network is not available then
- a cluster may be configured to use TLS. The
<code>EncryptInterceptor</code> is deprecated and should no longer be
- used to secure cluster traffic. Other options for providing a secure,
trusted network for use by a Tomcat cluster
- include:</p>
+ a cluster may be configured to use TLS. Other options for providing a
secure, trusted network for use by a Tomcat
+ cluster include:</p>
<ul>
<li>private LAN</li>
<li>a Virtual Private Network (VPN)</li>
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]