blob: 61a91253ee4e864bed6283797fc48c4ed6923888 [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>
20
21#include <android-base/logging.h>
22
23#include <binder/IPCThreadState.h>
24
25#include "Credential.h"
David Zeuthena6f9fba2020-02-11 22:08:27 -050026#include "CredentialData.h"
David Zeuthenab3e5652019-10-28 13:32:48 -040027#include "CredentialStore.h"
David Zeuthen045a2c82021-09-11 13:52:17 -040028#include "Session.h"
David Zeuthenab3e5652019-10-28 13:32:48 -040029#include "Util.h"
30#include "WritableCredential.h"
31
32namespace android {
33namespace security {
34namespace identity {
35
David Zeuthenab3e5652019-10-28 13:32:48 -040036CredentialStore::CredentialStore(const std::string& dataPath, sp<IIdentityCredentialStore> hal)
37 : dataPath_(dataPath), hal_(hal) {}
38
39bool CredentialStore::init() {
David Zeuthena6f9fba2020-02-11 22:08:27 -050040 Status status = hal_->getHardwareInformation(&hwInfo_);
41 if (!status.isOk()) {
42 LOG(ERROR) << "Error getting hardware information: " << status.toString8();
David Zeuthenab3e5652019-10-28 13:32:48 -040043 return false;
44 }
David Zeuthen472e6c82020-10-16 11:50:13 -040045 halApiVersion_ = hal_->getInterfaceVersion();
David Zeuthena6f9fba2020-02-11 22:08:27 -050046
David Zeuthen472e6c82020-10-16 11:50:13 -040047 LOG(INFO) << "Connected to Identity Credential HAL with API version " << halApiVersion_
48 << " and name '" << hwInfo_.credentialStoreName << "' authored by '"
49 << hwInfo_.credentialStoreAuthorName << "' with chunk size " << hwInfo_.dataChunkSize
50 << " and directoAccess set to " << (hwInfo_.isDirectAccess ? "true" : "false");
David Zeuthenab3e5652019-10-28 13:32:48 -040051 return true;
52}
53
54CredentialStore::~CredentialStore() {}
55
56Status CredentialStore::getSecurityHardwareInfo(SecurityHardwareInfoParcel* _aidl_return) {
57 SecurityHardwareInfoParcel info;
David Zeuthena6f9fba2020-02-11 22:08:27 -050058 info.directAccess = hwInfo_.isDirectAccess;
59 info.supportedDocTypes = hwInfo_.supportedDocTypes;
David Zeuthenab3e5652019-10-28 13:32:48 -040060 *_aidl_return = info;
61 return Status::ok();
62};
63
64Status CredentialStore::createCredential(const std::string& credentialName,
65 const std::string& docType,
66 sp<IWritableCredential>* _aidl_return) {
67 uid_t callingUid = android::IPCThreadState::self()->getCallingUid();
68 optional<bool> credentialExists =
69 CredentialData::credentialExists(dataPath_, callingUid, credentialName);
70 if (!credentialExists.has_value()) {
71 return Status::fromServiceSpecificError(
72 ERROR_GENERIC, "Error determining if credential with given name exists");
73 }
74 if (credentialExists.value()) {
75 return Status::fromServiceSpecificError(ERROR_ALREADY_PERSONALIZED,
76 "Credential with given name already exists");
77 }
78
David Zeuthena6f9fba2020-02-11 22:08:27 -050079 if (hwInfo_.supportedDocTypes.size() > 0) {
80 if (std::find(hwInfo_.supportedDocTypes.begin(), hwInfo_.supportedDocTypes.end(),
81 docType) == hwInfo_.supportedDocTypes.end()) {
David Zeuthenab3e5652019-10-28 13:32:48 -040082 return Status::fromServiceSpecificError(ERROR_DOCUMENT_TYPE_NOT_SUPPORTED,
83 "No support for given document type");
84 }
85 }
86
David Zeuthenab3e5652019-10-28 13:32:48 -040087 sp<IWritableIdentityCredential> halWritableCredential;
David Zeuthena6f9fba2020-02-11 22:08:27 -050088 Status status = hal_->createCredential(docType, false, &halWritableCredential);
89 if (!status.isOk()) {
90 return halStatusToGenericError(status);
David Zeuthenab3e5652019-10-28 13:32:48 -040091 }
92
93 sp<IWritableCredential> writableCredential = new WritableCredential(
David Zeuthen27407a52021-03-04 16:32:43 -050094 dataPath_, credentialName, docType, false, hwInfo_, halWritableCredential);
David Zeuthenab3e5652019-10-28 13:32:48 -040095 *_aidl_return = writableCredential;
96 return Status::ok();
97}
98
David Zeuthen045a2c82021-09-11 13:52:17 -040099Status CredentialStore::getCredentialCommon(const std::string& credentialName, int32_t cipherSuite,
100 sp<IPresentationSession> halSessionBinder,
David Zeuthenab3e5652019-10-28 13:32:48 -0400101 sp<ICredential>* _aidl_return) {
102 *_aidl_return = nullptr;
103
104 uid_t callingUid = android::IPCThreadState::self()->getCallingUid();
105 optional<bool> credentialExists =
106 CredentialData::credentialExists(dataPath_, callingUid, credentialName);
107 if (!credentialExists.has_value()) {
108 return Status::fromServiceSpecificError(
109 ERROR_GENERIC, "Error determining if credential with given name exists");
110 }
111 if (!credentialExists.value()) {
112 return Status::fromServiceSpecificError(ERROR_NO_SUCH_CREDENTIAL,
113 "Credential with given name doesn't exist");
114 }
115
David Zeuthena6f9fba2020-02-11 22:08:27 -0500116 // Note: IdentityCredentialStore.java's CipherSuite enumeration and CipherSuite from the
117 // HAL is manually kept in sync. So this cast is safe.
David Zeuthen045a2c82021-09-11 13:52:17 -0400118 sp<Credential> credential =
119 new Credential(CipherSuite(cipherSuite), dataPath_, credentialName, callingUid, hwInfo_,
120 hal_, halSessionBinder, halApiVersion_);
David Zeuthenab3e5652019-10-28 13:32:48 -0400121
David Zeuthen472e6c82020-10-16 11:50:13 -0400122 Status loadStatus = credential->ensureOrReplaceHalBinder();
David Zeuthenab3e5652019-10-28 13:32:48 -0400123 if (!loadStatus.isOk()) {
124 LOG(ERROR) << "Error loading credential";
125 } else {
126 *_aidl_return = credential;
127 }
128 return loadStatus;
129}
130
David Zeuthen045a2c82021-09-11 13:52:17 -0400131Status CredentialStore::getCredentialByName(const std::string& credentialName, int32_t cipherSuite,
132 sp<ICredential>* _aidl_return) {
133 return getCredentialCommon(credentialName, cipherSuite, nullptr, _aidl_return);
134}
135
136Status CredentialStore::createPresentationSession(int32_t cipherSuite, sp<ISession>* _aidl_return) {
137 sp<IPresentationSession> halPresentationSession;
138 Status status =
139 hal_->createPresentationSession(CipherSuite(cipherSuite), &halPresentationSession);
140 if (!status.isOk()) {
141 return halStatusToGenericError(status);
142 }
143
144 *_aidl_return = new Session(cipherSuite, halPresentationSession, this);
145 return Status::ok();
146}
147
David Zeuthenab3e5652019-10-28 13:32:48 -0400148} // namespace identity
149} // namespace security
150} // namespace android