blob: 30cad7cbf0a276e6d7a7efec3df7d3fa70fd922c [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
33#include <openssl/objects.h>
34#include <openssl/engine.h>
35#include <openssl/evp.h>
36
Brian Carlstroma8c703d2012-07-17 14:43:46 -070037//#define LOG_NDEBUG 0
Kenny Root70e3a862012-02-15 17:20:23 -080038#define LOG_TAG "OpenSSL-keystore"
39#include <cutils/log.h>
40
Kenny Root07438c82012-11-02 15:41:02 -070041#include <binder/IServiceManager.h>
42#include <keystore/keystore.h>
43#include <keystore/IKeystoreService.h>
Kenny Root70e3a862012-02-15 17:20:23 -080044
Kenny Root9d422a52013-06-27 09:14:46 -070045#include "methods.h"
46
Kenny Root07438c82012-11-02 15:41:02 -070047using namespace android;
Kenny Root70e3a862012-02-15 17:20:23 -080048
49#define DYNAMIC_ENGINE
Kenny Root9d422a52013-06-27 09:14:46 -070050const char* kKeystoreEngineId = "keystore";
51static const char* kKeystoreEngineDesc = "Android keystore engine";
Kenny Root70e3a862012-02-15 17:20:23 -080052
53/**
54 * Many OpenSSL APIs take ownership of an argument on success but don't free the argument
55 * on failure. This means we need to tell our scoped pointers when we've transferred ownership,
56 * without triggering a warning by not using the result of release().
57 */
58#define OWNERSHIP_TRANSFERRED(obj) \
59 typeof (obj.release()) _dummy __attribute__((unused)) = obj.release()
60
61struct ENGINE_Delete {
62 void operator()(ENGINE* p) const {
63 ENGINE_free(p);
64 }
65};
66typedef UniquePtr<ENGINE, ENGINE_Delete> Unique_ENGINE;
67
68struct EVP_PKEY_Delete {
69 void operator()(EVP_PKEY* p) const {
70 EVP_PKEY_free(p);
71 }
72};
73typedef UniquePtr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY;
74
Kenny Root70e3a862012-02-15 17:20:23 -080075
Brian Carlstroma8c703d2012-07-17 14:43:46 -070076static EVP_PKEY* keystore_loadkey(ENGINE* e, const char* key_id, UI_METHOD* ui_method,
77 void* callback_data) {
78#if LOG_NDEBUG
79 (void)ui_method;
80 (void)callback_data;
81#else
Kenny Root70e3a862012-02-15 17:20:23 -080082 ALOGV("keystore_loadkey(%p, \"%s\", %p, %p)", e, key_id, ui_method, callback_data);
Brian Carlstroma8c703d2012-07-17 14:43:46 -070083#endif
Kenny Root70e3a862012-02-15 17:20:23 -080084
Kenny Root07438c82012-11-02 15:41:02 -070085 sp<IServiceManager> sm = defaultServiceManager();
86 sp<IBinder> binder = sm->getService(String16("android.security.keystore"));
87 sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder);
88
89 if (service == NULL) {
90 ALOGE("could not contact keystore");
91 return 0;
92 }
93
94 uint8_t *pubkey = NULL;
95 size_t pubkeyLen;
96 int32_t ret = service->get_pubkey(String16(key_id), &pubkey, &pubkeyLen);
97 if (ret < 0) {
98 ALOGW("could not contact keystore");
99 free(pubkey);
100 return NULL;
101 } else if (ret != 0) {
102 ALOGW("keystore reports error: %d", ret);
103 free(pubkey);
Kenny Root70e3a862012-02-15 17:20:23 -0800104 return NULL;
105 }
106
Kenny Root07438c82012-11-02 15:41:02 -0700107 const unsigned char* tmp = reinterpret_cast<const unsigned char*>(pubkey);
108 Unique_EVP_PKEY pkey(d2i_PUBKEY(NULL, &tmp, pubkeyLen));
109 free(pubkey);
Kenny Root70e3a862012-02-15 17:20:23 -0800110 if (pkey.get() == NULL) {
111 ALOGW("Cannot convert pubkey");
112 return NULL;
113 }
114
115 switch (EVP_PKEY_type(pkey->type)) {
116 case EVP_PKEY_RSA: {
Kenny Root9d422a52013-06-27 09:14:46 -0700117 rsa_pkey_setup(e, pkey.get(), key_id);
Kenny Root70e3a862012-02-15 17:20:23 -0800118 break;
119 }
120 default:
121 ALOGE("Unsupported key type %d", EVP_PKEY_type(pkey->type));
122 return NULL;
123 }
124
125 return pkey.release();
126}
127
128static const ENGINE_CMD_DEFN keystore_cmd_defns[] = {
129 {0, NULL, NULL, 0}
130};
131
132static int keystore_engine_setup(ENGINE* e) {
133 ALOGV("keystore_engine_setup");
134
Kenny Root9d422a52013-06-27 09:14:46 -0700135 if (!ENGINE_set_id(e, kKeystoreEngineId)
136 || !ENGINE_set_name(e, kKeystoreEngineDesc)
Kenny Root70e3a862012-02-15 17:20:23 -0800137 || !ENGINE_set_load_privkey_function(e, keystore_loadkey)
138 || !ENGINE_set_load_pubkey_function(e, keystore_loadkey)
Kenny Root938a9912012-08-15 22:19:25 -0700139 || !ENGINE_set_flags(e, 0)
Kenny Root70e3a862012-02-15 17:20:23 -0800140 || !ENGINE_set_cmd_defns(e, keystore_cmd_defns)) {
141 ALOGE("Could not set up keystore engine");
142 return 0;
143 }
144
Kenny Root9d422a52013-06-27 09:14:46 -0700145 if (!rsa_register(e)) {
146 ALOGE("RSA registration failed");
Kenny Root70e3a862012-02-15 17:20:23 -0800147 return 0;
148 }
149
150 return 1;
151}
152
153ENGINE* ENGINE_keystore() {
154 ALOGV("ENGINE_keystore");
155
156 Unique_ENGINE engine(ENGINE_new());
157 if (engine.get() == NULL) {
158 return NULL;
159 }
160
161 if (!keystore_engine_setup(engine.get())) {
162 return NULL;
163 }
164
165 return engine.release();
166}
167
168static int keystore_bind_fn(ENGINE *e, const char *id) {
169 ALOGV("keystore_bind_fn");
170
171 if (!id) {
172 return 0;
173 }
174
Kenny Root9d422a52013-06-27 09:14:46 -0700175 if (strcmp(id, kKeystoreEngineId)) {
Kenny Root70e3a862012-02-15 17:20:23 -0800176 return 0;
177 }
178
179 if (!keystore_engine_setup(e)) {
180 return 0;
181 }
182
183 return 1;
184}
185
186extern "C" {
187#undef OPENSSL_EXPORT
188#define OPENSSL_EXPORT extern __attribute__ ((visibility ("default")))
189
190IMPLEMENT_DYNAMIC_CHECK_FN()
191IMPLEMENT_DYNAMIC_BIND_FN(keystore_bind_fn)
192};