xref: /aosp_15_r20/system/security/identity/CredentialStore.cpp (revision e1997b9af69e3155ead6e072d106a0077849ffba)
1*e1997b9aSAndroid Build Coastguard Worker /*
2*e1997b9aSAndroid Build Coastguard Worker  * Copyright (c) 2019, The Android Open Source Project
3*e1997b9aSAndroid Build Coastguard Worker  *
4*e1997b9aSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*e1997b9aSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*e1997b9aSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*e1997b9aSAndroid Build Coastguard Worker  *
8*e1997b9aSAndroid Build Coastguard Worker  *     http://www.apache.org/licenses/LICENSE-2.0
9*e1997b9aSAndroid Build Coastguard Worker  *
10*e1997b9aSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*e1997b9aSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*e1997b9aSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*e1997b9aSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*e1997b9aSAndroid Build Coastguard Worker  * limitations under the License.
15*e1997b9aSAndroid Build Coastguard Worker  */
16*e1997b9aSAndroid Build Coastguard Worker 
17*e1997b9aSAndroid Build Coastguard Worker #define LOG_TAG "credstore"
18*e1997b9aSAndroid Build Coastguard Worker 
19*e1997b9aSAndroid Build Coastguard Worker #include <algorithm>
20*e1997b9aSAndroid Build Coastguard Worker #include <optional>
21*e1997b9aSAndroid Build Coastguard Worker 
22*e1997b9aSAndroid Build Coastguard Worker #include <android-base/logging.h>
23*e1997b9aSAndroid Build Coastguard Worker #include <android/hardware/security/keymint/IRemotelyProvisionedComponent.h>
24*e1997b9aSAndroid Build Coastguard Worker #include <android/hardware/security/keymint/RpcHardwareInfo.h>
25*e1997b9aSAndroid Build Coastguard Worker #include <binder/IPCThreadState.h>
26*e1997b9aSAndroid Build Coastguard Worker #include <binder/IServiceManager.h>
27*e1997b9aSAndroid Build Coastguard Worker #include <rkp/support/rkpd_client.h>
28*e1997b9aSAndroid Build Coastguard Worker 
29*e1997b9aSAndroid Build Coastguard Worker #include "Credential.h"
30*e1997b9aSAndroid Build Coastguard Worker #include "CredentialData.h"
31*e1997b9aSAndroid Build Coastguard Worker #include "CredentialStore.h"
32*e1997b9aSAndroid Build Coastguard Worker #include "Session.h"
33*e1997b9aSAndroid Build Coastguard Worker #include "Util.h"
34*e1997b9aSAndroid Build Coastguard Worker #include "WritableCredential.h"
35*e1997b9aSAndroid Build Coastguard Worker 
36*e1997b9aSAndroid Build Coastguard Worker namespace android {
37*e1997b9aSAndroid Build Coastguard Worker namespace security {
38*e1997b9aSAndroid Build Coastguard Worker namespace identity {
39*e1997b9aSAndroid Build Coastguard Worker namespace {
40*e1997b9aSAndroid Build Coastguard Worker 
41*e1997b9aSAndroid Build Coastguard Worker using ::android::security::rkp::RemotelyProvisionedKey;
42*e1997b9aSAndroid Build Coastguard Worker using ::android::security::rkp::support::getRpcKey;
43*e1997b9aSAndroid Build Coastguard Worker 
44*e1997b9aSAndroid Build Coastguard Worker }  // namespace
45*e1997b9aSAndroid Build Coastguard Worker 
CredentialStore(const std::string & dataPath,sp<IIdentityCredentialStore> hal)46*e1997b9aSAndroid Build Coastguard Worker CredentialStore::CredentialStore(const std::string& dataPath, sp<IIdentityCredentialStore> hal)
47*e1997b9aSAndroid Build Coastguard Worker     : dataPath_(dataPath), hal_(hal) {}
48*e1997b9aSAndroid Build Coastguard Worker 
init()49*e1997b9aSAndroid Build Coastguard Worker bool CredentialStore::init() {
50*e1997b9aSAndroid Build Coastguard Worker     Status status = hal_->getHardwareInformation(&hwInfo_);
51*e1997b9aSAndroid Build Coastguard Worker     if (!status.isOk()) {
52*e1997b9aSAndroid Build Coastguard Worker         LOG(ERROR) << "Error getting hardware information: " << status.toString8();
53*e1997b9aSAndroid Build Coastguard Worker         return false;
54*e1997b9aSAndroid Build Coastguard Worker     }
55*e1997b9aSAndroid Build Coastguard Worker     halApiVersion_ = hal_->getInterfaceVersion();
56*e1997b9aSAndroid Build Coastguard Worker 
57*e1997b9aSAndroid Build Coastguard Worker     if (hwInfo_.isRemoteKeyProvisioningSupported) {
58*e1997b9aSAndroid Build Coastguard Worker         status = hal_->getRemotelyProvisionedComponent(&rpc_);
59*e1997b9aSAndroid Build Coastguard Worker         if (!status.isOk()) {
60*e1997b9aSAndroid Build Coastguard Worker             LOG(ERROR) << "Error getting remotely provisioned component: " << status;
61*e1997b9aSAndroid Build Coastguard Worker             return false;
62*e1997b9aSAndroid Build Coastguard Worker         }
63*e1997b9aSAndroid Build Coastguard Worker     }
64*e1997b9aSAndroid Build Coastguard Worker 
65*e1997b9aSAndroid Build Coastguard Worker     LOG(INFO) << "Connected to Identity Credential HAL with API version " << halApiVersion_
66*e1997b9aSAndroid Build Coastguard Worker               << " and name '" << hwInfo_.credentialStoreName << "' authored by '"
67*e1997b9aSAndroid Build Coastguard Worker               << hwInfo_.credentialStoreAuthorName << "' with chunk size " << hwInfo_.dataChunkSize
68*e1997b9aSAndroid Build Coastguard Worker               << " directoAccess set to " << (hwInfo_.isDirectAccess ? "true" : "false")
69*e1997b9aSAndroid Build Coastguard Worker               << " and remote key provisioning support "
70*e1997b9aSAndroid Build Coastguard Worker               << (hwInfo_.isRemoteKeyProvisioningSupported ? "enabled" : "disabled");
71*e1997b9aSAndroid Build Coastguard Worker     return true;
72*e1997b9aSAndroid Build Coastguard Worker }
73*e1997b9aSAndroid Build Coastguard Worker 
~CredentialStore()74*e1997b9aSAndroid Build Coastguard Worker CredentialStore::~CredentialStore() {}
75*e1997b9aSAndroid Build Coastguard Worker 
getSecurityHardwareInfo(SecurityHardwareInfoParcel * _aidl_return)76*e1997b9aSAndroid Build Coastguard Worker Status CredentialStore::getSecurityHardwareInfo(SecurityHardwareInfoParcel* _aidl_return) {
77*e1997b9aSAndroid Build Coastguard Worker     SecurityHardwareInfoParcel info;
78*e1997b9aSAndroid Build Coastguard Worker     info.directAccess = hwInfo_.isDirectAccess;
79*e1997b9aSAndroid Build Coastguard Worker     info.supportedDocTypes = hwInfo_.supportedDocTypes;
80*e1997b9aSAndroid Build Coastguard Worker     *_aidl_return = info;
81*e1997b9aSAndroid Build Coastguard Worker     return Status::ok();
82*e1997b9aSAndroid Build Coastguard Worker };
83*e1997b9aSAndroid Build Coastguard Worker 
createCredential(const std::string & credentialName,const std::string & docType,sp<IWritableCredential> * _aidl_return)84*e1997b9aSAndroid Build Coastguard Worker Status CredentialStore::createCredential(const std::string& credentialName,
85*e1997b9aSAndroid Build Coastguard Worker                                          const std::string& docType,
86*e1997b9aSAndroid Build Coastguard Worker                                          sp<IWritableCredential>* _aidl_return) {
87*e1997b9aSAndroid Build Coastguard Worker     uid_t callingUid = android::IPCThreadState::self()->getCallingUid();
88*e1997b9aSAndroid Build Coastguard Worker     optional<bool> credentialExists =
89*e1997b9aSAndroid Build Coastguard Worker         CredentialData::credentialExists(dataPath_, callingUid, credentialName);
90*e1997b9aSAndroid Build Coastguard Worker     if (!credentialExists.has_value()) {
91*e1997b9aSAndroid Build Coastguard Worker         return Status::fromServiceSpecificError(
92*e1997b9aSAndroid Build Coastguard Worker             ERROR_GENERIC, "Error determining if credential with given name exists");
93*e1997b9aSAndroid Build Coastguard Worker     }
94*e1997b9aSAndroid Build Coastguard Worker     if (credentialExists.value()) {
95*e1997b9aSAndroid Build Coastguard Worker         return Status::fromServiceSpecificError(ERROR_ALREADY_PERSONALIZED,
96*e1997b9aSAndroid Build Coastguard Worker                                                 "Credential with given name already exists");
97*e1997b9aSAndroid Build Coastguard Worker     }
98*e1997b9aSAndroid Build Coastguard Worker 
99*e1997b9aSAndroid Build Coastguard Worker     if (hwInfo_.supportedDocTypes.size() > 0) {
100*e1997b9aSAndroid Build Coastguard Worker         if (std::find(hwInfo_.supportedDocTypes.begin(), hwInfo_.supportedDocTypes.end(),
101*e1997b9aSAndroid Build Coastguard Worker                       docType) == hwInfo_.supportedDocTypes.end()) {
102*e1997b9aSAndroid Build Coastguard Worker             return Status::fromServiceSpecificError(ERROR_DOCUMENT_TYPE_NOT_SUPPORTED,
103*e1997b9aSAndroid Build Coastguard Worker                                                     "No support for given document type");
104*e1997b9aSAndroid Build Coastguard Worker         }
105*e1997b9aSAndroid Build Coastguard Worker     }
106*e1997b9aSAndroid Build Coastguard Worker 
107*e1997b9aSAndroid Build Coastguard Worker     sp<IWritableIdentityCredential> halWritableCredential;
108*e1997b9aSAndroid Build Coastguard Worker     Status status = hal_->createCredential(docType, false, &halWritableCredential);
109*e1997b9aSAndroid Build Coastguard Worker     if (!status.isOk()) {
110*e1997b9aSAndroid Build Coastguard Worker         return halStatusToGenericError(status);
111*e1997b9aSAndroid Build Coastguard Worker     }
112*e1997b9aSAndroid Build Coastguard Worker 
113*e1997b9aSAndroid Build Coastguard Worker     if (hwInfo_.isRemoteKeyProvisioningSupported) {
114*e1997b9aSAndroid Build Coastguard Worker         status = setRemotelyProvisionedAttestationKey(halWritableCredential.get());
115*e1997b9aSAndroid Build Coastguard Worker         if (!status.isOk()) {
116*e1997b9aSAndroid Build Coastguard Worker             LOG(WARNING) << status.toString8()
117*e1997b9aSAndroid Build Coastguard Worker                          << "\nUnable to fetch remotely provisioned attestation key, falling back "
118*e1997b9aSAndroid Build Coastguard Worker                          << "to the factory-provisioned attestation key.";
119*e1997b9aSAndroid Build Coastguard Worker         }
120*e1997b9aSAndroid Build Coastguard Worker     }
121*e1997b9aSAndroid Build Coastguard Worker 
122*e1997b9aSAndroid Build Coastguard Worker     sp<IWritableCredential> writableCredential = new WritableCredential(
123*e1997b9aSAndroid Build Coastguard Worker         dataPath_, credentialName, docType, false, hwInfo_, halWritableCredential);
124*e1997b9aSAndroid Build Coastguard Worker     *_aidl_return = writableCredential;
125*e1997b9aSAndroid Build Coastguard Worker     return Status::ok();
126*e1997b9aSAndroid Build Coastguard Worker }
127*e1997b9aSAndroid Build Coastguard Worker 
getCredentialCommon(const std::string & credentialName,int32_t cipherSuite,sp<IPresentationSession> halSessionBinder,sp<ICredential> * _aidl_return)128*e1997b9aSAndroid Build Coastguard Worker Status CredentialStore::getCredentialCommon(const std::string& credentialName, int32_t cipherSuite,
129*e1997b9aSAndroid Build Coastguard Worker                                             sp<IPresentationSession> halSessionBinder,
130*e1997b9aSAndroid Build Coastguard Worker                                             sp<ICredential>* _aidl_return) {
131*e1997b9aSAndroid Build Coastguard Worker     *_aidl_return = nullptr;
132*e1997b9aSAndroid Build Coastguard Worker 
133*e1997b9aSAndroid Build Coastguard Worker     uid_t callingUid = android::IPCThreadState::self()->getCallingUid();
134*e1997b9aSAndroid Build Coastguard Worker     optional<bool> credentialExists =
135*e1997b9aSAndroid Build Coastguard Worker         CredentialData::credentialExists(dataPath_, callingUid, credentialName);
136*e1997b9aSAndroid Build Coastguard Worker     if (!credentialExists.has_value()) {
137*e1997b9aSAndroid Build Coastguard Worker         return Status::fromServiceSpecificError(
138*e1997b9aSAndroid Build Coastguard Worker             ERROR_GENERIC, "Error determining if credential with given name exists");
139*e1997b9aSAndroid Build Coastguard Worker     }
140*e1997b9aSAndroid Build Coastguard Worker     if (!credentialExists.value()) {
141*e1997b9aSAndroid Build Coastguard Worker         return Status::fromServiceSpecificError(ERROR_NO_SUCH_CREDENTIAL,
142*e1997b9aSAndroid Build Coastguard Worker                                                 "Credential with given name doesn't exist");
143*e1997b9aSAndroid Build Coastguard Worker     }
144*e1997b9aSAndroid Build Coastguard Worker 
145*e1997b9aSAndroid Build Coastguard Worker     // Note: IdentityCredentialStore.java's CipherSuite enumeration and CipherSuite from the
146*e1997b9aSAndroid Build Coastguard Worker     // HAL is manually kept in sync. So this cast is safe.
147*e1997b9aSAndroid Build Coastguard Worker     sp<Credential> credential =
148*e1997b9aSAndroid Build Coastguard Worker         new Credential(CipherSuite(cipherSuite), dataPath_, credentialName, callingUid, hwInfo_,
149*e1997b9aSAndroid Build Coastguard Worker                        hal_, halSessionBinder, halApiVersion_);
150*e1997b9aSAndroid Build Coastguard Worker 
151*e1997b9aSAndroid Build Coastguard Worker     Status loadStatus = credential->ensureOrReplaceHalBinder();
152*e1997b9aSAndroid Build Coastguard Worker     if (!loadStatus.isOk()) {
153*e1997b9aSAndroid Build Coastguard Worker         LOG(ERROR) << "Error loading credential";
154*e1997b9aSAndroid Build Coastguard Worker     } else {
155*e1997b9aSAndroid Build Coastguard Worker         *_aidl_return = credential;
156*e1997b9aSAndroid Build Coastguard Worker     }
157*e1997b9aSAndroid Build Coastguard Worker     return loadStatus;
158*e1997b9aSAndroid Build Coastguard Worker }
159*e1997b9aSAndroid Build Coastguard Worker 
getCredentialByName(const std::string & credentialName,int32_t cipherSuite,sp<ICredential> * _aidl_return)160*e1997b9aSAndroid Build Coastguard Worker Status CredentialStore::getCredentialByName(const std::string& credentialName, int32_t cipherSuite,
161*e1997b9aSAndroid Build Coastguard Worker                                             sp<ICredential>* _aidl_return) {
162*e1997b9aSAndroid Build Coastguard Worker     return getCredentialCommon(credentialName, cipherSuite, nullptr, _aidl_return);
163*e1997b9aSAndroid Build Coastguard Worker }
164*e1997b9aSAndroid Build Coastguard Worker 
createPresentationSession(int32_t cipherSuite,sp<ISession> * _aidl_return)165*e1997b9aSAndroid Build Coastguard Worker Status CredentialStore::createPresentationSession(int32_t cipherSuite, sp<ISession>* _aidl_return) {
166*e1997b9aSAndroid Build Coastguard Worker     sp<IPresentationSession> halPresentationSession;
167*e1997b9aSAndroid Build Coastguard Worker     Status status =
168*e1997b9aSAndroid Build Coastguard Worker         hal_->createPresentationSession(CipherSuite(cipherSuite), &halPresentationSession);
169*e1997b9aSAndroid Build Coastguard Worker     if (!status.isOk()) {
170*e1997b9aSAndroid Build Coastguard Worker         return halStatusToGenericError(status);
171*e1997b9aSAndroid Build Coastguard Worker     }
172*e1997b9aSAndroid Build Coastguard Worker 
173*e1997b9aSAndroid Build Coastguard Worker     *_aidl_return = new Session(cipherSuite, halPresentationSession, this);
174*e1997b9aSAndroid Build Coastguard Worker     return Status::ok();
175*e1997b9aSAndroid Build Coastguard Worker }
176*e1997b9aSAndroid Build Coastguard Worker 
setRemotelyProvisionedAttestationKey(IWritableIdentityCredential * halWritableCredential)177*e1997b9aSAndroid Build Coastguard Worker Status CredentialStore::setRemotelyProvisionedAttestationKey(
178*e1997b9aSAndroid Build Coastguard Worker     IWritableIdentityCredential* halWritableCredential) {
179*e1997b9aSAndroid Build Coastguard Worker     std::vector<uint8_t> keyBlob;
180*e1997b9aSAndroid Build Coastguard Worker     std::vector<uint8_t> encodedCertChain;
181*e1997b9aSAndroid Build Coastguard Worker     Status status;
182*e1997b9aSAndroid Build Coastguard Worker 
183*e1997b9aSAndroid Build Coastguard Worker     LOG(INFO) << "Fetching attestation key from RKPD";
184*e1997b9aSAndroid Build Coastguard Worker 
185*e1997b9aSAndroid Build Coastguard Worker     uid_t callingUid = android::IPCThreadState::self()->getCallingUid();
186*e1997b9aSAndroid Build Coastguard Worker     std::optional<RemotelyProvisionedKey> key = getRpcKey(rpc_, callingUid);
187*e1997b9aSAndroid Build Coastguard Worker     if (!key) {
188*e1997b9aSAndroid Build Coastguard Worker         return Status::fromServiceSpecificError(
189*e1997b9aSAndroid Build Coastguard Worker             ERROR_GENERIC, "Failed to get remotely provisioned attestation key");
190*e1997b9aSAndroid Build Coastguard Worker     }
191*e1997b9aSAndroid Build Coastguard Worker 
192*e1997b9aSAndroid Build Coastguard Worker     if (key->keyBlob.empty()) {
193*e1997b9aSAndroid Build Coastguard Worker         return Status::fromServiceSpecificError(
194*e1997b9aSAndroid Build Coastguard Worker             ERROR_GENERIC, "Remotely provisioned attestation key blob is empty");
195*e1997b9aSAndroid Build Coastguard Worker     }
196*e1997b9aSAndroid Build Coastguard Worker 
197*e1997b9aSAndroid Build Coastguard Worker     keyBlob = std::move(key->keyBlob);
198*e1997b9aSAndroid Build Coastguard Worker     encodedCertChain = std::move(key->encodedCertChain);
199*e1997b9aSAndroid Build Coastguard Worker 
200*e1997b9aSAndroid Build Coastguard Worker     status = halWritableCredential->setRemotelyProvisionedAttestationKey(keyBlob, encodedCertChain);
201*e1997b9aSAndroid Build Coastguard Worker     if (!status.isOk()) {
202*e1997b9aSAndroid Build Coastguard Worker         LOG(ERROR) << "Error setting remotely provisioned attestation key on credential";
203*e1997b9aSAndroid Build Coastguard Worker         return status;
204*e1997b9aSAndroid Build Coastguard Worker     }
205*e1997b9aSAndroid Build Coastguard Worker     return Status::ok();
206*e1997b9aSAndroid Build Coastguard Worker }
207*e1997b9aSAndroid Build Coastguard Worker 
208*e1997b9aSAndroid Build Coastguard Worker }  // namespace identity
209*e1997b9aSAndroid Build Coastguard Worker }  // namespace security
210*e1997b9aSAndroid Build Coastguard Worker }  // namespace android
211