Add function for reading passphrase from terminal
This commit is contained in:
parent
7bf44017a4
commit
741c0d0bb5
99
puer.c
99
puer.c
|
@ -1,8 +1,14 @@
|
|||
#include <assert.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
void xxtea128(uint32_t const key[4], uint32_t block[4]) {
|
||||
// Encryption half of the XXTEA algorithm, with block size limited
|
||||
|
@ -427,11 +433,93 @@ bool ccm_decrypt(unsigned char key[16], uint32_t messageindex, unsigned char mes
|
|||
return true;
|
||||
}
|
||||
|
||||
size_t passphrase_prompt(unsigned char *passphrase, size_t size, const char *prompt) {
|
||||
// Read from controlling TTY, even if stdion has been redirected
|
||||
int tty = open("/dev/tty", O_RDWR);
|
||||
if (tty == -1) {
|
||||
perror("Failed to open controlling tty");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (write(tty, prompt, strlen(prompt)) == -1) {
|
||||
perror("Failed to write to terminal");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Turn off echo
|
||||
struct termios saved;
|
||||
if (tcgetattr(tty, &saved) != 0) {
|
||||
perror("tcgetattr");
|
||||
exit(1);
|
||||
}
|
||||
struct termios altered;
|
||||
altered = saved;
|
||||
altered.c_lflag &= ~ECHO;
|
||||
if (tcsetattr(tty, TCSANOW, &altered) != 0) {
|
||||
perror("tcsetattr");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Read until newline
|
||||
size_t index = 0;
|
||||
for (;;) {
|
||||
if (index >= size) {
|
||||
fprintf(stderr, "Passphrase too long, maximum size is %zu bytes\n", size - 1);
|
||||
// Clean any line buffer
|
||||
char tmp;
|
||||
for (;;) {
|
||||
if (read(tty, &tmp, 1) <= 0) {
|
||||
break;
|
||||
}
|
||||
if (tmp == '\n') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
tcsetattr(tty, TCSANOW, &saved);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ssize_t bytes_read = read(tty, &passphrase[index], size - index);
|
||||
if (bytes_read == -1) {
|
||||
perror("Failed to read passphrase");
|
||||
tcsetattr(tty, TCSANOW, &saved);
|
||||
exit(1);
|
||||
} else if (bytes_read == 0) {
|
||||
fprintf(stderr, "Unexpected EOF\n");
|
||||
tcsetattr(tty, TCSANOW, &saved);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
index += bytes_read;
|
||||
if (passphrase[index-1] == '\n') {
|
||||
// Got end of line
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Write a newline (since the user's is not visible) and restore
|
||||
// terminal settings
|
||||
if (write(tty, "\n", 1) == -1) {
|
||||
perror("Failed to write to terminal");
|
||||
exit(1);
|
||||
}
|
||||
tcsetattr(tty, TCSANOW, &saved);
|
||||
close(tty);
|
||||
|
||||
return index - 1;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
unsigned char key[16] = {0};
|
||||
unsigned char salt[32] = "seasaltrocksalt seasaltrocksalt";
|
||||
unsigned char passphrase[] = "a quick brown fox jumps over the lazy dog";
|
||||
kdf(key, salt, passphrase, sizeof(passphrase) - 1);
|
||||
unsigned char salt[32];
|
||||
if (getentropy(salt, 32) != 0) {
|
||||
perror("getentropy");
|
||||
}
|
||||
|
||||
unsigned char passphrase[128] = {0};
|
||||
size_t passphrase_len = passphrase_prompt(passphrase, sizeof(passphrase), "passphrase: ");
|
||||
|
||||
unsigned char key[16];
|
||||
kdf(key, salt, passphrase, passphrase_len);
|
||||
for (size_t i = 0; i < 16; i++) {
|
||||
printf("%02hhx ", key[i]);
|
||||
}
|
||||
|
@ -455,7 +543,6 @@ int main(void) {
|
|||
}
|
||||
printf("\n");
|
||||
|
||||
|
||||
bool auth = ccm_decrypt(key, 25, buf, strlen(message), &buf[48]);
|
||||
printf("auth %s\n", auth ? "succeeded" : "failed");
|
||||
for (size_t i = 0; i < sizeof(buf); i++) {
|
||||
|
|
Loading…
Reference in New Issue