summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRemi Gacogne <rgacogne[at]aquaray[dot]fr>2014-06-12 14:58:40 +0200
committerWilly Tarreau <w@1wt.eu>2014-06-12 16:12:23 +0200
commitf46cd6e4ec3ab1bc30d432e5fce358da5d545d12 (patch)
treefa565c395a66d09eaf2e03371aca293776f6d8a9
parentb7f1cfc8463382fdb230b537bf297f1ce4854d49 (diff)
downloadhaproxy-f46cd6e4ec3ab1bc30d432e5fce358da5d545d12.tar.gz
MEDIUM: ssl: Add the option to use standardized DH parameters >= 1024 bits
When no static DH parameters are specified, this patch makes haproxy use standardized (rfc 2409 / rfc 3526) DH parameters with prime lenghts of 1024, 2048, 4096 or 8192 bits for DHE key exchange. The size of the temporary/ephemeral DH key is computed as the minimum of the RSA/DSA server key size and the value of a new option named tune.ssl.default-dh-param.
-rw-r--r--doc/configuration.txt11
-rw-r--r--include/common/defaults.h5
-rw-r--r--include/types/global.h1
-rw-r--r--src/cfgparse.c13
-rw-r--r--src/haproxy.c1
-rw-r--r--src/ssl_sock.c387
6 files changed, 380 insertions, 38 deletions
diff --git a/doc/configuration.txt b/doc/configuration.txt
index d28c91a6e..54ccacac9 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -497,6 +497,7 @@ The following keywords are supported in the "global" section :
- tune.ssl.lifetime
- tune.ssl.force-private-cache
- tune.ssl.maxrecord
+ - tune.ssl.default-dh-param
- tune.zlib.memlevel
- tune.zlib.windowsize
@@ -1017,6 +1018,16 @@ tune.ssl.maxrecord <number>
best value. Haproxy will automatically switch to this setting after an idle
stream has been detected (see tune.idletimer above).
+tune.ssl.default-dh-param <number>
+ Sets the maximum size of the Diffie-Hellman parameters used for generating
+ the ephemeral/temporary Diffie-Hellman key in case of DHE key exchange. The
+ final size will try to match the size of the server's RSA (or DSA) key (e.g,
+ a 2048 bits temporary DH key for a 2048 bits RSA key), but will not exceed
+ 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.
+
tune.zlib.memlevel <number>
Sets the memLevel parameter in zlib initialization for each session. It
defines how much memory should be allocated for the internal compression
diff --git a/include/common/defaults.h b/include/common/defaults.h
index f765e90e9..bdd75cf90 100644
--- a/include/common/defaults.h
+++ b/include/common/defaults.h
@@ -214,4 +214,9 @@
#define SSLCACHESIZE 20000
#endif
+/* ssl max dh param size */
+#ifndef SSL_DEFAULT_DH_PARAM
+#define SSL_DEFAULT_DH_PARAM 0
+#endif
+
#endif /* _COMMON_DEFAULTS_H */
diff --git a/include/types/global.h b/include/types/global.h
index f7942b35d..23e3f3d53 100644
--- a/include/types/global.h
+++ b/include/types/global.h
@@ -136,6 +136,7 @@ struct global {
int sslprivatecache; /* Force to use a private session cache even if nbproc > 1 */
unsigned int ssllifetime; /* SSL session lifetime in seconds */
unsigned int ssl_max_record; /* SSL max record size */
+ unsigned int ssl_default_dh_param; /* SSL maximum DH parameter size */
#endif
#ifdef USE_ZLIB
int zlibmemlevel; /* zlib memlevel */
diff --git a/src/cfgparse.c b/src/cfgparse.c
index a3edc32d9..06ea63ee3 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -633,6 +633,19 @@ int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
}
global.tune.ssl_max_record = atol(args[1]);
}
+ else if (!strcmp(args[0], "tune.ssl.default-dh-param")) {
+ if (*(args[1]) == 0) {
+ Alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
+ err_code |= ERR_ALERT | ERR_FATAL;
+ goto out;
+ }
+ global.tune.ssl_default_dh_param = atol(args[1]);
+ if (global.tune.ssl_default_dh_param < 1024) {
+ Alert("parsing [%s:%d] : '%s' expects a value >= 1024.\n", file, linenum, args[0]);
+ err_code |= ERR_ALERT | ERR_FATAL;
+ goto out;
+ }
+ }
#endif
else if (!strcmp(args[0], "tune.bufsize")) {
if (*(args[1]) == 0) {
diff --git a/src/haproxy.c b/src/haproxy.c
index 6bfab069c..c4442de81 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -143,6 +143,7 @@ struct global global = {
.chksize = BUFSIZE,
#ifdef USE_OPENSSL
.sslcachesize = SSLCACHESIZE,
+ .ssl_default_dh_param = SSL_DEFAULT_DH_PARAM,
#ifdef DEFAULT_SSL_MAX_RECORD
.ssl_max_record = DEFAULT_SSL_MAX_RECORD,
#endif
diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index b207580b6..bfbb5b8fc 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -314,6 +314,304 @@ static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
#ifndef OPENSSL_NO_DH
+
+static DH * ssl_get_dh_1024(void)
+{
+#if OPENSSL_VERSION_NUMBER < 0x0090801fL
+ static const unsigned char rfc_2409_prime_1024[] = {
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
+ 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
+ 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
+ 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
+ 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
+ 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
+ 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
+ 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
+ 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
+ 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE6,0x53,0x81,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ };
+#endif
+ DH *dh = DH_new();
+ if (dh) {
+#if OPENSSL_VERSION_NUMBER >= 0x0090801fL
+ dh->p = get_rfc2409_prime_1024(NULL);
+#else
+ dh->p = BN_bin2bn(rfc_2409_prime_1024, sizeof rfc_2409_prime_1024, NULL);
+#endif
+ /* See RFC 2409, Section 6 "Oakley Groups"
+ for the reason why 2 is used as generator.
+ */
+ BN_dec2bn(&dh->g, "2");
+ if (!dh->p || !dh->g) {
+ DH_free(dh);
+ dh = NULL;
+ }
+ }
+ return dh;
+}
+
+static DH *ssl_get_dh_2048(void)
+{
+#if OPENSSL_VERSION_NUMBER < 0x0090801fL
+ static const unsigned char rfc_3526_prime_2048[] = {
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
+ 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
+ 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
+ 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
+ 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
+ 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
+ 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
+ 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
+ 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
+ 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
+ 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
+ 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
+ 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
+ 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
+ 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
+ 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
+ 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
+ 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
+ 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
+ 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
+ 0x15,0x72,0x8E,0x5A,0x8A,0xAC,0xAA,0x68,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ };
+#endif
+ DH *dh = DH_new();
+ if (dh) {
+#if OPENSSL_VERSION_NUMBER >= 0x0090801fL
+ dh->p = get_rfc3526_prime_2048(NULL);
+#else
+ dh->p = BN_bin2bn(rfc_3526_prime_2048, sizeof rfc_3526_prime_2048, NULL);
+#endif
+ /* See RFC 3526, Section 3 "2048-bit MODP Group"
+ for the reason why 2 is used as generator.
+ */
+ BN_dec2bn(&dh->g, "2");
+ if (!dh->p || !dh->g) {
+ DH_free(dh);
+ dh = NULL;
+ }
+ }
+ return dh;
+}
+
+static DH *ssl_get_dh_4096(void)
+{
+#if OPENSSL_VERSION_NUMBER < 0x0090801fL
+ static const unsigned char rfc_3526_prime_4096[] = {
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
+ 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
+ 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
+ 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
+ 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
+ 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
+ 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
+ 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
+ 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
+ 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
+ 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
+ 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
+ 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
+ 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
+ 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
+ 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
+ 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
+ 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
+ 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
+ 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
+ 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,
+ 0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,
+ 0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,0x8A,0xEA,0x71,0x57,
+ 0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
+ 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,
+ 0x4A,0x25,0x61,0x9D,0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,
+ 0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,0xD8,0x76,0x02,0x73,
+ 0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
+ 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,
+ 0xBA,0xD9,0x46,0xE2,0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,
+ 0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,0x4B,0x82,0xD1,0x20,
+ 0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
+ 0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,
+ 0x6A,0xF4,0xE2,0x3C,0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,
+ 0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,0xDB,0xBB,0xC2,0xDB,
+ 0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
+ 0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,
+ 0xA0,0x90,0xC3,0xA2,0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,
+ 0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,0xB8,0x1B,0xDD,0x76,
+ 0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
+ 0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,
+ 0x90,0xA6,0xC0,0x8F,0x4D,0xF4,0x35,0xC9,0x34,0x06,0x31,0x99,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ };
+#endif
+ DH *dh = DH_new();
+ if (dh) {
+#if OPENSSL_VERSION_NUMBER >= 0x0090801fL
+ dh->p = get_rfc3526_prime_4096(NULL);
+#else
+ dh->p = BN_bin2bn(rfc_3526_prime_4096, sizeof rfc_3526_prime_4096, NULL);
+#endif
+ /* See RFC 3526, Section 5 "4096-bit MODP Group"
+ for the reason why 2 is used as generator.
+ */
+ BN_dec2bn(&dh->g, "2");
+ if (!dh->p || !dh->g) {
+ DH_free(dh);
+ dh = NULL;
+ }
+ }
+ return dh;
+}
+
+static DH *ssl_get_dh_8192(void)
+{
+#if OPENSSL_VERSION_NUMBER < 0x0090801fL
+ static const unsigned char rfc_3526_prime_8192[] = {
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
+ 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
+ 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
+ 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
+ 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
+ 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
+ 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
+ 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
+ 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
+ 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
+ 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
+ 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
+ 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
+ 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
+ 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
+ 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
+ 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
+ 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
+ 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
+ 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
+ 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,
+ 0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,
+ 0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,0x8A,0xEA,0x71,0x57,
+ 0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
+ 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,
+ 0x4A,0x25,0x61,0x9D,0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,
+ 0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,0xD8,0x76,0x02,0x73,
+ 0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
+ 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,
+ 0xBA,0xD9,0x46,0xE2,0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,
+ 0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,0x4B,0x82,0xD1,0x20,
+ 0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
+ 0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,
+ 0x6A,0xF4,0xE2,0x3C,0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,
+ 0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,0xDB,0xBB,0xC2,0xDB,
+ 0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
+ 0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,
+ 0xA0,0x90,0xC3,0xA2,0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,
+ 0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,0xB8,0x1B,0xDD,0x76,
+ 0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
+ 0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,
+ 0x90,0xA6,0xC0,0x8F,0x4D,0xF4,0x35,0xC9,0x34,0x02,0x84,0x92,
+ 0x36,0xC3,0xFA,0xB4,0xD2,0x7C,0x70,0x26,0xC1,0xD4,0xDC,0xB2,
+ 0x60,0x26,0x46,0xDE,0xC9,0x75,0x1E,0x76,0x3D,0xBA,0x37,0xBD,
+ 0xF8,0xFF,0x94,0x06,0xAD,0x9E,0x53,0x0E,0xE5,0xDB,0x38,0x2F,
+ 0x41,0x30,0x01,0xAE,0xB0,0x6A,0x53,0xED,0x90,0x27,0xD8,0x31,
+ 0x17,0x97,0x27,0xB0,0x86,0x5A,0x89,0x18,0xDA,0x3E,0xDB,0xEB,
+ 0xCF,0x9B,0x14,0xED,0x44,0xCE,0x6C,0xBA,0xCE,0xD4,0xBB,0x1B,
+ 0xDB,0x7F,0x14,0x47,0xE6,0xCC,0x25,0x4B,0x33,0x20,0x51,0x51,
+ 0x2B,0xD7,0xAF,0x42,0x6F,0xB8,0xF4,0x01,0x37,0x8C,0xD2,0xBF,
+ 0x59,0x83,0xCA,0x01,0xC6,0x4B,0x92,0xEC,0xF0,0x32,0xEA,0x15,
+ 0xD1,0x72,0x1D,0x03,0xF4,0x82,0xD7,0xCE,0x6E,0x74,0xFE,0xF6,
+ 0xD5,0x5E,0x70,0x2F,0x46,0x98,0x0C,0x82,0xB5,0xA8,0x40,0x31,
+ 0x90,0x0B,0x1C,0x9E,0x59,0xE7,0xC9,0x7F,0xBE,0xC7,0xE8,0xF3,
+ 0x23,0xA9,0x7A,0x7E,0x36,0xCC,0x88,0xBE,0x0F,0x1D,0x45,0xB7,
+ 0xFF,0x58,0x5A,0xC5,0x4B,0xD4,0x07,0xB2,0x2B,0x41,0x54,0xAA,
+ 0xCC,0x8F,0x6D,0x7E,0xBF,0x48,0xE1,0xD8,0x14,0xCC,0x5E,0xD2,
+ 0x0F,0x80,0x37,0xE0,0xA7,0x97,0x15,0xEE,0xF2,0x9B,0xE3,0x28,
+ 0x06,0xA1,0xD5,0x8B,0xB7,0xC5,0xDA,0x76,0xF5,0x50,0xAA,0x3D,
+ 0x8A,0x1F,0xBF,0xF0,0xEB,0x19,0xCC,0xB1,0xA3,0x13,0xD5,0x5C,
+ 0xDA,0x56,0xC9,0xEC,0x2E,0xF2,0x96,0x32,0x38,0x7F,0xE8,0xD7,
+ 0x6E,0x3C,0x04,0x68,0x04,0x3E,0x8F,0x66,0x3F,0x48,0x60,0xEE,
+ 0x12,0xBF,0x2D,0x5B,0x0B,0x74,0x74,0xD6,0xE6,0x94,0xF9,0x1E,
+ 0x6D,0xBE,0x11,0x59,0x74,0xA3,0x92,0x6F,0x12,0xFE,0xE5,0xE4,
+ 0x38,0x77,0x7C,0xB6,0xA9,0x32,0xDF,0x8C,0xD8,0xBE,0xC4,0xD0,
+ 0x73,0xB9,0x31,0xBA,0x3B,0xC8,0x32,0xB6,0x8D,0x9D,0xD3,0x00,
+ 0x74,0x1F,0xA7,0xBF,0x8A,0xFC,0x47,0xED,0x25,0x76,0xF6,0x93,
+ 0x6B,0xA4,0x24,0x66,0x3A,0xAB,0x63,0x9C,0x5A,0xE4,0xF5,0x68,
+ 0x34,0x23,0xB4,0x74,0x2B,0xF1,0xC9,0x78,0x23,0x8F,0x16,0xCB,
+ 0xE3,0x9D,0x65,0x2D,0xE3,0xFD,0xB8,0xBE,0xFC,0x84,0x8A,0xD9,
+ 0x22,0x22,0x2E,0x04,0xA4,0x03,0x7C,0x07,0x13,0xEB,0x57,0xA8,
+ 0x1A,0x23,0xF0,0xC7,0x34,0x73,0xFC,0x64,0x6C,0xEA,0x30,0x6B,
+ 0x4B,0xCB,0xC8,0x86,0x2F,0x83,0x85,0xDD,0xFA,0x9D,0x4B,0x7F,
+ 0xA2,0xC0,0x87,0xE8,0x79,0x68,0x33,0x03,0xED,0x5B,0xDD,0x3A,
+ 0x06,0x2B,0x3C,0xF5,0xB3,0xA2,0x78,0xA6,0x6D,0x2A,0x13,0xF8,
+ 0x3F,0x44,0xF8,0x2D,0xDF,0x31,0x0E,0xE0,0x74,0xAB,0x6A,0x36,
+ 0x45,0x97,0xE8,0x99,0xA0,0x25,0x5D,0xC1,0x64,0xF3,0x1C,0xC5,
+ 0x08,0x46,0x85,0x1D,0xF9,0xAB,0x48,0x19,0x5D,0xED,0x7E,0xA1,
+ 0xB1,0xD5,0x10,0xBD,0x7E,0xE7,0x4D,0x73,0xFA,0xF3,0x6B,0xC3,
+ 0x1E,0xCF,0xA2,0x68,0x35,0x90,0x46,0xF4,0xEB,0x87,0x9F,0x92,
+ 0x40,0x09,0x43,0x8B,0x48,0x1C,0x6C,0xD7,0x88,0x9A,0x00,0x2E,
+ 0xD5,0xEE,0x38,0x2B,0xC9,0x19,0x0D,0xA6,0xFC,0x02,0x6E,0x47,
+ 0x95,0x58,0xE4,0x47,0x56,0x77,0xE9,0xAA,0x9E,0x30,0x50,0xE2,
+ 0x76,0x56,0x94,0xDF,0xC8,0x1F,0x56,0xE8,0x80,0xB9,0x6E,0x71,
+ 0x60,0xC9,0x80,0xDD,0x98,0xED,0xD3,0xDF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ };
+#endif
+ DH *dh = DH_new();
+ if (dh) {
+#if OPENSSL_VERSION_NUMBER >= 0x0090801fL
+ dh->p = get_rfc3526_prime_8192(NULL);
+#else
+ dh->p = BN_bin2bn(rfc_3526_prime_8192, sizeof rfc_3526_prime_8192, NULL);
+#endif
+ /* See RFC 3526, Section 7 "8192-bit MODP Group"
+ for the reason why 2 is used as generator.
+ */
+ BN_dec2bn(&dh->g, "2");
+ if (!dh->p || !dh->g) {
+ DH_free(dh);
+ dh = NULL;
+ }
+ }
+ return dh;
+}
+
+/* Returns Diffie-Hellman parameters matching the private key length
+ but not exceeding global.tune.ssl_default_dh_param */
+static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
+{
+ DH *dh = NULL;
+ EVP_PKEY *pkey = SSL_get_privatekey(ssl);
+ int type = pkey ? EVP_PKEY_type(pkey->type) : EVP_PKEY_NONE;
+
+ /* The keylen supplied by OpenSSL can only be 512 or 1024.
+ See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
+ */
+ if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
+ keylen = EVP_PKEY_bits(pkey);
+ }
+
+ if (keylen > global.tune.ssl_default_dh_param) {
+ keylen = global.tune.ssl_default_dh_param;
+ }
+
+ if (keylen >= 8192) {
+ dh = ssl_get_dh_8192();
+ }
+ else if (keylen >= 4096) {
+ dh = ssl_get_dh_4096();
+ }
+ else if (keylen >= 2048) {
+ dh = ssl_get_dh_2048();
+ }
+ else {
+ dh = ssl_get_dh_1024();
+ }
+
+ return dh;
+}
+
/* 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)
@@ -321,29 +619,6 @@ int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
int ret = -1;
BIO *in;
DH *dh = NULL;
- /* If not present, use parameters generated using 'openssl dhparam 1024 -C':
- * -----BEGIN DH PARAMETERS-----
- * MIGHAoGBAJJAJDXDoS5E03MNjnjK36eOL1tRqVa/9NuOVlI+lpXmPjJQbP65EvKn
- * fSLnG7VMhoCJO4KtG88zf393ltP7loGB2bofcDSr+x+XsxBM8yA/Zj6BmQt+CQ9s
- * TF7hoOV+wXTT6ErZ5y5qx9pq6hLfKXwTGFT78hrE6HnCO7xgtPdTAgEC
- * -----END DH PARAMETERS-----
- */
- static const unsigned char dh1024_p[] = {
- 0x92, 0x40, 0x24, 0x35, 0xC3, 0xA1, 0x2E, 0x44, 0xD3, 0x73, 0x0D, 0x8E,
- 0x78, 0xCA, 0xDF, 0xA7, 0x8E, 0x2F, 0x5B, 0x51, 0xA9, 0x56, 0xBF, 0xF4,
- 0xDB, 0x8E, 0x56, 0x52, 0x3E, 0x96, 0x95, 0xE6, 0x3E, 0x32, 0x50, 0x6C,
- 0xFE, 0xB9, 0x12, 0xF2, 0xA7, 0x7D, 0x22, 0xE7, 0x1B, 0xB5, 0x4C, 0x86,
- 0x80, 0x89, 0x3B, 0x82, 0xAD, 0x1B, 0xCF, 0x33, 0x7F, 0x7F, 0x77, 0x96,
- 0xD3, 0xFB, 0x96, 0x81, 0x81, 0xD9, 0xBA, 0x1F, 0x70, 0x34, 0xAB, 0xFB,
- 0x1F, 0x97, 0xB3, 0x10, 0x4C, 0xF3, 0x20, 0x3F, 0x66, 0x3E, 0x81, 0x99,
- 0x0B, 0x7E, 0x09, 0x0F, 0x6C, 0x4C, 0x5E, 0xE1, 0xA0, 0xE5, 0x7E, 0xC1,
- 0x74, 0xD3, 0xE8, 0x4A, 0xD9, 0xE7, 0x2E, 0x6A, 0xC7, 0xDA, 0x6A, 0xEA,
- 0x12, 0xDF, 0x29, 0x7C, 0x13, 0x18, 0x54, 0xFB, 0xF2, 0x1A, 0xC4, 0xE8,
- 0x79, 0xC2, 0x3B, 0xBC, 0x60, 0xB4, 0xF7, 0x53,
- };
- static const unsigned char dh1024_g[] = {
- 0x02,
- };
in = BIO_new(BIO_s_file());
if (in == NULL)
@@ -353,28 +628,32 @@ int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
goto end;
dh = PEM_read_bio_DHparams(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
- if (!dh) {
+ if (dh) {
+ ret = 1;
+ SSL_CTX_set_tmp_dh(ctx, dh);
+ /* Setting ssl default dh param to the size of the static DH params
+ found in the file. This way we know that there is no use
+ complaining later about ssl-default-dh-param not being set. */
+ global.tune.ssl_default_dh_param = DH_size(dh) * 8;
+ }
+ else {
/* Clear openssl global errors stack */
ERR_clear_error();
- dh = DH_new();
- if (dh == NULL)
- goto end;
-
- dh->p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL);
- if (dh->p == NULL)
- goto end;
+ if (global.tune.ssl_default_dh_param <= 1024) {
+ /* we are limited to DH parameter of 1024 bits anyway */
+ dh = ssl_get_dh_1024();
+ if (dh == NULL)
+ goto end;
- dh->g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL);
- if (dh->g == NULL)
- goto end;
+ SSL_CTX_set_tmp_dh(ctx, dh);
+ }
+ else {
+ SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
+ }
ret = 0; /* DH params not found */
}
- else
- ret = 1;
-
- SSL_CTX_set_tmp_dh(ctx, dh);
end:
if (dh)
@@ -724,6 +1003,7 @@ int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct
#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
#define SSL_MODE_RELEASE_BUFFERS 0
#endif
+
int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
{
int cfgerr = 0;
@@ -740,6 +1020,14 @@ int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy
SSL_MODE_ENABLE_PARTIAL_WRITE |
SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
SSL_MODE_RELEASE_BUFFERS;
+ STACK_OF(SSL_CIPHER) * ciphers = NULL;
+ SSL_CIPHER * cipher = NULL;
+ const char * cipher_name = NULL;
+ /* The name of ciphers using an Ephemeral Diffie Hellman key exchange
+ starts with "EDH". */
+ const char edh_name[] = "EDH";
+ int idx = 0;
+ int dhe_found = 0;
/* Make sure openssl opens /dev/urandom before the chroot */
if (!ssl_initialize_random()) {
@@ -828,6 +1116,29 @@ 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 (global.tune.ssl_default_dh_param == 0) {
+ ciphers = ctx->cipher_list;
+
+ if (ciphers) {
+ for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
+ cipher = sk_SSL_CIPHER_value(ciphers, idx);
+ cipher_name = SSL_CIPHER_get_name(cipher);
+ if (strncmp(cipher_name, edh_name, sizeof (edh_name)-1) == 0) {
+ dhe_found = 1;
+ break;
+ }
+ }
+
+ if (dhe_found) {
+ Warning("Setting tune.ssl.default-dh-param to 1024 by default, if your workload permits it you should set it to at least 2048. Please set a value >= 1024 to make this warning disappear.\n");
+ }
+ }
+
+ global.tune.ssl_default_dh_param = 1024;
+ }
+
SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
#if OPENSSL_VERSION_NUMBER >= 0x00907000L
SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);