Author: schultz Date: Sun Nov 25 14:18:23 2018 New Revision: 1847412 URL: http://svn.apache.org/viewvc?rev=1847412&view=rev Log: Prevent reconfiguration of crypto provider after the interceptor has been started. Slightly reduce the time Cipher objects are checked-out of the Cipher pool. Clarify that IVs have their own size and arent' necessarily always the same as the block size.
Modified: tomcat/trunk/java/org/apache/catalina/tribes/group/interceptors/EncryptInterceptor.java Modified: tomcat/trunk/java/org/apache/catalina/tribes/group/interceptors/EncryptInterceptor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/tribes/group/interceptors/EncryptInterceptor.java?rev=1847412&r1=1847411&r2=1847412&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/tribes/group/interceptors/EncryptInterceptor.java (original) +++ tomcat/trunk/java/org/apache/catalina/tribes/group/interceptors/EncryptInterceptor.java Sun Nov 25 14:18:23 2018 @@ -17,10 +17,13 @@ package org.apache.catalina.tribes.group.interceptors; import java.security.GeneralSecurityException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; import java.security.SecureRandom; import java.util.concurrent.ConcurrentLinkedQueue; import javax.crypto.Cipher; +import javax.crypto.NoSuchPaddingException; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; @@ -63,6 +66,16 @@ public class EncryptInterceptor extends * This is the name of the core encryption algorithm e.g. AES. */ private String algorithmName; + /** + * The size of the initialization vector to use for encryption. This is + * often, but not always, the same as the block size. + */ + private int ivSize; + /** + * This is the name of the provider which will not change after + * a call to {@link #start}. + */ + private String providerNameInternal; private SecretKeySpec secretKey; private ConcurrentLinkedQueue<Cipher> cipherPool; private ConcurrentLinkedQueue<SecureRandom> randomPool; @@ -73,7 +86,11 @@ public class EncryptInterceptor extends @Override public void start(int svc) throws ChannelException { if(Channel.SND_TX_SEQ == (svc & Channel.SND_TX_SEQ)) { - initInternal(); + try { + initInternal(); + } catch (GeneralSecurityException gse) { + throw new ChannelException(sm.getString("encryptInterceptor.init.failed"), gse); + } } super.start(svc); @@ -269,7 +286,24 @@ public class EncryptInterceptor extends return algorithmName; } - private void initInternal() { + private void setIVSize(int size) { + ivSize = size; + } + + private int getIVSize() { + return ivSize; + } + + private void setProviderNameInternal(String providerName) { + providerNameInternal = providerName; + } + + private String getProviderNameInternal() { + return providerNameInternal; + } + + private void initInternal() + throws NoSuchAlgorithmException, NoSuchPaddingException, NoSuchProviderException { if(null == getEncryptionKey()) throw new IllegalStateException(sm.getString("encryptInterceptor.key.required")); @@ -303,23 +337,32 @@ public class EncryptInterceptor extends throw new IllegalArgumentException(sm.getString("encryptInterceptor.algorithm.unsupported-mode", algorithmMode)); setAlgorithmName(algorithm); + setProviderNameInternal(getProviderName()); setSecretKey(new SecretKeySpec(getEncryptionKeyInternal(), algorithmName)); cipherPool = new ConcurrentLinkedQueue<>(); + Cipher cipher = createCipher(); + setIVSize(cipher.getBlockSize()); + cipherPool.offer(cipher); randomPool = new ConcurrentLinkedQueue<>(); } + private Cipher createCipher() + throws NoSuchAlgorithmException, NoSuchPaddingException, NoSuchProviderException { + String providerName = getProviderNameInternal(); + + if(null == providerName) { + return Cipher.getInstance(getAlgorithmName()); + } else { + return Cipher.getInstance(getAlgorithmName(), providerName); + } + } + private Cipher getCipher() throws GeneralSecurityException { Cipher cipher = cipherPool.poll(); if(null == cipher) { - String providerName = getProviderName(); - - if(null == providerName) { - return Cipher.getInstance(getAlgorithmName()); - } else { - return Cipher.getInstance(getAlgorithmName(), providerName); - } + cipher = createCipher(); } return cipher; @@ -361,13 +404,11 @@ public class EncryptInterceptor extends private byte[][] encrypt(byte[] bytes) throws GeneralSecurityException { Cipher cipher = null; SecureRandom random = null; + byte[] iv = new byte[getIVSize()]; try { - cipher = getCipher(); random = getRandom(); - byte[] iv = new byte[cipher.getBlockSize()]; - // 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. @@ -375,6 +416,7 @@ public class EncryptInterceptor extends IvParameterSpec IV = new IvParameterSpec(iv); + cipher = getCipher(); cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(), IV); // Prepend the IV to the beginning of the encrypted data @@ -403,17 +445,17 @@ public class EncryptInterceptor extends private byte[] decrypt(byte[] bytes) throws GeneralSecurityException { Cipher cipher = null; + int ivSize = getIVSize(); + // Use first part of incoming data as IV + IvParameterSpec IV = new IvParameterSpec(bytes, 0, ivSize); + try { cipher = getCipher(); - int blockSize = cipher.getBlockSize(); - - // Use first-block of incoming data as IV - IvParameterSpec IV = new IvParameterSpec(bytes, 0, blockSize); cipher.init(Cipher.DECRYPT_MODE, getSecretKey(), IV); // Decrypt remainder of the message. - return cipher.doFinal(bytes, blockSize, bytes.length - blockSize); + return cipher.doFinal(bytes, ivSize, bytes.length - ivSize); } finally { if(null != cipher) returnCipher(cipher); --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org