#68 从目录中加载额外的证书和crl。

This commit is contained in:
zhengchao
2018-11-02 20:38:06 +08:00
committed by Lu Qiuwen
parent d0ea605a5b
commit 668c1b3e52
10 changed files with 450 additions and 994 deletions

View File

@@ -132,7 +132,9 @@ struct ssl_mgr
char * crl_url;
uint8_t ssl_mode_release_buffers;
char trust_CA_file[TFE_PATH_MAX];
char trusted_cert_file[TFE_PATH_MAX];
char trusted_cert_dir[TFE_PATH_MAX];
char crl_file[TFE_PATH_MAX];
struct ssl_trusted_cert_storage * trust_CA_store;
@@ -565,20 +567,17 @@ struct ssl_mgr * ssl_manager_init(const char * ini_profile, const char * section
goto error_out;
}
MESA_load_profile_string_def(ini_profile, section, "trust_CA_file", mgr->trust_CA_file, sizeof(mgr->trust_CA_file),
MESA_load_profile_string_def(ini_profile, section, "trusted_cert_file", mgr->trusted_cert_file, sizeof(mgr->trusted_cert_file),
"/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem");
mgr->trust_CA_store = ssl_trusted_cert_storage_create(mgr->trust_CA_file);
MESA_load_profile_string_def(ini_profile, section, "trusted_cert_dir", mgr->trusted_cert_dir, sizeof(mgr->trusted_cert_dir),
"./conf/trusted_storage");
mgr->trust_CA_store = ssl_trusted_cert_storage_create(mgr->trusted_cert_file, mgr->trusted_cert_dir);
if (mgr->trust_CA_store == NULL)
{
TFE_LOG_ERROR(logger, "Failed at creating X509_STORE");
goto error_out;
}
MESA_load_profile_string_def(ini_profile, section, "crl_file", mgr->crl_file, sizeof(mgr->crl_file), "");
if(strlen(mgr->crl_file)>0)
{
ssl_trusted_cert_storage_add(mgr->trust_CA_store, SSL_X509_OBJ_CRL, mgr->crl_file);
}
memcpy(mgr->ssl_session_context, "mesa-tfe", sizeof(mgr->ssl_session_context));
@@ -941,23 +940,27 @@ static void ssl_server_connected_eventcb(struct bufferevent * bev, short events,
struct ssl_stream * s_stream = ctx->s_stream;
struct ssl_mgr* mgr=s_stream->mgr;
SSL_SESSION * ssl_sess = NULL;
char error_string[TFE_STRING_MAX];
char error_str[TFE_STRING_MAX];
const char* sni=s_stream->client_hello->sni?s_stream->client_hello->sni:"null";
if (events & BEV_EVENT_ERROR)
{
ATOMIC_INC(&(ctx->mgr->stat_val[SSL_UP_ERR]));
ssl_stream_log_error(bev, CONN_DIR_UPSTREAM, ctx->mgr->logger);
promise_failed(p, FUTURE_ERROR_EXCEPTION, "connect to original server failed.");
snprintf(error_str, sizeof(error_str), "connect to original server failed : sni=%s", sni);
promise_failed(p, FUTURE_ERROR_EXCEPTION, error_str);
}
else if(events & BEV_EVENT_EOF)
{
ATOMIC_INC(&(ctx->mgr->stat_val[SSL_UP_ERR]));
promise_failed(p, FUTURE_ERROR_EXCEPTION, "original server closed.");
ATOMIC_INC(&(ctx->mgr->stat_val[SSL_UP_ERR]));
snprintf(error_str, sizeof(error_str), "original server closed : sni=%s", sni);
promise_failed(p, FUTURE_ERROR_EXCEPTION, error_str);
}
else if(events & BEV_EVENT_TIMEOUT)
{
ATOMIC_INC(&(ctx->mgr->stat_val[SSL_UP_ERR]));
promise_failed(p, FUTURE_ERROR_TIMEOUT, NULL);
ATOMIC_INC(&(ctx->mgr->stat_val[SSL_UP_ERR]));
snprintf(error_str, sizeof(error_str), "timeout : sni=%s", sni);
promise_failed(p, FUTURE_ERROR_TIMEOUT, error_str);
}
else if(events & BEV_EVENT_CONNECTED)
{
@@ -967,7 +970,7 @@ static void ssl_server_connected_eventcb(struct bufferevent * bev, short events,
if(!SSL_session_reused(s_stream->ssl))
{
s_stream->is_peer_cert_verify_passed = ssl_trusted_cert_storage_verify_conn(s_stream->mgr->trust_CA_store,
s_stream->ssl, error_string, sizeof(error_string));
s_stream->ssl, error_str, sizeof(error_str));
if(s_stream->is_peer_cert_verify_passed)
{
//ONLY verified session is cacheable.
@@ -980,7 +983,7 @@ static void ssl_server_connected_eventcb(struct bufferevent * bev, short events,
{
ATOMIC_INC(&(mgr->stat_val[SSL_FAKE_CRT]));
char* addr_str=tfe_string_addr_create_by_fd(ctx->fd_upstream, CONN_DIR_UPSTREAM);
TFE_LOG_INFO(mgr->logger, "Fake Cert %s %s : %s", addr_str, ctx->s_stream->client_hello->sni, error_string);
TFE_LOG_INFO(mgr->logger, "Fake Cert %s %s : %s", addr_str, ctx->s_stream->client_hello->sni, error_str);
free(addr_str);
}
}
@@ -1430,22 +1433,26 @@ static void ssl_client_connected_eventcb(struct bufferevent * bev, short events,
struct ssl_stream * s_stream = ctx->downstream;
struct ssl_mgr* mgr=s_stream->mgr;
SSL_SESSION * ssl_sess = NULL;
const char* sni=ctx->origin_ssl->client_hello->sni?ctx->origin_ssl->client_hello->sni:"null";
char error_str[TFE_STRING_MAX]={0};
if (events & BEV_EVENT_ERROR)
{
ATOMIC_INC(&(mgr->stat_val[SSL_DOWN_ERR]));
ssl_stream_log_error(bev, CONN_DIR_DOWNSTREAM, mgr->logger);
promise_failed(p, FUTURE_ERROR_EXCEPTION, "connect to client failed.");
snprintf(error_str, sizeof(error_str), "connect to client failed : sni=%s", sni);
promise_failed(p, FUTURE_ERROR_EXCEPTION, error_str);
}
else if(events & BEV_EVENT_EOF)
{
ATOMIC_INC(&(mgr->stat_val[SSL_DOWN_ERR]));
promise_failed(p, FUTURE_ERROR_EXCEPTION, "client side closed.");
ATOMIC_INC(&(mgr->stat_val[SSL_DOWN_ERR]));
snprintf(error_str, sizeof(error_str), "client side closed : sni=%s", sni);
promise_failed(p, FUTURE_ERROR_EXCEPTION, error_str);
}
else if(events & BEV_EVENT_TIMEOUT)
{
ATOMIC_INC(&(mgr->stat_val[SSL_DOWN_ERR]));
promise_failed(p, FUTURE_ERROR_TIMEOUT, NULL);
snprintf(error_str, sizeof(error_str), "timeout : sni=%s", sni);
promise_failed(p, FUTURE_ERROR_TIMEOUT, error_str);
}
else if(events & BEV_EVENT_CONNECTED)
{

View File

@@ -26,15 +26,79 @@ static void free_ssl_x509_obj(void* data)
}
struct ssl_trusted_cert_storage
{
char* pem_bundle;
char* pem_bundle, *pem_dir;
MESA_htable_handle hash_table;
pthread_rwlock_t rwlock;
X509_STORE* effective_store;
};
static X509_STORE* _X509_store_create(const char* pem_bundle)
static int _X509_add_cert_or_crl_add(X509_STORE* store, enum ssl_X509_obj_type type, const char* filename)
{
int ret=0;
BIO *bio=NULL;
X509* x=NULL;
X509_CRL* x_crl=NULL;
int error;
bio=BIO_new_file(filename, "r");
if(bio==NULL)
{
return -1;
}
ret=0;
if(type==SSL_X509_OBJ_CERT)
{
while(NULL!=(x=PEM_read_bio_X509_AUX(bio, NULL, NULL, NULL)))
{
ret=X509_STORE_add_cert(store, x);
if(ret==0)
{
X509_free(x);
break;
}
}
}
else if(type==SSL_X509_OBJ_CRL)
{
while(NULL!=(x_crl=PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL)))
{
ret=X509_STORE_add_crl(store, x_crl);
if(ret==0)
{
X509_CRL_free(x_crl);
break;
}
}
}
if(ret==0)
{
BIO_free(bio);
return -1;
}
BIO_free(bio);
return 1;
}
static int filter_pem_fn(const struct dirent * ent)
{
const char* fn_suffix=".pem";
if(strlen(ent->d_name)< strlen(fn_suffix))
{
return 0;
}
if(0!=strcmp(ent->d_name+strlen(ent->d_name)-strlen(fn_suffix), fn_suffix))
{
return 0;
}
return 1;
}
static X509_STORE* _X509_store_create(const char* pem_bundle, const char* pem_dir)
{
int ret=0;
int ret=0, n=0, i=0;
struct dirent **namelist;
X509_STORE* store=X509_STORE_new();
char path[TFE_STRING_MAX]={0};
if (store == NULL)
{
return NULL;
@@ -55,6 +119,24 @@ static X509_STORE* _X509_store_create(const char* pem_bundle)
X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
X509_STORE_set1_param(store, param);
X509_VERIFY_PARAM_free(param);
n=tfe_scandir(pem_dir, &namelist, NULL, (int (*)(const void*, const void*))alphasort);
for(i=0;i<n;i++)
{
snprintf(path, sizeof(path), "%s/%s",pem_dir, namelist[i]->d_name);
if(0==strcasecmp(namelist[i]->d_name+strlen(namelist[i]->d_name)-strlen(".pem"), ".pem"))
{
_X509_add_cert_or_crl_add(store, SSL_X509_OBJ_CERT, path);
}
else if(0==strcasecmp(namelist[i]->d_name+strlen(namelist[i]->d_name)-strlen(".crl"), ".crl"))
{
_X509_add_cert_or_crl_add(store, SSL_X509_OBJ_CRL, path);
}
free(namelist[i]);
}
free(namelist);
return store;
}
static MESA_htable_handle _create_mesa_htable(void)
@@ -76,18 +158,18 @@ static MESA_htable_handle _create_mesa_htable(void)
ret = MESA_htable_mature(htable);
return htable;
}
struct ssl_trusted_cert_storage* ssl_trusted_cert_storage_create(const char* pem_bundle)
struct ssl_trusted_cert_storage* ssl_trusted_cert_storage_create(const char* pem_bundle, const char* pem_dir)
{
int ret=0;
struct ssl_trusted_cert_storage* storage=ALLOC(struct ssl_trusted_cert_storage, 1);
storage->effective_store=_X509_store_create(pem_bundle);
storage->effective_store=_X509_store_create(pem_bundle, pem_dir);
if (storage->effective_store == NULL)
{
return NULL;
}
storage->pem_bundle=tfe_strdup(pem_bundle);
storage->pem_dir=tfe_strdup(pem_dir);
storage->hash_table=_create_mesa_htable();
pthread_rwlock_init(&(storage->rwlock), NULL);
@@ -100,52 +182,7 @@ void ssl_trusted_cert_storage_destroy(struct ssl_trusted_cert_storage* storage)
return;
}
static int _X509_add_cert_or_crl_add(X509_STORE* store, enum ssl_X509_obj_type type, const char* filename)
{
int ret=0;
BIO *bio=NULL;
X509* x=NULL;
X509_CRL* x_crl=NULL;
int error;
bio=BIO_new_file(filename, "r");
if(bio==NULL)
{
return -1;
}
ret=0;
if(type==SSL_X509_OBJ_CERT)
{
while(NULL!=(x=PEM_read_bio_X509_AUX(bio, NULL, NULL, NULL)))
{
ret=X509_STORE_add_cert(store, x);
if(ret==0)
{
X509_free(x);
break;
}
}
}
else if(type==SSL_X509_OBJ_CRL)
{
while(NULL!=(x_crl=PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL)))
{
ret=X509_STORE_add_crl(store, x_crl);
if(ret==0)
{
X509_CRL_free(x_crl);
break;
}
}
}
if(ret==0)
{
BIO_free(bio);
return -1;
}
BIO_free(bio);
return 1;
}
int ssl_trusted_cert_storage_add(struct ssl_trusted_cert_storage* storage, enum ssl_X509_obj_type type, const char* filename)
{
@@ -198,7 +235,7 @@ int ssl_trusted_cert_storage_del(struct ssl_trusted_cert_storage* storage, enum
ret=-1;
goto error_out;
}
temp_store=_X509_store_create(storage->pem_bundle);
temp_store=_X509_store_create(storage->pem_bundle, storage->pem_dir);
MESA_htable_iterate(storage->hash_table, cert_storage_htable_traverse_cb, temp_store);
X509_STORE_free(storage->effective_store);
storage->effective_store=temp_store;
@@ -215,7 +252,7 @@ void ssl_trusted_cert_storage_reset(struct ssl_trusted_cert_storage* storage)
MESA_htable_destroy(storage->hash_table, NULL);
storage->hash_table=_create_mesa_htable();
temp_store=_X509_store_create(storage->pem_bundle);
temp_store=_X509_store_create(storage->pem_bundle, storage->pem_dir);
pthread_rwlock_wrlock(&(storage->rwlock));
X509_STORE_free(storage->effective_store);