diff options
| author | @syxhe <https://t.me/syxhe> | 2025-01-19 17:58:45 -0600 |
|---|---|---|
| committer | @syxhe <https://t.me/syxhe> | 2025-01-19 17:58:45 -0600 |
| commit | 2f66e8678971ba0340a96d811ced405d75dbb114 (patch) | |
| tree | 85bbeb6d86e8abecd18782f0be18151c57bb8b27 /src | |
| parent | 0c19d693bfe1dd3071c71d9d95f68c0db5cc75d0 (diff) | |
Write example code for generating, storing, and verifying a password
Diffstat (limited to 'src')
| -rw-r--r-- | src/encryption.c | 74 | ||||
| -rw-r--r-- | src/encryption.h | 2 | ||||
| -rw-r--r-- | src/shared.c | 57 | ||||
| -rw-r--r-- | src/shared.h | 3 |
4 files changed, 124 insertions, 12 deletions
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 @@ | |||
| 8 | #include <sys/types.h> | 8 | #include <sys/types.h> |
| 9 | #include <sys/stat.h> | 9 | #include <sys/stat.h> |
| 10 | #include <stdarg.h> | 10 | #include <stdarg.h> |
| 11 | #include <string.h> | ||
| 11 | #include <unistd.h> | 12 | #include <unistd.h> |
| 12 | #include <errno.h> | 13 | #include <errno.h> |
| 13 | #include <error.h> | 14 | #include <error.h> |
| 14 | #include <fcntl.h> | 15 | #include <fcntl.h> |
| 15 | #include <stdio.h> | 16 | #include <stdio.h> |
| 16 | 17 | ||
| 18 | |||
| 17 | #if defined ___VXGG___ALWAYS_CHECK_LIBSODIUM___ && ___VXGG___ALWAYS_CHECK_LIBSODIUM___ > 0 | 19 | #if defined ___VXGG___ALWAYS_CHECK_LIBSODIUM___ && ___VXGG___ALWAYS_CHECK_LIBSODIUM___ > 0 |
| 18 | void naclfaildefault(void *none) { | 20 | void naclfaildefault(void *none) { |
| 19 | none = none; // Makes gcc happy | 21 | none = none; // Makes gcc happy |
| @@ -60,17 +62,20 @@ void checksodium(void) { | |||
| 60 | // 2- Encrypt the file's contents to the temp file -- | 62 | // 2- Encrypt the file's contents to the temp file -- |
| 61 | // 2.1- Open the file -- | 63 | // 2.1- Open the file -- |
| 62 | // 2.2- Stream the file's contents into some encryption algo -- | 64 | // 2.2- Stream the file's contents into some encryption algo -- |
| 65 | // 2.2.1- Pick which encryption algo to use -- | ||
| 66 | // 2.2.2- Generate a key -- | ||
| 67 | // 2.2.2.1- Create a password to derrive a key from -- DONE | ||
| 63 | // 2.3- Pipe the output of the encryption into the temp file -- | 68 | // 2.3- Pipe the output of the encryption into the temp file -- |
| 64 | // 3- Once the file has been encrypted, hard link it back to the original location, with the right name -- | 69 | // 3- Once the file has been encrypted, hard link it back to the original location, with the right name -- |
| 65 | // 4- Delete the original file -- | 70 | // 4- Delete the original file -- |
| 66 | // 5- Delete the temp file -- | 71 | // 5- Delete the temp file -- |
| 67 | 72 | ||
| 68 | 73 | ||
| 69 | int maketmp(const char *dest) { | 74 | int maketmp(const char * const dest) { |
| 70 | return open(dest, (O_TMPFILE | O_WRONLY | O_CLOEXEC | O_SYNC), (S_IRUSR | S_IWUSR)); | 75 | return open(dest, (O_TMPFILE | O_WRONLY | O_CLOEXEC | O_SYNC), (S_IRUSR | S_IWUSR)); |
| 71 | } | 76 | } |
| 72 | 77 | ||
| 73 | int encrypttotmp(const char *toencrypt) { | 78 | int encrypttotmp(const char * const toencrypt) { |
| 74 | #if defined ___VXGG___ALWAYS_CHECK_LIBSODIUM___ && ___VXGG___ALWAYS_CHECK_LIBSODIUM___ > 0 | 79 | #if defined ___VXGG___ALWAYS_CHECK_LIBSODIUM___ && ___VXGG___ALWAYS_CHECK_LIBSODIUM___ > 0 |
| 75 | checksodium(); | 80 | checksodium(); |
| 76 | #endif | 81 | #endif |
| @@ -110,6 +115,7 @@ int genpassword(char **str, unsigned int words) { | |||
| 110 | int ret; | 115 | int ret; |
| 111 | for(unsigned int i = 1; i < words; i++) { | 116 | for(unsigned int i = 1; i < words; i++) { |
| 112 | ret = asprintf(&tmp, "%s %s", lstr, PASSWORD_WORDS[randombytes_uniform(PASSWORD_WORDS_LEN)]); | 117 | ret = asprintf(&tmp, "%s %s", lstr, PASSWORD_WORDS[randombytes_uniform(PASSWORD_WORDS_LEN)]); |
| 118 | sodium_memzero(lstr, strlen(lstr) + 1); | ||
| 113 | free(lstr); | 119 | free(lstr); |
| 114 | if(ret < 0) | 120 | if(ret < 0) |
| 115 | return -1; | 121 | return -1; |
| @@ -119,18 +125,29 @@ int genpassword(char **str, unsigned int words) { | |||
| 119 | 125 | ||
| 120 | *str = lstr; | 126 | *str = lstr; |
| 121 | return words; | 127 | return words; |
| 122 | |||
| 123 | // This function was exploding because of some weird conflict with using my buggy implementation of asprintf instead of the | ||
| 124 | // _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 | ||
| 125 | // prevent it from being compiled if _GNU_SOURCE was defined, but whatever | ||
| 126 | } | 128 | } |
| 127 | 129 | ||
| 130 | // 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` | ||
| 131 | void* xsodium_malloc(size_t size) { | ||
| 132 | #if defined ___VXGG___ALWAYS_CHECK_LIBSODIUM___ && ___VXGG___ALWAYS_CHECK_LIBSODIUM___ > 0 | ||
| 133 | checksodium(); | ||
| 134 | #endif | ||
| 135 | |||
| 136 | void *mem = sodium_malloc(size); | ||
| 137 | if(mem == NULL) { | ||
| 138 | #if defined ___VXGG___XALLOC_EXIT_ON_ERROR___ && ___VXGG___XALLOC_EXIT_ON_ERROR___ > 0 | ||
| 139 | error(1, errno, "xsodium_malloc: could not allocate memory... Quitting"); | ||
| 140 | #endif | ||
| 141 | |||
| 142 | abort(); | ||
| 143 | } | ||
| 144 | |||
| 145 | return mem; | ||
| 146 | } | ||
| 128 | 147 | ||
| 129 | #define TESTING | 148 | #define TESTING |
| 130 | #ifdef TESTING | 149 | #ifdef TESTING |
| 131 | 150 | ||
| 132 | #include <string.h> | ||
| 133 | |||
| 134 | int main(void) { | 151 | int main(void) { |
| 135 | /*// Example code for creating a temp file, writing to it, then linking it back into the fs | 152 | /*// Example code for creating a temp file, writing to it, then linking it back into the fs |
| 136 | const char *dir = ".", *testmsg = "we do a little testing\n"; | 153 | const char *dir = ".", *testmsg = "we do a little testing\n"; |
| @@ -153,7 +170,7 @@ int main(void) { | |||
| 153 | error(1, errno, "close broke"); | 170 | error(1, errno, "close broke"); |
| 154 | //*/// | 171 | //*/// |
| 155 | 172 | ||
| 156 | //*// Example code for getting a password using genpassword | 173 | /*// Example code for getting a password using genpassword |
| 157 | checksodium(); | 174 | checksodium(); |
| 158 | 175 | ||
| 159 | char *password = NULL; | 176 | char *password = NULL; |
| @@ -162,6 +179,45 @@ int main(void) { | |||
| 162 | free(password); | 179 | free(password); |
| 163 | //*/// | 180 | //*/// |
| 164 | 181 | ||
| 182 | //*// Example code for generating a password, derriving a secret key from it, and storing things properly | ||
| 183 | |||
| 184 | // Initialization | ||
| 185 | checksodium(); | ||
| 186 | char *pass = NULL, hpass[crypto_pwhash_STRBYTES]; | ||
| 187 | |||
| 188 | if(genpassword(&pass, 20) < 0) { | ||
| 189 | error(1, 0, "Could not generate password, quitting..."); | ||
| 190 | abort(); // Makes gcc happy. Not sure why gcc randomly decides that error() isn't a proper exit, but hey whatever | ||
| 191 | } | ||
| 192 | sodium_mlock(pass, strlen(pass) + 1); | ||
| 193 | printf("Password:%s\n", pass); | ||
| 194 | |||
| 195 | // Store the password | ||
| 196 | if(crypto_pwhash_str(hpass, pass, strlen(pass) + 1, crypto_pwhash_OPSLIMIT_MODERATE, crypto_pwhash_MEMLIMIT_MODERATE) != 0) | ||
| 197 | error(1, errno, "Couldn't generate password, quitting..."); | ||
| 198 | /* Don't know if I want to use MODERATE or SENSITIVE for this. SENSITIVE takes a little bit on my laptop, which honestly | ||
| 199 | // shouldn't be a problem, but it annoys me. MODERATE is quick and snappy, or at least quick enough that the slowdown is | ||
| 200 | // barely noticable. I might do MODERATE for testing and SENSITIVE for release */ | ||
| 201 | |||
| 202 | sodium_munlock(pass, strlen(pass) + 1); | ||
| 203 | free(pass); | ||
| 204 | |||
| 205 | printf("Hashed password: %s\n", hpass); | ||
| 206 | |||
| 207 | // Check if the password from the user is correct | ||
| 208 | char *uin = NULL; int size = -1; | ||
| 209 | if((size = readwholebuffer(&uin, 20, STDIN_FILENO)) < 0) | ||
| 210 | error(1, errno, "Could not read from stdin"); | ||
| 211 | sodium_mlock(uin, size); | ||
| 212 | |||
| 213 | printf("Valid password? %s\n", (crypto_pwhash_str_verify(hpass, uin, size) == 0) ? "True" : "False"); | ||
| 214 | |||
| 215 | |||
| 216 | sodium_munlock(uin, strlen(uin) + 1); | ||
| 217 | free(uin); | ||
| 218 | |||
| 219 | //*/// | ||
| 220 | |||
| 165 | return 0; | 221 | return 0; |
| 166 | } | 222 | } |
| 167 | 223 | ||
diff --git a/src/encryption.h b/src/encryption.h index 01aa704..c780e2b 100644 --- a/src/encryption.h +++ b/src/encryption.h | |||
| @@ -77,6 +77,6 @@ void vxgg_setsodiumfailcb(const vxgg_naclfailcb cb, void *data); | |||
| 77 | void checksodium(void); | 77 | void checksodium(void); |
| 78 | 78 | ||
| 79 | // open() with the flags O_TMPFILE, O_WRONLY, O_CLOEXEC, and O_SYNC. Opened with mode S_IRUSR, S_IWUSR | 79 | // open() with the flags O_TMPFILE, O_WRONLY, O_CLOEXEC, and O_SYNC. Opened with mode S_IRUSR, S_IWUSR |
| 80 | int maketmp(const char *dest); | 80 | int maketmp(const char * const dest); |
| 81 | 81 | ||
| 82 | #endif \ No newline at end of file | 82 | #endif \ No newline at end of file |
diff --git a/src/shared.c b/src/shared.c index b154391..e5f0f13 100644 --- a/src/shared.c +++ b/src/shared.c | |||
| @@ -2,6 +2,8 @@ | |||
| 2 | 2 | ||
| 3 | #include <stdarg.h> | 3 | #include <stdarg.h> |
| 4 | #include <stdlib.h> | 4 | #include <stdlib.h> |
| 5 | #include <string.h> | ||
| 6 | #include <unistd.h> | ||
| 5 | #include <errno.h> | 7 | #include <errno.h> |
| 6 | #include <error.h> | 8 | #include <error.h> |
| 7 | #include <stdio.h> | 9 | #include <stdio.h> |
| @@ -9,7 +11,7 @@ | |||
| 9 | void* xcalloc(size_t nmemb, size_t size) { | 11 | void* xcalloc(size_t nmemb, size_t size) { |
| 10 | void *mem = calloc(nmemb, size); | 12 | void *mem = calloc(nmemb, size); |
| 11 | 13 | ||
| 12 | if(mem == NULL) { | 14 | if(!mem) { |
| 13 | #if defined ___VXGG___XALLOC_EXIT_ON_ERROR___ && ___VXGG___XALLOC_EXIT_ON_ERROR___ > 0 | 15 | #if defined ___VXGG___XALLOC_EXIT_ON_ERROR___ && ___VXGG___XALLOC_EXIT_ON_ERROR___ > 0 |
| 14 | error(1, errno, "<xcalloc> Could not allocate memory"); | 16 | error(1, errno, "<xcalloc> Could not allocate memory"); |
| 15 | #endif | 17 | #endif |
| @@ -33,4 +35,55 @@ void* xreallocarray(void *ptr, size_t nmemb, size_t size) { | |||
| 33 | } | 35 | } |
| 34 | 36 | ||
| 35 | return mem; | 37 | return mem; |
| 36 | } \ No newline at end of file | 38 | } |
| 39 | |||
| 40 | int readwholebuffer(char **str, unsigned long int initsize, int fd) { | ||
| 41 | // Try to read bytes from fd into str | ||
| 42 | // Bytes read == 0, return 0 | ||
| 43 | // Bytes read < 0, free string, return -1; | ||
| 44 | // When string hits capacity, double the capacity, and reallocate the string | ||
| 45 | |||
| 46 | char *lstr = NULL, *tmp = NULL; | ||
| 47 | ssize_t bytesread = -1; | ||
| 48 | int csize = initsize, ccap = initsize; | ||
| 49 | |||
| 50 | lstr = xcalloc(initsize, sizeof(char)); | ||
| 51 | while((bytesread = read(fd, lstr + (csize - ccap), ccap)) > 0) { | ||
| 52 | ccap -= bytesread; | ||
| 53 | if(ccap <= 0) { | ||
| 54 | csize *= 2; | ||
| 55 | ccap = csize / 2; | ||
| 56 | |||
| 57 | tmp = realloc(lstr, csize * sizeof(char)); | ||
| 58 | if(!tmp) { | ||
| 59 | error(0, errno, "Could not reallocate enough space for lstr"); | ||
| 60 | free(lstr); | ||
| 61 | bytesread = -100; | ||
| 62 | break; | ||
| 63 | } | ||
| 64 | lstr = tmp; | ||
| 65 | } | ||
| 66 | } | ||
| 67 | if(bytesread < 0 && bytesread != -100) { | ||
| 68 | error(0, errno, "Ran into a read() error"); | ||
| 69 | free(lstr); | ||
| 70 | lstr = NULL; | ||
| 71 | } | ||
| 72 | |||
| 73 | if(lstr) { | ||
| 74 | tmp = realloc(lstr, csize - ccap + 1); | ||
| 75 | if(!tmp) { | ||
| 76 | error(0, errno, "Could not shrink lstr after reading buffer"); | ||
| 77 | free(lstr); | ||
| 78 | bytesread = -100; | ||
| 79 | } | ||
| 80 | lstr = tmp; | ||
| 81 | } | ||
| 82 | |||
| 83 | if(lstr) { | ||
| 84 | lstr[csize - ccap - 1] = '\0'; // Don't include the newline | ||
| 85 | } | ||
| 86 | |||
| 87 | *str = lstr; | ||
| 88 | return ((bytesread == 0) ? (csize - ccap) : -1); | ||
| 89 | } | ||
diff --git a/src/shared.h b/src/shared.h index 620ec82..dce02fc 100644 --- a/src/shared.h +++ b/src/shared.h | |||
| @@ -17,4 +17,7 @@ void* xcalloc(size_t nmemb, size_t size); | |||
| 17 | // `reallocarray()` with error checking. Calls `error()` or `abort()` on error, depending on the value of `___VXGG___XALLOC_EXIT_ON_ERROR___` | 17 | // `reallocarray()` with error checking. Calls `error()` or `abort()` on error, depending on the value of `___VXGG___XALLOC_EXIT_ON_ERROR___` |
| 18 | void* xreallocarray(void *ptr, size_t nmemb, size_t size); | 18 | void* xreallocarray(void *ptr, size_t nmemb, size_t size); |
| 19 | 19 | ||
| 20 | // Read the entire contents of a file descriptor into a malloc()'ed buffer | ||
| 21 | int readwholebuffer(char **str, unsigned long int initsize, int fd); | ||
| 22 | |||
| 20 | #endif \ No newline at end of file | 23 | #endif \ No newline at end of file |
