gatekeeperd.cpp revision 7c9c3bc9c2d3f98ff839f73dc76750dc23693eae
1/*
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
21#include <errno.h>
22#include <stdint.h>
23#include <inttypes.h>
24#include <fcntl.h>
25#include <unistd.h>
26
27#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>
36#include <keystore/keystore.h> // For error code
37#include <gatekeeper/password_handle.h> // for password_handle_t
38#include <hardware/gatekeeper.h>
39#include <hardware/hw_auth_token.h>
40
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
61    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
91    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);
110        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;
117    }
118
119    virtual status_t verify(uint32_t uid,
120            const uint8_t *enrolled_password_handle, uint32_t enrolled_password_handle_length,
121            const uint8_t *provided_password, uint32_t provided_password_length) {
122        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) {
133        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
144        int ret = device->verify(device, uid, challenge,
145                enrolled_password_handle, enrolled_password_handle_length,
146                provided_password, provided_password_length, auth_token, auth_token_length);
147
148        if (ret >= 0 && *auth_token != NULL && *auth_token_length > 0) {
149            // 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) {
154                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);
157                }
158            } else {
159                ALOGE("Unable to communicate with KeyStore");
160            }
161        }
162
163        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);
174    }
175
176    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
187    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
212int main(int argc, char* argv[]) {
213    ALOGI("Starting gatekeeperd...");
214    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
223    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}
239