commit ca3a7d621cf9582089642e159d9feb75823d0449
parent 8172eecea0e181426c4d5949e268103b22ade4f2
Author: Christian Grothoff <christian@grothoff.org>
Date: Mon, 7 Apr 2014 11:27:18 +0000
add MHD_OPTION_HTTPS_MEM_DHPARAMS to support PFS
Diffstat:
6 files changed, 96 insertions(+), 18 deletions(-)
diff --git a/AUTHORS b/AUTHORS
@@ -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>
diff --git a/ChangeLog b/ChangeLog
@@ -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
diff --git a/doc/libmicrohttpd.texi b/doc/libmicrohttpd.texi
@@ -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
diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h
@@ -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
};
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
@@ -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])
{
diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h
@@ -1194,6 +1194,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
* event-loop timeout (as it needs to be zero if there is any connection