1/*
2 * Copyright 2015 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#include <arpa/inet.h>
18#include <iostream>
19
20#include <gtest/gtest.h>
21#include <hardware/hw_auth_token.h>
22#include <UniquePtr.h>
23
24#include "../SoftGateKeeper.h"
25
26using ::gatekeeper::SizedBuffer;
27using ::testing::Test;
28using ::gatekeeper::EnrollRequest;
29using ::gatekeeper::EnrollResponse;
30using ::gatekeeper::VerifyRequest;
31using ::gatekeeper::VerifyResponse;
32using ::gatekeeper::SoftGateKeeper;
33using ::gatekeeper::secure_id_t;
34
35static void do_enroll(SoftGateKeeper &gatekeeper, EnrollResponse *response) {
36    SizedBuffer password;
37
38    password.buffer.reset(new uint8_t[16]);
39    password.length = 16;
40    memset(password.buffer.get(), 0, 16);
41    EnrollRequest request(0, NULL, &password, NULL);
42
43    gatekeeper.Enroll(request, response);
44}
45
46TEST(GateKeeperTest, EnrollSuccess) {
47    SoftGateKeeper gatekeeper;
48    EnrollResponse response;
49    do_enroll(gatekeeper, &response);
50    ASSERT_EQ(::gatekeeper::gatekeeper_error_t::ERROR_NONE, response.error);
51}
52
53TEST(GateKeeperTest, EnrollBogusData) {
54    SoftGateKeeper gatekeeper;
55    SizedBuffer password;
56    EnrollResponse response;
57
58    EnrollRequest request(0, NULL, &password, NULL);
59
60    gatekeeper.Enroll(request, &response);
61
62    ASSERT_EQ(::gatekeeper::gatekeeper_error_t::ERROR_INVALID, response.error);
63}
64
65TEST(GateKeeperTest, VerifySuccess) {
66    SoftGateKeeper gatekeeper;
67    SizedBuffer provided_password;
68    EnrollResponse enroll_response;
69
70    provided_password.buffer.reset(new uint8_t[16]);
71    provided_password.length = 16;
72    memset(provided_password.buffer.get(), 0, 16);
73
74    do_enroll(gatekeeper, &enroll_response);
75    ASSERT_EQ(::gatekeeper::gatekeeper_error_t::ERROR_NONE, enroll_response.error);
76    VerifyRequest request(0, 1, &enroll_response.enrolled_password_handle,
77            &provided_password);
78    VerifyResponse response;
79
80    gatekeeper.Verify(request, &response);
81
82    ASSERT_EQ(::gatekeeper::gatekeeper_error_t::ERROR_NONE, response.error);
83
84    hw_auth_token_t *auth_token =
85        reinterpret_cast<hw_auth_token_t *>(response.auth_token.buffer.get());
86
87    ASSERT_EQ((uint32_t) HW_AUTH_PASSWORD, ntohl(auth_token->authenticator_type));
88    ASSERT_EQ((uint64_t) 1, auth_token->challenge);
89    ASSERT_NE(~((uint32_t) 0), auth_token->timestamp);
90    ASSERT_NE((uint64_t) 0, auth_token->user_id);
91    ASSERT_NE((uint64_t) 0, auth_token->authenticator_id);
92}
93
94TEST(GateKeeperTest, TrustedReEnroll) {
95    SoftGateKeeper gatekeeper;
96    SizedBuffer provided_password;
97    EnrollResponse enroll_response;
98    SizedBuffer password_handle;
99
100    // do_enroll enrolls an all 0 password
101    provided_password.buffer.reset(new uint8_t[16]);
102    provided_password.length = 16;
103    memset(provided_password.buffer.get(), 0, 16);
104    do_enroll(gatekeeper, &enroll_response);
105    ASSERT_EQ(::gatekeeper::gatekeeper_error_t::ERROR_NONE, enroll_response.error);
106
107    // keep a copy of the handle
108    password_handle.buffer.reset(new uint8_t[enroll_response.enrolled_password_handle.length]);
109    password_handle.length = enroll_response.enrolled_password_handle.length;
110    memcpy(password_handle.buffer.get(), enroll_response.enrolled_password_handle.buffer.get(),
111            password_handle.length);
112
113    // verify first password
114    VerifyRequest request(0, 0, &enroll_response.enrolled_password_handle,
115            &provided_password);
116    VerifyResponse response;
117    gatekeeper.Verify(request, &response);
118    ASSERT_EQ(::gatekeeper::gatekeeper_error_t::ERROR_NONE, response.error);
119    hw_auth_token_t *auth_token =
120        reinterpret_cast<hw_auth_token_t *>(response.auth_token.buffer.get());
121
122    secure_id_t secure_id = auth_token->user_id;
123
124    // enroll new password
125    provided_password.buffer.reset(new uint8_t[16]);
126    provided_password.length = 16;
127    memset(provided_password.buffer.get(), 0, 16);
128    SizedBuffer password;
129    password.buffer.reset(new uint8_t[16]);
130    memset(password.buffer.get(), 1, 16);
131    password.length = 16;
132    EnrollRequest enroll_request(0, &password_handle, &password, &provided_password);
133    gatekeeper.Enroll(enroll_request, &enroll_response);
134    ASSERT_EQ(::gatekeeper::gatekeeper_error_t::ERROR_NONE, enroll_response.error);
135
136    // verify new password
137    password.buffer.reset(new uint8_t[16]);
138    memset(password.buffer.get(), 1, 16);
139    password.length = 16;
140    VerifyRequest new_request(0, 0, &enroll_response.enrolled_password_handle,
141            &password);
142    gatekeeper.Verify(new_request, &response);
143    ASSERT_EQ(::gatekeeper::gatekeeper_error_t::ERROR_NONE, response.error);
144    ASSERT_EQ(secure_id,
145        reinterpret_cast<hw_auth_token_t *>(response.auth_token.buffer.get())->user_id);
146}
147
148
149TEST(GateKeeperTest, UntrustedReEnroll) {
150    SoftGateKeeper gatekeeper;
151    SizedBuffer provided_password;
152    EnrollResponse enroll_response;
153
154    // do_enroll enrolls an all 0 password
155    provided_password.buffer.reset(new uint8_t[16]);
156    provided_password.length = 16;
157    memset(provided_password.buffer.get(), 0, 16);
158    do_enroll(gatekeeper, &enroll_response);
159    ASSERT_EQ(::gatekeeper::gatekeeper_error_t::ERROR_NONE, enroll_response.error);
160
161    // verify first password
162    VerifyRequest request(0, 0, &enroll_response.enrolled_password_handle,
163            &provided_password);
164    VerifyResponse response;
165    gatekeeper.Verify(request, &response);
166    ASSERT_EQ(::gatekeeper::gatekeeper_error_t::ERROR_NONE, response.error);
167    hw_auth_token_t *auth_token =
168        reinterpret_cast<hw_auth_token_t *>(response.auth_token.buffer.get());
169
170    secure_id_t secure_id = auth_token->user_id;
171
172    // enroll new password
173    SizedBuffer password;
174    password.buffer.reset(new uint8_t[16]);
175    memset(password.buffer.get(), 1, 16);
176    password.length = 16;
177    EnrollRequest enroll_request(0, NULL, &password, NULL);
178    gatekeeper.Enroll(enroll_request, &enroll_response);
179    ASSERT_EQ(::gatekeeper::gatekeeper_error_t::ERROR_NONE, enroll_response.error);
180
181    // verify new password
182    password.buffer.reset(new uint8_t[16]);
183    memset(password.buffer.get(), 1, 16);
184    password.length = 16;
185    VerifyRequest new_request(0, 0, &enroll_response.enrolled_password_handle,
186            &password);
187    gatekeeper.Verify(new_request, &response);
188    ASSERT_EQ(::gatekeeper::gatekeeper_error_t::ERROR_NONE, response.error);
189    ASSERT_NE(secure_id,
190        reinterpret_cast<hw_auth_token_t *>(response.auth_token.buffer.get())->user_id);
191}
192
193
194TEST(GateKeeperTest, VerifyBogusData) {
195    SoftGateKeeper gatekeeper;
196    SizedBuffer provided_password;
197    SizedBuffer password_handle;
198    VerifyResponse response;
199
200    VerifyRequest request(0, 0, &provided_password, &password_handle);
201
202    gatekeeper.Verify(request, &response);
203
204    ASSERT_EQ(::gatekeeper::gatekeeper_error_t::ERROR_INVALID, response.error);
205}
206