Add function for reading passphrase from terminal
This commit is contained in:
parent
7bf44017a4
commit
741c0d0bb5
1 changed files with 93 additions and 6 deletions
99
puer.c
99
puer.c
|
@ -1,8 +1,14 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.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]) {
|
void xxtea128(uint32_t const key[4], uint32_t block[4]) {
|
||||||
// Encryption half of the XXTEA algorithm, with block size limited
|
// 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;
|
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) {
|
int main(void) {
|
||||||
unsigned char key[16] = {0};
|
unsigned char salt[32];
|
||||||
unsigned char salt[32] = "seasaltrocksalt seasaltrocksalt";
|
if (getentropy(salt, 32) != 0) {
|
||||||
unsigned char passphrase[] = "a quick brown fox jumps over the lazy dog";
|
perror("getentropy");
|
||||||
kdf(key, salt, passphrase, sizeof(passphrase) - 1);
|
}
|
||||||
|
|
||||||
|
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++) {
|
for (size_t i = 0; i < 16; i++) {
|
||||||
printf("%02hhx ", key[i]);
|
printf("%02hhx ", key[i]);
|
||||||
}
|
}
|
||||||
|
@ -455,7 +543,6 @@ int main(void) {
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
|
|
||||||
bool auth = ccm_decrypt(key, 25, buf, strlen(message), &buf[48]);
|
bool auth = ccm_decrypt(key, 25, buf, strlen(message), &buf[48]);
|
||||||
printf("auth %s\n", auth ? "succeeded" : "failed");
|
printf("auth %s\n", auth ? "succeeded" : "failed");
|
||||||
for (size_t i = 0; i < sizeof(buf); i++) {
|
for (size_t i = 0; i < sizeof(buf); i++) {
|
||||||
|
|
Loading…
Reference in a new issue