tRead key/salt and deriv key right from main() - safe - password protected secret keeper
HTML git clone git://git.z3bra.org/safe.git
DIR Log
DIR Files
DIR Refs
DIR README
DIR LICENSE
---
DIR commit 5254f08121341ae91042257b11bd299788f3ebd5
DIR parent 5bca68cbe7e38dd4c00464515a9755196db4fc8b
HTML Author: Willy Goiffon <dev@z3bra.org>
Date: Mon, 3 Jun 2019 15:32:18 +0200
Read key/salt and deriv key right from main()
This allow checking the master password and deriving the key from it
before storing/showing any password in/from the safe.
Diffstat:
M safe.c | 92 ++++++++++++++++---------------
1 file changed, 49 insertions(+), 43 deletions(-)
---
DIR diff --git a/safe.c b/safe.c
t@@ -243,13 +243,9 @@ agent(struct safe *s, char *path)
{
int cfd, sfd;
- readpass("password:", &passphrase, &pplen);
-
sfd = creatsock(path);
while ((cfd = accept(sfd, NULL, NULL)) > 0) {
- xread(cfd, s->salt, sizeof(s->salt), NULL);
- deriv((char *)passphrase, s);
xwrite(cfd, s->key, sizeof(s->key));
close(cfd);
}
t@@ -281,48 +277,31 @@ getkey(struct safe *s, char *path)
}
int
-genkey(struct safe *s)
-{
- readpass("password:", &passphrase, &pplen);
- deriv((char *)passphrase, s);
-
- return 0;
-}
-
-int
-store_secret(struct safe *s, int fd, char *name)
+show_secret(struct safe *s, int fd, char *name)
{
int sfd, eof, flags = 0;
ssize_t n;
uint8_t m[BUFSIZ];
uint8_t c[BUFSIZ + crypto_secretstream_xchacha20poly1305_ABYTES];
- unsigned long long clen;
-
- if (!secret_exists(LOCK))
- randombytes_buf(s->salt, sizeof(s->salt));
-
- genkey(s);
+ unsigned long long mlen;
- mkdir_p(dirname(name), 0700);
- sfd = open(name, O_WRONLY | O_CREAT | O_EXCL, 0600);
+ sfd = open(name, O_RDONLY);
if (sfd < 0)
err(1, "%s", name);
- xwrite(sfd, s->salt, sizeof(s->salt));
+ xread(sfd, s->salt, sizeof(s->salt), NULL);
+ xread(sfd, s->h, sizeof(s->h), NULL);
flags = SAFE_INIT;
- while ((n = xread(fd, m, sizeof(m), &eof)) > 0) {
+ while ((n = xread(sfd, c, sizeof(c), &eof)) > 0) {
flags |= eof ? SAFE_FINAL : 0;
- if (secret_encrypt(s, m, n, c, &clen, flags) < 0) {
- fprintf(stderr, "%s: failed to encrypt password\n", name);
+
+ if (secret_decrypt(s, c, n, m, &mlen, flags) < 0) {
close(sfd);
return -1;
}
- if (flags & SAFE_INIT)
- xwrite(sfd, s->h, sizeof(s->h));
-
- xwrite(sfd, c, clen);
+ xwrite(fd, m, mlen);
flags &= ~(SAFE_INIT);
}
t@@ -332,33 +311,49 @@ store_secret(struct safe *s, int fd, char *name)
}
int
-show_secret(struct safe *s, int fd, char *name)
+check_master(struct safe *s)
+{
+ int r, fd;
+
+ fd = open("/dev/null", O_RDONLY);
+ if (fd < 0)
+ err(1, "/dev/null");
+
+ r = show_secret(s, fd, LOCK);
+ close(fd);
+
+ return r;
+}
+
+int
+store_secret(struct safe *s, int fd, char *name)
{
int sfd, eof, flags = 0;
ssize_t n;
uint8_t m[BUFSIZ];
uint8_t c[BUFSIZ + crypto_secretstream_xchacha20poly1305_ABYTES];
- unsigned long long mlen;
+ unsigned long long clen;
- sfd = open(name, O_RDONLY);
+ mkdir_p(dirname(name), 0700);
+ sfd = open(name, O_WRONLY | O_CREAT | O_EXCL, 0600);
if (sfd < 0)
err(1, "%s", name);
- xread(sfd, s->salt, sizeof(s->salt), NULL);
- xread(sfd, s->h, sizeof(s->h), NULL);
-
- genkey(s);
+ xwrite(sfd, s->salt, sizeof(s->salt));
flags = SAFE_INIT;
- while ((n = xread(sfd, c, sizeof(c), &eof)) > 0) {
+ while ((n = xread(fd, m, sizeof(m), &eof)) > 0) {
flags |= eof ? SAFE_FINAL : 0;
- if (secret_decrypt(s, c, n, m, &mlen, flags) < 0) {
- fprintf(stderr, "%s: failed to decrypt password\n", name);
+
+ if (secret_encrypt(s, m, n, c, &clen, flags) < 0) {
close(sfd);
return -1;
}
- xwrite(fd, m, mlen);
+ if (flags & SAFE_INIT)
+ xwrite(sfd, s->h, sizeof(s->h));
+
+ xwrite(sfd, c, clen);
flags &= ~(SAFE_INIT);
}
t@@ -403,8 +398,19 @@ main(int argc, char *argv[])
if (secret_exists(LOCK)) {
if ((fd = open(LOCK, O_RDONLY)) < 0)
err(1, "%s", LOCK);
+
xread(fd, s.salt, sizeof(s.salt), NULL);
close(fd);
+ } else {
+ randombytes_buf(s.salt, sizeof(s.salt));
+ }
+
+ readpass("password:", &passphrase, &pplen);
+ deriv((char *)passphrase, &s);
+
+ if (check_master(&s) < 0) {
+ fprintf(stderr, "master password incorrect\n");
+ return -1;
}
if (dflag)
t@@ -413,9 +419,9 @@ main(int argc, char *argv[])
secret = argv[0];
if (aflag) {
- store_secret(&s, STDIN_FILENO, secret);
+ return store_secret(&s, STDIN_FILENO, secret);
} else {
- show_secret(&s, STDOUT_FILENO, secret);
+ return show_secret(&s, STDOUT_FILENO, secret);
}
return 0;