// Path: AndroidVault/vault/src/main/java/com/bottlerocketstudios/vault/EncryptionConstants.java
// public class EncryptionConstants {
//     public static final String AES_CIPHER = "AES";
//     public static final String BLOCK_MODE_CBC = "CBC";
//     public static final String ENCRYPTION_PADDING_PKCS5 = "PKCS5Padding";
//     public static final String ENCRYPTION_PADDING_PKCS7 = "PKCS7Padding";
// 
//     /**
//       * While this specifies PKCS5Padding and a 256 bit key, a historical artifact in the Sun encryption
//       * implementation interprets PKCS5 to be PKCS7 for block sizes over 8 bytes. In Android M this
//       * appears to have been corrected so that PKCS7Padding will work when instantiating a Cipher object.
//       */
//     public static final String AES_CBC_PADDED_TRANSFORM = AES_CIPHER + "/" + BLOCK_MODE_CBC + "/" + ENCRYPTION_PADDING_PKCS5;
//     public static final String AES_CBC_PADDED_TRANSFORM_ANDROID_M = AES_CIPHER + "/" + BLOCK_MODE_CBC + "/" + ENCRYPTION_PADDING_PKCS7;
//     public static final int AES_256_KEY_LENGTH_BITS = 256;
// 
//     public static final String DIGEST_SHA256 = "SHA256";
// 
//     public static final String ANDROID_KEY_STORE = "AndroidKeyStore";
// }
// 
// Path: AndroidVault/vault/src/main/java/com/bottlerocketstudios/vault/keys/generator/Aes256RandomKeyFactory.java
// public class Aes256RandomKeyFactory {
// 
//     /**
//      * Create a randomly generated AES256 key.
//      */
//     public static SecretKey createKey() {
//         RandomKeyGenerator keyGenerator = new RandomKeyGenerator(new PrngSaltGenerator(), EncryptionConstants.AES_256_KEY_LENGTH_BITS);
//         return keyGenerator.generateKey(EncryptionConstants.AES_CIPHER);
//     }
// }
// 
// Path: AndroidVault/vault/src/main/java/com/bottlerocketstudios/vault/salt/PrngSaltGenerator.java
// public class PrngSaltGenerator implements SaltGenerator {
// 
//     SecureRandom mSecureRandom;
// 
//     public PrngSaltGenerator() {
//         mSecureRandom = new SecureRandom();
//     }
// 
//     @Override
//     public byte[] createSaltBytes(int size) {
//         byte[] result = new byte[size];
//         mSecureRandom.nextBytes(result);
//         return result;
//     }
// }


import android.os.Build;
import android.test.AndroidTestCase;
import android.util.Log;
import com.bottlerocketstudios.vault.EncryptionConstants;
import com.bottlerocketstudios.vault.keys.generator.Aes256RandomKeyFactory;
import com.bottlerocketstudios.vault.salt.PrngSaltGenerator;
import java.security.GeneralSecurityException;
import java.util.Arrays;
import javax.crypto.SecretKey;
            SecretKey originalKey = Aes256RandomKeyFactory.createKey();
            KeyStorage keyStorageOld = getKeyStorage(Build.VERSION_CODES.JELLY_BEAN);
            assertEquals("Incorrect KeyStorageType", KeyStorageType.OBFUSCATED, keyStorageOld.getKeyStorageType());
            keyStorageOld.clearKey(getContext());
            keyStorageOld.saveKey(getContext(), originalKey);

            SecretKey originalReadKey = keyStorageOld.loadKey(getContext());
            assertNotNull("Key was null after creation and read from old storage.", originalReadKey);
            assertTrue("Keys were not identical after creation and read from old storage", Arrays.equals(originalKey.getEncoded(), originalReadKey.getEncoded()));

            KeyStorage keyStorageNew = getKeyStorage(Build.VERSION_CODES.JELLY_BEAN_MR2);
            assertEquals("Incorrect KeyStorageType", KeyStorageType.ANDROID_KEYSTORE, keyStorageNew.getKeyStorageType());
            SecretKey upgradedKey = keyStorageNew.loadKey(getContext());
            assertNotNull("Key was null after upgrade.", upgradedKey);
            assertTrue("Keys were not identical after upgrade", Arrays.equals(originalKey.getEncoded(), upgradedKey.getEncoded()));

            KeyStorage keyStorageRead = getKeyStorage(Build.VERSION_CODES.JELLY_BEAN_MR2);
            assertEquals("Incorrect KeyStorageType", KeyStorageType.ANDROID_KEYSTORE, keyStorageRead.getKeyStorageType());
            SecretKey upgradedReadKey = keyStorageRead.loadKey(getContext());
            assertNotNull("Key was null after upgrade and read from storage.", upgradedReadKey);
            assertTrue("Keys were not identical after upgrade and read from storage", Arrays.equals(originalKey.getEncoded(), upgradedReadKey.getEncoded()));

        } catch (GeneralSecurityException e) {
            Log.e(TAG, "Caught java.security.GeneralSecurityException", e);
            assertTrue("Exception when creating keystores", false);
        }

    }

    private KeyStorage getKeyStorage(int sdkInt) throws GeneralSecurityException {
// Path: AndroidVault/vault/src/main/java/com/bottlerocketstudios/vault/EncryptionConstants.java
// public class EncryptionConstants {
//     public static final String AES_CIPHER = "AES";
//     public static final String BLOCK_MODE_CBC = "CBC";
//     public static final String ENCRYPTION_PADDING_PKCS5 = "PKCS5Padding";
//     public static final String ENCRYPTION_PADDING_PKCS7 = "PKCS7Padding";
// 
//     /**
//       * While this specifies PKCS5Padding and a 256 bit key, a historical artifact in the Sun encryption
//       * implementation interprets PKCS5 to be PKCS7 for block sizes over 8 bytes. In Android M this
//       * appears to have been corrected so that PKCS7Padding will work when instantiating a Cipher object.
//       */
//     public static final String AES_CBC_PADDED_TRANSFORM = AES_CIPHER + "/" + BLOCK_MODE_CBC + "/" + ENCRYPTION_PADDING_PKCS5;
//     public static final String AES_CBC_PADDED_TRANSFORM_ANDROID_M = AES_CIPHER + "/" + BLOCK_MODE_CBC + "/" + ENCRYPTION_PADDING_PKCS7;
//     public static final int AES_256_KEY_LENGTH_BITS = 256;
// 
//     public static final String DIGEST_SHA256 = "SHA256";
// 
//     public static final String ANDROID_KEY_STORE = "AndroidKeyStore";
// }
// 
// Path: AndroidVault/vault/src/main/java/com/bottlerocketstudios/vault/keys/generator/Aes256RandomKeyFactory.java
// public class Aes256RandomKeyFactory {
// 
//     /**
//      * Create a randomly generated AES256 key.
//      */
//     public static SecretKey createKey() {
//         RandomKeyGenerator keyGenerator = new RandomKeyGenerator(new PrngSaltGenerator(), EncryptionConstants.AES_256_KEY_LENGTH_BITS);
//         return keyGenerator.generateKey(EncryptionConstants.AES_CIPHER);
//     }
// }
// 
// Path: AndroidVault/vault/src/main/java/com/bottlerocketstudios/vault/salt/PrngSaltGenerator.java
// public class PrngSaltGenerator implements SaltGenerator {
// 
//     SecureRandom mSecureRandom;
// 
//     public PrngSaltGenerator() {
//         mSecureRandom = new SecureRandom();
//     }
// 
//     @Override
//     public byte[] createSaltBytes(int size) {
//         byte[] result = new byte[size];
//         mSecureRandom.nextBytes(result);
//         return result;
//     }
// }


// Path: AndroidVault/vault/src/androidTest/java/com/bottlerocketstudios/vault/keys/storage/TestVaultUpgradePre18.java
import android.os.Build;
import android.test.AndroidTestCase;
import android.util.Log;
import com.bottlerocketstudios.vault.EncryptionConstants;
import com.bottlerocketstudios.vault.keys.generator.Aes256RandomKeyFactory;
import com.bottlerocketstudios.vault.salt.PrngSaltGenerator;
import java.security.GeneralSecurityException;
import java.util.Arrays;
import javax.crypto.SecretKey;

            SecretKey originalKey = Aes256RandomKeyFactory.createKey();
            KeyStorage keyStorageOld = getKeyStorage(Build.VERSION_CODES.JELLY_BEAN);
            assertEquals("Incorrect KeyStorageType", KeyStorageType.OBFUSCATED, keyStorageOld.getKeyStorageType());
            keyStorageOld.clearKey(getContext());
            keyStorageOld.saveKey(getContext(), originalKey);

            SecretKey originalReadKey = keyStorageOld.loadKey(getContext());
            assertNotNull("Key was null after creation and read from old storage.", originalReadKey);
            assertTrue("Keys were not identical after creation and read from old storage", Arrays.equals(originalKey.getEncoded(), originalReadKey.getEncoded()));

            KeyStorage keyStorageNew = getKeyStorage(Build.VERSION_CODES.JELLY_BEAN_MR2);
            assertEquals("Incorrect KeyStorageType", KeyStorageType.ANDROID_KEYSTORE, keyStorageNew.getKeyStorageType());
            SecretKey upgradedKey = keyStorageNew.loadKey(getContext());
            assertNotNull("Key was null after upgrade.", upgradedKey);
            assertTrue("Keys were not identical after upgrade", Arrays.equals(originalKey.getEncoded(), upgradedKey.getEncoded()));

            KeyStorage keyStorageRead = getKeyStorage(Build.VERSION_CODES.JELLY_BEAN_MR2);
            assertEquals("Incorrect KeyStorageType", KeyStorageType.ANDROID_KEYSTORE, keyStorageRead.getKeyStorageType());
            SecretKey upgradedReadKey = keyStorageRead.loadKey(getContext());
            assertNotNull("Key was null after upgrade and read from storage.", upgradedReadKey);
            assertTrue("Keys were not identical after upgrade and read from storage", Arrays.equals(originalKey.getEncoded(), upgradedReadKey.getEncoded()));

        } catch (GeneralSecurityException e) {
            Log.e(TAG, "Caught java.security.GeneralSecurityException", e);
            assertTrue("Exception when creating keystores", false);
        }

    }

    private KeyStorage getKeyStorage(int sdkInt) throws GeneralSecurityException {
        return CompatSharedPrefKeyStorageFactory.createKeyStorage(