mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-02-05 21:11:53 +00:00
MEDIUM: ssl: add the possibility to use a global DH parameters file
This patch adds the ssl-dh-param-file global setting. It sets the default DH parameters that will be used during the SSL/TLS handshake when ephemeral Diffie-Hellman (DHE) key exchange is used, for all "bind" lines which do not explicitely define theirs.
This commit is contained in:
parent
79318d79ba
commit
47783ef05b
@ -766,6 +766,20 @@ ssl-default-server-options [<option>]...
|
||||
default ssl-options to force on all "server" lines. Please check the "server"
|
||||
keyword to see available options.
|
||||
|
||||
ssl-dh-param-file <file>
|
||||
This setting is only available when support for OpenSSL was built in. It sets
|
||||
the default DH parameters that are used during the SSL/TLS handshake when
|
||||
ephemeral Diffie-Hellman (DHE) key exchange is used, for all "bind" lines
|
||||
which do not explicitely define theirs. It will be overridden by custom DH
|
||||
parameters found in a bind certificate file if any. If custom DH parameters
|
||||
are not specified either by using ssl-dh-param-file or by setting them directly
|
||||
in the certificate file, pre-generated DH parameters of the size specified
|
||||
by tune.ssl.default-dh-param will be used. Custom parameters are known to be
|
||||
more secure and therefore their use is recommended.
|
||||
Custom DH parameters may be generated by using the OpenSSL command
|
||||
"openssl dhparam <size>", where size should be at least 2048, as 1024-bit DH
|
||||
parameters should not be considered secure anymore.
|
||||
|
||||
ssl-server-verify [none|required]
|
||||
The default behavior for SSL verify on servers side. If specified to 'none',
|
||||
servers certificates are not verified. The default is 'required' except if
|
||||
@ -1224,7 +1238,8 @@ tune.ssl.default-dh-param <number>
|
||||
this maximum value. Default value if 1024. Only 1024 or higher values are
|
||||
allowed. Higher values will increase the CPU load, and values greater than
|
||||
1024 bits are not supported by Java 7 and earlier clients. This value is not
|
||||
used if static Diffie-Hellman parameters are supplied via the certificate file.
|
||||
used if static Diffie-Hellman parameters are supplied either directly
|
||||
in the certificate file or by using the ssl-dh-param-file parameter.
|
||||
|
||||
tune.zlib.memlevel <number>
|
||||
Sets the memLevel parameter in zlib initialization for each session. It
|
||||
|
@ -64,6 +64,9 @@ struct tls_keys_ref *tlskeys_ref_lookup(const char *filename);
|
||||
struct tls_keys_ref *tlskeys_ref_lookupid(int unique_id);
|
||||
void tlskeys_finalize_config(void);
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_DH
|
||||
int ssl_sock_load_global_dh_param_from_file(const char *filename);
|
||||
#endif
|
||||
|
||||
#endif /* _PROTO_SSL_SOCK_H */
|
||||
|
||||
|
@ -753,6 +753,7 @@ int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
|
||||
}
|
||||
global.tune.ssl_max_record = atol(args[1]);
|
||||
}
|
||||
#ifndef OPENSSL_NO_DH
|
||||
else if (!strcmp(args[0], "tune.ssl.default-dh-param")) {
|
||||
if (alertif_too_many_args(1, file, linenum, args, &err_code))
|
||||
goto out;
|
||||
@ -768,6 +769,7 @@ int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
else if (!strcmp(args[0], "tune.buffers.limit")) {
|
||||
if (alertif_too_many_args(1, file, linenum, args, &err_code))
|
||||
@ -1187,6 +1189,22 @@ int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
|
||||
goto out;
|
||||
#endif
|
||||
}
|
||||
#ifdef USE_OPENSSL
|
||||
#ifndef OPENSSL_NO_DH
|
||||
else if (!strcmp(args[0], "ssl-dh-param-file")) {
|
||||
if (*(args[1]) == 0) {
|
||||
Alert("parsing [%s:%d] : '%s' expects a file path as an argument.\n", file, linenum, args[0]);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
if (ssl_sock_load_global_dh_param_from_file(args[1])) {
|
||||
Alert("parsing [%s:%d] : '%s': unable to load DH parameters from file <%s>.\n", file, linenum, args[0], args[1]);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
else if (!strcmp(args[0], "ssl-server-verify")) {
|
||||
if (alertif_too_many_args(1, file, linenum, args, &err_code))
|
||||
goto out;
|
||||
|
@ -124,6 +124,7 @@ struct list tlskeys_reference = LIST_HEAD_INIT(tlskeys_reference);
|
||||
|
||||
#ifndef OPENSSL_NO_DH
|
||||
static int ssl_dh_ptr_index = -1;
|
||||
static DH *global_dh = NULL;
|
||||
static DH *local_dh_1024 = NULL;
|
||||
static DH *local_dh_2048 = NULL;
|
||||
static DH *local_dh_4096 = NULL;
|
||||
@ -1332,22 +1333,44 @@ static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
|
||||
return dh;
|
||||
}
|
||||
|
||||
static DH * ssl_sock_get_dh_from_file(const char *filename)
|
||||
{
|
||||
DH *dh = NULL;
|
||||
BIO *in = BIO_new(BIO_s_file());
|
||||
|
||||
if (in == NULL)
|
||||
goto end;
|
||||
|
||||
if (BIO_read_filename(in, filename) <= 0)
|
||||
goto end;
|
||||
|
||||
dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
|
||||
|
||||
end:
|
||||
if (in)
|
||||
BIO_free(in);
|
||||
|
||||
return dh;
|
||||
}
|
||||
|
||||
int ssl_sock_load_global_dh_param_from_file(const char *filename)
|
||||
{
|
||||
global_dh = ssl_sock_get_dh_from_file(filename);
|
||||
|
||||
if (global_dh) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
|
||||
if an error occured, and 0 if parameter not found. */
|
||||
int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
|
||||
{
|
||||
int ret = -1;
|
||||
BIO *in;
|
||||
DH *dh = NULL;
|
||||
DH *dh = ssl_sock_get_dh_from_file(file);
|
||||
|
||||
in = BIO_new(BIO_s_file());
|
||||
if (in == NULL)
|
||||
goto end;
|
||||
|
||||
if (BIO_read_filename(in, file) <= 0)
|
||||
goto end;
|
||||
|
||||
dh = PEM_read_bio_DHparams(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
|
||||
if (dh) {
|
||||
ret = 1;
|
||||
SSL_CTX_set_tmp_dh(ctx, dh);
|
||||
@ -1358,6 +1381,10 @@ int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
|
||||
SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, dh);
|
||||
}
|
||||
}
|
||||
else if (global_dh) {
|
||||
SSL_CTX_set_tmp_dh(ctx, global_dh);
|
||||
ret = 0; /* DH params not found */
|
||||
}
|
||||
else {
|
||||
/* Clear openssl global errors stack */
|
||||
ERR_clear_error();
|
||||
@ -1381,9 +1408,6 @@ end:
|
||||
if (dh)
|
||||
DH_free(dh);
|
||||
|
||||
if (in)
|
||||
BIO_free(in);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
@ -1901,9 +1925,11 @@ int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy
|
||||
cfgerr++;
|
||||
}
|
||||
|
||||
/* If tune.ssl.default-dh-param has not been set and
|
||||
no static DH params were in the certificate file. */
|
||||
/* If tune.ssl.default-dh-param has not been set,
|
||||
neither has ssl-default-dh-file and no static DH
|
||||
params were in the certificate file. */
|
||||
if (global.tune.ssl_default_dh_param == 0 &&
|
||||
global_dh == NULL &&
|
||||
(ssl_dh_ptr_index == -1 ||
|
||||
SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
|
||||
|
||||
@ -5083,6 +5109,11 @@ static void __ssl_sock_deinit(void)
|
||||
DH_free(local_dh_8192);
|
||||
local_dh_8192 = NULL;
|
||||
}
|
||||
|
||||
if (global_dh) {
|
||||
DH_free(global_dh);
|
||||
global_dh = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
ERR_remove_state(0);
|
||||
|
Loading…
Reference in New Issue
Block a user