From a3c97d1f759cf5fce5dc5fa7aeb5b4812e6c89a1 Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos Date: Mon, 3 Dec 2007 18:26:23 +0000 Subject: better handling of RSAFile and DHFile --- NEWS | 5 +- include/mod_gnutls.h.in | 4 +- src/gnutls_config.c | 49 ++++++++++++++++-- src/gnutls_hooks.c | 133 ++++++++++++------------------------------------ 4 files changed, 85 insertions(+), 106 deletions(-) diff --git a/NEWS b/NEWS index 9392872..81a6954 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,9 @@ SSL_CLIENT_S_TYPE, SSL_SERVER_M_VERSION, SSL_SERVER_S_SAN%, SSL_SERVER_S_TYPE - The compatibility mode can now be enabled explicitely with the %COMPAT keyword at the GnuTLSPriorities string. It is no longer the default. -- Check for GnuTLSPriorities directive. +- Check for GnuTLSPriorities directive. This corrects a segfault. Thanks +to David Hrbáč. + +- Better handling of GnuTLSDHFile and GnuTLSRSAFile. - No longer default paths for RSA and DH parameter files. diff --git a/include/mod_gnutls.h.in b/include/mod_gnutls.h.in index 11c35aa..6a311a3 100644 --- a/include/mod_gnutls.h.in +++ b/include/mod_gnutls.h.in @@ -96,11 +96,11 @@ typedef struct */ int export_certificates_enabled; gnutls_priority_t priorities; + gnutls_rsa_params_t rsa_params; + gnutls_dh_params_t dh_params; int cache_timeout; mgs_cache_e cache_type; const char* cache_config; - const char* rsa_params_file; - const char* dh_params_file; const char* srp_tpasswd_file; const char* srp_tpasswd_conf_file; gnutls_x509_crt_t ca_list[MAX_CA_CRTS]; diff --git a/src/gnutls_config.c b/src/gnutls_config.c index 697dae1..22e8fbc 100644 --- a/src/gnutls_config.c +++ b/src/gnutls_config.c @@ -54,12 +54,34 @@ static int load_datum_from_file(apr_pool_t * pool, const char *mgs_set_dh_file(cmd_parms * parms, void *dummy, const char *arg) { + int ret; + gnutls_datum_t data; + const char *file; + apr_pool_t *spool; mgs_srvconf_rec *sc = (mgs_srvconf_rec *) ap_get_module_config(parms->server-> module_config, &gnutls_module); - sc->dh_params_file = ap_server_root_relative(parms->pool, arg); + apr_pool_create(&spool, parms->pool); + + file = ap_server_root_relative(spool, arg); + + if (load_datum_from_file(spool, file, &data) != 0) { + return apr_psprintf(parms->pool, "GnuTLS: Error Reading " + "DH params '%s'", file); + } + + gnutls_dh_params_init(&sc->dh_params); + ret = + gnutls_dh_params_import_pkcs3(sc->dh_params, &data, GNUTLS_X509_FMT_PEM); + if (ret != 0) { + return apr_psprintf(parms->pool, "GnuTLS: Failed to Import " + "DH params '%s': (%d) %s", file, ret, + gnutls_strerror(ret)); + } + + apr_pool_destroy(spool); return NULL; } @@ -67,13 +89,34 @@ const char *mgs_set_dh_file(cmd_parms * parms, void *dummy, const char *mgs_set_rsa_export_file(cmd_parms * parms, void *dummy, const char *arg) { + int ret; + gnutls_datum_t data; + const char *file; + apr_pool_t *spool; mgs_srvconf_rec *sc = (mgs_srvconf_rec *) ap_get_module_config(parms->server-> module_config, &gnutls_module); - sc->rsa_params_file = ap_server_root_relative(parms->pool, arg); + apr_pool_create(&spool, parms->pool); + + file = ap_server_root_relative(spool, arg); + + if (load_datum_from_file(spool, file, &data) != 0) { + return apr_psprintf(parms->pool, "GnuTLS: Error Reading " + "RSA params '%s'", file); + } + + gnutls_rsa_params_init(&sc->rsa_params); + ret = + gnutls_rsa_params_import_pkcs1(sc->rsa_params, &data, GNUTLS_X509_FMT_PEM); + if (ret != 0) { + return apr_psprintf(parms->pool, "GnuTLS: Failed to Import " + "RSA params '%s': (%d) %s", file, ret, + gnutls_strerror(ret)); + } + apr_pool_destroy(spool); return NULL; } @@ -103,7 +146,7 @@ const char *mgs_set_cert_file(cmd_parms * parms, void *dummy, gnutls_x509_crt_import(sc->cert_x509, &data, GNUTLS_X509_FMT_PEM); if (ret != 0) { return apr_psprintf(parms->pool, "GnuTLS: Failed to Import " - "Certificate'%s': (%d) %s", file, ret, + "Certificate '%s': (%d) %s", file, ret, gnutls_strerror(ret)); } diff --git a/src/gnutls_hooks.c b/src/gnutls_hooks.c index 55f8e5f..7b7e2b3 100644 --- a/src/gnutls_hooks.c +++ b/src/gnutls_hooks.c @@ -84,48 +84,6 @@ mgs_hook_pre_config(apr_pool_t * pconf, return OK; } - -static gnutls_datum -load_params(const char *file, server_rec * s, apr_pool_t * pool) -{ - gnutls_datum ret = { NULL, 0 }; - apr_file_t *fp; - apr_finfo_t finfo; - apr_status_t rv; - apr_size_t br = 0; - - rv = apr_file_open(&fp, file, APR_READ | APR_BINARY, APR_OS_DEFAULT, - pool); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, rv, s, - "GnuTLS failed to load params file at: %s. Will use internal params.", - file); - return ret; - } - - rv = apr_file_info_get(&finfo, APR_FINFO_SIZE, fp); - - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, rv, s, - "GnuTLS failed to stat params file at: %s", file); - return ret; - } - - ret.data = apr_palloc(pool, finfo.size + 1); - rv = apr_file_read_full(fp, ret.data, finfo.size, &br); - - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, rv, s, - "GnuTLS failed to read params file at: %s", file); - return ret; - } - apr_file_close(fp); - ret.data[br] = '\0'; - ret.size = br; - - return ret; -} - /* We don't support openpgp certificates, yet */ const static int cert_type_prio[2] = { GNUTLS_CRT_X509, 0 }; @@ -284,68 +242,33 @@ mgs_hook_post_config(apr_pool_t * p, apr_pool_t * plog, { - gnutls_datum pdata = { NULL, 0 }; - apr_pool_t *tpool; s = base_server; sc_base = (mgs_srvconf_rec *) ap_get_module_config(s->module_config, &gnutls_module); - apr_pool_create(&tpool, p); - - gnutls_dh_params_init(&dh_params); - if (sc_base->dh_params_file) - pdata = load_params(sc_base->dh_params_file, s, tpool); - - if (pdata.size != 0) { - rv = gnutls_dh_params_import_pkcs3(dh_params, &pdata, - GNUTLS_X509_FMT_PEM); - if (rv != 0) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, - "GnuTLS: Unable to load DH Params: (%d) %s", - rv, gnutls_strerror(rv)); - exit(rv); - } - } else { - /* If the file does not exist use internal parameters - */ - pdata.data = (void *) static_dh_params; - pdata.size = sizeof(static_dh_params); - rv = gnutls_dh_params_import_pkcs3(dh_params, &pdata, + if (sc_base->dh_params == NULL) { + gnutls_datum pdata = { (void *) static_dh_params, sizeof(static_dh_params) }; + /* loading defaults */ + rv = gnutls_dh_params_import_pkcs3(dh_params, &pdata, GNUTLS_X509_FMT_PEM); - if (rv < 0) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, - "GnuTLS: Unable to load internal DH Params." - " Shutting down."); - exit(-1); - } - } - apr_pool_clear(tpool); - - pdata.data = NULL; - pdata.size = 0; - - if (sc_base->rsa_params_file) - pdata = load_params(sc_base->rsa_params_file, s, tpool); - - if (pdata.size != 0) { - gnutls_rsa_params_init(&rsa_params); - rv = gnutls_rsa_params_import_pkcs1(rsa_params, &pdata, - GNUTLS_X509_FMT_PEM); - if (rv != 0) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, - "GnuTLS: Unable to load RSA Params: (%d) %s", - rv, gnutls_strerror(rv)); - exit(rv); - } - } - /* not an error but RSA-EXPORT ciphersuites are not available + if (rv < 0) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, + "GnuTLS: Unable to load DH Params: (%d) %s", + rv, gnutls_strerror(rv)); + exit(rv); + } + } else dh_params = sc_base->dh_params; + + if (sc_base->rsa_params != NULL) + rsa_params = sc_base->rsa_params; + + /* else not an error but RSA-EXPORT ciphersuites are not available */ - apr_pool_destroy(tpool); rv = mgs_cache_post_config(p, s, sc_base); if (rv != 0) { ap_log_error(APLOG_MARK, APLOG_STARTUP, rv, s, @@ -355,6 +278,7 @@ mgs_hook_post_config(apr_pool_t * p, apr_pool_t * plog, } for (s = base_server; s; s = s->next) { + void *load = NULL; sc = (mgs_srvconf_rec *) ap_get_module_config(s->module_config, &gnutls_module); sc->cache_type = sc_base->cache_type; @@ -367,16 +291,25 @@ mgs_hook_post_config(apr_pool_t * p, apr_pool_t * plog, s->server_hostname, s->port); exit(-1); } - - if (rsa_params != NULL) - gnutls_certificate_set_rsa_export_params(sc->certs, - rsa_params); - if (dh_params != NULL) /* not needed but anyway */ - gnutls_certificate_set_dh_params(sc->certs, dh_params); + /* Check if DH or RSA params have been set per host */ + if (sc->rsa_params != NULL) + load = sc->rsa_params; + else if (rsa_params) load = rsa_params; + + if (load != NULL) + gnutls_certificate_set_rsa_export_params(sc->certs, load); - gnutls_anon_set_server_dh_params(sc->anon_creds, dh_params); + load = NULL; + if (sc->dh_params != NULL) + load = sc->dh_params; + else if (dh_params) load = dh_params; + + if (load != NULL) { /* not needed but anyway */ + gnutls_certificate_set_dh_params(sc->certs, load); + gnutls_anon_set_server_dh_params(sc->anon_creds, load); + } gnutls_certificate_server_set_retrieve_function(sc->certs, cert_retrieve_fn); -- cgit