diff options
-rw-r--r-- | src/Makefile.am | 6 | ||||
-rw-r--r-- | src/dvault.c | 24 | ||||
-rw-r--r-- | src/pack.h | 1 | ||||
-rw-r--r-- | src/proone-mask.c | 25 | ||||
-rw-r--r-- | src/proone-test_util.c | 131 | ||||
-rw-r--r-- | src/util_rt.c | 140 | ||||
-rw-r--r-- | src/util_rt.h | 6 |
7 files changed, 278 insertions, 55 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 33b7521..2bbb740 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -64,9 +64,13 @@ proone_resolv_LDFLAGS = $(LIBS) $(DEP_PKGCFG_LIBS) proone_resolv_SOURCES = proone-resolv.c if TESTS -bin_PROGRAMS += proone-test_proto +bin_PROGRAMS += proone-test_proto proone-test_util proone_test_proto_LDADD = libproone.a proone_test_proto_LDFLAGS = $(LIBS) $(DEP_PKGCFG_LIBS) proone_test_proto_SOURCES = proone-test_proto.c + +proone_test_util_LDADD = libproone.a +proone_test_util_LDFLAGS = $(LIBS) $(DEP_PKGCFG_LIBS) +proone_test_util_SOURCES = proone-test_util.c endif diff --git a/src/dvault.c b/src/dvault.c index 57f15da..81bd7a7 100644 --- a/src/dvault.c +++ b/src/dvault.c @@ -5,7 +5,6 @@ #include <stdint.h> #include <stdbool.h> #include <stdlib.h> -#include <stdio.h> #include <string.h> @@ -106,7 +105,7 @@ void prne_free_dvault_mask_result (prne_dvault_mask_result_t *r) { prne_dvault_mask_result_t prne_dvault_mask (const prne_data_type_t type, const uint8_t salt, const size_t data_size, const uint8_t *data) { size_t i; prne_dvault_mask_result_t ret; - int f_ret; + char *p; prne_init_dvault_mask_result(&ret); @@ -127,16 +126,21 @@ prne_dvault_mask_result_t prne_dvault_mask (const prne_data_type_t type, const u return ret; } - f_ret = sprintf(ret.str, "\\x%02X\\x%02X\\x%02X\\x%02X", - type, - salt, - (int)((0xFF00 & (uint_fast16_t)data_size) >> 8), - (int)((0x00FF & (uint_fast16_t)data_size) >> 0)); - assert(f_ret > 0); + p = ret.str; + p[0] = p[4] = p[8] = p[12] = '\\'; + p[1] = p[5] = p[9] = p[13] = 'x'; + prne_hex_tochar((uint_fast8_t)type, p + 2, true); + prne_hex_tochar((uint_fast8_t)salt, p + 6, true); + prne_hex_tochar((uint_fast8_t)((0xFF00 & (uint_fast16_t)data_size) >> 8), p + 10, true); + prne_hex_tochar((uint_fast8_t)((0x00FF & (uint_fast16_t)data_size) >> 0), p + 14, true); + p += 16; for (i = 0; i < data_size; i += 1) { - f_ret = sprintf(ret.str + 4 * 4 + 4 * i, "\\x%02X", data[i] ^ PRNE_DVAULT_MASK[(i + (size_t)salt) % 256]); - assert(f_ret > 0); + p[0] = '\\'; + p[1] = 'x'; + prne_hex_tochar(data[i] ^ PRNE_DVAULT_MASK[(i + (size_t)salt) % 256], p + 2, true); + p += 4; } + *p = 0; return ret; } @@ -51,4 +51,5 @@ prne_unpack_ctx_pt prne_alloc_unpack_ctx (const prne_bin_archive_t *archive, con void prne_free_unpack_ctx (prne_unpack_ctx_pt ctx); ssize_t prne_do_unpack (prne_unpack_ctx_pt ctx, uint8_t *out, const size_t out_len, prne_pack_ret_t *pr_out); +// WARN: uses stdio func char *prne_pack_ret_tostr (const prne_pack_ret_t pr); diff --git a/src/proone-mask.c b/src/proone-mask.c index 1807f3f..3385c5a 100644 --- a/src/proone-mask.c +++ b/src/proone-mask.c @@ -2,6 +2,7 @@ #include <stddef.h> #include <stdint.h> #include <stdbool.h> +#include <ctype.h> #include <unistd.h> #include <fcntl.h> @@ -10,7 +11,7 @@ #include "dvault.h" -int main (const int argc, const char **args) { +int main (const int argc, char **args) { int exit_code = 0; ssize_t fd_read_size; size_t read_size = 0; @@ -22,13 +23,29 @@ int main (const int argc, const char **args) { if (argc <= 1) { fprintf(stderr, - "Usage: %s <type>\n" - "<type>: 'cstr', 'bin'\n", + "Usage: %s <type> [salt]\n" + "<type>: 'cstr', 'bin'\n" + "[salt]: salt hex value\n", args[0]); exit_code = 2; goto END; } + if (argc >= 3) { + for (char *p = args[2]; *p != 0; p += 1) { + *p = (char)tolower(*p); + } + + if (sscanf(args[2], "%hhx", &salt) != 1) { + perror("parsing salt: "); + exit_code = 1; + goto END; + } + } + else { + getrandom(&salt, sizeof(salt), 0); + } + type = prne_data_type_fstr(args[1]); switch (type) { case PRNE_DATA_TYPE_BIN: @@ -59,8 +76,6 @@ int main (const int argc, const char **args) { goto END; } - getrandom(&salt, sizeof(salt), 0); - mask_result = prne_dvault_mask(type, salt, read_size, buf); if (mask_result.result == PRNE_DVAULT_MASK_OK) { printf("(uint8_t*)\"%s\",\n", mask_result.str); diff --git a/src/proone-test_util.c b/src/proone-test_util.c new file mode 100644 index 0000000..43fc654 --- /dev/null +++ b/src/proone-test_util.c @@ -0,0 +1,131 @@ +#include "util_rt.h" + +#include <stdio.h> +#include <assert.h> +#include <string.h> +#include <errno.h> + + +static void test_uuid (void); +static void test_alloc (void); +static void test_str (void); + +int main (void) { + test_alloc(); + test_str(); + test_uuid(); + + return 0; +} + +static void test_str (void) { + static const char *const str_a = "a"; + static const char *const str_b = "b"; + static const char *const str_sample = "abcdefg"; + + assert(prne_nstreq(NULL, NULL)); + assert(!prne_nstreq(str_a, NULL)); + assert(!prne_nstreq(NULL, str_b)); + assert(!prne_nstreq(str_a, str_b)); + assert(prne_nstreq(str_a, str_a)); + + assert(prne_nstrlen(NULL) == 0); + assert(prne_nstrlen("") == 0); + assert(prne_nstrlen(str_a) == 1); + assert(prne_nstrlen(str_sample) == 7); + + assert(prne_strnchr(str_sample, 'a', 7) == str_sample); + assert(prne_strnchr(str_sample, 'g', 7) == str_sample + 6); + assert(prne_strnchr(str_sample, 0, 8) == str_sample + 7); + assert(prne_strnchr(str_sample, 'g', 6) == NULL); + assert(prne_strnchr(str_sample, 'a', 0) == NULL); + assert(prne_strnchr(str_sample, 'x', 7) == NULL); + + for (int i = 0; i <= UINT_FAST8_MAX; i += 1) { + char exp_str[3], str[3]; + uint_fast8_t out; + + str[2] = 0; + + sprintf(exp_str, "%02hhx", i); + prne_hex_tochar((uint8_t)i, str, false); + assert(memcmp(exp_str, str, 3) == 0); + assert(prne_hex_fromstr(str, &out) && out == i); + + sprintf(exp_str, "%02hhX", i); + prne_hex_tochar((uint8_t)i, str, true); + assert(memcmp(exp_str, str, 3) == 0); + assert(prne_hex_fromstr(str, &out) && out == i); + } +} + +static void test_alloc (void) { + prne_free(NULL); + + errno = 0; + assert(prne_malloc(0, 0) == NULL && prne_malloc(1, 0) == NULL && prne_malloc(0, 1) == NULL && errno == 0); + errno = 0; + assert(prne_malloc(2, SIZE_MAX / 2 + 1) == NULL); + assert(errno == ENOMEM); + errno = 0; + assert(prne_malloc(SIZE_MAX / 2 + 1, 2) == NULL); + assert(errno == ENOMEM); + + errno = 0; + assert(prne_calloc(0, 0) == NULL && prne_calloc(1, 0) == NULL && prne_calloc(0, 1) == NULL && errno == 0); + errno = 0; + assert(prne_calloc(2, SIZE_MAX / 2 + 1) == NULL); + assert(errno == ENOMEM); + errno = 0; + assert(prne_calloc(SIZE_MAX / 2 + 1, 2) == NULL); + assert(errno == ENOMEM); + + errno = 0; + assert(prne_realloc(NULL, 0, 0) == NULL && prne_realloc(NULL, 1, 0) == NULL && prne_realloc(NULL, 0, 1) == NULL && errno == 0); + errno = 0; + assert(prne_realloc(NULL, 2, SIZE_MAX / 2 + 1) == NULL); + assert(errno == ENOMEM); + errno = 0; + assert(prne_realloc(NULL, SIZE_MAX / 2 + 1, 2) == NULL); + assert(errno == ENOMEM); + + errno = 0; + assert(prne_alloc_str(SIZE_MAX) == NULL); + assert(errno == ENOMEM); +} + +static void test_uuid (void) { + static const char *sample_str = "f31605bb-5ec9-46e7-918d-4810a39a858d"; + static const uint8_t sample_arr[16] = { 0xf3, 0x16, 0x05, 0xbb, 0x5e, 0xc9, 0x46, 0xe7, 0x91, 0x8d, 0x48, 0x10, 0xa3, 0x9a, 0x85, 0x8d }; + static const char *empty_str = "00000000-0000-0000-0000-000000000000"; + static const uint8_t empty_arr[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + uint8_t out_arr[16]; + char out_str[37]; + + memzero(out_arr, 16); + memzero(out_str, 37); + assert(prne_uuid_fromstr(sample_str, out_arr)); + assert(memcmp(sample_arr, out_arr, 16) == 0); + prne_uuid_tostr(out_arr, out_str); + assert(memcmp(sample_str, out_str, 37) == 0); + + memset(out_arr, 0xFF, 16); + memzero(out_str, 37); + assert(prne_uuid_fromstr(empty_str, out_arr)); + assert(memcmp(empty_arr, out_arr, 16) == 0); + prne_uuid_tostr(out_arr, out_str); + assert(memcmp(empty_str, out_str, 37) == 0); + + errno = 0; + assert(!prne_uuid_fromstr("", out_arr)); + assert(errno == EINVAL); + errno = 0; + assert(!prne_uuid_fromstr("f31605bb-5ec9-46e7-918d-4810a39a858da", out_arr)); + assert(errno == EINVAL); + assert(!prne_uuid_fromstr("f31605bb-5ec9-46e7-918d-4810a39a858d-", out_arr)); + assert(errno == EINVAL); + assert(!prne_uuid_fromstr("f31605bb-5ec9-46e7-918d-4810Z39a858d", out_arr)); + assert(errno == EINVAL); + assert(!prne_uuid_fromstr("f31605bb-5ec9046e7-918d-4810a39a858d", out_arr)); + assert(errno == EINVAL); +} diff --git a/src/util_rt.c b/src/util_rt.c index 801f3dc..c582d08 100644 --- a/src/util_rt.c +++ b/src/util_rt.c @@ -1,6 +1,6 @@ #include "util_rt.h" -#include <stdio.h> +#include <stdio.h> // TODO: remove dep #include <stdlib.h> #include <string.h> #include <ctype.h> @@ -63,6 +63,9 @@ void prne_shutdown (const int fd, const int how) { void *prne_malloc (const size_t se, const size_t cnt) { size_t size; + if (se == 0) { + return NULL; + } if (SIZE_MAX / se < cnt) { errno = ENOMEM; return NULL; @@ -79,6 +82,10 @@ void *prne_malloc (const size_t se, const size_t cnt) { void *prne_realloc (void *ptr, const size_t se, const size_t cnt) { size_t size; + if (se == 0) { + prne_free(ptr); + return NULL; + } if (SIZE_MAX / se < cnt) { errno = ENOMEM; return NULL; @@ -196,46 +203,103 @@ size_t prne_str_shift_spaces (char *str, const size_t len) { return ret; } +bool prne_hex_fromstr (const char *str, uint_fast8_t *out) { + static const uint_fast8_t shift[2] = { 4, 0 }; + size_t i; + uint_fast8_t ret[2]; + char c; + + for (i = 0; i < 2; i += 1) { + c = str[i]; + + if ('0' <= c && c <= '9') { + ret[i] = (c - '0') << shift[i]; + } + else if ('a' <= c && c <= 'f') { + ret[i] = (c - 'a' + 10) << shift[i]; + } + else if ('A' <= c && c <= 'F') { + ret[i] = (c - 'A' + 10) << shift[i]; + } + else { + errno = EINVAL; + return false; + } + } + + *out = ret[0] | ret[1]; + return true; +} + +void prne_hex_tochar (const uint_fast8_t in, char *out, const bool upper) { + static const uint_fast8_t mask[2] = { 0xF0, 0x0F }; + static const uint_fast8_t shift[2] = { 4, 0 }; + size_t i; + uint_fast8_t v; + + for (i = 0; i < 2; i += 1) { + v = (in & mask[i]) >> shift[i]; + if (v <= 9) { + out[i] = '0' + v; + } + else { + out[i] = (upper ? 'A' : 'a') + (v - 10); + } + } +} + bool prne_uuid_fromstr (const char *str, uint8_t *out) { - return sscanf(str, "%hhx%hhx%hhx%hhx-%hhx%hhx-%hhx%hhx-%hhx%hhx-%hhx%hhx%hhx%hhx%hhx%hhx", - &out[0], - &out[1], - &out[2], - &out[3], - &out[4], - &out[5], - &out[6], - &out[7], - &out[8], - &out[9], - &out[10], - &out[11], - &out[12], - &out[13], - &out[14], - &out[15]) == 16; -} - -bool prne_uuid_tostr (const uint8_t *in, const size_t out_size, char *out) { - return snprintf(out, out_size, "%hhx%hhx%hhx%hhx-%hhx%hhx-%hhx%hhx-%hhx%hhx-%hhx%hhx%hhx%hhx%hhx%hhx", - in[0], - in[1], - in[2], - in[3], - in[4], - in[5], - in[6], - in[7], - in[8], - in[9], - in[10], - in[11], - in[12], - in[13], - in[14], - in[15]) == 16; + size_t i, ptr = 0; + + if (prne_nstrlen(str) != 36) { + errno = EINVAL; + return false; + } + + for (i = 0; i < 36;) { + switch (i) { + case 8: + case 13: + case 18: + case 23: + if (str[i] != '-') { + errno = EINVAL; + return false; + } + i += 1; + break; + default: + if (!prne_hex_fromstr(str + i, out + ptr)) { + return false; + } + ptr += 1; + i += 2; + } + } + + return true; } +void prne_uuid_tostr (const uint8_t *in, char *out) { + size_t i, ptr = 0; + + for (i = 0; i < 16; i += 1) { + prne_hex_tochar(in[i], out + ptr, false); + + switch (i) { + case 3: + case 5: + case 7: + case 9: + out[ptr + 2] = '-'; + ptr += 3; + break; + default: + ptr += 2; + } + } + out[ptr] = 0; +} struct timespec prne_sub_timespec (const struct timespec a, const struct timespec b) { struct timespec ret; diff --git a/src/util_rt.h b/src/util_rt.h index 7f95c49..2531f80 100644 --- a/src/util_rt.h +++ b/src/util_rt.h @@ -52,8 +52,12 @@ size_t prne_nstrlen (const char *s); void prne_rnd_anum_str (mbedtls_ctr_drbg_context *rnd, char *str, const size_t len); char *prne_strnchr (const char *p, const char c, const size_t n); size_t prne_str_shift_spaces (char *str, const size_t len); + +bool prne_hex_fromstr (const char *str, uint_fast8_t *out); +void prne_hex_tochar (const uint_fast8_t in, char *out, const bool upper); + bool prne_uuid_fromstr (const char *str, uint8_t *out); -bool prne_uuid_tostr (const uint8_t *in, const size_t out_size, char *out); +void prne_uuid_tostr (const uint8_t *in, char *out); struct timespec prne_sub_timespec (const struct timespec a, const struct timespec b); double prne_real_timespec (const struct timespec ts); |