blob: 7f9c38da3125584cb776d42735762de7a729570b [file] [log] [blame]
Janis Danisevskis18f27ad2016-06-01 13:57:40 -07001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#include "keystore_attestation_id.h"
17
18#define LOG_TAG "keystore_att_id"
19
20#include <cutils/log.h>
21
22#include <memory>
23#include <string>
24#include <vector>
25
26#include <binder/IServiceManager.h>
27#include <binder/Parcel.h>
28#include <binder/Parcelable.h>
29#include <binder/PersistableBundle.h>
30
31#include <android/security/keymaster/BpKeyAttestationApplicationIdProvider.h>
32#include <android/security/keymaster/IKeyAttestationApplicationIdProvider.h>
33#include <keystore/KeyAttestationApplicationId.h>
34#include <keystore/KeyAttestationPackageInfo.h>
35#include <keystore/Signature.h>
36
Eran Messeriea47d3f2017-12-06 12:01:42 +000037#include <private/android_filesystem_config.h> /* for AID_SYSTEM */
38
Janis Danisevskis18f27ad2016-06-01 13:57:40 -070039#include <openssl/asn1t.h>
40#include <openssl/sha.h>
41
42#include <utils/String8.h>
43
44namespace android {
45
46namespace {
47
Shawn Willden9e8edcf2017-12-18 15:11:46 -070048constexpr const char* kAttestationSystemPackageName = "AndroidSystem";
49
50std::vector<uint8_t> signature2SHA256(const content::pm::Signature& sig) {
Janis Danisevskis18f27ad2016-06-01 13:57:40 -070051 std::vector<uint8_t> digest_buffer(SHA256_DIGEST_LENGTH);
52 SHA256(sig.data().data(), sig.data().size(), digest_buffer.data());
53 return digest_buffer;
54}
55
56using ::android::security::keymaster::BpKeyAttestationApplicationIdProvider;
57
58class KeyAttestationApplicationIdProvider : public BpKeyAttestationApplicationIdProvider {
59 public:
60 KeyAttestationApplicationIdProvider();
61
62 static KeyAttestationApplicationIdProvider& get();
63
64 private:
65 android::sp<android::IServiceManager> service_manager_;
66};
67
68KeyAttestationApplicationIdProvider& KeyAttestationApplicationIdProvider::get() {
69 static KeyAttestationApplicationIdProvider mpm;
70 return mpm;
71}
72
73KeyAttestationApplicationIdProvider::KeyAttestationApplicationIdProvider()
74 : BpKeyAttestationApplicationIdProvider(
75 android::defaultServiceManager()->getService(String16("sec_key_att_app_id_provider"))) {}
76
77DECLARE_STACK_OF(ASN1_OCTET_STRING);
78
79typedef struct km_attestation_package_info {
80 ASN1_OCTET_STRING* package_name;
81 ASN1_INTEGER* version;
Janis Danisevskis18f27ad2016-06-01 13:57:40 -070082} KM_ATTESTATION_PACKAGE_INFO;
83
84ASN1_SEQUENCE(KM_ATTESTATION_PACKAGE_INFO) = {
85 ASN1_SIMPLE(KM_ATTESTATION_PACKAGE_INFO, package_name, ASN1_OCTET_STRING),
86 ASN1_SIMPLE(KM_ATTESTATION_PACKAGE_INFO, version, ASN1_INTEGER),
Janis Danisevskis18f27ad2016-06-01 13:57:40 -070087} ASN1_SEQUENCE_END(KM_ATTESTATION_PACKAGE_INFO);
88IMPLEMENT_ASN1_FUNCTIONS(KM_ATTESTATION_PACKAGE_INFO);
89
90DECLARE_STACK_OF(KM_ATTESTATION_PACKAGE_INFO);
91
92typedef struct km_attestation_application_id {
93 STACK_OF(KM_ATTESTATION_PACKAGE_INFO) * package_infos;
Janis Danisevskis011675d2016-09-01 11:41:29 +010094 STACK_OF(ASN1_OCTET_STRING) * signature_digests;
Janis Danisevskis18f27ad2016-06-01 13:57:40 -070095} KM_ATTESTATION_APPLICATION_ID;
96
97ASN1_SEQUENCE(KM_ATTESTATION_APPLICATION_ID) = {
98 ASN1_SET_OF(KM_ATTESTATION_APPLICATION_ID, package_infos, KM_ATTESTATION_PACKAGE_INFO),
Janis Danisevskis011675d2016-09-01 11:41:29 +010099 ASN1_SET_OF(KM_ATTESTATION_APPLICATION_ID, signature_digests, ASN1_OCTET_STRING),
Janis Danisevskis18f27ad2016-06-01 13:57:40 -0700100} ASN1_SEQUENCE_END(KM_ATTESTATION_APPLICATION_ID);
101IMPLEMENT_ASN1_FUNCTIONS(KM_ATTESTATION_APPLICATION_ID);
Shawn Willden9e8edcf2017-12-18 15:11:46 -0700102
103} // namespace
Janis Danisevskis18f27ad2016-06-01 13:57:40 -0700104
105} // namespace android
106
107namespace std {
108template <> struct default_delete<android::KM_ATTESTATION_PACKAGE_INFO> {
109 void operator()(android::KM_ATTESTATION_PACKAGE_INFO* p) {
110 android::KM_ATTESTATION_PACKAGE_INFO_free(p);
111 }
112};
113template <> struct default_delete<ASN1_OCTET_STRING> {
114 void operator()(ASN1_OCTET_STRING* p) { ASN1_OCTET_STRING_free(p); }
115};
116template <> struct default_delete<android::KM_ATTESTATION_APPLICATION_ID> {
117 void operator()(android::KM_ATTESTATION_APPLICATION_ID* p) {
118 android::KM_ATTESTATION_APPLICATION_ID_free(p);
119 }
120};
121} // namespace std
122
123namespace android {
124namespace security {
125namespace {
126
127using ::android::security::keymaster::KeyAttestationApplicationId;
128using ::android::security::keymaster::KeyAttestationPackageInfo;
129
Janis Danisevskis011675d2016-09-01 11:41:29 +0100130status_t build_attestation_package_info(const KeyAttestationPackageInfo& pinfo,
Janis Danisevskis18f27ad2016-06-01 13:57:40 -0700131 std::unique_ptr<KM_ATTESTATION_PACKAGE_INFO>* attestation_package_info_ptr) {
132
133 if (!attestation_package_info_ptr) return BAD_VALUE;
134 auto& attestation_package_info = *attestation_package_info_ptr;
135
136 attestation_package_info.reset(KM_ATTESTATION_PACKAGE_INFO_new());
137 if (!attestation_package_info.get()) return NO_MEMORY;
138
Janis Danisevskis011675d2016-09-01 11:41:29 +0100139 if (!pinfo.package_name()) {
140 ALOGE("Key attestation package info lacks package name");
141 return BAD_VALUE;
142 }
143
144 std::string pkg_name(String8(*pinfo.package_name()).string());
Janis Danisevskis18f27ad2016-06-01 13:57:40 -0700145 if (!ASN1_OCTET_STRING_set(attestation_package_info->package_name,
146 reinterpret_cast<const unsigned char*>(pkg_name.data()),
147 pkg_name.size())) {
148 return UNKNOWN_ERROR;
149 }
150
Janis Danisevskis011675d2016-09-01 11:41:29 +0100151 if (!ASN1_INTEGER_set(attestation_package_info->version, pinfo.version_code())) {
152 return UNKNOWN_ERROR;
153 }
154 return NO_ERROR;
155}
Janis Danisevskis18f27ad2016-06-01 13:57:40 -0700156
Janis Danisevskis011675d2016-09-01 11:41:29 +0100157StatusOr<std::vector<uint8_t>>
158build_attestation_application_id(const KeyAttestationApplicationId& key_attestation_id) {
159 auto attestation_id =
160 std::unique_ptr<KM_ATTESTATION_APPLICATION_ID>(KM_ATTESTATION_APPLICATION_ID_new());
Janis Danisevskis18f27ad2016-06-01 13:57:40 -0700161
Janis Danisevskis011675d2016-09-01 11:41:29 +0100162 auto attestation_pinfo_stack = reinterpret_cast<_STACK*>(attestation_id->package_infos);
163
164 if (key_attestation_id.pinfos_begin() == key_attestation_id.pinfos_end()) return BAD_VALUE;
165
166 for (auto pinfo = key_attestation_id.pinfos_begin(); pinfo != key_attestation_id.pinfos_end();
167 ++pinfo) {
168 if (!pinfo->package_name()) {
169 ALOGE("Key attestation package info lacks package name");
170 return BAD_VALUE;
171 }
172 std::string package_name(String8(*pinfo->package_name()).string());
173 std::unique_ptr<KM_ATTESTATION_PACKAGE_INFO> attestation_package_info;
174 auto rc = build_attestation_package_info(*pinfo, &attestation_package_info);
175 if (rc != NO_ERROR) {
176 ALOGE("Building DER attestation package info failed %d", rc);
177 return rc;
178 }
179 if (!sk_push(attestation_pinfo_stack, attestation_package_info.get())) {
180 return NO_MEMORY;
181 }
182 // if push succeeded, the stack takes ownership
183 attestation_package_info.release();
184 }
185
186 /** Apps can only share a uid iff they were signed with the same certificate(s). Because the
187 * signature field actually holds the signing certificate, rather than a signature, we can
188 * simply use the set of signature digests of the first package info.
189 */
190 const auto& pinfo = *key_attestation_id.pinfos_begin();
191 std::vector<std::vector<uint8_t>> signature_digests;
192
193 for (auto sig = pinfo.sigs_begin(); sig != pinfo.sigs_end(); ++sig) {
194 signature_digests.push_back(signature2SHA256(*sig));
195 }
196
197 auto signature_digest_stack = reinterpret_cast<_STACK*>(attestation_id->signature_digests);
Janis Danisevskis18f27ad2016-06-01 13:57:40 -0700198 for (auto si : signature_digests) {
199 auto asn1_item = std::unique_ptr<ASN1_OCTET_STRING>(ASN1_OCTET_STRING_new());
200 if (!asn1_item) return NO_MEMORY;
201 if (!ASN1_OCTET_STRING_set(asn1_item.get(), si.data(), si.size())) {
202 return UNKNOWN_ERROR;
203 }
204 if (!sk_push(signature_digest_stack, asn1_item.get())) {
205 return NO_MEMORY;
206 }
207 asn1_item.release(); // if push succeeded, the stack takes ownership
208 }
209
Janis Danisevskis18f27ad2016-06-01 13:57:40 -0700210 int len = i2d_KM_ATTESTATION_APPLICATION_ID(attestation_id.get(), nullptr);
Janis Danisevskis011675d2016-09-01 11:41:29 +0100211 if (len < 0) return UNKNOWN_ERROR;
212
213 std::vector<uint8_t> result(len);
214 uint8_t* p = result.data();
Janis Danisevskis18f27ad2016-06-01 13:57:40 -0700215 len = i2d_KM_ATTESTATION_APPLICATION_ID(attestation_id.get(), &p);
Janis Danisevskis011675d2016-09-01 11:41:29 +0100216 if (len < 0) return UNKNOWN_ERROR;
Janis Danisevskis18f27ad2016-06-01 13:57:40 -0700217
218 return result;
219}
220
221/* The following function are not used. They are mentioned here to silence
222 * warnings about them not being used.
223 */
224void unused_functions_silencer() __attribute__((unused));
225void unused_functions_silencer() {
226 i2d_KM_ATTESTATION_PACKAGE_INFO(nullptr, nullptr);
227 d2i_KM_ATTESTATION_APPLICATION_ID(nullptr, nullptr, 0);
228 d2i_KM_ATTESTATION_PACKAGE_INFO(nullptr, nullptr, 0);
229}
230
231} // namespace
232
Janis Danisevskis011675d2016-09-01 11:41:29 +0100233StatusOr<std::vector<uint8_t>> gather_attestation_application_id(uid_t uid) {
Shawn Willden9e8edcf2017-12-18 15:11:46 -0700234 KeyAttestationApplicationId key_attestation_id;
Janis Danisevskis18f27ad2016-06-01 13:57:40 -0700235
Eran Messeriea47d3f2017-12-06 12:01:42 +0000236 if (uid == AID_SYSTEM) {
Shawn Willden9e8edcf2017-12-18 15:11:46 -0700237 /* Use a fixed ID for system callers */
238 auto pinfo = std::make_unique<KeyAttestationPackageInfo>(
239 String16(kAttestationSystemPackageName), 1 /* version code */,
240 std::make_shared<KeyAttestationPackageInfo::SignaturesVector>());
241 key_attestation_id = KeyAttestationApplicationId(std::move(pinfo));
Eran Messeriea47d3f2017-12-06 12:01:42 +0000242 } else {
Shawn Willden9e8edcf2017-12-18 15:11:46 -0700243 /* Get the attestation application ID from package manager */
244 auto& pm = KeyAttestationApplicationIdProvider::get();
245 auto status = pm.getKeyAttestationApplicationId(uid, &key_attestation_id);
Eran Messeriea47d3f2017-12-06 12:01:42 +0000246 if (!status.isOk()) {
247 ALOGE("package manager request for key attestation ID failed with: %s %d",
248 status.exceptionMessage().string(), status.exceptionCode());
249 return FAILED_TRANSACTION;
250 }
Janis Danisevskis18f27ad2016-06-01 13:57:40 -0700251 }
252
253 /* DER encode the attestation application ID */
Shawn Willden9e8edcf2017-12-18 15:11:46 -0700254 return build_attestation_application_id(key_attestation_id);
Janis Danisevskis18f27ad2016-06-01 13:57:40 -0700255}
256
257} // namespace security
258} // namespace android