-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 All,
Can I get a technical review for (a) appropriateness and (b) technical implementation of the attached cluster interceptor? Let's assume for a moment that encryption is something worth adding to clustering and not argue that point. It should be straightforward. Knowing virtually nothing about the way that Tribes works, implementing this as an interceptor seemed like the least invasive (and easiest!) way to add encryption to clustering. The only question I have about what I've actually written is what to do about the cipher IV? Both sides of the conversation need to know the IV in order to communicate. Should I just add another member to the class for the IV and require that users specify both the key AND the IV? Thanks, - -chris -----BEGIN PGP SIGNATURE----- Comment: Using GnuPG with Thunderbird - https://www.enigmail.net/ iQIzBAEBCAAdFiEEMmKgYcQvxMe7tcJcHPApP6U8pFgFAlvPKqsACgkQHPApP6U8 pFgGSxAAy1vj8FY7uzcvstimHwUGKd6dJkFiKRxygY30Lp3bHor5O4GKoWP4eWwJ l0rl0ojvhgLzHwPB/+Cdm1gpZD2cSSiqyz3V6eGlt8oq8mm3M4lCMqZqXckNHYG5 cSRHXPIO0XaoCrUR2KA4NRS207OXTUYZe7ihPb0Bblev5SE/S/vIArRs+1Gybdi+ zYXY4XwBUHRHu2PzWy6c0HFPP3hDJ85I3Mn4O/uqZgh01eRRpsfvbmros45znTfc frKqBeT3O/+dwNOX9HhshnIW92U8dyYto70CsKdtPrsVXpY9kQH3zOc3vC+UN2qf jJZYie32mHjg22JDrYOqFpfAhTQi9r4xUMzprMVjTk93p34SxvmZNbLBVi/Li6OA PdthMBpHiAQp+bLVGSU4UbHdEG9t/Ixp8RodWJzxGWtduy3/GGCsifQke5H6yBf5 Kb3Rux4u/3mKwn0PZL8HljUgEZCge3g1+KOX1qL9Uw5TCKm4YIF744C1P7piSllR GW3UxamATH4qmZ/ccAUJVBgdQQYPjVKAc0tAvCVBZSxf6+OB8D5HfA/A8f8N7Fzj wBVPbcW5d4OjFpjEshOtehb74q1WAGhg1+rUkPbd1Nkd/WTQN8YXXayN0+TE28gm LPSv8RSsAEWFLzh/TiY8BNzdehEaHID6R6h5q7io9JNMbtljhgQ= =nSgU -----END PGP SIGNATURE-----
/* * 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.security.GeneralSecurityException; import java.security.Key; import javax.crypto.Cipher; 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.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.util.StringManager; import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; import org.apache.tomcat.util.buf.HexUtils; /** * Adds encryption using a pre-shared key. */ public class EncryptInterceptor extends ChannelInterceptorBase { private static final Log log = LogFactory.getLog(EncryptInterceptor.class); protected static final StringManager sm = StringManager.getManager(EncryptInterceptor.class); private static final String DEFAULT_ENCRYPTION_ALGORITHM = "AES/CBC/PKCS5Padding"; private String providerName; private String encryptionAlgorithm = DEFAULT_ENCRYPTION_ALGORITHM; private Key encryptionKey; private Cipher encryptionCipher; private Cipher decryptionCipher; public EncryptInterceptor() { } @Override public void start(int svc) throws ChannelException { super.start(svc); if(Channel.SND_TX_SEQ == svc) { try { initCiphers(); } catch (GeneralSecurityException gse) { log.fatal(sm.getString("encryptInterceptor.init.failed")); throw new ChannelException(sm.getString("encryptInterceptor.init.failed"), gse); } } } @Override public void sendMessage(Member[] destination, ChannelMessage msg, InterceptorPayload payload) throws ChannelException { try { byte[] data = msg.getMessage().getBytes(); data = encrypt(data); msg.getMessage().trim(msg.getMessage().getLength()); msg.getMessage().append(data,0,data.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(); data = decrypt(data); msg.getMessage().trim(msg.getMessage().getLength()); msg.getMessage().append(data,0,data.length); super.messageReceived(msg); } catch (GeneralSecurityException gse) { log.error(sm.getString("encryptInterceptor.decrypt.failed"), gse); } } public void setEncryptionAlgorithm(String algorithm) { encryptionAlgorithm = algorithm; } public String getEncryptionAlgorithm() { return encryptionAlgorithm; } public void setEncryptionKey(byte[] key) { encryptionKey = new SecretKeySpec(key, getEncryptionAlgorithm()); } public void setEncryptionKey(String keyBytes) { setEncryptionKey(HexUtils.fromHexString(keyBytes)); } private Key getEncryptionKey() { return encryptionKey; } public void setProviderName(String provider) { providerName = provider; } public String getProviderName() { return providerName; } private void initCiphers() throws GeneralSecurityException { if(null == getEncryptionAlgorithm()) throw new IllegalStateException(sm.getString("encryptInterceptor.algorithm.required")); if(null == getEncryptionKey()) throw new IllegalStateException(sm.getString("encryptInterceptor.key.required")); Cipher cipher = Cipher.getInstance(getEncryptionAlgorithm(), getProviderName()); IvParameterSpec IV = null; // TODO: determine how to solve the IV problem cipher.init(Cipher.ENCRYPT_MODE, getEncryptionKey(), IV); encryptionCipher = cipher; cipher = Cipher.getInstance(getEncryptionAlgorithm(), getProviderName()); cipher.init(Cipher.DECRYPT_MODE, getEncryptionKey(), IV); decryptionCipher = cipher; } private Cipher getEncryptionCipher() { return encryptionCipher; } private byte[] encrypt(byte[] bytes) throws GeneralSecurityException { return getEncryptionCipher().doFinal(bytes); } private Cipher getDecryptionCipher() throws GeneralSecurityException { return decryptionCipher; } private byte[] decrypt(byte[] bytes) throws GeneralSecurityException { return getDecryptionCipher().doFinal(bytes); } }
--------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org