aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2018-07-14 11:44:01 +0200
committerChristian Grothoff <christian@grothoff.org>2018-07-14 13:27:45 +0200
commit2c47a23dec110fb77e1cda36d6bdb83fc4d5e252 (patch)
tree37e41d6e5c477105788c74ef7243ec83e92c70d4
parent2ed04522e24b801251d7fd1768b7fccfd7b8deac (diff)
downloadlibmicrohttpd-2c47a23dec110fb77e1cda36d6bdb83fc4d5e252.tar.gz
libmicrohttpd-2c47a23dec110fb77e1cda36d6bdb83fc4d5e252.zip
integrate TLS PSK patch from Tal Moaz (plus documentation, plus style and bugfixes
-rw-r--r--AUTHORS1
-rw-r--r--ChangeLog4
-rw-r--r--doc/libmicrohttpd.texi10
-rw-r--r--src/include/microhttpd.h38
-rw-r--r--src/include/microhttpd2.h35
-rw-r--r--src/microhttpd/daemon.c94
-rw-r--r--src/microhttpd/internal.h15
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 <louisbenoit@videotron.ca>
58Flavio Coelin <flavio.ceolin@intel.com> 58Flavio Coelin <flavio.ceolin@intel.com>
59Silvio Clecio <silvioprog@gmail.com> 59Silvio Clecio <silvioprog@gmail.com>
60Robert D Kosisko <rkocisko@gmail.com> 60Robert D Kosisko <rkocisko@gmail.com>
61Tal Moaz <tmoaz@cisco.com>
61 62
62Documentation contributions also came from: 63Documentation contributions also came from:
63Marco Maggi <marco.maggi-ipsu@poste.it> 64Marco Maggi <marco.maggi-ipsu@poste.it>
diff --git a/ChangeLog b/ChangeLog
index 1c4ddd61..dbeccbd8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
1Sat Jul 14 11:42:15 CEST 2018
2 Add MHD_OPTION_GNUTLS_PSK_CRED_HANDLER to allow use of PSK with
3 TLS connections. -CG/TM
4
1Sat Jul 14 11:03:37 CEST 2018 5Sat Jul 14 11:03:37 CEST 2018
2 Integrate patch for checking digest authentication based on 6 Integrate patch for checking digest authentication based on
3 a digest, allowing servers to store passwords only hashed. 7 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
869using gnutls_server_name_get(). Using this option requires GnuTLS 3.0 869using gnutls_server_name_get(). Using this option requires GnuTLS 3.0
870or higher. 870or higher.
871 871
872@item MHD_OPTION_GNUTLS_PSK_CRED_HANDLER
873@cindex SSL
874@cindex TLS
875@cindex PSK
876Use pre-shared key for TLS credentials.
877Pass a pointer to callback of type
878@code{MHD_PskServerCredentialsCallback} and a closure.
879The function will be called to
880retrieve the shared key for a given username.
881
872@item MHD_OPTION_DIGEST_AUTH_RANDOM 882@item MHD_OPTION_DIGEST_AUTH_RANDOM
873@cindex digest auth 883@cindex digest auth
874@cindex random 884@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
1167 1167
1168 1168
1169/** 1169/**
1170 * Function called to lookup the pre shared key (@a psk) for a given
1171 * HTTP connection based on the @a username.
1172 *
1173 * @param cls closure
1174 * @param connection the HTTPS connection
1175 * @param username the user name claimed by the other side
1176 * @param psk[out] to be set to the pre-shared-key; should be allocated with malloc(),
1177 * will be freed by MHD
1178 * @param psk_size[out] to be set to the number of bytes in @a psk
1179 * @return 0 on success, -1 on errors
1180 */
1181typedef int
1182(*MHD_PskServerCredentialsCallback)(void *cls,
1183 const struct MHD_Connection *connection,
1184 const char *username,
1185 void **psk,
1186 size_t *psk_size);
1187
1188/**
1170 * @brief MHD options. 1189 * @brief MHD options.
1171 * 1190 *
1172 * Passed in the varargs portion of #MHD_start_daemon. 1191 * Passed in the varargs portion of #MHD_start_daemon.
@@ -1489,7 +1508,15 @@ enum MHD_OPTION
1489 * testing clients against MHD, and 0 in production. This option 1508 * testing clients against MHD, and 0 in production. This option
1490 * should be followed by an `int` argument. 1509 * should be followed by an `int` argument.
1491 */ 1510 */
1492 MHD_OPTION_STRICT_FOR_CLIENT = 29 1511 MHD_OPTION_STRICT_FOR_CLIENT = 29,
1512
1513 /**
1514 * This should be a pointer to callback of type
1515 * gnutls_psk_server_credentials_function that will be given to
1516 * gnutls_psk_set_server_credentials_function. It is used to
1517 * retrieve the shared key for a given username.
1518 */
1519 MHD_OPTION_GNUTLS_PSK_CRED_HANDLER = 30
1493}; 1520};
1494 1521
1495 1522
@@ -3150,10 +3177,11 @@ MHD_free (void *ptr);
3150 */ 3177 */
3151_MHD_EXTERN int 3178_MHD_EXTERN int
3152MHD_digest_auth_check (struct MHD_Connection *connection, 3179MHD_digest_auth_check (struct MHD_Connection *connection,
3153 const char *realm, 3180 const char *realm,
3154 const char *username, 3181 const char *username,
3155 const char *password, 3182 const char *password,
3156 unsigned int nonce_timeout); 3183 unsigned int nonce_timeout);
3184
3157 3185
3158/** 3186/**
3159 * Authenticates the authorization header sent by the client 3187 * 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,
2181 2181
2182 2182
2183/** 2183/**
2184 * Function called to lookup the pre shared key (@a psk) for a given
2185 * HTTP connection based on the @a username.
2186 *
2187 * @param cls closure
2188 * @param connection the HTTPS connection
2189 * @param username the user name claimed by the other side
2190 * @param psk[out] to be set to the pre-shared-key; should be allocated with malloc(),
2191 * will be freed by MHD
2192 * @param psk_size[out] to be set to the number of bytes in @a psk
2193 * @return 0 on success, -1 on errors
2194 */
2195typedef int
2196(*MHD_PskServerCredentialsCallback)(void *cls,
2197 const struct MHD_Connection *connection,
2198 const char *username,
2199 void **psk,
2200 size_t *psk_size);
2201
2202
2203/**
2204 * Configure PSK to use for the TLS key exchange.
2205 *
2206 * @param daemon daemon to configure tls for
2207 * @param psk_cb function to call to obtain pre-shared key
2208 * @param psk_cb_cls closure for @a psk_cb
2209 * @return #MHD_SC_OK upon success; TODO: define failure modes
2210 */
2211_MHD_EXTERN enum MHD_StatusCode
2212MHD_daemon_set_tls_psk_callback (struct MHD_Daemon *daemon,
2213 MHD_PskServerCredentialsCallback psk_cb,
2214 void *psk_cb_cls)
2215 MHD_NONNULL(1);
2216
2217
2218/**
2184 * Memory pointer for the certificate (ca.pem) to be used by the 2219 * Memory pointer for the certificate (ca.pem) to be used by the
2185 * HTTPS daemon for client authentification. 2220 * HTTPS daemon for client authentification.
2186 * 2221 *
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)
565 return -1; 565 return -1;
566} 566}
567 567
568
569/** 568/**
570 * Initialize security aspects of the HTTPS daemon 569 * Initialize security aspects of the HTTPS daemon
571 * 570 *
@@ -582,6 +581,11 @@ MHD_TLS_init (struct MHD_Daemon *daemon)
582 gnutls_certificate_allocate_credentials (&daemon->x509_cred)) 581 gnutls_certificate_allocate_credentials (&daemon->x509_cred))
583 return GNUTLS_E_MEMORY_ERROR; 582 return GNUTLS_E_MEMORY_ERROR;
584 return MHD_init_daemon_certificate (daemon); 583 return MHD_init_daemon_certificate (daemon);
584 case GNUTLS_CRD_PSK:
585 if (0 !=
586 gnutls_psk_allocate_server_credentials (&daemon->psk_cred))
587 return GNUTLS_E_MEMORY_ERROR;
588 return 0;
585 default: 589 default:
586#ifdef HAVE_MESSAGES 590#ifdef HAVE_MESSAGES
587 MHD_DLOG (daemon, 591 MHD_DLOG (daemon,
@@ -2137,6 +2141,67 @@ MHD_tls_push_func_(gnutls_transport_ptr_t trnsp,
2137#endif /* MHD_TLSLIB_DONT_SUPPRESS_SIGPIPE */ 2141#endif /* MHD_TLSLIB_DONT_SUPPRESS_SIGPIPE */
2138#endif /* HTTPS_SUPPORT */ 2142#endif /* HTTPS_SUPPORT */
2139 2143
2144
2145/**
2146 * Function called by GNUtls to obtain the PSK for a given session.
2147 *
2148 * @param session the session to lookup PSK for
2149 * @param username username to lookup PSK for
2150 * @param key[out] where to write PSK
2151 * @return 0 on success, -1 on error
2152 */
2153static int
2154psk_gnutls_adapter (gnutls_session_t session,
2155 const char *username,
2156 gnutls_datum_t *key)
2157{
2158 struct MHD_Connection *connection;
2159 struct MHD_Daemon *daemon;
2160 void *app_psk;
2161 size_t app_psk_size;
2162
2163 connection = gnutls_session_get_ptr (session);
2164 if (NULL == connection)
2165 {
2166#ifdef HAVE_MESSAGES
2167 MHD_DLOG (daemon,
2168 _("Internal server error. This should be impossible.\n"));
2169#endif
2170 return -1;
2171 }
2172 daemon = connection->daemon;
2173 if (NULL == daemon->cred_callback)
2174 {
2175#ifdef HAVE_MESSAGES
2176 MHD_DLOG (daemon,
2177 _("PSK not supported by this server.\n"));
2178#endif
2179 return -1;
2180 }
2181 if (0 != daemon->cred_callback (daemon->cred_callback_cls,
2182 connection,
2183 username,
2184 &app_psk,
2185 &app_psk_size))
2186 return -1;
2187 if (NULL == (key->data = gnutls_malloc (app_psk_size)))
2188 {
2189#ifdef HAVE_MESSAGES
2190 MHD_DLOG (daemon,
2191 _("PSK authentication failed: gnutls_malloc failed to allocate memory\n"));
2192#endif
2193 free (app_psk);
2194 return -1;
2195 }
2196 key->size = app_psk_size;
2197 memcpy (key->data,
2198 app_psk,
2199 app_psk_size);
2200 free (app_psk);
2201 return 0;
2202}
2203
2204
2140/** 2205/**
2141 * Add another client connection to the set of connections 2206 * Add another client connection to the set of connections
2142 * managed by MHD. This API is usually not needed (since 2207 * managed by MHD. This API is usually not needed (since
@@ -2372,6 +2437,12 @@ internal_add_connection (struct MHD_Daemon *daemon,
2372 gnutls_credentials_set (connection->tls_session, 2437 gnutls_credentials_set (connection->tls_session,
2373 GNUTLS_CRD_CERTIFICATE, 2438 GNUTLS_CRD_CERTIFICATE,
2374 daemon->x509_cred); 2439 daemon->x509_cred);
2440 case GNUTLS_CRD_PSK:
2441 gnutls_credentials_set (connection->tls_session,
2442 GNUTLS_CRD_PSK,
2443 daemon->psk_cred);
2444 gnutls_psk_set_server_credentials_function (daemon->psk_cred,
2445 &psk_gnutls_adapter);
2375 break; 2446 break;
2376 default: 2447 default:
2377#ifdef HAVE_MESSAGES 2448#ifdef HAVE_MESSAGES
@@ -2392,12 +2463,15 @@ internal_add_connection (struct MHD_Daemon *daemon,
2392 return MHD_NO; 2463 return MHD_NO;
2393 } 2464 }
2394#if (GNUTLS_VERSION_NUMBER+0 >= 0x030109) && !defined(_WIN64) 2465#if (GNUTLS_VERSION_NUMBER+0 >= 0x030109) && !defined(_WIN64)
2395 gnutls_transport_set_int (connection->tls_session, (int)(client_socket)); 2466 gnutls_transport_set_int (connection->tls_session,
2467 (int)(client_socket));
2396#else /* GnuTLS before 3.1.9 or Win x64 */ 2468#else /* GnuTLS before 3.1.9 or Win x64 */
2397 gnutls_transport_set_ptr (connection->tls_session, (gnutls_transport_ptr_t)(intptr_t)(client_socket)); 2469 gnutls_transport_set_ptr (connection->tls_session,
2470 (gnutls_transport_ptr_t)(intptr_t)(client_socket));
2398#endif /* GnuTLS before 3.1.9 */ 2471#endif /* GnuTLS before 3.1.9 */
2399#ifdef MHD_TLSLIB_NEED_PUSH_FUNC 2472#ifdef MHD_TLSLIB_NEED_PUSH_FUNC
2400 gnutls_transport_set_push_function (connection->tls_session, MHD_tls_push_func_); 2473 gnutls_transport_set_push_function (connection->tls_session,
2474 MHD_tls_push_func_);
2401#endif /* MHD_TLSLIB_NEED_PUSH_FUNC */ 2475#endif /* MHD_TLSLIB_NEED_PUSH_FUNC */
2402 if (daemon->https_mem_trust) 2476 if (daemon->https_mem_trust)
2403 gnutls_certificate_server_set_request (connection->tls_session, 2477 gnutls_certificate_server_set_request (connection->tls_session,
@@ -2407,7 +2481,8 @@ internal_add_connection (struct MHD_Daemon *daemon,
2407 goto cleanup; 2481 goto cleanup;
2408#endif /* ! HTTPS_SUPPORT */ 2482#endif /* ! HTTPS_SUPPORT */
2409 } 2483 }
2410 2484 gnutls_session_set_ptr (connection->tls_session,
2485 connection);
2411 2486
2412 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 2487 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
2413 /* Firm check under lock. */ 2488 /* Firm check under lock. */
@@ -5070,6 +5145,7 @@ parse_options_va (struct MHD_Daemon *daemon,
5070 case MHD_OPTION_URI_LOG_CALLBACK: 5145 case MHD_OPTION_URI_LOG_CALLBACK:
5071 case MHD_OPTION_EXTERNAL_LOGGER: 5146 case MHD_OPTION_EXTERNAL_LOGGER:
5072 case MHD_OPTION_UNESCAPE_CALLBACK: 5147 case MHD_OPTION_UNESCAPE_CALLBACK:
5148 case MHD_OPTION_GNUTLS_PSK_CRED_HANDLER:
5073 if (MHD_YES != parse_options (daemon, 5149 if (MHD_YES != parse_options (daemon,
5074 servaddr, 5150 servaddr,
5075 opt, 5151 opt,
@@ -5100,6 +5176,12 @@ parse_options_va (struct MHD_Daemon *daemon,
5100 daemon->unescape_callback_cls = va_arg (ap, 5176 daemon->unescape_callback_cls = va_arg (ap,
5101 void *); 5177 void *);
5102 break; 5178 break;
5179 case MHD_OPTION_GNUTLS_PSK_CRED_HANDLER:
5180 daemon->cred_callback = va_arg (ap,
5181 MHD_PskServerCredentialsCallback);
5182 daemon->cred_callback_cls = va_arg (ap,
5183 void *);
5184 break;
5103 default: 5185 default:
5104#ifdef HAVE_MESSAGES 5186#ifdef HAVE_MESSAGES
5105 if ( ( (opt >= MHD_OPTION_HTTPS_MEM_KEY) && 5187 if ( ( (opt >= MHD_OPTION_HTTPS_MEM_KEY) &&
@@ -6419,6 +6501,8 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
6419 gnutls_priority_deinit (daemon->priority_cache); 6501 gnutls_priority_deinit (daemon->priority_cache);
6420 if (daemon->x509_cred) 6502 if (daemon->x509_cred)
6421 gnutls_certificate_free_credentials (daemon->x509_cred); 6503 gnutls_certificate_free_credentials (daemon->x509_cred);
6504 if (daemon->psk_cred)
6505 gnutls_psk_free_server_credentials (daemon->psk_cred);
6422 } 6506 }
6423#endif /* HTTPS_SUPPORT */ 6507#endif /* HTTPS_SUPPORT */
6424 6508
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
1611 */ 1611 */
1612 gnutls_dh_params_t dh_params; 1612 gnutls_dh_params_t dh_params;
1613 1613
1614 /**
1615 * Server PSK credentials
1616 */
1617 gnutls_psk_server_credentials_t psk_cred;
1618
1614#if GNUTLS_VERSION_MAJOR >= 3 1619#if GNUTLS_VERSION_MAJOR >= 3
1615 /** 1620 /**
1616 * Function that can be used to obtain the certificate. Needed 1621 * Function that can be used to obtain the certificate. Needed
1617 * for SNI support. See #MHD_OPTION_HTTPS_CERT_CALLBACK. 1622 * for SNI support. See #MHD_OPTION_HTTPS_CERT_CALLBACK.
1618 */ 1623 */
1619 gnutls_certificate_retrieve_function2 *cert_callback; 1624 gnutls_certificate_retrieve_function2 *cert_callback;
1625
1626 /**
1627 * Function that can be used to obtain the shared key.
1628 */
1629 MHD_PskServerCredentialsCallback cred_callback;
1630
1631 /**
1632 * Closure for @e cred_callback.
1633 */
1634 void *cred_callback_cls;
1620#endif 1635#endif
1621 1636
1622 /** 1637 /**