This source file includes following definitions.
- getBytes
 
- getBytes
 
- setUp
 
- testCipherUse
 
- testSameBundleRestoration
 
- testDifferentBundleRestoration
 
- testIncompleteBundleRestoration
 
- testRestorationSucceedsBeforeCipherCreated
 
- testRestorationDiscardsAfterOtherCipherAlreadyCreated
 
- testSavingToBundle
 
- sameOutputDifferentCiphers
 
package org.chromium.content.browser.crypto;
import android.os.Bundle;
import android.test.InstrumentationTestCase;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Arrays;
import javax.crypto.Cipher;
public class CipherFactoryTest extends InstrumentationTestCase {
    private static final byte[] INPUT_DATA = {1, 16, 84};
    
    private static class DeterministicParameterGenerator extends ByteArrayGenerator {
        @Override
        public byte[] getBytes(int numBytes) throws IOException, GeneralSecurityException {
            return getBytes(numBytes, (byte) 0);
        }
        
        public byte[] getBytes(int numBytes, byte startByte) {
            byte[] bytes = new byte[numBytes];
            for (int i = 0; i < numBytes; ++i) {
                bytes[i] = (byte) (startByte + i);
            }
            return bytes;
        }
    }
    private DeterministicParameterGenerator mNumberProvider;
    
    @Override
    protected void setUp() throws Exception {
        super.setUp();
        mNumberProvider = new DeterministicParameterGenerator();
        CipherFactory.getInstance().setRandomNumberProviderForTests(mNumberProvider);
    }
    
    public void testCipherUse() throws Exception {
        
        Cipher aEncrypt = CipherFactory.getInstance().getCipher(Cipher.ENCRYPT_MODE);
        Cipher bEncrypt = CipherFactory.getInstance().getCipher(Cipher.ENCRYPT_MODE);
        byte[] output = sameOutputDifferentCiphers(INPUT_DATA, aEncrypt, bEncrypt);
        
        Cipher aDecrypt = CipherFactory.getInstance().getCipher(Cipher.DECRYPT_MODE);
        Cipher bDecrypt = CipherFactory.getInstance().getCipher(Cipher.DECRYPT_MODE);
        byte[] decrypted = sameOutputDifferentCiphers(output, aDecrypt, bDecrypt);
        assertTrue(Arrays.equals(decrypted, INPUT_DATA));
    }
    
    public void testSameBundleRestoration() throws Exception {
        
        Bundle aBundle = new Bundle();
        Bundle bBundle = new Bundle();
        byte[] sameIv = mNumberProvider.getBytes(CipherFactory.NUM_BYTES, (byte) 100);
        aBundle.putByteArray(CipherFactory.BUNDLE_IV, sameIv);
        bBundle.putByteArray(CipherFactory.BUNDLE_IV, sameIv);
        byte[] sameKey = mNumberProvider.getBytes(CipherFactory.NUM_BYTES, (byte) 200);
        aBundle.putByteArray(CipherFactory.BUNDLE_KEY, sameKey);
        bBundle.putByteArray(CipherFactory.BUNDLE_KEY, sameKey);
        
        assertTrue(CipherFactory.getInstance().restoreFromBundle(aBundle));
        Cipher aCipher = CipherFactory.getInstance().getCipher(Cipher.ENCRYPT_MODE);
        assertTrue(CipherFactory.getInstance().restoreFromBundle(bBundle));
        Cipher bCipher = CipherFactory.getInstance().getCipher(Cipher.ENCRYPT_MODE);
        
        sameOutputDifferentCiphers(INPUT_DATA, aCipher, bCipher);
    }
    
    public void testDifferentBundleRestoration() throws Exception {
        
        Bundle aBundle = new Bundle();
        byte[] aIv = mNumberProvider.getBytes(CipherFactory.NUM_BYTES, (byte) 50);
        byte[] aKey = mNumberProvider.getBytes(CipherFactory.NUM_BYTES, (byte) 100);
        aBundle.putByteArray(CipherFactory.BUNDLE_IV, aIv);
        aBundle.putByteArray(CipherFactory.BUNDLE_KEY, aKey);
        assertTrue(CipherFactory.getInstance().restoreFromBundle(aBundle));
        Cipher aCipher = CipherFactory.getInstance().getCipher(Cipher.ENCRYPT_MODE);
        
        Bundle bBundle = new Bundle();
        byte[] bIv = mNumberProvider.getBytes(CipherFactory.NUM_BYTES, (byte) 150);
        byte[] bKey = mNumberProvider.getBytes(CipherFactory.NUM_BYTES, (byte) 200);
        bBundle.putByteArray(CipherFactory.BUNDLE_IV, bIv);
        bBundle.putByteArray(CipherFactory.BUNDLE_KEY, bKey);
        assertFalse(CipherFactory.getInstance().restoreFromBundle(bBundle));
        Cipher bCipher = CipherFactory.getInstance().getCipher(Cipher.ENCRYPT_MODE);
        
        sameOutputDifferentCiphers(INPUT_DATA, aCipher, bCipher);
    }
    
    public void testIncompleteBundleRestoration() throws Exception {
        
        assertFalse(CipherFactory.getInstance().restoreFromBundle(null));
        
        Bundle aBundle = new Bundle();
        byte[] iv = mNumberProvider.getBytes(CipherFactory.NUM_BYTES, (byte) 50);
        aBundle.putByteArray(CipherFactory.BUNDLE_IV, iv);
        assertFalse(CipherFactory.getInstance().restoreFromBundle(aBundle));
        
        Bundle bBundle = new Bundle();
        byte[] key = mNumberProvider.getBytes(CipherFactory.NUM_BYTES, (byte) 100);
        bBundle.putByteArray(CipherFactory.BUNDLE_KEY, key);
        assertFalse(CipherFactory.getInstance().restoreFromBundle(bBundle));
    }
    
    public void testRestorationSucceedsBeforeCipherCreated() throws Exception {
        byte[] iv = mNumberProvider.getBytes(CipherFactory.NUM_BYTES, (byte) 50);
        byte[] key = mNumberProvider.getBytes(CipherFactory.NUM_BYTES, (byte) 100);
        Bundle bundle = new Bundle();
        bundle.putByteArray(CipherFactory.BUNDLE_IV, iv);
        bundle.putByteArray(CipherFactory.BUNDLE_KEY, key);
        
        assertNull(CipherFactory.getInstance().getCipherData(false));
        assertTrue(CipherFactory.getInstance().restoreFromBundle(bundle));
        assertNotNull(CipherFactory.getInstance().getCipherData(false));
    }
    
    public void testRestorationDiscardsAfterOtherCipherAlreadyCreated() throws Exception {
        byte[] iv = mNumberProvider.getBytes(CipherFactory.NUM_BYTES, (byte) 50);
        byte[] key = mNumberProvider.getBytes(CipherFactory.NUM_BYTES, (byte) 100);
        Bundle bundle = new Bundle();
        bundle.putByteArray(CipherFactory.BUNDLE_IV, iv);
        bundle.putByteArray(CipherFactory.BUNDLE_KEY, key);
        
        Cipher aCipher = CipherFactory.getInstance().getCipher(Cipher.ENCRYPT_MODE);
        assertFalse(CipherFactory.getInstance().restoreFromBundle(bundle));
        Cipher bCipher = CipherFactory.getInstance().getCipher(Cipher.ENCRYPT_MODE);
        
        sameOutputDifferentCiphers(INPUT_DATA, aCipher, bCipher);
    }
    
    public void testSavingToBundle() throws Exception {
        
        Bundle initialBundle = new Bundle();
        CipherFactory.getInstance().saveToBundle(initialBundle);
        assertFalse(initialBundle.containsKey(CipherFactory.BUNDLE_IV));
        assertFalse(initialBundle.containsKey(CipherFactory.BUNDLE_KEY));
        
        CipherFactory.getInstance().getCipher(Cipher.ENCRYPT_MODE);
        Bundle afterBundle = new Bundle();
        CipherFactory.getInstance().saveToBundle(afterBundle);
        assertTrue(afterBundle.containsKey(CipherFactory.BUNDLE_IV));
        assertTrue(afterBundle.containsKey(CipherFactory.BUNDLE_KEY));
        
        assertTrue(CipherFactory.getInstance().restoreFromBundle(afterBundle));
    }
    
    private byte[] sameOutputDifferentCiphers(byte[] input, Cipher aCipher, Cipher bCipher)
            throws Exception {
        assertNotNull(aCipher);
        assertNotNull(bCipher);
        assertNotSame(aCipher, bCipher);
        byte[] aOutput = aCipher.doFinal(input);
        byte[] bOutput = bCipher.doFinal(input);
        assertNotNull(aOutput);
        assertNotNull(bOutput);
        assertTrue(Arrays.equals(aOutput, bOutput));
        return aOutput;
    }
}