From 3d12da5569c59259092f578ba62023ced941b1cf Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Wed, 23 Apr 2014 18:24:25 +0200 Subject: first draft MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- src/autopasswd.c | 182 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 182 insertions(+) create mode 100644 src/autopasswd.c (limited to 'src/autopasswd.c') diff --git a/src/autopasswd.c b/src/autopasswd.c new file mode 100644 index 0000000..adec52f --- /dev/null +++ b/src/autopasswd.c @@ -0,0 +1,182 @@ +/** + * autopasswd – On the fly password generator + * + * Copyright © 2014 Mattias Andrée (maandree@member.fsf.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + + +#include +#include +#include +#include + +#include + +#include "sha3.h" + + + +/** + * Prompt string that tells you to enter your master passphrase + */ +#ifndef PASSPHRASE_PROMPT_STRING +# define PASSPHRASE_PROMPT_STRING "[autopasswd] Enter master passphrase: " +# warning: you should personalise PASSPHRASE_PROMPT_STRING. +#endif + +/** + * Prompt string that tells you to enter site + */ +#ifndef SITE_PROMPT_STRING +# define SITE_PROMPT_STRING "[autopasswd] Enter site: " +#endif + + + +#ifndef KECCAK_OUTPUT +# define KECCAK_OUTPUT 512 +#endif +#ifndef KECCAK_BITRATE +# define KECCAK_BITRATE (KECCAK_OUTPUT * 2) +#endif +#ifndef KECCAK_CAPACITY +# define KECCAK_CAPACITY (1600 - KECCAK_BITRATE) +#endif + +#ifndef KECCAK_SQUEEZES +# define KECCAK_SQUEEZES 300000 +#endif + +#define KECCAK_BYTE_OUTPUT ((KECCAK_OUTPUT + 7) / 8) + +#ifndef BASE64 +# define BASE64 "0123456789qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM,.-=" +#endif + + + +int main(int argc, char** argv) +{ + size_t ptr = 0; + size_t site_size = 64; + char* site; + char* passphrase; + uint8_t* digest; + char* base64; + size_t ptr64; + + /* Read site. */ + site = malloc(site_size * sizeof(char)); + if (site == NULL) + { + perror(*argv); + return 1; + } + fprintf(stderr, "%s", SITE_PROMPT_STRING); + fflush(stderr); + for (;;) + { + int c = getchar(); + if (c == -1) + { + free(site); + return 0; + } + if (c == '\n') + { + *(site + ptr) = 0; + break; + } + *(site + ptr++) = (char)c; + } + + /* Disable echoing. (Should be done as soon as possible.) */ + passphrase_disable_echo(); + + /* Initialise Keccak sponge. */ + sha3_initialise(KECCAK_BITRATE, KECCAK_CAPACITY, KECCAK_OUTPUT); + + /* Read passphrease. */ + fprintf(stderr, "%s", PASSPHRASE_PROMPT_STRING); + fflush(stderr); + passphrase = passphrase_read(); + if (passphrase == NULL) + { + perror(*argv); + passphrase_reenable_echo(); + sha3_dispose(); + free(site); + return 1; + } + + /* Reset terminal settings. */ + passphrase_reenable_echo(); + + /* Add passphrase to Keccak sponge input. */ + sha3_update(passphrase, strlen(passphrase)); + + /* Clear passphrase from memory. (Should be done as sone as possible.) */ + memset(passphrase, 0, strlen(passphrase)); + free(passphrase); + + /* Add site to Keccak sponge input. */ + sha3_digest(site, strlen(site), 0); + + /* Release resources. */ + free(site); + + /* Squeeze that sponge. */ + sha3_fastSqueeze(KECCAK_SQUEEZES); + digest = sha3_squeeze(); + + /* Release resources. */ + sha3_dispose(); + + /* Encode with base64 (no invalid character, shorter than hexadecimal.) */ + base64 = malloc((4 * ((KECCAK_BYTE_OUTPUT + 2) / 3) + 2) * sizeof(char)); + if (base64 == NULL) + { + perror(*argv); + free(digest); + free(base64); + } + for (ptr = ptr64 = 0; ptr < KECCAK_BYTE_OUTPUT; ptr64 += 4) + { + uint32_t a = ptr < KECCAK_BYTE_OUTPUT ? digest[ptr++] : 0; + uint32_t b = ptr < KECCAK_BYTE_OUTPUT ? digest[ptr++] : 0; + uint32_t c = ptr < KECCAK_BYTE_OUTPUT ? digest[ptr++] : 0; + + uint32_t abc = (a << 16) | (b << 8) | (c << 0); + + base64[ptr64 | 0] = BASE64[(abc >> (3 * 6)) & 63]; + base64[ptr64 | 1] = BASE64[(abc >> (2 * 6)) & 63]; + base64[ptr64 | 2] = BASE64[(abc >> (1 * 6)) & 63]; + base64[ptr64 | 3] = BASE64[(abc >> (0 * 6)) & 63]; + } + if ((KECCAK_BYTE_OUTPUT % 3) == 1) base64[ptr64++] = BASE64[64]; + if ((KECCAK_BYTE_OUTPUT % 3) == 2) base64[ptr64++] = BASE64[65]; + base64[ptr64++] = 0; + + /* Print generated password. */ + printf("\033[00m>\033[00;30;40m%s\033[00m<\n", base64); + + /* Release resources. */ + free(digest); + free(base64); + + return 0; +} + -- cgit v1.2.3-70-g09d2