gatekeeperd.cpp revision 851b57c1f81bd3572cf5908611ba029be934c706
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 <cutils/log.h> 22#include <utils/Log.h> 23 24#include <binder/IPCThreadState.h> 25#include <binder/IServiceManager.h> 26#include <binder/PermissionCache.h> 27#include <utils/String16.h> 28 29#include <keystore/IKeystoreService.h> 30#include <hardware/gatekeeper.h> 31 32namespace android { 33 34static const String16 KEYGUARD_PERMISSION("android.permission.ACCESS_KEYGUARD_SECURE_STORAGE"); 35static const String16 DUMP_PERMISSION("android.permission.DUMP"); 36 37class GateKeeperProxy : public BnGateKeeperService { 38public: 39 GateKeeperProxy() { 40 int ret = hw_get_module_by_class(GATEKEEPER_HARDWARE_MODULE_ID, NULL, &module); 41 if (ret < 0) 42 LOG_ALWAYS_FATAL_IF(ret < 0, "Unable to find GateKeeper HAL"); 43 ret = gatekeeper_open(module, &device); 44 if (ret < 0) 45 LOG_ALWAYS_FATAL_IF(ret < 0, "Unable to open GateKeeper HAL"); 46 } 47 48 virtual ~GateKeeperProxy() { 49 gatekeeper_close(device); 50 } 51 52 virtual status_t enroll(uint32_t uid, 53 const uint8_t *current_password_handle, uint32_t current_password_handle_length, 54 const uint8_t *current_password, uint32_t current_password_length, 55 const uint8_t *desired_password, uint32_t desired_password_length, 56 uint8_t **enrolled_password_handle, uint32_t *enrolled_password_handle_length) { 57 IPCThreadState* ipc = IPCThreadState::self(); 58 const int calling_pid = ipc->getCallingPid(); 59 const int calling_uid = ipc->getCallingUid(); 60 if (!PermissionCache::checkPermission(KEYGUARD_PERMISSION, calling_pid, calling_uid)) { 61 return PERMISSION_DENIED; 62 } 63 64 // need a desired password to enroll 65 if (desired_password_length == 0) return -EINVAL; 66 int ret = device->enroll(device, uid, 67 current_password_handle, current_password_handle_length, 68 current_password, current_password_length, 69 desired_password, desired_password_length, 70 enrolled_password_handle, enrolled_password_handle_length); 71 return ret >= 0 ? NO_ERROR : UNKNOWN_ERROR; 72 } 73 74 virtual status_t verify(uint32_t uid, uint64_t challenge, 75 const uint8_t *enrolled_password_handle, uint32_t enrolled_password_handle_length, 76 const uint8_t *provided_password, uint32_t provided_password_length) { 77 IPCThreadState* ipc = IPCThreadState::self(); 78 const int calling_pid = ipc->getCallingPid(); 79 const int calling_uid = ipc->getCallingUid(); 80 if (!PermissionCache::checkPermission(KEYGUARD_PERMISSION, calling_pid, calling_uid)) { 81 return PERMISSION_DENIED; 82 } 83 84 // can't verify if we're missing either param 85 if ((enrolled_password_handle_length | provided_password_length) == 0) 86 return -EINVAL; 87 88 uint8_t *auth_token; 89 uint32_t auth_token_length; 90 int ret = device->verify(device, uid, challenge, 91 enrolled_password_handle, enrolled_password_handle_length, 92 provided_password, provided_password_length, &auth_token, &auth_token_length); 93 94 if (ret >= 0 && auth_token != NULL && auth_token_length > 0) { 95 // TODO: cache service? 96 sp<IServiceManager> sm = defaultServiceManager(); 97 sp<IBinder> binder = sm->getService(String16("android.security.keystore")); 98 sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder); 99 if (service != NULL) { 100 if (service->addAuthToken(auth_token, auth_token_length) != NO_ERROR) { 101 ALOGE("Falure sending auth token to KeyStore"); 102 } 103 } else { 104 ALOGE("Unable to communicate with KeyStore"); 105 } 106 } 107 108 return ret >= 0 ? NO_ERROR : UNKNOWN_ERROR; 109 } 110 111 virtual status_t dump(int fd, const Vector<String16> &) { 112 IPCThreadState* ipc = IPCThreadState::self(); 113 const int pid = ipc->getCallingPid(); 114 const int uid = ipc->getCallingUid(); 115 if (!PermissionCache::checkPermission(DUMP_PERMISSION, pid, uid)) { 116 return PERMISSION_DENIED; 117 } 118 119 if (device == NULL) { 120 const char *result = "Device not available"; 121 write(fd, result, strlen(result) + 1); 122 } else { 123 const char *result = "OK"; 124 write(fd, result, strlen(result) + 1); 125 } 126 127 return NO_ERROR; 128 } 129 130private: 131 gatekeeper_device_t *device; 132 const hw_module_t *module; 133}; 134}// namespace android 135 136int main() { 137 ALOGI("Starting gatekeeperd..."); 138 android::sp<android::IServiceManager> sm = android::defaultServiceManager(); 139 android::sp<android::GateKeeperProxy> proxy = new android::GateKeeperProxy(); 140 android::status_t ret = sm->addService( 141 android::String16("android.service.gatekeeper.IGateKeeperService"), proxy); 142 if (ret != android::OK) { 143 ALOGE("Couldn't register binder service!"); 144 return -1; 145 } 146 147 /* 148 * We're the only thread in existence, so we're just going to process 149 * Binder transaction as a single-threaded program. 150 */ 151 android::IPCThreadState::self()->joinThreadPool(); 152 return 0; 153} 154