blob: a2425046407f7f0d98b69e88e4260807f9925d24 [file] [log] [blame]
Andres Morales2d08dce2015-04-03 16:40:15 -07001/*
2 * Copyright (C) 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#define LOG_TAG "gatekeeperd"
18
19#include "IGateKeeperService.h"
20
Andres Morales6a49c2f2015-04-16 13:16:24 -070021#include <errno.h>
22#include <stdint.h>
23#include <inttypes.h>
24#include <fcntl.h>
25#include <unistd.h>
26
Andres Morales2d08dce2015-04-03 16:40:15 -070027#include <cutils/log.h>
28#include <utils/Log.h>
29
30#include <binder/IPCThreadState.h>
31#include <binder/IServiceManager.h>
32#include <binder/PermissionCache.h>
33#include <utils/String16.h>
34
35#include <keystore/IKeystoreService.h>
Andres Morales2ae8b4c2015-04-13 09:20:09 -070036#include <keystore/keystore.h> // For error code
Andres Morales6a49c2f2015-04-16 13:16:24 -070037#include <gatekeeper/password_handle.h> // for password_handle_t
Andres Morales2d08dce2015-04-03 16:40:15 -070038#include <hardware/gatekeeper.h>
Andres Morales6a49c2f2015-04-16 13:16:24 -070039#include <hardware/hw_auth_token.h>
Andres Morales2d08dce2015-04-03 16:40:15 -070040
41namespace android {
42
43static const String16 KEYGUARD_PERMISSION("android.permission.ACCESS_KEYGUARD_SECURE_STORAGE");
44static const String16 DUMP_PERMISSION("android.permission.DUMP");
45
46class GateKeeperProxy : public BnGateKeeperService {
47public:
48 GateKeeperProxy() {
49 int ret = hw_get_module_by_class(GATEKEEPER_HARDWARE_MODULE_ID, NULL, &module);
50 if (ret < 0)
51 LOG_ALWAYS_FATAL_IF(ret < 0, "Unable to find GateKeeper HAL");
52 ret = gatekeeper_open(module, &device);
53 if (ret < 0)
54 LOG_ALWAYS_FATAL_IF(ret < 0, "Unable to open GateKeeper HAL");
55 }
56
57 virtual ~GateKeeperProxy() {
58 gatekeeper_close(device);
59 }
60
Andres Morales6a49c2f2015-04-16 13:16:24 -070061 void store_sid(uint32_t uid, uint64_t sid) {
62 char filename[21];
63 sprintf(filename, "%u", uid);
64 int fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR);
65 if (fd < 0) {
66 ALOGW("could not open file: %s: %s", filename, strerror(errno));
67 return;
68 }
69 write(fd, &sid, sizeof(sid));
70 close(fd);
71 }
72
73 void maybe_store_sid(uint32_t uid, uint64_t sid) {
74 char filename[21];
75 sprintf(filename, "%u", uid);
76 if (access(filename, F_OK) == -1) {
77 store_sid(uid, sid);
78 }
79 }
80
81 uint64_t read_sid(uint32_t uid) {
82 char filename[21];
83 uint64_t sid;
84 sprintf(filename, "%u", uid);
85 int fd = open(filename, O_RDONLY);
86 if (fd < 0) return 0;
87 read(fd, &sid, sizeof(sid));
88 return sid;
89 }
90
Andres Morales2d08dce2015-04-03 16:40:15 -070091 virtual status_t enroll(uint32_t uid,
92 const uint8_t *current_password_handle, uint32_t current_password_handle_length,
93 const uint8_t *current_password, uint32_t current_password_length,
94 const uint8_t *desired_password, uint32_t desired_password_length,
95 uint8_t **enrolled_password_handle, uint32_t *enrolled_password_handle_length) {
96 IPCThreadState* ipc = IPCThreadState::self();
97 const int calling_pid = ipc->getCallingPid();
98 const int calling_uid = ipc->getCallingUid();
99 if (!PermissionCache::checkPermission(KEYGUARD_PERMISSION, calling_pid, calling_uid)) {
100 return PERMISSION_DENIED;
101 }
102
103 // need a desired password to enroll
104 if (desired_password_length == 0) return -EINVAL;
105 int ret = device->enroll(device, uid,
106 current_password_handle, current_password_handle_length,
107 current_password, current_password_length,
108 desired_password, desired_password_length,
109 enrolled_password_handle, enrolled_password_handle_length);
Andres Morales6a49c2f2015-04-16 13:16:24 -0700110 if (ret >= 0) {
111 gatekeeper::password_handle_t *handle =
112 reinterpret_cast<gatekeeper::password_handle_t *>(*enrolled_password_handle);
113 store_sid(uid, handle->user_id);
114 return NO_ERROR;
115 }
116 return UNKNOWN_ERROR;
Andres Morales2d08dce2015-04-03 16:40:15 -0700117 }
118
Andres Moralesc828ae82015-04-10 21:03:07 -0700119 virtual status_t verify(uint32_t uid,
Andres Morales2d08dce2015-04-03 16:40:15 -0700120 const uint8_t *enrolled_password_handle, uint32_t enrolled_password_handle_length,
121 const uint8_t *provided_password, uint32_t provided_password_length) {
Andres Moralesc828ae82015-04-10 21:03:07 -0700122 uint8_t *auth_token;
123 uint32_t auth_token_length;
124 return verifyChallenge(uid, 0, enrolled_password_handle, enrolled_password_handle_length,
125 provided_password, provided_password_length,
126 &auth_token, &auth_token_length);
127 }
128
129 virtual status_t verifyChallenge(uint32_t uid, uint64_t challenge,
130 const uint8_t *enrolled_password_handle, uint32_t enrolled_password_handle_length,
131 const uint8_t *provided_password, uint32_t provided_password_length,
132 uint8_t **auth_token, uint32_t *auth_token_length) {
Andres Morales2d08dce2015-04-03 16:40:15 -0700133 IPCThreadState* ipc = IPCThreadState::self();
134 const int calling_pid = ipc->getCallingPid();
135 const int calling_uid = ipc->getCallingUid();
136 if (!PermissionCache::checkPermission(KEYGUARD_PERMISSION, calling_pid, calling_uid)) {
137 return PERMISSION_DENIED;
138 }
139
140 // can't verify if we're missing either param
141 if ((enrolled_password_handle_length | provided_password_length) == 0)
142 return -EINVAL;
143
Andres Morales851b57c2015-04-09 19:23:48 -0700144 int ret = device->verify(device, uid, challenge,
Andres Morales2d08dce2015-04-03 16:40:15 -0700145 enrolled_password_handle, enrolled_password_handle_length,
Andres Moralesc828ae82015-04-10 21:03:07 -0700146 provided_password, provided_password_length, auth_token, auth_token_length);
Andres Morales2d08dce2015-04-03 16:40:15 -0700147
Andres Moralesc828ae82015-04-10 21:03:07 -0700148 if (ret >= 0 && *auth_token != NULL && *auth_token_length > 0) {
Andres Morales2d08dce2015-04-03 16:40:15 -0700149 // TODO: cache service?
150 sp<IServiceManager> sm = defaultServiceManager();
151 sp<IBinder> binder = sm->getService(String16("android.security.keystore"));
152 sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder);
153 if (service != NULL) {
Andres Morales2ae8b4c2015-04-13 09:20:09 -0700154 status_t ret = service->addAuthToken(*auth_token, *auth_token_length);
155 if (ret != ResponseCode::NO_ERROR) {
156 ALOGE("Falure sending auth token to KeyStore: %d", ret);
Andres Morales2d08dce2015-04-03 16:40:15 -0700157 }
158 } else {
159 ALOGE("Unable to communicate with KeyStore");
160 }
161 }
162
Andres Morales6a49c2f2015-04-16 13:16:24 -0700163 if (ret >= 0) {
164 maybe_store_sid(uid, reinterpret_cast<const gatekeeper::password_handle_t *>(
165 enrolled_password_handle)->user_id);
166 return NO_ERROR;
167 }
168
169 return UNKNOWN_ERROR;
170 }
171
172 virtual uint64_t getSecureUserId(uint32_t uid) {
173 return read_sid(uid);
Andres Morales2d08dce2015-04-03 16:40:15 -0700174 }
175
Andres Morales7c9c3bc2015-04-16 15:57:17 -0700176 virtual void clearSecureUserId(uint32_t uid) {
177 IPCThreadState* ipc = IPCThreadState::self();
178 const int calling_pid = ipc->getCallingPid();
179 const int calling_uid = ipc->getCallingUid();
180 if (!PermissionCache::checkPermission(KEYGUARD_PERMISSION, calling_pid, calling_uid)) {
181 ALOGE("%s: permission denied for [%d:%d]", __func__, calling_pid, calling_uid);
182 return;
183 }
184 store_sid(uid, 0);
185 }
186
Andres Morales2d08dce2015-04-03 16:40:15 -0700187 virtual status_t dump(int fd, const Vector<String16> &) {
188 IPCThreadState* ipc = IPCThreadState::self();
189 const int pid = ipc->getCallingPid();
190 const int uid = ipc->getCallingUid();
191 if (!PermissionCache::checkPermission(DUMP_PERMISSION, pid, uid)) {
192 return PERMISSION_DENIED;
193 }
194
195 if (device == NULL) {
196 const char *result = "Device not available";
197 write(fd, result, strlen(result) + 1);
198 } else {
199 const char *result = "OK";
200 write(fd, result, strlen(result) + 1);
201 }
202
203 return NO_ERROR;
204 }
205
206private:
207 gatekeeper_device_t *device;
208 const hw_module_t *module;
209};
210}// namespace android
211
Andres Morales6a49c2f2015-04-16 13:16:24 -0700212int main(int argc, char* argv[]) {
Andres Morales2d08dce2015-04-03 16:40:15 -0700213 ALOGI("Starting gatekeeperd...");
Andres Morales6a49c2f2015-04-16 13:16:24 -0700214 if (argc < 2) {
215 ALOGE("A directory must be specified!");
216 return 1;
217 }
218 if (chdir(argv[1]) == -1) {
219 ALOGE("chdir: %s: %s", argv[1], strerror(errno));
220 return 1;
221 }
222
Andres Morales2d08dce2015-04-03 16:40:15 -0700223 android::sp<android::IServiceManager> sm = android::defaultServiceManager();
224 android::sp<android::GateKeeperProxy> proxy = new android::GateKeeperProxy();
225 android::status_t ret = sm->addService(
226 android::String16("android.service.gatekeeper.IGateKeeperService"), proxy);
227 if (ret != android::OK) {
228 ALOGE("Couldn't register binder service!");
229 return -1;
230 }
231
232 /*
233 * We're the only thread in existence, so we're just going to process
234 * Binder transaction as a single-threaded program.
235 */
236 android::IPCThreadState::self()->joinThreadPool();
237 return 0;
238}