From 2f66e8678971ba0340a96d811ced405d75dbb114 Mon Sep 17 00:00:00 2001 From: "@syxhe" Date: Sun, 19 Jan 2025 17:58:45 -0600 Subject: Write example code for generating, storing, and verifying a password --- src/encryption.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 65 insertions(+), 9 deletions(-) (limited to 'src/encryption.c') diff --git a/src/encryption.c b/src/encryption.c index 052b9aa..692b46a 100644 --- a/src/encryption.c +++ b/src/encryption.c @@ -8,12 +8,14 @@ #include #include #include +#include #include #include #include #include #include + #if defined ___VXGG___ALWAYS_CHECK_LIBSODIUM___ && ___VXGG___ALWAYS_CHECK_LIBSODIUM___ > 0 void naclfaildefault(void *none) { none = none; // Makes gcc happy @@ -60,17 +62,20 @@ void checksodium(void) { // 2- Encrypt the file's contents to the temp file -- // 2.1- Open the file -- // 2.2- Stream the file's contents into some encryption algo -- + // 2.2.1- Pick which encryption algo to use -- + // 2.2.2- Generate a key -- + // 2.2.2.1- Create a password to derrive a key from -- DONE // 2.3- Pipe the output of the encryption into the temp file -- // 3- Once the file has been encrypted, hard link it back to the original location, with the right name -- // 4- Delete the original file -- // 5- Delete the temp file -- -int maketmp(const char *dest) { +int maketmp(const char * const dest) { return open(dest, (O_TMPFILE | O_WRONLY | O_CLOEXEC | O_SYNC), (S_IRUSR | S_IWUSR)); } -int encrypttotmp(const char *toencrypt) { +int encrypttotmp(const char * const toencrypt) { #if defined ___VXGG___ALWAYS_CHECK_LIBSODIUM___ && ___VXGG___ALWAYS_CHECK_LIBSODIUM___ > 0 checksodium(); #endif @@ -110,6 +115,7 @@ int genpassword(char **str, unsigned int words) { int ret; for(unsigned int i = 1; i < words; i++) { ret = asprintf(&tmp, "%s %s", lstr, PASSWORD_WORDS[randombytes_uniform(PASSWORD_WORDS_LEN)]); + sodium_memzero(lstr, strlen(lstr) + 1); free(lstr); if(ret < 0) return -1; @@ -119,18 +125,29 @@ int genpassword(char **str, unsigned int words) { *str = lstr; return words; - - // This function was exploding because of some weird conflict with using my buggy implementation of asprintf instead of the - // _GNU_SOURCE version. Don't know why it wasn't using the _GNU_SOURCE version, as I had a define macro put in place to - // prevent it from being compiled if _GNU_SOURCE was defined, but whatever } +// sodium_malloc wrapper. Calls `error()` or `abort()` depnding on the value of `___VXGG___XALLOC_EXIT_ON_ERROR___`. Will make sure libsodium is initialized if `___VXGG___ALWAYS_CHECK_LIBSODIUM___ > 0` +void* xsodium_malloc(size_t size) { + #if defined ___VXGG___ALWAYS_CHECK_LIBSODIUM___ && ___VXGG___ALWAYS_CHECK_LIBSODIUM___ > 0 + checksodium(); + #endif + + void *mem = sodium_malloc(size); + if(mem == NULL) { + #if defined ___VXGG___XALLOC_EXIT_ON_ERROR___ && ___VXGG___XALLOC_EXIT_ON_ERROR___ > 0 + error(1, errno, "xsodium_malloc: could not allocate memory... Quitting"); + #endif + + abort(); + } + + return mem; +} #define TESTING #ifdef TESTING -#include - int main(void) { /*// Example code for creating a temp file, writing to it, then linking it back into the fs const char *dir = ".", *testmsg = "we do a little testing\n"; @@ -153,7 +170,7 @@ int main(void) { error(1, errno, "close broke"); //*/// - //*// Example code for getting a password using genpassword + /*// Example code for getting a password using genpassword checksodium(); char *password = NULL; @@ -162,6 +179,45 @@ int main(void) { free(password); //*/// + //*// Example code for generating a password, derriving a secret key from it, and storing things properly + + // Initialization + checksodium(); + char *pass = NULL, hpass[crypto_pwhash_STRBYTES]; + + if(genpassword(&pass, 20) < 0) { + error(1, 0, "Could not generate password, quitting..."); + abort(); // Makes gcc happy. Not sure why gcc randomly decides that error() isn't a proper exit, but hey whatever + } + sodium_mlock(pass, strlen(pass) + 1); + printf("Password:%s\n", pass); + + // Store the password + if(crypto_pwhash_str(hpass, pass, strlen(pass) + 1, crypto_pwhash_OPSLIMIT_MODERATE, crypto_pwhash_MEMLIMIT_MODERATE) != 0) + error(1, errno, "Couldn't generate password, quitting..."); + /* Don't know if I want to use MODERATE or SENSITIVE for this. SENSITIVE takes a little bit on my laptop, which honestly + // shouldn't be a problem, but it annoys me. MODERATE is quick and snappy, or at least quick enough that the slowdown is + // barely noticable. I might do MODERATE for testing and SENSITIVE for release */ + + sodium_munlock(pass, strlen(pass) + 1); + free(pass); + + printf("Hashed password: %s\n", hpass); + + // Check if the password from the user is correct + char *uin = NULL; int size = -1; + if((size = readwholebuffer(&uin, 20, STDIN_FILENO)) < 0) + error(1, errno, "Could not read from stdin"); + sodium_mlock(uin, size); + + printf("Valid password? %s\n", (crypto_pwhash_str_verify(hpass, uin, size) == 0) ? "True" : "False"); + + + sodium_munlock(uin, strlen(uin) + 1); + free(uin); + + //*/// + return 0; } -- cgit v1.2.3