Mercurial > hg > freeDiameter-dtls
changeset 578:7c9a00bfd115
Allow TLS Diffie-Hellmann parameters to be loaded from a file (ticket #17)
author | Sebastien Decugis <sdecugis@nict.go.jp> |
---|---|
date | Wed, 27 Oct 2010 10:52:30 +0900 |
parents | 9dae8bc2d04a |
children | 8c62a1c435e8 |
files | doc/freediameter.conf.sample freeDiameter/config.c freeDiameter/fdd.l freeDiameter/fdd.y include/freeDiameter/freeDiameter.h |
diffstat | 5 files changed, 79 insertions(+), 16 deletions(-) [+] |
line wrap: on
line diff
--- a/doc/freediameter.conf.sample Wed Oct 20 15:37:49 2010 +0900 +++ b/doc/freediameter.conf.sample Wed Oct 27 10:52:30 2010 +0900 @@ -120,6 +120,13 @@ # Default : 1024 #TLS_DH_Bits = 1024; +# Alternatively, you can specify a file to load the PKCS#3 encoded +# DH parameters directly from. This accelerates the daemon start +# but is slightly less secure. If this file is provided, the +# TLS_DH_Bits parameters has no effect. +# Default : no default. +#TLS_DH_File = "<file.PEM>"; + ############################################################## ## Timers configuration
--- a/freeDiameter/config.c Wed Oct 20 15:37:49 2010 +0900 +++ b/freeDiameter/config.c Wed Oct 27 10:52:30 2010 +0900 @@ -133,7 +133,10 @@ fd_log_debug(" - CA (trust) ... : %s (%d certs)\n", fd_g_config->cnf_sec_data.ca_file ?: "(none)", fd_g_config->cnf_sec_data.ca_file_nr); fd_log_debug(" - CRL .......... : %s\n", fd_g_config->cnf_sec_data.crl_file ?: "(none)"); fd_log_debug(" - Priority ..... : %s\n", fd_g_config->cnf_sec_data.prio_string ?: "(default: '" GNUTLS_DEFAULT_PRIORITY "')"); - fd_log_debug(" - DH bits ...... : %d\n", fd_g_config->cnf_sec_data.dh_bits ?: GNUTLS_DEFAULT_DHBITS); + if (fd_g_config->cnf_sec_data.dh_file) + fd_log_debug(" - DH file ...... : %s\n", fd_g_config->cnf_sec_data.dh_file); + else + fd_log_debug(" - DH bits ...... : %d\n", fd_g_config->cnf_sec_data.dh_bits ?: GNUTLS_DEFAULT_DHBITS); fd_log_debug(" Origin-State-Id ........ : %u\n", fd_g_config->cnf_orstateid); } @@ -260,14 +263,6 @@ &err_pos), { TRACE_DEBUG(INFO, "Error in priority string at position : %s", err_pos); return EINVAL; } ); } - if (! fd_g_config->cnf_sec_data.dh_bits) { - TRACE_DEBUG(INFO, "Generating Diffie-Hellman parameters of size %d (this takes a few seconds)... ", GNUTLS_DEFAULT_DHBITS); - CHECK_GNUTLS_DO( gnutls_dh_params_generate2( - fd_g_config->cnf_sec_data.dh_cache, - GNUTLS_DEFAULT_DHBITS), - { TRACE_DEBUG(INFO, "Error in DH bits value : %d", GNUTLS_DEFAULT_DHBITS); return EINVAL; } ); - } - /* Verify that our certificate is valid -- otherwise remote peers will reject it */ { @@ -402,6 +397,56 @@ /* gnutls_certificate_set_verify_limits -- so far the default values are fine... */ + /* DH */ + if (fd_g_config->cnf_sec_data.dh_file) { + gnutls_datum_t dhparams = { NULL, 0 }; + size_t alloc = 0; + FILE *stream = fopen (fd_g_config->cnf_sec_data.dh_file, "rb"); + if (!stream) { + int err = errno; + TRACE_DEBUG(INFO, "An error occurred while opening '%s': %s\n", fd_g_config->cnf_sec_data.dh_file, strerror(err)); + return err; + } + do { + uint8_t * realloced = NULL; + size_t read = 0; + + if (alloc < dhparams.size + BUFSIZ + 1) { + alloc += alloc / 2 + BUFSIZ + 1; + CHECK_MALLOC_DO( realloced = realloc(dhparams.data, alloc), + { + free(dhparams.data); + return ENOMEM; + } ) + dhparams.data = realloced; + } + + read = fread( dhparams.data + dhparams.size, 1, alloc - dhparams.size - 1, stream ); + dhparams.size += read; + + if (ferror(stream)) { + int err = errno; + TRACE_DEBUG(INFO, "An error occurred while reading '%s': %s\n", fd_g_config->cnf_sec_data.dh_file, strerror(err)); + return err; + } + } while (!feof(stream)); + dhparams.data[dhparams.size] = '\0'; + fclose(stream); + CHECK_GNUTLS_DO( gnutls_dh_params_import_pkcs3( + fd_g_config->cnf_sec_data.dh_cache, + &dhparams, + GNUTLS_X509_FMT_PEM), + { TRACE_DEBUG(INFO, "Error in DH bits value : %d", fd_g_config->cnf_sec_data.dh_bits ?: GNUTLS_DEFAULT_DHBITS); return EINVAL; } ); + free(dhparams.data); + + } else { + TRACE_DEBUG(INFO, "Generating fresh Diffie-Hellman parameters of size %d (this takes some time)... ", fd_g_config->cnf_sec_data.dh_bits ?: GNUTLS_DEFAULT_DHBITS); + CHECK_GNUTLS_DO( gnutls_dh_params_generate2( + fd_g_config->cnf_sec_data.dh_cache, + fd_g_config->cnf_sec_data.dh_bits ?: GNUTLS_DEFAULT_DHBITS), + { TRACE_DEBUG(INFO, "Error in DH bits value : %d", fd_g_config->cnf_sec_data.dh_bits ?: GNUTLS_DEFAULT_DHBITS); return EINVAL; } ); + } + return 0; } @@ -421,6 +466,7 @@ free(fd_g_config->cnf_sec_data.ca_file); fd_g_config->cnf_sec_data.ca_file = NULL; free(fd_g_config->cnf_sec_data.crl_file); fd_g_config->cnf_sec_data.crl_file = NULL; free(fd_g_config->cnf_sec_data.prio_string); fd_g_config->cnf_sec_data.prio_string = NULL; + free(fd_g_config->cnf_sec_data.dh_file); fd_g_config->cnf_sec_data.dh_file = NULL; /* Destroy dictionary */ CHECK_FCT_DO( fd_dict_fini(&fd_g_config->cnf_dict), );
--- a/freeDiameter/fdd.l Wed Oct 20 15:37:49 2010 +0900 +++ b/freeDiameter/fdd.l Wed Oct 27 10:52:30 2010 +0900 @@ -136,6 +136,7 @@ (?i:"TLS_CRL") { return TLS_CRL; } (?i:"TLS_Prio") { return TLS_PRIO; } (?i:"TLS_DH_bits") { return TLS_DH_BITS; } +(?i:"TLS_DH_file") { return TLS_DH_FILE; } /* Valid single characters for yyparse */
--- a/freeDiameter/fdd.y Wed Oct 20 15:37:49 2010 +0900 +++ b/freeDiameter/fdd.y Wed Oct 27 10:52:30 2010 +0900 @@ -117,6 +117,7 @@ %token TLS_CRL %token TLS_PRIO %token TLS_DH_BITS +%token TLS_DH_FILE /* -------------------------------------- */ @@ -581,12 +582,19 @@ tls_dh: TLS_DH_BITS '=' INTEGER ';' { conf->cnf_sec_data.dh_bits = $3; - TRACE_DEBUG(FULL, "Generating DH parameters..."); - CHECK_GNUTLS_DO( gnutls_dh_params_generate2( - conf->cnf_sec_data.dh_cache, - conf->cnf_sec_data.dh_bits), - { yyerror (&yylloc, conf, "Error setting DH Bits parameters."); - YYERROR; } ); - TRACE_DEBUG(FULL, "DH parameters generated."); + } + | TLS_DH_FILE '=' QSTRING ';' + { + FILE * fd; + free(conf->cnf_sec_data.dh_file); + conf->cnf_sec_data.dh_file = $3; + fd = fopen($3, "r"); + if (fd == NULL) { + int ret = errno; + TRACE_DEBUG(INFO, "Unable to open DH file %s for reading: %s\n", $3, strerror(ret)); + yyerror (&yylloc, conf, "Error on file name"); + YYERROR; + } + fclose(fd); } ;