// 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";
// }


import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyProperties;
import android.util.Log;
import com.bottlerocketstudios.vault.EncryptionConstants;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
/*
 * Copyright (c) 2016. Bottle Rocket LLC
 * Licensed 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 com.bottlerocketstudios.vault.keys.storage;





/**
 * Use Android Keystore to keep the SecretKey. Requires user authentication to be enabled and
 * requires re-authentication at specified intervals.
 */
public class KeychainAuthenticatedKeyStorage implements KeyStorage {
    private static final String TAG = KeychainAuthenticatedKeyStorage.class.getSimpleName();

    private final String mKeyAlias;
    private final String mAlgorithm;
    private final String mBlockMode;
    private final String mPadding;
    private final int mAuthDurationSeconds;

    private final String mKeyLock = "keyLock";

    public KeychainAuthenticatedKeyStorage(String keyAlias, String algorithm, String blockMode, String padding, int authDurationSeconds) {
        mKeyAlias = keyAlias;
        mAlgorithm = algorithm;
        mBlockMode = blockMode;
        mPadding = padding;
        mAuthDurationSeconds = authDurationSeconds;
    }

    @Override
    public SecretKey loadKey(Context context) {
        SecretKey secretKey = null;
        synchronized (mKeyLock) {
            try {
// 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/storage/KeychainAuthenticatedKeyStorage.java
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyProperties;
import android.util.Log;
import com.bottlerocketstudios.vault.EncryptionConstants;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;

/*
 * Copyright (c) 2016. Bottle Rocket LLC
 * Licensed 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 com.bottlerocketstudios.vault.keys.storage;





/**
 * Use Android Keystore to keep the SecretKey. Requires user authentication to be enabled and
 * requires re-authentication at specified intervals.
 */
public class KeychainAuthenticatedKeyStorage implements KeyStorage {
    private static final String TAG = KeychainAuthenticatedKeyStorage.class.getSimpleName();

    private final String mKeyAlias;
    private final String mAlgorithm;
    private final String mBlockMode;
    private final String mPadding;
    private final int mAuthDurationSeconds;

    private final String mKeyLock = "keyLock";

    public KeychainAuthenticatedKeyStorage(String keyAlias, String algorithm, String blockMode, String padding, int authDurationSeconds) {
        mKeyAlias = keyAlias;
        mAlgorithm = algorithm;
        mBlockMode = blockMode;
        mPadding = padding;
        mAuthDurationSeconds = authDurationSeconds;
    }

    @Override
    public SecretKey loadKey(Context context) {
        SecretKey secretKey = null;
        synchronized (mKeyLock) {
            try {
                KeyStore keyStore = KeyStore.getInstance(EncryptionConstants.ANDROID_KEY_STORE);