add MHD_OPTION_HTTPS_MEM_DHPARAMS to support PFS

This commit is contained in:
Christian Grothoff
2014-04-07 11:27:18 +00:00
parent 8172eecea0
commit ca3a7d621c
6 changed files with 96 additions and 18 deletions
+2 -1
View File
@@ -46,8 +46,9 @@ Matthew Mundell <matthew.mundell@greenbone.net>
Scott Goldman <scottjg@github.com>
Jared Cantwell
Luke-Jr <luke@dashjr.org>
Evgeny Grin (Karlson2k) <k2k@narod.ru>
Sree Harsha Totakura <sreeharsha@totakura.in>
Evgeny Grin (Karlson2k) <k2k@narod.ru>
Hani Benhabiles <kroosec@gmail.com>
Documentation contributions also came from:
Marco Maggi <marco.maggi-ipsu@poste.it>
+4
View File
@@ -1,3 +1,7 @@
Mon Apr 7 13:25:30 CEST 2014
Add MHD_OPTION_HTTPS_MEM_DHPARAMS to allow applications
to enable PFS. -HB/CG
Tue Apr 01 07:10:23 CET 2014
Added usage of native mutex on W32. -EG
+11 -1
View File
@@ -360,7 +360,7 @@ for the specific platform.
@section Portability to W32
libmicrohttpd in general ported well to W32. Most libmicrohttpd features
are supported. W32 do not support some functions, like epoll and
are supported. W32 do not support some functions, like epoll and
corresponding MHD features are not available on W32.
@@ -847,6 +847,16 @@ associate state until handshake is completed. If this option is not
given the queue size is set to a default value of 10. This option must
be followed by a @code{unsigned int}.
@item MHD_OPTION_HTTPS_MEM_DHPARAMS
@cindex TLS
@cindex SSL
@cindex DH
Memory pointer for the Diffie-Hellman parameters (dh.pem) to be used
by the HTTPS daemon for key exchange. This option must be followed by
a @code{const char *} argument. The argument would be a GNUtls
property string, such as ``NORMAL:+DHE-RSA''. This option is needed
to activate ciphersuites with so-called ``Perfect Forward Secrecy''
property.
@end table
@end deftp
+10 -3
View File
@@ -130,7 +130,7 @@ typedef intptr_t ssize_t;
* Current version of the library.
* 0x01093001 = 1.9.30-1.
*/
#define MHD_VERSION 0x00093400
#define MHD_VERSION 0x00093401
/**
* MHD-internal return code for "YES".
@@ -837,7 +837,14 @@ enum MHD_OPTION
* resources for the SYN packet along with its DATA. This option should be
* followed by an `unsigned int` argument.
*/
MHD_OPTION_TCP_FASTOPEN_QUEUE_SIZE = 23
MHD_OPTION_TCP_FASTOPEN_QUEUE_SIZE = 23,
/**
* Memory pointer for the Diffie-Hellman parameters (dh.pem) to be used by the
* HTTPS daemon for key exchange.
* This option must be followed by a `const char *` argument.
*/
MHD_OPTION_HTTPS_MEM_DHPARAMS = 24
};
@@ -2448,7 +2455,7 @@ enum MHD_FEATURE
* #MHD_destroy_post_processor, #MHD_destroy_post_processor can
* be used.
*/
MHD_FEATURE_POSTPROCESSOR = 13,
MHD_FEATURE_POSTPROCESSOR = 13
};
+59 -13
View File
@@ -520,6 +520,11 @@ MHD_init_daemon_certificate (struct MHD_Daemon *daemon)
}
}
if (MHD_YES == daemon->have_dhparams)
{
gnutls_certificate_set_dh_params (daemon->x509_cred,
daemon->https_mem_dhparams);
}
/* certificate & key loaded from memory */
if ( (NULL != daemon->https_mem_cert) &&
(NULL != daemon->https_mem_key) )
@@ -2968,6 +2973,42 @@ parse_options_va (struct MHD_Daemon *daemon,
case MHD_OPTION_HTTPS_CRED_TYPE:
daemon->cred_type = (gnutls_credentials_type_t) va_arg (ap, int);
break;
case MHD_OPTION_HTTPS_MEM_DHPARAMS:
if (0 != (daemon->options & MHD_USE_SSL))
{
const char *arg = va_arg (ap, const unsigned char *);
gnutls_datum_t dhpar;
if (gnutls_dh_params_init (&daemon->https_mem_dhparams) < 0)
{
#if HAVE_MESSAGES
MHD_DLOG(daemon, "Error initializing DH parameters\n");
#endif
return MHD_NO;
}
dhpar.data = (unsigned char *) arg;
dhpar.size = strlen (arg);
if (gnutls_dh_params_import_pkcs3 (daemon->https_mem_dhparams, &dhpar,
GNUTLS_X509_FMT_PEM) < 0)
{
#if HAVE_MESSAGES
MHD_DLOG(daemon, "Bad Diffie-Hellman parameters format\n");
#endif
gnutls_dh_params_deinit (daemon->https_mem_dhparams);
return MHD_NO;
}
daemon->have_dhparams = MHD_YES;
}
else
{
#if HAVE_MESSAGES
MHD_DLOG (daemon,
"MHD HTTPS option %d passed to MHD but MHD_USE_SSL not set\n",
opt);
#endif
return MHD_NO;
}
break;
case MHD_OPTION_HTTPS_PRIORITIES:
if (0 != (daemon->options & MHD_USE_SSL))
{
@@ -3706,7 +3747,7 @@ MHD_start_daemon_va (unsigned int flags,
MHD_DLOG (daemon,
"MHD failed to initialize IP connection limit mutex\n");
#endif
MHD_mutex_destroy_ (&daemon->cleanup_connection_mutex);
(void) MHD_mutex_destroy_ (&daemon->cleanup_connection_mutex);
if ( (MHD_INVALID_SOCKET != socket_fd) &&
(0 != MHD_socket_close_ (socket_fd)) )
MHD_PANIC ("close failed\n");
@@ -3724,8 +3765,8 @@ MHD_start_daemon_va (unsigned int flags,
if ( (MHD_INVALID_SOCKET != socket_fd) &&
(0 != MHD_socket_close_ (socket_fd)) )
MHD_PANIC ("close failed\n");
MHD_mutex_destroy_ (&daemon->cleanup_connection_mutex);
MHD_mutex_destroy_ (&daemon->per_ip_connection_mutex);
(void) MHD_mutex_destroy_ (&daemon->cleanup_connection_mutex);
(void) MHD_mutex_destroy_ (&daemon->per_ip_connection_mutex);
goto free_and_fail;
}
#endif
@@ -3741,8 +3782,8 @@ MHD_start_daemon_va (unsigned int flags,
"Failed to create listen thread: %s\n",
MHD_strerror_ (res_thread_create));
#endif
MHD_mutex_destroy_ (&daemon->cleanup_connection_mutex);
MHD_mutex_destroy_ (&daemon->per_ip_connection_mutex);
(void) MHD_mutex_destroy_ (&daemon->cleanup_connection_mutex);
(void) MHD_mutex_destroy_ (&daemon->per_ip_connection_mutex);
if ( (MHD_INVALID_SOCKET != socket_fd) &&
(0 != MHD_socket_close_ (socket_fd)) )
MHD_PANIC ("close failed\n");
@@ -3861,7 +3902,7 @@ MHD_start_daemon_va (unsigned int flags,
#endif
/* Free memory for this worker; cleanup below handles
* all previously-created workers. */
MHD_mutex_destroy_ (&d->cleanup_connection_mutex);
(void) MHD_mutex_destroy_ (&d->cleanup_connection_mutex);
goto thread_failed;
}
}
@@ -3878,8 +3919,8 @@ thread_failed:
if ( (MHD_INVALID_SOCKET != socket_fd) &&
(0 != MHD_socket_close_ (socket_fd)) )
MHD_PANIC ("close failed\n");
MHD_mutex_destroy_ (&daemon->cleanup_connection_mutex);
MHD_mutex_destroy_ (&daemon->per_ip_connection_mutex);
(void) MHD_mutex_destroy_ (&daemon->cleanup_connection_mutex);
(void) MHD_mutex_destroy_ (&daemon->per_ip_connection_mutex);
if (NULL != daemon->worker_pool)
free (daemon->worker_pool);
goto free_and_fail;
@@ -3902,7 +3943,7 @@ thread_failed:
#endif
#ifdef DAUTH_SUPPORT
free (daemon->nnc);
MHD_mutex_destroy_ (&daemon->nnc_lock);
(void) MHD_mutex_destroy_ (&daemon->nnc_lock);
#endif
#if HTTPS_SUPPORT
if (0 != (flags & MHD_USE_SSL))
@@ -4091,7 +4132,7 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
if (0 != (rc = pthread_join (daemon->worker_pool[i].pid, &unused)))
MHD_PANIC ("Failed to join a thread\n");
close_all_connections (&daemon->worker_pool[i]);
MHD_mutex_destroy_ (&daemon->worker_pool[i].cleanup_connection_mutex);
(void) MHD_mutex_destroy_ (&daemon->worker_pool[i].cleanup_connection_mutex);
#if EPOLL_SUPPORT
if ( (-1 != daemon->worker_pool[i].epoll_fd) &&
(0 != MHD_socket_close_ (daemon->worker_pool[i].epoll_fd)) )
@@ -4130,6 +4171,11 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
/* TLS clean up */
#if HTTPS_SUPPORT
if (MHD_YES == daemon->have_dhparams)
{
gnutls_dh_params_deinit (daemon->https_mem_dhparams);
daemon->have_dhparams = MHD_NO;
}
if (0 != (daemon->options & MHD_USE_SSL))
{
gnutls_priority_deinit (daemon->priority_cache);
@@ -4146,10 +4192,10 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
#ifdef DAUTH_SUPPORT
free (daemon->nnc);
MHD_mutex_destroy_ (&daemon->nnc_lock);
(void) MHD_mutex_destroy_ (&daemon->nnc_lock);
#endif
MHD_mutex_destroy_ (&daemon->per_ip_connection_mutex);
MHD_mutex_destroy_ (&daemon->cleanup_connection_mutex);
(void) MHD_mutex_destroy_ (&daemon->per_ip_connection_mutex);
(void) MHD_mutex_destroy_ (&daemon->cleanup_connection_mutex);
if (MHD_INVALID_PIPE_ != daemon->wpipe[1])
{
+10
View File
@@ -1193,6 +1193,16 @@ struct MHD_Daemon
*/
const char *https_mem_trust;
/**
* Our Diffie-Hellman parameters in memory.
*/
gnutls_dh_params_t https_mem_dhparams;
/**
* #MHD_YES if we have initialized @e https_mem_dhparams.
*/
int have_dhparams;
/**
* For how many connections do we have 'tls_read_ready' set to MHD_YES?
* Used to avoid O(n) traversal over all connections when determining