Merge cherrypicks of [4871059, 4868580, 4869372] into pi-qpr1-release

Change-Id: I9c8f77bf25e97f0f906ea31474f3b492d1dd3a04
diff --git a/src/com/android/keychain/KeyChainService.java b/src/com/android/keychain/KeyChainService.java
index e109d6b..3f17636 100644
--- a/src/com/android/keychain/KeyChainService.java
+++ b/src/com/android/keychain/KeyChainService.java
@@ -182,7 +182,7 @@
                 return KeyChain.KEY_ATTESTATION_MISSING_CHALLENGE;
             }
 
-            final KeymasterArguments attestArgs;
+            KeymasterArguments attestArgs;
             try {
                 attestArgs = AttestationUtils.prepareAttestationArguments(
                         mContext, idAttestationFlags, attestationChallenge);
@@ -190,6 +190,31 @@
                 Log.e(TAG, "Failed collecting attestation data", e);
                 return KeyChain.KEY_ATTESTATION_CANNOT_COLLECT_DATA;
             }
+            int errorCode = checkKeyChainStatus(alias, attestationChain, attestArgs);
+            if (errorCode == KeyChain.KEY_ATTESTATION_CANNOT_ATTEST_IDS) {
+                // b/69471841: id attestation might fail due to incorrect provisioning of device
+                try {
+                    attestArgs =
+                            AttestationUtils.prepareAttestationArgumentsIfMisprovisioned(
+                            mContext, idAttestationFlags, attestationChallenge);
+                    if (attestArgs == null) {
+                        return errorCode;
+                    }
+                } catch (DeviceIdAttestationException e) {
+                    Log.e(TAG, "Failed collecting attestation data "
+                            + "during second attempt on misprovisioned device", e);
+                    return KeyChain.KEY_ATTESTATION_CANNOT_COLLECT_DATA;
+                }
+            }
+
+            return checkKeyChainStatus(alias, attestationChain, attestArgs);
+        }
+
+        private int checkKeyChainStatus(
+                String alias,
+                KeymasterCertificateChain attestationChain,
+                KeymasterArguments attestArgs) {
+
             final String keystoreAlias = Credentials.USER_PRIVATE_KEY + alias;
             final int errorCode = mKeyStore.attestKey(keystoreAlias, attestArgs, attestationChain);
             if (errorCode != KeyStore.NO_ERROR) {