1 /*
2 * Copyright 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
17 #define LOG_TAG "IdentityCredentialStore"
18
19 #include <android-base/logging.h>
20 #include <android/binder_manager.h>
21
22 #include "IdentityCredential.h"
23 #include "IdentityCredentialStore.h"
24 #include "PresentationSession.h"
25 #include "WritableIdentityCredential.h"
26
27 namespace aidl::android::hardware::identity {
28
29 using ::aidl::android::hardware::security::keymint::IRemotelyProvisionedComponent;
30
IdentityCredentialStore(sp<SecureHardwareProxyFactory> hwProxyFactory,optional<string> remotelyProvisionedComponent)31 IdentityCredentialStore::IdentityCredentialStore(sp<SecureHardwareProxyFactory> hwProxyFactory,
32 optional<string> remotelyProvisionedComponent)
33 : hwProxyFactory_(hwProxyFactory),
34 remotelyProvisionedComponentName_(remotelyProvisionedComponent) {
35 hardwareInformation_.credentialStoreName = "Identity Credential Reference Implementation";
36 hardwareInformation_.credentialStoreAuthorName = "Google";
37 hardwareInformation_.dataChunkSize = kGcmChunkSize;
38 hardwareInformation_.isDirectAccess = false;
39 hardwareInformation_.supportedDocTypes = {};
40 hardwareInformation_.isRemoteKeyProvisioningSupported =
41 remotelyProvisionedComponentName_.has_value();
42 }
43
getHardwareInformation(HardwareInformation * hardwareInformation)44 ndk::ScopedAStatus IdentityCredentialStore::getHardwareInformation(
45 HardwareInformation* hardwareInformation) {
46 *hardwareInformation = hardwareInformation_;
47 return ndk::ScopedAStatus::ok();
48 }
49
createCredential(const string & docType,bool testCredential,shared_ptr<IWritableIdentityCredential> * outWritableCredential)50 ndk::ScopedAStatus IdentityCredentialStore::createCredential(
51 const string& docType, bool testCredential,
52 shared_ptr<IWritableIdentityCredential>* outWritableCredential) {
53 sp<SecureHardwareProvisioningProxy> hwProxy = hwProxyFactory_->createProvisioningProxy();
54 shared_ptr<WritableIdentityCredential> wc =
55 ndk::SharedRefBase::make<WritableIdentityCredential>(hwProxy, docType, testCredential,
56 hardwareInformation_);
57 if (!wc->initialize()) {
58 return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
59 IIdentityCredentialStore::STATUS_FAILED,
60 "Error initializing WritableIdentityCredential"));
61 }
62 *outWritableCredential = wc;
63 return ndk::ScopedAStatus::ok();
64 }
65
getCredential(CipherSuite cipherSuite,const vector<uint8_t> & credentialData,shared_ptr<IIdentityCredential> * outCredential)66 ndk::ScopedAStatus IdentityCredentialStore::getCredential(
67 CipherSuite cipherSuite, const vector<uint8_t>& credentialData,
68 shared_ptr<IIdentityCredential>* outCredential) {
69 // We only support CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256 right now.
70 if (cipherSuite != CipherSuite::CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256) {
71 return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
72 IIdentityCredentialStore::STATUS_CIPHER_SUITE_NOT_SUPPORTED,
73 "Unsupported cipher suite"));
74 }
75
76 shared_ptr<IdentityCredential> credential = ndk::SharedRefBase::make<IdentityCredential>(
77 hwProxyFactory_, credentialData, nullptr /* session */, hardwareInformation_);
78 auto ret = credential->initialize();
79 if (ret != IIdentityCredentialStore::STATUS_OK) {
80 return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
81 int(ret), "Error initializing IdentityCredential"));
82 }
83 *outCredential = credential;
84 return ndk::ScopedAStatus::ok();
85 }
86
createPresentationSession(CipherSuite cipherSuite,shared_ptr<IPresentationSession> * outSession)87 ndk::ScopedAStatus IdentityCredentialStore::createPresentationSession(
88 CipherSuite cipherSuite, shared_ptr<IPresentationSession>* outSession) {
89 // We only support CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256 right now.
90 if (cipherSuite != CipherSuite::CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256) {
91 return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
92 IIdentityCredentialStore::STATUS_CIPHER_SUITE_NOT_SUPPORTED,
93 "Unsupported cipher suite"));
94 }
95
96 sp<SecureHardwareSessionProxy> hwProxy = hwProxyFactory_->createSessionProxy();
97 shared_ptr<PresentationSession> session = ndk::SharedRefBase::make<PresentationSession>(
98 hwProxyFactory_, hwProxy, hardwareInformation_);
99 auto ret = session->initialize();
100 if (ret != IIdentityCredentialStore::STATUS_OK) {
101 return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
102 int(ret), "Error initializing PresentationSession"));
103 }
104 *outSession = session;
105 return ndk::ScopedAStatus::ok();
106 }
107
getRemotelyProvisionedComponent(shared_ptr<IRemotelyProvisionedComponent> * outRemotelyProvisionedComponent)108 ndk::ScopedAStatus IdentityCredentialStore::getRemotelyProvisionedComponent(
109 shared_ptr<IRemotelyProvisionedComponent>* outRemotelyProvisionedComponent) {
110 if (!remotelyProvisionedComponentName_) {
111 return ndk::ScopedAStatus(AStatus_fromExceptionCodeWithMessage(
112 EX_UNSUPPORTED_OPERATION, "Remote key provisioning is not supported"));
113 }
114
115 ndk::SpAIBinder binder(
116 AServiceManager_waitForService(remotelyProvisionedComponentName_->c_str()));
117 if (binder.get() == nullptr) {
118 return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
119 IIdentityCredentialStore::STATUS_FAILED,
120 "Unable to get remotely provisioned component"));
121 }
122
123 *outRemotelyProvisionedComponent = IRemotelyProvisionedComponent::fromBinder(binder);
124 return ndk::ScopedAStatus::ok();
125 }
126
127 } // namespace aidl::android::hardware::identity
128