tRewrite encrypt/decrypt to handle memory buffers - 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 3a6a19326fb0700a02c76683c1d736b3c59b760a
DIR parent 19a78db25e6054e65e787442738bcbf3e4e88398
HTML Author: Willy Goiffon <dev@z3bra.org>
Date: Fri, 31 May 2019 17:27:33 +0200
Rewrite encrypt/decrypt to handle memory buffers
Diffstat:
M safe.c | 122 +++++++++++++++++--------------
1 file changed, 68 insertions(+), 54 deletions(-)
---
DIR diff --git a/safe.c b/safe.c
t@@ -21,6 +21,19 @@
#define SOCKET "agent"
#define SAFE ".secrets"
+struct safe {
+ crypto_secretstream_xchacha20poly1305_state st;
+ uint8_t h[crypto_secretstream_xchacha20poly1305_HEADERBYTES];
+
+ uint8_t key[crypto_secretstream_xchacha20poly1305_KEYBYTES];
+ uint8_t salt[crypto_pwhash_SALTBYTES];
+};
+
+enum {
+ SAFE_INIT = 1 << 1,
+ SAFE_FINAL = 1 << 2,
+};
+
uint8_t *passphrase;
size_t pplen;
char *argv0;
t@@ -112,52 +125,31 @@ xwrite(int fd, const void *buf, size_t nbytes)
}
void
-encrypt_stream(int ifd, int ofd, uint8_t *key)
+secret_encrypt(struct safe *s, uint8_t *m, size_t mlen, uint8_t *c, unsigned long long *clen, int flags)
{
- int eof;
- uint8_t tag;
- ssize_t n;
- uint8_t m[BUFSIZ];
- uint8_t c[BUFSIZ + crypto_secretstream_xchacha20poly1305_ABYTES];
- uint8_t h[crypto_secretstream_xchacha20poly1305_HEADERBYTES];
- crypto_secretstream_xchacha20poly1305_state st;
- unsigned long long len;
+ int tag = 0;
- crypto_secretstream_xchacha20poly1305_init_push(&st, h, key);
- xwrite(ofd, h, sizeof(h));
+ if (flags & SAFE_INIT)
+ crypto_secretstream_xchacha20poly1305_init_push(&s->st, s->h, s->key);
- while ((n = xread(ifd, m, sizeof(m), &eof)) > 0) {
- tag = eof ? crypto_secretstream_xchacha20poly1305_TAG_FINAL : 0;
- crypto_secretstream_xchacha20poly1305_push(&st, c, &len, m, n, NULL, 0, tag);
- xwrite(ofd, c, len);
- }
+ if (flags & SAFE_FINAL)
+ tag = crypto_secretstream_xchacha20poly1305_TAG_FINAL;
+
+ crypto_secretstream_xchacha20poly1305_push(&s->st, c, clen, m, mlen, NULL, 0, tag);
}
void
-decrypt_stream(int ifd, int ofd, uint8_t *key)
+secret_decrypt(struct safe *s, uint8_t *c, size_t clen, uint8_t *m, unsigned long long *mlen, int flags)
{
- int eof;
uint8_t tag;
- ssize_t n;
- uint8_t m[BUFSIZ];
- uint8_t c[BUFSIZ + crypto_secretstream_xchacha20poly1305_ABYTES];
- uint8_t h[crypto_secretstream_xchacha20poly1305_HEADERBYTES];
- crypto_secretstream_xchacha20poly1305_state st;
- unsigned long long len;
+ if (flags & SAFE_INIT)
+ crypto_secretstream_xchacha20poly1305_init_pull(&s->st, s->h, s->key);
- xread(ifd, h, sizeof(h), NULL);
- if (crypto_secretstream_xchacha20poly1305_init_pull(&st, h, key)) {
- fprintf(stderr, "decrypt_stream: incomplete header\n");
- exit(1);
- }
+ crypto_secretstream_xchacha20poly1305_pull(&s->st, m, mlen, &tag, c, clen, NULL, 0);
- while ((n = xread(ifd, c, sizeof(c), &eof)) > 0) {
- crypto_secretstream_xchacha20poly1305_pull(&st, m, &len, &tag, c, n, NULL, 0);
- if (eof && tag != crypto_secretstream_xchacha20poly1305_TAG_FINAL) {
- fprintf(stderr, "decrypt_stream: premature EOF\n");
- exit(1);
- }
- xwrite(ofd, m, len);
+ if (flags & SAFE_FINAL && tag != crypto_secretstream_xchacha20poly1305_TAG_FINAL) {
+ fprintf(stderr, "secret_decrypt: premature EOF detected\n");
+ exit(1);
}
}
t@@ -231,17 +223,16 @@ int
agent(char *path)
{
int cfd, sfd;
- uint8_t salt[crypto_pwhash_SALTBYTES];
- uint8_t key[crypto_secretstream_xchacha20poly1305_KEYBYTES];
+ struct safe s;
readpass("password:", &passphrase, &pplen);
sfd = creatsock(path);
while ((cfd = accept(sfd, NULL, NULL)) > 0) {
- xread(cfd, salt, sizeof(salt), NULL);
- deriv((char *)passphrase, salt, key, sizeof(key));
- xwrite(cfd, key, sizeof(key));
+ xread(cfd, s.salt, sizeof(s.salt), NULL);
+ deriv((char *)passphrase, s.salt, s.key, sizeof(s.key));
+ xwrite(cfd, s.key, sizeof(s.key));
close(cfd);
}
t@@ -283,21 +274,33 @@ genkey(uint8_t *key, size_t ks, uint8_t *salt)
int
store_secret(int fd, char *name)
{
- int sfd;
- uint8_t key[crypto_secretstream_xchacha20poly1305_KEYBYTES];
- uint8_t salt[crypto_pwhash_SALTBYTES];
+ int sfd, eof, flags = 0;
+ ssize_t n;
+ struct safe s;
+ uint8_t m[BUFSIZ];
+ uint8_t c[BUFSIZ + crypto_secretstream_xchacha20poly1305_ABYTES];
+ unsigned long long clen;
mkdir_p(dirname(name), 0700);
sfd = open(name, O_WRONLY | O_CREAT, 0600);
if (sfd < 0)
err(1, "open %s", name);
- randombytes_buf(salt, sizeof(salt));
- xwrite(sfd, salt, sizeof(salt));
+ memset(s.salt, 0, sizeof(s.salt));
- genkey(key, sizeof(key), salt);
+ xwrite(sfd, s.salt, sizeof(s.salt));
+ genkey(s.key, sizeof(s.key), s.salt);
+
+ flags = SAFE_INIT;
+ while ((n = xread(fd, m, sizeof(m), &eof)) > 0) {
+ flags |= eof ? SAFE_FINAL : 0;
+ secret_encrypt(&s, m, n, c, &clen, flags);
+ if (flags & SAFE_INIT)
+ xwrite(sfd, s.h, sizeof(s.h));
+ xwrite(sfd, c, clen);
+ flags &= ~(SAFE_INIT);
+ }
- encrypt_stream(fd, sfd, key);
close(sfd);
return 0;
t@@ -306,19 +309,30 @@ store_secret(int fd, char *name)
int
show_secret(int fd, char *name)
{
- int sfd;
- uint8_t key[crypto_secretstream_xchacha20poly1305_KEYBYTES];
- uint8_t salt[crypto_pwhash_SALTBYTES];
+ int sfd, eof, flags = 0;
+ ssize_t n;
+ struct safe s;
+ uint8_t m[BUFSIZ];
+ uint8_t c[BUFSIZ + crypto_secretstream_xchacha20poly1305_ABYTES];
+ unsigned long long mlen;
sfd = open(name, O_RDONLY);
if (sfd < 0)
err(1, "open %s", name);
- xread(sfd, salt, sizeof(salt), NULL);
+ xread(sfd, s.salt, sizeof(s.salt), NULL);
+ genkey(s.key, sizeof(s.key), s.salt);
- genkey(key, sizeof(key), salt);
+ xread(sfd, s.h, sizeof(s.h), NULL);
+
+ flags = SAFE_INIT;
+ while ((n = xread(sfd, c, sizeof(c), &eof)) > 0) {
+ flags |= eof ? SAFE_FINAL : 0;
+ secret_decrypt(&s, c, n, m, &mlen, flags);
+ xwrite(fd, m, mlen);
+ flags &= ~(SAFE_INIT);
+ }
- decrypt_stream(sfd, fd, key);
close(sfd);
return 0;