Skip to content

Commit

Permalink
TEIID-4663 defaulting to cbc with an explicit init vector
Browse files Browse the repository at this point in the history
  • Loading branch information
shawkins committed Dec 24, 2016
1 parent 24cbae6 commit 4cb43be
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 21 deletions.
18 changes: 18 additions & 0 deletions client/src/main/java/org/teiid/net/socket/Handshake.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.OptionalDataException;
import java.util.List;

import org.teiid.core.util.ApplicationInfo;
Expand All @@ -44,6 +45,7 @@ public class Handshake implements Externalizable {
private byte[] publicKey;
private byte[] publicKeyLarge;
private AuthenticationType authType = AuthenticationType.USERPASSWORD;
private boolean cbc = true;

public Handshake() {

Expand Down Expand Up @@ -113,6 +115,14 @@ public void setPublicKeyLarge(byte[] publicKeyLarge) {
this.publicKeyLarge = publicKeyLarge;
}

public boolean isCbc() {
return cbc;
}

public void setCbc(boolean cbc) {
this.cbc = cbc;
}

@Override
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
Expand All @@ -128,6 +138,13 @@ public void readExternal(ObjectInput in) throws IOException,
} catch (EOFException e) {
publicKeyLarge = null;
}
try {
cbc = in.readBoolean();
} catch (OptionalDataException e) {
cbc = false;
} catch (EOFException e) {
cbc = false;
}
}

@Override
Expand All @@ -141,6 +158,7 @@ public void writeExternal(ObjectOutput out) throws IOException {
out.writeInt(publicKeyLarge.length);
out.write(publicKeyLarge);
}
out.writeBoolean(cbc);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,8 @@ private void doHandshake() throws IOException, CommunicationException {
handshake.setPublicKey(publicKey);
handshake.setPublicKeyLarge(null);
}
this.cryptor = keyGen.getSymmetricCryptor(serverPublicKey, "08.03".compareTo(serverVersion) > 0, this.getClass().getClassLoader(), large); //$NON-NLS-1$
boolean useCbc = handshake.isCbc();
this.cryptor = keyGen.getSymmetricCryptor(serverPublicKey, "08.03".compareTo(serverVersion) > 0, this.getClass().getClassLoader(), large, useCbc); //$NON-NLS-1$
} else {
this.cryptor = new NullCryptor();
}
Expand Down
42 changes: 37 additions & 5 deletions common-core/src/main/java/org/teiid/core/crypto/BasicCryptor.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,17 @@
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Arrays;

import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SealedObject;
import javax.crypto.spec.IvParameterSpec;

import org.teiid.core.CorePlugin;
import org.teiid.core.util.AccessibleByteArrayOutputStream;
Expand All @@ -57,13 +61,21 @@ public class BasicCryptor implements Cryptor {
public static final String OLD_ENCRYPT_PREFIX = "{mm-encrypt}"; //$NON-NLS-1$
public static final String ENCRYPT_PREFIX = "{teiid-encrypt}"; //$NON-NLS-1$

private static final SecureRandom random = new SecureRandom();

private ClassLoader classLoader = BasicCryptor.class.getClassLoader();
private boolean useSealedObject = true;
private IvParameterSpec iv;
private byte[] randBuffer;

public BasicCryptor( Key encryptKey, Key decryptKey, String algorithm) throws CryptoException {
public BasicCryptor( Key encryptKey, Key decryptKey, String algorithm, IvParameterSpec iv) throws CryptoException {
this.encryptKey = encryptKey;
this.cipherAlgorithm = algorithm;
this.decryptKey = decryptKey;
this.iv = iv;
if (iv != null) {
randBuffer = new byte[iv.getIV().length];
}

initEncryptCipher();
initDecryptCipher();
Expand All @@ -84,7 +96,12 @@ public synchronized void setClassLoader(ClassLoader classLoader) {
*/
public synchronized byte[] decrypt( byte[] ciphertext ) throws CryptoException {
try {
return decryptCipher.doFinal(ciphertext);
byte[] result = decryptCipher.doFinal(ciphertext);
if (iv != null) {
//throw away the first block
return Arrays.copyOfRange(result, iv.getIV().length, result.length);
}
return result;
} catch ( Exception e ) {
try {
initDecryptCipher();
Expand Down Expand Up @@ -134,13 +151,15 @@ protected void initDecryptCipher() throws CryptoException {
// Create and initialize decryption cipher
try {
decryptCipher = Cipher.getInstance( cipherAlgorithm);
decryptCipher.init( Cipher.DECRYPT_MODE, decryptKey );
decryptCipher.init( Cipher.DECRYPT_MODE, decryptKey, iv );
} catch ( NoSuchAlgorithmException e ) {
throw new CryptoException(CorePlugin.Event.TEIID10009, e, CorePlugin.Util.gs(CorePlugin.Event.TEIID10009, cipherAlgorithm ));
} catch ( NoSuchPaddingException e ) {
throw new CryptoException(CorePlugin.Event.TEIID10010, CorePlugin.Util.gs(CorePlugin.Event.TEIID10010, cipherAlgorithm, e.getClass().getName(), e.getMessage() ));
} catch ( InvalidKeyException e ) {
throw new CryptoException(CorePlugin.Event.TEIID10011, e, CorePlugin.Util.gs(CorePlugin.Event.TEIID10011, e.getClass().getName(), e.getMessage()) );
} catch (InvalidAlgorithmParameterException e) {
throw new CryptoException(CorePlugin.Event.TEIID10009, e, CorePlugin.Util.gs(CorePlugin.Event.TEIID10009, cipherAlgorithm ));
}
}

Expand Down Expand Up @@ -194,7 +213,18 @@ public byte[] encrypt( byte[] cleartext ) throws CryptoException {
public synchronized byte[] encrypt(byte[] buffer, int offset, int length)
throws CryptoException {
try {
return encryptCipher.doFinal(buffer, offset, length);
byte[] initBlock = null;
if (iv != null) {
random.nextBytes(randBuffer);
initBlock = encryptCipher.update(randBuffer);
}
byte[] result = encryptCipher.doFinal(buffer, offset, length);
if (initBlock != null) {
byte[] newResult = Arrays.copyOf(initBlock, initBlock.length + result.length);
System.arraycopy(result, 0, newResult, initBlock.length, result.length);
return newResult;
}
return result;
} catch ( Exception e ) {
try {
initEncryptCipher();
Expand Down Expand Up @@ -233,13 +263,15 @@ protected void initEncryptCipher() throws CryptoException {
// Create and initialize encryption cipher
try {
encryptCipher = Cipher.getInstance( cipherAlgorithm );
encryptCipher.init( Cipher.ENCRYPT_MODE, encryptKey );
encryptCipher.init( Cipher.ENCRYPT_MODE, encryptKey, iv );
} catch ( NoSuchAlgorithmException e ) {
throw new CryptoException(CorePlugin.Event.TEIID10016, e, CorePlugin.Util.gs(CorePlugin.Event.TEIID10016, cipherAlgorithm ));
} catch ( NoSuchPaddingException e ) {
throw new CryptoException(CorePlugin.Event.TEIID10017, e, CorePlugin.Util.gs(CorePlugin.Event.TEIID10017, cipherAlgorithm , e.getMessage() ));
} catch ( InvalidKeyException e ) {
throw new CryptoException(CorePlugin.Event.TEIID10018, e, CorePlugin.Util.gs(CorePlugin.Event.TEIID10018, e.getMessage() ));
} catch (InvalidAlgorithmParameterException e) {
throw new CryptoException(CorePlugin.Event.TEIID10016, e, CorePlugin.Util.gs(CorePlugin.Event.TEIID10016, cipherAlgorithm ));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ public byte[] createPublicKey(boolean large) throws CryptoException {
}
}

public SymmetricCryptor getSymmetricCryptor(byte[] peerPublicKeyBytes, boolean useSealedObject, ClassLoader classLoader, boolean large)
public SymmetricCryptor getSymmetricCryptor(byte[] peerPublicKeyBytes, boolean useSealedObject, ClassLoader classLoader, boolean large, boolean cbc)
throws CryptoException {
PrivateKey privKey = large?privateKeyLarge:privateKey;
if (privKey == null) {
Expand Down Expand Up @@ -139,7 +139,7 @@ public SymmetricCryptor getSymmetricCryptor(byte[] peerPublicKeyBytes, boolean u
byte[] hash = sha.digest(secret);
byte[] symKey = new byte[keySize / 8];
System.arraycopy(hash, 0, symKey, 0, symKey.length);
SymmetricCryptor sc = SymmetricCryptor.getSymmectricCryptor(symKey);
SymmetricCryptor sc = SymmetricCryptor.getSymmectricCryptor(symKey, cbc);
sc.setUseSealedObject(useSealedObject);
sc.setClassLoader(classLoader);
return sc;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@

import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import org.teiid.core.CorePlugin;
Expand All @@ -44,7 +45,8 @@
public class SymmetricCryptor extends BasicCryptor {

public static final String DEFAULT_SYM_KEY_ALGORITHM = "AES"; //$NON-NLS-1$
public static final String DEFAULT_SYM_ALGORITHM = "AES/ECB/PKCS5Padding"; //$NON-NLS-1$
public static final String ECB_SYM_ALGORITHM = "AES/ECB/PKCS5Padding"; //$NON-NLS-1$
public static final String CBC_SYM_ALGORITHM = "AES/CBC/PKCS5Padding"; //$NON-NLS-1$
public static final int DEFAULT_KEY_BITS = 128;
public static final String DEFAULT_STORE_PASSWORD = "changeit"; //$NON-NLS-1$
public static final String DEFAULT_ALIAS = "cluster_key"; //$NON-NLS-1$
Expand All @@ -57,10 +59,10 @@ public class SymmetricCryptor extends BasicCryptor {
* @return a new SymmetricCryptor
* @throws CryptoException
*/
public static SymmetricCryptor getSymmectricCryptor() throws CryptoException {
public static SymmetricCryptor getSymmectricCryptor(boolean cbc) throws CryptoException {
Key key = generateKey();

return new SymmetricCryptor(key);
return new SymmetricCryptor(key, cbc);
}

public static SecretKey generateKey() throws CryptoException {
Expand Down Expand Up @@ -92,7 +94,7 @@ public static SymmetricCryptor getSymmectricCryptor(URL keyResource) throws Cryp
KeyStore store = KeyStore.getInstance("JCEKS"); //$NON-NLS-1$
store.load(stream, DEFAULT_STORE_PASSWORD.toCharArray());
Key key = store.getKey(DEFAULT_ALIAS, DEFAULT_STORE_PASSWORD.toCharArray());
return new SymmetricCryptor(key);
return new SymmetricCryptor(key, true);
} catch (GeneralSecurityException e) {
throw new CryptoException(CorePlugin.Event.TEIID10022, e);
} finally {
Expand All @@ -107,9 +109,9 @@ public static SymmetricCryptor getSymmectricCryptor(URL keyResource) throws Cryp
* @return a new SymmetricCryptor
* @throws CryptoException
*/
public static SymmetricCryptor getSymmectricCryptor(byte[] key) throws CryptoException {
public static SymmetricCryptor getSymmectricCryptor(byte[] key, boolean cbc) throws CryptoException {
Key secretKey = new SecretKeySpec(key, DEFAULT_SYM_KEY_ALGORITHM);
return new SymmetricCryptor(secretKey);
return new SymmetricCryptor(secretKey, cbc);
}

public static void generateAndSaveKey(String file) throws CryptoException, IOException {
Expand All @@ -132,8 +134,8 @@ private static void saveKey(String file, SecretKey key) throws CryptoException,
}
}

SymmetricCryptor(Key key) throws CryptoException {
super(key, key, DEFAULT_SYM_ALGORITHM);
SymmetricCryptor(Key key, boolean cbc) throws CryptoException {
super(key, key, cbc?CBC_SYM_ALGORITHM:ECB_SYM_ALGORITHM, cbc?new IvParameterSpec(new byte[] {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf}):null);
}

public byte[] getEncodedKey() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ public void testKeyGenerationDefault() throws CryptoException {
DhKeyGenerator keyGenClient = new DhKeyGenerator();
byte[] serverKey = keyGenServer.createPublicKey(true);
byte[] clientKey = keyGenClient.createPublicKey(true);
SymmetricCryptor serverCryptor = keyGenServer.getSymmetricCryptor(clientKey, false, TestDhKeyGenerator.class.getClassLoader(), true);
SymmetricCryptor clientCryptor = keyGenClient.getSymmetricCryptor(serverKey, false, TestDhKeyGenerator.class.getClassLoader(), true);
SymmetricCryptor serverCryptor = keyGenServer.getSymmetricCryptor(clientKey, false, TestDhKeyGenerator.class.getClassLoader(), true, true);
SymmetricCryptor clientCryptor = keyGenClient.getSymmetricCryptor(serverKey, false, TestDhKeyGenerator.class.getClassLoader(), true, true);

String cleartext = "cleartext!"; //$NON-NLS-1$

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ public void helpTestEncryptDecrypt( String cleartext ) throws CryptoException {

@Test public void testSymmetricEncryptionWithRandomKey() throws Exception {

SymmetricCryptor randomSymCryptor = SymmetricCryptor.getSymmectricCryptor();
SymmetricCryptor randomSymCryptor = SymmetricCryptor.getSymmectricCryptor(true);

ArrayList test = new ArrayList(Arrays.asList(new String[] {ALPHA_L, ALPHA_U, CLEARTEXT, NUMBERS}));

Expand All @@ -213,7 +213,7 @@ public void helpTestEncryptDecrypt( String cleartext ) throws CryptoException {

assertEquals(test, clearObject);

SymmetricCryptor cryptor1 = SymmetricCryptor.getSymmectricCryptor(randomSymCryptor.getEncodedKey());
SymmetricCryptor cryptor1 = SymmetricCryptor.getSymmectricCryptor(randomSymCryptor.getEncodedKey(), true);

clearObject = (ArrayList)cryptor1.unsealObject(result);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,9 @@ private void receivedHahdshake(Handshake handshake) throws CommunicationExceptio
if (LogManager.isMessageToBeRecorded(LogConstants.CTX_TRANSPORT, MessageLevel.DETAIL)) {
LogManager.logDetail(LogConstants.CTX_TRANSPORT, large?"2048":"1024", "key exchange being used."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
boolean useCbc = handshake.isCbc();
try {
this.cryptor = keyGen.getSymmetricCryptor(returnedPublicKey, "08.03".compareTo(clientVersion) > 0, SocketClientInstance.class.getClassLoader(), large); //$NON-NLS-1$
this.cryptor = keyGen.getSymmetricCryptor(returnedPublicKey, "08.03".compareTo(clientVersion) > 0, SocketClientInstance.class.getClassLoader(), large, useCbc); //$NON-NLS-1$
} catch (CryptoException e) {
throw new CommunicationException(RuntimePlugin.Event.TEIID40053, e);
}
Expand Down

0 comments on commit 4cb43be

Please sign in to comment.