diff options
author | David Timber <mieabby@gmail.com> | 2020-01-01 08:47:51 +1100 |
---|---|---|
committer | David Timber <mieabby@gmail.com> | 2020-01-01 08:47:51 +1100 |
commit | 6e456edb2757cf9d28d306afb836aa16780fb912 (patch) | |
tree | 2744c874583f03d70ef2aaeb405c74fb5b65ff75 /src/proone_util.c | |
parent | 85d78af0cd8b809abc28491c46c648a242053044 (diff) |
checkpoint
Diffstat (limited to 'src/proone_util.c')
-rw-r--r-- | src/proone_util.c | 154 |
1 files changed, 153 insertions, 1 deletions
diff --git a/src/proone_util.c b/src/proone_util.c index dc9e498..6017e54 100644 --- a/src/proone_util.c +++ b/src/proone_util.c @@ -1,6 +1,13 @@ #include "proone_util.h" #include <stdlib.h> +#include <string.h> +#include <ctype.h> + +#include <errno.h> + +#include <openssl/bio.h> +#include <openssl/evp.h> void proone_succeed_or_die (const int ret) { @@ -9,6 +16,8 @@ void proone_succeed_or_die (const int ret) { } } +void proone_empty_func () {} + void proone_rnd_alphanumeric_str (proone_rnd_engine_t *rnd_engine, char *str, const size_t len) { static const char SET[] = "qwertyuiopasdfghjklzxcvbnm0123456789"; size_t i = 0; @@ -31,7 +40,27 @@ void proone_rnd_alphanumeric_str (proone_rnd_engine_t *rnd_engine, char *str, co } } -void proone_empty_func () {} +size_t proone_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 proone_sub_timespec (const struct timespec *a, const struct timespec *b) { struct timespec ret; @@ -62,3 +91,126 @@ int proone_cmp_timespec (const struct timespec *a, const struct timespec *b) { return a->tv_nsec < b->tv_nsec ? -1 : a->tv_nsec > b->tv_nsec ? 1 : 0; } + +char *proone_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*)malloc(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) { + free(ret); + ret = NULL; + } + + return ret; +} + +bool proone_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*)malloc(str_len); + if (in_mem == NULL) { + ret = false; + goto END; + } + memcpy(in_mem, str, str_len); + in_mem_len = proone_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*)malloc((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); + free(in_mem); + if (ret) { + if (read_size > 0) { + *data = out_mem; + *size = (size_t)read_size; + } + else { + free(out_mem); + *data = NULL; + *size = 0; + } + } + else { + free(out_mem); + } + + return ret; +} |