util: extend unhexmem() to accept secure flag

When the flag is set, buffer is cleared on failure.
This is a continuation of 2432d09c7a.
This commit is contained in:
Yu Watanabe 2019-04-10 17:50:27 +09:00
parent 03abeb0baf
commit 7088befb17
2 changed files with 23 additions and 7 deletions

View file

@ -108,10 +108,12 @@ static int unhex_next(const char **p, size_t *l) {
return r;
}
int unhexmem(const char *p, size_t l, void **ret, size_t *ret_len) {
int unhexmem_full(const char *p, size_t l, bool secure, void **ret, size_t *ret_len) {
_cleanup_free_ uint8_t *buf = NULL;
size_t buf_size;
const char *x;
uint8_t *z;
int r;
assert(ret);
assert(ret_len);
@ -121,7 +123,8 @@ int unhexmem(const char *p, size_t l, void **ret, size_t *ret_len) {
l = strlen(p);
/* Note that the calculation of memory size is an upper boundary, as we ignore whitespace while decoding */
buf = malloc((l + 1) / 2 + 1);
buf_size = (l + 1) / 2 + 1;
buf = malloc(buf_size);
if (!buf)
return -ENOMEM;
@ -131,12 +134,16 @@ int unhexmem(const char *p, size_t l, void **ret, size_t *ret_len) {
a = unhex_next(&x, &l);
if (a == -EPIPE) /* End of string */
break;
if (a < 0)
return a;
if (a < 0) {
r = a;
goto on_failure;
}
b = unhex_next(&x, &l);
if (b < 0)
return b;
if (b < 0) {
r = b;
goto on_failure;
}
*(z++) = (uint8_t) a << 4 | (uint8_t) b;
}
@ -147,6 +154,12 @@ int unhexmem(const char *p, size_t l, void **ret, size_t *ret_len) {
*ret = TAKE_PTR(buf);
return 0;
on_failure:
if (secure)
explicit_bzero_safe(buf, buf_size);
return r;
}
/* https://tools.ietf.org/html/rfc4648#section-6

View file

@ -18,7 +18,10 @@ char hexchar(int x) _const_;
int unhexchar(char c) _const_;
char *hexmem(const void *p, size_t l);
int unhexmem(const char *p, size_t l, void **mem, size_t *len);
int unhexmem_full(const char *p, size_t l, bool secure, void **mem, size_t *len);
static inline int unhexmem(const char *p, size_t l, void **mem, size_t *len) {
return unhexmem_full(p, l, false, mem, len);
}
char base32hexchar(int x) _const_;
int unbase32hexchar(char c) _const_;