libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

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:
MChangeLog | 4++++
Mdoc/libmicrohttpd.texi | 17+++++++++++++++--
Msrc/include/microhttpd.h | 10+++++++++-
Msrc/microhttpd/daemon.c | 36+++++++++++++++++++++++++++++++++---
Msrc/microhttpd/internal.h | 5+++++
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;