Merge "Add attestation application id for key attestation"
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_