1/* 2 * Copyright 2012 The Android Open Source Project 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY 17 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 20 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 * 24 */ 25 26#include <UniquePtr.h> 27 28#include <sys/socket.h> 29#include <stdarg.h> 30#include <string.h> 31#include <unistd.h> 32 33#include <openssl/dsa.h> 34#include <openssl/engine.h> 35#include <openssl/ec.h> 36#include <openssl/evp.h> 37#include <openssl/objects.h> 38#include <openssl/rsa.h> 39 40//#define LOG_NDEBUG 0 41#define LOG_TAG "OpenSSL-keystore" 42#include <cutils/log.h> 43 44#include <binder/IServiceManager.h> 45#include <keystore/keystore.h> 46#include <keystore/IKeystoreService.h> 47 48#include "methods.h" 49 50using namespace android; 51 52#define DYNAMIC_ENGINE 53const char* kKeystoreEngineId = "keystore"; 54static const char* kKeystoreEngineDesc = "Android keystore engine"; 55 56 57/* 58 * ex_data index for keystore's key alias. 59 */ 60int rsa_key_handle; 61int dsa_key_handle; 62 63 64/* 65 * Only initialize the *_key_handle once. 66 */ 67static pthread_once_t key_handle_control = PTHREAD_ONCE_INIT; 68 69/** 70 * Many OpenSSL APIs take ownership of an argument on success but don't free the argument 71 * on failure. This means we need to tell our scoped pointers when we've transferred ownership, 72 * without triggering a warning by not using the result of release(). 73 */ 74#define OWNERSHIP_TRANSFERRED(obj) \ 75 typeof (obj.release()) _dummy __attribute__((unused)) = obj.release() 76 77 78struct ENGINE_Delete { 79 void operator()(ENGINE* p) const { 80 ENGINE_free(p); 81 } 82}; 83typedef UniquePtr<ENGINE, ENGINE_Delete> Unique_ENGINE; 84 85struct EVP_PKEY_Delete { 86 void operator()(EVP_PKEY* p) const { 87 EVP_PKEY_free(p); 88 } 89}; 90typedef UniquePtr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY; 91 92/** 93 * Called to initialize RSA's ex_data for the key_id handle. This should 94 * only be called when protected by a lock. 95 */ 96static void init_key_handle() { 97 rsa_key_handle = RSA_get_ex_new_index(0, NULL, keyhandle_new, keyhandle_dup, keyhandle_free); 98 dsa_key_handle = DSA_get_ex_new_index(0, NULL, keyhandle_new, keyhandle_dup, keyhandle_free); 99} 100 101static EVP_PKEY* keystore_loadkey(ENGINE* e, const char* key_id, UI_METHOD* ui_method, 102 void* callback_data) { 103#if LOG_NDEBUG 104 (void)ui_method; 105 (void)callback_data; 106#else 107 ALOGV("keystore_loadkey(%p, \"%s\", %p, %p)", e, key_id, ui_method, callback_data); 108#endif 109 110 sp<IServiceManager> sm = defaultServiceManager(); 111 sp<IBinder> binder = sm->getService(String16("android.security.keystore")); 112 sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder); 113 114 if (service == NULL) { 115 ALOGE("could not contact keystore"); 116 return 0; 117 } 118 119 uint8_t *pubkey = NULL; 120 size_t pubkeyLen; 121 int32_t ret = service->get_pubkey(String16(key_id), &pubkey, &pubkeyLen); 122 if (ret < 0) { 123 ALOGW("could not contact keystore"); 124 free(pubkey); 125 return NULL; 126 } else if (ret != 0) { 127 ALOGW("keystore reports error: %d", ret); 128 free(pubkey); 129 return NULL; 130 } 131 132 const unsigned char* tmp = reinterpret_cast<const unsigned char*>(pubkey); 133 Unique_EVP_PKEY pkey(d2i_PUBKEY(NULL, &tmp, pubkeyLen)); 134 free(pubkey); 135 if (pkey.get() == NULL) { 136 ALOGW("Cannot convert pubkey"); 137 return NULL; 138 } 139 140 switch (EVP_PKEY_type(pkey->type)) { 141 case EVP_PKEY_DSA: { 142 dsa_pkey_setup(e, pkey.get(), key_id); 143 break; 144 } 145 case EVP_PKEY_RSA: { 146 rsa_pkey_setup(e, pkey.get(), key_id); 147 break; 148 } 149 case EVP_PKEY_EC: { 150 ecdsa_pkey_setup(e, pkey.get(), key_id); 151 break; 152 } 153 default: 154 ALOGE("Unsupported key type %d", EVP_PKEY_type(pkey->type)); 155 return NULL; 156 } 157 158 return pkey.release(); 159} 160 161static const ENGINE_CMD_DEFN keystore_cmd_defns[] = { 162 {0, NULL, NULL, 0} 163}; 164 165static int keystore_engine_setup(ENGINE* e) { 166 ALOGV("keystore_engine_setup"); 167 168 if (!ENGINE_set_id(e, kKeystoreEngineId) 169 || !ENGINE_set_name(e, kKeystoreEngineDesc) 170 || !ENGINE_set_load_privkey_function(e, keystore_loadkey) 171 || !ENGINE_set_load_pubkey_function(e, keystore_loadkey) 172 || !ENGINE_set_flags(e, 0) 173 || !ENGINE_set_cmd_defns(e, keystore_cmd_defns)) { 174 ALOGE("Could not set up keystore engine"); 175 return 0; 176 } 177 178 /* We need a handle in the keys types as well for keygen if it's not already initialized. */ 179 pthread_once(&key_handle_control, init_key_handle); 180 if ((rsa_key_handle < 0) || (dsa_key_handle < 0)) { 181 ALOGE("Could not set up ex_data index"); 182 return 0; 183 } 184 185 if (!dsa_register(e)) { 186 ALOGE("DSA registration failed"); 187 return 0; 188 } else if (!ecdsa_register(e)) { 189 ALOGE("ECDSA registration failed"); 190 return 0; 191 } else if (!rsa_register(e)) { 192 ALOGE("RSA registration failed"); 193 return 0; 194 } 195 196 return 1; 197} 198 199ENGINE* ENGINE_keystore() { 200 ALOGV("ENGINE_keystore"); 201 202 Unique_ENGINE engine(ENGINE_new()); 203 if (engine.get() == NULL) { 204 return NULL; 205 } 206 207 if (!keystore_engine_setup(engine.get())) { 208 return NULL; 209 } 210 211 return engine.release(); 212} 213 214static int keystore_bind_fn(ENGINE *e, const char *id) { 215 ALOGV("keystore_bind_fn"); 216 217 if (!id) { 218 return 0; 219 } 220 221 if (strcmp(id, kKeystoreEngineId)) { 222 return 0; 223 } 224 225 if (!keystore_engine_setup(e)) { 226 return 0; 227 } 228 229 return 1; 230} 231 232extern "C" { 233#undef OPENSSL_EXPORT 234#define OPENSSL_EXPORT extern __attribute__ ((visibility ("default"))) 235 236IMPLEMENT_DYNAMIC_CHECK_FN() 237IMPLEMENT_DYNAMIC_BIND_FN(keystore_bind_fn) 238}; 239