You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by sc...@apache.org on 2018/11/25 14:18:23 UTC

svn commit: r1847412 - /tomcat/trunk/java/org/apache/catalina/tribes/group/interceptors/EncryptInterceptor.java

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-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org