Add attestation application id for key attestation

This patch adds functionality for gathering an application id
for the attestation of a key that is bound to an application
in the keystore.

Keystore gathers the information package name, package version,
and signing certificates of the calling app from the package manager.
It then DER encodes the information and appends it to attestation
parameters.

Bug: 22914603
Change-Id: I9fe1d8f97ee1dfa79284bcf751f86631c94d4174
diff --git a/keystore/.clang-format b/keystore/.clang-format
index 5747e19..b0dc94c 100644
--- a/keystore/.clang-format
+++ b/keystore/.clang-format
@@ -3,7 +3,7 @@
 UseTab: Never
 BreakBeforeBraces: Attach
 AllowShortFunctionsOnASingleLine: Inline
-AllowShortIfStatementsOnASingleLine: false
+AllowShortIfStatementsOnASingleLine: true
 IndentCaseLabels: false
 ColumnLimit: 100
 PointerBindsToType: true
diff --git a/keystore/Android.mk b/keystore/Android.mk
index f17d5eb..1af8b75 100644
--- a/keystore/Android.mk
+++ b/keystore/Android.mk
@@ -32,13 +32,15 @@
 	blob.cpp \
 	entropy.cpp \
 	key_store_service.cpp \
+	keystore_attestation_id.cpp \
 	keyblob_utils.cpp \
 	keystore.cpp \
 	keystore_main.cpp \
 	keystore_utils.cpp \
 	operation.cpp \
 	permissions.cpp \
-	user_state.cpp
+	user_state.cpp \
+	../../../frameworks/base/core/java/android/security/keymaster/IKeyAttestationApplicationIdProvider.aidl
 LOCAL_SHARED_LIBRARIES := \
 	libbinder \
 	libcutils \
@@ -59,6 +61,7 @@
 LOCAL_CLANG := true
 LOCAL_SANITIZE := integer
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+LOCAL_AIDL_INCLUDES := frameworks/base/core/java/
 include $(BUILD_EXECUTABLE)
 
 include $(CLEAR_VARS)
@@ -97,6 +100,9 @@
 LOCAL_CFLAGS := -Wall -Wextra -Werror
 LOCAL_SRC_FILES := \
 	IKeystoreService.cpp \
+	KeyAttestationApplicationId.cpp \
+	KeyAttestationPackageInfo.cpp \
+	Signature.cpp \
 	keyblob_utils.cpp \
 	keystore_client.proto \
 	keystore_client_impl.cpp \
diff --git a/keystore/KeyAttestationApplicationId.cpp b/keystore/KeyAttestationApplicationId.cpp
new file mode 100644
index 0000000..1352124
--- /dev/null
+++ b/keystore/KeyAttestationApplicationId.cpp
@@ -0,0 +1,40 @@
+/*
+**
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#include "include/keystore/KeyAttestationApplicationId.h"
+
+#include <binder/Parcel.h>
+
+namespace android {
+namespace security {
+namespace keymaster {
+
+status_t KeyAttestationApplicationId::writeToParcel(Parcel* parcel) const {
+    return parcel->writeParcelableVector(packageInfos_);
+}
+
+status_t KeyAttestationApplicationId::readFromParcel(const Parcel* parcel) {
+    std::unique_ptr<std::vector<std::unique_ptr<KeyAttestationPackageInfo>>> temp_vector;
+    auto rc = parcel->readParcelableVector(&temp_vector);
+    if (rc != NO_ERROR) return rc;
+    packageInfos_.reset(temp_vector.release());
+    return NO_ERROR;
+}
+
+}  // namespace keymaster
+}  // namespace security
+}  // namespace android
diff --git a/keystore/KeyAttestationPackageInfo.cpp b/keystore/KeyAttestationPackageInfo.cpp
new file mode 100644
index 0000000..a84c246
--- /dev/null
+++ b/keystore/KeyAttestationPackageInfo.cpp
@@ -0,0 +1,49 @@
+/*
+**
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#include "include/keystore/KeyAttestationPackageInfo.h"
+
+#include <binder/Parcel.h>
+
+namespace android {
+namespace security {
+namespace keymaster {
+
+status_t KeyAttestationPackageInfo::writeToParcel(Parcel* parcel) const {
+    auto rc = parcel->writeString16(packageName_);
+    if (rc != NO_ERROR) return rc;
+    rc = parcel->writeInt32(versionCode_);
+    if (rc != NO_ERROR) return rc;
+    return parcel->writeParcelableVector(signatures_);
+}
+
+status_t KeyAttestationPackageInfo::readFromParcel(const Parcel* parcel) {
+    auto rc = parcel->readString16(&packageName_);
+    if (rc != NO_ERROR) return rc;
+    rc = parcel->readInt32(&versionCode_);
+    if (rc != NO_ERROR) return rc;
+
+    std::unique_ptr<std::vector<std::unique_ptr<content::pm::Signature>>> temp_vector;
+    rc = parcel->readParcelableVector(&temp_vector);
+    if (rc != NO_ERROR) return rc;
+    signatures_.reset(temp_vector.release());
+    return NO_ERROR;
+}
+
+}  // namespace keymaster
+}  // namespace security
+}  // namespace android
diff --git a/keystore/Signature.cpp b/keystore/Signature.cpp
new file mode 100644
index 0000000..1566df9
--- /dev/null
+++ b/keystore/Signature.cpp
@@ -0,0 +1,36 @@
+/*
+**
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#include "include/keystore/Signature.h"
+
+#include <binder/Parcel.h>
+
+namespace android {
+namespace content {
+namespace pm {
+
+status_t Signature::writeToParcel(Parcel* parcel) const {
+    return parcel->writeByteVector(sig_data_);
+}
+
+status_t Signature::readFromParcel(const Parcel* parcel) {
+    return parcel->readByteVector(&sig_data_);
+}
+
+}  // namespace pm
+}  // namespace content
+}  // namespace android
diff --git a/keystore/include/keystore/KeyAttestationApplicationId.h b/keystore/include/keystore/KeyAttestationApplicationId.h
new file mode 100644
index 0000000..a7ce210
--- /dev/null
+++ b/keystore/include/keystore/KeyAttestationApplicationId.h
@@ -0,0 +1,51 @@
+// Copyright 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef KEYSTORE_INCLUDE_KEYSTORE_KEYATTESTATIONAPPLICATIONID_H_
+#define KEYSTORE_INCLUDE_KEYSTORE_KEYATTESTATIONAPPLICATIONID_H_
+
+#include "KeyAttestationPackageInfo.h"
+#include "utils.h"
+#include <binder/Parcelable.h>
+#include <memory>
+#include <vector>
+
+namespace android {
+namespace security {
+namespace keymaster {
+
+class KeyAttestationApplicationId : public Parcelable {
+  public:
+    typedef SharedNullableIterator<const KeyAttestationPackageInfo, std::vector>
+        ConstKeyAttestationPackageInfoIterator;
+
+    status_t writeToParcel(Parcel*) const override;
+    status_t readFromParcel(const Parcel* parcel) override;
+
+    ConstKeyAttestationPackageInfoIterator pinfos_begin() const {
+        return ConstKeyAttestationPackageInfoIterator(packageInfos_);
+    }
+    ConstKeyAttestationPackageInfoIterator pinfos_end() const {
+        return ConstKeyAttestationPackageInfoIterator();
+    }
+
+  private:
+    std::shared_ptr<std::vector<std::unique_ptr<KeyAttestationPackageInfo>>> packageInfos_;
+};
+
+}  // namespace keymaster
+}  // namespace security
+}  // namsepace android
+
+#endif  // KEYSTORE_INCLUDE_KEYSTORE_KEYATTESTATIONAPPLICATIONID_H_
diff --git a/keystore/include/keystore/KeyAttestationPackageInfo.h b/keystore/include/keystore/KeyAttestationPackageInfo.h
new file mode 100644
index 0000000..b938e83
--- /dev/null
+++ b/keystore/include/keystore/KeyAttestationPackageInfo.h
@@ -0,0 +1,53 @@
+// Copyright 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef KEYSTORE_INCLUDE_KEYSTORE_KEYATTESTATIONPACKAGEINFO_H_
+#define KEYSTORE_INCLUDE_KEYSTORE_KEYATTESTATIONPACKAGEINFO_H_
+
+#include "Signature.h"
+#include "utils.h"
+#include <binder/Parcelable.h>
+#include <memory>
+#include <stdint.h>
+#include <vector>
+
+namespace android {
+namespace security {
+namespace keymaster {
+
+class KeyAttestationPackageInfo : public Parcelable {
+  public:
+    typedef SharedNullableIterator<const content::pm::Signature, std::vector>
+        ConstSignatureIterator;
+
+    status_t writeToParcel(Parcel*) const override;
+    status_t readFromParcel(const Parcel* parcel) override;
+
+    const std::unique_ptr<String16>& package_name() const { return packageName_; }
+    int32_t version_code() const { return versionCode_; }
+
+    ConstSignatureIterator sigs_begin() const { return ConstSignatureIterator(signatures_); }
+    ConstSignatureIterator sigs_end() const { return ConstSignatureIterator(); }
+
+  private:
+    std::unique_ptr<String16> packageName_;
+    int32_t versionCode_;
+    std::shared_ptr<std::vector<std::unique_ptr<content::pm::Signature>>> signatures_;
+};
+
+}  // namespace keymaster
+}  // namespace security
+}  // namespace android
+
+#endif  // KEYSTORE_INCLUDE_KEYSTORE_KEYATTESTATIONPACKAGEINFO_H_
diff --git a/keystore/include/keystore/Signature.h b/keystore/include/keystore/Signature.h
new file mode 100644
index 0000000..59b77bf
--- /dev/null
+++ b/keystore/include/keystore/Signature.h
@@ -0,0 +1,43 @@
+// Copyright 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef KEYSTORE_INCLUDE_KEYSTORE_SIGNATURE_H_
+#define KEYSTORE_INCLUDE_KEYSTORE_SIGNATURE_H_
+
+#include <binder/Parcelable.h>
+#include <stdint.h>
+#include <vector>
+
+namespace android {
+namespace content {
+namespace pm {
+
+class Signature : public Parcelable {
+  public:
+    status_t writeToParcel(Parcel*) const override;
+    status_t readFromParcel(const Parcel* parcel) override;
+
+    const std::vector<uint8_t>& data() const & { return sig_data_; }
+    std::vector<uint8_t>& data() & { return sig_data_; }
+    std::vector<uint8_t>&& data() && { return std::move(sig_data_); }
+
+  private:
+    std::vector<uint8_t> sig_data_;
+};
+
+}  // namespace pm
+}  // namespace content
+}  // namespace android
+
+#endif  // KEYSTORE_INCLUDE_KEYSTORE_SIGNATURE_H_
diff --git a/keystore/include/keystore/utils.h b/keystore/include/keystore/utils.h
new file mode 100644
index 0000000..f95ae71
--- /dev/null
+++ b/keystore/include/keystore/utils.h
@@ -0,0 +1,96 @@
+// TODO: Insert description here. (generated by jdanis)
+
+#ifndef KEYSTORE_INCLUDE_KEYSTORE_UTILS_H_
+#define KEYSTORE_INCLUDE_KEYSTORE_UTILS_H_
+
+#include <iterator>
+#include <memory>
+#include <vector>
+
+namespace android {
+namespace security {
+
+/*
+ * This iterator abstracts from a collection of the form
+ * std::shared_ptr<COLLECTION_TYPE<std::unique_ptr<T>>>
+ * such that it is defined both for nulled outer pointer and
+ * nulled entries. If shared_ptr(nullptr) is passed in, the iterator behaves
+ * like the end iterator yielding an empty collection. Nulled
+ * entries are skipped so that the iterator is always dereferencable unless
+ * it is equal to end.
+ * The default constructor always yields an iterator equal to end.
+ * The same iterator invalidation rules apply as they do for the iterators
+ * of the corresponding collection.
+ */
+template <typename T, template <typename...> class Coll = std::vector>
+class SharedNullableIterator {
+  public:
+    typedef Coll<std::unique_ptr<typename std::remove_const<T>::type>> CollectionType;
+    typedef std::shared_ptr<CollectionType> CollectionPtr;
+
+    SharedNullableIterator() {}
+    SharedNullableIterator(const std::shared_ptr<CollectionType>& coll) : coll_(coll) { init(); }
+    SharedNullableIterator(std::shared_ptr<CollectionType>&& coll) : coll_(coll) { init(); }
+
+    SharedNullableIterator(const SharedNullableIterator& other)
+        : coll_(other.coll_), cur_(other.cur_) {}
+    SharedNullableIterator(SharedNullableIterator&& other)
+        : coll_(std::move(other.coll_)), cur_(std::move(other.cur_)) {}
+
+    SharedNullableIterator& operator++() {
+        inc();
+        return *this;
+    }
+    SharedNullableIterator operator++(int) {
+        SharedNullableIterator retval(*this);
+        ++(*this);
+        return retval;
+    }
+    T& operator*() const { return **cur_; }
+
+    T* operator->() const { return &**cur_; }
+
+    bool operator==(const SharedNullableIterator& other) const {
+        return cur_ == other.cur_ || (is_end() && other.is_end());
+    }
+    bool operator!=(const SharedNullableIterator& other) const { return !(*this == other); }
+
+    SharedNullableIterator& operator=(const SharedNullableIterator&) = default;
+    SharedNullableIterator& operator=(SharedNullableIterator&&) = default;
+
+  private:
+    inline bool is_end() const { return !coll_ || cur_ == coll_->end(); }
+    inline void inc() {
+        if (!is_end()) {
+            do {
+                ++cur_;
+                // move forward to the next non null member or stay at end
+            } while (cur_ != coll_->end() && !(*cur_));
+        }
+    }
+    void init() {
+        if (coll_) {
+            // move forward to the first non null member
+            for (cur_ = coll_->begin(); cur_ != coll_->end() && !(*cur_); ++cur_) {
+            }
+        }
+    }
+
+    CollectionPtr coll_;
+    typename CollectionType::iterator cur_;
+};
+
+}  // namespace security
+}  // namespace android
+
+namespace std {
+template <typename T, template <typename...> class COLL>
+struct iterator_traits<android::security::SharedNullableIterator<T, COLL>> {
+    typedef T& reference;
+    typedef T value_type;
+    typedef T* pointer;
+    typedef forward_iterator_tag iterator_category;
+};
+}
+
+#endif  // KEYSTORE_INCLUDE_KEYSTORE_UTILS_H_
diff --git a/keystore/key_store_service.cpp b/keystore/key_store_service.cpp
index 329898b..bd7fd18 100644
--- a/keystore/key_store_service.cpp
+++ b/keystore/key_store_service.cpp
@@ -28,6 +28,7 @@
 #include <hardware/keymaster_defs.h>
 
 #include "defaults.h"
+#include "keystore_attestation_id.h"
 #include "keystore_utils.h"
 
 using keymaster::AuthorizationSet;
@@ -1129,8 +1130,7 @@
 
 int32_t KeyStoreService::attestKey(const String16& name, const KeymasterArguments& params,
                                    KeymasterCertificateChain* outChain) {
-    if (!outChain)
-        return KM_ERROR_OUTPUT_PARAMETER_NULL;
+    if (!outChain) return KM_ERROR_OUTPUT_PARAMETER_NULL;
 
     if (!checkAllowedOperationParams(params.params)) {
         return KM_ERROR_INVALID_ARGUMENT;
@@ -1149,15 +1149,33 @@
     keymaster_key_blob_t key = {keyBlob.getValue(),
                                 static_cast<size_t>(std::max(0, keyBlob.getLength()))};
     auto* dev = mKeyStore->getDeviceForBlob(keyBlob);
-    if (!dev->attest_key)
-        return KM_ERROR_UNIMPLEMENTED;
+    if (!dev->attest_key) return KM_ERROR_UNIMPLEMENTED;
+
+    /* get the attestation application id
+     * the result is actually a pair: .second contains the error code and if this is NO_ERROR
+     *                                .first contains the requested attestation id
+     */
+    auto asn1_attestation_id_result = security::gather_attestation_application_id(callingUid);
+    if (asn1_attestation_id_result.second != android::NO_ERROR) {
+        ALOGE("failed to gather attestation_id");
+        return KM_ERROR_ATTESTATION_APPLICATION_ID_MISSING;
+    }
+
+    /*
+     * Make a mutable copy of the params vector which to append the attestation id to.
+     * The copy is shallow, and the lifetime of the inner objects is the calling scope.
+     */
+    auto mutable_params = params.params;
+
+    mutable_params.push_back({.tag = KM_TAG_ATTESTATION_APPLICATION_ID,
+                              .blob = {asn1_attestation_id_result.first.data(),
+                                       asn1_attestation_id_result.first.size()}});
 
     const keymaster_key_param_set_t in_params = {
-        const_cast<keymaster_key_param_t*>(params.params.data()), params.params.size()};
+        const_cast<keymaster_key_param_t*>(mutable_params.data()), mutable_params.size()};
     outChain->chain = {nullptr, 0};
     int32_t rc = dev->attest_key(dev, &key, &in_params, &outChain->chain);
-    if (rc)
-        return rc;
+    if (rc) return rc;
     return ::NO_ERROR;
 }
 
@@ -1306,6 +1324,8 @@
     for (auto param : params) {
         switch (param.tag) {
         case KM_TAG_AUTH_TOKEN:
+        // fall through intended
+        case KM_TAG_ATTESTATION_APPLICATION_ID:
             return false;
         default:
             break;
diff --git a/keystore/keystore_attestation_id.cpp b/keystore/keystore_attestation_id.cpp
new file mode 100644
index 0000000..36c692f
--- /dev/null
+++ b/keystore/keystore_attestation_id.cpp
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "keystore_attestation_id.h"
+
+#define LOG_TAG "keystore_att_id"
+
+#include <cutils/log.h>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <binder/IServiceManager.h>
+#include <binder/Parcel.h>
+#include <binder/Parcelable.h>
+#include <binder/PersistableBundle.h>
+
+#include <android/security/keymaster/BpKeyAttestationApplicationIdProvider.h>
+#include <android/security/keymaster/IKeyAttestationApplicationIdProvider.h>
+#include <keystore/KeyAttestationApplicationId.h>
+#include <keystore/KeyAttestationPackageInfo.h>
+#include <keystore/Signature.h>
+
+#include <openssl/asn1t.h>
+#include <openssl/sha.h>
+
+#include <utils/String8.h>
+
+namespace android {
+
+namespace {
+
+static std::vector<uint8_t> signature2SHA256(const content::pm::Signature& sig) {
+    std::vector<uint8_t> digest_buffer(SHA256_DIGEST_LENGTH);
+    SHA256(sig.data().data(), sig.data().size(), digest_buffer.data());
+    return digest_buffer;
+}
+
+using ::android::security::keymaster::BpKeyAttestationApplicationIdProvider;
+
+class KeyAttestationApplicationIdProvider : public BpKeyAttestationApplicationIdProvider {
+  public:
+    KeyAttestationApplicationIdProvider();
+
+    static KeyAttestationApplicationIdProvider& get();
+
+  private:
+    android::sp<android::IServiceManager> service_manager_;
+};
+
+KeyAttestationApplicationIdProvider& KeyAttestationApplicationIdProvider::get() {
+    static KeyAttestationApplicationIdProvider mpm;
+    return mpm;
+}
+
+KeyAttestationApplicationIdProvider::KeyAttestationApplicationIdProvider()
+    : BpKeyAttestationApplicationIdProvider(
+          android::defaultServiceManager()->getService(String16("sec_key_att_app_id_provider"))) {}
+
+DECLARE_STACK_OF(ASN1_OCTET_STRING);
+
+typedef struct km_attestation_package_info {
+    ASN1_OCTET_STRING* package_name;
+    ASN1_INTEGER* version;
+    STACK_OF(ASN1_OCTET_STRING) * signature_digests;
+} KM_ATTESTATION_PACKAGE_INFO;
+
+ASN1_SEQUENCE(KM_ATTESTATION_PACKAGE_INFO) = {
+    ASN1_SIMPLE(KM_ATTESTATION_PACKAGE_INFO, package_name, ASN1_OCTET_STRING),
+    ASN1_SIMPLE(KM_ATTESTATION_PACKAGE_INFO, version, ASN1_INTEGER),
+    ASN1_SET_OF(KM_ATTESTATION_PACKAGE_INFO, signature_digests, ASN1_OCTET_STRING),
+} ASN1_SEQUENCE_END(KM_ATTESTATION_PACKAGE_INFO);
+IMPLEMENT_ASN1_FUNCTIONS(KM_ATTESTATION_PACKAGE_INFO);
+
+DECLARE_STACK_OF(KM_ATTESTATION_PACKAGE_INFO);
+
+typedef struct km_attestation_application_id {
+    STACK_OF(KM_ATTESTATION_PACKAGE_INFO) * package_infos;
+} KM_ATTESTATION_APPLICATION_ID;
+
+ASN1_SEQUENCE(KM_ATTESTATION_APPLICATION_ID) = {
+    ASN1_SET_OF(KM_ATTESTATION_APPLICATION_ID, package_infos, KM_ATTESTATION_PACKAGE_INFO),
+} ASN1_SEQUENCE_END(KM_ATTESTATION_APPLICATION_ID);
+IMPLEMENT_ASN1_FUNCTIONS(KM_ATTESTATION_APPLICATION_ID);
+}
+
+}  // namespace android
+
+namespace std {
+template <> struct default_delete<android::KM_ATTESTATION_PACKAGE_INFO> {
+    void operator()(android::KM_ATTESTATION_PACKAGE_INFO* p) {
+        android::KM_ATTESTATION_PACKAGE_INFO_free(p);
+    }
+};
+template <> struct default_delete<ASN1_OCTET_STRING> {
+    void operator()(ASN1_OCTET_STRING* p) { ASN1_OCTET_STRING_free(p); }
+};
+template <> struct default_delete<android::KM_ATTESTATION_APPLICATION_ID> {
+    void operator()(android::KM_ATTESTATION_APPLICATION_ID* p) {
+        android::KM_ATTESTATION_APPLICATION_ID_free(p);
+    }
+};
+}  // namespace std
+
+namespace android {
+namespace security {
+namespace {
+
+using ::android::security::keymaster::KeyAttestationApplicationId;
+using ::android::security::keymaster::KeyAttestationPackageInfo;
+
+status_t build_attestation_package_info(
+    const std::string& pkg_name, const uint32_t pkg_version,
+    const std::vector<std::vector<uint8_t>>& signature_digests,
+    std::unique_ptr<KM_ATTESTATION_PACKAGE_INFO>* attestation_package_info_ptr) {
+
+    if (!attestation_package_info_ptr) return BAD_VALUE;
+    auto& attestation_package_info = *attestation_package_info_ptr;
+
+    attestation_package_info.reset(KM_ATTESTATION_PACKAGE_INFO_new());
+    if (!attestation_package_info.get()) return NO_MEMORY;
+
+    if (!ASN1_OCTET_STRING_set(attestation_package_info->package_name,
+                               reinterpret_cast<const unsigned char*>(pkg_name.data()),
+                               pkg_name.size())) {
+        return UNKNOWN_ERROR;
+    }
+
+    auto signature_digest_stack =
+        reinterpret_cast<_STACK*>(attestation_package_info->signature_digests);
+
+    assert(signature_digest_stack != nullptr);
+
+    for (auto si : signature_digests) {
+        auto asn1_item = std::unique_ptr<ASN1_OCTET_STRING>(ASN1_OCTET_STRING_new());
+        if (!asn1_item) return NO_MEMORY;
+        if (!ASN1_OCTET_STRING_set(asn1_item.get(), si.data(), si.size())) {
+            return UNKNOWN_ERROR;
+        }
+        if (!sk_push(signature_digest_stack, asn1_item.get())) {
+            return NO_MEMORY;
+        }
+        asn1_item.release();  // if push succeeded, the stack takes ownership
+    }
+
+    if (!ASN1_INTEGER_set(attestation_package_info->version, pkg_version)) {
+        return UNKNOWN_ERROR;
+    }
+
+    return NO_ERROR;
+}
+
+inline std::pair<std::vector<uint8_t>, status_t> wraperror(const status_t status) {
+    return std::pair<std::vector<uint8_t>, status_t>(std::vector<uint8_t>(), status);
+}
+
+std::pair<std::vector<uint8_t>, status_t>
+build_attestation_application_id(const KeyAttestationApplicationId& key_attestation_id) {
+    auto attestation_id =
+        std::unique_ptr<KM_ATTESTATION_APPLICATION_ID>(KM_ATTESTATION_APPLICATION_ID_new());
+
+    auto attestation_pinfo_stack = reinterpret_cast<_STACK*>(attestation_id->package_infos);
+
+    for (auto pinfo = key_attestation_id.pinfos_begin(); pinfo != key_attestation_id.pinfos_end();
+         ++pinfo) {
+        std::vector<std::vector<uint8_t>> signature_digests;
+
+        for (auto sig = pinfo->sigs_begin(); sig != pinfo->sigs_end(); ++sig) {
+            signature_digests.push_back(signature2SHA256(*sig));
+        }
+
+        if (!pinfo->package_name()) {
+            ALOGE("Key attestation package info lacks package name");
+            return wraperror(BAD_VALUE);
+        }
+        std::string package_name(String8(*pinfo->package_name()).string());
+        std::unique_ptr<KM_ATTESTATION_PACKAGE_INFO> attestation_package_info;
+        auto rc = build_attestation_package_info(package_name, pinfo->version_code(),
+                                                 signature_digests, &attestation_package_info);
+        if (rc != NO_ERROR) {
+            ALOGE("Building DER attestation package info failed %d", rc);
+            return wraperror(rc);
+        }
+        if (!sk_push(attestation_pinfo_stack, attestation_package_info.get())) {
+            return wraperror(NO_MEMORY);
+        }
+        // if push succeeded, the stack takes ownership
+        attestation_package_info.release();
+    }
+
+    int len = i2d_KM_ATTESTATION_APPLICATION_ID(attestation_id.get(), nullptr);
+    if (len < 0) return wraperror(UNKNOWN_ERROR);
+    auto result = std::make_pair(std::vector<uint8_t>(len), NO_ERROR);
+    uint8_t* p = result.first.data();
+    len = i2d_KM_ATTESTATION_APPLICATION_ID(attestation_id.get(), &p);
+    if (len < 0) return wraperror(UNKNOWN_ERROR);
+
+    return result;
+}
+
+/* The following function are not used. They are mentioned here to silence
+ * warnings about them not being used.
+ */
+void unused_functions_silencer() __attribute__((unused));
+void unused_functions_silencer() {
+    i2d_KM_ATTESTATION_PACKAGE_INFO(nullptr, nullptr);
+    d2i_KM_ATTESTATION_APPLICATION_ID(nullptr, nullptr, 0);
+    d2i_KM_ATTESTATION_PACKAGE_INFO(nullptr, nullptr, 0);
+}
+
+}  // namespace
+
+std::pair<std::vector<uint8_t>, status_t> gather_attestation_application_id(uid_t uid) {
+    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 wraperror(FAILED_TRANSACTION);
+    }
+
+    /* DER encode the attestation application ID */
+    return build_attestation_application_id(key_attestation_id);
+}
+
+}  // namespace security
+}  // namespace android
diff --git a/keystore/keystore_attestation_id.h b/keystore/keystore_attestation_id.h
new file mode 100644
index 0000000..55d2c94
--- /dev/null
+++ b/keystore/keystore_attestation_id.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef KEYSTORE_KEYSTORE_ATTESTATION_ID_H_
+#define KEYSTORE_KEYSTORE_ATTESTATION_ID_H_
+
+#include <utils/Errors.h>
+#include <vector>
+
+namespace android {
+namespace security {
+
+/**
+ * Gathers the attestation id for the application determined by uid by querying the package manager
+ * As of this writing uids can be shared in android, which is why the asn.1 encoded result may
+ * contain more than one application attestation id.
+ *
+ * @returns .first the asn.1 encoded attestation application id if .second is NO_ERROR. If .second
+ *          is not NO_ERROR the content of .first is undefined.
+ */
+std::pair<std::vector<uint8_t>, status_t> gather_attestation_application_id(uid_t uid);
+
+}  // namespace security
+}  // namespace android
+#endif  // KEYSTORE_KEYSTORE_ATTESTATION_ID_H_