blob: 071cf247ea183a401cf05423314bdb47d34ccf9e [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"
28#include "Util.h"
29#include "WritableCredential.h"
30
31namespace android {
32namespace security {
33namespace identity {
34
David Zeuthenab3e5652019-10-28 13:32:48 -040035CredentialStore::CredentialStore(const std::string& dataPath, sp<IIdentityCredentialStore> hal)
36 : dataPath_(dataPath), hal_(hal) {}
37
38bool CredentialStore::init() {
David Zeuthena6f9fba2020-02-11 22:08:27 -050039 Status status = hal_->getHardwareInformation(&hwInfo_);
40 if (!status.isOk()) {
41 LOG(ERROR) << "Error getting hardware information: " << status.toString8();
David Zeuthenab3e5652019-10-28 13:32:48 -040042 return false;
43 }
David Zeuthen472e6c82020-10-16 11:50:13 -040044 halApiVersion_ = hal_->getInterfaceVersion();
David Zeuthena6f9fba2020-02-11 22:08:27 -050045
David Zeuthen472e6c82020-10-16 11:50:13 -040046 LOG(INFO) << "Connected to Identity Credential HAL with API version " << halApiVersion_
47 << " and name '" << hwInfo_.credentialStoreName << "' authored by '"
48 << hwInfo_.credentialStoreAuthorName << "' with chunk size " << hwInfo_.dataChunkSize
49 << " and directoAccess set to " << (hwInfo_.isDirectAccess ? "true" : "false");
David Zeuthenab3e5652019-10-28 13:32:48 -040050 return true;
51}
52
53CredentialStore::~CredentialStore() {}
54
55Status CredentialStore::getSecurityHardwareInfo(SecurityHardwareInfoParcel* _aidl_return) {
56 SecurityHardwareInfoParcel info;
David Zeuthena6f9fba2020-02-11 22:08:27 -050057 info.directAccess = hwInfo_.isDirectAccess;
58 info.supportedDocTypes = hwInfo_.supportedDocTypes;
David Zeuthenab3e5652019-10-28 13:32:48 -040059 *_aidl_return = info;
60 return Status::ok();
61};
62
63Status CredentialStore::createCredential(const std::string& credentialName,
64 const std::string& docType,
65 sp<IWritableCredential>* _aidl_return) {
66 uid_t callingUid = android::IPCThreadState::self()->getCallingUid();
67 optional<bool> credentialExists =
68 CredentialData::credentialExists(dataPath_, callingUid, credentialName);
69 if (!credentialExists.has_value()) {
70 return Status::fromServiceSpecificError(
71 ERROR_GENERIC, "Error determining if credential with given name exists");
72 }
73 if (credentialExists.value()) {
74 return Status::fromServiceSpecificError(ERROR_ALREADY_PERSONALIZED,
75 "Credential with given name already exists");
76 }
77
David Zeuthena6f9fba2020-02-11 22:08:27 -050078 if (hwInfo_.supportedDocTypes.size() > 0) {
79 if (std::find(hwInfo_.supportedDocTypes.begin(), hwInfo_.supportedDocTypes.end(),
80 docType) == hwInfo_.supportedDocTypes.end()) {
David Zeuthenab3e5652019-10-28 13:32:48 -040081 return Status::fromServiceSpecificError(ERROR_DOCUMENT_TYPE_NOT_SUPPORTED,
82 "No support for given document type");
83 }
84 }
85
David Zeuthenab3e5652019-10-28 13:32:48 -040086 sp<IWritableIdentityCredential> halWritableCredential;
David Zeuthena6f9fba2020-02-11 22:08:27 -050087 Status status = hal_->createCredential(docType, false, &halWritableCredential);
88 if (!status.isOk()) {
89 return halStatusToGenericError(status);
David Zeuthenab3e5652019-10-28 13:32:48 -040090 }
91
92 sp<IWritableCredential> writableCredential = new WritableCredential(
David Zeuthen27407a52021-03-04 16:32:43 -050093 dataPath_, credentialName, docType, false, hwInfo_, halWritableCredential);
David Zeuthenab3e5652019-10-28 13:32:48 -040094 *_aidl_return = writableCredential;
95 return Status::ok();
96}
97
David Zeuthenab3e5652019-10-28 13:32:48 -040098Status CredentialStore::getCredentialByName(const std::string& credentialName, int32_t cipherSuite,
99 sp<ICredential>* _aidl_return) {
100 *_aidl_return = nullptr;
101
102 uid_t callingUid = android::IPCThreadState::self()->getCallingUid();
103 optional<bool> credentialExists =
104 CredentialData::credentialExists(dataPath_, callingUid, credentialName);
105 if (!credentialExists.has_value()) {
106 return Status::fromServiceSpecificError(
107 ERROR_GENERIC, "Error determining if credential with given name exists");
108 }
109 if (!credentialExists.value()) {
110 return Status::fromServiceSpecificError(ERROR_NO_SUCH_CREDENTIAL,
111 "Credential with given name doesn't exist");
112 }
113
David Zeuthena6f9fba2020-02-11 22:08:27 -0500114 // Note: IdentityCredentialStore.java's CipherSuite enumeration and CipherSuite from the
115 // HAL is manually kept in sync. So this cast is safe.
David Zeuthen472e6c82020-10-16 11:50:13 -0400116 sp<Credential> credential = new Credential(CipherSuite(cipherSuite), dataPath_, credentialName,
117 callingUid, hwInfo_, hal_, halApiVersion_);
David Zeuthenab3e5652019-10-28 13:32:48 -0400118
David Zeuthen472e6c82020-10-16 11:50:13 -0400119 Status loadStatus = credential->ensureOrReplaceHalBinder();
David Zeuthenab3e5652019-10-28 13:32:48 -0400120 if (!loadStatus.isOk()) {
121 LOG(ERROR) << "Error loading credential";
122 } else {
123 *_aidl_return = credential;
124 }
125 return loadStatus;
126}
127
128} // namespace identity
129} // namespace security
130} // namespace android