ssl cert cleanups: round 3

fix bitmask detection and refcount more correctly


SVN revision: 50679
This commit is contained in:
Mike Blumenkrantz 2010-07-30 06:47:59 +00:00
parent 68b8380d51
commit bc39497059
1 changed files with 122 additions and 67 deletions

View File

@ -47,18 +47,29 @@ static int _client_connected = 0;
#endif #endif
#if USE_GNUTLS #if USE_GNUTLS
static gnutls_certificate_credentials_t client_cert = NULL; typedef struct _cert_thingy
static gnutls_certificate_credentials_t server_cert = NULL; {
gnutls_certificate_credentials_t cert;
int count;
} gnutls;
static gnutls *client_cert = NULL;
static gnutls *server_cert = NULL;
#elif USE_OPENSSL #elif USE_OPENSSL
static EVP_PKEY *private_key = NULL; typedef struct _cert_thingy
static int private_count = 0; {
static X509 *client_cert = NULL; X509 *cert;
static X509 *server_cert = NULL; int count;
} openssl;
typedef struct _key_thingy
{
EVP_PKEY *key;
int count;
} openssl_pkey;
static openssl_pkey *private_key = NULL;
static openssl *client_cert = NULL;
static openssl *server_cert = NULL;
#endif #endif
static int client_count = 0;
static int server_count = 0;
static Ecore_Con_Ssl_Error static Ecore_Con_Ssl_Error
SSL_SUFFIX(_ecore_con_ssl_init) (void); SSL_SUFFIX(_ecore_con_ssl_init) (void);
static Ecore_Con_Ssl_Error static Ecore_Con_Ssl_Error
@ -122,10 +133,17 @@ ecore_con_ssl_shutdown(void)
{ {
if (!--_init_con_ssl_init_count) if (!--_init_con_ssl_init_count)
{ {
client_count = 0; #if USE_OPENSSL || USE_GNUTLS
server_count = 0; if (client_cert)
client_cert->count = 0;
if (server_cert)
server_cert->count = 0;
#endif
#if USE_OPENSSL && !USE_GNUTLS #if USE_OPENSSL && !USE_GNUTLS
private_count = 0; if (private_key)
private_key->count = 0;
#endif #endif
SSL_SUFFIX(_ecore_con_ssl_shutdown) (); SSL_SUFFIX(_ecore_con_ssl_shutdown) ();
} }
@ -294,10 +312,11 @@ _ecore_con_ssl_server_init_gnutls(Ecore_Con_Server *svr)
return ECORE_CON_SSL_ERROR_NONE; return ECORE_CON_SSL_ERROR_NONE;
} }
if (server_cert && (svr->type & ECORE_CON_LOAD_CERT)) if ((server_cert) && (server_cert->cert) &&
((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOAD_CERT))
{ {
svr->cert = server_cert; svr->cert = server_cert->cert;
server_count++; server_cert->count++;
} }
gnutls_init(&(svr->session), GNUTLS_CLIENT); gnutls_init(&(svr->session), GNUTLS_CLIENT);
@ -341,12 +360,17 @@ _ecore_con_ssl_server_cert_add_gnutls(const char *cert_file)
GNUTLS_X509_FMT_PEM) < 0) GNUTLS_X509_FMT_PEM) < 0)
goto on_error; goto on_error;
gnutls_certificate_free_credentials(cert); if (!server_cert)
if ((server_cert) && ((--server_count) < 1)) {
gnutls_certificate_free_credentials(server_cert); server_cert = malloc(sizeof(gnutls));
if (!server_cert)
return EINA_FALSE;
}
else if ((server_cert->cert) && ((--server_cert->count) < 1))
gnutls_certificate_free_credentials(server_cert->cert);
server_cert = cert; server_cert->cert = cert;
server_count = 1; server_cert->count = 1;
return EINA_TRUE; return EINA_TRUE;
@ -366,10 +390,12 @@ _ecore_con_ssl_server_shutdown_gnutls(Ecore_Con_Server *svr)
gnutls_deinit(svr->session); gnutls_deinit(svr->session);
} }
if ((svr->type & ECORE_CON_LOAD_CERT) && (server_cert) && if (((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOAD_CERT) &&
(--server_count < 1)) (server_cert) &&
(server_cert->cert) && (--server_cert->count < 1))
{ {
gnutls_certificate_free_credentials(server_cert); gnutls_certificate_free_credentials(server_cert->cert);
free(server_cert);
server_cert = NULL; server_cert = NULL;
} }
else if (svr->anoncred_c) else if (svr->anoncred_c)
@ -473,10 +499,11 @@ _ecore_con_ssl_client_init_gnutls(Ecore_Con_Client *cl)
gnutls_dh_params_init(&dh_params); gnutls_dh_params_init(&dh_params);
gnutls_dh_params_generate2(dh_params, 1024); gnutls_dh_params_generate2(dh_params, 1024);
if (client_cert && (cl->server->type & ECORE_CON_LOAD_CERT)) if ((client_cert) && (client_cert->cert) &&
((cl->server->type & ECORE_CON_TYPE) == ECORE_CON_LOAD_CERT))
{ {
cl->server->cert = client_cert; cl->server->cert = client_cert->cert;
client_count++; client_cert->count++;
gnutls_certificate_set_dh_params(cl->server->cert, dh_params); gnutls_certificate_set_dh_params(cl->server->cert, dh_params);
} }
@ -531,10 +558,12 @@ _ecore_con_ssl_client_shutdown_gnutls(Ecore_Con_Client *cl)
if (cl->server->anoncred_s && !--_client_connected) if (cl->server->anoncred_s && !--_client_connected)
gnutls_anon_free_server_credentials(cl->server->anoncred_s); gnutls_anon_free_server_credentials(cl->server->anoncred_s);
if ((cl->server->type & ECORE_CON_LOAD_CERT) && (client_cert) && if (((cl->server->type & ECORE_CON_TYPE) == ECORE_CON_LOAD_CERT) &&
(--client_count < 1)) (client_cert) &&
(client_cert->cert) && (--client_cert->count < 1))
{ {
gnutls_certificate_free_credentials(client_cert); gnutls_certificate_free_credentials(client_cert->cert);
free(client_cert);
client_cert = NULL; client_cert = NULL;
} }
@ -573,12 +602,17 @@ _ecore_con_ssl_client_cert_add_gnutls(const char *cert_file,
} }
#endif #endif
if (!client_cert)
{
client_cert = malloc(sizeof(gnutls));
if (!client_cert)
return EINA_FALSE;
}
else if ((client_cert->cert) && ((--client_cert->count) < 1))
gnutls_certificate_free_credentials(client_cert->cert);
if ((client_cert) && ((--client_count) < 1)) client_cert->cert = cert;
gnutls_certificate_free_credentials(client_cert); client_cert->count = 1;
client_cert = cert;
client_count = 1;
return EINA_TRUE; return EINA_TRUE;
@ -694,14 +728,15 @@ _ecore_con_ssl_server_init_openssl(Ecore_Con_Server *svr)
return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED; return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
} }
if (server_cert && (svr->type & ECORE_CON_LOAD_CERT)) if ((server_cert) && (server_cert->cert) &&
((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOAD_CERT))
{ {
//FIXME: just log and go on without cert if loading fails? //FIXME: just log and go on without cert if loading fails?
if (!SSL_CTX_use_certificate(svr->ssl_ctx, server_cert)) if (!SSL_CTX_use_certificate(svr->ssl_ctx, server_cert->cert))
ERR( ERR(
"ssl cert load failed: %s", ERR_reason_error_string(ERR_get_error())); "ssl cert load failed: %s", ERR_reason_error_string(ERR_get_error()));
server_count++; server_cert->count++;
} }
SSL_set_fd(svr->ssl, svr->fd); SSL_set_fd(svr->ssl, svr->fd);
@ -723,13 +758,18 @@ _ecore_con_ssl_server_cert_add_openssl(const char *cert_file)
fclose(fp); fclose(fp);
if (!server_cert)
{
server_cert = malloc(sizeof(openssl));
if (!server_cert)
return EINA_FALSE;
}
else if ((server_cert->cert) && ((--server_cert->count) < 1))
X509_free(server_cert->cert);
if ((server_cert) && (--server_count < 1)) server_cert->cert = cert;
X509_free(server_cert);
server_cert = cert; server_cert->count = 1;
server_count = 1;
return EINA_TRUE; return EINA_TRUE;
@ -751,10 +791,12 @@ _ecore_con_ssl_server_shutdown_openssl(Ecore_Con_Server *svr)
SSL_free(svr->ssl); SSL_free(svr->ssl);
} }
if ((svr->type & ECORE_CON_LOAD_CERT) && (server_cert) && if (((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOAD_CERT) &&
(--server_count < 1)) (server_cert) && (server_cert->cert) &&
(--server_cert->count < 1))
{ {
X509_free(server_cert); X509_free(server_cert->cert);
free(server_cert);
server_cert = NULL; server_cert = NULL;
} }
@ -917,18 +959,18 @@ _ecore_con_ssl_client_init_openssl(Ecore_Con_Client *cl)
return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED; return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
} }
if ((client_cert) && (private_key) && if ((client_cert) && (client_cert->cert) && (private_key->key) &&
(cl->server->type & ECORE_CON_LOAD_CERT)) ((cl->server->type & ECORE_CON_TYPE) == ECORE_CON_LOAD_CERT))
{ {
//FIXME: just log and go on without cert if loading fails? //FIXME: just log and go on without cert if loading fails?
if (!SSL_CTX_use_certificate(cl->server->ssl_ctx, client_cert) || if (!SSL_CTX_use_certificate(cl->server->ssl_ctx, client_cert->cert) ||
!SSL_CTX_use_PrivateKey(cl->server->ssl_ctx, private_key) || !SSL_CTX_use_PrivateKey(cl->server->ssl_ctx, private_key->key) ||
!SSL_CTX_check_private_key(cl->server->ssl_ctx)) !SSL_CTX_check_private_key(cl->server->ssl_ctx))
ERR( ERR(
"ssl cert load failed: %s", ERR_reason_error_string(ERR_get_error())); "ssl cert load failed: %s", ERR_reason_error_string(ERR_get_error()));
client_count++; client_cert->count++;
private_count++; private_key->count++;
} }
SSL_set_fd(cl->ssl, cl->fd); SSL_set_fd(cl->ssl, cl->fd);
@ -964,16 +1006,27 @@ _ecore_con_ssl_client_cert_add_openssl(const char *cert_file,
fclose(fp); fclose(fp);
if ((client_cert) && (--client_count < 1)) if (!client_cert)
X509_free(client_cert); {
client_cert = malloc(sizeof(openssl));
if (!client_cert)
return EINA_FALSE;
}
else if ((client_cert->cert) && (--client_cert->count < 1))
X509_free(client_cert->cert);
if ((private_key) && ((--private_count) < 1)) if (!private_key)
EVP_PKEY_free(private_key); {
private_key = malloc(sizeof(openssl_pkey));
if (!private_key) return EINA_FALSE;
}
else if ((private_key->key) && ((--private_key->count) < 1))
EVP_PKEY_free(private_key->key);
private_key = privkey; private_key->key = privkey;
client_cert = cert; client_cert->cert = cert;
private_count = client_count = 1; private_key->count = client_cert->count = 1;
return EINA_TRUE; return EINA_TRUE;
@ -1004,17 +1057,19 @@ _ecore_con_ssl_client_shutdown_openssl(Ecore_Con_Client *cl)
if (cl->ssl_ctx) if (cl->ssl_ctx)
{ {
SSL_CTX_free(cl->ssl_ctx); SSL_CTX_free(cl->ssl_ctx);
if ((cl->server->type & ECORE_CON_LOAD_CERT) && (client_cert) && if (((cl->server->type & ECORE_CON_TYPE) == ECORE_CON_LOAD_CERT) &&
(--client_count < 1)) (client_cert) && (client_cert->cert) && (--client_cert->count < 1))
{ {
X509_free(client_cert); X509_free(client_cert->cert);
free(client_cert);
client_cert = NULL; client_cert = NULL;
} }
if ((cl->server->type & ECORE_CON_LOAD_CERT) && (private_key) && if (((cl->server->type & ECORE_CON_TYPE) == ECORE_CON_LOAD_CERT) &&
(--private_count < 1)) (private_key) && (private_key->key) && (--private_key->count < 1))
{ {
EVP_PKEY_free(private_key); EVP_PKEY_free(private_key->key);
free(private_key);
private_key = NULL; private_key = NULL;
} }
} }
@ -1169,10 +1224,10 @@ _ecore_con_ssl_client_init_none(Ecore_Con_Client *cl)
static Eina_Bool static Eina_Bool
_ecore_con_ssl_client_cert_add_none(const char *cert_file, _ecore_con_ssl_client_cert_add_none(const char *cert_file,
const char *crl_file, const char *crl_file,
const char *key_file) const char *key_file)
{ {
return EINA_TRUE; return EINA_TRUE;
} }
static Ecore_Con_Ssl_Error static Ecore_Con_Ssl_Error