commit 19183a161c18f339f7a34894973c254086adb81d
parent a12c532cba2af140f041081a5a2734355358cac1
Author: Christian Grothoff <christian@grothoff.org>
Date: Sun, 8 Feb 2015 00:37:10 +0000
adding MHD_OPTION_HTTPS_KEY_PASSWORD
Diffstat:
5 files changed, 66 insertions(+), 6 deletions(-)
diff --git a/ChangeLog b/ChangeLog
@@ -1,3 +1,7 @@
+Sun Feb 8 01:24:38 CET 2015
+ Adding MHD_OPTION_HTTPS_KEY_PASSWORD as proposed by
+ Andrew Basile. -CG/AB
+
Wed Feb 4 20:34:22 CET 2015
Fix issue where for HTTP/1.0-clients that set
Connection: Keep-Alive header a response of
diff --git a/doc/libmicrohttpd.texi b/doc/libmicrohttpd.texi
@@ -661,6 +661,19 @@ HTTPS daemon. This option should be followed by an
"const char*" argument.
This should be used in conjunction with 'MHD_OPTION_HTTPS_MEM_CERT'.
+@item MHD_OPTION_HTTPS_KEY_PASSWORD
+@cindex SSL
+@cindex TLS
+Memory pointer to the password that decrypts the
+private key to be used by the HTTPS daemon.
+This option should be followed by an
+"const char*" argument.
+This should be used in conjunction with 'MHD_OPTION_HTTPS_MEM_KEY'.
+
+The password (or passphrase) is only used immediately during
+@code{MHD_start_daemon()}. Thus, the application may want to
+erase it from memory afterwards for additional security.
+
@item MHD_OPTION_HTTPS_MEM_CERT
@cindex SSL
@cindex TLS
@@ -1103,14 +1116,14 @@ data is available, the first time the callback is
invoked there won't be upload data, as this is done
just after MHD parses the headers. If supported by
the client and the HTTP version, the application can
-at this point queue an error response to possibly
+at this point queue an error response to possibly
avoid the upload entirely. If no response is generated,
MHD will (if required) automatically send a 100 CONTINUE
reply to the client.
Afterwards, POST data will be passed to the callback
to be processed incrementally by the application. The
-application may return @code{MHD_NO} to forcefully
+application may return @code{MHD_NO} to forcefully
terminate the TCP connection without generating a
proper HTTP response. Once all of the upload data has
been provided to the application, the application
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 0x00093902
+#define MHD_VERSION 0x00093903
/**
* MHD-internal return code for "YES".
@@ -863,6 +863,14 @@ enum MHD_OPTION
* This option must be followed by a `unsigned int` argument.
*/
MHD_OPTION_LISTENING_ADDRESS_REUSE = 25,
+
+ /**
+ * Memory pointer for a password that decrypts the private key (key.pem)
+ * to be used by the HTTPS daemon. This option should be followed by a
+ * `const char *` argument.
+ * This should be used in conjunction with #MHD_OPTION_HTTPS_MEM_KEY.
+ */
+ MHD_OPTION_HTTPS_KEY_PASSWORD = 26
};
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
@@ -508,6 +508,7 @@ MHD_init_daemon_certificate (struct MHD_Daemon *daemon)
{
gnutls_datum_t key;
gnutls_datum_t cert;
+ int ret;
#if GNUTLS_VERSION_MAJOR >= 3
if (NULL != daemon->cert_callback)
@@ -545,9 +546,24 @@ MHD_init_daemon_certificate (struct MHD_Daemon *daemon)
cert.data = (unsigned char *) daemon->https_mem_cert;
cert.size = strlen (daemon->https_mem_cert);
- return gnutls_certificate_set_x509_key_mem (daemon->x509_cred,
- &cert, &key,
- GNUTLS_X509_FMT_PEM);
+ if (NULL != daemon->https_key_password)
+ ret = gnutls_certificate_set_x509_key_mem2 (daemon->x509_cred,
+ &cert, &key,
+ GNUTLS_X509_FMT_PEM,
+ daemon->https_key_password,
+ 0);
+
+ else
+ ret = gnutls_certificate_set_x509_key_mem (daemon->x509_cred,
+ &cert, &key,
+ GNUTLS_X509_FMT_PEM);
+#if HAVE_MESSAGES
+ if (0 != ret)
+ MHD_DLOG (daemon,
+ "GnuTLS failed to setup x509 certificate/key: %s\n",
+ gnutls_strerror (ret));
+#endif
+ return ret;
}
#if GNUTLS_VERSION_MAJOR >= 3
if (NULL != daemon->cert_callback)
@@ -3002,6 +3018,16 @@ parse_options_va (struct MHD_Daemon *daemon,
opt);
#endif
break;
+ case MHD_OPTION_HTTPS_KEY_PASSWORD:
+ if (0 != (daemon->options & MHD_USE_SSL))
+ daemon->https_key_password = va_arg (ap, const char *);
+#if HAVE_MESSAGES
+ else
+ MHD_DLOG (daemon,
+ "MHD HTTPS option %d passed to MHD but MHD_USE_SSL not set\n",
+ opt);
+#endif
+ break;
case MHD_OPTION_HTTPS_MEM_CERT:
if (0 != (daemon->options & MHD_USE_SSL))
daemon->https_mem_cert = va_arg (ap, const char *);
@@ -3183,6 +3209,7 @@ parse_options_va (struct MHD_Daemon *daemon,
/* all options taking one pointer */
case MHD_OPTION_SOCK_ADDR:
case MHD_OPTION_HTTPS_MEM_KEY:
+ case MHD_OPTION_HTTPS_KEY_PASSWORD:
case MHD_OPTION_HTTPS_MEM_CERT:
case MHD_OPTION_HTTPS_MEM_TRUST:
case MHD_OPTION_HTTPS_PRIORITIES:
@@ -4049,6 +4076,9 @@ MHD_start_daemon_va (unsigned int flags,
}
}
}
+ /* API promises to never use the password after initialization,
+ so we additionally NULL it here to not deref a dangling pointer. */
+ daemon->https_key_password = NULL;
return daemon;
thread_failed:
diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h
@@ -1205,6 +1205,11 @@ struct MHD_Daemon
const char *https_mem_cert;
/**
+ * Pointer to 0-terminated HTTPS passphrase in memory.
+ */
+ const char *https_key_password;
+
+ /**
* Pointer to our SSL/TLS certificate authority (in ASCII) in memory.
*/
const char *https_mem_trust;