credstore: Pass additional information to Identity Credential HAL.

Without this extra information passed upfront it's not practical to
implement a HAL which incrementally builds up cryptographically
authenticated data.

This information is conveyed by using two new methods on version 2 of
the Identity Credential HAL. If these methods are not implemented (if
a version 1 HAL is running) the invocation fails and we handle this
gracefully by just ignoring the error.

Bug: 154631410
Test: atest VtsHalIdentityTargetTest
Test: atest android.security.identity.cts

Change-Id: I17d516e41e800f58daa4c11dcca0305c80740d5b
diff --git a/identity/Credential.cpp b/identity/Credential.cpp
index 05c31d3..49b412f 100644
--- a/identity/Credential.cpp
+++ b/identity/Credential.cpp
@@ -261,7 +261,35 @@
         signingKeyBlob = authKey->keyBlob;
     }
 
-    Status status =
+    // Pass the HAL enough information to allow calculating the size of
+    // DeviceNameSpaces ahead of time.
+    vector<RequestNamespace> halRequestNamespaces;
+    for (const RequestNamespaceParcel& rns : requestNamespaces) {
+        RequestNamespace ns;
+        ns.namespaceName = rns.namespaceName;
+        for (const RequestEntryParcel& rep : rns.entries) {
+            optional<EntryData> entryData = data_->getEntryData(rns.namespaceName, rep.name);
+            if (entryData) {
+                RequestDataItem di;
+                di.name = rep.name;
+                di.size = entryData.value().size;
+                di.accessControlProfileIds = entryData.value().accessControlProfileIds;
+                ns.items.push_back(di);
+            }
+        }
+        if (ns.items.size() > 0) {
+            halRequestNamespaces.push_back(ns);
+        }
+    }
+    // This is not catastrophic, we might be dealing with a version 1 implementation which
+    // doesn't have this method.
+    Status status = halBinder_->setRequestedNamespaces(halRequestNamespaces);
+    if (!status.isOk()) {
+        LOG(INFO) << "Failed setting expected requested namespaces assuming V1 HAL "
+                  << "and continuing";
+    }
+
+    status =
         halBinder_->startRetrieval(selectedProfiles, aidlAuthToken, requestMessage, signingKeyBlob,
                                    sessionTranscript, readerSignature, requestCounts);
     if (!status.isOk() && status.exceptionCode() == binder::Status::EX_SERVICE_SPECIFIC) {