keystore: fix upgrades

During an upgrade, a blob would be written out to disk. Whenever a blob
is written to disk, it is encrypted in-place. After upgrade, keystore
would attempt to use the blob, but get garbage instead of what it
expected since it was encrypted.

This moves the work of writing up a level so it can then re-read the
blob after upgrade.

Bug: 7249554
Change-Id: I3946c5db1c2fc57ace476db04f792e3b82d1cb15
diff --git a/keystore/keystore.cpp b/keystore/keystore.cpp
index a413948..fdbea3d 100644
--- a/keystore/keystore.cpp
+++ b/keystore/keystore.cpp
@@ -681,7 +681,16 @@
 
         const uint8_t version = keyBlob->getVersion();
         if (version < CURRENT_BLOB_VERSION) {
-            upgrade(filename, keyBlob, version, type);
+            /* If we upgrade the key, we need to write it to disk again. Then
+             * it must be read it again since the blob is encrypted each time
+             * it's written.
+             */
+            if (upgrade(filename, keyBlob, version, type)) {
+                if ((rc = this->put(filename, keyBlob)) != NO_ERROR
+                        || (rc = keyBlob->readBlob(filename, &mMasterKeyDecryption)) != NO_ERROR) {
+                    return rc;
+                }
+            }
         }
 
         if (type != TYPE_ANY && keyBlob->getType() != type) {
@@ -846,7 +855,7 @@
      * Upgrade code. This will upgrade the key from the current version
      * to whatever is newest.
      */
-    void upgrade(const char* filename, Blob* blob, const uint8_t oldVersion, const BlobType type) {
+    bool upgrade(const char* filename, Blob* blob, const uint8_t oldVersion, const BlobType type) {
         bool updated = false;
         uint8_t version = oldVersion;
 
@@ -865,12 +874,13 @@
         /*
          * If we've updated, set the key blob to the right version
          * and write it.
-         * */
+         */
         if (updated) {
             ALOGV("updated and writing file %s", filename);
             blob->setVersion(version);
-            this->put(filename, blob);
         }
+
+        return updated;
     }
 
     /**