More work on splitting out OpenSSL specific bits.
This commit is contained in:
parent
f3922bb3e0
commit
50912bdf75
|
@ -731,43 +731,23 @@ static int load_ssl_certificates(struct hub_info* hub, struct hub_config* config
|
||||||
{
|
{
|
||||||
if (config->tls_enable)
|
if (config->tls_enable)
|
||||||
{
|
{
|
||||||
#ifdef SSL_USE_OPENSSL
|
hub->ctx = net_ssl_context_create();
|
||||||
hub->ssl_method = (SSL_METHOD*) SSLv23_method(); /* TLSv1_method() */
|
if (ssl_load_certificate(hub->ctx, config->tls_certificate) &&
|
||||||
hub->ssl_ctx = SSL_CTX_new(hub->ssl_method);
|
ssl_load_private_key(hub->ctx, config->tls_private_key) &&
|
||||||
|
ssl_check_private_key(hub->ctx))
|
||||||
/* Disable SSLv2 */
|
|
||||||
SSL_CTX_set_options(hub->ssl_ctx, SSL_OP_NO_SSLv2);
|
|
||||||
SSL_CTX_set_quiet_shutdown(hub->ssl_ctx, 1);
|
|
||||||
|
|
||||||
if (SSL_CTX_use_certificate_file(hub->ssl_ctx, config->tls_certificate, SSL_FILETYPE_PEM) < 0)
|
|
||||||
{
|
{
|
||||||
LOG_ERROR("SSL_CTX_use_certificate_file: %s", ERR_error_string(ERR_get_error(), NULL));
|
LOG_INFO("Enabling TLS (%s), using certificate: %s, private key: %s", net_ssl_get_provider(), config->tls_certificate, config->tls_private_key);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
if (SSL_CTX_use_PrivateKey_file(hub->ssl_ctx, config->tls_private_key, SSL_FILETYPE_PEM) < 0)
|
|
||||||
{
|
|
||||||
LOG_ERROR("SSL_CTX_use_PrivateKey_file: %s", ERR_error_string(ERR_get_error(), NULL));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SSL_CTX_check_private_key(hub->ssl_ctx) != 1)
|
|
||||||
{
|
|
||||||
LOG_FATAL("SSL_CTX_check_private_key: Private key does not match the certificate public key: %s", ERR_error_string(ERR_get_error(), NULL));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
LOG_INFO("Enabling TLS, using certificate: %s, private key: %s", config->tls_certificate, config->tls_private_key);
|
|
||||||
#endif /* SSL_USE_OPENSSL */
|
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void unload_ssl_certificates(struct hub_info* hub)
|
static void unload_ssl_certificates(struct hub_info* hub)
|
||||||
{
|
{
|
||||||
#ifdef SSL_USE_OPENSSL
|
if (hub->ctx)
|
||||||
if (hub->ssl_ctx)
|
net_ssl_context_destroy(hub->ctx);
|
||||||
{
|
|
||||||
SSL_CTX_free(hub->ssl_ctx);
|
|
||||||
}
|
|
||||||
#endif /* SSL_USE_OPENSSL */
|
|
||||||
}
|
}
|
||||||
#endif /* SSL_SUPPORT */
|
#endif /* SSL_SUPPORT */
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2011, Jan Vidar Krey
|
* Copyright (C) 2007-2012, Jan Vidar Krey
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -116,10 +116,7 @@ struct hub_info
|
||||||
struct uhub_plugins* plugins; /* Plug-ins loaded for this hub instance. */
|
struct uhub_plugins* plugins; /* Plug-ins loaded for this hub instance. */
|
||||||
|
|
||||||
#ifdef SSL_SUPPORT
|
#ifdef SSL_SUPPORT
|
||||||
#ifdef SSL_USE_OPENSSL
|
struct ssl_context_handle* ctx;
|
||||||
SSL_METHOD* ssl_method;
|
|
||||||
SSL_CTX* ssl_ctx;
|
|
||||||
#endif // SSL_USE_OPENSSL
|
|
||||||
#endif /* SSL_SUPPORT */
|
#endif /* SSL_SUPPORT */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -85,9 +85,7 @@ static void probe_net_event(struct net_connection* con, int events, void *arg)
|
||||||
{
|
{
|
||||||
probe->connection = 0;
|
probe->connection = 0;
|
||||||
}
|
}
|
||||||
#ifdef SSL_USE_OPENSSL
|
net_con_ssl_handshake(con, net_con_ssl_mode_server, probe->hub->ctx);
|
||||||
net_con_ssl_handshake(con, net_con_ssl_mode_server, probe->hub->ssl_ctx);
|
|
||||||
#endif /* SSL_USE_OPENSSL */
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -24,18 +24,90 @@
|
||||||
#ifdef SSL_SUPPORT
|
#ifdef SSL_SUPPORT
|
||||||
#ifdef SSL_USE_OPENSSL
|
#ifdef SSL_USE_OPENSSL
|
||||||
|
|
||||||
|
#define NETWORK_DUMP_DEBUG
|
||||||
|
|
||||||
struct net_ssl_openssl
|
struct net_ssl_openssl
|
||||||
{
|
{
|
||||||
SSL* ssl;
|
SSL* ssl;
|
||||||
enum ssl_state state;
|
enum ssl_state state;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct net_context_openssl
|
||||||
|
{
|
||||||
|
SSL_METHOD* ssl_method;
|
||||||
|
SSL_CTX* ssl_ctx;
|
||||||
|
};
|
||||||
|
|
||||||
static struct net_ssl_openssl* get_handle(struct net_connection* con)
|
static struct net_ssl_openssl* get_handle(struct net_connection* con)
|
||||||
{
|
{
|
||||||
uhub_assert(con);
|
uhub_assert(con);
|
||||||
return (struct net_ssl_openssl*) con->ssl;
|
return (struct net_ssl_openssl*) con->ssl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* net_ssl_get_provider()
|
||||||
|
{
|
||||||
|
return OPENSSL_VERSION_TEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new SSL context.
|
||||||
|
*/
|
||||||
|
struct ssl_context_handle* net_ssl_context_create()
|
||||||
|
{
|
||||||
|
|
||||||
|
struct net_context_openssl* ctx = (struct net_context_openssl*) hub_malloc_zero(sizeof(struct net_context_openssl));
|
||||||
|
ctx->ssl_method = (SSL_METHOD*) SSLv23_method(); /* TLSv1_method() */
|
||||||
|
ctx->ssl_ctx = SSL_CTX_new(ctx->ssl_method);
|
||||||
|
|
||||||
|
/* Disable SSLv2 */
|
||||||
|
SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_SSLv2);
|
||||||
|
SSL_CTX_set_quiet_shutdown(ctx->ssl_ctx, 1);
|
||||||
|
|
||||||
|
return (struct ssl_context_handle*) ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern void net_ssl_context_destroy(struct ssl_context_handle* ctx_)
|
||||||
|
{
|
||||||
|
struct net_context_openssl* ctx = (struct net_context_openssl*) ctx_;
|
||||||
|
SSL_CTX_free(ctx->ssl_ctx);
|
||||||
|
hub_free(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ssl_load_certificate(struct ssl_context_handle* ctx_, const char* pem_file)
|
||||||
|
{
|
||||||
|
struct net_context_openssl* ctx = (struct net_context_openssl*) ctx_;
|
||||||
|
if (SSL_CTX_use_certificate_file(ctx->ssl_ctx, pem_file, SSL_FILETYPE_PEM) < 0)
|
||||||
|
{
|
||||||
|
LOG_ERROR("SSL_CTX_use_certificate_file: %s", ERR_error_string(ERR_get_error(), NULL));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ssl_load_private_key(struct ssl_context_handle* ctx_, const char* pem_file)
|
||||||
|
{
|
||||||
|
struct net_context_openssl* ctx = (struct net_context_openssl*) ctx_;
|
||||||
|
if (SSL_CTX_use_PrivateKey_file(ctx->ssl_ctx, pem_file, SSL_FILETYPE_PEM) < 0)
|
||||||
|
{
|
||||||
|
LOG_ERROR("SSL_CTX_use_PrivateKey_file: %s", ERR_error_string(ERR_get_error(), NULL));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ssl_check_private_key(struct ssl_context_handle* ctx_)
|
||||||
|
{
|
||||||
|
struct net_context_openssl* ctx = (struct net_context_openssl*) ctx_;
|
||||||
|
if (SSL_CTX_check_private_key(ctx->ssl_ctx) != 1)
|
||||||
|
{
|
||||||
|
LOG_FATAL("SSL_CTX_check_private_key: Private key does not match the certificate public key: %s", ERR_error_string(ERR_get_error(), NULL));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int handle_openssl_error(struct net_connection* con, int ret)
|
static int handle_openssl_error(struct net_connection* con, int ret)
|
||||||
{
|
{
|
||||||
struct net_ssl_openssl* handle = get_handle(con);
|
struct net_ssl_openssl* handle = get_handle(con);
|
||||||
|
@ -103,10 +175,12 @@ ssize_t net_con_ssl_connect(struct net_connection* con)
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
handle->state = tls_st_connecting;
|
handle->state = tls_st_connecting;
|
||||||
|
|
||||||
|
|
||||||
ret = SSL_connect(handle->ssl);
|
ret = SSL_connect(handle->ssl);
|
||||||
#ifdef NETWORK_DUMP_DEBUG
|
#ifdef NETWORK_DUMP_DEBUG
|
||||||
LOG_PROTO("SSL_connect() ret=%d", ret);
|
LOG_PROTO("SSL_connect() ret=%d", ret);
|
||||||
#endif /* NETWORK_DUMP_DEBUG */
|
#endif /* NETWORK_DUMP_DEBUG */
|
||||||
|
|
||||||
if (ret > 0)
|
if (ret > 0)
|
||||||
{
|
{
|
||||||
handle->state = tls_st_connected;
|
handle->state = tls_st_connected;
|
||||||
|
@ -119,15 +193,16 @@ ssize_t net_con_ssl_connect(struct net_connection* con)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t net_con_ssl_handshake(struct net_connection* con, enum net_con_ssl_mode ssl_mode, SSL_CTX* ssl_ctx)
|
ssize_t net_con_ssl_handshake(struct net_connection* con, enum net_con_ssl_mode ssl_mode, struct ssl_context_handle* ssl_ctx)
|
||||||
{
|
{
|
||||||
uhub_assert(con);
|
uhub_assert(con);
|
||||||
|
|
||||||
|
struct net_context_openssl* ctx = (struct net_context_openssl*) ssl_ctx;
|
||||||
struct net_ssl_openssl* handle = (struct net_ssl_openssl*) hub_malloc_zero(sizeof(struct net_ssl_openssl));
|
struct net_ssl_openssl* handle = (struct net_ssl_openssl*) hub_malloc_zero(sizeof(struct net_ssl_openssl));
|
||||||
|
|
||||||
if (ssl_mode == net_con_ssl_mode_server)
|
if (ssl_mode == net_con_ssl_mode_server)
|
||||||
{
|
{
|
||||||
handle->ssl = SSL_new(ssl_ctx);
|
handle->ssl = SSL_new(ctx->ssl_ctx);
|
||||||
if (!handle->ssl)
|
if (!handle->ssl)
|
||||||
{
|
{
|
||||||
LOG_ERROR("Unable to create new SSL stream\n");
|
LOG_ERROR("Unable to create new SSL stream\n");
|
||||||
|
@ -197,7 +272,7 @@ void net_ssl_destroy(struct net_connection* con)
|
||||||
void net_ssl_callback(struct net_connection* con, int events)
|
void net_ssl_callback(struct net_connection* con, int events)
|
||||||
{
|
{
|
||||||
struct net_ssl_openssl* handle = get_handle(con);
|
struct net_ssl_openssl* handle = get_handle(con);
|
||||||
|
int ret;
|
||||||
uint32_t flags = con->flags;
|
uint32_t flags = con->flags;
|
||||||
con->flags &= ~NET_SSL_ANY; /* reset the SSL related flags */
|
con->flags &= ~NET_SSL_ANY; /* reset the SSL related flags */
|
||||||
|
|
||||||
|
@ -219,10 +294,9 @@ void net_ssl_callback(struct net_connection* con, int events)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case tls_st_connecting:
|
case tls_st_connecting:
|
||||||
if (net_con_ssl_connect(con) < 0)
|
ret = net_con_ssl_connect(con);
|
||||||
{
|
if (ret != 0)
|
||||||
con->callback(con, NET_EVENT_READ, con->ptr);
|
con->callback(con, NET_EVENT_READ, con->ptr);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case tls_st_connected:
|
case tls_st_connected:
|
||||||
|
|
|
@ -41,6 +41,33 @@ enum net_con_ssl_mode
|
||||||
net_con_ssl_mode_client,
|
net_con_ssl_mode_client,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ssl_context_handle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a string describing the TLS/SSL provider information
|
||||||
|
*/
|
||||||
|
extern const char* net_ssl_get_provider();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new SSL context.
|
||||||
|
*/
|
||||||
|
extern struct ssl_context_handle* net_ssl_context_create();
|
||||||
|
extern void net_ssl_context_destroy(struct ssl_context_handle* ctx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return 0 on error, 1 otherwise.
|
||||||
|
*/
|
||||||
|
extern int ssl_load_certificate(struct ssl_context_handle* ctx, const char* pem_file);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return 0 on error, 1 otherwise.
|
||||||
|
*/
|
||||||
|
extern int ssl_load_private_key(struct ssl_context_handle* ctx, const char* pem_file);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return 0 if private key does not match certificate, 1 if everything is OK.
|
||||||
|
*/
|
||||||
|
extern int ssl_check_private_key(struct ssl_context_handle* ctx);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start SSL_accept()
|
* Start SSL_accept()
|
||||||
|
@ -60,9 +87,10 @@ extern void net_ssl_destroy(struct net_connection* con);
|
||||||
extern void net_ssl_callback(struct net_connection* con, int events);
|
extern void net_ssl_callback(struct net_connection* con, int events);
|
||||||
|
|
||||||
|
|
||||||
#ifdef SSL_USE_OPENSSL
|
|
||||||
extern ssize_t net_con_ssl_handshake(struct net_connection* con, enum net_con_ssl_mode, SSL_CTX* ssl_ctx);
|
extern ssize_t net_con_ssl_handshake(struct net_connection* con, enum net_con_ssl_mode, struct ssl_context_handle* ssl_ctx);
|
||||||
extern SSL* net_con_get_ssl(struct net_connection* con);
|
extern SSL* net_con_get_ssl(struct net_connection* con);
|
||||||
|
#ifdef SSL_USE_OPENSSL
|
||||||
extern void net_con_set_ssl(struct net_connection* con, SSL*);
|
extern void net_con_set_ssl(struct net_connection* con, SSL*);
|
||||||
#endif // SSL_USE_OPENSSL
|
#endif // SSL_USE_OPENSSL
|
||||||
extern int net_con_is_ssl(struct net_connection* con);
|
extern int net_con_is_ssl(struct net_connection* con);
|
||||||
|
|
|
@ -65,12 +65,6 @@ struct ADC_client
|
||||||
char* desc;
|
char* desc;
|
||||||
int flags;
|
int flags;
|
||||||
void* ptr;
|
void* ptr;
|
||||||
#ifdef SSL_SUPPORT
|
|
||||||
#ifdef SSL_USE_OPENSSL
|
|
||||||
const SSL_METHOD* ssl_method;
|
|
||||||
SSL_CTX* ssl_ctx;
|
|
||||||
#endif /* SSL_USE_OPENSSL */
|
|
||||||
#endif /* SSL_SUPPORT */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -524,15 +518,7 @@ struct ADC_client* ADC_client_create(const char* nickname, const char* descripti
|
||||||
if (sd == -1) return NULL;
|
if (sd == -1) return NULL;
|
||||||
|
|
||||||
client->con = net_con_create();
|
client->con = net_con_create();
|
||||||
#if 0
|
|
||||||
/* FIXME */
|
|
||||||
client->timer = 0; /* FIXME: hub_malloc(sizeof(struct net_timer)); */
|
|
||||||
#endif
|
|
||||||
net_con_initialize(client->con, sd, event_callback, client, 0);
|
net_con_initialize(client->con, sd, event_callback, client, 0);
|
||||||
#if 0
|
|
||||||
/* FIXME */
|
|
||||||
net_timer_initialize(client->timer, timer_callback, client);
|
|
||||||
#endif
|
|
||||||
ADC_client_set_state(client, ps_none);
|
ADC_client_set_state(client, ps_none);
|
||||||
|
|
||||||
client->nick = hub_strdup(nickname);
|
client->nick = hub_strdup(nickname);
|
||||||
|
@ -549,10 +535,6 @@ void ADC_client_destroy(struct ADC_client* client)
|
||||||
{
|
{
|
||||||
ADC_TRACE;
|
ADC_TRACE;
|
||||||
ADC_client_disconnect(client);
|
ADC_client_disconnect(client);
|
||||||
#if 0
|
|
||||||
/* FIXME */
|
|
||||||
net_timer_shutdown(client->timer);
|
|
||||||
#endif
|
|
||||||
ioq_send_destroy(client->send_queue);
|
ioq_send_destroy(client->send_queue);
|
||||||
ioq_recv_destroy(client->recv_queue);
|
ioq_recv_destroy(client->recv_queue);
|
||||||
hub_free(client->timer);
|
hub_free(client->timer);
|
||||||
|
@ -600,6 +582,8 @@ static void ADC_client_on_connected(struct ADC_client* client)
|
||||||
net_con_update(client->con, NET_EVENT_READ | NET_EVENT_WRITE);
|
net_con_update(client->con, NET_EVENT_READ | NET_EVENT_WRITE);
|
||||||
client->callback(client, ADC_CLIENT_SSL_HANDSHAKE, 0);
|
client->callback(client, ADC_CLIENT_SSL_HANDSHAKE, 0);
|
||||||
ADC_client_set_state(client, ps_conn_ssl);
|
ADC_client_set_state(client, ps_conn_ssl);
|
||||||
|
|
||||||
|
net_con_ssl_handshake(client->con, net_con_ssl_mode_client, NULL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
|
@ -615,9 +599,9 @@ static void ADC_client_on_connected(struct ADC_client* client)
|
||||||
static void ADC_client_on_connected_ssl(struct ADC_client* client)
|
static void ADC_client_on_connected_ssl(struct ADC_client* client)
|
||||||
{
|
{
|
||||||
ADC_TRACE;
|
ADC_TRACE;
|
||||||
net_con_update(client->con, NET_EVENT_READ);
|
|
||||||
client->callback(client, ADC_CLIENT_SSL_OK, 0);
|
client->callback(client, ADC_CLIENT_SSL_OK, 0);
|
||||||
client->callback(client, ADC_CLIENT_CONNECTED, 0);
|
client->callback(client, ADC_CLIENT_CONNECTED, 0);
|
||||||
|
net_con_update(client->con, NET_EVENT_READ);
|
||||||
ADC_client_send(client, adc_msg_create(ADC_HANDSHAKE));
|
ADC_client_send(client, adc_msg_create(ADC_HANDSHAKE));
|
||||||
ADC_client_set_state(client, ps_protocol);
|
ADC_client_set_state(client, ps_protocol);
|
||||||
}
|
}
|
||||||
|
@ -729,4 +713,4 @@ const char* ADC_client_get_description(const struct ADC_client* client)
|
||||||
void* ADC_client_get_ptr(const struct ADC_client* client)
|
void* ADC_client_get_ptr(const struct ADC_client* client)
|
||||||
{
|
{
|
||||||
return client->ptr;
|
return client->ptr;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue