summaryrefslogtreecommitdiff
path: root/identity
diff options
context:
space:
mode:
authorHasini Gunasinghe <hasinitg@google.com>2021-03-02 00:34:58 +0000
committerHasini Gunasinghe <hasinitg@google.com>2021-03-12 20:25:31 +0000
commit1b531b91c092e782d5b7959f04f0381c98575d8e (patch)
tree71abc97a766d5b531347bb279c059a39b844a2ae /identity
parentb3715fb9a6ad50d0f4be942098e27d67250e344b (diff)
downloadsecurity-1b531b91c092e782d5b7959f04f0381c98575d8e.tar.gz
Integrate getAuthTokensForCredStore method with credstore.
Bug: 159341610 Test: CtsVerifier Change-Id: Ia2b7f1a27a05e92c7b5bb5da14caa423a70ac15b
Diffstat (limited to 'identity')
-rw-r--r--identity/Android.bp4
-rw-r--r--identity/Credential.cpp167
-rw-r--r--identity/main.cpp2
3 files changed, 123 insertions, 50 deletions
diff --git a/identity/Android.bp b/identity/Android.bp
index ed8ff2f3..5841bf6a 100644
--- a/identity/Android.bp
+++ b/identity/Android.bp
@@ -39,6 +39,7 @@ cc_binary {
shared_libs: [
"libbase",
"libbinder",
+ "libbinder_ndk",
"libkeystore_aidl",
"libcredstore_aidl",
"libutils",
@@ -46,6 +47,9 @@ cc_binary {
"android.hardware.identity-support-lib",
"libkeymaster4support",
"libkeystore-attestation-application-id",
+ "android.hardware.security.keymint-V1-ndk_platform",
+ "android.security.authorization-ndk_platform",
+ "PlatformProperties",
],
static_libs: [
"android.hardware.identity-V3-cpp",
diff --git a/identity/Credential.cpp b/identity/Credential.cpp
index a3c72edc..183ddebc 100644
--- a/identity/Credential.cpp
+++ b/identity/Credential.cpp
@@ -17,7 +17,7 @@
#define LOG_TAG "Credential"
#include <android-base/logging.h>
-
+#include <android/binder_manager.h>
#include <android/hardware/identity/support/IdentityCredentialSupport.h>
#include <android/security/identity/ICredentialStore.h>
@@ -33,6 +33,12 @@
#include <future>
#include <tuple>
+#include <aidl/android/hardware/security/keymint/HardwareAuthToken.h>
+#include <aidl/android/hardware/security/secureclock/TimeStampToken.h>
+#include <aidl/android/security/authorization/AuthorizationTokens.h>
+#include <aidl/android/security/authorization/IKeystoreAuthorization.h>
+#include <android/sysprop/Keystore2Properties.sysprop.h>
+
#include "Credential.h"
#include "CredentialData.h"
#include "Util.h"
@@ -47,6 +53,7 @@ using std::promise;
using std::tuple;
using android::security::keystore::IKeystoreService;
+using namespace android::sysprop;
using ::android::hardware::identity::IWritableIdentityCredential;
@@ -55,11 +62,17 @@ using ::android::hardware::identity::support::ecKeyPairGetPrivateKey;
using ::android::hardware::identity::support::ecKeyPairGetPublicKey;
using ::android::hardware::identity::support::sha256;
+using android::hardware::keymaster::SecurityLevel;
using android::hardware::keymaster::V4_0::HardwareAuthToken;
using android::hardware::keymaster::V4_0::VerificationToken;
using AidlHardwareAuthToken = android::hardware::keymaster::HardwareAuthToken;
using AidlVerificationToken = android::hardware::keymaster::VerificationToken;
+using KeyMintAuthToken = ::aidl::android::hardware::security::keymint::HardwareAuthToken;
+using ::aidl::android::hardware::security::secureclock::TimeStampToken;
+using ::aidl::android::security::authorization::AuthorizationTokens;
+using ::aidl::android::security::authorization::IKeystoreAuthorization;
+
Credential::Credential(CipherSuite cipherSuite, const std::string& dataPath,
const std::string& credentialName, uid_t callingUid,
HardwareInformation hwInfo, sp<IIdentityCredentialStore> halStoreBinder,
@@ -168,9 +181,10 @@ class CredstoreTokenCallback : public android::security::keystore::BnCredstoreTo
// Returns false if an error occurred communicating with keystore.
//
-bool getTokensFromKeystore(uint64_t challenge, uint64_t secureUserId,
- unsigned int authTokenMaxAgeMillis, vector<uint8_t>& authToken,
- vector<uint8_t>& verificationToken) {
+bool getTokensFromKeystore1(uint64_t challenge, uint64_t secureUserId,
+ unsigned int authTokenMaxAgeMillis,
+ AidlHardwareAuthToken& aidlAuthToken,
+ AidlVerificationToken& aidlVerificationToken) {
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder = sm->getService(String16("android.security.keystore"));
sp<IKeystoreService> keystore = interface_cast<IKeystoreService>(binder);
@@ -189,19 +203,100 @@ bool getTokensFromKeystore(uint64_t challenge, uint64_t secureUserId,
auto fstatus = future.wait_for(std::chrono::milliseconds(5000));
if (fstatus != std::future_status::ready) {
- LOG(ERROR) << "Waited 5 seconds from tokens for credstore, aborting";
+ LOG(ERROR) << "Waited 5 seconds for tokens from keystore, aborting";
return false;
}
auto [success, returnedAuthToken, returnedVerificationToken] = future.get();
if (!success) {
- LOG(ERROR) << "Error getting tokens from credstore";
+ LOG(ERROR) << "Error getting tokens from keystore1";
return false;
}
- authToken = returnedAuthToken;
- verificationToken = returnedVerificationToken;
+ // It's entirely possible getTokensFromKeystore() succeeded but didn't
+ // return any tokens (in which case the returned byte-vectors are
+ // empty). For example, this can happen if no auth token is available
+ // which satifies e.g. |authTokenMaxAgeMillis|.
+ //
+ if (returnedAuthToken.size() > 0) {
+ HardwareAuthToken authToken =
+ android::hardware::keymaster::V4_0::support::hidlVec2AuthToken(returnedAuthToken);
+ // Convert from HIDL to AIDL...
+ aidlAuthToken.challenge = int64_t(authToken.challenge);
+ aidlAuthToken.userId = int64_t(authToken.userId);
+ aidlAuthToken.authenticatorId = int64_t(authToken.authenticatorId);
+ aidlAuthToken.authenticatorType = ::android::hardware::keymaster::HardwareAuthenticatorType(
+ int32_t(authToken.authenticatorType));
+ aidlAuthToken.timestamp.milliSeconds = int64_t(authToken.timestamp);
+ aidlAuthToken.mac = authToken.mac;
+ }
+
+ if (returnedVerificationToken.size() > 0) {
+ optional<VerificationToken> token =
+ android::hardware::keymaster::V4_0::support::deserializeVerificationToken(
+ returnedVerificationToken);
+ if (!token) {
+ LOG(ERROR) << "Error deserializing verification token";
+ }
+ aidlVerificationToken.challenge = token->challenge;
+ aidlVerificationToken.timestamp.milliSeconds = token->timestamp;
+ aidlVerificationToken.securityLevel =
+ ::android::hardware::keymaster::SecurityLevel(token->securityLevel);
+ aidlVerificationToken.mac = token->mac;
+ }
return true;
}
+// Returns false if an error occurred communicating with keystore.
+//
+bool getTokensFromKeystore2(uint64_t challenge, uint64_t secureUserId,
+ unsigned int authTokenMaxAgeMillis,
+ AidlHardwareAuthToken& aidlAuthToken,
+ AidlVerificationToken& aidlVerificationToken) {
+ // try to connect to IKeystoreAuthorization AIDL service first.
+ AIBinder* authzAIBinder = AServiceManager_checkService("android.security.authorization");
+ ::ndk::SpAIBinder authzBinder(authzAIBinder);
+ auto authzService = IKeystoreAuthorization::fromBinder(authzBinder);
+ if (authzService) {
+ AuthorizationTokens authzTokens;
+ auto result = authzService->getAuthTokensForCredStore(challenge, secureUserId,
+ authTokenMaxAgeMillis, &authzTokens);
+ // Convert KeyMint auth token to KeyMaster authtoken, only if tokens are
+ // returned
+ if (result.isOk()) {
+ KeyMintAuthToken keymintAuthToken = authzTokens.authToken;
+ aidlAuthToken.challenge = keymintAuthToken.challenge;
+ aidlAuthToken.userId = keymintAuthToken.userId;
+ aidlAuthToken.authenticatorId = keymintAuthToken.authenticatorId;
+ aidlAuthToken.authenticatorType =
+ ::android::hardware::keymaster::HardwareAuthenticatorType(
+ int32_t(keymintAuthToken.authenticatorType));
+ aidlAuthToken.timestamp.milliSeconds = keymintAuthToken.timestamp.milliSeconds;
+ aidlAuthToken.mac = keymintAuthToken.mac;
+
+ // Convert timestamp token to KeyMaster verification token
+ TimeStampToken timestampToken = authzTokens.timestampToken;
+ aidlVerificationToken.challenge = timestampToken.challenge;
+ aidlVerificationToken.timestamp.milliSeconds = timestampToken.timestamp.milliSeconds;
+ // Legacy verification tokens were always minted by TEE.
+ aidlVerificationToken.securityLevel = SecurityLevel::TRUSTED_ENVIRONMENT;
+ aidlVerificationToken.mac = timestampToken.mac;
+ } else {
+ if (result.getServiceSpecificError() == 0) {
+ // Here we differentiate the errors occurred during communication
+ // from the service specific errors.
+ LOG(ERROR) << "Error getting tokens from keystore2: " << result.getDescription();
+ return false;
+ } else {
+ // Log the reason for not finding auth tokens.
+ LOG(INFO) << "Auth tokens not found: " << result.getDescription();
+ }
+ }
+ return true;
+ } else {
+ LOG(ERROR) << "Error connecting to IKeystoreAuthorization service";
+ return false;
+ }
+}
+
Status Credential::getEntries(const vector<uint8_t>& requestMessage,
const vector<RequestNamespaceParcel>& requestNamespaces,
const vector<uint8_t>& sessionTranscript,
@@ -334,49 +429,23 @@ Status Credential::getEntries(const vector<uint8_t>& requestMessage,
// not a guarantee and it's also not required.
//
- vector<uint8_t> authTokenBytes;
- vector<uint8_t> verificationTokenBytes;
- if (!getTokensFromKeystore(selectedChallenge_, data->getSecureUserId(),
- authTokenMaxAgeMillis, authTokenBytes, verificationTokenBytes)) {
- LOG(ERROR) << "Error getting tokens from keystore";
- return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
- "Error getting tokens from keystore");
- }
-
- // It's entirely possible getTokensFromKeystore() succeeded but didn't
- // return any tokens (in which case the returned byte-vectors are
- // empty). For example, this can happen if no auth token is available
- // which satifies e.g. |authTokenMaxAgeMillis|.
- //
- if (authTokenBytes.size() > 0) {
- HardwareAuthToken authToken =
- android::hardware::keymaster::V4_0::support::hidlVec2AuthToken(authTokenBytes);
-
- // Convert from HIDL to AIDL...
- aidlAuthToken.challenge = int64_t(authToken.challenge);
- aidlAuthToken.userId = int64_t(authToken.userId);
- aidlAuthToken.authenticatorId = int64_t(authToken.authenticatorId);
- aidlAuthToken.authenticatorType =
- ::android::hardware::keymaster::HardwareAuthenticatorType(
- int32_t(authToken.authenticatorType));
- aidlAuthToken.timestamp.milliSeconds = int64_t(authToken.timestamp);
- aidlAuthToken.mac = authToken.mac;
- }
-
- if (verificationTokenBytes.size() > 0) {
- optional<VerificationToken> token =
- android::hardware::keymaster::V4_0::support::deserializeVerificationToken(
- verificationTokenBytes);
- if (!token) {
- LOG(ERROR) << "Error deserializing verification token";
+ auto keystore2_status = Keystore2Properties::keystore2_enabled();
+ if (keystore2_status.has_value() && keystore2_status.value()) {
+ if (!getTokensFromKeystore2(selectedChallenge_, data->getSecureUserId(),
+ authTokenMaxAgeMillis, aidlAuthToken,
+ aidlVerificationToken)) {
+ LOG(ERROR) << "Error getting tokens from keystore2";
+ return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
+ "Error getting tokens from keystore2");
+ }
+ } else {
+ if (!getTokensFromKeystore1(selectedChallenge_, data->getSecureUserId(),
+ authTokenMaxAgeMillis, aidlAuthToken,
+ aidlVerificationToken)) {
+ LOG(ERROR) << "Error getting tokens from keystore";
return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
- "Error deserializing verification token");
+ "Error getting tokens from keystore");
}
- aidlVerificationToken.challenge = token->challenge;
- aidlVerificationToken.timestamp.milliSeconds = token->timestamp;
- aidlVerificationToken.securityLevel =
- ::android::hardware::keymaster::SecurityLevel(token->securityLevel);
- aidlVerificationToken.mac = token->mac;
}
}
diff --git a/identity/main.cpp b/identity/main.cpp
index 8f4968db..b51bd285 100644
--- a/identity/main.cpp
+++ b/identity/main.cpp
@@ -40,7 +40,7 @@ using ::android::base::StderrLogger;
using ::android::security::identity::CredentialStoreFactory;
int main(int argc, char* argv[]) {
- InitLogging(argv, StderrLogger);
+ InitLogging(argv);
CHECK(argc == 2) << "A directory must be specified";
string data_dir = string(argv[1]);