• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2021, 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 "PresentationSession"
18 
19 #include "PresentationSession.h"
20 #include "IdentityCredentialStore.h"
21 
22 #include <android/hardware/identity/support/IdentityCredentialSupport.h>
23 
24 #include <string.h>
25 
26 #include <android-base/logging.h>
27 #include <android-base/stringprintf.h>
28 
29 #include <cppbor.h>
30 #include <cppbor_parse.h>
31 
32 #include "FakeSecureHardwareProxy.h"
33 #include "IdentityCredential.h"
34 #include "PresentationSession.h"
35 
36 namespace aidl::android::hardware::identity {
37 
38 using ::std::optional;
39 
40 using namespace ::android::hardware::identity;
41 
~PresentationSession()42 PresentationSession::~PresentationSession() {}
43 
initialize()44 int PresentationSession::initialize() {
45     if (!hwProxy_->initialize()) {
46         LOG(ERROR) << "hwProxy->initialize failed";
47         return IIdentityCredentialStore::STATUS_FAILED;
48     }
49 
50     optional<uint64_t> id = hwProxy_->getId();
51     if (!id) {
52         LOG(ERROR) << "Error getting id for session";
53         return IIdentityCredentialStore::STATUS_FAILED;
54     }
55     id_ = id.value();
56 
57     optional<vector<uint8_t>> ephemeralKeyPriv = hwProxy_->getEphemeralKeyPair();
58     if (!ephemeralKeyPriv) {
59         LOG(ERROR) << "Error getting ephemeral private key for session";
60         return IIdentityCredentialStore::STATUS_FAILED;
61     }
62     optional<vector<uint8_t>> ephemeralKeyPair =
63             support::ecPrivateKeyToKeyPair(ephemeralKeyPriv.value());
64     if (!ephemeralKeyPair) {
65         LOG(ERROR) << "Error creating ephemeral key-pair";
66         return IIdentityCredentialStore::STATUS_FAILED;
67     }
68     ephemeralKeyPair_ = ephemeralKeyPair.value();
69 
70     optional<uint64_t> authChallenge = hwProxy_->getAuthChallenge();
71     if (!authChallenge) {
72         LOG(ERROR) << "Error getting authChallenge for session";
73         return IIdentityCredentialStore::STATUS_FAILED;
74     }
75     authChallenge_ = authChallenge.value();
76 
77     return IIdentityCredentialStore::STATUS_OK;
78 }
79 
getEphemeralKeyPair(vector<uint8_t> * outKeyPair)80 ndk::ScopedAStatus PresentationSession::getEphemeralKeyPair(vector<uint8_t>* outKeyPair) {
81     *outKeyPair = ephemeralKeyPair_;
82     return ndk::ScopedAStatus::ok();
83 }
84 
getAuthChallenge(int64_t * outChallenge)85 ndk::ScopedAStatus PresentationSession::getAuthChallenge(int64_t* outChallenge) {
86     *outChallenge = authChallenge_;
87     return ndk::ScopedAStatus::ok();
88 }
89 
setReaderEphemeralPublicKey(const vector<uint8_t> & publicKey)90 ndk::ScopedAStatus PresentationSession::setReaderEphemeralPublicKey(
91         const vector<uint8_t>& publicKey) {
92     // We expect the reader ephemeral public key to be same size and curve
93     // as the ephemeral key we generated (e.g. P-256 key), otherwise ECDH
94     // won't work. So its length should be 65 bytes and it should be
95     // starting with 0x04.
96     if (publicKey.size() != 65 || publicKey[0] != 0x04) {
97         return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
98                 IIdentityCredentialStore::STATUS_FAILED,
99                 "Reader public key is not in expected format"));
100     }
101     readerPublicKey_ = publicKey;
102     vector<uint8_t> pubKeyP256(publicKey.begin() + 1, publicKey.end());
103     if (!hwProxy_->setReaderEphemeralPublicKey(pubKeyP256)) {
104         return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
105                 IIdentityCredentialStore::STATUS_FAILED,
106                 "Error setting readerEphemeralPublicKey for session"));
107     }
108     return ndk::ScopedAStatus::ok();
109 }
110 
setSessionTranscript(const vector<uint8_t> & sessionTranscript)111 ndk::ScopedAStatus PresentationSession::setSessionTranscript(
112         const vector<uint8_t>& sessionTranscript) {
113     sessionTranscript_ = sessionTranscript;
114     if (!hwProxy_->setSessionTranscript(sessionTranscript)) {
115         return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
116                 IIdentityCredentialStore::STATUS_FAILED,
117                 "Error setting SessionTranscript for session"));
118     }
119     return ndk::ScopedAStatus::ok();
120 }
121 
getCredential(const vector<uint8_t> & credentialData,shared_ptr<IIdentityCredential> * outCredential)122 ndk::ScopedAStatus PresentationSession::getCredential(
123         const vector<uint8_t>& credentialData, shared_ptr<IIdentityCredential>* outCredential) {
124     shared_ptr<PresentationSession> p = ref<PresentationSession>();
125     shared_ptr<IdentityCredential> credential = ndk::SharedRefBase::make<IdentityCredential>(
126             hwProxyFactory_, credentialData, p, hardwareInformation_);
127     int ret = credential->initialize();
128     if (ret != IIdentityCredentialStore::STATUS_OK) {
129         return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
130                 ret, "Error initializing IdentityCredential"));
131     }
132     *outCredential = std::move(credential);
133 
134     return ndk::ScopedAStatus::ok();
135 }
136 
getSessionId()137 uint64_t PresentationSession::getSessionId() {
138     return id_;
139 }
140 
getSessionTranscript()141 vector<uint8_t> PresentationSession::getSessionTranscript() {
142     return sessionTranscript_;
143 }
144 
getReaderEphemeralPublicKey()145 vector<uint8_t> PresentationSession::getReaderEphemeralPublicKey() {
146     return readerPublicKey_;
147 }
148 
149 }  // namespace aidl::android::hardware::identity
150