#include "tfe_rpc.h" #include "tfe_utils.h" #include "MESA/MESA_prof_load.h" #include "MESA/MESA_handle_logger.h" #include "string.h" #include "cjson/cJSON.h" #include "ssl_utils.h" #include "key_keeper.h" #include struct keyring_private { struct keyring head; pthread_mutex_t mutex; size_t references; }; static struct keyring_private* keyring_new(void) { struct keyring_private *kyr; if (!(kyr = (struct keyring_private *)ALLOC(struct keyring_private, 1))) { return NULL; } if (pthread_mutex_init(&kyr->mutex, NULL)) { free(kyr); return NULL; } kyr->references = 1; return kyr; } /* * Thread-safe setter functions; they copy the value (refcounts are inc'd). */ static void keyring_set_key(struct keyring_private* kyr, EVP_PKEY *key) { pthread_mutex_lock(&kyr->mutex); if ((kyr->head).key) { EVP_PKEY_free((kyr->head).key); } (kyr->head).key = key; if (key) { ssl_key_refcount_inc((kyr->head).key); } pthread_mutex_unlock(&kyr->mutex); } static void keyring_set_cert(struct keyring_private* kry, X509 *cert) { pthread_mutex_lock(&kry->mutex); if (kry->head.cert) { X509_free((kry->head).cert); } kry->head.cert = cert; if (cert) { ssl_x509_refcount_inc((kry->head).cert); } pthread_mutex_unlock(&kry->mutex); } static void keyring_set_chain(struct keyring_private* kyr, STACK_OF(X509) *chain) { pthread_mutex_lock(&(kyr->mutex)); if (kyr->head.chain) { sk_X509_pop_free(kyr->head.chain, X509_free); } if (chain) { kyr->head.chain = sk_X509_dup(chain); int i = 0; for (i = 0; i < sk_X509_num(kyr->head.chain); i++) { ssl_x509_refcount_inc(sk_X509_value(kyr->head.chain, i)); } } else { kyr->head.chain = NULL; } pthread_mutex_unlock(&(kyr->mutex)); } static X509* transform_cert_to_x509(const char* str) { BIO *bio; X509 *cert; bio = BIO_new(BIO_s_mem()); BIO_write(bio, (const void*)str, strnlen(str, TFE_STRING_MAX)); cert = PEM_read_bio_X509(bio, NULL, NULL, NULL); return cert; } static EVP_PKEY* transform_key_to_EVP(const char* str) { BIO *mem; mem = BIO_new_mem_buf(str, -1); EVP_PKEY* key = PEM_read_bio_PrivateKey(mem, NULL, NULL, 0); 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; } static struct keyring* get_keyring_from_response(const char* data) { 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; } if(chain_cert) printf("push to chain\n"); sk_X509_push(chain, chain_cert); ssl_x509_refcount_inc(chain_cert); } struct keyring_private* _kyr= keyring_new(); printf("cert is %s", cert == NULL ? "null" : "not null\n"); printf("key is %s", key == NULL ? "null" : "not null\n"); printf("chain is %s", chain == NULL ? "null" : "not null\n"); 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); return &(_kyr->head); } static void tfe_rpc_on_succ(void* result, void* user) { struct tfe_rpc_response_result* response = tfe_rpc_release(result); int status_code = response->status_code; const char* status_msg = response->status_msg; char* data = (char*)response->data; int len = response->len; *(data+len) = '\0'; printf("status_code is %d\n", status_code); printf("status_msg is %s\n", status_msg); //printf("data is %s\n", data); printf("len is %d\n", len); struct keyring* kyr = get_keyring_from_response(data); assert(kyr!=NULL); (void)kyr; //add to hash table } static void tfe_rpc_on_fail(enum e_future_error err, const char * what, void * user){ printf("err is %d\n", err); printf("what is %s\n", what); printf("user is %s\n", (char*)user); } int main() { char cert_store_host[TFE_STRING_MAX]; unsigned int cert_store_port; future_promise_library_init(NULL); //const char* file_path = "./log/test_tfe_rpc.log",*host="localhost"; //void * logger = (void *)MESA_create_runtime_log_handle(file_path, RLOG_LV_INFO); const char* profile = "./conf/tfe.conf"; const char* section = "key_keeper"; int keyring_id = 0; MESA_load_profile_string_def(profile, section, "cert_store_host", cert_store_host, sizeof(cert_store_host), "xxxxx"); MESA_load_profile_uint_def(profile, section, "cert_store_port", &cert_store_port, 80); struct event_base* evbase = event_base_new(); struct evdns_base* dnsbase=evdns_base_new(evbase, EVDNS_BASE_INITIALIZE_NAMESERVERS); struct future* f_tfe_rpc = future_create("tfe_rpc", tfe_rpc_on_succ, tfe_rpc_on_fail, NULL); char url[TFE_STRING_MAX]; char sni[TFE_STRING_MAX] = "www.baidu.com"; snprintf(url, TFE_STRING_MAX, "http://%s:%d/ca?host=%s&flag=1&valid=1&kering_id=%d", cert_store_host, cert_store_port, sni, keyring_id); printf("url is %s\n", url); tfe_rpc_async_ask(f_tfe_rpc, url, GET, DONE_CB, NULL, 0, evbase, dnsbase); event_base_dispatch(evbase); }