This repository has been archived on 2025-09-14. You can view files and clone it, but cannot push or open issues or pull requests.
Files
tango-tfe/platform/src/key_keeper.cpp

691 lines
18 KiB
C++
Raw Normal View History

2018-09-04 15:47:41 +08:00
#include "key_keeper.h"
#include <string.h>
2018-09-04 15:47:41 +08:00
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "MESA/MESA_prof_load.h"
#include "tfe_rpc.h"
#include <event2/http.h>
#include <cjson/cJSON.h>
#include <curl/curl.h>
2018-09-04 15:47:41 +08:00
#define HTABLE_MAX_KEY_LEN 256
#define KEYRING_EXSITED 0
#define KEYRING_NOT_EXSITED -1
enum key_keeper_mode{
KK_MODE_NORMAL = 0,
KK_MODE_DEBUG,
};
2018-09-04 18:13:05 +08:00
struct key_keeper
{
enum key_keeper_mode work_mode;
char trusted_ca_path[TFE_PATH_MAX];
char untrusted_ca_path[TFE_PATH_MAX];
char cert_store_host[TFE_SYMBOL_MAX];
2018-09-04 18:13:05 +08:00
unsigned int cert_store_port;
2018-09-07 17:42:57 +08:00
unsigned int hash_slot_size;
unsigned int hash_expire_seconds;
2018-09-04 18:13:05 +08:00
MESA_htable_handle htable;
void* logger;
X509* trusted_ca_cert;
EVP_PKEY* trusted_ca_key;
X509* untrusted_ca_cert;
EVP_PKEY* untrusted_ca_key;
2018-09-04 18:13:05 +08:00
};
2018-09-04 15:47:41 +08:00
struct keyring_private
{
struct keyring head;
pthread_mutex_t mutex;
size_t references;
};
2018-09-04 15:47:41 +08:00
struct key_keeper_promise_ctx
{
void* logger;
MESA_htable_handle htable;
2018-09-07 17:42:57 +08:00
uchar* key;
struct future* f_certstore_rpc;
2018-09-04 15:47:41 +08:00
unsigned int key_len;
};
2018-09-07 17:42:57 +08:00
static void key_keeper_promise_free_ctx(void* ctx)
{
struct key_keeper_promise_ctx* _ctx = (struct key_keeper_promise_ctx*)ctx;
free(_ctx->key);
_ctx->key = NULL;
free(_ctx);
}
2018-09-04 15:47:41 +08:00
2018-09-04 18:13:05 +08:00
static struct keyring_private* keyring_new(void)
{
2018-09-04 18:13:05 +08:00
struct keyring_private *kyr;
if (!(kyr = (struct keyring_private *)ALLOC(struct keyring_private, 1)))
2018-09-04 15:47:41 +08:00
{
return NULL;
2018-09-04 15:47:41 +08:00
}
2018-09-04 18:13:05 +08:00
if (pthread_mutex_init(&kyr->mutex, NULL)) {
free(kyr);
return NULL;
}
2018-09-04 18:13:05 +08:00
kyr->references = 1;
return kyr;
}
/*
2018-09-07 17:42:57 +08:00
static struct keyring* keyring_new3(EVP_PKEY *key, X509 *cert, STACK_OF(X509) *chain)
{
2018-09-04 18:13:05 +08:00
struct keyring_private* kyr=NULL;
kyr=keyring_new();
kyr->references = 1;
(kyr->head).key = key;
(kyr->head).cert = cert;
(kyr->head).chain = chain;
2018-09-04 15:47:41 +08:00
if(key)
{
ssl_key_refcount_inc(key);
}
if(cert)
{
ssl_x509_refcount_inc(cert);
}
if(chain){
int i = 0;
for (i = 0; i < sk_X509_num(chain); i++)
{
ssl_x509_refcount_inc(sk_X509_value(chain, i));
}
}
2018-09-04 18:13:05 +08:00
return &(kyr->head);
2018-09-04 15:47:41 +08:00
}
*/
2018-09-04 15:47:41 +08:00
// Increment reference count.
2018-09-07 17:42:57 +08:00
static void keyring_ref_inc(struct keyring_private* kyr)
2018-09-04 15:47:41 +08:00
{
2018-09-04 18:13:05 +08:00
pthread_mutex_lock(&kyr->mutex);
kyr->references++;
pthread_mutex_unlock(&kyr->mutex);
}
2018-09-04 15:47:41 +08:00
/*
* Thread-safe setter functions; they copy the value (refcounts are inc'd).
*/
2018-09-04 18:13:05 +08:00
static void keyring_set_key(struct keyring_private* kyr, EVP_PKEY *key)
2018-09-04 15:47:41 +08:00
{
2018-09-04 18:13:05 +08:00
pthread_mutex_lock(&kyr->mutex);
if ((kyr->head).key)
2018-09-04 15:47:41 +08:00
{
2018-09-04 18:13:05 +08:00
EVP_PKEY_free((kyr->head).key);
2018-09-04 15:47:41 +08:00
}
2018-09-04 18:13:05 +08:00
(kyr->head).key = key;
2018-09-04 15:47:41 +08:00
if (key)
{
2018-09-04 18:13:05 +08:00
ssl_key_refcount_inc((kyr->head).key);
2018-09-04 15:47:41 +08:00
}
2018-09-04 18:13:05 +08:00
pthread_mutex_unlock(&kyr->mutex);
2018-09-04 15:47:41 +08:00
}
2018-09-04 18:13:05 +08:00
static void keyring_set_cert(struct keyring_private* kry, X509 *cert)
2018-09-04 15:47:41 +08:00
{
2018-09-04 18:13:05 +08:00
pthread_mutex_lock(&kry->mutex);
if ((kry->head).cert)
2018-09-04 15:47:41 +08:00
{
2018-09-04 18:13:05 +08:00
X509_free((kry->head).cert);
2018-09-04 15:47:41 +08:00
}
2018-09-04 18:13:05 +08:00
(kry->head).cert = cert;
2018-09-04 15:47:41 +08:00
if (cert)
{
2018-09-04 18:13:05 +08:00
ssl_x509_refcount_inc((kry->head).cert);
2018-09-04 15:47:41 +08:00
}
2018-09-04 18:13:05 +08:00
pthread_mutex_unlock(&kry->mutex);
2018-09-04 15:47:41 +08:00
}
2018-09-04 18:13:05 +08:00
static void keyring_set_chain(struct keyring_private* kyr, STACK_OF(X509) *chain)
2018-09-04 15:47:41 +08:00
{
2018-09-04 18:13:05 +08:00
pthread_mutex_lock(&kyr->mutex);
if ((kyr->head).chain)
2018-09-04 15:47:41 +08:00
{
2018-09-04 18:13:05 +08:00
sk_X509_pop_free((kyr->head).chain, X509_free);
2018-09-04 15:47:41 +08:00
}
if (chain)
{
2018-09-04 18:13:05 +08:00
(kyr->head).chain = sk_X509_dup(chain);
2018-09-04 15:47:41 +08:00
int i = 0;
2018-09-04 18:13:05 +08:00
for (i = 0; i < sk_X509_num((kyr->head).chain); i++)
2018-09-04 15:47:41 +08:00
{
2018-09-04 18:13:05 +08:00
ssl_x509_refcount_inc(sk_X509_value((kyr->head).chain, i));
2018-09-04 15:47:41 +08:00
}
} else
{
2018-09-04 18:13:05 +08:00
(kyr->head).chain = NULL;
2018-09-04 15:47:41 +08:00
}
2018-09-04 18:13:05 +08:00
pthread_mutex_unlock(&kyr->mutex);
2018-09-04 15:47:41 +08:00
}
/*
* Free keyring including internal objects.
*/
2018-09-04 18:13:05 +08:00
void key_keeper_free_keyring(struct keyring *kyr)
2018-09-04 15:47:41 +08:00
{
2018-09-04 18:13:05 +08:00
struct keyring_private* _kyr = (struct keyring_private*)kyr;
pthread_mutex_lock(&_kyr->mutex);
_kyr->references--;
if (_kyr->references>0)
2018-09-04 15:47:41 +08:00
{
2018-09-04 18:13:05 +08:00
pthread_mutex_unlock(&_kyr->mutex);
2018-09-04 15:47:41 +08:00
return;
}
2018-09-04 18:13:05 +08:00
pthread_mutex_unlock(&_kyr->mutex);
pthread_mutex_destroy(&_kyr->mutex);
if ((_kyr->head).key)
2018-09-04 15:47:41 +08:00
{
2018-09-04 18:13:05 +08:00
EVP_PKEY_free((_kyr->head).key);
(_kyr->head).key=NULL;
2018-09-04 15:47:41 +08:00
}
2018-09-04 18:13:05 +08:00
if ((_kyr->head).cert)
2018-09-04 15:47:41 +08:00
{
2018-09-04 18:13:05 +08:00
X509_free((_kyr->head).cert);
(_kyr->head).cert=NULL;
2018-09-04 15:47:41 +08:00
}
2018-09-04 18:13:05 +08:00
if ((_kyr->head).chain)
2018-09-04 15:47:41 +08:00
{
2018-09-04 18:13:05 +08:00
sk_X509_pop_free((_kyr->head).chain, X509_free);
(_kyr->head).chain=NULL;
2018-09-04 15:47:41 +08:00
}
2018-09-04 18:13:05 +08:00
free(_kyr);
2018-09-04 15:47:41 +08:00
}
2018-09-07 17:42:57 +08:00
static X509* transform_cert_to_x509(const char* str)
{
//printf("cert: %s", str);
BIO *bio = NULL;
X509 *cert = NULL;
2018-09-07 17:42:57 +08:00
bio = BIO_new(BIO_s_mem());
if(bio == NULL)
{
return NULL;
}
int len = BIO_write(bio, (const void*)str, strlen(str));
if (len <= 0 )
{
BIO_free_all(bio);
return NULL;
}
2018-09-07 17:42:57 +08:00
cert = PEM_read_bio_X509(bio, NULL, NULL, NULL);
BIO_free_all(bio);
return cert;
}
static char* transform_cert_to_pem(X509* cert)
{
if (NULL == cert)
{
return NULL;
}
BIO* bio = NULL;
bio = BIO_new(BIO_s_mem());
if (NULL == bio)
{
return NULL;
}
if (0 == PEM_write_bio_X509(bio, cert))
{
BIO_free(bio);
return NULL;
}
char *p = NULL;
int len = BIO_get_mem_data(bio, &p);
char *pem = (char*)malloc(len + 1);
memset(pem, 0, len + 1);
BIO_read(bio, pem, len);
BIO_free(bio);
return pem;
}
2018-09-07 17:42:57 +08:00
static EVP_PKEY* transform_key_to_EVP(const char* str)
{
//printf("private key: %s", str);
2018-09-07 17:42:57 +08:00
BIO *mem;
mem = BIO_new_mem_buf(str, -1);
if(mem == NULL)
{
return NULL;
}
2018-09-07 17:42:57 +08:00
EVP_PKEY* key = PEM_read_bio_PrivateKey(mem, NULL, NULL, 0);
BIO_free(mem);
return key;
}
static void err_out(X509* cert, EVP_PKEY* key, STACK_OF(X509)* chain)
{
if(cert)
{
X509_free(cert);
}
if(key)
{
EVP_PKEY_free(key);
}
if(chain)
{
sk_X509_pop_free(chain, X509_free);
}
return;
}
2018-09-14 16:58:19 +08:00
static struct keyring_private* get_keyring_from_response(const char* data)
2018-09-07 17:42:57 +08:00
{
X509* cert = NULL;
EVP_PKEY* key = NULL;
STACK_OF(X509)* chain = NULL;
if(data == NULL)
{
return NULL;
}
cJSON* data_json = cJSON_Parse(data);
if(data_json == NULL)
{
return NULL;
}
cJSON* cert_json = NULL;
cJSON* key_json = NULL;
cJSON* chain_json = NULL;
cert_json = cJSON_GetObjectItemCaseSensitive(data_json, "CERTIFICATE");
key_json = cJSON_GetObjectItemCaseSensitive(data_json, "PRIVATE_KEY");
chain_json = cJSON_GetObjectItemCaseSensitive(data_json, "CERTIFICATE_CHAIN");
if (cert_json && cert_json->valuestring != NULL)
{
cert = transform_cert_to_x509(cert_json->valuestring);
}
if(cert == NULL)
{
err_out(cert, key, chain);
return NULL;
}
if (key_json && key_json->valuestring != NULL)
{
key = transform_key_to_EVP(key_json->valuestring);
}
if(key == NULL)
{
err_out(cert, key, chain);
return NULL;
}
if(chain_json == NULL)
{
err_out(cert, key, chain);
return NULL;
}
cJSON* chain_cert_json = NULL;
chain = sk_X509_new_null();
cJSON_ArrayForEach(chain_cert_json, chain_json)
{
X509* chain_cert = NULL;
if (chain_cert_json && chain_cert_json->valuestring != NULL)
{
chain_cert = transform_cert_to_x509(chain_cert_json->valuestring);
}
if(chain_cert == NULL)
{
err_out(cert, key, chain);
return NULL;
}
sk_X509_push(chain, chain_cert);
2018-09-14 21:23:08 +08:00
ssl_x509_refcount_inc(chain_cert);
2018-09-07 17:42:57 +08:00
}
struct keyring_private* _kyr= keyring_new();
keyring_set_cert(_kyr, cert);
keyring_set_key(_kyr, key);
keyring_set_chain(_kyr, chain);
X509_free(cert);
EVP_PKEY_free(key);
sk_X509_pop_free(chain, X509_free);
2018-09-14 16:58:19 +08:00
return _kyr;
2018-09-07 17:42:57 +08:00
}
2018-09-04 18:13:05 +08:00
static long keyring_local_cache_query_cb(void * data, const uchar * key, uint size, void * user_arg)
2018-09-04 15:47:41 +08:00
{
2018-09-04 18:13:05 +08:00
struct keyring_private* kyr=(struct keyring_private*)data;
if(kyr == NULL)
{
return KEYRING_NOT_EXSITED;
}
else
{
struct promise* p = (struct promise*)user_arg;
promise_success(p, data);
return KEYRING_EXSITED;
}
2018-09-04 15:47:41 +08:00
}
2018-09-07 17:42:57 +08:00
static struct keyring_private* generate_x509_keyring(X509* origin_cert, X509* ca, EVP_PKEY* cakey)
2018-09-04 15:47:41 +08:00
{
//TODO: could be optimized to save cpu.
2018-09-04 15:47:41 +08:00
EVP_PKEY* forge_key = ssl_key_genrsa(1024);
X509* forge_cert = ssl_x509_forge(ca, cakey, origin_cert, forge_key, NULL, NULL);
STACK_OF(X509)* chain = sk_X509_new_null();
sk_X509_push(chain, ca);
sk_X509_push(chain, forge_cert);
2018-09-14 21:23:08 +08:00
ssl_x509_refcount_inc(ca);
ssl_x509_refcount_inc(forge_cert);
2018-09-07 17:42:57 +08:00
struct keyring_private* _kyr= keyring_new();
keyring_set_key(_kyr, forge_key);
keyring_set_cert(_kyr, forge_cert);
keyring_set_chain(_kyr, chain);
2018-09-07 17:42:57 +08:00
X509_free(forge_cert);
EVP_PKEY_free(forge_key);
sk_X509_pop_free(chain, X509_free);
return _kyr;
2018-09-04 18:13:05 +08:00
}
static void certstore_rpc_on_succ(void* result, void* user)
2018-09-04 15:47:41 +08:00
{
struct promise * p = (struct promise *) user;
struct key_keeper_promise_ctx* ctx = (struct key_keeper_promise_ctx*)promise_get_ctx(p);
// TFE_LOG_INFO(ctx->logger, "certstore rpc success");
future_destroy(ctx->f_certstore_rpc);
2018-09-04 15:47:41 +08:00
MESA_htable_handle htable= ctx->htable;
const uchar* key = ctx->key;
unsigned int key_len = ctx->key_len;
struct tfe_rpc_response_result* response = tfe_rpc_release(result);
int status_code = response->status_code;
const char* status_msg = response->status_msg;
2018-09-07 17:42:57 +08:00
char* data = response->data;
2018-09-13 20:25:12 +08:00
size_t len = response->len;
2018-09-04 15:47:41 +08:00
if(status_code == HTTP_OK)
{
2018-09-07 17:42:57 +08:00
*(data+len) = '\0';
2018-09-14 16:58:19 +08:00
struct keyring_private* kyr= get_keyring_from_response(data);
if(kyr == NULL)
{
promise_failed(p, FUTURE_ERROR_EXCEPTION, "get_keyring_from_response failed");
return;
}
2018-09-14 16:58:19 +08:00
keyring_ref_inc(kyr);
2018-09-07 17:42:57 +08:00
int ret = MESA_htable_add(htable, key, key_len, (void*)kyr);
2018-09-04 18:13:05 +08:00
if(ret<0)
{
2018-09-07 17:42:57 +08:00
key_keeper_free_keyring((struct keyring*)kyr);
2018-09-04 18:13:05 +08:00
}
2018-09-14 16:58:19 +08:00
promise_success(p, (void*)kyr);
key_keeper_free_keyring((struct keyring*)kyr);
2018-09-04 15:47:41 +08:00
}
else
{
promise_failed(p, FUTURE_ERROR_EXCEPTION, status_msg);
}
2018-09-07 17:42:57 +08:00
//promise_dettach_ctx(p);
//ctx_destroy_cb((void*)ctx);
2018-09-04 15:47:41 +08:00
}
2018-09-07 17:42:57 +08:00
static void certstore_rpc_on_fail(enum e_future_error err, const char * what, void * user)
{
struct promise * p = (struct promise *) user;
struct key_keeper_promise_ctx* ctx= (struct key_keeper_promise_ctx*)promise_get_ctx(p);
TFE_LOG_ERROR(ctx->logger, "certstore rpc failed, what is %s", what);
2018-09-07 17:42:57 +08:00
future_destroy(ctx->f_certstore_rpc);
promise_failed(p, err, what);
2018-09-07 17:42:57 +08:00
//promise_dettach_ctx(p);
//ctx_destroy_cb((void*)ctx);
}
2018-09-04 15:47:41 +08:00
2018-09-04 18:13:05 +08:00
/*
* Certificate, including private key and keyring chain.
*/
2018-09-28 14:55:36 +08:00
static int __wrapper_MESA_htable_set_opt_int(MESA_htable_handle table, enum MESA_htable_opt opt_type, unsigned int value)
2018-09-07 17:42:57 +08:00
{
int ret = MESA_htable_set_opt(table, opt_type, &value, (int)(sizeof(value)));
assert(ret == 0);
return ret;
}
2018-09-04 18:13:05 +08:00
2018-09-28 14:55:36 +08:00
static int __wrapper_MESA_htable_set_opt_func(MESA_htable_handle table, enum MESA_htable_opt opt_type, void * val, size_t len)
{
int ret = MESA_htable_set_opt(table, opt_type, val, (int)len);
assert(ret == 0);
return ret;
}
static void key_keeper_free_serialized(void* data)
{
// printf("call key_keeper_free_serialized\n");
2018-09-28 14:55:36 +08:00
struct keyring_private* kyr = (struct keyring_private*)data;
key_keeper_free_keyring(&(kyr->head));
}
2018-09-07 17:42:57 +08:00
static MESA_htable_handle create_hash_table(unsigned int slot_size, unsigned int expire_seconds)
{
int ret = 0;
unsigned max_num = slot_size * 4;
MESA_htable_handle htable = MESA_htable_born();
2018-09-28 14:55:36 +08:00
ret = __wrapper_MESA_htable_set_opt_int(htable, MHO_SCREEN_PRINT_CTRL, 0);
ret = __wrapper_MESA_htable_set_opt_int(htable, MHO_THREAD_SAFE, 1);
ret = __wrapper_MESA_htable_set_opt_int(htable, MHO_MUTEX_NUM, 16);
ret = __wrapper_MESA_htable_set_opt_int(htable, MHO_HASH_SLOT_SIZE, slot_size);
ret = __wrapper_MESA_htable_set_opt_int(htable, MHO_HASH_MAX_ELEMENT_NUM, max_num);
ret = __wrapper_MESA_htable_set_opt_int(htable, MHO_EXPIRE_TIME, expire_seconds);
ret = __wrapper_MESA_htable_set_opt_int(htable, MHO_ELIMIMINATE_TYPE,
2018-09-07 17:42:57 +08:00
HASH_ELIMINATE_ALGO_FIFO);
2018-09-28 14:55:36 +08:00
ret = __wrapper_MESA_htable_set_opt_func(htable, MHO_CBFUN_DATA_FREE,
(void *)key_keeper_free_serialized, sizeof(&key_keeper_free_serialized));
2018-09-07 17:42:57 +08:00
//ret = __wrapper_MESA_htable_set_opt(htable, MHO_CBFUN_DATA_EXPIRE_NOTIFY,
// (void *)key_keeper_verify_cb);
ret = MESA_htable_mature(htable);
assert(ret == 0);
return htable;
}
2018-09-04 18:13:05 +08:00
void key_keeper_destroy(struct key_keeper *keeper)
{
MESA_htable_destroy(keeper->htable, NULL);
X509_free(keeper->trusted_ca_cert);
EVP_PKEY_free(keeper->trusted_ca_key);
X509_free(keeper->untrusted_ca_cert);
EVP_PKEY_free(keeper->untrusted_ca_key);
free(keeper);
keeper = NULL;
return;
}
2018-09-05 10:38:27 +08:00
struct key_keeper* key_keeper_init(const char * profile, const char* section, void* logger)
2018-09-04 18:13:05 +08:00
{
struct key_keeper* keeper = ALLOC(struct key_keeper, 1);
keeper->logger = logger;
char tmp[TFE_STRING_MAX]={0};
MESA_load_profile_string_def(profile, section, "mode", tmp, sizeof(tmp), "debug");
if(strcasecmp(tmp, "debug") == 0)
{
keeper->work_mode = KK_MODE_DEBUG;
}
else
{
keeper->work_mode = KK_MODE_NORMAL;
}
MESA_load_profile_string_def(profile, section, "ca_path", keeper->trusted_ca_path, sizeof(keeper->trusted_ca_path), "./conf/mesalab-ca.pem");
MESA_load_profile_string_def(profile, section, "untrusted_ca_path", keeper->untrusted_ca_path, sizeof(keeper->untrusted_ca_path), "./conf/mesalab-ca-untrust.pem");
2018-09-04 18:13:05 +08:00
MESA_load_profile_string_def(profile, section, "cert_store_host", keeper->cert_store_host, sizeof(keeper->cert_store_host), "xxxxx");
MESA_load_profile_uint_def(profile, section, "cert_store_port", &(keeper->cert_store_port), 80);
MESA_load_profile_uint_def(profile, section, "hash_slot_size", &(keeper->hash_slot_size), 1024*128);
MESA_load_profile_uint_def(profile, section, "hash_expire_seconds", &(keeper->hash_expire_seconds), 5*60);
2018-09-07 17:42:57 +08:00
keeper->htable = create_hash_table(keeper->hash_slot_size, keeper->hash_expire_seconds);
if(0==strcmp(keeper->untrusted_ca_path, keeper->trusted_ca_path))
{
TFE_LOG_ERROR(logger, "Warnning: Trusted and Untrusted Root CA share the same path % .", keeper->trusted_ca_path);
}
if(keeper->work_mode==KK_MODE_DEBUG)
{
keeper->trusted_ca_cert=ssl_x509_load(keeper->trusted_ca_path);
keeper->trusted_ca_key=ssl_key_load(keeper->trusted_ca_path);
if(keeper->trusted_ca_cert==NULL||keeper->trusted_ca_key==NULL)
{
TFE_LOG_ERROR(logger, "Load Trusted Root CA %s failed.", keeper->trusted_ca_path);
goto error_out;
}
keeper->untrusted_ca_cert=ssl_x509_load(keeper->untrusted_ca_path);
keeper->untrusted_ca_key=ssl_key_load(keeper->untrusted_ca_path);
if(keeper->untrusted_ca_cert==NULL||keeper->trusted_ca_key==NULL)
{
TFE_LOG_ERROR(logger, "Load Untrusted Root CA %s failed.", keeper->untrusted_ca_path);
goto error_out;
}
}
TFE_LOG_INFO(logger, "MESA_load_profile, [%s]: mode:%s, ca_path:%s, untrusted_ca_path:%s, cert_store_host:%s, cert_store_port:%d, hash_slot_size:%d, hash_expire_seconds:%d",
section, tmp, keeper->trusted_ca_path, keeper->untrusted_ca_path, keeper->cert_store_host, keeper->cert_store_port, keeper->hash_slot_size, keeper->hash_expire_seconds);
2018-09-04 18:13:05 +08:00
return keeper;
error_out:
key_keeper_destroy(keeper);
return NULL;
2018-09-04 18:13:05 +08:00
}
struct keyring* key_keeper_release_keyring(future_result_t* result)
{
struct keyring_private* kyr=(struct keyring_private*)result;
keyring_ref_inc(kyr);
return &(kyr->head);
2018-09-04 15:47:41 +08:00
}
2018-09-07 17:42:57 +08:00
static uchar* get_key_by_cert(X509* cert, int keyring_id, unsigned int* len)
{
if(cert == NULL)
{
return NULL;
}
2018-09-07 17:42:57 +08:00
char* cert_fgr = NULL;
cert_fgr = ssl_x509_fingerprint(cert, 0);
if(cert_fgr == NULL)
2018-09-07 17:42:57 +08:00
{
return NULL;
}
char* key = (char*)malloc(HTABLE_MAX_KEY_LEN);
memset(key, 0, HTABLE_MAX_KEY_LEN);
2018-09-07 17:42:57 +08:00
snprintf(key, HTABLE_MAX_KEY_LEN, "%d:", keyring_id);
strncat(key, cert_fgr, HTABLE_MAX_KEY_LEN);
*len = strnlen(key, HTABLE_MAX_KEY_LEN);
free(cert_fgr);
return (uchar*)key;
2018-09-04 15:47:41 +08:00
}
2018-09-07 17:42:57 +08:00
char* url_escape(char* url)
{
if(url == NULL)
{
return NULL;
}
CURL *curl = curl_easy_init();
char* _url = NULL;
if(curl)
{
_url = curl_easy_escape(curl, url, strlen(url));
}
return _url;
}
2018-09-04 18:13:05 +08:00
void key_keeper_async_ask(struct future * f, struct key_keeper * keeper, const char* sni, int keyring_id, X509 * origin_cert, int is_cert_valid, struct event_base * evbase)
2018-09-04 15:47:41 +08:00
{
struct promise* p = future_to_promise(f);
unsigned int len = 0;
2018-09-07 17:42:57 +08:00
uchar* key = get_key_by_cert(origin_cert, keyring_id, &len);
if(key == NULL)
{
promise_failed(p, FUTURE_ERROR_EXCEPTION, "get hash key by_cert failed");
return;
}
struct key_keeper_promise_ctx* ctx = ALLOC(struct key_keeper_promise_ctx, 1);
2018-09-04 15:47:41 +08:00
ctx->logger = keeper->logger;
ctx->htable = keeper->htable;
ctx->key = key;
ctx->key_len = len;
2018-09-07 17:42:57 +08:00
promise_set_ctx(p, (void*)ctx, key_keeper_promise_free_ctx);
2018-09-04 15:47:41 +08:00
long int cb_rtn = 0;
2018-09-04 18:13:05 +08:00
MESA_htable_search_cb(ctx->htable, (const unsigned char*)(ctx->key), ctx->key_len, keyring_local_cache_query_cb, p, &cb_rtn);
2018-09-04 15:47:41 +08:00
if(cb_rtn == KEYRING_EXSITED)
{
//printf("KEYRING_EXSITED\n");
2018-09-04 15:47:41 +08:00
return;
}
switch(keeper->work_mode)
2018-09-07 17:42:57 +08:00
{
case KK_MODE_NORMAL:
2018-09-04 15:47:41 +08:00
{
char* origin_cert_pem = transform_cert_to_pem(origin_cert);
if(origin_cert_pem == NULL)
{
promise_failed(p, FUTURE_ERROR_EXCEPTION, "transform origin_cert to pem failed");
return;
}
char* escaped_origin_cert_pem = url_escape(origin_cert_pem);
free(origin_cert_pem);
if(escaped_origin_cert_pem == NULL)
{
promise_failed(p, FUTURE_ERROR_EXCEPTION, "url escape failed");
break;
}
2018-09-07 17:42:57 +08:00
struct future* f_certstore_rpc = future_create("tfe_rpc", certstore_rpc_on_succ, certstore_rpc_on_fail, p);
ctx->f_certstore_rpc = f_certstore_rpc;
char *url = NULL;
url = (char*)malloc(strlen(escaped_origin_cert_pem) + TFE_STRING_MAX);
//keyring_id = 1;
if(sni == NULL || sni[0] == '\0')
{
sprintf(url, "http://%s:%d/ca?keyring_id=%d&is_valid=%d&origin_cert=%s",
keeper->cert_store_host, keeper->cert_store_port, keyring_id, is_cert_valid, escaped_origin_cert_pem);
}
else
2018-09-07 17:42:57 +08:00
{
sprintf(url, "http://%s:%d/ca?keyring_id=%d&sni=%s&is_valid=%d&origin_cert=%s",
keeper->cert_store_host, keeper->cert_store_port, keyring_id, sni, is_cert_valid, escaped_origin_cert_pem);
2018-09-07 17:42:57 +08:00
}
curl_free(escaped_origin_cert_pem);
2018-09-07 17:42:57 +08:00
tfe_rpc_async_ask(f_certstore_rpc, url, GET, DONE_CB, NULL, 0, evbase);
free(url);
2018-09-04 15:47:41 +08:00
break;
}
case KK_MODE_DEBUG:
2018-09-04 15:47:41 +08:00
{
struct keyring_private* kyr=NULL;
2018-09-07 17:42:57 +08:00
if(is_cert_valid == 1)
{
kyr=generate_x509_keyring(origin_cert, keeper->trusted_ca_cert, keeper->trusted_ca_key);
2018-09-07 17:42:57 +08:00
}
else
{
kyr=generate_x509_keyring(origin_cert, keeper->untrusted_ca_cert, keeper->untrusted_ca_key);
2018-09-07 17:42:57 +08:00
}
2018-09-14 16:58:19 +08:00
if(kyr)
2018-09-04 15:47:41 +08:00
{
2018-09-14 16:58:19 +08:00
keyring_ref_inc(kyr);
int ret = MESA_htable_add(ctx->htable, ctx->key, ctx->key_len, (void*)kyr);
if(ret < 0)
2018-09-04 18:13:05 +08:00
{
2018-09-14 16:58:19 +08:00
key_keeper_free_keyring((struct keyring*)kyr);
2018-09-04 18:13:05 +08:00
}
2018-09-14 16:58:19 +08:00
promise_success(p, (void*)kyr);
key_keeper_free_keyring((struct keyring*)kyr);
2018-09-04 15:47:41 +08:00
}
else
{
promise_failed(p, FUTURE_ERROR_EXCEPTION, "generate X509 cert failed");
}
break;
}
}
return;
}