16914efca8fe737a753d234d7e91222da6a8cdabeKenny Root/*
26914efca8fe737a753d234d7e91222da6a8cdabeKenny Root * Copyright (C) 2013 The Android Open Source Project
36914efca8fe737a753d234d7e91222da6a8cdabeKenny Root *
46914efca8fe737a753d234d7e91222da6a8cdabeKenny Root * Licensed under the Apache License, Version 2.0 (the "License");
56914efca8fe737a753d234d7e91222da6a8cdabeKenny Root * you may not use this file except in compliance with the License.
66914efca8fe737a753d234d7e91222da6a8cdabeKenny Root * You may obtain a copy of the License at
76914efca8fe737a753d234d7e91222da6a8cdabeKenny Root *
86914efca8fe737a753d234d7e91222da6a8cdabeKenny Root *      http://www.apache.org/licenses/LICENSE-2.0
96914efca8fe737a753d234d7e91222da6a8cdabeKenny Root *
106914efca8fe737a753d234d7e91222da6a8cdabeKenny Root * Unless required by applicable law or agreed to in writing, software
116914efca8fe737a753d234d7e91222da6a8cdabeKenny Root * distributed under the License is distributed on an "AS IS" BASIS,
126914efca8fe737a753d234d7e91222da6a8cdabeKenny Root * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136914efca8fe737a753d234d7e91222da6a8cdabeKenny Root * See the License for the specific language governing permissions and
146914efca8fe737a753d234d7e91222da6a8cdabeKenny Root * limitations under the License.
156914efca8fe737a753d234d7e91222da6a8cdabeKenny Root */
166914efca8fe737a753d234d7e91222da6a8cdabeKenny Root
176914efca8fe737a753d234d7e91222da6a8cdabeKenny Root#include "UniquePtr.h"
186914efca8fe737a753d234d7e91222da6a8cdabeKenny Root
196914efca8fe737a753d234d7e91222da6a8cdabeKenny Root#include <stdarg.h>
206914efca8fe737a753d234d7e91222da6a8cdabeKenny Root#include <string.h>
216914efca8fe737a753d234d7e91222da6a8cdabeKenny Root#include <unistd.h>
226914efca8fe737a753d234d7e91222da6a8cdabeKenny Root
236914efca8fe737a753d234d7e91222da6a8cdabeKenny Root#include <openssl/objects.h>
246914efca8fe737a753d234d7e91222da6a8cdabeKenny Root#include <openssl/engine.h>
256914efca8fe737a753d234d7e91222da6a8cdabeKenny Root#include <openssl/evp.h>
266914efca8fe737a753d234d7e91222da6a8cdabeKenny Root#include <openssl/pem.h>
276914efca8fe737a753d234d7e91222da6a8cdabeKenny Root
286914efca8fe737a753d234d7e91222da6a8cdabeKenny Root#define DYNAMIC_ENGINE
29fefaf999c4878681be0551331ff3028b381a9203Kenny Root#define TEST_ENGINE_ID   "javacoretests"
306914efca8fe737a753d234d7e91222da6a8cdabeKenny Root#define TEST_ENGINE_NAME "libcore test engine"
316914efca8fe737a753d234d7e91222da6a8cdabeKenny Root
326914efca8fe737a753d234d7e91222da6a8cdabeKenny Rootstruct RSA_Delete {
336914efca8fe737a753d234d7e91222da6a8cdabeKenny Root    void operator()(RSA* p) const {
346914efca8fe737a753d234d7e91222da6a8cdabeKenny Root        RSA_free(p);
356914efca8fe737a753d234d7e91222da6a8cdabeKenny Root    }
366914efca8fe737a753d234d7e91222da6a8cdabeKenny Root};
376914efca8fe737a753d234d7e91222da6a8cdabeKenny Roottypedef UniquePtr<RSA, RSA_Delete> Unique_RSA;
386914efca8fe737a753d234d7e91222da6a8cdabeKenny Root
39a45d02e5fbf1ec387dcb1e6c91e867d32ab36193Kenny Rootstatic const char* HMAC_TAG = "-HMAC-";
40a45d02e5fbf1ec387dcb1e6c91e867d32ab36193Kenny Rootstatic const size_t HMAC_TAG_LEN = strlen(HMAC_TAG);
41a45d02e5fbf1ec387dcb1e6c91e867d32ab36193Kenny Root
426914efca8fe737a753d234d7e91222da6a8cdabeKenny Rootstatic EVP_PKEY *test_load_key(ENGINE* e, const char *key_id,
436914efca8fe737a753d234d7e91222da6a8cdabeKenny Root        EVP_PKEY* (*read_func)(BIO*, EVP_PKEY**, pem_password_cb*, void*)) {
446914efca8fe737a753d234d7e91222da6a8cdabeKenny Root    void* data = static_cast<void*>(const_cast<char*>(key_id));
456914efca8fe737a753d234d7e91222da6a8cdabeKenny Root
46a45d02e5fbf1ec387dcb1e6c91e867d32ab36193Kenny Root    EVP_PKEY *key = NULL;
47a45d02e5fbf1ec387dcb1e6c91e867d32ab36193Kenny Root
48a45d02e5fbf1ec387dcb1e6c91e867d32ab36193Kenny Root    const size_t key_len = strlen(key_id);
49a45d02e5fbf1ec387dcb1e6c91e867d32ab36193Kenny Root    if (key_len > HMAC_TAG_LEN && !strncmp(key_id, HMAC_TAG, HMAC_TAG_LEN)) {
50a45d02e5fbf1ec387dcb1e6c91e867d32ab36193Kenny Root        key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, e, reinterpret_cast<const unsigned char*>(key_id),
51a45d02e5fbf1ec387dcb1e6c91e867d32ab36193Kenny Root                key_len);
52a45d02e5fbf1ec387dcb1e6c91e867d32ab36193Kenny Root    } else {
53a45d02e5fbf1ec387dcb1e6c91e867d32ab36193Kenny Root        BIO* in = BIO_new_mem_buf(data, strlen(key_id));
54a45d02e5fbf1ec387dcb1e6c91e867d32ab36193Kenny Root        if (!in) {
55a45d02e5fbf1ec387dcb1e6c91e867d32ab36193Kenny Root            return NULL;
56a45d02e5fbf1ec387dcb1e6c91e867d32ab36193Kenny Root        }
57a45d02e5fbf1ec387dcb1e6c91e867d32ab36193Kenny Root        key = read_func(in, NULL, 0, NULL);
58a45d02e5fbf1ec387dcb1e6c91e867d32ab36193Kenny Root        BIO_free(in);
59a45d02e5fbf1ec387dcb1e6c91e867d32ab36193Kenny Root
60a45d02e5fbf1ec387dcb1e6c91e867d32ab36193Kenny Root        if (key != NULL && EVP_PKEY_type(key->type) == EVP_PKEY_RSA) {
61a45d02e5fbf1ec387dcb1e6c91e867d32ab36193Kenny Root            ENGINE_init(e);
62a45d02e5fbf1ec387dcb1e6c91e867d32ab36193Kenny Root
63a45d02e5fbf1ec387dcb1e6c91e867d32ab36193Kenny Root            Unique_RSA rsa(EVP_PKEY_get1_RSA(key));
64a45d02e5fbf1ec387dcb1e6c91e867d32ab36193Kenny Root            rsa->engine = e;
65a45d02e5fbf1ec387dcb1e6c91e867d32ab36193Kenny Root            rsa->flags |= RSA_FLAG_EXT_PKEY;
66a45d02e5fbf1ec387dcb1e6c91e867d32ab36193Kenny Root        }
676914efca8fe737a753d234d7e91222da6a8cdabeKenny Root    }
686914efca8fe737a753d234d7e91222da6a8cdabeKenny Root
696914efca8fe737a753d234d7e91222da6a8cdabeKenny Root    return key;
706914efca8fe737a753d234d7e91222da6a8cdabeKenny Root}
716914efca8fe737a753d234d7e91222da6a8cdabeKenny Root
726914efca8fe737a753d234d7e91222da6a8cdabeKenny Rootstatic EVP_PKEY* test_load_privkey(ENGINE* e, const char* key_id, UI_METHOD*, void*) {
736914efca8fe737a753d234d7e91222da6a8cdabeKenny Root    return test_load_key(e, key_id, PEM_read_bio_PrivateKey);
746914efca8fe737a753d234d7e91222da6a8cdabeKenny Root}
756914efca8fe737a753d234d7e91222da6a8cdabeKenny Root
766914efca8fe737a753d234d7e91222da6a8cdabeKenny Rootstatic EVP_PKEY* test_load_pubkey(ENGINE* e, const char* key_id, UI_METHOD*, void*) {
776914efca8fe737a753d234d7e91222da6a8cdabeKenny Root    return test_load_key(e, key_id, PEM_read_bio_PUBKEY);
786914efca8fe737a753d234d7e91222da6a8cdabeKenny Root}
796914efca8fe737a753d234d7e91222da6a8cdabeKenny Root
80a45d02e5fbf1ec387dcb1e6c91e867d32ab36193Kenny Rootstatic const int meths[] = {
81a45d02e5fbf1ec387dcb1e6c91e867d32ab36193Kenny Root        EVP_PKEY_HMAC,
82a45d02e5fbf1ec387dcb1e6c91e867d32ab36193Kenny Root};
83a45d02e5fbf1ec387dcb1e6c91e867d32ab36193Kenny Root
84a45d02e5fbf1ec387dcb1e6c91e867d32ab36193Kenny Rootstatic int pkey_meths(ENGINE*, EVP_PKEY_METHOD** meth, const int** nids, int nid) {
85a45d02e5fbf1ec387dcb1e6c91e867d32ab36193Kenny Root    if (nid == EVP_PKEY_HMAC) {
86a45d02e5fbf1ec387dcb1e6c91e867d32ab36193Kenny Root        *meth = const_cast<EVP_PKEY_METHOD*>(EVP_PKEY_meth_find(nid));
87a45d02e5fbf1ec387dcb1e6c91e867d32ab36193Kenny Root        return 1;
88a45d02e5fbf1ec387dcb1e6c91e867d32ab36193Kenny Root    } else if (nid != 0) {
89a45d02e5fbf1ec387dcb1e6c91e867d32ab36193Kenny Root        return 0;
90a45d02e5fbf1ec387dcb1e6c91e867d32ab36193Kenny Root    }
91a45d02e5fbf1ec387dcb1e6c91e867d32ab36193Kenny Root
92a45d02e5fbf1ec387dcb1e6c91e867d32ab36193Kenny Root    if (nids != NULL) {
93a45d02e5fbf1ec387dcb1e6c91e867d32ab36193Kenny Root        *nids = meths;
94a45d02e5fbf1ec387dcb1e6c91e867d32ab36193Kenny Root        return 1;
95a45d02e5fbf1ec387dcb1e6c91e867d32ab36193Kenny Root    }
96a45d02e5fbf1ec387dcb1e6c91e867d32ab36193Kenny Root
97a45d02e5fbf1ec387dcb1e6c91e867d32ab36193Kenny Root    return 0;
98a45d02e5fbf1ec387dcb1e6c91e867d32ab36193Kenny Root}
99a45d02e5fbf1ec387dcb1e6c91e867d32ab36193Kenny Root
1006914efca8fe737a753d234d7e91222da6a8cdabeKenny Rootstatic int test_engine_setup(ENGINE* e) {
1016914efca8fe737a753d234d7e91222da6a8cdabeKenny Root    if (!ENGINE_set_id(e, TEST_ENGINE_ID)
1026914efca8fe737a753d234d7e91222da6a8cdabeKenny Root            || !ENGINE_set_name(e, TEST_ENGINE_NAME)
1036914efca8fe737a753d234d7e91222da6a8cdabeKenny Root            || !ENGINE_set_flags(e, 0)
1046914efca8fe737a753d234d7e91222da6a8cdabeKenny Root            || !ENGINE_set_RSA(e, RSA_get_default_method())
1056914efca8fe737a753d234d7e91222da6a8cdabeKenny Root            || !ENGINE_set_load_privkey_function(e, test_load_privkey)
106a45d02e5fbf1ec387dcb1e6c91e867d32ab36193Kenny Root            || !ENGINE_set_load_pubkey_function(e, test_load_pubkey)
107a45d02e5fbf1ec387dcb1e6c91e867d32ab36193Kenny Root            || !ENGINE_set_pkey_meths(e, pkey_meths)) {
1086914efca8fe737a753d234d7e91222da6a8cdabeKenny Root        return 0;
1096914efca8fe737a753d234d7e91222da6a8cdabeKenny Root    }
1106914efca8fe737a753d234d7e91222da6a8cdabeKenny Root
1116914efca8fe737a753d234d7e91222da6a8cdabeKenny Root    return 1;
1126914efca8fe737a753d234d7e91222da6a8cdabeKenny Root}
1136914efca8fe737a753d234d7e91222da6a8cdabeKenny Root
1146914efca8fe737a753d234d7e91222da6a8cdabeKenny Rootstatic int test_engine_bind_fn(ENGINE *e, const char *id) {
1156914efca8fe737a753d234d7e91222da6a8cdabeKenny Root    if (id && (strcmp(id, TEST_ENGINE_ID) != 0)) {
1166914efca8fe737a753d234d7e91222da6a8cdabeKenny Root        return 0;
1176914efca8fe737a753d234d7e91222da6a8cdabeKenny Root    }
1186914efca8fe737a753d234d7e91222da6a8cdabeKenny Root
1196914efca8fe737a753d234d7e91222da6a8cdabeKenny Root    if (!test_engine_setup(e)) {
1206914efca8fe737a753d234d7e91222da6a8cdabeKenny Root        return 0;
1216914efca8fe737a753d234d7e91222da6a8cdabeKenny Root    }
1226914efca8fe737a753d234d7e91222da6a8cdabeKenny Root
1236914efca8fe737a753d234d7e91222da6a8cdabeKenny Root    return 1;
1246914efca8fe737a753d234d7e91222da6a8cdabeKenny Root}
1256914efca8fe737a753d234d7e91222da6a8cdabeKenny Root
1266914efca8fe737a753d234d7e91222da6a8cdabeKenny Rootextern "C" {
1276914efca8fe737a753d234d7e91222da6a8cdabeKenny Root#undef OPENSSL_EXPORT
1286914efca8fe737a753d234d7e91222da6a8cdabeKenny Root#define OPENSSL_EXPORT extern __attribute__ ((visibility ("default")))
1296914efca8fe737a753d234d7e91222da6a8cdabeKenny Root
1306914efca8fe737a753d234d7e91222da6a8cdabeKenny RootIMPLEMENT_DYNAMIC_CHECK_FN()
1316914efca8fe737a753d234d7e91222da6a8cdabeKenny RootIMPLEMENT_DYNAMIC_BIND_FN(test_engine_bind_fn)
1326914efca8fe737a753d234d7e91222da6a8cdabeKenny Root};
133