Home | History | Annotate | Download | only in keystore-engine
      1 /*
      2  * Copyright (C) 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 <keystore.h>
     27 
     28 #include <utils/UniquePtr.h>
     29 
     30 #include <sys/socket.h>
     31 #include <stdarg.h>
     32 #include <string.h>
     33 #include <unistd.h>
     34 
     35 #include <openssl/objects.h>
     36 #include <openssl/engine.h>
     37 #include <openssl/evp.h>
     38 
     39 //#define LOG_NDEBUG 0
     40 #define LOG_TAG "OpenSSL-keystore"
     41 #include <cutils/log.h>
     42 
     43 #include <keystore_client.h>
     44 
     45 
     46 #define DYNAMIC_ENGINE
     47 #define KEYSTORE_ENGINE_ID   "keystore"
     48 #define KEYSTORE_ENGINE_NAME "Android keystore engine"
     49 
     50 /**
     51  * Many OpenSSL APIs take ownership of an argument on success but don't free the argument
     52  * on failure. This means we need to tell our scoped pointers when we've transferred ownership,
     53  * without triggering a warning by not using the result of release().
     54  */
     55 #define OWNERSHIP_TRANSFERRED(obj) \
     56     typeof (obj.release()) _dummy __attribute__((unused)) = obj.release()
     57 
     58 struct ENGINE_Delete {
     59     void operator()(ENGINE* p) const {
     60         ENGINE_free(p);
     61     }
     62 };
     63 typedef UniquePtr<ENGINE, ENGINE_Delete> Unique_ENGINE;
     64 
     65 struct EVP_PKEY_Delete {
     66     void operator()(EVP_PKEY* p) const {
     67         EVP_PKEY_free(p);
     68     }
     69 };
     70 typedef UniquePtr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY;
     71 
     72 struct RSA_Delete {
     73     void operator()(RSA* p) const {
     74         RSA_free(p);
     75     }
     76 };
     77 typedef UniquePtr<RSA, RSA_Delete> Unique_RSA;
     78 
     79 
     80 /*
     81  * RSA ex_data index for keystore's key handle.
     82  */
     83 static int rsa_key_handle;
     84 
     85 /*
     86  * Only initialize the rsa_key_handle once.
     87  */
     88 static pthread_once_t rsa_key_handle_control = PTHREAD_ONCE_INIT;
     89 
     90 
     91 /**
     92  * Makes sure the ex_data for the keyhandle is initially set to NULL.
     93  */
     94 int keyhandle_new(void*, void*, CRYPTO_EX_DATA* ad, int idx, long, void*) {
     95     return CRYPTO_set_ex_data(ad, idx, NULL);
     96 }
     97 
     98 /**
     99  * Frees a previously allocated keyhandle stored in ex_data.
    100  */
    101 void keyhandle_free(void *, void *ptr, CRYPTO_EX_DATA*, int, long, void*) {
    102     char* keyhandle = reinterpret_cast<char*>(ptr);
    103     if (keyhandle != NULL) {
    104         free(keyhandle);
    105     }
    106 }
    107 
    108 /**
    109  * Duplicates a keyhandle stored in ex_data in case we copy a key.
    110  */
    111 int keyhandle_dup(CRYPTO_EX_DATA* to, CRYPTO_EX_DATA*, void *ptrRef, int idx, long, void *) {
    112     // This appears to be a bug in OpenSSL.
    113     void** ptr = reinterpret_cast<void**>(ptrRef);
    114     char* keyhandle = reinterpret_cast<char*>(*ptr);
    115     if (keyhandle != NULL) {
    116         char* keyhandle_copy = strdup(keyhandle);
    117         *ptr = keyhandle_copy;
    118 
    119         // Call this in case OpenSSL is fixed in the future.
    120         (void) CRYPTO_set_ex_data(to, idx, keyhandle_copy);
    121     }
    122     return 1;
    123 }
    124 
    125 int keystore_rsa_priv_enc(int flen, const unsigned char* from, unsigned char* to, RSA* rsa,
    126         int padding) {
    127     ALOGV("keystore_rsa_sign(%d, %p, %p, %p, %d)", flen, from, to, rsa, padding);
    128 
    129     int num = RSA_size(rsa);
    130     UniquePtr<uint8_t> padded(new uint8_t[num]);
    131     if (padded.get() == NULL) {
    132         ALOGE("could not allocate padded signature");
    133         return 0;
    134     }
    135 
    136     switch (padding) {
    137     case RSA_PKCS1_PADDING:
    138         if (!RSA_padding_add_PKCS1_type_1(padded.get(), num, from, flen)) {
    139             return 0;
    140         }
    141         break;
    142     case RSA_X931_PADDING:
    143         if (!RSA_padding_add_X931(padded.get(), num, from, flen)) {
    144             return 0;
    145         }
    146         break;
    147     case RSA_NO_PADDING:
    148         if (!RSA_padding_add_none(padded.get(), num, from, flen)) {
    149             return 0;
    150         }
    151         break;
    152     default:
    153         ALOGE("Unknown padding type: %d", padding);
    154         return 0;
    155     }
    156 
    157     uint8_t* key_id = reinterpret_cast<uint8_t*>(RSA_get_ex_data(rsa, rsa_key_handle));
    158     if (key_id == NULL) {
    159         ALOGE("key had no key_id!");
    160         return 0;
    161     }
    162 
    163     Keystore_Reply reply;
    164     if (keystore_cmd(CommandCodes[SIGN], &reply, 2, strlen(reinterpret_cast<const char*>(key_id)),
    165             key_id, static_cast<size_t>(num), reinterpret_cast<const uint8_t*>(padded.get()))
    166             != NO_ERROR) {
    167         ALOGE("There was an error during rsa_mod_exp");
    168         return 0;
    169     }
    170 
    171     const size_t replyLen = reply.length();
    172     if (replyLen <= 0) {
    173         ALOGW("No valid signature returned");
    174         return 0;
    175     }
    176 
    177     memcpy(to, reply.get(), replyLen);
    178 
    179     ALOGV("rsa=%p keystore_rsa_sign => returning %p len %llu", rsa, to,
    180             (unsigned long long) replyLen);
    181     return static_cast<int>(replyLen);
    182 }
    183 
    184 static RSA_METHOD keystore_rsa_meth = {
    185         KEYSTORE_ENGINE_NAME,
    186         NULL, /* rsa_pub_enc */
    187         NULL, /* rsa_pub_dec (verification) */
    188         keystore_rsa_priv_enc, /* rsa_priv_enc (signing) */
    189         NULL, /* rsa_priv_dec */
    190         NULL, /* rsa_mod_exp */
    191         NULL, /* bn_mod_exp */
    192         NULL, /* init */
    193         NULL, /* finish */
    194         RSA_FLAG_EXT_PKEY | RSA_FLAG_NO_BLINDING, /* flags */
    195         NULL, /* app_data */
    196         NULL, /* rsa_sign */
    197         NULL, /* rsa_verify */
    198         NULL, /* rsa_keygen */
    199 };
    200 
    201 static int register_rsa_methods() {
    202     const RSA_METHOD* rsa_meth = RSA_PKCS1_SSLeay();
    203 
    204     keystore_rsa_meth.rsa_pub_enc = rsa_meth->rsa_pub_enc;
    205     keystore_rsa_meth.rsa_pub_dec = rsa_meth->rsa_pub_dec;
    206     keystore_rsa_meth.rsa_priv_dec = rsa_meth->rsa_priv_dec;
    207     keystore_rsa_meth.rsa_mod_exp = rsa_meth->rsa_mod_exp;
    208     keystore_rsa_meth.bn_mod_exp = rsa_meth->bn_mod_exp;
    209 
    210     return 1;
    211 }
    212 
    213 static EVP_PKEY* keystore_loadkey(ENGINE* e, const char* key_id, UI_METHOD* ui_method,
    214         void* callback_data) {
    215 #if LOG_NDEBUG
    216     (void)ui_method;
    217     (void)callback_data;
    218 #else
    219     ALOGV("keystore_loadkey(%p, \"%s\", %p, %p)", e, key_id, ui_method, callback_data);
    220 #endif
    221 
    222     Keystore_Reply reply;
    223     if (keystore_cmd(CommandCodes[GET_PUBKEY], &reply, 1, strlen(key_id), key_id) != NO_ERROR) {
    224         ALOGV("Cannot get public key for %s", key_id);
    225         return NULL;
    226     }
    227 
    228     const unsigned char* tmp = reinterpret_cast<const unsigned char*>(reply.get());
    229     Unique_EVP_PKEY pkey(d2i_PUBKEY(NULL, &tmp, reply.length()));
    230     if (pkey.get() == NULL) {
    231         ALOGW("Cannot convert pubkey");
    232         return NULL;
    233     }
    234 
    235     switch (EVP_PKEY_type(pkey->type)) {
    236     case EVP_PKEY_RSA: {
    237         Unique_RSA rsa(EVP_PKEY_get1_RSA(pkey.get()));
    238         if (!RSA_set_ex_data(rsa.get(), rsa_key_handle, reinterpret_cast<void*>(strdup(key_id)))) {
    239             ALOGW("Could not set ex_data for loaded RSA key");
    240             return NULL;
    241         }
    242 
    243         RSA_set_method(rsa.get(), &keystore_rsa_meth);
    244         RSA_blinding_off(rsa.get());
    245 
    246         /*
    247          * This should probably be an OpenSSL API, but EVP_PKEY_free calls
    248          * ENGINE_finish(), so we need to call ENGINE_init() here.
    249          */
    250         ENGINE_init(e);
    251         rsa->engine = e;
    252         rsa->flags |= RSA_FLAG_EXT_PKEY;
    253 
    254         break;
    255     }
    256     default:
    257         ALOGE("Unsupported key type %d", EVP_PKEY_type(pkey->type));
    258         return NULL;
    259     }
    260 
    261     return pkey.release();
    262 }
    263 
    264 static const ENGINE_CMD_DEFN keystore_cmd_defns[] = {
    265     {0, NULL, NULL, 0}
    266 };
    267 
    268 /**
    269  * Called to initialize RSA's ex_data for the key_id handle. This should
    270  * only be called when protected by a lock.
    271  */
    272 static void init_rsa_key_handle() {
    273     rsa_key_handle = RSA_get_ex_new_index(0, NULL, keyhandle_new, keyhandle_dup,
    274             keyhandle_free);
    275 }
    276 
    277 static int keystore_engine_setup(ENGINE* e) {
    278     ALOGV("keystore_engine_setup");
    279 
    280     if (!ENGINE_set_id(e, KEYSTORE_ENGINE_ID)
    281             || !ENGINE_set_name(e, KEYSTORE_ENGINE_NAME)
    282             || !ENGINE_set_load_privkey_function(e, keystore_loadkey)
    283             || !ENGINE_set_load_pubkey_function(e, keystore_loadkey)
    284             || !ENGINE_set_flags(e, 0)
    285             || !ENGINE_set_cmd_defns(e, keystore_cmd_defns)) {
    286         ALOGE("Could not set up keystore engine");
    287         return 0;
    288     }
    289 
    290     if (!ENGINE_set_RSA(e, &keystore_rsa_meth)
    291             || !register_rsa_methods()) {
    292         ALOGE("Could not set up keystore RSA methods");
    293         return 0;
    294     }
    295 
    296     /* We need a handle in the RSA keys as well for keygen if it's not already initialized. */
    297     pthread_once(&rsa_key_handle_control, init_rsa_key_handle);
    298     if (rsa_key_handle < 0) {
    299         ALOGE("Could not set up RSA ex_data index");
    300         return 0;
    301     }
    302 
    303     return 1;
    304 }
    305 
    306 ENGINE* ENGINE_keystore() {
    307     ALOGV("ENGINE_keystore");
    308 
    309     Unique_ENGINE engine(ENGINE_new());
    310     if (engine.get() == NULL) {
    311         return NULL;
    312     }
    313 
    314     if (!keystore_engine_setup(engine.get())) {
    315         return NULL;
    316     }
    317 
    318     return engine.release();
    319 }
    320 
    321 static int keystore_bind_fn(ENGINE *e, const char *id) {
    322     ALOGV("keystore_bind_fn");
    323 
    324     if (!id) {
    325         return 0;
    326     }
    327 
    328     if (strcmp(id, KEYSTORE_ENGINE_ID)) {
    329         return 0;
    330     }
    331 
    332     if (!keystore_engine_setup(e)) {
    333         return 0;
    334     }
    335 
    336     return 1;
    337 }
    338 
    339 extern "C" {
    340 #undef OPENSSL_EXPORT
    341 #define OPENSSL_EXPORT extern __attribute__ ((visibility ("default")))
    342 
    343 IMPLEMENT_DYNAMIC_CHECK_FN()
    344 IMPLEMENT_DYNAMIC_BIND_FN(keystore_bind_fn)
    345 };
    346