npm

Nihal's Password Manager (WIP)
git clone git://git.nihaljere.xyz/npm
Log | Files | Refs | LICENSE

commit a7100b6fe92d300e08a3a98962c91c71477fd482
parent 4cce80a84b22109875f74fa21faf89a321474961
Author: Nihal Jere <nihal@nihaljere.xyz>
Date:   Wed, 29 Sep 2021 11:29:16 -0500

simplify get_password

fgets isn't appropriate for this because we want an error on EOF
and success on newline. This also makes it easier to report EOF errors

Diffstat:
Mnpm.c | 49+++++++++++++++++++++++++++++++++----------------
1 file changed, 33 insertions(+), 16 deletions(-)

diff --git a/npm.c b/npm.c @@ -36,17 +36,21 @@ clear() ssize_t get_password(char *buf) { - fgets(buf, PASSWORD_MAX_LEN+1, stdin); - // XXX: is strlen problematic because it isn't constant time and acts on a secret? - size_t len = strlen(buf); + int ret; + char *ptr = buf; + while (ptr - buf < PASSWORD_MAX_LEN) { + ret = fgetc(stdin); + if (ret == EOF) { + return -1; + } + + if (ret == '\n') + return ptr - buf; - /* the last character of the line should be '\n', which should not be - * included in the password */ - if (len == PASSWORD_MAX_LEN && buf[PASSWORD_MAX_LEN-1] != '\n') - return -1; + *(ptr++) = ret; + } - buf[len-1] = '\0'; - return len - 1; + return -2; } void @@ -116,9 +120,12 @@ int main(int argc, char *argv[]) { goto fail; } - len = get_password(encryptor); - if (len < 0) { - error("master password too long"); + switch (len = get_password(encryptor)) { + case -1: + error("encountered EOF when reading master password"); + goto fail; + case -2: + error("entered master password is too long"); goto fail; } @@ -134,9 +141,12 @@ int main(int argc, char *argv[]) { memcpy(data, salt, SALT_LEN); - len = get_password(encryptee); - if (len < 0) { - error("password to encrypt is too long"); + switch (len = get_password(encryptor)) { + case -1: + error("encountered EOF when reading password"); + goto fail; + case -2: + error("entered password is too long"); goto fail; } @@ -174,7 +184,14 @@ int main(int argc, char *argv[]) { goto fail; } - len = get_password(encryptor); + switch (len = get_password(encryptor)) { + case -1: + error("encountered EOF when reading master password"); + goto fail; + case -2: + error("entered master password is too long"); + goto fail; + } if (argon2id_hash_raw(T_COST, M_COST, PARALLELISM, encryptor, len, salt, SALT_LEN, key, KEY_LEN) < 0) { error("key derivation failed");