Keystore: Enable key attestation from the system context.

When key attestation is requested by the system context, indicate, in
the attestation record, that the requesting package is the system and
not a user app.
This is done by including a single package information with
"AndroidSystem" as the package name and an empty signature.

This change is needed because the package manager currently fails to
provide package details for the system context (UID 1000). Even if it did,
it would be too verbose and include irrelevant packages.

This is necessary for supporting key attestation for keys generated
directly by KeyChain.

Bug: 63388672
Test: Combined with CTS tests for the attestation feature.
Change-Id: I33492ad1286709fe94b11be77e94d4effdf7566f
diff --git a/keystore/KeyAttestationApplicationId.cpp b/keystore/KeyAttestationApplicationId.cpp
index 1352124..4bc939d 100644
--- a/keystore/KeyAttestationApplicationId.cpp
+++ b/keystore/KeyAttestationApplicationId.cpp
@@ -23,6 +23,14 @@
 namespace security {
 namespace keymaster {
 
+KeyAttestationApplicationId::KeyAttestationApplicationId() = default;
+
+KeyAttestationApplicationId::KeyAttestationApplicationId(
+        std::unique_ptr<KeyAttestationPackageInfo> package) :
+    packageInfos_(new std::vector<std::unique_ptr<KeyAttestationPackageInfo>>()) {
+    packageInfos_->push_back(std::move(package));
+}
+
 status_t KeyAttestationApplicationId::writeToParcel(Parcel* parcel) const {
     return parcel->writeParcelableVector(packageInfos_);
 }
diff --git a/keystore/KeyAttestationPackageInfo.cpp b/keystore/KeyAttestationPackageInfo.cpp
index a84c246..8092828 100644
--- a/keystore/KeyAttestationPackageInfo.cpp
+++ b/keystore/KeyAttestationPackageInfo.cpp
@@ -23,6 +23,15 @@
 namespace security {
 namespace keymaster {
 
+KeyAttestationPackageInfo::KeyAttestationPackageInfo() = default;
+
+KeyAttestationPackageInfo::KeyAttestationPackageInfo(
+        const String16& packageName, int32_t versionCode,
+        SharedSignaturesVector signatures) :
+    packageName_(new String16(packageName)), versionCode_(versionCode),
+    signatures_(signatures) {
+}
+
 status_t KeyAttestationPackageInfo::writeToParcel(Parcel* parcel) const {
     auto rc = parcel->writeString16(packageName_);
     if (rc != NO_ERROR) return rc;
@@ -37,7 +46,7 @@
     rc = parcel->readInt32(&versionCode_);
     if (rc != NO_ERROR) return rc;
 
-    std::unique_ptr<std::vector<std::unique_ptr<content::pm::Signature>>> temp_vector;
+    std::unique_ptr<SignaturesVector> temp_vector;
     rc = parcel->readParcelableVector(&temp_vector);
     if (rc != NO_ERROR) return rc;
     signatures_.reset(temp_vector.release());
diff --git a/keystore/include/keystore/KeyAttestationApplicationId.h b/keystore/include/keystore/KeyAttestationApplicationId.h
index 5161d4b..550a7e1 100644
--- a/keystore/include/keystore/KeyAttestationApplicationId.h
+++ b/keystore/include/keystore/KeyAttestationApplicationId.h
@@ -30,6 +30,8 @@
   public:
     typedef SharedNullableIterator<const KeyAttestationPackageInfo, std::vector>
         ConstKeyAttestationPackageInfoIterator;
+    KeyAttestationApplicationId();
+    KeyAttestationApplicationId(std::unique_ptr<KeyAttestationPackageInfo> package);
 
     status_t writeToParcel(Parcel*) const override;
     status_t readFromParcel(const Parcel* parcel) override;
diff --git a/keystore/include/keystore/KeyAttestationPackageInfo.h b/keystore/include/keystore/KeyAttestationPackageInfo.h
index b938e83..5ca6c8c 100644
--- a/keystore/include/keystore/KeyAttestationPackageInfo.h
+++ b/keystore/include/keystore/KeyAttestationPackageInfo.h
@@ -30,6 +30,13 @@
   public:
     typedef SharedNullableIterator<const content::pm::Signature, std::vector>
         ConstSignatureIterator;
+    typedef std::vector<std::unique_ptr<content::pm::Signature>>
+        SignaturesVector;
+    typedef std::shared_ptr<SignaturesVector> SharedSignaturesVector;
+
+    KeyAttestationPackageInfo(
+        const String16& packageName, int32_t versionCode, SharedSignaturesVector signatures);
+    KeyAttestationPackageInfo();
 
     status_t writeToParcel(Parcel*) const override;
     status_t readFromParcel(const Parcel* parcel) override;
@@ -43,7 +50,7 @@
   private:
     std::unique_ptr<String16> packageName_;
     int32_t versionCode_;
-    std::shared_ptr<std::vector<std::unique_ptr<content::pm::Signature>>> signatures_;
+    SharedSignaturesVector signatures_;
 };
 
 }  // namespace keymaster
diff --git a/keystore/keystore_attestation_id.cpp b/keystore/keystore_attestation_id.cpp
index 830482b..97d81c5 100644
--- a/keystore/keystore_attestation_id.cpp
+++ b/keystore/keystore_attestation_id.cpp
@@ -34,6 +34,8 @@
 #include <keystore/KeyAttestationPackageInfo.h>
 #include <keystore/Signature.h>
 
+#include <private/android_filesystem_config.h> /* for AID_SYSTEM */
+
 #include <openssl/asn1t.h>
 #include <openssl/sha.h>
 
@@ -229,16 +231,28 @@
     auto& pm = KeyAttestationApplicationIdProvider::get();
 
     /* Get the attestation application ID from package manager */
-    KeyAttestationApplicationId key_attestation_id;
-    auto status = pm.getKeyAttestationApplicationId(uid, &key_attestation_id);
-    if (!status.isOk()) {
-        ALOGE("package manager request for key attestation ID failed with: %s",
-              status.exceptionMessage().string());
-        return FAILED_TRANSACTION;
+    KeyAttestationApplicationId* key_attestation_id = nullptr;
+    if (uid == AID_SYSTEM) {
+      KeyAttestationPackageInfo::SharedSignaturesVector signatures(
+                new KeyAttestationPackageInfo::SignaturesVector());
+        signatures->push_back(std::unique_ptr<content::pm::Signature>(
+                new content::pm::Signature()));
+
+        std::unique_ptr<KeyAttestationPackageInfo> package_info(
+                new KeyAttestationPackageInfo(
+                        String16("AndroidSystem"), 1, signatures));
+        key_attestation_id = new KeyAttestationApplicationId(std::move(package_info));
+    } else {
+        auto status = pm.getKeyAttestationApplicationId(uid, key_attestation_id);
+        if (!status.isOk()) {
+            ALOGE("package manager request for key attestation ID failed with: %s %d",
+                  status.exceptionMessage().string(), status.exceptionCode());
+            return FAILED_TRANSACTION;
+        }
     }
 
     /* DER encode the attestation application ID */
-    return build_attestation_application_id(key_attestation_id);
+    return build_attestation_application_id(*key_attestation_id);
 }
 
 }  // namespace security