|
@@ -23,33 +23,10 @@ package com.owncloud.android.utils;
|
|
|
import android.app.KeyguardManager;
|
|
|
import android.content.Context;
|
|
|
import android.os.Build;
|
|
|
-import android.security.keystore.KeyGenParameterSpec;
|
|
|
-import android.security.keystore.KeyProperties;
|
|
|
import android.support.annotation.RequiresApi;
|
|
|
|
|
|
-import com.owncloud.android.R;
|
|
|
import com.owncloud.android.lib.common.utils.Log_OC;
|
|
|
|
|
|
-import java.io.IOException;
|
|
|
-import java.nio.ByteBuffer;
|
|
|
-import java.nio.IntBuffer;
|
|
|
-import java.security.InvalidAlgorithmParameterException;
|
|
|
-import java.security.InvalidKeyException;
|
|
|
-import java.security.KeyStore;
|
|
|
-import java.security.KeyStoreException;
|
|
|
-import java.security.NoSuchAlgorithmException;
|
|
|
-import java.security.NoSuchProviderException;
|
|
|
-import java.security.ProviderException;
|
|
|
-import java.security.UnrecoverableKeyException;
|
|
|
-import java.security.cert.CertificateException;
|
|
|
-
|
|
|
-import javax.crypto.BadPaddingException;
|
|
|
-import javax.crypto.Cipher;
|
|
|
-import javax.crypto.IllegalBlockSizeException;
|
|
|
-import javax.crypto.KeyGenerator;
|
|
|
-import javax.crypto.NoSuchPaddingException;
|
|
|
-import javax.crypto.SecretKey;
|
|
|
-
|
|
|
/**
|
|
|
* Utility class with methods for handling device credentials.
|
|
|
*/
|
|
@@ -68,7 +45,7 @@ public final class DeviceCredentialUtils {
|
|
|
|
|
|
public static boolean areCredentialsAvailable(Context context) {
|
|
|
KeyguardManager keyguardManager = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
|
|
|
-
|
|
|
+
|
|
|
if (keyguardManager != null) {
|
|
|
return keyguardManager.isKeyguardSecure();
|
|
|
} else {
|
|
@@ -76,66 +53,4 @@ public final class DeviceCredentialUtils {
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- /**
|
|
|
- * Creates a symmetric key in the Android Key Store which can only be used after the user has
|
|
|
- * authenticated with device credentials within the last X seconds.
|
|
|
- */
|
|
|
- public static void createKey(Context context) {
|
|
|
- // Generate a key to decrypt payment credentials, tokens, etc.
|
|
|
- final String keyName = context.getResources().getString(R.string.secret_key_name);
|
|
|
- try {
|
|
|
- KeyStore keyStore = KeyStore.getInstance(ANDROID_KEY_STORE);
|
|
|
- keyStore.load(null);
|
|
|
- KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, ANDROID_KEY_STORE);
|
|
|
-
|
|
|
- // Set the alias of the entry in Android KeyStore where the key will appear
|
|
|
- // and the constrains (purposes) in the constructor of the Builder
|
|
|
- keyGenerator.init(new KeyGenParameterSpec.Builder(keyName, KeyProperties.PURPOSE_ENCRYPT |
|
|
|
- KeyProperties.PURPOSE_DECRYPT)
|
|
|
- .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
|
|
|
- .setUserAuthenticationRequired(true)
|
|
|
- // Require that the user has unlocked in the last 30 seconds
|
|
|
- .setUserAuthenticationValidityDurationSeconds(AUTHENTICATION_DURATION_SECONDS)
|
|
|
- .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
|
|
|
- .build());
|
|
|
- keyGenerator.generateKey();
|
|
|
- } catch (NoSuchAlgorithmException | NoSuchProviderException
|
|
|
- | InvalidAlgorithmParameterException | KeyStoreException
|
|
|
- | CertificateException | ProviderException | IOException e) {
|
|
|
- Log_OC.e(TAG, "Exception: " + e.getMessage());
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Tries to encrypt some data with the generated key in {@link #createKey} which
|
|
|
- * only works if the user has just authenticated via device credentials.
|
|
|
- */
|
|
|
- public static boolean tryEncrypt(Context context) {
|
|
|
- try {
|
|
|
- final String keyName = context.getResources().getString(R.string.secret_key_name);
|
|
|
- final int[] secretIntArray = context.getResources().getIntArray(R.array.secret_byte_array);
|
|
|
- ByteBuffer byteBuffer = ByteBuffer.allocate(secretIntArray.length * 4);
|
|
|
- IntBuffer intBuffer = byteBuffer.asIntBuffer();
|
|
|
- intBuffer.put(secretIntArray);
|
|
|
- byte[] secretByteArray = byteBuffer.array();
|
|
|
- KeyStore keyStore = KeyStore.getInstance(ANDROID_KEY_STORE);
|
|
|
- keyStore.load(null);
|
|
|
- SecretKey secretKey = (SecretKey) keyStore.getKey(keyName, null);
|
|
|
- Cipher cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/" +
|
|
|
- KeyProperties.BLOCK_MODE_CBC + "/" + KeyProperties.ENCRYPTION_PADDING_PKCS7);
|
|
|
-
|
|
|
- // Try encrypting something, it will only work if the user authenticated within
|
|
|
- // the last AUTHENTICATION_DURATION_SECONDS seconds.
|
|
|
- cipher.init(Cipher.ENCRYPT_MODE, secretKey);
|
|
|
- cipher.doFinal(secretByteArray);
|
|
|
-
|
|
|
- // If the user has recently authenticated, you will reach here.
|
|
|
- return true;
|
|
|
- } catch (BadPaddingException | IllegalBlockSizeException | KeyStoreException |
|
|
|
- CertificateException | UnrecoverableKeyException | IOException
|
|
|
- | NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException e) {
|
|
|
- return false;
|
|
|
- }
|
|
|
- }
|
|
|
}
|