Author: schultz Date: Sun Nov 25 15:49:28 2018 New Revision: 1847417 URL: http://svn.apache.org/viewvc?rev=1847417&view=rev Log: Add support for GCM block cipher mode.
Modified: tomcat/trunk/java/org/apache/catalina/tribes/group/interceptors/EncryptInterceptor.java tomcat/trunk/test/org/apache/catalina/tribes/group/interceptors/TestEncryptInterceptor.java tomcat/trunk/webapps/docs/changelog.xml 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=1847417&r1=1847416&r2=1847417&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 15:49:28 2018 @@ -25,6 +25,7 @@ import java.util.concurrent.ConcurrentLi import javax.crypto.Cipher; import javax.crypto.NoSuchPaddingException; +import javax.crypto.spec.GCMParameterSpec; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; @@ -64,7 +65,7 @@ public class EncryptInterceptor extends private String encryptionKeyString; - private EncryptionManager encryptionManager; + private BaseEncryptionManager encryptionManager; public EncryptInterceptor() { } @@ -300,7 +301,7 @@ public class EncryptInterceptor extends return result; } - private static EncryptionManager createEncryptionManager(String algorithm, + private static BaseEncryptionManager createEncryptionManager(String algorithm, byte[] encryptionKey, String providerName) throws NoSuchAlgorithmException, NoSuchPaddingException, NoSuchProviderException { if(null == encryptionKey) @@ -328,29 +329,31 @@ public class EncryptInterceptor extends } // Note: ECB is not an appropriate mode for secure communications. + if("GCM".equalsIgnoreCase(algorithmMode)) + return new GCMEncryptionManager(algorithm, new SecretKeySpec(encryptionKey, algorithmName), providerName); + if(!("CBC".equalsIgnoreCase(algorithmMode) || "OFB".equalsIgnoreCase(algorithmMode) || "CFB".equalsIgnoreCase(algorithmMode))) throw new IllegalArgumentException(sm.getString("encryptInterceptor.algorithm.unsupported-mode", algorithmMode)); - EncryptionManager mgr = new EncryptionManager(algorithm, + BaseEncryptionManager mgr = new BaseEncryptionManager(algorithm, new SecretKeySpec(encryptionKey, algorithmName), providerName); return mgr; } - private static class EncryptionManager { + private static class BaseEncryptionManager { /** * The fully-specified algorithm e.g. AES/CBC/PKCS5Padding. */ private final String algorithm; /** - * The size of the initialization vector to use for encryption. This is - * often, but not always, the same as the block size. + * The block size of the cipher. */ - private final int ivSize; + private final int blockSize; /** * The cryptographic provider name. @@ -375,7 +378,7 @@ public class EncryptInterceptor extends */ private final ConcurrentLinkedQueue<SecureRandom> randomPool; - public EncryptionManager(String algorithm, SecretKeySpec secretKey, String providerName) + public BaseEncryptionManager(String algorithm, SecretKeySpec secretKey, String providerName) throws NoSuchAlgorithmException, NoSuchPaddingException, NoSuchProviderException { this.algorithm = algorithm; this.providerName = providerName; @@ -383,7 +386,7 @@ public class EncryptInterceptor extends cipherPool = new ConcurrentLinkedQueue<>(); Cipher cipher = createCipher(); - ivSize = cipher.getBlockSize(); + blockSize = cipher.getBlockSize(); cipherPool.offer(cipher); randomPool = new ConcurrentLinkedQueue<>(); } @@ -402,8 +405,14 @@ public class EncryptInterceptor extends return secretKey; } - private int getIVSize() { - return ivSize; + /** + * Gets the size 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() { @@ -474,7 +483,7 @@ public class EncryptInterceptor extends try { cipher = getCipher(); - cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(), generateIV(iv, 0, ivSize)); + 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][]; @@ -500,6 +509,7 @@ public class EncryptInterceptor extends private byte[] decrypt(byte[] bytes) throws GeneralSecurityException { Cipher cipher = null; + int ivSize = getIVSize(); AlgorithmParameterSpec IV = generateIV(bytes, 0, ivSize); try { @@ -539,4 +549,22 @@ public class EncryptInterceptor extends return new IvParameterSpec(ivBytes, offset, length); } } + + private static class GCMEncryptionManager extends BaseEncryptionManager + { + public GCMEncryptionManager(String algorithm, SecretKeySpec secretKey, String providerName) + throws NoSuchAlgorithmException, NoSuchPaddingException, NoSuchProviderException { + super(algorithm, secretKey, providerName); + } + + @Override + protected int getIVSize() { + return 12; + } + + @Override + protected AlgorithmParameterSpec generateIV(byte[] bytes, int offset, int length) { + return new GCMParameterSpec(128, bytes, offset, length); + } + } } Modified: tomcat/trunk/test/org/apache/catalina/tribes/group/interceptors/TestEncryptInterceptor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/catalina/tribes/group/interceptors/TestEncryptInterceptor.java?rev=1847417&r1=1847416&r2=1847417&view=diff ============================================================================== --- tomcat/trunk/test/org/apache/catalina/tribes/group/interceptors/TestEncryptInterceptor.java (original) +++ tomcat/trunk/test/org/apache/catalina/tribes/group/interceptors/TestEncryptInterceptor.java Sun Nov 25 15:49:28 2018 @@ -255,7 +255,6 @@ public class TestEncryptInterceptor { } @Test - @Ignore("GCM mode is unsupported because it requires a custom initialization vector") public void testGCM() throws Exception { src.setEncryptionAlgorithm("AES/GCM/PKCS5Padding"); src.start(Channel.SND_TX_SEQ); Modified: tomcat/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1847417&r1=1847416&r2=1847417&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/changelog.xml (original) +++ tomcat/trunk/webapps/docs/changelog.xml Sun Nov 25 15:49:28 2018 @@ -163,6 +163,9 @@ Make EncryptInterceptor thread-safe. This makes this interceptor actually usable. (schultz/markt) </fix> + <add> + Add support for GCM mode to EncryptInterceptor. (schultz) + </add> </changelog> </subsection> <subsection name="Other"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org