diff options
| -rw-r--r-- | src/encryption.c | 126 |
1 files changed, 6 insertions, 120 deletions
diff --git a/src/encryption.c b/src/encryption.c index 8526f15..2d48e4e 100644 --- a/src/encryption.c +++ b/src/encryption.c | |||
| @@ -9,11 +9,6 @@ | |||
| 9 | * | 9 | * |
| 10 | */ | 10 | */ |
| 11 | 11 | ||
| 12 | // TODO: Go back and make sure every function has proper error handling | ||
| 13 | // Oh fucking christ what have I done | ||
| 14 | // I need to make sure every single function in this file returns with an indicated error instead of nuking the whole program with | ||
| 15 | // error() | ||
| 16 | |||
| 17 | #define _GNU_SOURCE 1 | 12 | #define _GNU_SOURCE 1 |
| 18 | 13 | ||
| 19 | #ifndef __VXGG_REWRITE___ENCRYPTION_C___1481879318188___ | 14 | #ifndef __VXGG_REWRITE___ENCRYPTION_C___1481879318188___ |
| @@ -40,12 +35,6 @@ | |||
| 40 | #include <errno.h> | 35 | #include <errno.h> |
| 41 | #include <error.h> | 36 | #include <error.h> |
| 42 | 37 | ||
| 43 | /// Runs sodium_init() before every call of a sodium function. Use is discouraged as this may cause unexpected early exits | ||
| 44 | #define ___VXGG___ALWAYS_CHECK_LIBSODIUM___ 0 | ||
| 45 | |||
| 46 | /// Defines `vxgg_setsodiumfailcb` function, which is used to set a custom callback for handling a failed libsodium init | ||
| 47 | #define ___VXGG___USE_CLS_CALLBACK___ 0 | ||
| 48 | |||
| 49 | /// Chunk size for encryption/decryption | 38 | /// Chunk size for encryption/decryption |
| 50 | #define CHUNKSIZE (1 << 9) | 39 | #define CHUNKSIZE (1 << 9) |
| 51 | 40 | ||
| @@ -105,94 +94,6 @@ | |||
| 105 | //! Short macro for getting the `PASSWORD_WORDS` array size | 94 | //! Short macro for getting the `PASSWORD_WORDS` array size |
| 106 | #define PASSWORD_WORDS_LEN (STATIC_ARRAY_LEN(PASSWORD_WORDS)) | 95 | #define PASSWORD_WORDS_LEN (STATIC_ARRAY_LEN(PASSWORD_WORDS)) |
| 107 | 96 | ||
| 108 | #if ___VXGG___ALWAYS_CHECK_LIBSODIUM___ > 0 | ||
| 109 | #if ___VXGG___USE_CLS_CALLBACK___ > 0 | ||
| 110 | |||
| 111 | //! Definition for the callback function that fires when a call to checksodium fails | ||
| 112 | typedef void (*vxgg_naclfailcb)(void*); | ||
| 113 | |||
| 114 | /** | ||
| 115 | * @brief Default sodium init fail callback for use in `checksodiumcb()` | ||
| 116 | * | ||
| 117 | * @param none Unused param to fit callback spec | ||
| 118 | */ | ||
| 119 | static void naclfaildefault(void *none) { | ||
| 120 | none = none; // Makes gcc happy | ||
| 121 | if(___VXGG___VERBOSE_ERRORS___) | ||
| 122 | error(1, ENOTSUP, "<naclfaildefault> Couldn't initialize sodium for some reason. Quitting..."); | ||
| 123 | exit(EXIT_FAILURE); | ||
| 124 | } | ||
| 125 | |||
| 126 | /** | ||
| 127 | * @brief Internal function to deal with the `___VXGG___USE_CLS_CALLBACK___` macro | ||
| 128 | * | ||
| 129 | * `checksodiumcb()` runs the sodium function `sodium_init()` and on error calls the provided callback with the provided data. The | ||
| 130 | * callback and data default to `naclfaildefault` and `NULL`, but can be changed when the `set` parameter is non-zero. When `set` | ||
| 131 | * is zero, the sodium init check is preformed | ||
| 132 | * | ||
| 133 | * @note `checksodiumcb()` is ran when these conditions are true - 1: The `___VXGG___ALWAYS_CHECK_LIBSODIUM___` and `___VXGG___USE_CLS_CALLBACK___` | ||
| 134 | * macros are both greater than 0 when compiling, and 2: a function in `encryption.c` calls a function originating from sodium. This | ||
| 135 | * function exists as a way to deal with sodium failing yourself, instead of instantly calling `exit()`. If you don't care to handle | ||
| 136 | * it, or are initializing sodium yourself, this is unnecessary | ||
| 137 | * | ||
| 138 | * @param callback A callback to be ran when sodium fails to initialize itself. Ignored if `set` is zero. Must be non-null when `set` is non-zero | ||
| 139 | * @param data Data to be passed to the callback when it is fired. Ignored if `set` is zero. May be null | ||
| 140 | * @param set Flag on whether to check sodium or to set a new callback and data pair. Checks sodium when zero, sets callback & data when non-zero | ||
| 141 | * @retval int | ||
| 142 | */ | ||
| 143 | static int checksodiumcb(vxgg_naclfailcb const callback, void *data, unsigned char set) { | ||
| 144 | static vxgg_naclfailcb cb = naclfaildefault; | ||
| 145 | static void *usr = NULL; | ||
| 146 | int ret; | ||
| 147 | |||
| 148 | if(set) { | ||
| 149 | if(cb == NULL) ERRRET(EINVAL, -1); | ||
| 150 | cb = callback; | ||
| 151 | usr = data; | ||
| 152 | return 2; // libsodium normally returns 1 if the library is already initialized, so this is to signal that the callback has been updated | ||
| 153 | } | ||
| 154 | |||
| 155 | if((ret = sodium_init()) < 0) { | ||
| 156 | if(cb == NULL) | ||
| 157 | error(0, EINVAL, "<checksodiumcb> refusing to run a null callback"); | ||
| 158 | else | ||
| 159 | cb(usr); | ||
| 160 | } | ||
| 161 | |||
| 162 | return ret; | ||
| 163 | } | ||
| 164 | |||
| 165 | void vxgg_setsodiumfailcb(vxgg_naclfailcb cb, void *data) { | ||
| 166 | checksodiumcb(cb, data, 1); | ||
| 167 | } | ||
| 168 | |||
| 169 | #endif | ||
| 170 | |||
| 171 | /** | ||
| 172 | * @brief Simple function to check if sodium has been properly initialized | ||
| 173 | * | ||
| 174 | * `checksodium()` will run in functions located in `encryption.h` only when the macro `___VXGG___ALWAYS_CHECK_LIBSODIUM___` is greater | ||
| 175 | * than zero when compiling. It will call the `checksodiumcb()` function if compiled with the `___VXGG___USE_CLS_CALLBACK___` macro. | ||
| 176 | * When called, checksodium will run `sodium_init()`, and will either run the user-defined callback or `XALLOC_EXIT`. | ||
| 177 | * | ||
| 178 | */ | ||
| 179 | static void checksodium(void) { | ||
| 180 | #if ___VXGG___USE_CLS_CALLBACK___ > 0 | ||
| 181 | checksodiumcb(NULL, NULL, 0); | ||
| 182 | #else | ||
| 183 | |||
| 184 | if(sodium_init() < 0) { | ||
| 185 | errno = ENOTSUP; | ||
| 186 | XALLOC_EXIT("<checksodium> Couldn't initialize sodium for some reason. Quitting..."); | ||
| 187 | } | ||
| 188 | |||
| 189 | #endif | ||
| 190 | |||
| 191 | return; | ||
| 192 | } | ||
| 193 | |||
| 194 | #endif | ||
| 195 | |||
| 196 | /** | 97 | /** |
| 197 | * @brief open() with the flags O_TMPFILE, O_WRONLY, O_CLOEXEC, and O_SYNC. Opened with mode S_IRUSR, S_IWUSR | 98 | * @brief open() with the flags O_TMPFILE, O_WRONLY, O_CLOEXEC, and O_SYNC. Opened with mode S_IRUSR, S_IWUSR |
| 198 | * | 99 | * |
| @@ -214,13 +115,16 @@ int maketmp(const char * const dest) { | |||
| 214 | int linkto(const char * const target, int tgfd) { | 115 | int linkto(const char * const target, int tgfd) { |
| 215 | if(!target || tgfd < 0) ERRRET(EINVAL, -1); | 116 | if(!target || tgfd < 0) ERRRET(EINVAL, -1); |
| 216 | if(access(target, F_OK) != -1) ERRRET(EEXIST, -1); | 117 | if(access(target, F_OK) != -1) ERRRET(EEXIST, -1); |
| 118 | |||
| 217 | char *path = NULL; | 119 | char *path = NULL; |
| 120 | int res = -1; | ||
| 218 | 121 | ||
| 219 | asprintf(&path, "/proc/self/fd/%d", tgfd); | 122 | asprintf(&path, "/proc/self/fd/%d", tgfd); |
| 220 | if(!path) ERROR(1, errno, "<linkto> Couldn't get path to move file into system",); | 123 | if(!path) {WARN(errno, "<linkto> Couldn't get path to move file into system",); goto CLEANUP_linkto;} |
| 221 | 124 | ||
| 222 | int res = linkat(AT_FDCWD, path, AT_FDCWD, target, AT_SYMLINK_FOLLOW); | 125 | res = linkat(AT_FDCWD, path, AT_FDCWD, target, AT_SYMLINK_FOLLOW); |
| 223 | 126 | ||
| 127 | CLEANUP_linkto: | ||
| 224 | free(path); | 128 | free(path); |
| 225 | return res; | 129 | return res; |
| 226 | } | 130 | } |
| @@ -237,9 +141,6 @@ int linkto(const char * const target, int tgfd) { | |||
| 237 | */ | 141 | */ |
| 238 | int encrypttofile(FILE *src, FILE *dst, const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]) { | 142 | int encrypttofile(FILE *src, FILE *dst, const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]) { |
| 239 | if(!src || !dst || !key) ERRRET(EINVAL, -1); | 143 | if(!src || !dst || !key) ERRRET(EINVAL, -1); |
| 240 | #if ___VXGG___ALWAYS_CHECK_LIBSODIUM___ > 0 | ||
| 241 | checksodium(); | ||
| 242 | #endif | ||
| 243 | 144 | ||
| 244 | unsigned char buf[CHUNKSIZE], cbuf[CHUNKSIZE + crypto_secretstream_xchacha20poly1305_ABYTES]; | 145 | unsigned char buf[CHUNKSIZE], cbuf[CHUNKSIZE + crypto_secretstream_xchacha20poly1305_ABYTES]; |
| 245 | unsigned char header[crypto_secretstream_xchacha20poly1305_HEADERBYTES]; | 146 | unsigned char header[crypto_secretstream_xchacha20poly1305_HEADERBYTES]; |
| @@ -289,9 +190,6 @@ int encrypttofile(FILE *src, FILE *dst, const unsigned char key[crypto_secretstr | |||
| 289 | */ | 190 | */ |
| 290 | int decrypttofile(FILE *src, FILE *dst, const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]) { | 191 | int decrypttofile(FILE *src, FILE *dst, const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]) { |
| 291 | if(!src || !dst || !key) ERRRET(EINVAL, -1); | 192 | if(!src || !dst || !key) ERRRET(EINVAL, -1); |
| 292 | #if ___VXGG___ALWAYS_CHECK_LIBSODIUM___ > 0 | ||
| 293 | checksodium(); | ||
| 294 | #endif | ||
| 295 | 193 | ||
| 296 | unsigned char cbuf[CHUNKSIZE + crypto_secretstream_xchacha20poly1305_ABYTES], buf[CHUNKSIZE]; | 194 | unsigned char cbuf[CHUNKSIZE + crypto_secretstream_xchacha20poly1305_ABYTES], buf[CHUNKSIZE]; |
| 297 | unsigned char header[crypto_secretstream_xchacha20poly1305_HEADERBYTES]; | 195 | unsigned char header[crypto_secretstream_xchacha20poly1305_HEADERBYTES]; |
| @@ -354,9 +252,7 @@ int decrypttofile(FILE *src, FILE *dst, const unsigned char key[crypto_secretstr | |||
| 354 | * @retval (int)[,] | 252 | * @retval (int)[,] |
| 355 | */ | 253 | */ |
| 356 | int encryptviatmp(const char * const target, const char * const output, const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]) { | 254 | int encryptviatmp(const char * const target, const char * const output, const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]) { |
| 357 | #if ___VXGG___ALWAYS_CHECK_LIBSODIUM___ > 0 | 255 | if(!target || !output || !key) ERRRET(EINVAL, -1); |
| 358 | checksodium(); | ||
| 359 | #endif | ||
| 360 | 256 | ||
| 361 | int fd = -1, tfd = -1, res = -1; | 257 | int fd = -1, tfd = -1, res = -1; |
| 362 | FILE *src, *dst; | 258 | FILE *src, *dst; |
| @@ -409,9 +305,6 @@ CLEANUP_encryptviatmp: | |||
| 409 | */ | 305 | */ |
| 410 | int decryptto(const char * const target, const char * const output, const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]) { | 306 | int decryptto(const char * const target, const char * const output, const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]) { |
| 411 | if(!target || !output || !key) ERRRET(EINVAL, -1); | 307 | if(!target || !output || !key) ERRRET(EINVAL, -1); |
| 412 | #if ___VXGG___ALWAYS_CHECK_LIBSODIUM___ > 0 | ||
| 413 | checksodium(); | ||
| 414 | #endif | ||
| 415 | 308 | ||
| 416 | FILE *src, *dst; | 309 | FILE *src, *dst; |
| 417 | int fdst, eflag = -1, res = -1; | 310 | int fdst, eflag = -1, res = -1; |
| @@ -463,9 +356,6 @@ int genpassword(char **str, unsigned int words) { | |||
| 463 | // Early returns | 356 | // Early returns |
| 464 | if(words < 1) return 0; | 357 | if(words < 1) return 0; |
| 465 | if(!str) ERRRET(EINVAL, -1); | 358 | if(!str) ERRRET(EINVAL, -1); |
| 466 | #if ___VXGG___ALWAYS_CHECK_LIBSODIUM___ > 0 | ||
| 467 | checksodium(); | ||
| 468 | #endif | ||
| 469 | 359 | ||
| 470 | // Bootstrap the first word | 360 | // Bootstrap the first word |
| 471 | char *lstr = NULL, *tmp = NULL; | 361 | char *lstr = NULL, *tmp = NULL; |
| @@ -497,10 +387,6 @@ int genpassword(char **str, unsigned int words) { | |||
| 497 | * @retval (void*) A pointer to some data allocated via `sodium_malloc()` | 387 | * @retval (void*) A pointer to some data allocated via `sodium_malloc()` |
| 498 | */ | 388 | */ |
| 499 | void* xsodium_malloc(size_t size) { | 389 | void* xsodium_malloc(size_t size) { |
| 500 | #if ___VXGG___ALWAYS_CHECK_LIBSODIUM___ > 0 | ||
| 501 | checksodium(); | ||
| 502 | #endif | ||
| 503 | |||
| 504 | void *mem = sodium_malloc(size); | 390 | void *mem = sodium_malloc(size); |
| 505 | if(mem == NULL) | 391 | if(mem == NULL) |
| 506 | XALLOC_EXIT("<xsodium_malloc> could not allocate memory... Quitting", ); | 392 | XALLOC_EXIT("<xsodium_malloc> could not allocate memory... Quitting", ); |
