]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
auth: Make plaintext password comparisons safe against timing attacks
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Sat, 8 Apr 2017 21:50:15 +0000 (00:50 +0300)
committerGitLab <gitlab@git.dovecot.net>
Tue, 11 Apr 2017 12:55:26 +0000 (15:55 +0300)
src/auth/password-scheme.c

index eda507a6888b36269d158e7f903ba97b87b33a44..03b8a98b8f9241acb2d9960fa9cb79721e9f64ee 100644 (file)
@@ -609,6 +609,18 @@ plain_generate(const char *plaintext, const char *user ATTR_UNUSED,
        *size_r = strlen(plaintext);
 }
 
+static int
+plain_verify(const char *plaintext, const char *user ATTR_UNUSED,
+            const unsigned char *raw_password, size_t size,
+            const char **error_r ATTR_UNUSED)
+{
+       size_t plaintext_len = strlen(plaintext);
+
+       if (plaintext_len != size)
+               return 0;
+       return mem_equals_timing_safe(plaintext, raw_password, size) ? 1 : 0;
+}
+
 static int
 plain_trunc_verify(const char *plaintext, const char *user ATTR_UNUSED,
                   const unsigned char *raw_password, size_t size,
@@ -633,10 +645,10 @@ plain_trunc_verify(const char *plaintext, const char *user ATTR_UNUSED,
        if (size-i == trunc_len && plaintext_len >= trunc_len) {
                /* possibly truncated password. allow the given password as
                   long as the prefix matches. */
-               return memcmp(raw_password+i, plaintext, trunc_len) == 0 ? 1 : 0;
+               return mem_equals_timing_safe(raw_password+i, plaintext, trunc_len) ? 1 : 0;
        }
        return plaintext_len == size-i &&
-               memcmp(raw_password+i, plaintext, plaintext_len) == 0 ? 1 : 0;
+               mem_equals_timing_safe(raw_password+i, plaintext, plaintext_len) ? 1 : 0;
 }
 
 static void
@@ -803,9 +815,9 @@ static const struct password_scheme builtin_schemes[] = {
        { "SSHA", PW_ENCODING_BASE64, 0, ssha_verify, ssha_generate },
        { "SSHA256", PW_ENCODING_BASE64, 0, ssha256_verify, ssha256_generate },
        { "SSHA512", PW_ENCODING_BASE64, 0, ssha512_verify, ssha512_generate },
-       { "PLAIN", PW_ENCODING_NONE, 0, NULL, plain_generate },
-       { "CLEAR", PW_ENCODING_NONE, 0, NULL, plain_generate },
-       { "CLEARTEXT", PW_ENCODING_NONE, 0, NULL, plain_generate },
+       { "PLAIN", PW_ENCODING_NONE, 0, plain_verify, plain_generate },
+       { "CLEAR", PW_ENCODING_NONE, 0, plain_verify, plain_generate },
+       { "CLEARTEXT", PW_ENCODING_NONE, 0, plain_verify, plain_generate },
        { "PLAIN-TRUNC", PW_ENCODING_NONE, 0, plain_trunc_verify, plain_generate },
        { "CRAM-MD5", PW_ENCODING_HEX, CRAM_MD5_CONTEXTLEN,
          NULL, cram_md5_generate },