blob: eb9bdb6465819d0108f7e7425b330a4d48e1cbe4 [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>
Seth Moore81db3782022-01-18 15:58:47 -080023#include <android/hardware/security/keymint/IRemotelyProvisionedComponent.h>
24#include <android/hardware/security/keymint/RpcHardwareInfo.h>
25#include <android/security/remoteprovisioning/IRemotelyProvisionedKeyPool.h>
26#include <android/security/remoteprovisioning/RemotelyProvisionedKey.h>
David Zeuthenab3e5652019-10-28 13:32:48 -040027#include <binder/IPCThreadState.h>
Seth Moore81db3782022-01-18 15:58:47 -080028#include <binder/IServiceManager.h>
Tri Vo3ab6f052022-11-22 10:26:16 -080029#include <server_configurable_flags/get_flags.h>
30#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"
David Zeuthen045a2c82021-09-11 13:52:17 -040035#include "Session.h"
David Zeuthenab3e5652019-10-28 13:32:48 -040036#include "Util.h"
37#include "WritableCredential.h"
38
39namespace android {
40namespace security {
41namespace identity {
Seth Moore81db3782022-01-18 15:58:47 -080042namespace {
43
Seth Moore81db3782022-01-18 15:58:47 -080044using ::android::security::remoteprovisioning::IRemotelyProvisionedKeyPool;
Tri Vo3ab6f052022-11-22 10:26:16 -080045using ::android::security::rkp::IRemoteProvisioning;
Seth Moore81db3782022-01-18 15:58:47 -080046
Tri Vo3ab6f052022-11-22 10:26:16 -080047bool useRkpd() {
48 std::string useRkpdFlagValue = server_configurable_flags::GetServerConfigurableFlag(
49 "remote_key_provisioning_native", "enable_rkpd",
50 /*default_value=*/"false");
51 return useRkpdFlagValue == "true";
Seth Moore81db3782022-01-18 15:58:47 -080052}
53
54} // namespace
David Zeuthenab3e5652019-10-28 13:32:48 -040055
David Zeuthenab3e5652019-10-28 13:32:48 -040056CredentialStore::CredentialStore(const std::string& dataPath, sp<IIdentityCredentialStore> hal)
57 : dataPath_(dataPath), hal_(hal) {}
58
59bool CredentialStore::init() {
David Zeuthena6f9fba2020-02-11 22:08:27 -050060 Status status = hal_->getHardwareInformation(&hwInfo_);
61 if (!status.isOk()) {
62 LOG(ERROR) << "Error getting hardware information: " << status.toString8();
David Zeuthenab3e5652019-10-28 13:32:48 -040063 return false;
64 }
David Zeuthen472e6c82020-10-16 11:50:13 -040065 halApiVersion_ = hal_->getInterfaceVersion();
David Zeuthena6f9fba2020-02-11 22:08:27 -050066
Seth Moore81db3782022-01-18 15:58:47 -080067 if (hwInfo_.isRemoteKeyProvisioningSupported) {
Tri Vo3ab6f052022-11-22 10:26:16 -080068 status = hal_->getRemotelyProvisionedComponent(&rpc_);
69 if (!status.isOk()) {
70 LOG(ERROR) << "Error getting remotely provisioned component: " << status;
Seth Moore81db3782022-01-18 15:58:47 -080071 return false;
72 }
Tri Vo3ab6f052022-11-22 10:26:16 -080073 useRkpd_ = useRkpd();
74
75 if (useRkpd_) {
76 uid_t callingUid = android::IPCThreadState::self()->getCallingUid();
77 auto rpcKeyFuture = getRpcKeyFuture(rpc_, callingUid);
78 if (!rpcKeyFuture) {
79 LOG(ERROR) << "Error in getRpcKeyFuture()";
80 return false;
81 }
82 rpcKeyFuture_ = std::move(*rpcKeyFuture);
83 } else {
84 keyPool_ = android::waitForService<IRemotelyProvisionedKeyPool>(
85 IRemotelyProvisionedKeyPool::descriptor);
86 if (!keyPool_) {
87 LOG(ERROR) << "Error getting IRemotelyProvisionedKeyPool HAL with service name '"
88 << IRemotelyProvisionedKeyPool::descriptor << "'";
89 return false;
90 }
91 }
Seth Moore81db3782022-01-18 15:58:47 -080092 }
93
David Zeuthen472e6c82020-10-16 11:50:13 -040094 LOG(INFO) << "Connected to Identity Credential HAL with API version " << halApiVersion_
95 << " and name '" << hwInfo_.credentialStoreName << "' authored by '"
96 << hwInfo_.credentialStoreAuthorName << "' with chunk size " << hwInfo_.dataChunkSize
97 << " and directoAccess set to " << (hwInfo_.isDirectAccess ? "true" : "false");
David Zeuthenab3e5652019-10-28 13:32:48 -040098 return true;
99}
100
101CredentialStore::~CredentialStore() {}
102
103Status CredentialStore::getSecurityHardwareInfo(SecurityHardwareInfoParcel* _aidl_return) {
104 SecurityHardwareInfoParcel info;
David Zeuthena6f9fba2020-02-11 22:08:27 -0500105 info.directAccess = hwInfo_.isDirectAccess;
106 info.supportedDocTypes = hwInfo_.supportedDocTypes;
David Zeuthenab3e5652019-10-28 13:32:48 -0400107 *_aidl_return = info;
108 return Status::ok();
109};
110
111Status CredentialStore::createCredential(const std::string& credentialName,
112 const std::string& docType,
113 sp<IWritableCredential>* _aidl_return) {
114 uid_t callingUid = android::IPCThreadState::self()->getCallingUid();
115 optional<bool> credentialExists =
116 CredentialData::credentialExists(dataPath_, callingUid, credentialName);
117 if (!credentialExists.has_value()) {
118 return Status::fromServiceSpecificError(
119 ERROR_GENERIC, "Error determining if credential with given name exists");
120 }
121 if (credentialExists.value()) {
122 return Status::fromServiceSpecificError(ERROR_ALREADY_PERSONALIZED,
123 "Credential with given name already exists");
124 }
125
David Zeuthena6f9fba2020-02-11 22:08:27 -0500126 if (hwInfo_.supportedDocTypes.size() > 0) {
127 if (std::find(hwInfo_.supportedDocTypes.begin(), hwInfo_.supportedDocTypes.end(),
128 docType) == hwInfo_.supportedDocTypes.end()) {
David Zeuthenab3e5652019-10-28 13:32:48 -0400129 return Status::fromServiceSpecificError(ERROR_DOCUMENT_TYPE_NOT_SUPPORTED,
130 "No support for given document type");
131 }
132 }
133
David Zeuthenab3e5652019-10-28 13:32:48 -0400134 sp<IWritableIdentityCredential> halWritableCredential;
David Zeuthena6f9fba2020-02-11 22:08:27 -0500135 Status status = hal_->createCredential(docType, false, &halWritableCredential);
136 if (!status.isOk()) {
137 return halStatusToGenericError(status);
David Zeuthenab3e5652019-10-28 13:32:48 -0400138 }
139
Seth Moore81db3782022-01-18 15:58:47 -0800140 if (hwInfo_.isRemoteKeyProvisioningSupported) {
141 status = setRemotelyProvisionedAttestationKey(halWritableCredential.get());
142 if (!status.isOk()) {
143 return halStatusToGenericError(status);
144 }
145 }
146
David Zeuthenab3e5652019-10-28 13:32:48 -0400147 sp<IWritableCredential> writableCredential = new WritableCredential(
David Zeuthen27407a52021-03-04 16:32:43 -0500148 dataPath_, credentialName, docType, false, hwInfo_, halWritableCredential);
David Zeuthenab3e5652019-10-28 13:32:48 -0400149 *_aidl_return = writableCredential;
150 return Status::ok();
151}
152
David Zeuthen045a2c82021-09-11 13:52:17 -0400153Status CredentialStore::getCredentialCommon(const std::string& credentialName, int32_t cipherSuite,
154 sp<IPresentationSession> halSessionBinder,
David Zeuthenab3e5652019-10-28 13:32:48 -0400155 sp<ICredential>* _aidl_return) {
156 *_aidl_return = nullptr;
157
158 uid_t callingUid = android::IPCThreadState::self()->getCallingUid();
159 optional<bool> credentialExists =
160 CredentialData::credentialExists(dataPath_, callingUid, credentialName);
161 if (!credentialExists.has_value()) {
162 return Status::fromServiceSpecificError(
163 ERROR_GENERIC, "Error determining if credential with given name exists");
164 }
165 if (!credentialExists.value()) {
166 return Status::fromServiceSpecificError(ERROR_NO_SUCH_CREDENTIAL,
167 "Credential with given name doesn't exist");
168 }
169
David Zeuthena6f9fba2020-02-11 22:08:27 -0500170 // Note: IdentityCredentialStore.java's CipherSuite enumeration and CipherSuite from the
171 // HAL is manually kept in sync. So this cast is safe.
David Zeuthen045a2c82021-09-11 13:52:17 -0400172 sp<Credential> credential =
173 new Credential(CipherSuite(cipherSuite), dataPath_, credentialName, callingUid, hwInfo_,
174 hal_, halSessionBinder, halApiVersion_);
David Zeuthenab3e5652019-10-28 13:32:48 -0400175
David Zeuthen472e6c82020-10-16 11:50:13 -0400176 Status loadStatus = credential->ensureOrReplaceHalBinder();
David Zeuthenab3e5652019-10-28 13:32:48 -0400177 if (!loadStatus.isOk()) {
178 LOG(ERROR) << "Error loading credential";
179 } else {
180 *_aidl_return = credential;
181 }
182 return loadStatus;
183}
184
David Zeuthen045a2c82021-09-11 13:52:17 -0400185Status CredentialStore::getCredentialByName(const std::string& credentialName, int32_t cipherSuite,
186 sp<ICredential>* _aidl_return) {
187 return getCredentialCommon(credentialName, cipherSuite, nullptr, _aidl_return);
188}
189
190Status CredentialStore::createPresentationSession(int32_t cipherSuite, sp<ISession>* _aidl_return) {
191 sp<IPresentationSession> halPresentationSession;
192 Status status =
193 hal_->createPresentationSession(CipherSuite(cipherSuite), &halPresentationSession);
194 if (!status.isOk()) {
195 return halStatusToGenericError(status);
196 }
197
198 *_aidl_return = new Session(cipherSuite, halPresentationSession, this);
199 return Status::ok();
200}
201
Seth Moore81db3782022-01-18 15:58:47 -0800202Status CredentialStore::setRemotelyProvisionedAttestationKey(
203 IWritableIdentityCredential* halWritableCredential) {
Tri Vo3ab6f052022-11-22 10:26:16 -0800204 std::vector<uint8_t> keyBlob;
205 std::vector<uint8_t> encodedCertChain;
206 Status status;
207
208 if (useRkpd_) {
209 if (rpcKeyFuture_.wait_for(std::chrono::seconds(10)) != std::future_status::ready) {
210 return Status::fromServiceSpecificError(
211 ERROR_GENERIC, "Waiting for remotely provisioned attestation key timed out");
212 }
213
214 std::optional<::android::security::rkp::RemotelyProvisionedKey> key = rpcKeyFuture_.get();
215 if (!key) {
216 return Status::fromServiceSpecificError(
217 ERROR_GENERIC, "Failed to get remotely provisioned attestation key");
218 }
219
220 if (key->keyBlob.empty()) {
221 return Status::fromServiceSpecificError(
222 ERROR_GENERIC, "Remotely provisioned attestation key blob is empty");
223 }
224
225 keyBlob = std::move(key->keyBlob);
226 encodedCertChain = std::move(key->encodedCertChain);
227 } else {
228 std::optional<std::string> rpcId = getRpcId(rpc_);
229 if (!rpcId) {
230 return Status::fromServiceSpecificError(
231 ERROR_GENERIC, "Error getting remotely provisioned component id");
232 }
233
234 uid_t callingUid = android::IPCThreadState::self()->getCallingUid();
235 ::android::security::remoteprovisioning::RemotelyProvisionedKey key;
236 Status status = keyPool_->getAttestationKey(callingUid, *rpcId, &key);
237 if (!status.isOk()) {
238 LOG(WARNING) << "Unable to fetch remotely provisioned attestation key, falling back "
239 << "to the factory-provisioned attestation key.";
240 return Status::ok();
241 }
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