Revert "Add another purchase button that uses a key which isn't invalidated even if a new fingerprint is enrolled."

This reverts commit 8b0db26f323429174a9362ef294a6fa0855ff7ef.

Change-Id: Icec966eed10886fd15641ddcbcd981e25474f5ac
diff --git a/security/FingerprintDialog/Application/src/main/java/com/example/android/fingerprintdialog/FingerprintAuthenticationDialogFragment.java b/security/FingerprintDialog/Application/src/main/java/com/example/android/fingerprintdialog/FingerprintAuthenticationDialogFragment.java
index 0537573..cb240db 100644
--- a/security/FingerprintDialog/Application/src/main/java/com/example/android/fingerprintdialog/FingerprintAuthenticationDialogFragment.java
+++ b/security/FingerprintDialog/Application/src/main/java/com/example/android/fingerprintdialog/FingerprintAuthenticationDialogFragment.java
@@ -181,12 +181,12 @@
 
             if (mUseFingerprintFutureCheckBox.isChecked()) {
                 // Re-create the key so that fingerprints including new ones are validated.
-                mActivity.createKey(MainActivity.DEFAULT_KEY_NAME, true);
+                mActivity.createKey();
                 mStage = Stage.FINGERPRINT;
             }
         }
         mPassword.setText("");
-        mActivity.onPurchased(false /* without Fingerprint */, null);
+        mActivity.onPurchased(false /* without Fingerprint */);
         dismiss();
     }
 
@@ -243,7 +243,7 @@
     public void onAuthenticated() {
         // Callback from FingerprintUiHelper. Let the activity know that authentication was
         // successful.
-        mActivity.onPurchased(true /* withFingerprint */, mCryptoObject);
+        mActivity.onPurchased(true /* withFingerprint */);
         dismiss();
     }
 
diff --git a/security/FingerprintDialog/Application/src/main/java/com/example/android/fingerprintdialog/MainActivity.java b/security/FingerprintDialog/Application/src/main/java/com/example/android/fingerprintdialog/MainActivity.java
index 400b2d6..77c8788 100644
--- a/security/FingerprintDialog/Application/src/main/java/com/example/android/fingerprintdialog/MainActivity.java
+++ b/security/FingerprintDialog/Application/src/main/java/com/example/android/fingerprintdialog/MainActivity.java
@@ -21,13 +21,11 @@
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.hardware.fingerprint.FingerprintManager;
-import android.os.Build;
 import android.os.Bundle;
 import android.preference.PreferenceManager;
 import android.security.keystore.KeyGenParameterSpec;
 import android.security.keystore.KeyPermanentlyInvalidatedException;
 import android.security.keystore.KeyProperties;
-import android.support.annotation.Nullable;
 import android.util.Base64;
 import android.util.Log;
 import android.view.Menu;
@@ -63,11 +61,12 @@
 
     private static final String DIALOG_FRAGMENT_TAG = "myFragment";
     private static final String SECRET_MESSAGE = "Very secret message";
-    private static final String KEY_NAME_NOT_INVALIDATED = "key_not_invalidated";
-    static final String DEFAULT_KEY_NAME = "default_key";
+    /** Alias for our key in the Android Key Store */
+    private static final String KEY_NAME = "my_key";
 
     private KeyStore mKeyStore;
     private KeyGenerator mKeyGenerator;
+    private Cipher mCipher;
     private SharedPreferences mSharedPreferences;
 
     @Override
@@ -86,13 +85,8 @@
         } catch (NoSuchAlgorithmException | NoSuchProviderException e) {
             throw new RuntimeException("Failed to get an instance of KeyGenerator", e);
         }
-        Cipher defaultCipher;
-        Cipher cipherNotInvalidated;
         try {
-            defaultCipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
-                    + KeyProperties.BLOCK_MODE_CBC + "/"
-                    + KeyProperties.ENCRYPTION_PADDING_PKCS7);
-            cipherNotInvalidated = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
+            mCipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
                     + KeyProperties.BLOCK_MODE_CBC + "/"
                     + KeyProperties.ENCRYPTION_PADDING_PKCS7);
         } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
@@ -103,22 +97,6 @@
         KeyguardManager keyguardManager = getSystemService(KeyguardManager.class);
         FingerprintManager fingerprintManager = getSystemService(FingerprintManager.class);
         Button purchaseButton = (Button) findViewById(R.id.purchase_button);
-        Button purchaseButtonNotInvalidated = (Button) findViewById(
-                R.id.purchase_button_not_invalidated);
-
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
-            purchaseButtonNotInvalidated.setEnabled(true);
-            purchaseButtonNotInvalidated.setOnClickListener(
-                    new PurchaseButtonClickListener(cipherNotInvalidated,
-                            KEY_NAME_NOT_INVALIDATED));
-        } else {
-            // Hide the purchase button which uses a non-invalidated key
-            // if the app doesn't work on Android N preview
-            purchaseButtonNotInvalidated.setVisibility(View.GONE);
-            findViewById(R.id.purchase_button_not_invalidated_description)
-                    .setVisibility(View.GONE);
-        }
-
         if (!keyguardManager.isKeyguardSecure()) {
             // Show a message that the user hasn't set up a fingerprint or lock screen.
             Toast.makeText(this,
@@ -126,7 +104,6 @@
                             + "Go to 'Settings -> Security -> Fingerprint' to set up a fingerprint",
                     Toast.LENGTH_LONG).show();
             purchaseButton.setEnabled(false);
-            purchaseButtonNotInvalidated.setEnabled(false);
             return;
         }
 
@@ -142,27 +119,62 @@
                     Toast.LENGTH_LONG).show();
             return;
         }
-        createKey(DEFAULT_KEY_NAME, true);
-        createKey(KEY_NAME_NOT_INVALIDATED, false);
+        createKey();
         purchaseButton.setEnabled(true);
-        purchaseButton.setOnClickListener(
-                new PurchaseButtonClickListener(defaultCipher, DEFAULT_KEY_NAME));
+        purchaseButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                findViewById(R.id.confirmation_message).setVisibility(View.GONE);
+                findViewById(R.id.encrypted_message).setVisibility(View.GONE);
+
+                // Set up the crypto object for later. The object will be authenticated by use
+                // of the fingerprint.
+                if (initCipher()) {
+                    // Show the fingerprint dialog. The user has the option to use the fingerprint
+                    // with crypto, or you can fall back to using a server-side verified password.
+                    FingerprintAuthenticationDialogFragment fragment
+                            = new FingerprintAuthenticationDialogFragment();
+                    fragment.setCryptoObject(new FingerprintManager.CryptoObject(mCipher));
+                    boolean useFingerprintPreference = mSharedPreferences
+                            .getBoolean(getString(R.string.use_fingerprint_to_authenticate_key),
+                                    true);
+                    if (useFingerprintPreference) {
+                        fragment.setStage(
+                                FingerprintAuthenticationDialogFragment.Stage.FINGERPRINT);
+                    } else {
+                        fragment.setStage(
+                                FingerprintAuthenticationDialogFragment.Stage.PASSWORD);
+                    }
+                    fragment.show(getFragmentManager(), DIALOG_FRAGMENT_TAG);
+                } else {
+                    // This happens if the lock screen has been disabled or or a fingerprint got
+                    // enrolled. Thus show the dialog to authenticate with their password first
+                    // and ask the user if they want to authenticate with fingerprints in the
+                    // future
+                    FingerprintAuthenticationDialogFragment fragment
+                            = new FingerprintAuthenticationDialogFragment();
+                    fragment.setCryptoObject(new FingerprintManager.CryptoObject(mCipher));
+                    fragment.setStage(
+                            FingerprintAuthenticationDialogFragment.Stage.NEW_FINGERPRINT_ENROLLED);
+                    fragment.show(getFragmentManager(), DIALOG_FRAGMENT_TAG);
+                }
+            }
+        });
     }
 
     /**
-     * Initialize the {@link Cipher} instance with the created key in the
-     * {@link #createKey(String, boolean)} method.
+     * Initialize the {@link Cipher} instance with the created key in the {@link #createKey()}
+     * method.
      *
-     * @param keyName the key name to init the cipher
      * @return {@code true} if initialization is successful, {@code false} if the lock screen has
      * been disabled or reset after the key was generated, or if a fingerprint got enrolled after
      * the key was generated.
      */
-    private boolean initCipher(Cipher cipher, String keyName) {
+    private boolean initCipher() {
         try {
             mKeyStore.load(null);
-            SecretKey key = (SecretKey) mKeyStore.getKey(keyName, null);
-            cipher.init(Cipher.ENCRYPT_MODE, key);
+            SecretKey key = (SecretKey) mKeyStore.getKey(KEY_NAME, null);
+            mCipher.init(Cipher.ENCRYPT_MODE, key);
             return true;
         } catch (KeyPermanentlyInvalidatedException e) {
             return false;
@@ -172,19 +184,11 @@
         }
     }
 
-    /**
-     * Proceed the purchase operation
-     *
-     * @param withFingerprint {@code true} if the purchase was made by using a fingerprint
-     * @param cryptoObject the Crypto object
-     */
-    public void onPurchased(boolean withFingerprint,
-            @Nullable FingerprintManager.CryptoObject cryptoObject) {
+    public void onPurchased(boolean withFingerprint) {
         if (withFingerprint) {
             // If the user has authenticated with fingerprint, verify that using cryptography and
             // then show the confirmation message.
-            assert cryptoObject != null;
-            tryEncrypt(cryptoObject.getCipher());
+            tryEncrypt();
         } else {
             // Authentication happened with backup password. Just show the confirmation message.
             showConfirmation(null);
@@ -205,9 +209,9 @@
      * Tries to encrypt some data with the generated key in {@link #createKey} which is
      * only works if the user has just authenticated via fingerprint.
      */
-    private void tryEncrypt(Cipher cipher) {
+    private void tryEncrypt() {
         try {
-            byte[] encrypted = cipher.doFinal(SECRET_MESSAGE.getBytes());
+            byte[] encrypted = mCipher.doFinal(SECRET_MESSAGE.getBytes());
             showConfirmation(encrypted);
         } catch (BadPaddingException | IllegalBlockSizeException e) {
             Toast.makeText(this, "Failed to encrypt the data with the generated key. "
@@ -219,18 +223,8 @@
     /**
      * Creates a symmetric key in the Android Key Store which can only be used after the user has
      * authenticated with fingerprint.
-     *
-     * @param keyName the name of the key to be created
-     * @param invalidatedByBiometricEnrollment if {@code false} is passed, the created key will not
-     *                                         be invalidated even if a new fingerprint is enrolled.
-     *                                         The default value is {@code true}, so passing
-     *                                         {@code true} doesn't change the behavior
-     *                                         (the key will be invalidated if a new fingerprint is
-     *                                         enrolled.). Note that this parameter is only valid if
-     *                                         the app works on Android N developer preview.
-     *
      */
-    public void createKey(String keyName, boolean invalidatedByBiometricEnrollment) {
+    public void createKey() {
         // The enrolling flow for fingerprint. This is where you ask the user to set up fingerprint
         // for your flow. Use of keys is necessary if you need to know if the set of
         // enrolled fingerprints has changed.
@@ -238,25 +232,15 @@
             mKeyStore.load(null);
             // Set the alias of the entry in Android KeyStore where the key will appear
             // and the constrains (purposes) in the constructor of the Builder
-
-            KeyGenParameterSpec.Builder builder = new KeyGenParameterSpec.Builder(keyName,
+            mKeyGenerator.init(new KeyGenParameterSpec.Builder(KEY_NAME,
                     KeyProperties.PURPOSE_ENCRYPT |
                             KeyProperties.PURPOSE_DECRYPT)
                     .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
                     // Require the user to authenticate with a fingerprint to authorize every use
                     // of the key
                     .setUserAuthenticationRequired(true)
-                    .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7);
-
-            // This is a workaround to avoid crashes on devices whose API level is < 24
-            // because KeyGenParameterSpec.Builder#setInvalidatedByBiometricEnrollment is only
-            // visible on API level +24.
-            // Ideally there should be a compat library for KeyGenParameterSpec.Builder but
-            // which isn't available yet.
-            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
-                builder.setInvalidatedByBiometricEnrollment(invalidatedByBiometricEnrollment);
-            }
-            mKeyGenerator.init(builder.build());
+                    .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
+                    .build());
             mKeyGenerator.generateKey();
         } catch (NoSuchAlgorithmException | InvalidAlgorithmParameterException
                 | CertificateException | IOException e) {
@@ -281,54 +265,4 @@
         }
         return super.onOptionsItemSelected(item);
     }
-
-    private class PurchaseButtonClickListener implements View.OnClickListener {
-
-        Cipher mCipher;
-        String mKeyName;
-
-        PurchaseButtonClickListener(Cipher cipher, String keyName) {
-            mCipher = cipher;
-            mKeyName = keyName;
-        }
-
-        @Override
-        public void onClick(View view) {
-            findViewById(R.id.confirmation_message).setVisibility(View.GONE);
-            findViewById(R.id.encrypted_message).setVisibility(View.GONE);
-
-            // Set up the crypto object for later. The object will be authenticated by use
-            // of the fingerprint.
-            if (initCipher(mCipher, mKeyName)) {
-
-                // Show the fingerprint dialog. The user has the option to use the fingerprint with
-                // crypto, or you can fall back to using a server-side verified password.
-                FingerprintAuthenticationDialogFragment fragment
-                        = new FingerprintAuthenticationDialogFragment();
-                fragment.setCryptoObject(new FingerprintManager.CryptoObject(mCipher));
-                boolean useFingerprintPreference = mSharedPreferences
-                        .getBoolean(getString(R.string.use_fingerprint_to_authenticate_key),
-                                true);
-                if (useFingerprintPreference) {
-                    fragment.setStage(
-                            FingerprintAuthenticationDialogFragment.Stage.FINGERPRINT);
-                } else {
-                    fragment.setStage(
-                            FingerprintAuthenticationDialogFragment.Stage.PASSWORD);
-                }
-                fragment.show(getFragmentManager(), DIALOG_FRAGMENT_TAG);
-            } else {
-                // This happens if the lock screen has been disabled or or a fingerprint got
-                // enrolled. Thus show the dialog to authenticate with their password first
-                // and ask the user if they want to authenticate with fingerprints in the
-                // future
-                FingerprintAuthenticationDialogFragment fragment
-                        = new FingerprintAuthenticationDialogFragment();
-                fragment.setCryptoObject(new FingerprintManager.CryptoObject(mCipher));
-                fragment.setStage(
-                        FingerprintAuthenticationDialogFragment.Stage.NEW_FINGERPRINT_ENROLLED);
-                fragment.show(getFragmentManager(), DIALOG_FRAGMENT_TAG);
-            }
-        }
-    }
 }
diff --git a/security/FingerprintDialog/Application/src/main/res/layout/activity_main.xml b/security/FingerprintDialog/Application/src/main/res/layout/activity_main.xml
index 075899f..8f30557 100644
--- a/security/FingerprintDialog/Application/src/main/res/layout/activity_main.xml
+++ b/security/FingerprintDialog/Application/src/main/res/layout/activity_main.xml
@@ -77,27 +77,8 @@
                 android:layout_gravity="end"
                 android:textColor="?android:attr/textColorPrimaryInverse"
                 android:text="@string/purchase"
-                android:id="@+id/purchase_button" />
-
-        <Button style="@android:style/Widget.Material.Button.Colored"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginTop="8dp"
-            android:layout_marginEnd="4dp"
-            android:layout_gravity="end"
-            android:textColor="?android:attr/textColorPrimaryInverse"
-            android:text="@string/purchase_not_invalidated"
-            android:id="@+id/purchase_button_not_invalidated" />
-
-        <TextView
-            android:id="@+id/purchase_button_not_invalidated_description"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_marginEnd="4dp"
-            android:gravity="end"
-            android:textAlignment="gravity"
-            android:text="@string/purchase_button_not_invalidated_description"
-            />
+                android:id="@+id/purchase_button"
+                android:layout_alignParentEnd="true"/>
 
         <TextView
                 android:id="@+id/confirmation_message"
diff --git a/security/FingerprintDialog/Application/src/main/res/values/strings.xml b/security/FingerprintDialog/Application/src/main/res/values/strings.xml
index 86f200c..77d1176 100644
--- a/security/FingerprintDialog/Application/src/main/res/values/strings.xml
+++ b/security/FingerprintDialog/Application/src/main/res/values/strings.xml
@@ -31,10 +31,6 @@
     <string name="fingerprint_hint">Touch sensor</string>
     <string name="password_description">Enter your store password to continue</string>
     <string name="purchase">Purchase</string>
-    <string name="purchase_not_invalidated">Purchase not invalidated</string>
-    <string name="purchase_button_not_invalidated_description">
-        You can proceed to purchase with this button \n even if a new fingerprint is enrolled
-    </string>
     <string name="fingerprint_not_recognized">Fingerprint not recognized. Try again</string>
     <string name="fingerprint_success">Fingerprint recognized</string>
     <string name="item_title">White Mesh Pluto Backpack</string>
diff --git a/security/FingerprintDialog/template-params.xml b/security/FingerprintDialog/template-params.xml
index 7818492..c13a82f 100644
--- a/security/FingerprintDialog/template-params.xml
+++ b/security/FingerprintDialog/template-params.xml
@@ -25,8 +25,6 @@
     <package>com.example.android.fingerprintdialog</package>
 
     <minSdk>23</minSdk>
-    <targetSdkVersion>24</targetSdkVersion>
-    <compileSdkVersion>24</compileSdkVersion>
 
     <strings>
         <intro>