[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] [libmicrohttpd] 02/03: integrate TLS PSK patch from Tal Moa
From: |
gnunet |
Subject: |
[GNUnet-SVN] [libmicrohttpd] 02/03: integrate TLS PSK patch from Tal Moaz (plus documentation, plus style and bugfixes |
Date: |
Sat, 14 Jul 2018 14:41:44 +0200 |
This is an automated email from the git hooks/post-receive script.
grothoff pushed a commit to branch master
in repository libmicrohttpd.
commit 2c47a23dec110fb77e1cda36d6bdb83fc4d5e252
Author: Christian Grothoff <address@hidden>
AuthorDate: Sat Jul 14 11:44:01 2018 +0200
integrate TLS PSK patch from Tal Moaz (plus documentation, plus style and
bugfixes
---
AUTHORS | 1 +
ChangeLog | 4 ++
doc/libmicrohttpd.texi | 10 +++++
src/include/microhttpd.h | 38 ++++++++++++++++---
src/include/microhttpd2.h | 35 ++++++++++++++++++
src/microhttpd/daemon.c | 94 ++++++++++++++++++++++++++++++++++++++++++++---
src/microhttpd/internal.h | 15 ++++++++
7 files changed, 187 insertions(+), 10 deletions(-)
diff --git a/AUTHORS b/AUTHORS
index 62b8c244..42f3a9c9 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -58,6 +58,7 @@ Louis Benoit <address@hidden>
Flavio Coelin <address@hidden>
Silvio Clecio <address@hidden>
Robert D Kosisko <address@hidden>
+Tal Moaz <address@hidden>
Documentation contributions also came from:
Marco Maggi <address@hidden>
diff --git a/ChangeLog b/ChangeLog
index 1c4ddd61..dbeccbd8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+Sat Jul 14 11:42:15 CEST 2018
+ Add MHD_OPTION_GNUTLS_PSK_CRED_HANDLER to allow use of PSK with
+ TLS connections. -CG/TM
+
Sat Jul 14 11:03:37 CEST 2018
Integrate patch for checking digest authentication based on
a digest, allowing servers to store passwords only hashed.
diff --git a/doc/libmicrohttpd.texi b/doc/libmicrohttpd.texi
index e4437441..d2886a25 100644
--- a/doc/libmicrohttpd.texi
+++ b/doc/libmicrohttpd.texi
@@ -869,6 +869,16 @@ information provided. The callback is expected to access
the SNI data
using gnutls_server_name_get(). Using this option requires GnuTLS 3.0
or higher.
address@hidden MHD_OPTION_GNUTLS_PSK_CRED_HANDLER
address@hidden SSL
address@hidden TLS
address@hidden PSK
+Use pre-shared key for TLS credentials.
+Pass a pointer to callback of type
address@hidden and a closure.
+The function will be called to
+retrieve the shared key for a given username.
+
@item MHD_OPTION_DIGEST_AUTH_RANDOM
@cindex digest auth
@cindex random
diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h
index cdbde609..f43935c7 100644
--- a/src/include/microhttpd.h
+++ b/src/include/microhttpd.h
@@ -1167,6 +1167,25 @@ typedef void
/**
+ * Function called to lookup the pre shared key (@a psk) for a given
+ * HTTP connection based on the @a username.
+ *
+ * @param cls closure
+ * @param connection the HTTPS connection
+ * @param username the user name claimed by the other side
+ * @param psk[out] to be set to the pre-shared-key; should be allocated with
malloc(),
+ * will be freed by MHD
+ * @param psk_size[out] to be set to the number of bytes in @a psk
+ * @return 0 on success, -1 on errors
+ */
+typedef int
+(*MHD_PskServerCredentialsCallback)(void *cls,
+ const struct MHD_Connection *connection,
+ const char *username,
+ void **psk,
+ size_t *psk_size);
+
+/**
* @brief MHD options.
*
* Passed in the varargs portion of #MHD_start_daemon.
@@ -1489,7 +1508,15 @@ enum MHD_OPTION
* testing clients against MHD, and 0 in production. This option
* should be followed by an `int` argument.
*/
- MHD_OPTION_STRICT_FOR_CLIENT = 29
+ MHD_OPTION_STRICT_FOR_CLIENT = 29,
+
+ /**
+ * This should be a pointer to callback of type
+ * gnutls_psk_server_credentials_function that will be given to
+ * gnutls_psk_set_server_credentials_function. It is used to
+ * retrieve the shared key for a given username.
+ */
+ MHD_OPTION_GNUTLS_PSK_CRED_HANDLER = 30
};
@@ -3150,10 +3177,11 @@ MHD_free (void *ptr);
*/
_MHD_EXTERN int
MHD_digest_auth_check (struct MHD_Connection *connection,
- const char *realm,
- const char *username,
- const char *password,
- unsigned int nonce_timeout);
+ const char *realm,
+ const char *username,
+ const char *password,
+ unsigned int nonce_timeout);
+
/**
* Authenticates the authorization header sent by the client
diff --git a/src/include/microhttpd2.h b/src/include/microhttpd2.h
index 063b2d98..e8671825 100644
--- a/src/include/microhttpd2.h
+++ b/src/include/microhttpd2.h
@@ -2181,6 +2181,41 @@ MHD_daemon_tls_mem_dhparams (struct MHD_Daemon *daemon,
/**
+ * Function called to lookup the pre shared key (@a psk) for a given
+ * HTTP connection based on the @a username.
+ *
+ * @param cls closure
+ * @param connection the HTTPS connection
+ * @param username the user name claimed by the other side
+ * @param psk[out] to be set to the pre-shared-key; should be allocated with
malloc(),
+ * will be freed by MHD
+ * @param psk_size[out] to be set to the number of bytes in @a psk
+ * @return 0 on success, -1 on errors
+ */
+typedef int
+(*MHD_PskServerCredentialsCallback)(void *cls,
+ const struct MHD_Connection *connection,
+ const char *username,
+ void **psk,
+ size_t *psk_size);
+
+
+/**
+ * Configure PSK to use for the TLS key exchange.
+ *
+ * @param daemon daemon to configure tls for
+ * @param psk_cb function to call to obtain pre-shared key
+ * @param psk_cb_cls closure for @a psk_cb
+ * @return #MHD_SC_OK upon success; TODO: define failure modes
+ */
+_MHD_EXTERN enum MHD_StatusCode
+MHD_daemon_set_tls_psk_callback (struct MHD_Daemon *daemon,
+ MHD_PskServerCredentialsCallback psk_cb,
+ void *psk_cb_cls)
+ MHD_NONNULL(1);
+
+
+/**
* Memory pointer for the certificate (ca.pem) to be used by the
* HTTPS daemon for client authentification.
*
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index 0b85764b..31ed1574 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -565,7 +565,6 @@ MHD_init_daemon_certificate (struct MHD_Daemon *daemon)
return -1;
}
-
/**
* Initialize security aspects of the HTTPS daemon
*
@@ -582,6 +581,11 @@ MHD_TLS_init (struct MHD_Daemon *daemon)
gnutls_certificate_allocate_credentials (&daemon->x509_cred))
return GNUTLS_E_MEMORY_ERROR;
return MHD_init_daemon_certificate (daemon);
+ case GNUTLS_CRD_PSK:
+ if (0 !=
+ gnutls_psk_allocate_server_credentials (&daemon->psk_cred))
+ return GNUTLS_E_MEMORY_ERROR;
+ return 0;
default:
#ifdef HAVE_MESSAGES
MHD_DLOG (daemon,
@@ -2137,6 +2141,67 @@ MHD_tls_push_func_(gnutls_transport_ptr_t trnsp,
#endif /* MHD_TLSLIB_DONT_SUPPRESS_SIGPIPE */
#endif /* HTTPS_SUPPORT */
+
+/**
+ * Function called by GNUtls to obtain the PSK for a given session.
+ *
+ * @param session the session to lookup PSK for
+ * @param username username to lookup PSK for
+ * @param key[out] where to write PSK
+ * @return 0 on success, -1 on error
+ */
+static int
+psk_gnutls_adapter (gnutls_session_t session,
+ const char *username,
+ gnutls_datum_t *key)
+{
+ struct MHD_Connection *connection;
+ struct MHD_Daemon *daemon;
+ void *app_psk;
+ size_t app_psk_size;
+
+ connection = gnutls_session_get_ptr (session);
+ if (NULL == connection)
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _("Internal server error. This should be impossible.\n"));
+#endif
+ return -1;
+ }
+ daemon = connection->daemon;
+ if (NULL == daemon->cred_callback)
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _("PSK not supported by this server.\n"));
+#endif
+ return -1;
+ }
+ if (0 != daemon->cred_callback (daemon->cred_callback_cls,
+ connection,
+ username,
+ &app_psk,
+ &app_psk_size))
+ return -1;
+ if (NULL == (key->data = gnutls_malloc (app_psk_size)))
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _("PSK authentication failed: gnutls_malloc failed to allocate
memory\n"));
+#endif
+ free (app_psk);
+ return -1;
+ }
+ key->size = app_psk_size;
+ memcpy (key->data,
+ app_psk,
+ app_psk_size);
+ free (app_psk);
+ return 0;
+}
+
+
/**
* Add another client connection to the set of connections
* managed by MHD. This API is usually not needed (since
@@ -2372,6 +2437,12 @@ internal_add_connection (struct MHD_Daemon *daemon,
gnutls_credentials_set (connection->tls_session,
GNUTLS_CRD_CERTIFICATE,
daemon->x509_cred);
+ case GNUTLS_CRD_PSK:
+ gnutls_credentials_set (connection->tls_session,
+ GNUTLS_CRD_PSK,
+ daemon->psk_cred);
+ gnutls_psk_set_server_credentials_function (daemon->psk_cred,
+ &psk_gnutls_adapter);
break;
default:
#ifdef HAVE_MESSAGES
@@ -2392,12 +2463,15 @@ internal_add_connection (struct MHD_Daemon *daemon,
return MHD_NO;
}
#if (GNUTLS_VERSION_NUMBER+0 >= 0x030109) && !defined(_WIN64)
- gnutls_transport_set_int (connection->tls_session, (int)(client_socket));
+ gnutls_transport_set_int (connection->tls_session,
+ (int)(client_socket));
#else /* GnuTLS before 3.1.9 or Win x64 */
- gnutls_transport_set_ptr (connection->tls_session,
(gnutls_transport_ptr_t)(intptr_t)(client_socket));
+ gnutls_transport_set_ptr (connection->tls_session,
+
(gnutls_transport_ptr_t)(intptr_t)(client_socket));
#endif /* GnuTLS before 3.1.9 */
#ifdef MHD_TLSLIB_NEED_PUSH_FUNC
- gnutls_transport_set_push_function (connection->tls_session,
MHD_tls_push_func_);
+ gnutls_transport_set_push_function (connection->tls_session,
+ MHD_tls_push_func_);
#endif /* MHD_TLSLIB_NEED_PUSH_FUNC */
if (daemon->https_mem_trust)
gnutls_certificate_server_set_request (connection->tls_session,
@@ -2407,7 +2481,8 @@ internal_add_connection (struct MHD_Daemon *daemon,
goto cleanup;
#endif /* ! HTTPS_SUPPORT */
}
-
+ gnutls_session_set_ptr (connection->tls_session,
+ connection);
MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
/* Firm check under lock. */
@@ -5070,6 +5145,7 @@ parse_options_va (struct MHD_Daemon *daemon,
case MHD_OPTION_URI_LOG_CALLBACK:
case MHD_OPTION_EXTERNAL_LOGGER:
case MHD_OPTION_UNESCAPE_CALLBACK:
+ case MHD_OPTION_GNUTLS_PSK_CRED_HANDLER:
if (MHD_YES != parse_options (daemon,
servaddr,
opt,
@@ -5100,6 +5176,12 @@ parse_options_va (struct MHD_Daemon *daemon,
daemon->unescape_callback_cls = va_arg (ap,
void *);
break;
+ case MHD_OPTION_GNUTLS_PSK_CRED_HANDLER:
+ daemon->cred_callback = va_arg (ap,
+ MHD_PskServerCredentialsCallback);
+ daemon->cred_callback_cls = va_arg (ap,
+ void *);
+ break;
default:
#ifdef HAVE_MESSAGES
if ( ( (opt >= MHD_OPTION_HTTPS_MEM_KEY) &&
@@ -6419,6 +6501,8 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
gnutls_priority_deinit (daemon->priority_cache);
if (daemon->x509_cred)
gnutls_certificate_free_credentials (daemon->x509_cred);
+ if (daemon->psk_cred)
+ gnutls_psk_free_server_credentials (daemon->psk_cred);
}
#endif /* HTTPS_SUPPORT */
diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h
index 01f2dbea..d1835ea0 100644
--- a/src/microhttpd/internal.h
+++ b/src/microhttpd/internal.h
@@ -1611,12 +1611,27 @@ struct MHD_Daemon
*/
gnutls_dh_params_t dh_params;
+ /**
+ * Server PSK credentials
+ */
+ gnutls_psk_server_credentials_t psk_cred;
+
#if GNUTLS_VERSION_MAJOR >= 3
/**
* Function that can be used to obtain the certificate. Needed
* for SNI support. See #MHD_OPTION_HTTPS_CERT_CALLBACK.
*/
gnutls_certificate_retrieve_function2 *cert_callback;
+
+ /**
+ * Function that can be used to obtain the shared key.
+ */
+ MHD_PskServerCredentialsCallback cred_callback;
+
+ /**
+ * Closure for @e cred_callback.
+ */
+ void *cred_callback_cls;
#endif
/**
--
To stop receiving notification emails like this one, please contact
address@hidden