diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2016-10-11 16:42:28 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2016-10-14 22:54:39 +0200 |
commit | 68124e32acac2a23d2ef969ae81c6ac16b4ef707 (patch) | |
tree | 71033decb07270bffb8da839425c2a5db5be7be3 /lib | |
parent | e3d2d37fa0670288202f539c1c2df0e15aadaf00 (diff) | |
download | gnutls-68124e32acac2a23d2ef969ae81c6ac16b4ef707.tar.gz |
DH: introduced gnutls_*_set_known_dh_params()
That is, the functions gnutls_certificate_set_known_dh_params(),
gnutls_anon_set_server_known_dh_params(),
gnutls_psk_set_server_known_dh_params().
These functions allow to statically set the DH parameters, based
on the RFC7919 FFDHE parameters. This can simplify server configuration
by allowing DH without loading parameters from file.
Relates #37
Diffstat (limited to 'lib')
-rw-r--r-- | lib/anon_cred.c | 46 | ||||
-rw-r--r-- | lib/auth/anon.h | 2 | ||||
-rw-r--r-- | lib/auth/cert.h | 2 | ||||
-rw-r--r-- | lib/auth/psk.h | 1 | ||||
-rw-r--r-- | lib/cert.c | 49 | ||||
-rw-r--r-- | lib/dh-primes.c | 51 | ||||
-rw-r--r-- | lib/dh.h | 2 | ||||
-rw-r--r-- | lib/includes/gnutls/gnutls.h.in | 12 | ||||
-rw-r--r-- | lib/libgnutls.map | 3 | ||||
-rw-r--r-- | lib/psk.c | 41 |
10 files changed, 207 insertions, 2 deletions
diff --git a/lib/anon_cred.c b/lib/anon_cred.c index 7d4adb374e..d97b8c6650 100644 --- a/lib/anon_cred.c +++ b/lib/anon_cred.c @@ -40,7 +40,9 @@ void gnutls_anon_free_server_credentials(gnutls_anon_server_credentials_t sc) { - + if (sc->deinit_dh_params) { + gnutls_dh_params_deinit(sc->dh_params); + } gnutls_free(sc); } @@ -111,10 +113,52 @@ void gnutls_anon_set_server_dh_params(gnutls_anon_server_credentials_t res, gnutls_dh_params_t dh_params) { + if (res->deinit_dh_params) { + res->deinit_dh_params = 0; + gnutls_dh_params_deinit(res->dh_params); + res->dh_params = NULL; + } + res->dh_params = dh_params; } /** + * gnutls_anon_set_server_known_dh_params: + * @res: is a gnutls_anon_server_credentials_t type + * @dh_params: The Diffie-Hellman parameters. + * + * This function will set the Diffie-Hellman parameters for an + * anonymous server to use. These parameters will be used in + * Anonymous Diffie-Hellman cipher suites and will be selected from + * the FFDHE set of RFC7919 according to the security level provided. + * + * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a + * negative error value. + * + * Since: 3.5.6 + **/ +int +gnutls_anon_set_server_known_dh_params(gnutls_anon_server_credentials_t res, + gnutls_sec_param_t sec_param) +{ + int ret; + + if (res->deinit_dh_params) { + res->deinit_dh_params = 0; + gnutls_dh_params_deinit(res->dh_params); + res->dh_params = NULL; + } + + ret = _gnutls_set_cred_dh_params(&res->dh_params, sec_param); + if (ret < 0) + return gnutls_assert_val(ret); + + res->deinit_dh_params = 1; + + return 0; +} + +/** * gnutls_anon_set_server_params_function: * @res: is a gnutls_certificate_credentials_t type * @func: is the function to be called diff --git a/lib/auth/anon.h b/lib/auth/anon.h index eb88e86144..02722c83e1 100644 --- a/lib/auth/anon.h +++ b/lib/auth/anon.h @@ -26,6 +26,8 @@ typedef struct gnutls_anon_server_credentials_st { gnutls_dh_params_t dh_params; + unsigned deinit_dh_params; + /* this callback is used to retrieve the DH or RSA * parameters. */ diff --git a/lib/auth/cert.h b/lib/auth/cert.h index fae049c09b..f1389fb3f6 100644 --- a/lib/auth/cert.h +++ b/lib/auth/cert.h @@ -45,6 +45,8 @@ typedef struct { */ typedef struct gnutls_certificate_credentials_st { gnutls_dh_params_t dh_params; + unsigned deinit_dh_params; /* if the internal values are set */ + /* this callback is used to retrieve the DH or RSA * parameters. */ diff --git a/lib/auth/psk.h b/lib/auth/psk.h index 3c1aba3980..b2d8a76fdf 100644 --- a/lib/auth/psk.h +++ b/lib/auth/psk.h @@ -41,6 +41,7 @@ typedef struct gnutls_psk_server_credentials_st { /* For DHE_PSK */ gnutls_dh_params_t dh_params; + unsigned int deinit_dh_params; /* this callback is used to retrieve the DH or RSA * parameters. */ diff --git a/lib/cert.c b/lib/cert.c index d81267e324..9d6d1ef6a8 100644 --- a/lib/cert.c +++ b/lib/cert.c @@ -43,7 +43,7 @@ #ifdef ENABLE_OPENPGP #include "openpgp/openpgp.h" #endif -#include "str.h" +#include "dh.h" /** * gnutls_certificate_free_keys: @@ -205,6 +205,9 @@ gnutls_certificate_free_credentials(gnutls_certificate_credentials_t sc) #ifdef ENABLE_OPENPGP gnutls_openpgp_keyring_deinit(sc->keyring); #endif + if (sc->deinit_dh_params) { + gnutls_dh_params_deinit(sc->dh_params); + } gnutls_free(sc); } @@ -238,6 +241,7 @@ gnutls_certificate_allocate_credentials(gnutls_certificate_credentials_t * (*res)->verify_bits = DEFAULT_MAX_VERIFY_BITS; (*res)->verify_depth = DEFAULT_MAX_VERIFY_DEPTH; + return 0; } @@ -1016,7 +1020,50 @@ void gnutls_certificate_set_dh_params(gnutls_certificate_credentials_t res, gnutls_dh_params_t dh_params) { + if (res->deinit_dh_params) { + res->deinit_dh_params = 0; + gnutls_dh_params_deinit(res->dh_params); + res->dh_params = NULL; + } + res->dh_params = dh_params; } + +/** + * gnutls_certificate_set_known_dh_params: + * @res: is a gnutls_certificate_credentials_t type + * @sec_param: is an option of the %gnutls_sec_param_t enumeration + * + * This function will set the Diffie-Hellman parameters for a + * certificate server to use. These parameters will be used in + * Ephemeral Diffie-Hellman cipher suites and will be selected from + * the FFDHE set of RFC7919 according to the security level provided. + * + * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a + * negative error value. + * + * Since: 3.5.6 + **/ +int +gnutls_certificate_set_known_dh_params(gnutls_certificate_credentials_t res, + gnutls_sec_param_t sec_param) +{ + int ret; + + if (res->deinit_dh_params) { + res->deinit_dh_params = 0; + gnutls_dh_params_deinit(res->dh_params); + res->dh_params = NULL; + } + + ret = _gnutls_set_cred_dh_params(&res->dh_params, sec_param); + if (ret < 0) + return gnutls_assert_val(ret); + + res->deinit_dh_params = 1; + + return 0; +} + #endif /* DH */ diff --git a/lib/dh-primes.c b/lib/dh-primes.c index a940d3c5b8..50af25f9c2 100644 --- a/lib/dh-primes.c +++ b/lib/dh-primes.c @@ -25,6 +25,8 @@ #if defined(ENABLE_DHE) || defined(ENABLE_ANON) +#include "dh.h" + static const unsigned char ffdhe_params_2048[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, @@ -388,4 +390,53 @@ const gnutls_datum_t gnutls_ffdhe_8192_group_prime = { }; const unsigned int gnutls_ffdhe_8192_key_bits = 512; + +int _gnutls_set_cred_dh_params(gnutls_dh_params_t *cparams, gnutls_sec_param_t sec_param) +{ + gnutls_dh_params_t tmp_params; + const gnutls_datum_t *p, *g; + unsigned key_bits, est_bits; + unsigned bits; + int ret; + + bits = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, sec_param); + + if (bits <= 2048) { + p = &gnutls_ffdhe_2048_group_prime; + g = &gnutls_ffdhe_2048_group_generator; + key_bits = gnutls_ffdhe_2048_key_bits; + } else if (bits <= 3072) { + p = &gnutls_ffdhe_3072_group_prime; + g = &gnutls_ffdhe_3072_group_generator; + key_bits = gnutls_ffdhe_3072_key_bits; + } else if (bits <= 4096) { + p = &gnutls_ffdhe_4096_group_prime; + g = &gnutls_ffdhe_4096_group_generator; + key_bits = gnutls_ffdhe_4096_key_bits; + } else { + p = &gnutls_ffdhe_8192_group_prime; + g = &gnutls_ffdhe_8192_group_generator; + key_bits = gnutls_ffdhe_8192_key_bits; + } + + /* if our estimation of subgroup bits is better/larger than + * the one provided by the rfc7919, use that one */ + est_bits = _gnutls_pk_bits_to_subgroup_bits(bits); + if (key_bits < est_bits) + key_bits = est_bits; + + ret = gnutls_dh_params_init(&tmp_params); + if (ret < 0) + return gnutls_assert_val(ret); + + ret = gnutls_dh_params_import_raw2(tmp_params, p, g, key_bits); + if (ret < 0) { + gnutls_dh_params_deinit(tmp_params); + return gnutls_assert_val(ret); + } + + *cparams = tmp_params; + + return 0; +} #endif @@ -30,4 +30,6 @@ _gnutls_get_dh_params(gnutls_dh_params_t dh_params, gnutls_params_function * func, gnutls_session_t session); +int _gnutls_set_cred_dh_params(gnutls_dh_params_t *cparams, gnutls_sec_param_t sec_param); + #endif diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in index ec754fcf82..75673c88ad 100644 --- a/lib/includes/gnutls/gnutls.h.in +++ b/lib/includes/gnutls/gnutls.h.in @@ -1594,6 +1594,10 @@ gnutls_anon_allocate_server_credentials(gnutls_anon_server_credentials_t void gnutls_anon_set_server_dh_params(gnutls_anon_server_credentials_t res, gnutls_dh_params_t dh_params); +int +gnutls_anon_set_server_known_dh_params(gnutls_anon_server_credentials_t res, + gnutls_sec_param_t sec_param); + void gnutls_anon_set_server_params_function(gnutls_anon_server_credentials_t res, gnutls_params_function * func); @@ -1641,6 +1645,9 @@ void gnutls_certificate_free_crls(gnutls_certificate_credentials_t sc); void gnutls_certificate_set_dh_params(gnutls_certificate_credentials_t res, gnutls_dh_params_t dh_params); + +int gnutls_certificate_set_known_dh_params(gnutls_certificate_credentials_t res, + gnutls_sec_param_t sec_param); void gnutls_certificate_set_verify_flags(gnutls_certificate_credentials_t res, unsigned int flags); unsigned int @@ -2011,6 +2018,7 @@ extern _SYM_EXPORT const gnutls_datum_t gnutls_srp_1024_group_generator; /* The static parameters defined in rfc7919 */ + extern _SYM_EXPORT const gnutls_datum_t gnutls_ffdhe_8192_group_prime; extern _SYM_EXPORT const gnutls_datum_t gnutls_ffdhe_8192_group_generator; extern _SYM_EXPORT const unsigned int gnutls_ffdhe_8192_key_bits; @@ -2141,6 +2149,10 @@ void gnutls_psk_set_server_dh_params(gnutls_psk_server_credentials_t res, gnutls_dh_params_t dh_params); +int +gnutls_psk_set_server_known_dh_params(gnutls_psk_server_credentials_t res, + gnutls_sec_param_t sec_param); + void gnutls_psk_set_server_params_function(gnutls_psk_server_credentials_t res, gnutls_params_function * func); diff --git a/lib/libgnutls.map b/lib/libgnutls.map index 72caaa3137..d0c028b995 100644 --- a/lib/libgnutls.map +++ b/lib/libgnutls.map @@ -1120,6 +1120,9 @@ GNUTLS_3_4 gnutls_ffdhe_4096_key_bits; gnutls_ffdhe_2048_key_bits; gnutls_ffdhe_3072_key_bits; + gnutls_certificate_set_known_dh_params; + gnutls_anon_set_server_known_dh_params; + gnutls_psk_set_server_known_dh_params; local: *; }; @@ -34,6 +34,7 @@ #include <file.h> #include <datum.h> #include "debug.h" +#include "dh.h" /** * gnutls_psk_free_client_credentials: @@ -154,6 +155,10 @@ gnutls_psk_set_client_credentials(gnutls_psk_client_credentials_t res, **/ void gnutls_psk_free_server_credentials(gnutls_psk_server_credentials_t sc) { + if (sc->deinit_dh_params) { + gnutls_dh_params_deinit(sc->dh_params); + } + gnutls_free(sc->password_file); gnutls_free(sc->hint); gnutls_free(sc); @@ -375,6 +380,42 @@ gnutls_psk_set_server_dh_params(gnutls_psk_server_credentials_t res, } /** + * gnutls_psk_set_server_known_dh_params: + * @res: is a gnutls_psk_server_credentials_t type + * @sec_param: is an option of the %gnutls_sec_param_t enumeration + * + * This function will set the Diffie-Hellman parameters for a + * PSK server to use. These parameters will be used in + * Ephemeral Diffie-Hellman cipher suites and will be selected from + * the FFDHE set of RFC7919 according to the security level provided. + * + * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a + * negative error value. + * + * Since: 3.5.6 + **/ +int +gnutls_psk_set_server_known_dh_params(gnutls_psk_server_credentials_t res, + gnutls_sec_param_t sec_param) +{ + int ret; + + if (res->deinit_dh_params) { + res->deinit_dh_params = 0; + gnutls_dh_params_deinit(res->dh_params); + res->dh_params = NULL; + } + + ret = _gnutls_set_cred_dh_params(&res->dh_params, sec_param); + if (ret < 0) + return gnutls_assert_val(ret); + + res->deinit_dh_params = 1; + + return 0; +} + +/** * gnutls_psk_set_server_params_function: * @res: is a #gnutls_certificate_credentials_t type * @func: is the function to be called |