1 /*
2 * Copyright (C) 2015 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 #define LOG_TAG "KeystoreOperation"
17
18 #include "operation.h"
19
20 #include <algorithm>
21 #include <android-base/logging.h>
22 #include <mutex>
23
24 namespace keystore {
25
OperationMap(IBinder::DeathRecipient * deathRecipient)26 OperationMap::OperationMap(IBinder::DeathRecipient* deathRecipient)
27 : mDeathRecipient(deathRecipient) {}
28
addOperation(uint64_t handle,uint64_t keyid,KeyPurpose purpose,const sp<Keymaster> & dev,const sp<IBinder> & appToken,KeyCharacteristics && characteristics,const hidl_vec<KeyParameter> & params,bool pruneable)29 sp<IBinder> OperationMap::addOperation(uint64_t handle, uint64_t keyid, KeyPurpose purpose,
30 const sp<Keymaster>& dev, const sp<IBinder>& appToken,
31 KeyCharacteristics&& characteristics,
32 const hidl_vec<KeyParameter>& params, bool pruneable) {
33 sp<IBinder> token = new ::android::BBinder();
34 mMap.emplace(token, std::make_shared<Operation>(handle, keyid, purpose, dev,
35 std::move(characteristics), appToken, params));
36 if (pruneable) mLru.push_back(token);
37 if (mAppTokenMap.find(appToken) == mAppTokenMap.end()) appToken->linkToDeath(mDeathRecipient);
38 mAppTokenMap[appToken].push_back(token);
39 return token;
40 }
41
getOperation(const sp<IBinder> & token)42 std::shared_ptr<Operation> OperationMap::getOperation(const sp<IBinder>& token) {
43 auto entry = mMap.find(token);
44 if (entry == mMap.end()) return {};
45
46 auto op = entry->second;
47
48 updateLru(token);
49 return op;
50 }
51
updateLru(const sp<IBinder> & token)52 void OperationMap::updateLru(const sp<IBinder>& token) {
53 auto lruEntry = std::find(mLru.begin(), mLru.end(), token);
54 if (lruEntry != mLru.end()) {
55 mLru.erase(lruEntry);
56 mLru.push_back(token);
57 }
58 }
59
removeOperation(const sp<IBinder> & token,bool wasSuccessful)60 std::shared_ptr<Operation> OperationMap::removeOperation(const sp<IBinder>& token,
61 bool wasSuccessful) {
62 auto entry = mMap.find(token);
63 if (entry == mMap.end()) return {};
64
65 auto op = entry->second;
66 operationUploader.uploadOpAsProto(*op, wasSuccessful);
67 mMap.erase(entry);
68
69 auto lruEntry = std::find(mLru.begin(), mLru.end(), token);
70 if (lruEntry != mLru.end()) mLru.erase(lruEntry);
71 removeOperationTracking(token, op->appToken);
72 return op;
73 }
74
removeOperationTracking(const sp<IBinder> & token,const sp<IBinder> & appToken)75 void OperationMap::removeOperationTracking(const sp<IBinder>& token, const sp<IBinder>& appToken) {
76 auto appEntry = mAppTokenMap.find(appToken);
77 if (appEntry == mAppTokenMap.end()) {
78 ALOGE("Entry for %p contains unmapped application token %p", token.get(), appToken.get());
79 return;
80 }
81 auto tokenEntry = std::find(appEntry->second.begin(), appEntry->second.end(), token);
82 appEntry->second.erase(tokenEntry);
83 // Stop listening for death if all operations tied to the token have finished.
84 if (appEntry->second.size() == 0) {
85 appToken->unlinkToDeath(mDeathRecipient);
86 mAppTokenMap.erase(appEntry);
87 }
88 }
89
getOldestPruneableOperation()90 sp<IBinder> OperationMap::getOldestPruneableOperation() {
91 if (mLru.size() == 0) return {};
92
93 return {mLru.front()};
94 }
95
getOperationsForToken(const sp<IBinder> & appToken)96 std::vector<sp<IBinder>> OperationMap::getOperationsForToken(const sp<IBinder>& appToken) {
97 auto appEntry = mAppTokenMap.find(appToken);
98 if (appEntry == mAppTokenMap.end()) return {};
99 return appEntry->second;
100 }
101
102 } // namespace keystore
103