Add support for reading passphrase from file
This commit is contained in:
parent
6079530e1d
commit
5393e64c18
93
puer.c
93
puer.c
|
@ -543,20 +543,57 @@ ssize_t passphrase_prompt(unsigned char *passphrase, size_t size, const char *pr
|
||||||
return index - 1;
|
return index - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ssize_t passphrase_file(char *passfile, unsigned char passphrase[], size_t size) {
|
||||||
|
int file = open(passfile, O_RDONLY);
|
||||||
|
|
||||||
|
// Read until newline
|
||||||
|
size_t index = 0;
|
||||||
|
for (;;) {
|
||||||
|
if (index >= size) {
|
||||||
|
fprintf(stderr, "Passphrase too long, maximum size is %zu bytes\n", size - 1);
|
||||||
|
close(file);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t bytes_read = read(file, &passphrase[index], size - index);
|
||||||
|
if (bytes_read == -1) {
|
||||||
|
perror("Failed to read passphrase");
|
||||||
|
close(file);
|
||||||
|
return -1;
|
||||||
|
} else if (bytes_read == 0) {
|
||||||
|
fprintf(stderr, "Unexpected EOF\n");
|
||||||
|
close(file);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
index += bytes_read;
|
||||||
|
if (passphrase[index-1] == '\n') {
|
||||||
|
// Got end of line
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
close(file);
|
||||||
|
|
||||||
|
return index - 1;
|
||||||
|
}
|
||||||
|
|
||||||
void usage(char *name) {
|
void usage(char *name) {
|
||||||
fprintf(stderr, "Usage: %s -d | -e [-f]\n\n", name);
|
fprintf(stderr, "Usage: %s -d | -e [-f] [-p passfile]\n\n", name);
|
||||||
fprintf(stderr, "-d Decrypt\n");
|
fprintf(stderr, "-d Decrypt\n");
|
||||||
fprintf(stderr, "-e Encrypt\n");
|
fprintf(stderr, "-e Encrypt\n");
|
||||||
fprintf(stderr, "-f Force output to terminal\n");
|
fprintf(stderr, "-f Force output to terminal\n");
|
||||||
|
fprintf(stderr, "-p Read passphrase from a file instead of the terminal.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
bool encrypting = false;
|
bool encrypting = false;
|
||||||
bool decrypting = false;
|
bool decrypting = false;
|
||||||
bool force = false;
|
bool force = false;
|
||||||
|
char *passfile = NULL;
|
||||||
|
|
||||||
int opt;
|
int opt;
|
||||||
while ((opt = getopt(argc, argv, "def")) != -1) {
|
while ((opt = getopt(argc, argv, "defp:")) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'd':
|
case 'd':
|
||||||
decrypting = true;
|
decrypting = true;
|
||||||
|
@ -567,12 +604,20 @@ int main(int argc, char *argv[]) {
|
||||||
case 'f':
|
case 'f':
|
||||||
force = true;
|
force = true;
|
||||||
break;
|
break;
|
||||||
|
case 'p':
|
||||||
|
passfile = optarg;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (optind != argc) {
|
||||||
|
usage(argv[0]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
if ((!encrypting && !decrypting) || (encrypting && decrypting)) {
|
if ((!encrypting && !decrypting) || (encrypting && decrypting)) {
|
||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -609,30 +654,40 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
// Read passphrase
|
// Read passphrase
|
||||||
unsigned char passphrase[128];
|
unsigned char passphrase[128];
|
||||||
ssize_t passphrase_len = passphrase_prompt(passphrase, sizeof(passphrase), "passphrase: ");
|
ssize_t passphrase_len;
|
||||||
if (passphrase_len == -1) {
|
if (passfile == NULL) {
|
||||||
explicit_bzero(passphrase, sizeof(passphrase));
|
// Read from terminal if no passfile specified
|
||||||
exit(1);
|
passphrase_len = passphrase_prompt(passphrase, sizeof(passphrase), "passphrase: ");
|
||||||
}
|
if (passphrase_len == -1) {
|
||||||
|
|
||||||
if (encrypting) {
|
|
||||||
// Have the user confirm the passphrase if encrypting, to avoid losing data
|
|
||||||
unsigned char confirm[128];
|
|
||||||
ssize_t confirm_len = passphrase_prompt(confirm, sizeof(confirm), "confirm passphrase: ");
|
|
||||||
if (confirm_len == -1) {
|
|
||||||
explicit_bzero(passphrase, sizeof(passphrase));
|
explicit_bzero(passphrase, sizeof(passphrase));
|
||||||
explicit_bzero(confirm, sizeof(confirm));
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (confirm_len != passphrase_len || memcmp(passphrase, confirm, passphrase_len) != 0) {
|
if (encrypting) {
|
||||||
fprintf(stderr, "Passphrases do not match\n");
|
// Have the user confirm the passphrase if encrypting, to avoid losing data
|
||||||
explicit_bzero(passphrase, sizeof(passphrase));
|
unsigned char confirm[sizeof(passphrase)];
|
||||||
|
ssize_t confirm_len = passphrase_prompt(confirm, sizeof(confirm), "confirm passphrase: ");
|
||||||
|
if (confirm_len == -1) {
|
||||||
|
explicit_bzero(passphrase, sizeof(passphrase));
|
||||||
|
explicit_bzero(confirm, sizeof(confirm));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (confirm_len != passphrase_len || memcmp(passphrase, confirm, passphrase_len) != 0) {
|
||||||
|
fprintf(stderr, "Passphrases do not match\n");
|
||||||
|
explicit_bzero(passphrase, sizeof(passphrase));
|
||||||
|
explicit_bzero(confirm, sizeof(confirm));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
explicit_bzero(confirm, sizeof(confirm));
|
explicit_bzero(confirm, sizeof(confirm));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
passphrase_len = passphrase_file(passfile, passphrase, sizeof(passphrase));
|
||||||
|
if (passphrase_len == -1) {
|
||||||
|
explicit_bzero(passphrase, sizeof(passphrase));
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit_bzero(confirm, sizeof(confirm));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Derive key
|
// Derive key
|
||||||
|
|
Loading…
Reference in New Issue