/* This code is part of Freenet. It is distributed under the GNU General * Public License, version 2 (or at your option any later version). See * http://www.gnu.org/ for further details of the GPL. */ package freenet.crypt; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.nio.ByteBuffer; import java.security.GeneralSecurityException; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.Security; import java.util.Arrays; import java.util.Random; import javax.crypto.spec.IvParameterSpec; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Hex; import org.junit.Test; public class CryptByteBufferTest { private static final CryptByteBufferType[] cipherTypes = CryptByteBufferType.values(); private static final String ivPlainText = "6bc1bee22e409f96e93d7e117393172a" + "ae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52ef" + "f69f2445df4f9b17ad2b417be66c3710"; private static final String[] plainText = { "0123456789abcdef1123456789abcdef2123456789abcdef3123456789abcdef", "0123456789abcdef1123456789abcdef", ivPlainText, ivPlainText, ivPlainText, ivPlainText}; private static final byte[][] keys = { Hex.decode("deadbeefcafebabe0123456789abcdefcafebabedeadbeefcafebabe01234567"), Hex.decode("deadbeefcafebabe0123456789abcdefcafebabedeadbeefcafebabe01234567"), Hex.decode("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"), Hex.decode("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"), Hex.decode("8c123cffb0297a71ae8388109a6527dd"), Hex.decode("a63add96a3d5975e2dad2f904ff584a32920e8aa54263254161362d1fb785790")}; private static final byte[][] ivs = { null, null, Hex.decode("f0f1f2f3f4f5f6f7f8f9fafbfcfdfefff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"), Hex.decode("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"), Hex.decode("73c3c8df749084bb"), Hex.decode("7b471cf26ee479fb")}; static{ Security.addProvider(new BouncyCastleProvider()); } @Test public void testSuccessfulRoundTripByteArray() throws GeneralSecurityException { for(int i = 0; i < cipherTypes.length; i++){ CryptByteBufferType type = cipherTypes[i]; CryptByteBuffer crypt; if(ivs[i] == null){ crypt = new CryptByteBuffer(type, keys[i]); } else { crypt = new CryptByteBuffer(type, keys[i], ivs[i]); } byte[] decipheredtext = crypt.decryptCopy(crypt.encryptCopy(Hex.decode(plainText[i]))); assertArrayEquals("CryptByteBufferType: "+type.name(), Hex.decode(plainText[i]), decipheredtext); } } @Test public void testRoundOneByte() throws GeneralSecurityException { for(int i = 0; i < cipherTypes.length; i++){ CryptByteBufferType type = cipherTypes[i]; CryptByteBuffer crypt1; CryptByteBuffer crypt2; if(!type.isStreamCipher) continue; if(ivs[i] == null){ crypt1 = new CryptByteBuffer(type, keys[i]); crypt2 = new CryptByteBuffer(type, keys[i]); } else { crypt1 = new CryptByteBuffer(type, keys[i], ivs[i]); crypt2 = new CryptByteBuffer(type, keys[i], ivs[i]); } byte[] origPlaintext = Hex.decode(plainText[i]); byte[] origCiphertext = crypt1.encryptCopy(origPlaintext); // Now encrypt one byte at a time. byte[] buf = origPlaintext.clone(); for(int j=0;j<buf.length;j++) { crypt2.encrypt(buf, j, 1); assertEquals(buf[j], origCiphertext[j]); } for(int j=0;j<buf.length;j++) { crypt2.decrypt(buf, j, 1); assertEquals(buf[j], origPlaintext[j]); } } } @Test public void testRoundRandomLengthBytes() throws GeneralSecurityException { Random random = new Random(0xAAAAAAAA); for(int i = 0; i < cipherTypes.length; i++){ CryptByteBufferType type = cipherTypes[i]; CryptByteBuffer crypt1; CryptByteBuffer crypt2; if(!type.isStreamCipher) continue; if(ivs[i] == null){ crypt1 = new CryptByteBuffer(type, keys[i]); crypt2 = new CryptByteBuffer(type, keys[i]); } else { crypt1 = new CryptByteBuffer(type, keys[i], ivs[i]); crypt2 = new CryptByteBuffer(type, keys[i], ivs[i]); } byte[] origPlaintext = Hex.decode(plainText[i]); byte[] origCiphertext = crypt1.encryptCopy(origPlaintext); // Now encrypt one byte at a time. byte[] buf = origPlaintext.clone(); int j=0; while(j < buf.length) { int r = buf.length - j; int copy = 1 + (r == 1 ? 0 : random.nextInt(r-1)); crypt2.encrypt(buf, j, copy); j += copy; } assertArrayEquals(buf, origCiphertext); j = 0; while(j < buf.length) { int r = buf.length - j; int copy = 1 + (r == 1 ? 0 : random.nextInt(r-1)); crypt2.decrypt(buf, j, copy); j += copy; } assertArrayEquals(buf, origPlaintext); } } @Test public void testSuccessfulRoundTripInPlace() throws GeneralSecurityException { for(int i = 0; i < cipherTypes.length; i++){ CryptByteBufferType type = cipherTypes[i]; CryptByteBuffer crypt; if(ivs[i] == null){ crypt = new CryptByteBuffer(type, keys[i]); } else { crypt = new CryptByteBuffer(type, keys[i], ivs[i]); } byte[] buffer = Hex.decode(plainText[i]); byte[] plaintextCopy = buffer.clone(); crypt.encrypt(buffer, 0, buffer.length); assertTrue(!Arrays.equals(buffer, plaintextCopy)); crypt.decrypt(buffer, 0, buffer.length); assertArrayEquals("CryptByteBufferType: "+type.name(), plaintextCopy, buffer); } } @Test public void testSuccessfulRoundTripInPlaceOffset() throws GeneralSecurityException { int header = 5; int footer = 5; for(int i = 0; i < cipherTypes.length; i++){ CryptByteBufferType type = cipherTypes[i]; CryptByteBuffer crypt; if(ivs[i] == null){ crypt = new CryptByteBuffer(type, keys[i]); } else { crypt = new CryptByteBuffer(type, keys[i], ivs[i]); } byte[] originalPlaintext = Hex.decode(plainText[i]); byte[] buffer = new byte[header+originalPlaintext.length+footer]; byte[] copyBuffer = buffer.clone(); System.arraycopy(originalPlaintext, 0, buffer, header, originalPlaintext.length); crypt.encrypt(buffer, footer, originalPlaintext.length); assertTrue(!Arrays.equals(buffer, copyBuffer)); crypt.decrypt(buffer, footer, originalPlaintext.length); assertArrayEquals("CryptByteBufferType: "+type.name(), originalPlaintext, Arrays.copyOfRange(buffer, footer, footer+originalPlaintext.length)); } } @Test public void testSuccessfulRoundTripOutOfPlaceOffset() throws GeneralSecurityException { int inHeader = 5; int inFooter = 5; int outHeader = 33; int outFooter = 33; for(int i = 0; i < cipherTypes.length; i++){ CryptByteBufferType type = cipherTypes[i]; CryptByteBuffer crypt; if(ivs[i] == null){ crypt = new CryptByteBuffer(type, keys[i]); } else { crypt = new CryptByteBuffer(type, keys[i], ivs[i]); } byte[] originalPlaintext = Hex.decode(plainText[i]); byte[] buffer = new byte[inHeader+originalPlaintext.length+inFooter]; System.arraycopy(originalPlaintext, 0, buffer, inHeader, originalPlaintext.length); byte[] copyBuffer = buffer.clone(); byte[] outBuffer = new byte[outHeader + originalPlaintext.length + outFooter]; crypt.encrypt(buffer, inFooter, originalPlaintext.length, outBuffer, outHeader); assertTrue(Arrays.equals(buffer, copyBuffer)); copyBuffer = outBuffer.clone(); crypt.decrypt(outBuffer, outHeader, originalPlaintext.length, buffer, inFooter); assertTrue(Arrays.equals(copyBuffer, outBuffer)); assertArrayEquals("CryptByteBufferType: "+type.name(), originalPlaintext, Arrays.copyOfRange(buffer, inFooter, inFooter+originalPlaintext.length)); } } @Test public void testSuccessfulRoundTripByteArrayReset() throws GeneralSecurityException { for(int i = 0; i < cipherTypes.length; i++){ CryptByteBufferType type = cipherTypes[i]; CryptByteBuffer crypt; byte[] originalData = Hex.decode(plainText[i]); int len = originalData.length; ByteBuffer plain = ByteBuffer.wrap(originalData); if(ivs[i] == null){ crypt = new CryptByteBuffer(type, keys[i]); } else { crypt = new CryptByteBuffer(type, keys[i], ivs[i]); } ByteBuffer ciphertext1 = crypt.encryptCopy(plain); ByteBuffer ciphertext2 = crypt.encryptCopy(plain); ByteBuffer ciphertext3 = crypt.encryptCopy(plain); assertEquals(ciphertext1.capacity(), len); assertEquals(ciphertext2.capacity(), len); assertEquals(ciphertext3.capacity(), len); assertEquals(ciphertext1.remaining(), len); assertEquals(ciphertext2.remaining(), len); assertEquals(ciphertext3.remaining(), len); if(type.isStreamCipher) { // Once we have initialised the cipher, it is treated as a stream. // Repeated encryption of the same data will return different ciphertext, // as it is treated as a later point in the stream. assertNotEquals(ciphertext1, ciphertext2); assertNotEquals(ciphertext1, ciphertext3); assertNotEquals(ciphertext2, ciphertext3); } ByteBuffer decipheredtext1 = crypt.decryptCopy(ciphertext1); ByteBuffer decipheredtext2 = crypt.decryptCopy(ciphertext2); ByteBuffer decipheredtext3 = crypt.decryptCopy(ciphertext3); assertTrue("CryptByteBufferType: "+type.name(), plain.equals(decipheredtext1)); assertTrue("CryptByteBufferType: "+type.name(), plain.equals(decipheredtext2)); assertTrue("CryptByteBufferType: "+type.name(), plain.equals(decipheredtext3)); } } private void assertNotEquals(Object o1, Object o2) { assertFalse(o1.equals(o2)); } @Test public void testEncryptWrapByteBuffer() throws GeneralSecurityException { int header = 5; int footer = 5; for(int i = 0; i < cipherTypes.length; i++){ CryptByteBufferType type = cipherTypes[i]; CryptByteBuffer crypt, crypt2; byte[] origPlaintext = Hex.decode(plainText[i]); byte[] buf = new byte[origPlaintext.length+header+footer]; System.arraycopy(origPlaintext, 0, buf, header, origPlaintext.length); byte[] cloneBuf = buf.clone(); if(ivs[i] == null){ crypt = new CryptByteBuffer(type, keys[i]); crypt2 = new CryptByteBuffer(type, keys[i]); } else { crypt = new CryptByteBuffer(type, keys[i], ivs[i]); crypt2 = new CryptByteBuffer(type, keys[i], ivs[i]); } ByteBuffer plaintext = ByteBuffer.wrap(buf, header, origPlaintext.length); ByteBuffer ciphertext = crypt.encryptCopy(plaintext); assertTrue(Arrays.equals(buf, cloneBuf)); // Plaintext not modified. assertEquals(ciphertext.remaining(), origPlaintext.length); byte[] altCiphertext = crypt2.encryptCopy(origPlaintext); byte[] ciphertextBytes = new byte[origPlaintext.length]; ciphertext.get(ciphertextBytes); ciphertext.position(0); assertTrue(Arrays.equals(altCiphertext, ciphertextBytes)); ByteBuffer deciphered = crypt.decryptCopy(ciphertext); assertTrue(deciphered.equals(plaintext)); byte[] data = new byte[origPlaintext.length]; deciphered.get(data); assertTrue(Arrays.equals(data, origPlaintext)); } } @Test public void testEncryptByteBufferToByteBuffer() throws GeneralSecurityException { int header = 5; int footer = 5; for(int i = 0; i < cipherTypes.length; i++){ CryptByteBufferType type = cipherTypes[i]; CryptByteBuffer crypt; byte[] origPlaintext = Hex.decode(plainText[i]); byte[] buf = new byte[origPlaintext.length+header+footer]; System.arraycopy(origPlaintext, 0, buf, header, origPlaintext.length); byte[] cloneBuf = buf.clone(); if(ivs[i] == null){ crypt = new CryptByteBuffer(type, keys[i]); } else { crypt = new CryptByteBuffer(type, keys[i], ivs[i]); } ByteBuffer plaintext = ByteBuffer.wrap(buf, header, origPlaintext.length); byte[] ciphertextBuf = new byte[origPlaintext.length+header+footer]; byte[] copyCiphertextBuf = ciphertextBuf.clone(); ByteBuffer ciphertext = ByteBuffer.wrap(ciphertextBuf, header, origPlaintext.length); crypt.encrypt(plaintext, ciphertext); assertEquals(plaintext.position(), header+origPlaintext.length); assertEquals(ciphertext.position(), header+origPlaintext.length); assertTrue(Arrays.equals(buf, cloneBuf)); // Plaintext not modified. plaintext.position(header); ciphertext.position(header); assertTrue(!Arrays.equals(ciphertextBuf, copyCiphertextBuf)); Arrays.fill(buf, (byte)0); assertFalse(Arrays.equals(buf, cloneBuf)); crypt.decrypt(ciphertext, plaintext); assertTrue(Arrays.equals(buf, cloneBuf)); } } @Test public void testEncryptByteBufferToByteBufferDirect() throws GeneralSecurityException { for(int i = 0; i < cipherTypes.length; i++){ CryptByteBufferType type = cipherTypes[i]; CryptByteBuffer crypt; byte[] origPlaintext = Hex.decode(plainText[i]); if(ivs[i] == null){ crypt = new CryptByteBuffer(type, keys[i]); } else { crypt = new CryptByteBuffer(type, keys[i], ivs[i]); } ByteBuffer plaintext = ByteBuffer.allocateDirect(origPlaintext.length); plaintext.put(origPlaintext); plaintext.position(0); ByteBuffer ciphertext = ByteBuffer.allocateDirect(origPlaintext.length); crypt.encrypt(plaintext, ciphertext); assertEquals(plaintext.position(), origPlaintext.length); assertEquals(ciphertext.position(), origPlaintext.length); plaintext.position(0); ciphertext.position(0); byte[] ciphertextCopy = new byte[origPlaintext.length]; ciphertext.get(ciphertextCopy); ciphertext.position(0); assertFalse(Arrays.equals(origPlaintext, ciphertextCopy)); crypt.decrypt(ciphertext, plaintext); assertEquals(plaintext.position(), origPlaintext.length); assertEquals(ciphertext.position(), origPlaintext.length); assertEquals(plaintext, ciphertext); plaintext.position(0); byte[] finalPlaintext = new byte[origPlaintext.length]; plaintext.get(finalPlaintext); assertArrayEquals(finalPlaintext, origPlaintext); } } @Test public void testDecryptWrapByteBuffer() throws GeneralSecurityException { int header = 5; int footer = 5; for(int i = 0; i < cipherTypes.length; i++){ CryptByteBufferType type = cipherTypes[i]; CryptByteBuffer crypt; byte[] origPlaintext = Hex.decode(plainText[i]); byte[] buf = origPlaintext.clone(); if(ivs[i] == null){ crypt = new CryptByteBuffer(type, keys[i]); } else { crypt = new CryptByteBuffer(type, keys[i], ivs[i]); } ByteBuffer plaintext = ByteBuffer.wrap(buf); ByteBuffer ciphertext = crypt.encryptCopy(plaintext); assertTrue(Arrays.equals(buf, origPlaintext)); // Plaintext not modified. assertEquals(ciphertext.remaining(), origPlaintext.length); byte[] decryptBuf = new byte[header+origPlaintext.length+footer]; ciphertext.get(decryptBuf, header, origPlaintext.length); byte[] copyOfDecryptBuf = decryptBuf.clone(); ByteBuffer toDecipher = ByteBuffer.wrap(decryptBuf, header, origPlaintext.length); ByteBuffer deciphered = crypt.decryptCopy(toDecipher); assertTrue(Arrays.equals(decryptBuf, copyOfDecryptBuf)); assertTrue(deciphered.equals(plaintext)); byte[] data = new byte[origPlaintext.length]; deciphered.get(data); assertTrue(Arrays.equals(data, origPlaintext)); } } @Test public void testEncryptDirectByteBuffer() throws GeneralSecurityException { for(int i = 0; i < cipherTypes.length; i++){ CryptByteBufferType type = cipherTypes[i]; CryptByteBuffer crypt; byte[] origPlaintext = Hex.decode(plainText[i]); ByteBuffer plaintext = ByteBuffer.allocateDirect(origPlaintext.length); plaintext.clear(); plaintext.put(origPlaintext); plaintext.clear(); if(ivs[i] == null){ crypt = new CryptByteBuffer(type, keys[i]); } else { crypt = new CryptByteBuffer(type, keys[i], ivs[i]); } ByteBuffer ciphertext = crypt.encryptCopy(plaintext); plaintext.clear(); byte[] copyPlaintext = new byte[origPlaintext.length]; plaintext.get(copyPlaintext); assertTrue(Arrays.equals(origPlaintext, copyPlaintext)); // Plaintext not modified. plaintext.clear(); assertEquals(ciphertext.remaining(), origPlaintext.length); ByteBuffer deciphered = crypt.decryptCopy(ciphertext); assertTrue(deciphered.equals(plaintext)); byte[] data = new byte[origPlaintext.length]; deciphered.get(data); assertTrue(Arrays.equals(data, origPlaintext)); } } @Test public void testSuccessfulRoundTripByteArrayNewInstance() throws GeneralSecurityException { for(int i = 0; i < cipherTypes.length; i++){ CryptByteBufferType type = cipherTypes[i]; CryptByteBuffer crypt; byte[] plain = Hex.decode(plainText[i]); if(ivs[i] == null){ crypt = new CryptByteBuffer(type, keys[i]); } else { crypt = new CryptByteBuffer(type, keys[i], ivs[i]); } byte[] ciphertext = crypt.encryptCopy(plain); byte[] ciphertext2 = crypt.encryptCopy(plain); byte[] ciphertext3 = crypt.encryptCopy(plain); if(type.isStreamCipher) { assertFalse(Arrays.equals(ciphertext, ciphertext2)); assertFalse(Arrays.equals(ciphertext, ciphertext3)); assertFalse(Arrays.equals(ciphertext2, ciphertext3)); } if(ivs[i] == null){ crypt = new CryptByteBuffer(type, keys[i]); } else { crypt = new CryptByteBuffer(type, keys[i], ivs[i]); } byte[] decipheredtext = crypt.decryptCopy(ciphertext); assertArrayEquals("CryptByteBufferType: "+type.name(), plain, decipheredtext); decipheredtext = crypt.decryptCopy(ciphertext2); assertArrayEquals("CryptByteBufferType2: "+type.name(), plain, decipheredtext); decipheredtext = crypt.decryptCopy(ciphertext3); assertArrayEquals("CryptByteBufferType3: "+type.name(), plain, decipheredtext); } } // @Test // public void testSuccessfulRoundTripBitSet() throws GeneralSecurityException { // for(int i = 0; i < cipherTypes.length; i++){ // CryptByteBufferType type = cipherTypes[i]; // CryptByteBuffer crypt; // byte[] plain = Hex.decode(plainText[i]); // if(ivs[i] == null){ // crypt = new CryptByteBuffer(type, keys[i]); // } else { // crypt = new CryptByteBuffer(type, keys[i], ivs[i]); // } // BitSet plaintext = BitSet.valueOf(plain); // BitSet ciphertext = crypt.encrypt(plaintext); // BitSet decipheredtext = crypt.decrypt(ciphertext); // assertTrue("CryptByteBufferType: "+type.name(), plaintext.equals(decipheredtext)); // } // } @Test public void testEncryptByteArrayNullInput() throws GeneralSecurityException{ for(int i = 0; i < cipherTypes.length; i++){ CryptByteBufferType type = cipherTypes[i]; CryptByteBuffer crypt; if(ivs[i] == null){ crypt = new CryptByteBuffer(type, keys[i]); } else { crypt = new CryptByteBuffer(type, keys[i], ivs[i]); } byte[] nullArray = null; try{ crypt.encryptCopy(nullArray); fail("CryptByteBufferType: "+type.name()+": Expected NullPointerException"); }catch(NullPointerException e){} } } // FIXME // @Test // public void testEncryptBitSetNullInput() throws GeneralSecurityException{ // for(int i = 0; i < cipherTypes.length; i++){ // CryptByteBufferType type = cipherTypes[i]; // CryptByteBuffer crypt; // if(ivs[i] == null){ // crypt = new CryptByteBuffer(type, keys[i]); // } else { // crypt = new CryptByteBuffer(type, keys[i], ivs[i]); // } // // BitSet nullSet = null; // try{ // crypt.encrypt(nullSet); // fail("CryptByteBufferType: "+type.name()+": Expected NullPointerException"); // }catch(NullPointerException e){} // } // } @Test public void testEncryptByteArrayIntIntNullInput() throws GeneralSecurityException { for(int i = 0; i < cipherTypes.length; i++){ CryptByteBufferType type = cipherTypes[i]; CryptByteBuffer crypt; if(ivs[i] == null){ crypt = new CryptByteBuffer(type, keys[i]); } else { crypt = new CryptByteBuffer(type, keys[i], ivs[i]); } byte[] nullArray = null; try{ crypt.encryptCopy(nullArray, 0, plainText[i].length()); fail("CryptByteBufferType: "+type.name()+": Expected IllegalArgumentException or " + "NullPointerException"); }catch(IllegalArgumentException e) { }catch(NullPointerException e){} } } @Test public void testEncryptByteArrayIntIntOffsetOutOfBounds() throws GeneralSecurityException { for(int i = 0; i < cipherTypes.length; i++){ CryptByteBufferType type = cipherTypes[i]; CryptByteBuffer crypt; if(ivs[i] == null){ crypt = new CryptByteBuffer(type, keys[i]); } else { crypt = new CryptByteBuffer(type, keys[i], ivs[i]); } try{ crypt.encryptCopy(Hex.decode(plainText[i]), -3, plainText[i].length()-3); fail("CryptByteBufferType: "+type.name()+": Expected IllegalArgumentException or " + "ArrayIndexOutOfBoundsException"); }catch(IllegalArgumentException e) { }catch(IndexOutOfBoundsException e){ } } } @Test public void testEncryptByteArrayIntIntLengthOutOfBounds() throws GeneralSecurityException { for(int i = 0; i < cipherTypes.length; i++){ CryptByteBufferType type = cipherTypes[i]; CryptByteBuffer crypt; if(ivs[i] == null){ crypt = new CryptByteBuffer(type, keys[i]); } else { crypt = new CryptByteBuffer(type, keys[i], ivs[i]); } try{ crypt.encryptCopy(Hex.decode(plainText[i]), 0, plainText[i].length()+3); fail("CryptByteBufferType: "+type.name()+": Expected IllegalArgumentException or " + "ArrayIndexOutOfBoundsException"); }catch(IllegalArgumentException e) { } catch(IndexOutOfBoundsException e){} } } @Test public void testDecryptByteArrayNullInput() throws GeneralSecurityException{ for(int i = 0; i < cipherTypes.length; i++){ CryptByteBufferType type = cipherTypes[i]; CryptByteBuffer crypt; if(ivs[i] == null){ crypt = new CryptByteBuffer(type, keys[i]); } else { crypt = new CryptByteBuffer(type, keys[i], ivs[i]); } byte[] nullArray = null; try{ crypt.decryptCopy(nullArray); fail("CryptByteBufferType: "+type.name()+": Expected NullPointerException"); }catch(NullPointerException e){} } } // FIXME // @Test // public void testDecryptBitSetNullInput() throws GeneralSecurityException{ // for(int i = 0; i < cipherTypes.length; i++){ // CryptByteBufferType type = cipherTypes[i]; // CryptByteBuffer crypt; // if(ivs[i] == null){ // crypt = new CryptByteBuffer(type, keys[i]); // } else { // crypt = new CryptByteBuffer(type, keys[i], ivs[i]); // } // // BitSet nullSet = null; // try{ // crypt.decrypt(nullSet); // fail("CryptByteBufferType: "+type.name()+": Expected NullPointerException"); // }catch(NullPointerException e){} // } // } @Test public void testDecryptByteArrayIntIntNullInput() throws GeneralSecurityException { for(int i = 0; i < cipherTypes.length; i++){ CryptByteBufferType type = cipherTypes[i]; CryptByteBuffer crypt; if(ivs[i] == null){ crypt = new CryptByteBuffer(type, keys[i]); } else { crypt = new CryptByteBuffer(type, keys[i], ivs[i]); } byte[] nullArray = null; try{ crypt.decryptCopy(nullArray, 0, plainText[i].length()); fail("CryptByteBufferType: "+type.name()+": Expected IllegalArgumentException or " + "NullPointerException"); }catch(NullPointerException e) { } catch(IllegalArgumentException e){ } } } @Test public void testDecryptByteArrayIntIntOffsetOutOfBounds() throws GeneralSecurityException { for(int i = 0; i < cipherTypes.length; i++){ CryptByteBufferType type = cipherTypes[i]; CryptByteBuffer crypt; if(ivs[i] == null){ crypt = new CryptByteBuffer(type, keys[i]); } else { crypt = new CryptByteBuffer(type, keys[i], ivs[i]); } try{ crypt.decryptCopy(Hex.decode(plainText[i]), -3, plainText[i].length()-3); fail("CryptByteBufferType: "+type.name()+": Expected IllegalArgumentException or " + "ArrayIndexOutOfBoundsException"); }catch(IllegalArgumentException e) { } catch (IndexOutOfBoundsException e){ } } } @Test public void testDecryptByteArrayIntIntLengthOutOfBounds() throws GeneralSecurityException { for(int i = 0; i < cipherTypes.length; i++){ CryptByteBufferType type = cipherTypes[i]; CryptByteBuffer crypt; if(ivs[i] == null){ crypt = new CryptByteBuffer(type, keys[i]); } else { crypt = new CryptByteBuffer(type, keys[i], ivs[i]); } try{ crypt.decryptCopy(Hex.decode(plainText[i]), 0, plainText[i].length()+3); fail("CryptByteBufferType: "+type.name()+": Expected IllegalArgumentException or " + "ArrayIndexOutOfBoundsException"); }catch(IllegalArgumentException e) { } catch (IndexOutOfBoundsException e){ } } } @Test public void testGetIV() throws InvalidKeyException, InvalidAlgorithmParameterException { int i = 4; CryptByteBuffer crypt = new CryptByteBuffer(cipherTypes[i], keys[i], ivs[i]); assertArrayEquals(crypt.getIV().getIV(), ivs[i]); } @Test public void testSetIVIvParameterSpec() throws InvalidKeyException, InvalidAlgorithmParameterException { int i = 4; CryptByteBuffer crypt = new CryptByteBuffer(cipherTypes[i], keys[i], ivs[i]); crypt.genIV(); crypt.setIV(new IvParameterSpec(ivs[i])); assertArrayEquals(ivs[i], crypt.getIV().getIV()); } @Test public void testSetIVIvParameterSpecNullInput() throws InvalidKeyException, InvalidAlgorithmParameterException { IvParameterSpec nullInput = null; int i = 4; CryptByteBuffer crypt = new CryptByteBuffer(cipherTypes[i], keys[i], ivs[i]); try{ crypt.setIV(nullInput); fail("Expected InvalidAlgorithmParameterException"); } catch (InvalidAlgorithmParameterException e){} } @Test (expected = UnsupportedTypeException.class) public void testSetIVIvParameterSpecUnsupportedTypeException() throws GeneralSecurityException { int i = 0; CryptByteBuffer crypt = new CryptByteBuffer(cipherTypes[i], keys[i]); crypt.setIV(new IvParameterSpec(ivs[4])); fail("Expected UnsupportedTypeException"); } @Test public void testGenIV() throws InvalidKeyException, InvalidAlgorithmParameterException { int i = 4; CryptByteBuffer crypt = new CryptByteBuffer(cipherTypes[i], keys[i], ivs[i]); assertNotNull(crypt.genIV()); } @Test public void testGenIVLength() throws InvalidKeyException, InvalidAlgorithmParameterException { int i = 4; CryptByteBuffer crypt = new CryptByteBuffer(cipherTypes[i], keys[i], ivs[i]); assertEquals(crypt.genIV().getIV().length, cipherTypes[i].ivSize.intValue()); } @Test (expected = UnsupportedTypeException.class) public void testGenIVUnsupportedTypeException() throws GeneralSecurityException { int i = 1; CryptByteBuffer crypt = new CryptByteBuffer(cipherTypes[i], keys[i]); crypt.genIV(); fail("Expected UnsupportedTypeException"); } @Test public void testOverlappingEncode() throws GeneralSecurityException { for(int i = 0; i < cipherTypes.length; i++){ CryptByteBufferType type = cipherTypes[i]; CryptByteBuffer crypt, crypt2; if(ivs[i] == null){ crypt = new CryptByteBuffer(type, keys[i]); crypt2 = new CryptByteBuffer(type, keys[i]); } else { crypt = new CryptByteBuffer(type, keys[i], ivs[i]); crypt2 = new CryptByteBuffer(type, keys[i], ivs[i]); } byte[] originalPlaintext = Hex.decode(plainText[i]); byte[] originalCiphertext = crypt2.encryptCopy(originalPlaintext); byte[] buf = new byte[originalPlaintext.length+1]; System.arraycopy(originalPlaintext, 0, buf, 0, originalPlaintext.length); crypt.encrypt(buf, 0, originalPlaintext.length, buf, 1); assertArrayEquals(originalCiphertext, Arrays.copyOfRange(buf, 1, buf.length)); } } @Test public void testOverlappingDecode() throws GeneralSecurityException { for(int i = 0; i < cipherTypes.length; i++){ CryptByteBufferType type = cipherTypes[i]; CryptByteBuffer crypt, crypt2; if(ivs[i] == null){ crypt = new CryptByteBuffer(type, keys[i]); crypt2 = new CryptByteBuffer(type, keys[i]); } else { crypt = new CryptByteBuffer(type, keys[i], ivs[i]); crypt2 = new CryptByteBuffer(type, keys[i], ivs[i]); } byte[] originalPlaintext = Hex.decode(plainText[i]); byte[] originalCiphertext = crypt2.encryptCopy(originalPlaintext); byte[] buf = new byte[originalPlaintext.length+1]; System.arraycopy(originalCiphertext, 0, buf, 0, originalCiphertext.length); crypt.decrypt(buf, 0, originalCiphertext.length, buf, 1); assertArrayEquals(originalPlaintext, Arrays.copyOfRange(buf, 1, buf.length)); } } }