xref: /aosp_15_r20/system/security/identity/WritableCredential.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 <android-base/logging.h>
20*e1997b9aSAndroid Build Coastguard Worker #include <android/hardware/identity/support/IdentityCredentialSupport.h>
21*e1997b9aSAndroid Build Coastguard Worker #include <android/security/identity/ICredentialStore.h>
22*e1997b9aSAndroid Build Coastguard Worker #include <binder/IPCThreadState.h>
23*e1997b9aSAndroid Build Coastguard Worker #include <cppbor.h>
24*e1997b9aSAndroid Build Coastguard Worker #include <cppbor_parse.h>
25*e1997b9aSAndroid Build Coastguard Worker #include <keystore/keystore_attestation_id.h>
26*e1997b9aSAndroid Build Coastguard Worker 
27*e1997b9aSAndroid Build Coastguard Worker #include "CredentialData.h"
28*e1997b9aSAndroid Build Coastguard Worker #include "Util.h"
29*e1997b9aSAndroid Build Coastguard Worker #include "WritableCredential.h"
30*e1997b9aSAndroid Build Coastguard Worker 
31*e1997b9aSAndroid Build Coastguard Worker namespace android {
32*e1997b9aSAndroid Build Coastguard Worker namespace security {
33*e1997b9aSAndroid Build Coastguard Worker namespace identity {
34*e1997b9aSAndroid Build Coastguard Worker 
35*e1997b9aSAndroid Build Coastguard Worker using ::std::pair;
36*e1997b9aSAndroid Build Coastguard Worker 
37*e1997b9aSAndroid Build Coastguard Worker using ::android::hardware::identity::SecureAccessControlProfile;
38*e1997b9aSAndroid Build Coastguard Worker 
39*e1997b9aSAndroid Build Coastguard Worker using ::android::hardware::identity::support::chunkVector;
40*e1997b9aSAndroid Build Coastguard Worker 
WritableCredential(const string & dataPath,const string & credentialName,const string & docType,bool isUpdate,HardwareInformation hwInfo,sp<IWritableIdentityCredential> halBinder)41*e1997b9aSAndroid Build Coastguard Worker WritableCredential::WritableCredential(const string& dataPath, const string& credentialName,
42*e1997b9aSAndroid Build Coastguard Worker                                        const string& docType, bool isUpdate,
43*e1997b9aSAndroid Build Coastguard Worker                                        HardwareInformation hwInfo,
44*e1997b9aSAndroid Build Coastguard Worker                                        sp<IWritableIdentityCredential> halBinder)
45*e1997b9aSAndroid Build Coastguard Worker     : dataPath_(dataPath), credentialName_(credentialName), docType_(docType), isUpdate_(isUpdate),
46*e1997b9aSAndroid Build Coastguard Worker       hwInfo_(std::move(hwInfo)), halBinder_(halBinder) {}
47*e1997b9aSAndroid Build Coastguard Worker 
~WritableCredential()48*e1997b9aSAndroid Build Coastguard Worker WritableCredential::~WritableCredential() {}
49*e1997b9aSAndroid Build Coastguard Worker 
setCredentialToReloadWhenUpdated(sp<Credential> credential)50*e1997b9aSAndroid Build Coastguard Worker void WritableCredential::setCredentialToReloadWhenUpdated(sp<Credential> credential) {
51*e1997b9aSAndroid Build Coastguard Worker     credentialToReloadWhenUpdated_ = credential;
52*e1997b9aSAndroid Build Coastguard Worker }
53*e1997b9aSAndroid Build Coastguard Worker 
ensureAttestationCertificateExists(const vector<uint8_t> & challenge)54*e1997b9aSAndroid Build Coastguard Worker Status WritableCredential::ensureAttestationCertificateExists(const vector<uint8_t>& challenge) {
55*e1997b9aSAndroid Build Coastguard Worker     if (!attestationCertificate_.empty()) {
56*e1997b9aSAndroid Build Coastguard Worker         return Status::ok();
57*e1997b9aSAndroid Build Coastguard Worker     }
58*e1997b9aSAndroid Build Coastguard Worker 
59*e1997b9aSAndroid Build Coastguard Worker     const int32_t callingUid = IPCThreadState::self()->getCallingUid();
60*e1997b9aSAndroid Build Coastguard Worker     auto asn1AttestationId = android::security::gather_attestation_application_id(callingUid);
61*e1997b9aSAndroid Build Coastguard Worker     if (!asn1AttestationId.isOk()) {
62*e1997b9aSAndroid Build Coastguard Worker         LOG(ERROR) << "Failed gathering AttestionApplicationId";
63*e1997b9aSAndroid Build Coastguard Worker         return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
64*e1997b9aSAndroid Build Coastguard Worker                                                 "Failed gathering AttestionApplicationId");
65*e1997b9aSAndroid Build Coastguard Worker     }
66*e1997b9aSAndroid Build Coastguard Worker 
67*e1997b9aSAndroid Build Coastguard Worker     vector<Certificate> certificateChain;
68*e1997b9aSAndroid Build Coastguard Worker     Status status = halBinder_->getAttestationCertificate(asn1AttestationId.value(), challenge,
69*e1997b9aSAndroid Build Coastguard Worker                                                           &certificateChain);
70*e1997b9aSAndroid Build Coastguard Worker     if (!status.isOk()) {
71*e1997b9aSAndroid Build Coastguard Worker         LOG(ERROR) << "Error calling getAttestationCertificate()";
72*e1997b9aSAndroid Build Coastguard Worker         return halStatusToGenericError(status);
73*e1997b9aSAndroid Build Coastguard Worker     }
74*e1997b9aSAndroid Build Coastguard Worker 
75*e1997b9aSAndroid Build Coastguard Worker     vector<vector<uint8_t>> splitCerts;
76*e1997b9aSAndroid Build Coastguard Worker     for (const auto& cert : certificateChain) {
77*e1997b9aSAndroid Build Coastguard Worker         splitCerts.push_back(cert.encodedCertificate);
78*e1997b9aSAndroid Build Coastguard Worker     }
79*e1997b9aSAndroid Build Coastguard Worker     attestationCertificate_ =
80*e1997b9aSAndroid Build Coastguard Worker         ::android::hardware::identity::support::certificateChainJoin(splitCerts);
81*e1997b9aSAndroid Build Coastguard Worker 
82*e1997b9aSAndroid Build Coastguard Worker     return Status::ok();
83*e1997b9aSAndroid Build Coastguard Worker }
84*e1997b9aSAndroid Build Coastguard Worker 
getCredentialKeyCertificateChain(const vector<uint8_t> & challenge,vector<uint8_t> * _aidl_return)85*e1997b9aSAndroid Build Coastguard Worker Status WritableCredential::getCredentialKeyCertificateChain(const vector<uint8_t>& challenge,
86*e1997b9aSAndroid Build Coastguard Worker                                                             vector<uint8_t>* _aidl_return) {
87*e1997b9aSAndroid Build Coastguard Worker     if (isUpdate_) {
88*e1997b9aSAndroid Build Coastguard Worker         return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
89*e1997b9aSAndroid Build Coastguard Worker                                                 "Cannot be called for an update");
90*e1997b9aSAndroid Build Coastguard Worker     }
91*e1997b9aSAndroid Build Coastguard Worker     Status ensureStatus = ensureAttestationCertificateExists(challenge);
92*e1997b9aSAndroid Build Coastguard Worker     if (!ensureStatus.isOk()) {
93*e1997b9aSAndroid Build Coastguard Worker         return ensureStatus;
94*e1997b9aSAndroid Build Coastguard Worker     }
95*e1997b9aSAndroid Build Coastguard Worker 
96*e1997b9aSAndroid Build Coastguard Worker     *_aidl_return = attestationCertificate_;
97*e1997b9aSAndroid Build Coastguard Worker     return Status::ok();
98*e1997b9aSAndroid Build Coastguard Worker }
99*e1997b9aSAndroid Build Coastguard Worker 
setAttestationCertificate(const vector<uint8_t> & attestationCertificate)100*e1997b9aSAndroid Build Coastguard Worker void WritableCredential::setAttestationCertificate(const vector<uint8_t>& attestationCertificate) {
101*e1997b9aSAndroid Build Coastguard Worker     attestationCertificate_ = attestationCertificate;
102*e1997b9aSAndroid Build Coastguard Worker }
103*e1997b9aSAndroid Build Coastguard Worker 
setAvailableAuthenticationKeys(int keyCount,int maxUsesPerKey,int64_t minValidTimeMillis)104*e1997b9aSAndroid Build Coastguard Worker void WritableCredential::setAvailableAuthenticationKeys(int keyCount, int maxUsesPerKey,
105*e1997b9aSAndroid Build Coastguard Worker                                                         int64_t minValidTimeMillis) {
106*e1997b9aSAndroid Build Coastguard Worker     keyCount_ = keyCount;
107*e1997b9aSAndroid Build Coastguard Worker     maxUsesPerKey_ = maxUsesPerKey;
108*e1997b9aSAndroid Build Coastguard Worker     minValidTimeMillis_ = minValidTimeMillis;
109*e1997b9aSAndroid Build Coastguard Worker }
110*e1997b9aSAndroid Build Coastguard Worker 
calcExpectedProofOfProvisioningSize(const vector<AccessControlProfileParcel> & accessControlProfiles,const vector<EntryNamespaceParcel> & entryNamespaces)111*e1997b9aSAndroid Build Coastguard Worker ssize_t WritableCredential::calcExpectedProofOfProvisioningSize(
112*e1997b9aSAndroid Build Coastguard Worker     const vector<AccessControlProfileParcel>& accessControlProfiles,
113*e1997b9aSAndroid Build Coastguard Worker     const vector<EntryNamespaceParcel>& entryNamespaces) {
114*e1997b9aSAndroid Build Coastguard Worker 
115*e1997b9aSAndroid Build Coastguard Worker     // Right now, we calculate the size by simply just calculating the
116*e1997b9aSAndroid Build Coastguard Worker     // CBOR. There's a little bit of overhead associated with this (as compared
117*e1997b9aSAndroid Build Coastguard Worker     // to just adding up sizes) but it's a lot simpler and robust. In the future
118*e1997b9aSAndroid Build Coastguard Worker     // if this turns out to be a problem, we can optimize it.
119*e1997b9aSAndroid Build Coastguard Worker     //
120*e1997b9aSAndroid Build Coastguard Worker 
121*e1997b9aSAndroid Build Coastguard Worker     cppbor::Array acpArray;
122*e1997b9aSAndroid Build Coastguard Worker     for (const AccessControlProfileParcel& profile : accessControlProfiles) {
123*e1997b9aSAndroid Build Coastguard Worker         cppbor::Map map;
124*e1997b9aSAndroid Build Coastguard Worker         map.add("id", profile.id);
125*e1997b9aSAndroid Build Coastguard Worker         if (profile.readerCertificate.size() > 0) {
126*e1997b9aSAndroid Build Coastguard Worker             map.add("readerCertificate", cppbor::Bstr(profile.readerCertificate));
127*e1997b9aSAndroid Build Coastguard Worker         }
128*e1997b9aSAndroid Build Coastguard Worker         if (profile.userAuthenticationRequired) {
129*e1997b9aSAndroid Build Coastguard Worker             map.add("userAuthenticationRequired", profile.userAuthenticationRequired);
130*e1997b9aSAndroid Build Coastguard Worker             map.add("timeoutMillis", profile.userAuthenticationTimeoutMillis);
131*e1997b9aSAndroid Build Coastguard Worker         }
132*e1997b9aSAndroid Build Coastguard Worker         acpArray.add(std::move(map));
133*e1997b9aSAndroid Build Coastguard Worker     }
134*e1997b9aSAndroid Build Coastguard Worker 
135*e1997b9aSAndroid Build Coastguard Worker     cppbor::Map dataMap;
136*e1997b9aSAndroid Build Coastguard Worker     for (const EntryNamespaceParcel& ensParcel : entryNamespaces) {
137*e1997b9aSAndroid Build Coastguard Worker         cppbor::Array entriesArray;
138*e1997b9aSAndroid Build Coastguard Worker         for (const EntryParcel& eParcel : ensParcel.entries) {
139*e1997b9aSAndroid Build Coastguard Worker             // TODO: ideally do do this without parsing the data (but still validate data is valid
140*e1997b9aSAndroid Build Coastguard Worker             // CBOR).
141*e1997b9aSAndroid Build Coastguard Worker             auto [itemForValue, _, _2] = cppbor::parse(eParcel.value);
142*e1997b9aSAndroid Build Coastguard Worker             if (itemForValue == nullptr) {
143*e1997b9aSAndroid Build Coastguard Worker                 return -1;
144*e1997b9aSAndroid Build Coastguard Worker             }
145*e1997b9aSAndroid Build Coastguard Worker             cppbor::Map entryMap;
146*e1997b9aSAndroid Build Coastguard Worker             entryMap.add("name", eParcel.name);
147*e1997b9aSAndroid Build Coastguard Worker             entryMap.add("value", std::move(itemForValue));
148*e1997b9aSAndroid Build Coastguard Worker             cppbor::Array acpIdsArray;
149*e1997b9aSAndroid Build Coastguard Worker             for (int32_t id : eParcel.accessControlProfileIds) {
150*e1997b9aSAndroid Build Coastguard Worker                 acpIdsArray.add(id);
151*e1997b9aSAndroid Build Coastguard Worker             }
152*e1997b9aSAndroid Build Coastguard Worker             entryMap.add("accessControlProfiles", std::move(acpIdsArray));
153*e1997b9aSAndroid Build Coastguard Worker             entriesArray.add(std::move(entryMap));
154*e1997b9aSAndroid Build Coastguard Worker         }
155*e1997b9aSAndroid Build Coastguard Worker         dataMap.add(ensParcel.namespaceName, std::move(entriesArray));
156*e1997b9aSAndroid Build Coastguard Worker     }
157*e1997b9aSAndroid Build Coastguard Worker 
158*e1997b9aSAndroid Build Coastguard Worker     cppbor::Array array;
159*e1997b9aSAndroid Build Coastguard Worker     array.add("ProofOfProvisioning");
160*e1997b9aSAndroid Build Coastguard Worker     array.add(docType_);
161*e1997b9aSAndroid Build Coastguard Worker     array.add(std::move(acpArray));
162*e1997b9aSAndroid Build Coastguard Worker     array.add(std::move(dataMap));
163*e1997b9aSAndroid Build Coastguard Worker     array.add(false);  // testCredential
164*e1997b9aSAndroid Build Coastguard Worker     return array.encode().size();
165*e1997b9aSAndroid Build Coastguard Worker }
166*e1997b9aSAndroid Build Coastguard Worker 
167*e1997b9aSAndroid Build Coastguard Worker Status
personalize(const vector<AccessControlProfileParcel> & accessControlProfiles,const vector<EntryNamespaceParcel> & entryNamespaces,int64_t secureUserId,vector<uint8_t> * _aidl_return)168*e1997b9aSAndroid Build Coastguard Worker WritableCredential::personalize(const vector<AccessControlProfileParcel>& accessControlProfiles,
169*e1997b9aSAndroid Build Coastguard Worker                                 const vector<EntryNamespaceParcel>& entryNamespaces,
170*e1997b9aSAndroid Build Coastguard Worker                                 int64_t secureUserId, vector<uint8_t>* _aidl_return) {
171*e1997b9aSAndroid Build Coastguard Worker     if (!isUpdate_) {
172*e1997b9aSAndroid Build Coastguard Worker         Status ensureStatus =
173*e1997b9aSAndroid Build Coastguard Worker             ensureAttestationCertificateExists({0x00});  // Challenge cannot be empty.
174*e1997b9aSAndroid Build Coastguard Worker         if (!ensureStatus.isOk()) {
175*e1997b9aSAndroid Build Coastguard Worker             return ensureStatus;
176*e1997b9aSAndroid Build Coastguard Worker         }
177*e1997b9aSAndroid Build Coastguard Worker     }
178*e1997b9aSAndroid Build Coastguard Worker 
179*e1997b9aSAndroid Build Coastguard Worker     uid_t callingUid = android::IPCThreadState::self()->getCallingUid();
180*e1997b9aSAndroid Build Coastguard Worker     CredentialData data = CredentialData(dataPath_, callingUid, credentialName_);
181*e1997b9aSAndroid Build Coastguard Worker 
182*e1997b9aSAndroid Build Coastguard Worker     // Note: The value 0 is used to convey that no user-authentication is needed for this
183*e1997b9aSAndroid Build Coastguard Worker     // credential. This is to allow creating credentials w/o user authentication on devices
184*e1997b9aSAndroid Build Coastguard Worker     // where Secure lock screen is not enabled.
185*e1997b9aSAndroid Build Coastguard Worker     data.setSecureUserId(secureUserId);
186*e1997b9aSAndroid Build Coastguard Worker 
187*e1997b9aSAndroid Build Coastguard Worker     data.setAttestationCertificate(attestationCertificate_);
188*e1997b9aSAndroid Build Coastguard Worker 
189*e1997b9aSAndroid Build Coastguard Worker     vector<int32_t> entryCounts;
190*e1997b9aSAndroid Build Coastguard Worker     for (const EntryNamespaceParcel& ensParcel : entryNamespaces) {
191*e1997b9aSAndroid Build Coastguard Worker         entryCounts.push_back(ensParcel.entries.size());
192*e1997b9aSAndroid Build Coastguard Worker     }
193*e1997b9aSAndroid Build Coastguard Worker 
194*e1997b9aSAndroid Build Coastguard Worker     ssize_t expectedPoPSize =
195*e1997b9aSAndroid Build Coastguard Worker         calcExpectedProofOfProvisioningSize(accessControlProfiles, entryNamespaces);
196*e1997b9aSAndroid Build Coastguard Worker     if (expectedPoPSize < 0) {
197*e1997b9aSAndroid Build Coastguard Worker         return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
198*e1997b9aSAndroid Build Coastguard Worker                                                 "Data is not valid CBOR");
199*e1997b9aSAndroid Build Coastguard Worker     }
200*e1997b9aSAndroid Build Coastguard Worker     // This is not catastrophic, we might be dealing with a version 1 implementation which
201*e1997b9aSAndroid Build Coastguard Worker     // doesn't have this method.
202*e1997b9aSAndroid Build Coastguard Worker     Status status = halBinder_->setExpectedProofOfProvisioningSize(expectedPoPSize);
203*e1997b9aSAndroid Build Coastguard Worker     if (!status.isOk()) {
204*e1997b9aSAndroid Build Coastguard Worker         LOG(INFO) << "Failed setting expected ProofOfProvisioning size, assuming V1 HAL "
205*e1997b9aSAndroid Build Coastguard Worker                   << "and continuing";
206*e1997b9aSAndroid Build Coastguard Worker     }
207*e1997b9aSAndroid Build Coastguard Worker 
208*e1997b9aSAndroid Build Coastguard Worker     status = halBinder_->startPersonalization(accessControlProfiles.size(), entryCounts);
209*e1997b9aSAndroid Build Coastguard Worker     if (!status.isOk()) {
210*e1997b9aSAndroid Build Coastguard Worker         return halStatusToGenericError(status);
211*e1997b9aSAndroid Build Coastguard Worker     }
212*e1997b9aSAndroid Build Coastguard Worker 
213*e1997b9aSAndroid Build Coastguard Worker     for (const AccessControlProfileParcel& acpParcel : accessControlProfiles) {
214*e1997b9aSAndroid Build Coastguard Worker         Certificate certificate;
215*e1997b9aSAndroid Build Coastguard Worker         certificate.encodedCertificate = acpParcel.readerCertificate;
216*e1997b9aSAndroid Build Coastguard Worker         SecureAccessControlProfile profile;
217*e1997b9aSAndroid Build Coastguard Worker         status = halBinder_->addAccessControlProfile(
218*e1997b9aSAndroid Build Coastguard Worker             acpParcel.id, certificate, acpParcel.userAuthenticationRequired,
219*e1997b9aSAndroid Build Coastguard Worker             acpParcel.userAuthenticationTimeoutMillis, secureUserId, &profile);
220*e1997b9aSAndroid Build Coastguard Worker         if (!status.isOk()) {
221*e1997b9aSAndroid Build Coastguard Worker             return halStatusToGenericError(status);
222*e1997b9aSAndroid Build Coastguard Worker         }
223*e1997b9aSAndroid Build Coastguard Worker         data.addSecureAccessControlProfile(profile);
224*e1997b9aSAndroid Build Coastguard Worker     }
225*e1997b9aSAndroid Build Coastguard Worker 
226*e1997b9aSAndroid Build Coastguard Worker     for (const EntryNamespaceParcel& ensParcel : entryNamespaces) {
227*e1997b9aSAndroid Build Coastguard Worker         for (const EntryParcel& eParcel : ensParcel.entries) {
228*e1997b9aSAndroid Build Coastguard Worker             vector<vector<uint8_t>> chunks = chunkVector(eParcel.value, hwInfo_.dataChunkSize);
229*e1997b9aSAndroid Build Coastguard Worker 
230*e1997b9aSAndroid Build Coastguard Worker             vector<int32_t> ids;
231*e1997b9aSAndroid Build Coastguard Worker             std::copy(eParcel.accessControlProfileIds.begin(),
232*e1997b9aSAndroid Build Coastguard Worker                       eParcel.accessControlProfileIds.end(), std::back_inserter(ids));
233*e1997b9aSAndroid Build Coastguard Worker 
234*e1997b9aSAndroid Build Coastguard Worker             status = halBinder_->beginAddEntry(ids, ensParcel.namespaceName, eParcel.name,
235*e1997b9aSAndroid Build Coastguard Worker                                                eParcel.value.size());
236*e1997b9aSAndroid Build Coastguard Worker             if (!status.isOk()) {
237*e1997b9aSAndroid Build Coastguard Worker                 return halStatusToGenericError(status);
238*e1997b9aSAndroid Build Coastguard Worker             }
239*e1997b9aSAndroid Build Coastguard Worker 
240*e1997b9aSAndroid Build Coastguard Worker             vector<vector<uint8_t>> encryptedChunks;
241*e1997b9aSAndroid Build Coastguard Worker             for (const auto& chunk : chunks) {
242*e1997b9aSAndroid Build Coastguard Worker                 vector<uint8_t> encryptedChunk;
243*e1997b9aSAndroid Build Coastguard Worker                 status = halBinder_->addEntryValue(chunk, &encryptedChunk);
244*e1997b9aSAndroid Build Coastguard Worker                 if (!status.isOk()) {
245*e1997b9aSAndroid Build Coastguard Worker                     return halStatusToGenericError(status);
246*e1997b9aSAndroid Build Coastguard Worker                 }
247*e1997b9aSAndroid Build Coastguard Worker                 encryptedChunks.push_back(encryptedChunk);
248*e1997b9aSAndroid Build Coastguard Worker             }
249*e1997b9aSAndroid Build Coastguard Worker             EntryData eData;
250*e1997b9aSAndroid Build Coastguard Worker             eData.size = eParcel.value.size();
251*e1997b9aSAndroid Build Coastguard Worker             eData.accessControlProfileIds = std::move(ids);
252*e1997b9aSAndroid Build Coastguard Worker             eData.encryptedChunks = std::move(encryptedChunks);
253*e1997b9aSAndroid Build Coastguard Worker             data.addEntryData(ensParcel.namespaceName, eParcel.name, eData);
254*e1997b9aSAndroid Build Coastguard Worker         }
255*e1997b9aSAndroid Build Coastguard Worker     }
256*e1997b9aSAndroid Build Coastguard Worker 
257*e1997b9aSAndroid Build Coastguard Worker     vector<uint8_t> credentialData;
258*e1997b9aSAndroid Build Coastguard Worker     vector<uint8_t> proofOfProvisioningSignature;
259*e1997b9aSAndroid Build Coastguard Worker     status = halBinder_->finishAddingEntries(&credentialData, &proofOfProvisioningSignature);
260*e1997b9aSAndroid Build Coastguard Worker     if (!status.isOk()) {
261*e1997b9aSAndroid Build Coastguard Worker         return halStatusToGenericError(status);
262*e1997b9aSAndroid Build Coastguard Worker     }
263*e1997b9aSAndroid Build Coastguard Worker     data.setCredentialData(credentialData);
264*e1997b9aSAndroid Build Coastguard Worker 
265*e1997b9aSAndroid Build Coastguard Worker     data.setAvailableAuthenticationKeys(keyCount_, maxUsesPerKey_, minValidTimeMillis_);
266*e1997b9aSAndroid Build Coastguard Worker 
267*e1997b9aSAndroid Build Coastguard Worker     if (!data.saveToDisk()) {
268*e1997b9aSAndroid Build Coastguard Worker         return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
269*e1997b9aSAndroid Build Coastguard Worker                                                 "Error saving credential data to disk");
270*e1997b9aSAndroid Build Coastguard Worker     }
271*e1997b9aSAndroid Build Coastguard Worker 
272*e1997b9aSAndroid Build Coastguard Worker     if (credentialToReloadWhenUpdated_) {
273*e1997b9aSAndroid Build Coastguard Worker         credentialToReloadWhenUpdated_->writableCredentialPersonalized();
274*e1997b9aSAndroid Build Coastguard Worker         credentialToReloadWhenUpdated_.clear();
275*e1997b9aSAndroid Build Coastguard Worker     }
276*e1997b9aSAndroid Build Coastguard Worker 
277*e1997b9aSAndroid Build Coastguard Worker     *_aidl_return = proofOfProvisioningSignature;
278*e1997b9aSAndroid Build Coastguard Worker     return Status::ok();
279*e1997b9aSAndroid Build Coastguard Worker }
280*e1997b9aSAndroid Build Coastguard Worker 
281*e1997b9aSAndroid Build Coastguard Worker }  // namespace identity
282*e1997b9aSAndroid Build Coastguard Worker }  // namespace security
283*e1997b9aSAndroid Build Coastguard Worker }  // namespace android
284