mirror of
https://git.gnunet.org/libmicrohttpd.git
synced 2026-09-25 04:09:31 +03:00
integrate TLS PSK patch from Tal Moaz (plus documentation, plus style and bugfixes
This commit is contained in:
@@ -58,6 +58,7 @@ Louis Benoit <louisbenoit@videotron.ca>
|
||||
Flavio Coelin <flavio.ceolin@intel.com>
|
||||
Silvio Clecio <silvioprog@gmail.com>
|
||||
Robert D Kosisko <rkocisko@gmail.com>
|
||||
Tal Moaz <tmoaz@cisco.com>
|
||||
|
||||
Documentation contributions also came from:
|
||||
Marco Maggi <marco.maggi-ipsu@poste.it>
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@item MHD_OPTION_GNUTLS_PSK_CRED_HANDLER
|
||||
@cindex SSL
|
||||
@cindex TLS
|
||||
@cindex PSK
|
||||
Use pre-shared key for TLS credentials.
|
||||
Pass a pointer to callback of type
|
||||
@code{MHD_PskServerCredentialsCallback} 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
|
||||
|
||||
@@ -1166,6 +1166,25 @@ typedef void
|
||||
va_list ap);
|
||||
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
@@ -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
|
||||
|
||||
@@ -2180,6 +2180,41 @@ MHD_daemon_tls_mem_dhparams (struct MHD_Daemon *daemon,
|
||||
MHD_NONNULL(1);
|
||||
|
||||
|
||||
/**
|
||||
* 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.
|
||||
|
||||
+89
-5
@@ -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 */
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user