GNUTLS: Rework rb_init_ssl() and rb_setup_ssl_server()

I did my best to remove all possible memory leaks in the latter.
It's ugly.
This commit is contained in:
Aaron Jones 2016-09-16 20:28:16 +00:00
parent 2d01971d05
commit d70129a0d6
No known key found for this signature in database
GPG key ID: EC6F86EE9CD840B5

View file

@ -339,17 +339,9 @@ rb_init_ssl(void)
rb_lib_log("%s: gnutls_global_init: %s", __func__, gnutls_strerror(ret)); rb_lib_log("%s: gnutls_global_init: %s", __func__, gnutls_strerror(ret));
return 0; return 0;
} }
if((ret = gnutls_certificate_allocate_credentials(&server_cert_key)) != GNUTLS_E_SUCCESS)
{
rb_lib_log("%s: gnutls_certificate_allocate_credentials: %s", __func__, gnutls_strerror(ret));
return 0;
}
#if (GNUTLS_VERSION_MAJOR < 3) #if (GNUTLS_VERSION_MAJOR < 3)
rb_event_addish("rb_gcry_random_seed", rb_gcry_random_seed, NULL, 300); rb_event_addish("rb_gcry_random_seed", rb_gcry_random_seed, NULL, 300);
gnutls_certificate_client_set_retrieve_function(server_cert_key, rb_ssl_cert_auth_cb);
#else
gnutls_certificate_set_retrieve_function(server_cert_key, rb_ssl_cert_auth_cb);
#endif #endif
return 1; return 1;
@ -420,54 +412,89 @@ rb_load_file_into_datum_t(const char *const file)
} }
int int
rb_setup_ssl_server(const char *cert, const char *keyfile, const char *dhfile, const char *cipher_list) rb_setup_ssl_server(const char *const certfile, const char *keyfile,
const char *const dhfile, const char *const cipherlist)
{ {
if(certfile == NULL)
{
rb_lib_log("%s: no certificate file specified", __func__);
return 0;
}
if(keyfile == NULL)
keyfile = certfile;
gnutls_datum_t *const d_cert = rb_load_file_into_datum_t(certfile);
if(d_cert == NULL)
{
rb_lib_log("%s: Error loading certificate: %s", __func__, strerror(errno));
return 0;
}
gnutls_datum_t *const d_key = rb_load_file_into_datum_t(keyfile);
if(d_key == NULL)
{
rb_lib_log("%s: Error loading key: %s", __func__, strerror(errno));
rb_free_datum_t(d_cert);
return 0;
}
int ret; int ret;
const char *err;
gnutls_datum_t *d_cert, *d_key; if((ret = gnutls_certificate_allocate_credentials(&server_cert_key)) != GNUTLS_E_SUCCESS)
if(cert == NULL)
{ {
rb_lib_log("rb_setup_ssl_server: No certificate file"); rb_lib_log("%s: gnutls_certificate_allocate_credentials: %s", __func__, gnutls_strerror(ret));
rb_free_datum_t(d_cert);
rb_free_datum_t(d_key);
return 0; return 0;
} }
if((d_cert = rb_load_file_into_datum_t(cert)) == NULL) #if (GNUTLS_VERSION_MAJOR < 3)
gnutls_certificate_client_set_retrieve_function(server_cert_key, rb_ssl_cert_auth_cb);
#else
gnutls_certificate_set_retrieve_function(server_cert_key, rb_ssl_cert_auth_cb);
#endif
if((ret = gnutls_certificate_set_x509_key_mem(server_cert_key, d_cert, d_key,
GNUTLS_X509_FMT_PEM)) != GNUTLS_E_SUCCESS)
{ {
rb_lib_log("rb_setup_ssl_server: Error loading certificate: %s", strerror(errno)); rb_lib_log("%s: gnutls_certificate_set_x509_key_mem: %s", __func__, gnutls_strerror(ret));
gnutls_certificate_free_credentials(server_cert_key);
rb_free_datum_t(d_cert);
rb_free_datum_t(d_key);
return 0; return 0;
} }
if((ret = gnutls_x509_crt_list_import(client_cert, &client_cert_count, d_cert, GNUTLS_X509_FMT_PEM,
if((d_key = rb_load_file_into_datum_t(keyfile)) == NULL) GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED)) < 1)
{ {
rb_lib_log("rb_setup_ssl_server: Error loading key: %s", strerror(errno)); rb_lib_log("%s: gnutls_x509_crt_list_import: %s", __func__, gnutls_strerror(ret));
gnutls_certificate_free_credentials(server_cert_key);
rb_free_datum_t(d_cert);
rb_free_datum_t(d_key);
return 0; return 0;
} }
client_cert_count = (unsigned int) ret;
/* In addition to creating the certificate set, we also need to store our cert elsewhere if((ret = gnutls_x509_privkey_init(&client_key)) != GNUTLS_E_SUCCESS)
* so we can force GNUTLS to identify with it when acting as a client.
*/
gnutls_x509_privkey_init(&client_key);
if ((ret = gnutls_x509_privkey_import(client_key, d_key, GNUTLS_X509_FMT_PEM)) != GNUTLS_E_SUCCESS)
{ {
rb_lib_log("rb_setup_ssl_server: Error loading key file: %s", gnutls_strerror(ret)); rb_lib_log("%s: gnutls_x509_privkey_init: %s", __func__, gnutls_strerror(ret));
gnutls_certificate_free_credentials(server_cert_key);
for(unsigned int i = 0; i < client_cert_count; i++)
gnutls_x509_crt_deinit(client_cert[i]);
rb_free_datum_t(d_cert);
rb_free_datum_t(d_key);
return 0; return 0;
} }
if((ret = gnutls_x509_privkey_import(client_key, d_key, GNUTLS_X509_FMT_PEM)) != GNUTLS_E_SUCCESS)
client_cert_count = MAX_CERTS;
if ((ret = gnutls_x509_crt_list_import(client_cert, &client_cert_count, d_cert, GNUTLS_X509_FMT_PEM,
GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED)) < 0)
{ {
rb_lib_log("rb_setup_ssl_server: Error loading certificate: %s", gnutls_strerror(ret)); rb_lib_log("%s: gnutls_x509_privkey_import: %s", __func__, gnutls_strerror(ret));
return 0; gnutls_certificate_free_credentials(server_cert_key);
} for(unsigned int i = 0; i < client_cert_count; i++)
client_cert_count = ret; gnutls_x509_crt_deinit(client_cert[i]);
gnutls_x509_privkey_deinit(client_key);
if((ret = rb_free_datum_t(d_cert);
gnutls_certificate_set_x509_key_mem(server_cert_key, d_cert, d_key, rb_free_datum_t(d_key);
GNUTLS_X509_FMT_PEM)) != GNUTLS_E_SUCCESS)
{
rb_lib_log("rb_setup_ssl_server: Error loading certificate or key file: %s",
gnutls_strerror(ret));
return 0; return 0;
} }
@ -476,35 +503,53 @@ rb_setup_ssl_server(const char *cert, const char *keyfile, const char *dhfile, c
if(dhfile != NULL) if(dhfile != NULL)
{ {
if(gnutls_dh_params_init(&server_dhp) == GNUTLS_E_SUCCESS) gnutls_datum_t *const d_dhp = rb_load_file_into_datum_t(dhfile);
if(d_dhp == NULL)
{ {
gnutls_datum_t *data; rb_lib_log("%s: Error parsing DH parameters: %s", __func__, strerror(errno));
int xret; gnutls_certificate_free_credentials(server_cert_key);
data = rb_load_file_into_datum_t(dhfile); for(unsigned int i = 0; i < client_cert_count; i++)
if(data != NULL) gnutls_x509_crt_deinit(client_cert[i]);
{ gnutls_x509_privkey_deinit(client_key);
xret = gnutls_dh_params_import_pkcs3(server_dhp, data, return 0;
GNUTLS_X509_FMT_PEM);
if(xret < 0)
rb_lib_log
("rb_setup_ssl_server: Error parsing DH file: %s\n",
gnutls_strerror(xret));
rb_free_datum_t(data);
}
gnutls_certificate_set_dh_params(server_cert_key, server_dhp);
} }
else if((ret = gnutls_dh_params_init(&server_dhp)) != GNUTLS_E_SUCCESS)
rb_lib_log("rb_setup_ssl_server: Unable to setup DH parameters"); {
rb_lib_log("%s: Error parsing DH parameters: %s", __func__, gnutls_strerror(ret));
gnutls_certificate_free_credentials(server_cert_key);
for(unsigned int i = 0; i < client_cert_count; i++)
gnutls_x509_crt_deinit(client_cert[i]);
gnutls_x509_privkey_deinit(client_key);
rb_free_datum_t(d_dhp);
return 0;
}
if((ret = gnutls_dh_params_import_pkcs3(server_dhp, d_dhp, GNUTLS_X509_FMT_PEM)) != GNUTLS_E_SUCCESS)
{
rb_lib_log("%s: Error parsing DH parameters: %s", __func__, gnutls_strerror(ret));
gnutls_certificate_free_credentials(server_cert_key);
for(unsigned int i = 0; i < client_cert_count; i++)
gnutls_x509_crt_deinit(client_cert[i]);
gnutls_x509_privkey_deinit(client_key);
gnutls_dh_params_deinit(server_dhp);
rb_free_datum_t(d_dhp);
return 0;
}
gnutls_certificate_set_dh_params(server_cert_key, server_dhp);
rb_free_datum_t(d_dhp);
} }
ret = gnutls_priority_init(&default_priority, cipher_list, &err); const char *err = NULL;
if (ret < 0) if((ret = gnutls_priority_init(&default_priority, cipherlist, &err)) != GNUTLS_E_SUCCESS)
{ {
rb_lib_log("rb_setup_ssl_server: syntax error (using defaults instead) in ssl cipher list at: %s", err); rb_lib_log("%s: gnutls_priority_init: %s, error begins at '%s'? -- using defaults instead",
gnutls_priority_init(&default_priority, NULL, &err); __func__, gnutls_strerror(ret), err ? err : "<unknown>");
return 1;
(void) gnutls_priority_init(&default_priority, NULL, &err);
} }
rb_lib_log("%s: TLS configuration successful", __func__);
return 1; return 1;
} }