summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2016-10-11 16:42:28 +0200
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2016-10-14 22:54:39 +0200
commit68124e32acac2a23d2ef969ae81c6ac16b4ef707 (patch)
tree71033decb07270bffb8da839425c2a5db5be7be3 /lib
parente3d2d37fa0670288202f539c1c2df0e15aadaf00 (diff)
downloadgnutls-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.c46
-rw-r--r--lib/auth/anon.h2
-rw-r--r--lib/auth/cert.h2
-rw-r--r--lib/auth/psk.h1
-rw-r--r--lib/cert.c49
-rw-r--r--lib/dh-primes.c51
-rw-r--r--lib/dh.h2
-rw-r--r--lib/includes/gnutls/gnutls.h.in12
-rw-r--r--lib/libgnutls.map3
-rw-r--r--lib/psk.c41
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
diff --git a/lib/dh.h b/lib/dh.h
index 7bc7bec125..5b15a93ef2 100644
--- a/lib/dh.h
+++ b/lib/dh.h
@@ -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:
*;
};
diff --git a/lib/psk.c b/lib/psk.c
index 6b305ee457..ba2e4874d3 100644
--- a/lib/psk.c
+++ b/lib/psk.c
@@ -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