You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

101 lines
3.0 KiB

  1. From 60d7aeb6e1450995e721d01f48f60b7db4c44e2b Mon Sep 17 00:00:00 2001
  2. From: Remi Gacogne <rgacogne[at]aquaray[dot]fr>
  3. Date: Tue, 15 Jul 2014 11:36:40 +0200
  4. Subject: [PATCH 3/3] BUG/MEDIUM: ssl: Fix a memory leak in DHE key exchange
  5. OpenSSL does not free the DH * value returned by the callback specified with SSL_CTX_set_tmp_dh_callback(),
  6. leading to a memory leak for SSL/TLS connections using Diffie Hellman Ephemeral key exchange.
  7. This patch fixes the leak by allocating the DH * structs holding the DH parameters once, at configuration time.
  8. Note: this fix must be backported to 1.5.
  9. (cherry picked from commit 8de5415b85512da871d58d1e9a0a33bd67f3b570)
  10. ---
  11. src/ssl_sock.c | 43 ++++++++++++++++++++++++++++++++++++-------
  12. 1 file changed, 36 insertions(+), 7 deletions(-)
  13. diff --git a/src/ssl_sock.c b/src/ssl_sock.c
  14. index 375225d..cf8adc7 100644
  15. --- a/src/ssl_sock.c
  16. +++ b/src/ssl_sock.c
  17. @@ -105,6 +105,13 @@ enum {
  18. int sslconns = 0;
  19. int totalsslconns = 0;
  20. +#ifndef OPENSSL_NO_DH
  21. +static DH *local_dh_1024 = NULL;
  22. +static DH *local_dh_2048 = NULL;
  23. +static DH *local_dh_4096 = NULL;
  24. +static DH *local_dh_8192 = NULL;
  25. +#endif /* OPENSSL_NO_DH */
  26. +
  27. #ifdef SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB
  28. struct certificate_ocsp {
  29. struct ebmb_node key;
  30. @@ -1034,16 +1041,16 @@ static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
  31. }
  32. if (keylen >= 8192) {
  33. - dh = ssl_get_dh_8192();
  34. + dh = local_dh_8192;
  35. }
  36. else if (keylen >= 4096) {
  37. - dh = ssl_get_dh_4096();
  38. + dh = local_dh_4096;
  39. }
  40. else if (keylen >= 2048) {
  41. - dh = ssl_get_dh_2048();
  42. + dh = local_dh_2048;
  43. }
  44. else {
  45. - dh = ssl_get_dh_1024();
  46. + dh = local_dh_1024;
  47. }
  48. return dh;
  49. @@ -1079,11 +1086,11 @@ int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
  50. if (global.tune.ssl_default_dh_param <= 1024) {
  51. /* we are limited to DH parameter of 1024 bits anyway */
  52. - dh = ssl_get_dh_1024();
  53. - if (dh == NULL)
  54. + local_dh_1024 = ssl_get_dh_1024();
  55. + if (local_dh_1024 == NULL)
  56. goto end;
  57. - SSL_CTX_set_tmp_dh(ctx, dh);
  58. + SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
  59. }
  60. else {
  61. SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
  62. @@ -1594,6 +1601,28 @@ int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy
  63. global.tune.ssl_default_dh_param = 1024;
  64. }
  65. +#ifndef OPENSSL_NO_DH
  66. + if (global.tune.ssl_default_dh_param >= 1024) {
  67. + if (local_dh_1024 == NULL) {
  68. + local_dh_1024 = ssl_get_dh_1024();
  69. + }
  70. + if (global.tune.ssl_default_dh_param >= 2048) {
  71. + if (local_dh_2048 == NULL) {
  72. + local_dh_2048 = ssl_get_dh_2048();
  73. + }
  74. + if (global.tune.ssl_default_dh_param >= 4096) {
  75. + if (local_dh_4096 == NULL) {
  76. + local_dh_4096 = ssl_get_dh_4096();
  77. + }
  78. + if (global.tune.ssl_default_dh_param >= 8192 &&
  79. + local_dh_8192 == NULL) {
  80. + local_dh_8192 = ssl_get_dh_8192();
  81. + }
  82. + }
  83. + }
  84. + }
  85. +#endif /* OPENSSL_NO_DH */
  86. +
  87. SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
  88. #if OPENSSL_VERSION_NUMBER >= 0x00907000L
  89. SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
  90. --
  91. 1.8.5.5