blob: fea4df99b931f4a30357cf85f90319164f9a5915 [file] [log] [blame]
David Zeuthenab3e5652019-10-28 13:32:48 -04001/*
2 * Copyright (c) 2019, 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
David Zeuthen62d43bf2021-03-31 10:41:27 -040017#define LOG_TAG "credstore"
David Zeuthenab3e5652019-10-28 13:32:48 -040018
19#include <algorithm>
Seth Moore81db3782022-01-18 15:58:47 -080020#include <optional>
David Zeuthenab3e5652019-10-28 13:32:48 -040021
22#include <android-base/logging.h>
Tri Vo71e8cc12023-01-17 15:37:50 -080023#include <android-base/properties.h>
Seth Moore81db3782022-01-18 15:58:47 -080024#include <android/hardware/security/keymint/IRemotelyProvisionedComponent.h>
25#include <android/hardware/security/keymint/RpcHardwareInfo.h>
26#include <android/security/remoteprovisioning/IRemotelyProvisionedKeyPool.h>
27#include <android/security/remoteprovisioning/RemotelyProvisionedKey.h>
David Zeuthenab3e5652019-10-28 13:32:48 -040028#include <binder/IPCThreadState.h>
Seth Moore81db3782022-01-18 15:58:47 -080029#include <binder/IServiceManager.h>
Tri Vo3ab6f052022-11-22 10:26:16 -080030#include <vintf/VintfObject.h>
David Zeuthenab3e5652019-10-28 13:32:48 -040031
32#include "Credential.h"
David Zeuthena6f9fba2020-02-11 22:08:27 -050033#include "CredentialData.h"
David Zeuthenab3e5652019-10-28 13:32:48 -040034#include "CredentialStore.h"
Tri Vo71e8cc12023-01-17 15:37:50 -080035#include "RemotelyProvisionedKey.h"
David Zeuthen045a2c82021-09-11 13:52:17 -040036#include "Session.h"
David Zeuthenab3e5652019-10-28 13:32:48 -040037#include "Util.h"
38#include "WritableCredential.h"
39
40namespace android {
41namespace security {
42namespace identity {
Seth Moore81db3782022-01-18 15:58:47 -080043namespace {
44
Seth Moore81db3782022-01-18 15:58:47 -080045using ::android::security::remoteprovisioning::IRemotelyProvisionedKeyPool;
Tri Vo3ab6f052022-11-22 10:26:16 -080046using ::android::security::rkp::IRemoteProvisioning;
Seth Moore81db3782022-01-18 15:58:47 -080047
Tri Vo3ab6f052022-11-22 10:26:16 -080048bool useRkpd() {
Tri Vo71e8cc12023-01-17 15:37:50 -080049 return android::base::GetBoolProperty("remote_provisioning.enable_rkpd",
50 /*default_value=*/false);
Seth Moore81db3782022-01-18 15:58:47 -080051}
52
53} // namespace
David Zeuthenab3e5652019-10-28 13:32:48 -040054
David Zeuthenab3e5652019-10-28 13:32:48 -040055CredentialStore::CredentialStore(const std::string& dataPath, sp<IIdentityCredentialStore> hal)
56 : dataPath_(dataPath), hal_(hal) {}
57
58bool CredentialStore::init() {
David Zeuthena6f9fba2020-02-11 22:08:27 -050059 Status status = hal_->getHardwareInformation(&hwInfo_);
60 if (!status.isOk()) {
61 LOG(ERROR) << "Error getting hardware information: " << status.toString8();
David Zeuthenab3e5652019-10-28 13:32:48 -040062 return false;
63 }
David Zeuthen472e6c82020-10-16 11:50:13 -040064 halApiVersion_ = hal_->getInterfaceVersion();
David Zeuthena6f9fba2020-02-11 22:08:27 -050065
Seth Moore81db3782022-01-18 15:58:47 -080066 if (hwInfo_.isRemoteKeyProvisioningSupported) {
Tri Vo3ab6f052022-11-22 10:26:16 -080067 status = hal_->getRemotelyProvisionedComponent(&rpc_);
68 if (!status.isOk()) {
69 LOG(ERROR) << "Error getting remotely provisioned component: " << status;
Seth Moore81db3782022-01-18 15:58:47 -080070 return false;
71 }
72 }
73
David Zeuthen472e6c82020-10-16 11:50:13 -040074 LOG(INFO) << "Connected to Identity Credential HAL with API version " << halApiVersion_
75 << " and name '" << hwInfo_.credentialStoreName << "' authored by '"
76 << hwInfo_.credentialStoreAuthorName << "' with chunk size " << hwInfo_.dataChunkSize
Tri Vo71e8cc12023-01-17 15:37:50 -080077 << " directoAccess set to " << (hwInfo_.isDirectAccess ? "true" : "false")
78 << " and remote key provisioning support "
79 << (hwInfo_.isRemoteKeyProvisioningSupported ? "enabled" : "disabled");
David Zeuthenab3e5652019-10-28 13:32:48 -040080 return true;
81}
82
83CredentialStore::~CredentialStore() {}
84
85Status CredentialStore::getSecurityHardwareInfo(SecurityHardwareInfoParcel* _aidl_return) {
86 SecurityHardwareInfoParcel info;
David Zeuthena6f9fba2020-02-11 22:08:27 -050087 info.directAccess = hwInfo_.isDirectAccess;
88 info.supportedDocTypes = hwInfo_.supportedDocTypes;
David Zeuthenab3e5652019-10-28 13:32:48 -040089 *_aidl_return = info;
90 return Status::ok();
91};
92
93Status CredentialStore::createCredential(const std::string& credentialName,
94 const std::string& docType,
95 sp<IWritableCredential>* _aidl_return) {
96 uid_t callingUid = android::IPCThreadState::self()->getCallingUid();
97 optional<bool> credentialExists =
98 CredentialData::credentialExists(dataPath_, callingUid, credentialName);
99 if (!credentialExists.has_value()) {
100 return Status::fromServiceSpecificError(
101 ERROR_GENERIC, "Error determining if credential with given name exists");
102 }
103 if (credentialExists.value()) {
104 return Status::fromServiceSpecificError(ERROR_ALREADY_PERSONALIZED,
105 "Credential with given name already exists");
106 }
107
David Zeuthena6f9fba2020-02-11 22:08:27 -0500108 if (hwInfo_.supportedDocTypes.size() > 0) {
109 if (std::find(hwInfo_.supportedDocTypes.begin(), hwInfo_.supportedDocTypes.end(),
110 docType) == hwInfo_.supportedDocTypes.end()) {
David Zeuthenab3e5652019-10-28 13:32:48 -0400111 return Status::fromServiceSpecificError(ERROR_DOCUMENT_TYPE_NOT_SUPPORTED,
112 "No support for given document type");
113 }
114 }
115
David Zeuthenab3e5652019-10-28 13:32:48 -0400116 sp<IWritableIdentityCredential> halWritableCredential;
David Zeuthena6f9fba2020-02-11 22:08:27 -0500117 Status status = hal_->createCredential(docType, false, &halWritableCredential);
118 if (!status.isOk()) {
119 return halStatusToGenericError(status);
David Zeuthenab3e5652019-10-28 13:32:48 -0400120 }
121
Seth Moore81db3782022-01-18 15:58:47 -0800122 if (hwInfo_.isRemoteKeyProvisioningSupported) {
123 status = setRemotelyProvisionedAttestationKey(halWritableCredential.get());
124 if (!status.isOk()) {
Tri Vo71e8cc12023-01-17 15:37:50 -0800125 LOG(WARNING) << status.toString8()
126 << "\nUnable to fetch remotely provisioned attestation key, falling back "
127 << "to the factory-provisioned attestation key.";
Seth Moore81db3782022-01-18 15:58:47 -0800128 }
129 }
130
David Zeuthenab3e5652019-10-28 13:32:48 -0400131 sp<IWritableCredential> writableCredential = new WritableCredential(
David Zeuthen27407a52021-03-04 16:32:43 -0500132 dataPath_, credentialName, docType, false, hwInfo_, halWritableCredential);
David Zeuthenab3e5652019-10-28 13:32:48 -0400133 *_aidl_return = writableCredential;
134 return Status::ok();
135}
136
David Zeuthen045a2c82021-09-11 13:52:17 -0400137Status CredentialStore::getCredentialCommon(const std::string& credentialName, int32_t cipherSuite,
138 sp<IPresentationSession> halSessionBinder,
David Zeuthenab3e5652019-10-28 13:32:48 -0400139 sp<ICredential>* _aidl_return) {
140 *_aidl_return = nullptr;
141
142 uid_t callingUid = android::IPCThreadState::self()->getCallingUid();
143 optional<bool> credentialExists =
144 CredentialData::credentialExists(dataPath_, callingUid, credentialName);
145 if (!credentialExists.has_value()) {
146 return Status::fromServiceSpecificError(
147 ERROR_GENERIC, "Error determining if credential with given name exists");
148 }
149 if (!credentialExists.value()) {
150 return Status::fromServiceSpecificError(ERROR_NO_SUCH_CREDENTIAL,
151 "Credential with given name doesn't exist");
152 }
153
David Zeuthena6f9fba2020-02-11 22:08:27 -0500154 // Note: IdentityCredentialStore.java's CipherSuite enumeration and CipherSuite from the
155 // HAL is manually kept in sync. So this cast is safe.
David Zeuthen045a2c82021-09-11 13:52:17 -0400156 sp<Credential> credential =
157 new Credential(CipherSuite(cipherSuite), dataPath_, credentialName, callingUid, hwInfo_,
158 hal_, halSessionBinder, halApiVersion_);
David Zeuthenab3e5652019-10-28 13:32:48 -0400159
David Zeuthen472e6c82020-10-16 11:50:13 -0400160 Status loadStatus = credential->ensureOrReplaceHalBinder();
David Zeuthenab3e5652019-10-28 13:32:48 -0400161 if (!loadStatus.isOk()) {
162 LOG(ERROR) << "Error loading credential";
163 } else {
164 *_aidl_return = credential;
165 }
166 return loadStatus;
167}
168
David Zeuthen045a2c82021-09-11 13:52:17 -0400169Status CredentialStore::getCredentialByName(const std::string& credentialName, int32_t cipherSuite,
170 sp<ICredential>* _aidl_return) {
171 return getCredentialCommon(credentialName, cipherSuite, nullptr, _aidl_return);
172}
173
174Status CredentialStore::createPresentationSession(int32_t cipherSuite, sp<ISession>* _aidl_return) {
175 sp<IPresentationSession> halPresentationSession;
176 Status status =
177 hal_->createPresentationSession(CipherSuite(cipherSuite), &halPresentationSession);
178 if (!status.isOk()) {
179 return halStatusToGenericError(status);
180 }
181
182 *_aidl_return = new Session(cipherSuite, halPresentationSession, this);
183 return Status::ok();
184}
185
Seth Moore81db3782022-01-18 15:58:47 -0800186Status CredentialStore::setRemotelyProvisionedAttestationKey(
187 IWritableIdentityCredential* halWritableCredential) {
Tri Vo3ab6f052022-11-22 10:26:16 -0800188 std::vector<uint8_t> keyBlob;
189 std::vector<uint8_t> encodedCertChain;
190 Status status;
191
Tri Vo71e8cc12023-01-17 15:37:50 -0800192 if (useRkpd()) {
193 LOG(INFO) << "Fetching attestation key from RKPD";
194
195 uid_t callingUid = android::IPCThreadState::self()->getCallingUid();
196 auto rpcKeyFuture = getRpcKeyFuture(rpc_, callingUid);
197 if (!rpcKeyFuture) {
198 return Status::fromServiceSpecificError(ERROR_GENERIC, "Error in getRpcKeyFuture()");
199 }
200
201 if (rpcKeyFuture->wait_for(std::chrono::seconds(10)) != std::future_status::ready) {
Tri Vo3ab6f052022-11-22 10:26:16 -0800202 return Status::fromServiceSpecificError(
203 ERROR_GENERIC, "Waiting for remotely provisioned attestation key timed out");
204 }
205
Tri Vo71e8cc12023-01-17 15:37:50 -0800206 std::optional<::android::security::rkp::RemotelyProvisionedKey> key = rpcKeyFuture->get();
Tri Vo3ab6f052022-11-22 10:26:16 -0800207 if (!key) {
208 return Status::fromServiceSpecificError(
209 ERROR_GENERIC, "Failed to get remotely provisioned attestation key");
210 }
211
212 if (key->keyBlob.empty()) {
213 return Status::fromServiceSpecificError(
214 ERROR_GENERIC, "Remotely provisioned attestation key blob is empty");
215 }
216
217 keyBlob = std::move(key->keyBlob);
218 encodedCertChain = std::move(key->encodedCertChain);
219 } else {
Tri Vo71e8cc12023-01-17 15:37:50 -0800220 LOG(INFO) << "Fetching attestation key from remotely provisioned key pool.";
221
222 sp<IRemotelyProvisionedKeyPool> keyPool =
223 android::waitForService<IRemotelyProvisionedKeyPool>(
224 IRemotelyProvisionedKeyPool::descriptor);
225 if (!keyPool) {
226 return Status::fromServiceSpecificError(
227 ERROR_GENERIC, "Error getting IRemotelyProvisionedKeyPool HAL");
228 }
229
Tri Vo3ab6f052022-11-22 10:26:16 -0800230 std::optional<std::string> rpcId = getRpcId(rpc_);
231 if (!rpcId) {
232 return Status::fromServiceSpecificError(
233 ERROR_GENERIC, "Error getting remotely provisioned component id");
234 }
235
236 uid_t callingUid = android::IPCThreadState::self()->getCallingUid();
237 ::android::security::remoteprovisioning::RemotelyProvisionedKey key;
Tri Vo71e8cc12023-01-17 15:37:50 -0800238 Status status = keyPool->getAttestationKey(callingUid, *rpcId, &key);
Tri Vo3ab6f052022-11-22 10:26:16 -0800239 if (!status.isOk()) {
Tri Vo71e8cc12023-01-17 15:37:50 -0800240 return status;
Tri Vo3ab6f052022-11-22 10:26:16 -0800241 }
242
243 keyBlob = std::move(key.keyBlob);
244 encodedCertChain = std::move(key.encodedCertChain);
Seth Moore81db3782022-01-18 15:58:47 -0800245 }
246
Tri Vo3ab6f052022-11-22 10:26:16 -0800247 status = halWritableCredential->setRemotelyProvisionedAttestationKey(keyBlob, encodedCertChain);
Seth Moore81db3782022-01-18 15:58:47 -0800248 if (!status.isOk()) {
249 LOG(ERROR) << "Error setting remotely provisioned attestation key on credential";
250 return status;
251 }
Seth Moore81db3782022-01-18 15:58:47 -0800252 return Status::ok();
253}
254
David Zeuthenab3e5652019-10-28 13:32:48 -0400255} // namespace identity
256} // namespace security
257} // namespace android