diff options
author | David Timber <mieabby@gmail.com> | 2020-01-03 03:08:19 +1100 |
---|---|---|
committer | David Timber <mieabby@gmail.com> | 2020-01-03 03:08:19 +1100 |
commit | 9a2a07861e3919ea2d8f3b4f36e2d51d7748ba9d (patch) | |
tree | 4cb2cea83cc440e67abef03e70b089369b0fecc6 /src/util_rt.c | |
parent | ed809a51fdd1c313cd256301ef6f7211e8394cb1 (diff) |
checkpoint
Diffstat (limited to 'src/util_rt.c')
-rw-r--r-- | src/util_rt.c | 240 |
1 files changed, 240 insertions, 0 deletions
diff --git a/src/util_rt.c b/src/util_rt.c new file mode 100644 index 0000000..28133e0 --- /dev/null +++ b/src/util_rt.c @@ -0,0 +1,240 @@ +#include "util_rt.h" + +#include <stdlib.h> +#include <string.h> +#include <ctype.h> + +#include <errno.h> + +#include <openssl/bio.h> +#include <openssl/evp.h> + + +void prne_succeed_or_die (const int ret) { + if (ret < 0) { + abort(); + } +} + +void prne_empty_func () {} + +void *prne_malloc (const size_t se, const size_t cnt) { + if (SIZE_MAX / se < cnt) { + errno = ENOMEM; + return NULL; + } + return malloc(cnt * se); +} + +void *prne_realloc (void *ptr, const size_t se, const size_t cnt) { + if (SIZE_MAX / se < cnt) { + errno = ENOMEM; + return NULL; + } + return realloc(ptr, se * cnt); +} + +void *prne_calloc (const size_t se, const size_t cnt) { + return calloc(se, cnt); +} + +void prne_free (void *ptr) { + free(ptr); +} + +void prne_rnd_anum_str (prne_rnd_engine_t *rnd_engine, char *str, const size_t len) { + static const char SET[] = "qwertyuiopasdfghjklzxcvbnm0123456789"; + size_t i = 0; + uint32_t n; + + if (len >= 4) { + for (; i < len / 4 * 4; i += 4) { + n = prne_rnd_gen_int(rnd_engine); + str[i + 0] = SET[((uint8_t*)&n)[0] % sizeof(SET)]; + str[i + 1] = SET[((uint8_t*)&n)[1] % sizeof(SET)]; + str[i + 2] = SET[((uint8_t*)&n)[2] % sizeof(SET)]; + str[i + 3] = SET[((uint8_t*)&n)[3] % sizeof(SET)]; + } + } + if (i < len) { + n = prne_rnd_gen_int(rnd_engine); + for (; i < len; i += 1) { + str[i] = SET[((uint8_t*)&n)[i % 4] % sizeof(SET)]; + } + } +} + +size_t prne_str_shift_spaces (char *str, const size_t len) { + size_t i, ret = len; + + for (i = 0; i < ret; ) { + if (isspace(str[i])) { + if (i + 1 >= ret) { + // last trailing whitespace + ret -= 1; + break; + } + memmove(str + i, str + i + 1, ret - i - 1); + ret -= 1; + } + else { + i += 1; + } + } + + return ret; +} + + +struct timespec prne_sub_timespec (const struct timespec *a, const struct timespec *b) { + struct timespec ret; + + if (a->tv_nsec < b->tv_nsec) { + ret.tv_sec = a->tv_sec - 1 - b->tv_sec; + ret.tv_nsec = 1000000000 + a->tv_nsec - b->tv_nsec; + } + else { + ret.tv_sec = a->tv_sec - b->tv_sec; + ret.tv_nsec = a->tv_nsec - b->tv_nsec; + } + + return ret; +} + +double prne_real_timespec (const struct timespec *ts) { + return (double)ts->tv_sec + (double)ts->tv_nsec / 1000000000.0; +} + +int prne_cmp_timespec (const struct timespec *a, const struct timespec *b) { + if (a->tv_sec < b->tv_sec) { + return -1; + } + else if (a->tv_sec > b->tv_sec) { + return 1; + } + + return a->tv_nsec < b->tv_nsec ? -1 : a->tv_nsec > b->tv_nsec ? 1 : 0; +} + +char *prne_enc_base64_mem (const uint8_t *data, const size_t size) { + char *ret = NULL, *p = NULL; + BIO *b64_bio = NULL, *mem_bio = NULL; + bool ok = true; + int out_len; + + if (size > INT32_MAX || size == 0) { + return NULL; + } + + b64_bio = BIO_new(BIO_f_base64()); + mem_bio = BIO_new(BIO_s_mem()); + if (b64_bio == NULL || mem_bio == NULL) { + ok = false; + goto END; + } + BIO_set_flags(b64_bio, BIO_FLAGS_BASE64_NO_NL); + BIO_push(b64_bio, mem_bio); + + if (BIO_write(b64_bio, data, size) != (int)size) { + ok = false; + goto END; + } + + out_len = BIO_get_mem_data(mem_bio, &p); + if (out_len < 0) { + ok = false; + goto END; + } + if (out_len > 0) { + ret = (char*)prne_malloc(1, out_len + 1); + if (ret == NULL) { + ok = false; + goto END; + } + memcpy(ret, p, out_len); + ret[out_len] = 0; + } + +END: + BIO_free(b64_bio); + BIO_free(mem_bio); + if (!ok) { + prne_free(ret); + ret = NULL; + } + + return ret; +} + +bool prne_dec_base64_mem (const char *str, const size_t str_len, uint8_t **data, size_t *size) { + char *in_mem = NULL; + size_t in_mem_len, out_len; + uint8_t *out_mem = NULL; + BIO *b64_bio = NULL, *mem_bio = NULL; + bool ret = true; + int read_size = 0; + + if (str_len > INT32_MAX) { + errno = EINVAL; + return false; + } + if (str_len == 0) { + ret = true; + goto END; + } + + in_mem = (char*)prne_malloc(1, str_len); + if (in_mem == NULL) { + ret = false; + goto END; + } + memcpy(in_mem, str, str_len); + in_mem_len = prne_str_shift_spaces(in_mem, str_len); + if (in_mem_len == 0) { + ret = true; + goto END; + } + + b64_bio = BIO_new(BIO_f_base64()); + mem_bio = BIO_new_mem_buf(in_mem, in_mem_len); + if (b64_bio == NULL || mem_bio == NULL) { + ret = false; + goto END; + } + BIO_set_flags(b64_bio, BIO_FLAGS_BASE64_NO_NL); + BIO_push(b64_bio, mem_bio); + + out_len = in_mem_len * 3 / 4; + out_mem = (uint8_t*)prne_malloc(1, (size_t)out_len); + if (out_mem == NULL) { + ret = false; + goto END; + } + + read_size = BIO_read(b64_bio, out_mem, out_len); + if (read_size < 0) { + ret = false; + goto END; + } + +END: + BIO_free(b64_bio); + BIO_free(mem_bio); + prne_free(in_mem); + if (ret) { + if (read_size > 0) { + *data = out_mem; + *size = (size_t)read_size; + } + else { + prne_free(out_mem); + *data = NULL; + *size = 0; + } + } + else { + prne_free(out_mem); + } + + return ret; +} |