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) | ||||
| 	{ | ||||
| #ifdef SSL_USE_OPENSSL | ||||
| 		hub->ssl_method = (SSL_METHOD*) SSLv23_method(); /* TLSv1_method() */ | ||||
| 		hub->ssl_ctx = SSL_CTX_new(hub->ssl_method); | ||||
| 
 | ||||
| 		/* 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) | ||||
| 		hub->ctx = net_ssl_context_create(); | ||||
| 		if (ssl_load_certificate(hub->ctx, config->tls_certificate) && | ||||
| 			ssl_load_private_key(hub->ctx, config->tls_private_key) && | ||||
| 			ssl_check_private_key(hub->ctx)) | ||||
| 		{ | ||||
| 			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; | ||||
| 		} | ||||
| 
 | ||||
| 		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 0; | ||||
| 	} | ||||
| 	return 1; | ||||
| } | ||||
| 
 | ||||
| static void unload_ssl_certificates(struct hub_info* hub) | ||||
| { | ||||
| #ifdef SSL_USE_OPENSSL | ||||
| 	if (hub->ssl_ctx) | ||||
| 	{ | ||||
| 		SSL_CTX_free(hub->ssl_ctx); | ||||
| 	} | ||||
| #endif /* SSL_USE_OPENSSL */ | ||||
| 	if (hub->ctx) | ||||
| 		net_ssl_context_destroy(hub->ctx); | ||||
| } | ||||
| #endif /* SSL_SUPPORT */ | ||||
| 
 | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * 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. */ | ||||
| 
 | ||||
| #ifdef SSL_SUPPORT | ||||
| #ifdef SSL_USE_OPENSSL | ||||
| 	SSL_METHOD* ssl_method; | ||||
| 	SSL_CTX* ssl_ctx; | ||||
| #endif // SSL_USE_OPENSSL
 | ||||
| 	struct ssl_context_handle* ctx; | ||||
| #endif /*  SSL_SUPPORT */ | ||||
| }; | ||||
| 
 | ||||
|  | ||||
| @ -85,9 +85,7 @@ static void probe_net_event(struct net_connection* con, int events, void *arg) | ||||
| 					{ | ||||
| 						probe->connection = 0; | ||||
| 					} | ||||
| #ifdef SSL_USE_OPENSSL | ||||
| 					net_con_ssl_handshake(con, net_con_ssl_mode_server, probe->hub->ssl_ctx); | ||||
| #endif /* SSL_USE_OPENSSL */ | ||||
| 					net_con_ssl_handshake(con, net_con_ssl_mode_server, probe->hub->ctx); | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
|  | ||||
| @ -24,18 +24,90 @@ | ||||
| #ifdef SSL_SUPPORT | ||||
| #ifdef SSL_USE_OPENSSL | ||||
| 
 | ||||
| #define NETWORK_DUMP_DEBUG | ||||
| 
 | ||||
| struct net_ssl_openssl | ||||
| { | ||||
| 	SSL* ssl; | ||||
| 	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) | ||||
| { | ||||
| 	uhub_assert(con); | ||||
| 	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) | ||||
| { | ||||
| 	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; | ||||
| 	handle->state = tls_st_connecting; | ||||
| 
 | ||||
| 
 | ||||
| 	ret = SSL_connect(handle->ssl); | ||||
| #ifdef NETWORK_DUMP_DEBUG | ||||
| 	LOG_PROTO("SSL_connect() ret=%d", ret); | ||||
| #endif /* NETWORK_DUMP_DEBUG */ | ||||
| 
 | ||||
| 	if (ret > 0) | ||||
| 	{ | ||||
| 		handle->state = tls_st_connected; | ||||
| @ -119,15 +193,16 @@ ssize_t net_con_ssl_connect(struct net_connection* con) | ||||
| 	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); | ||||
| 
 | ||||
| 	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)); | ||||
| 
 | ||||
| 	if (ssl_mode == net_con_ssl_mode_server) | ||||
| 	{ | ||||
| 		handle->ssl = SSL_new(ssl_ctx); | ||||
| 		handle->ssl = SSL_new(ctx->ssl_ctx); | ||||
| 		if (!handle->ssl) | ||||
| 		{ | ||||
| 			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) | ||||
| { | ||||
| 	struct net_ssl_openssl* handle = get_handle(con); | ||||
| 
 | ||||
| 	int ret; | ||||
| 	uint32_t flags = con->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; | ||||
| 
 | ||||
| 		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); | ||||
| 			} | ||||
| 			break; | ||||
| 
 | ||||
| 		case tls_st_connected: | ||||
|  | ||||
| @ -41,6 +41,33 @@ enum net_con_ssl_mode | ||||
| 	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() | ||||
| @ -60,9 +87,10 @@ extern void net_ssl_destroy(struct net_connection* con); | ||||
| 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); | ||||
| #ifdef SSL_USE_OPENSSL | ||||
| extern void net_con_set_ssl(struct net_connection* con, SSL*); | ||||
| #endif // SSL_USE_OPENSSL
 | ||||
| extern int   net_con_is_ssl(struct net_connection* con); | ||||
|  | ||||
| @ -65,12 +65,6 @@ struct ADC_client | ||||
| 	char* desc; | ||||
| 	int flags; | ||||
| 	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; | ||||
| 
 | ||||
| 	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); | ||||
| #if 0 | ||||
| 	/* FIXME */ | ||||
| 	net_timer_initialize(client->timer, timer_callback, client); | ||||
| #endif | ||||
| 	ADC_client_set_state(client, ps_none); | ||||
| 
 | ||||
| 	client->nick = hub_strdup(nickname); | ||||
| @ -549,10 +535,6 @@ void ADC_client_destroy(struct ADC_client* client) | ||||
| { | ||||
| 	ADC_TRACE; | ||||
| 	ADC_client_disconnect(client); | ||||
| #if 0 | ||||
| 	/* FIXME */ | ||||
| 	net_timer_shutdown(client->timer); | ||||
| #endif | ||||
| 	ioq_send_destroy(client->send_queue); | ||||
| 	ioq_recv_destroy(client->recv_queue); | ||||
| 	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); | ||||
| 		client->callback(client, ADC_CLIENT_SSL_HANDSHAKE, 0); | ||||
| 		ADC_client_set_state(client, ps_conn_ssl); | ||||
| 
 | ||||
| 		net_con_ssl_handshake(client->con, net_con_ssl_mode_client, NULL); | ||||
| 	} | ||||
| 	else | ||||
| #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) | ||||
| { | ||||
| 	ADC_TRACE; | ||||
| 	net_con_update(client->con, NET_EVENT_READ); | ||||
| 	client->callback(client, ADC_CLIENT_SSL_OK, 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_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) | ||||
| { | ||||
| 	return client->ptr; | ||||
| } | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user