Merge "Fix retreiving characteristics file for grant key" into oc-mr1-dev
diff --git a/keystore/blob.cpp b/keystore/blob.cpp
index a33334e..625d057 100644
--- a/keystore/blob.cpp
+++ b/keystore/blob.cpp
@@ -272,8 +272,9 @@
         return ResponseCode::VALUE_CORRUPTED;
     }
 
-    if ((isEncrypted() || isSuperEncrypted()) && (state != STATE_NO_ERROR)) {
-        return ResponseCode::LOCKED;
+    if ((isEncrypted() || isSuperEncrypted())) {
+        if (state == STATE_LOCKED) return ResponseCode::LOCKED;
+        if (state == STATE_UNINITIALIZED) return ResponseCode::UNINITIALIZED;
     }
 
     if (fileLength < offsetof(blobv3, value)) return ResponseCode::VALUE_CORRUPTED;
diff --git a/keystore/key_store_service.cpp b/keystore/key_store_service.cpp
index 28cff58..310d8e2 100644
--- a/keystore/key_store_service.cpp
+++ b/keystore/key_store_service.cpp
@@ -800,7 +800,26 @@
 
     KeyStoreServiceReturnCode rc =
         mKeyStore->getKeyForName(&keyBlob, name8, targetUid, TYPE_KEYMASTER_10);
-    if (!rc.isOk()) {
+    if (rc == ResponseCode::UNINITIALIZED) {
+        /*
+         * If we fail reading the blob because the master key is missing we try to retrieve the
+         * key characteristics from the characteristics file. This happens when auth-bound
+         * keys are used after a screen lock has been removed by the user.
+         */
+        rc = mKeyStore->getKeyForName(&keyBlob, name8, targetUid, TYPE_KEY_CHARACTERISTICS);
+        if (!rc.isOk()) {
+            return rc;
+        }
+        AuthorizationSet keyCharacteristics;
+        // TODO write one shot stream buffer to avoid copying (twice here)
+        std::string charBuffer(reinterpret_cast<const char*>(keyBlob.getValue()),
+                               keyBlob.getLength());
+        std::stringstream charStream(charBuffer);
+        keyCharacteristics.Deserialize(&charStream);
+
+        outCharacteristics->softwareEnforced = keyCharacteristics.hidl_data();
+        return rc;
+    } else if (!rc.isOk()) {
         return rc;
     }
 
@@ -1078,7 +1097,10 @@
     // If per-operation auth is needed we need to begin the operation and
     // the client will need to authorize that operation before calling
     // update. Any other auth issues stop here.
-    if (!authResult.isOk() && authResult != ResponseCode::OP_AUTH_NEEDED) return;
+    if (!authResult.isOk() && authResult != ResponseCode::OP_AUTH_NEEDED) {
+        result->resultCode = authResult;
+        return;
+    }
 
     addAuthTokenToParams(&opParams, authToken);
 
diff --git a/keystore/keystore.cpp b/keystore/keystore.cpp
index a5d482e..8037335 100644
--- a/keystore/keystore.cpp
+++ b/keystore/keystore.cpp
@@ -505,7 +505,7 @@
     uid_t userId = get_user_id(uid);
 
     ResponseCode responseCode = get(filepath8.string(), keyBlob, type, userId);
-    if (responseCode == ResponseCode::NO_ERROR) {
+    if (responseCode != ResponseCode::KEY_NOT_FOUND) {
         return responseCode;
     }