blob: 9397e53b3a82792f49129891f688c78109258013 [file] [log] [blame]
Kenny Root70e3a862012-02-15 17:20:23 -08001/*
Kenny Root9d422a52013-06-27 09:14:46 -07002 * Copyright 2012 The Android Open Source Project
Kenny Root70e3a862012-02-15 17:20:23 -08003 *
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
Colin Cross98c2f8f2012-03-28 09:44:09 -070026#include <utils/UniquePtr.h>
Kenny Root70e3a862012-02-15 17:20:23 -080027
28#include <sys/socket.h>
29#include <stdarg.h>
30#include <string.h>
Kenny Rootbef80832012-05-03 11:19:28 -070031#include <unistd.h>
Kenny Root70e3a862012-02-15 17:20:23 -080032
Kenny Root60711792013-08-16 14:02:41 -070033#include <openssl/dsa.h>
Kenny Root70e3a862012-02-15 17:20:23 -080034#include <openssl/engine.h>
Kenny Root60711792013-08-16 14:02:41 -070035#include <openssl/ec.h>
Kenny Root70e3a862012-02-15 17:20:23 -080036#include <openssl/evp.h>
Kenny Root60711792013-08-16 14:02:41 -070037#include <openssl/objects.h>
38#include <openssl/rsa.h>
Kenny Root70e3a862012-02-15 17:20:23 -080039
Brian Carlstroma8c703d2012-07-17 14:43:46 -070040//#define LOG_NDEBUG 0
Kenny Root70e3a862012-02-15 17:20:23 -080041#define LOG_TAG "OpenSSL-keystore"
42#include <cutils/log.h>
43
Kenny Root07438c82012-11-02 15:41:02 -070044#include <binder/IServiceManager.h>
45#include <keystore/keystore.h>
46#include <keystore/IKeystoreService.h>
Kenny Root70e3a862012-02-15 17:20:23 -080047
Kenny Root9d422a52013-06-27 09:14:46 -070048#include "methods.h"
49
Kenny Root07438c82012-11-02 15:41:02 -070050using namespace android;
Kenny Root70e3a862012-02-15 17:20:23 -080051
52#define DYNAMIC_ENGINE
Kenny Root9d422a52013-06-27 09:14:46 -070053const char* kKeystoreEngineId = "keystore";
54static const char* kKeystoreEngineDesc = "Android keystore engine";
Kenny Root70e3a862012-02-15 17:20:23 -080055
Kenny Root60711792013-08-16 14:02:41 -070056
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 * Used for generic EVP_PKEY* handling (only for EC stuff currently)
71 */
72static EVP_PKEY_METHOD* keystore_pkey_ec_methods;
73
Kenny Root70e3a862012-02-15 17:20:23 -080074/**
75 * Many OpenSSL APIs take ownership of an argument on success but don't free the argument
76 * on failure. This means we need to tell our scoped pointers when we've transferred ownership,
77 * without triggering a warning by not using the result of release().
78 */
79#define OWNERSHIP_TRANSFERRED(obj) \
80 typeof (obj.release()) _dummy __attribute__((unused)) = obj.release()
81
Kenny Root60711792013-08-16 14:02:41 -070082
Kenny Root70e3a862012-02-15 17:20:23 -080083struct ENGINE_Delete {
84 void operator()(ENGINE* p) const {
85 ENGINE_free(p);
86 }
87};
88typedef UniquePtr<ENGINE, ENGINE_Delete> Unique_ENGINE;
89
90struct EVP_PKEY_Delete {
91 void operator()(EVP_PKEY* p) const {
92 EVP_PKEY_free(p);
93 }
94};
95typedef UniquePtr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY;
96
Kenny Root60711792013-08-16 14:02:41 -070097/**
98 * Called to initialize RSA's ex_data for the key_id handle. This should
99 * only be called when protected by a lock.
100 */
101static void init_key_handle() {
102 rsa_key_handle = RSA_get_ex_new_index(0, NULL, keyhandle_new, keyhandle_dup, keyhandle_free);
103 dsa_key_handle = DSA_get_ex_new_index(0, NULL, keyhandle_new, keyhandle_dup, keyhandle_free);
104}
105
106static int pkey_setup(ENGINE *e, EVP_PKEY *pkey, const char *key_id) {
107 int ret = 1;
108 switch (EVP_PKEY_type(pkey->type)) {
109 case EVP_PKEY_EC: {
110 Unique_EC_KEY eckey(EVP_PKEY_get1_EC_KEY(pkey));
111 void* oldData = EC_KEY_insert_key_method_data(eckey.get(),
112 reinterpret_cast<void*>(strdup(key_id)), ex_data_dup, ex_data_free,
113 ex_data_clear_free);
114 if (oldData != NULL) {
115 free(oldData);
116 }
117 } break;
118 default:
119 ALOGW("Unsupported key type during setup %d", EVP_PKEY_type(pkey->type));
120 return 0;
121 }
122
123 if (ret != 1) {
124 return ret;
125 }
126
127 ENGINE_init(e);
128 pkey->engine = e;
129
130 return 1;
131}
Kenny Root70e3a862012-02-15 17:20:23 -0800132
Brian Carlstroma8c703d2012-07-17 14:43:46 -0700133static EVP_PKEY* keystore_loadkey(ENGINE* e, const char* key_id, UI_METHOD* ui_method,
134 void* callback_data) {
135#if LOG_NDEBUG
136 (void)ui_method;
137 (void)callback_data;
138#else
Kenny Root70e3a862012-02-15 17:20:23 -0800139 ALOGV("keystore_loadkey(%p, \"%s\", %p, %p)", e, key_id, ui_method, callback_data);
Brian Carlstroma8c703d2012-07-17 14:43:46 -0700140#endif
Kenny Root70e3a862012-02-15 17:20:23 -0800141
Kenny Root07438c82012-11-02 15:41:02 -0700142 sp<IServiceManager> sm = defaultServiceManager();
143 sp<IBinder> binder = sm->getService(String16("android.security.keystore"));
144 sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder);
145
146 if (service == NULL) {
147 ALOGE("could not contact keystore");
148 return 0;
149 }
150
151 uint8_t *pubkey = NULL;
152 size_t pubkeyLen;
153 int32_t ret = service->get_pubkey(String16(key_id), &pubkey, &pubkeyLen);
154 if (ret < 0) {
155 ALOGW("could not contact keystore");
156 free(pubkey);
157 return NULL;
158 } else if (ret != 0) {
159 ALOGW("keystore reports error: %d", ret);
160 free(pubkey);
Kenny Root70e3a862012-02-15 17:20:23 -0800161 return NULL;
162 }
163
Kenny Root07438c82012-11-02 15:41:02 -0700164 const unsigned char* tmp = reinterpret_cast<const unsigned char*>(pubkey);
165 Unique_EVP_PKEY pkey(d2i_PUBKEY(NULL, &tmp, pubkeyLen));
166 free(pubkey);
Kenny Root70e3a862012-02-15 17:20:23 -0800167 if (pkey.get() == NULL) {
168 ALOGW("Cannot convert pubkey");
169 return NULL;
170 }
171
172 switch (EVP_PKEY_type(pkey->type)) {
Kenny Root60711792013-08-16 14:02:41 -0700173 case EVP_PKEY_DSA: {
174 dsa_pkey_setup(e, pkey.get(), key_id);
175 break;
176 }
Kenny Root70e3a862012-02-15 17:20:23 -0800177 case EVP_PKEY_RSA: {
Kenny Root9d422a52013-06-27 09:14:46 -0700178 rsa_pkey_setup(e, pkey.get(), key_id);
Kenny Root70e3a862012-02-15 17:20:23 -0800179 break;
180 }
Kenny Root60711792013-08-16 14:02:41 -0700181 case EVP_PKEY_EC: {
182 pkey_setup(e, pkey.get(), key_id);
183 break;
184 }
Kenny Root70e3a862012-02-15 17:20:23 -0800185 default:
186 ALOGE("Unsupported key type %d", EVP_PKEY_type(pkey->type));
187 return NULL;
188 }
189
190 return pkey.release();
191}
192
193static const ENGINE_CMD_DEFN keystore_cmd_defns[] = {
194 {0, NULL, NULL, 0}
195};
196
Kenny Root60711792013-08-16 14:02:41 -0700197static uint8_t* get_key_id(EVP_PKEY* pkey) {
198 switch (EVP_PKEY_type(pkey->type)) {
199 case EVP_PKEY_EC: {
200 Unique_EC_KEY eckey(EVP_PKEY_get1_EC_KEY(pkey));
201 return reinterpret_cast<uint8_t*>(EC_KEY_get_key_method_data(eckey.get(),
202 ex_data_dup, ex_data_free, ex_data_clear_free));
203 } break;
204 }
205
206 return NULL;
207}
208
209static int keystore_pkey_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
210 const unsigned char *tbs, size_t tbs_len) {
211 EVP_PKEY* pkey = EVP_PKEY_CTX_get0_pkey(ctx);
212
213 const uint8_t* key_id = get_key_id(pkey);
214 if (key_id == NULL) {
215 ALOGW("key_id is empty");
216 return 0;
217 }
218
219 sp<IServiceManager> sm = defaultServiceManager();
220 sp<IBinder> binder = sm->getService(String16("android.security.keystore"));
221 sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder);
222
223 if (service == NULL) {
224 ALOGE("could not contact keystore");
225 return 0;
226 }
227
228 uint8_t* reply = NULL;
229 size_t replyLen;
230 int32_t ret = service->sign(String16(reinterpret_cast<const char*>(key_id)), tbs, tbs_len,
231 &reply, &replyLen);
232 if (ret < 0) {
233 ALOGW("There was an error during signing: could not connect");
234 free(reply);
235 return 0;
236 } else if (ret != 0) {
237 ALOGW("Error during signing from keystore: %d", ret);
238 free(reply);
239 return 0;
240 } else if (replyLen <= 0) {
241 ALOGW("No valid signature returned");
242 return 0;
243 }
244
245 memcpy(sig, reply, replyLen);
246 free(reply);
247 *siglen = replyLen;
248
249 return 1;
250}
251
252static int register_pkey_methods(EVP_PKEY_METHOD** meth, int nid) {
253 *meth = EVP_PKEY_meth_new(nid, 0);
254 if (*meth == NULL) {
255 ALOGE("Failure allocating PKEY methods for NID %d", nid);
256 return 0;
257 }
258
259 const EVP_PKEY_METHOD* orig = EVP_PKEY_meth_find(nid);
260 EVP_PKEY_meth_copy(*meth, orig);
261
262 EVP_PKEY_meth_set_sign(*meth, NULL, keystore_pkey_sign);
263
264 return 1;
265}
266
267static int keystore_nids[] = {
268 EVP_PKEY_EC,
269};
270
271static int keystore_pkey_meths(ENGINE*, EVP_PKEY_METHOD** meth, const int **nids, int nid) {
272 if (meth == NULL) {
273 *nids = keystore_nids;
274 return sizeof(keystore_nids) / sizeof(keystore_nids[0]);
275 }
276
277 switch (nid) {
278 case EVP_PKEY_EC:
279 *meth = keystore_pkey_ec_methods;
280 return 1;
281 }
282
283 *meth = NULL;
284 return 0;
285}
286
Kenny Root70e3a862012-02-15 17:20:23 -0800287static int keystore_engine_setup(ENGINE* e) {
288 ALOGV("keystore_engine_setup");
289
Kenny Root60711792013-08-16 14:02:41 -0700290 if (!register_pkey_methods(&keystore_pkey_ec_methods, EVP_PKEY_EC)) {
291 ALOGE("Could not set up keystore engine");
292 return 0;
293 }
294
Kenny Root9d422a52013-06-27 09:14:46 -0700295 if (!ENGINE_set_id(e, kKeystoreEngineId)
296 || !ENGINE_set_name(e, kKeystoreEngineDesc)
Kenny Root60711792013-08-16 14:02:41 -0700297 || !ENGINE_set_pkey_meths(e, keystore_pkey_meths)
Kenny Root70e3a862012-02-15 17:20:23 -0800298 || !ENGINE_set_load_privkey_function(e, keystore_loadkey)
299 || !ENGINE_set_load_pubkey_function(e, keystore_loadkey)
Kenny Root938a9912012-08-15 22:19:25 -0700300 || !ENGINE_set_flags(e, 0)
Kenny Root70e3a862012-02-15 17:20:23 -0800301 || !ENGINE_set_cmd_defns(e, keystore_cmd_defns)) {
302 ALOGE("Could not set up keystore engine");
303 return 0;
304 }
305
Kenny Root60711792013-08-16 14:02:41 -0700306 /* We need a handle in the keys types as well for keygen if it's not already initialized. */
307 pthread_once(&key_handle_control, init_key_handle);
308 if ((rsa_key_handle < 0) || (dsa_key_handle < 0)) {
309 ALOGE("Could not set up ex_data index");
310 return 0;
311 }
312
313 if (!dsa_register(e)) {
314 ALOGE("DSA registration failed");
315 return 0;
316 } else if (!rsa_register(e)) {
Kenny Root9d422a52013-06-27 09:14:46 -0700317 ALOGE("RSA registration failed");
Kenny Root70e3a862012-02-15 17:20:23 -0800318 return 0;
319 }
320
321 return 1;
322}
323
324ENGINE* ENGINE_keystore() {
325 ALOGV("ENGINE_keystore");
326
327 Unique_ENGINE engine(ENGINE_new());
328 if (engine.get() == NULL) {
329 return NULL;
330 }
331
332 if (!keystore_engine_setup(engine.get())) {
333 return NULL;
334 }
335
336 return engine.release();
337}
338
339static int keystore_bind_fn(ENGINE *e, const char *id) {
340 ALOGV("keystore_bind_fn");
341
342 if (!id) {
343 return 0;
344 }
345
Kenny Root9d422a52013-06-27 09:14:46 -0700346 if (strcmp(id, kKeystoreEngineId)) {
Kenny Root70e3a862012-02-15 17:20:23 -0800347 return 0;
348 }
349
350 if (!keystore_engine_setup(e)) {
351 return 0;
352 }
353
354 return 1;
355}
356
357extern "C" {
358#undef OPENSSL_EXPORT
359#define OPENSSL_EXPORT extern __attribute__ ((visibility ("default")))
360
361IMPLEMENT_DYNAMIC_CHECK_FN()
362IMPLEMENT_DYNAMIC_BIND_FN(keystore_bind_fn)
363};