summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGlenn Strauss <gstrauss@gluelogic.com>2018-03-11 00:28:56 -0500
committerGlenn Strauss <gstrauss@gluelogic.com>2018-03-11 00:28:56 -0500
commit81b7e8e2fb0c49eb2d913c8b2a39e06a767b051c (patch)
tree32fea144b58ec72efa9f15e0f03eaea093158a49
parent7265c72b6cc65f39111c1248bd996b152c57ec71 (diff)
downloadlighttpd-git-81b7e8e2fb0c49eb2d913c8b2a39e06a767b051c.tar.gz
[mod_auth] constant time compare plain passwords
(digests have same length)
-rw-r--r--src/http_auth.c17
-rw-r--r--src/http_auth.h1
-rw-r--r--src/mod_authn_file.c2
3 files changed, 19 insertions, 1 deletions
diff --git a/src/http_auth.c b/src/http_auth.c
index 773eb59d..92541ef8 100644
--- a/src/http_auth.c
+++ b/src/http_auth.c
@@ -49,6 +49,23 @@ void http_auth_backend_set (const http_auth_backend_t *backend)
}
+int http_auth_const_time_memeq (const char *a, const size_t alen, const char *b, const size_t blen)
+{
+ /* constant time memory compare, unless compiler figures it out
+ * (similar to mod_secdownload.c:const_time_memeq()) */
+ /* round to next multiple of 64 to avoid potentially leaking exact
+ * password length when subject to high precision timing attacks) */
+ size_t lim = ((alen >= blen ? alen : blen) + 0xFFFFF) & ~0xFFFFF;
+ int diff = 0;
+ for (size_t i = 0, j = 0; lim; --lim) {
+ diff |= (a[i] ^ b[j]);
+ i += (i < alen);
+ j += (j < blen);
+ }
+ return (0 == diff);
+}
+
+
void http_auth_dumbdata_reset (void)
{
memset(http_auth_schemes, 0, sizeof(http_auth_schemes));
diff --git a/src/http_auth.h b/src/http_auth.h
index 91082037..797a8680 100644
--- a/src/http_auth.h
+++ b/src/http_auth.h
@@ -41,6 +41,7 @@ const http_auth_scheme_t * http_auth_scheme_get (const buffer *name);
void http_auth_scheme_set (const http_auth_scheme_t *scheme);
const http_auth_backend_t * http_auth_backend_get (const buffer *name);
void http_auth_backend_set (const http_auth_backend_t *backend);
+int http_auth_const_time_memeq (const char *a, size_t alen, const char *b, size_t blen);
void http_auth_setenv(array *env, const char *username, size_t ulen, const char *auth_type, size_t alen);
diff --git a/src/mod_authn_file.c b/src/mod_authn_file.c
index c7cff52e..567ab1af 100644
--- a/src/mod_authn_file.c
+++ b/src/mod_authn_file.c
@@ -398,7 +398,7 @@ static handler_t mod_authn_file_plain_basic(server *srv, connection *con, void *
mod_authn_file_patch_connection(srv, con, p);
rc = mod_authn_file_htpasswd_get(srv, p->conf.auth_plain_userfile, username, password_buf);
if (0 == rc) {
- rc = buffer_is_equal_string(password_buf, pw, strlen(pw)) ? 0 : -1;
+ rc = http_auth_const_time_memeq(CONST_BUF_LEN(password_buf), pw, strlen(pw)) ? 0 : -1;
}
buffer_free(password_buf);
UNUSED(con);