| /* |
| * Copyright 2015 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. |
| */ |
| |
| #include <arpa/inet.h> |
| #include <iostream> |
| |
| #include <gtest/gtest.h> |
| #include <hardware/hw_auth_token.h> |
| |
| #include "../SoftGateKeeper.h" |
| |
| using ::gatekeeper::SizedBuffer; |
| using ::testing::Test; |
| using ::gatekeeper::EnrollRequest; |
| using ::gatekeeper::EnrollResponse; |
| using ::gatekeeper::VerifyRequest; |
| using ::gatekeeper::VerifyResponse; |
| using ::gatekeeper::SoftGateKeeper; |
| using ::gatekeeper::secure_id_t; |
| |
| static void do_enroll(SoftGateKeeper &gatekeeper, EnrollResponse *response) { |
| SizedBuffer password; |
| |
| password.buffer.reset(new uint8_t[16]); |
| password.length = 16; |
| memset(password.buffer.get(), 0, 16); |
| EnrollRequest request(0, NULL, &password, NULL); |
| |
| gatekeeper.Enroll(request, response); |
| } |
| |
| TEST(GateKeeperTest, EnrollSuccess) { |
| SoftGateKeeper gatekeeper; |
| EnrollResponse response; |
| do_enroll(gatekeeper, &response); |
| ASSERT_EQ(::gatekeeper::gatekeeper_error_t::ERROR_NONE, response.error); |
| } |
| |
| TEST(GateKeeperTest, EnrollBogusData) { |
| SoftGateKeeper gatekeeper; |
| SizedBuffer password; |
| EnrollResponse response; |
| |
| EnrollRequest request(0, NULL, &password, NULL); |
| |
| gatekeeper.Enroll(request, &response); |
| |
| ASSERT_EQ(::gatekeeper::gatekeeper_error_t::ERROR_INVALID, response.error); |
| } |
| |
| TEST(GateKeeperTest, VerifySuccess) { |
| SoftGateKeeper gatekeeper; |
| SizedBuffer provided_password; |
| EnrollResponse enroll_response; |
| |
| provided_password.buffer.reset(new uint8_t[16]); |
| provided_password.length = 16; |
| memset(provided_password.buffer.get(), 0, 16); |
| |
| do_enroll(gatekeeper, &enroll_response); |
| ASSERT_EQ(::gatekeeper::gatekeeper_error_t::ERROR_NONE, enroll_response.error); |
| VerifyRequest request(0, 1, &enroll_response.enrolled_password_handle, |
| &provided_password); |
| VerifyResponse response; |
| |
| gatekeeper.Verify(request, &response); |
| |
| ASSERT_EQ(::gatekeeper::gatekeeper_error_t::ERROR_NONE, response.error); |
| |
| hw_auth_token_t *auth_token = |
| reinterpret_cast<hw_auth_token_t *>(response.auth_token.buffer.get()); |
| |
| ASSERT_EQ((uint32_t) HW_AUTH_PASSWORD, ntohl(auth_token->authenticator_type)); |
| ASSERT_EQ((uint64_t) 1, auth_token->challenge); |
| ASSERT_NE(~((uint32_t) 0), auth_token->timestamp); |
| ASSERT_NE((uint64_t) 0, auth_token->user_id); |
| ASSERT_NE((uint64_t) 0, auth_token->authenticator_id); |
| } |
| |
| TEST(GateKeeperTest, TrustedReEnroll) { |
| SoftGateKeeper gatekeeper; |
| SizedBuffer provided_password; |
| EnrollResponse enroll_response; |
| SizedBuffer password_handle; |
| |
| // do_enroll enrolls an all 0 password |
| provided_password.buffer.reset(new uint8_t[16]); |
| provided_password.length = 16; |
| memset(provided_password.buffer.get(), 0, 16); |
| do_enroll(gatekeeper, &enroll_response); |
| ASSERT_EQ(::gatekeeper::gatekeeper_error_t::ERROR_NONE, enroll_response.error); |
| |
| // keep a copy of the handle |
| password_handle.buffer.reset(new uint8_t[enroll_response.enrolled_password_handle.length]); |
| password_handle.length = enroll_response.enrolled_password_handle.length; |
| memcpy(password_handle.buffer.get(), enroll_response.enrolled_password_handle.buffer.get(), |
| password_handle.length); |
| |
| // verify first password |
| VerifyRequest request(0, 0, &enroll_response.enrolled_password_handle, |
| &provided_password); |
| VerifyResponse response; |
| gatekeeper.Verify(request, &response); |
| ASSERT_EQ(::gatekeeper::gatekeeper_error_t::ERROR_NONE, response.error); |
| hw_auth_token_t *auth_token = |
| reinterpret_cast<hw_auth_token_t *>(response.auth_token.buffer.get()); |
| |
| secure_id_t secure_id = auth_token->user_id; |
| |
| // enroll new password |
| provided_password.buffer.reset(new uint8_t[16]); |
| provided_password.length = 16; |
| memset(provided_password.buffer.get(), 0, 16); |
| SizedBuffer password; |
| password.buffer.reset(new uint8_t[16]); |
| memset(password.buffer.get(), 1, 16); |
| password.length = 16; |
| EnrollRequest enroll_request(0, &password_handle, &password, &provided_password); |
| gatekeeper.Enroll(enroll_request, &enroll_response); |
| ASSERT_EQ(::gatekeeper::gatekeeper_error_t::ERROR_NONE, enroll_response.error); |
| |
| // verify new password |
| password.buffer.reset(new uint8_t[16]); |
| memset(password.buffer.get(), 1, 16); |
| password.length = 16; |
| VerifyRequest new_request(0, 0, &enroll_response.enrolled_password_handle, |
| &password); |
| gatekeeper.Verify(new_request, &response); |
| ASSERT_EQ(::gatekeeper::gatekeeper_error_t::ERROR_NONE, response.error); |
| ASSERT_EQ(secure_id, |
| reinterpret_cast<hw_auth_token_t *>(response.auth_token.buffer.get())->user_id); |
| } |
| |
| |
| TEST(GateKeeperTest, UntrustedReEnroll) { |
| SoftGateKeeper gatekeeper; |
| SizedBuffer provided_password; |
| EnrollResponse enroll_response; |
| |
| // do_enroll enrolls an all 0 password |
| provided_password.buffer.reset(new uint8_t[16]); |
| provided_password.length = 16; |
| memset(provided_password.buffer.get(), 0, 16); |
| do_enroll(gatekeeper, &enroll_response); |
| ASSERT_EQ(::gatekeeper::gatekeeper_error_t::ERROR_NONE, enroll_response.error); |
| |
| // verify first password |
| VerifyRequest request(0, 0, &enroll_response.enrolled_password_handle, |
| &provided_password); |
| VerifyResponse response; |
| gatekeeper.Verify(request, &response); |
| ASSERT_EQ(::gatekeeper::gatekeeper_error_t::ERROR_NONE, response.error); |
| hw_auth_token_t *auth_token = |
| reinterpret_cast<hw_auth_token_t *>(response.auth_token.buffer.get()); |
| |
| secure_id_t secure_id = auth_token->user_id; |
| |
| // enroll new password |
| SizedBuffer password; |
| password.buffer.reset(new uint8_t[16]); |
| memset(password.buffer.get(), 1, 16); |
| password.length = 16; |
| EnrollRequest enroll_request(0, NULL, &password, NULL); |
| gatekeeper.Enroll(enroll_request, &enroll_response); |
| ASSERT_EQ(::gatekeeper::gatekeeper_error_t::ERROR_NONE, enroll_response.error); |
| |
| // verify new password |
| password.buffer.reset(new uint8_t[16]); |
| memset(password.buffer.get(), 1, 16); |
| password.length = 16; |
| VerifyRequest new_request(0, 0, &enroll_response.enrolled_password_handle, |
| &password); |
| gatekeeper.Verify(new_request, &response); |
| ASSERT_EQ(::gatekeeper::gatekeeper_error_t::ERROR_NONE, response.error); |
| ASSERT_NE(secure_id, |
| reinterpret_cast<hw_auth_token_t *>(response.auth_token.buffer.get())->user_id); |
| } |
| |
| |
| TEST(GateKeeperTest, VerifyBogusData) { |
| SoftGateKeeper gatekeeper; |
| SizedBuffer provided_password; |
| SizedBuffer password_handle; |
| VerifyResponse response; |
| |
| VerifyRequest request(0, 0, &provided_password, &password_handle); |
| |
| gatekeeper.Verify(request, &response); |
| |
| ASSERT_EQ(::gatekeeper::gatekeeper_error_t::ERROR_INVALID, response.error); |
| } |