mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 11:36:00 +00:00
gatekeeper vts tests
Change-Id: I51eadf624341f4e5399cd73fdaf222d19701e611 Signed-off-by: Alexey Polyudov <apolyudov@google.com>
This commit is contained in:
93
gatekeeper/1.0/vts/Gatekeeper.vts
Normal file
93
gatekeeper/1.0/vts/Gatekeeper.vts
Normal file
@@ -0,0 +1,93 @@
|
||||
component_class: HAL_HIDL
|
||||
component_type_version: 1.0
|
||||
component_name: "IGatekeeper"
|
||||
|
||||
package: "android.hardware.gatekeeper"
|
||||
|
||||
import: "android.hardware.gatekeeper@1.0::types"
|
||||
|
||||
interface: {
|
||||
api: {
|
||||
name: "enroll"
|
||||
return_type_hidl: {
|
||||
type: TYPE_STRUCT
|
||||
predefined_type: "::android::hardware::gatekeeper::V1_0::GatekeeperResponse"
|
||||
}
|
||||
arg: {
|
||||
type: TYPE_SCALAR
|
||||
scalar_type: "uint32_t"
|
||||
}
|
||||
arg: {
|
||||
type: TYPE_VECTOR
|
||||
vector_value: {
|
||||
type: TYPE_SCALAR
|
||||
scalar_type: "uint8_t"
|
||||
}
|
||||
}
|
||||
arg: {
|
||||
type: TYPE_VECTOR
|
||||
vector_value: {
|
||||
type: TYPE_SCALAR
|
||||
scalar_type: "uint8_t"
|
||||
}
|
||||
}
|
||||
arg: {
|
||||
type: TYPE_VECTOR
|
||||
vector_value: {
|
||||
type: TYPE_SCALAR
|
||||
scalar_type: "uint8_t"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
api: {
|
||||
name: "verify"
|
||||
return_type_hidl: {
|
||||
type: TYPE_STRUCT
|
||||
predefined_type: "::android::hardware::gatekeeper::V1_0::GatekeeperResponse"
|
||||
}
|
||||
arg: {
|
||||
type: TYPE_SCALAR
|
||||
scalar_type: "uint32_t"
|
||||
}
|
||||
arg: {
|
||||
type: TYPE_SCALAR
|
||||
scalar_type: "uint64_t"
|
||||
}
|
||||
arg: {
|
||||
type: TYPE_VECTOR
|
||||
vector_value: {
|
||||
type: TYPE_SCALAR
|
||||
scalar_type: "uint8_t"
|
||||
}
|
||||
}
|
||||
arg: {
|
||||
type: TYPE_VECTOR
|
||||
vector_value: {
|
||||
type: TYPE_SCALAR
|
||||
scalar_type: "uint8_t"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
api: {
|
||||
name: "deleteUser"
|
||||
return_type_hidl: {
|
||||
type: TYPE_STRUCT
|
||||
predefined_type: "::android::hardware::gatekeeper::V1_0::GatekeeperResponse"
|
||||
}
|
||||
arg: {
|
||||
type: TYPE_SCALAR
|
||||
scalar_type: "uint32_t"
|
||||
}
|
||||
}
|
||||
|
||||
api: {
|
||||
name: "deleteAllUsers"
|
||||
return_type_hidl: {
|
||||
type: TYPE_STRUCT
|
||||
predefined_type: "::android::hardware::gatekeeper::V1_0::GatekeeperResponse"
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
37
gatekeeper/1.0/vts/functional/Android.bp
Normal file
37
gatekeeper/1.0/vts/functional/Android.bp
Normal file
@@ -0,0 +1,37 @@
|
||||
//
|
||||
// Copyright (C) 2016 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
cc_test {
|
||||
name: "gatekeeper_hidl_hal_test",
|
||||
gtest: true,
|
||||
srcs: ["gatekeeper_hidl_hal_test.cpp"],
|
||||
shared_libs: [
|
||||
"libbase",
|
||||
"liblog",
|
||||
"libcutils",
|
||||
"libhidlbase",
|
||||
"libhidltransport",
|
||||
"libhwbinder",
|
||||
"libnativehelper",
|
||||
"libutils",
|
||||
"android.hardware.gatekeeper@1.0",
|
||||
],
|
||||
static_libs: ["libgtest"],
|
||||
cflags: [
|
||||
"-O0",
|
||||
"-g",
|
||||
],
|
||||
}
|
||||
408
gatekeeper/1.0/vts/functional/gatekeeper_hidl_hal_test.cpp
Normal file
408
gatekeeper/1.0/vts/functional/gatekeeper_hidl_hal_test.cpp
Normal file
@@ -0,0 +1,408 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "gatekeeper_hidl_hal_test"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <hardware/hw_auth_token.h>
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <android/hardware/gatekeeper/1.0/IGatekeeper.h>
|
||||
#include <android/hardware/gatekeeper/1.0/types.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
using ::android::hardware::hidl_string;
|
||||
using ::android::hardware::hidl_vec;
|
||||
using ::android::hardware::gatekeeper::V1_0::IGatekeeper;
|
||||
using ::android::hardware::gatekeeper::V1_0::GatekeeperResponse;
|
||||
using ::android::hardware::gatekeeper::V1_0::GatekeeperStatusCode;
|
||||
using ::android::hardware::Return;
|
||||
using ::android::hardware::Void;
|
||||
using ::android::sp;
|
||||
|
||||
struct GatekeeperRequest {
|
||||
uint32_t uid;
|
||||
uint64_t challenge;
|
||||
hidl_vec<uint8_t> curPwdHandle;
|
||||
hidl_vec<uint8_t> curPwd;
|
||||
hidl_vec<uint8_t> newPwd;
|
||||
GatekeeperRequest() : uid(0), challenge(0) {}
|
||||
};
|
||||
|
||||
// ASSERT_* macros generate return "void" internally
|
||||
// we have to use EXPECT_* if we return anything but "void"
|
||||
static const hw_auth_token_t *toAuthToken(GatekeeperResponse &rsp) {
|
||||
const hw_auth_token_t *auth_token =
|
||||
reinterpret_cast<hw_auth_token_t *>(rsp.data.data());
|
||||
const size_t auth_token_size = rsp.data.size();
|
||||
|
||||
EXPECT_NE(nullptr, auth_token);
|
||||
EXPECT_EQ(sizeof(hw_auth_token_t), auth_token_size);
|
||||
|
||||
if (auth_token != nullptr && auth_token_size >= sizeof(*auth_token)) {
|
||||
// these are in network order: translate to host
|
||||
uint32_t auth_type = ntohl(auth_token->authenticator_type);
|
||||
uint64_t auth_tstamp = ntohq(auth_token->timestamp);
|
||||
|
||||
EXPECT_EQ(HW_AUTH_PASSWORD, auth_type);
|
||||
EXPECT_NE(UINT64_C(~0), auth_tstamp);
|
||||
EXPECT_EQ(HW_AUTH_TOKEN_VERSION, auth_token->version);
|
||||
// EXPECT_NE(UINT64_C(0), auth_token->authenticator_id);
|
||||
ALOGI("Authenticator ID: %016" PRIX64, auth_token->authenticator_id);
|
||||
EXPECT_NE(UINT32_C(0), auth_token->user_id);
|
||||
}
|
||||
return auth_token;
|
||||
}
|
||||
|
||||
// The main test class for Gatekeeper HIDL HAL.
|
||||
class GatekeeperHidlTest : public ::testing::Test {
|
||||
protected:
|
||||
void setUid(uint32_t uid) { uid_ = uid; }
|
||||
|
||||
void doEnroll(GatekeeperRequest &req, GatekeeperResponse &rsp) {
|
||||
while (true) {
|
||||
auto ret = gatekeeper_->enroll(
|
||||
uid_, req.curPwdHandle, req.curPwd, req.newPwd,
|
||||
[&rsp](const GatekeeperResponse &cbRsp) { rsp = cbRsp; });
|
||||
ASSERT_TRUE(ret.getStatus().isOk());
|
||||
if (rsp.code != GatekeeperStatusCode::ERROR_RETRY_TIMEOUT) break;
|
||||
ALOGI("%s: got retry code; retrying in 1 sec", __func__);
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
void doVerify(GatekeeperRequest &req, GatekeeperResponse &rsp) {
|
||||
while (true) {
|
||||
auto ret = gatekeeper_->verify(
|
||||
uid_, req.challenge, req.curPwdHandle, req.newPwd,
|
||||
[&rsp](const GatekeeperResponse &cb_rsp) { rsp = cb_rsp; });
|
||||
ASSERT_TRUE(ret.getStatus().isOk());
|
||||
if (rsp.code != GatekeeperStatusCode::ERROR_RETRY_TIMEOUT) break;
|
||||
ALOGI("%s: got retry code; retrying in 1 sec", __func__);
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
void doDeleteUser(GatekeeperResponse &rsp) {
|
||||
while (true) {
|
||||
auto ret = gatekeeper_->deleteUser(
|
||||
uid_, [&rsp](const GatekeeperResponse &cb_rsp) { rsp = cb_rsp; });
|
||||
ASSERT_TRUE(ret.getStatus().isOk());
|
||||
if (rsp.code != GatekeeperStatusCode::ERROR_RETRY_TIMEOUT) break;
|
||||
ALOGI("%s: got retry code; retrying in 1 sec", __func__);
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
void doDeleteAllUsers(GatekeeperResponse &rsp) {
|
||||
while (true) {
|
||||
auto ret = gatekeeper_->deleteAllUsers(
|
||||
[&rsp](const GatekeeperResponse &cb_rsp) { rsp = cb_rsp; });
|
||||
ASSERT_TRUE(ret.getStatus().isOk());
|
||||
if (rsp.code != GatekeeperStatusCode::ERROR_RETRY_TIMEOUT) break;
|
||||
ALOGI("%s: got retry code; retrying in 1 sec", __func__);
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
void generatePassword(hidl_vec<uint8_t> &password, uint8_t seed) {
|
||||
password.resize(16);
|
||||
memset(password.data(), seed, password.size());
|
||||
}
|
||||
|
||||
void checkEnroll(GatekeeperResponse &rsp, bool expectSuccess) {
|
||||
if (expectSuccess) {
|
||||
EXPECT_EQ(GatekeeperStatusCode::STATUS_OK, rsp.code);
|
||||
EXPECT_NE(nullptr, rsp.data.data());
|
||||
EXPECT_GT(rsp.data.size(), UINT32_C(0));
|
||||
} else {
|
||||
EXPECT_EQ(GatekeeperStatusCode::ERROR_GENERAL_FAILURE, rsp.code);
|
||||
EXPECT_EQ(UINT32_C(0), rsp.data.size());
|
||||
}
|
||||
}
|
||||
|
||||
void checkVerify(GatekeeperResponse &rsp, uint64_t challenge,
|
||||
bool expectSuccess) {
|
||||
if (expectSuccess) {
|
||||
EXPECT_GE(rsp.code, GatekeeperStatusCode::STATUS_OK);
|
||||
EXPECT_LE(rsp.code, GatekeeperStatusCode::STATUS_REENROLL);
|
||||
|
||||
const hw_auth_token_t *auth_token = toAuthToken(rsp);
|
||||
ASSERT_NE(nullptr, auth_token);
|
||||
EXPECT_EQ(challenge, auth_token->challenge);
|
||||
} else {
|
||||
EXPECT_EQ(GatekeeperStatusCode::ERROR_GENERAL_FAILURE, rsp.code);
|
||||
EXPECT_EQ(UINT32_C(0), rsp.data.size());
|
||||
}
|
||||
}
|
||||
|
||||
void enrollNewPassword(hidl_vec<uint8_t> &password, GatekeeperResponse &rsp,
|
||||
bool expectSuccess) {
|
||||
GatekeeperRequest req;
|
||||
req.newPwd.setToExternal(password.data(), password.size());
|
||||
doEnroll(req, rsp);
|
||||
checkEnroll(rsp, expectSuccess);
|
||||
}
|
||||
|
||||
void verifyPassword(hidl_vec<uint8_t> &password,
|
||||
hidl_vec<uint8_t> &passwordHandle, uint64_t challenge,
|
||||
GatekeeperResponse &verifyRsp, bool expectSuccess) {
|
||||
GatekeeperRequest verifyReq;
|
||||
|
||||
// build verify request for the same password (we want it to succeed)
|
||||
verifyReq.newPwd = password;
|
||||
// use enrolled password handle we've got
|
||||
verifyReq.curPwdHandle = passwordHandle;
|
||||
verifyReq.challenge = challenge;
|
||||
doVerify(verifyReq, verifyRsp);
|
||||
checkVerify(verifyRsp, challenge, expectSuccess);
|
||||
}
|
||||
|
||||
protected:
|
||||
sp<IGatekeeper> gatekeeper_;
|
||||
uint32_t uid_;
|
||||
|
||||
public:
|
||||
GatekeeperHidlTest() : uid_(0) {}
|
||||
virtual void SetUp() override {
|
||||
GatekeeperResponse rsp;
|
||||
gatekeeper_ = IGatekeeper::getService("gatekeeper", false);
|
||||
ASSERT_NE(nullptr, gatekeeper_.get());
|
||||
doDeleteAllUsers(rsp);
|
||||
}
|
||||
|
||||
virtual void TearDown() override {
|
||||
GatekeeperResponse rsp;
|
||||
doDeleteAllUsers(rsp);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Ensure we can enroll new password
|
||||
*/
|
||||
TEST_F(GatekeeperHidlTest, EnrollSuccess) {
|
||||
hidl_vec<uint8_t> password;
|
||||
GatekeeperResponse rsp;
|
||||
ALOGI("Testing Enroll (expected success)");
|
||||
generatePassword(password, 0);
|
||||
enrollNewPassword(password, rsp, true);
|
||||
ALOGI("Testing Enroll done");
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure we can not enroll empty password
|
||||
*/
|
||||
TEST_F(GatekeeperHidlTest, EnrollNoPassword) {
|
||||
hidl_vec<uint8_t> password;
|
||||
GatekeeperResponse rsp;
|
||||
ALOGI("Testing Enroll (expected failure)");
|
||||
enrollNewPassword(password, rsp, false);
|
||||
ALOGI("Testing Enroll done");
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure we can successfully verify previously enrolled password
|
||||
*/
|
||||
TEST_F(GatekeeperHidlTest, VerifySuccess) {
|
||||
GatekeeperResponse enrollRsp;
|
||||
GatekeeperResponse verifyRsp;
|
||||
hidl_vec<uint8_t> password;
|
||||
|
||||
ALOGI("Testing Enroll+Verify (expected success)");
|
||||
generatePassword(password, 0);
|
||||
enrollNewPassword(password, enrollRsp, true);
|
||||
verifyPassword(password, enrollRsp.data, 1, verifyRsp, true);
|
||||
ALOGI("Testing Enroll+Verify done");
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure we can securely update password (keep the same
|
||||
* secure user_id) if we prove we know old password
|
||||
*/
|
||||
TEST_F(GatekeeperHidlTest, TrustedReenroll) {
|
||||
GatekeeperResponse enrollRsp;
|
||||
GatekeeperRequest reenrollReq;
|
||||
GatekeeperResponse reenrollRsp;
|
||||
GatekeeperResponse verifyRsp;
|
||||
GatekeeperResponse reenrollVerifyRsp;
|
||||
hidl_vec<uint8_t> password;
|
||||
hidl_vec<uint8_t> newPassword;
|
||||
|
||||
generatePassword(password, 0);
|
||||
|
||||
ALOGI("Testing Trusted Reenroll (expected success)");
|
||||
enrollNewPassword(password, enrollRsp, true);
|
||||
verifyPassword(password, enrollRsp.data, 0, verifyRsp, true);
|
||||
ALOGI("Primary Enroll+Verify done");
|
||||
|
||||
generatePassword(newPassword, 1);
|
||||
reenrollReq.newPwd.setToExternal(newPassword.data(), newPassword.size());
|
||||
reenrollReq.curPwd.setToExternal(password.data(), password.size());
|
||||
reenrollReq.curPwdHandle.setToExternal(enrollRsp.data.data(),
|
||||
enrollRsp.data.size());
|
||||
|
||||
doEnroll(reenrollReq, reenrollRsp);
|
||||
checkEnroll(reenrollRsp, true);
|
||||
verifyPassword(newPassword, reenrollRsp.data, 0, reenrollVerifyRsp, true);
|
||||
ALOGI("Trusted ReEnroll+Verify done");
|
||||
|
||||
const hw_auth_token_t *first = toAuthToken(verifyRsp);
|
||||
const hw_auth_token_t *second = toAuthToken(reenrollVerifyRsp);
|
||||
if (first != nullptr && second != nullptr) {
|
||||
EXPECT_EQ(first->user_id, second->user_id);
|
||||
}
|
||||
ALOGI("Testing Trusted Reenroll done");
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure we can update password (and get new
|
||||
* secure user_id) if we don't know old password
|
||||
*/
|
||||
TEST_F(GatekeeperHidlTest, UntrustedReenroll) {
|
||||
GatekeeperResponse enrollRsp;
|
||||
GatekeeperRequest reenrollReq;
|
||||
GatekeeperResponse reenrollRsp;
|
||||
GatekeeperResponse verifyRsp;
|
||||
GatekeeperResponse reenrollVerifyRsp;
|
||||
hidl_vec<uint8_t> password;
|
||||
hidl_vec<uint8_t> newPassword;
|
||||
|
||||
ALOGI("Testing Untrusted Reenroll (expected success)");
|
||||
generatePassword(password, 0);
|
||||
enrollNewPassword(password, enrollRsp, true);
|
||||
verifyPassword(password, enrollRsp.data, 0, verifyRsp, true);
|
||||
ALOGI("Primary Enroll+Verify done");
|
||||
|
||||
generatePassword(newPassword, 1);
|
||||
enrollNewPassword(newPassword, reenrollRsp, true);
|
||||
verifyPassword(newPassword, reenrollRsp.data, 0, reenrollVerifyRsp, true);
|
||||
ALOGI("Untrusted ReEnroll+Verify done");
|
||||
|
||||
const hw_auth_token_t *first = toAuthToken(verifyRsp);
|
||||
const hw_auth_token_t *second = toAuthToken(reenrollVerifyRsp);
|
||||
if (first != nullptr && second != nullptr) {
|
||||
EXPECT_NE(first->user_id, second->user_id);
|
||||
}
|
||||
ALOGI("Testing Untrusted Reenroll done");
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure we dont get successful verify with invalid data
|
||||
*/
|
||||
TEST_F(GatekeeperHidlTest, VerifyNoData) {
|
||||
hidl_vec<uint8_t> password;
|
||||
hidl_vec<uint8_t> passwordHandle;
|
||||
GatekeeperResponse verifyRsp;
|
||||
|
||||
ALOGI("Testing Verify (expected failure)");
|
||||
verifyPassword(password, passwordHandle, 0, verifyRsp, false);
|
||||
EXPECT_EQ(GatekeeperStatusCode::ERROR_GENERAL_FAILURE, verifyRsp.code);
|
||||
ALOGI("Testing Verify done");
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure we can not verify password after we enrolled it and then deleted user
|
||||
*/
|
||||
TEST_F(GatekeeperHidlTest, DeleteUserTest) {
|
||||
hidl_vec<uint8_t> password;
|
||||
GatekeeperResponse enrollRsp;
|
||||
GatekeeperResponse verifyRsp;
|
||||
GatekeeperResponse delRsp;
|
||||
ALOGI("Testing deleteUser (expected success)");
|
||||
setUid(10001);
|
||||
generatePassword(password, 0);
|
||||
enrollNewPassword(password, enrollRsp, true);
|
||||
verifyPassword(password, enrollRsp.data, 0, verifyRsp, true);
|
||||
ALOGI("Enroll+Verify done");
|
||||
doDeleteUser(delRsp);
|
||||
EXPECT_EQ(UINT32_C(0), delRsp.data.size());
|
||||
EXPECT_TRUE(delRsp.code == GatekeeperStatusCode::ERROR_NOT_IMPLEMENTED ||
|
||||
delRsp.code == GatekeeperStatusCode::STATUS_OK);
|
||||
ALOGI("DeleteUser done");
|
||||
if (delRsp.code == GatekeeperStatusCode::STATUS_OK) {
|
||||
verifyPassword(password, enrollRsp.data, 0, verifyRsp, false);
|
||||
EXPECT_EQ(GatekeeperStatusCode::ERROR_GENERAL_FAILURE, verifyRsp.code);
|
||||
ALOGI("Verify after Delete done (must fail)");
|
||||
}
|
||||
ALOGI("Testing deleteUser done: rsp=%" PRIi32, delRsp.code);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure we can not verify passwords after we enrolled them and then deleted
|
||||
* all users
|
||||
*/
|
||||
TEST_F(GatekeeperHidlTest, DeleteAllUsersTest) {
|
||||
struct UserData {
|
||||
uint32_t userId;
|
||||
hidl_vec<uint8_t> password;
|
||||
GatekeeperResponse enrollRsp;
|
||||
GatekeeperResponse verifyRsp;
|
||||
UserData(int id) { userId = id; }
|
||||
} users[3]{10001, 10002, 10003};
|
||||
GatekeeperResponse delAllRsp;
|
||||
ALOGI("Testing deleteAllUsers (expected success)");
|
||||
|
||||
// enroll multiple users
|
||||
for (size_t i = 0; i < sizeof(users) / sizeof(users[0]); ++i) {
|
||||
setUid(users[i].userId);
|
||||
generatePassword(users[i].password, (i % 255) + 1);
|
||||
enrollNewPassword(users[i].password, users[i].enrollRsp, true);
|
||||
}
|
||||
ALOGI("Multiple users enrolled");
|
||||
|
||||
// verify multiple users
|
||||
for (size_t i = 0; i < sizeof(users) / sizeof(users[0]); ++i) {
|
||||
setUid(users[i].userId);
|
||||
verifyPassword(users[i].password, users[i].enrollRsp.data, 0,
|
||||
users[i].verifyRsp, true);
|
||||
}
|
||||
ALOGI("Multiple users verified");
|
||||
|
||||
doDeleteAllUsers(delAllRsp);
|
||||
EXPECT_EQ(UINT32_C(0), delAllRsp.data.size());
|
||||
EXPECT_TRUE(delAllRsp.code == GatekeeperStatusCode::ERROR_NOT_IMPLEMENTED ||
|
||||
delAllRsp.code == GatekeeperStatusCode::STATUS_OK);
|
||||
ALOGI("All users deleted");
|
||||
|
||||
if (delAllRsp.code == GatekeeperStatusCode::STATUS_OK) {
|
||||
// verify multiple users after they are deleted; all must fail
|
||||
for (size_t i = 0; i < sizeof(users) / sizeof(users[0]); ++i) {
|
||||
setUid(users[i].userId);
|
||||
verifyPassword(users[i].password, users[i].enrollRsp.data, 0,
|
||||
users[i].verifyRsp, false);
|
||||
EXPECT_EQ(GatekeeperStatusCode::ERROR_GENERAL_FAILURE,
|
||||
users[i].verifyRsp.code);
|
||||
}
|
||||
ALOGI("Multiple users verified after delete (all must fail)");
|
||||
}
|
||||
|
||||
ALOGI("Testing deleteAllUsers done: rsp=%" PRIi32, delAllRsp.code);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
int status = RUN_ALL_TESTS();
|
||||
ALOGI("Test result = %d", status);
|
||||
return status;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#
|
||||
# Copyright (C) 2016 The Android Open Source Project
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
include $(call all-subdir-makefiles)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE := HalGatekeeperHidlTargetBasicTest
|
||||
VTS_CONFIG_SRC_DIR := testcases/hal/gatekeeper/hidl/target
|
||||
include test/vts/tools/build/Android.host_config.mk
|
||||
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<configuration description="Config for VTS Gatekeeper HIDL HAL's basic target-side test cases">
|
||||
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.VtsFilePusher">
|
||||
<option name="push-group" value="HidlHalTest.push" />
|
||||
</target_preparer>
|
||||
<target_preparer class="com.android.tradefed.targetprep.VtsPythonVirtualenvPreparer" />
|
||||
<test class="com.android.tradefed.testtype.VtsMultiDeviceTest">
|
||||
<option name="test-module-name" value="HalGatekeeperHidlTargetBasicTest" />
|
||||
<option name="binary-test-sources" value="
|
||||
_32bit::DATA/nativetest/gatekeeper_hidl_hal_test/gatekeeper_hidl_hal_test,
|
||||
_64bit::DATA/nativetest64/gatekeeper_hidl_hal_test/gatekeeper_hidl_hal_test,
|
||||
"/>
|
||||
<option name="binary-test-type" value="gtest" />
|
||||
<option name="test-timeout" value="1m" />
|
||||
</test>
|
||||
</configuration>
|
||||
59
gatekeeper/1.0/vts/types.vts
Normal file
59
gatekeeper/1.0/vts/types.vts
Normal file
@@ -0,0 +1,59 @@
|
||||
component_class: HAL_HIDL
|
||||
component_type_version: 1.0
|
||||
component_name: "types"
|
||||
|
||||
package: "android.hardware.gatekeeper"
|
||||
|
||||
|
||||
attribute: {
|
||||
name: "::android::hardware::gatekeeper::V1_0::GatekeeperStatusCode"
|
||||
type: TYPE_ENUM
|
||||
enum_value: {
|
||||
scalar_type: "int32_t"
|
||||
|
||||
enumerator: "STATUS_REENROLL"
|
||||
scalar_value: {
|
||||
int32_t: 1
|
||||
}
|
||||
enumerator: "STATUS_OK"
|
||||
scalar_value: {
|
||||
int32_t: 0
|
||||
}
|
||||
enumerator: "ERROR_GENERAL_FAILURE"
|
||||
scalar_value: {
|
||||
int32_t: -1
|
||||
}
|
||||
enumerator: "ERROR_RETRY_TIMEOUT"
|
||||
scalar_value: {
|
||||
int32_t: -2
|
||||
}
|
||||
enumerator: "ERROR_NOT_IMPLEMENTED"
|
||||
scalar_value: {
|
||||
int32_t: -3
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
attribute: {
|
||||
name: "::android::hardware::gatekeeper::V1_0::GatekeeperResponse"
|
||||
type: TYPE_STRUCT
|
||||
struct_value: {
|
||||
name: "code"
|
||||
type: TYPE_ENUM
|
||||
predefined_type: "::android::hardware::gatekeeper::V1_0::GatekeeperStatusCode"
|
||||
}
|
||||
struct_value: {
|
||||
name: "timeout"
|
||||
type: TYPE_SCALAR
|
||||
scalar_type: "uint32_t"
|
||||
}
|
||||
struct_value: {
|
||||
name: "data"
|
||||
type: TYPE_VECTOR
|
||||
vector_value: {
|
||||
type: TYPE_SCALAR
|
||||
scalar_type: "uint8_t"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// This is an autogenerated file, do not edit.
|
||||
subdirs = [
|
||||
"1.0",
|
||||
"1.0/vts/functional",
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user