util: extend unbase64mem() to accept secure flag
When the flag is set, buffer is cleared on failure.
This commit is contained in:
parent
03fec54396
commit
2432d09c7a
|
@ -685,11 +685,12 @@ static int unbase64_next(const char **p, size_t *l) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int unbase64mem(const char *p, size_t l, void **ret, size_t *ret_size) {
|
int unbase64mem_full(const char *p, size_t l, bool secure, void **ret, size_t *ret_size) {
|
||||||
_cleanup_free_ uint8_t *buf = NULL;
|
_cleanup_free_ uint8_t *buf = NULL;
|
||||||
const char *x;
|
const char *x;
|
||||||
uint8_t *z;
|
uint8_t *z;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
int r;
|
||||||
|
|
||||||
assert(p || l == 0);
|
assert(p || l == 0);
|
||||||
assert(ret);
|
assert(ret);
|
||||||
|
@ -712,36 +713,54 @@ int unbase64mem(const char *p, size_t l, void **ret, size_t *ret_size) {
|
||||||
a = unbase64_next(&x, &l);
|
a = unbase64_next(&x, &l);
|
||||||
if (a == -EPIPE) /* End of string */
|
if (a == -EPIPE) /* End of string */
|
||||||
break;
|
break;
|
||||||
if (a < 0)
|
if (a < 0) {
|
||||||
return a;
|
r = a;
|
||||||
if (a == INT_MAX) /* Padding is not allowed at the beginning of a 4ch block */
|
goto on_failure;
|
||||||
return -EINVAL;
|
}
|
||||||
|
if (a == INT_MAX) { /* Padding is not allowed at the beginning of a 4ch block */
|
||||||
|
r = -EINVAL;
|
||||||
|
goto on_failure;
|
||||||
|
}
|
||||||
|
|
||||||
b = unbase64_next(&x, &l);
|
b = unbase64_next(&x, &l);
|
||||||
if (b < 0)
|
if (b < 0) {
|
||||||
return b;
|
r = b;
|
||||||
if (b == INT_MAX) /* Padding is not allowed at the second character of a 4ch block either */
|
goto on_failure;
|
||||||
return -EINVAL;
|
}
|
||||||
|
if (b == INT_MAX) { /* Padding is not allowed at the second character of a 4ch block either */
|
||||||
|
r = -EINVAL;
|
||||||
|
goto on_failure;
|
||||||
|
}
|
||||||
|
|
||||||
c = unbase64_next(&x, &l);
|
c = unbase64_next(&x, &l);
|
||||||
if (c < 0)
|
if (c < 0) {
|
||||||
return c;
|
r = c;
|
||||||
|
goto on_failure;
|
||||||
|
}
|
||||||
|
|
||||||
d = unbase64_next(&x, &l);
|
d = unbase64_next(&x, &l);
|
||||||
if (d < 0)
|
if (d < 0) {
|
||||||
return d;
|
r = d;
|
||||||
|
goto on_failure;
|
||||||
|
}
|
||||||
|
|
||||||
if (c == INT_MAX) { /* Padding at the third character */
|
if (c == INT_MAX) { /* Padding at the third character */
|
||||||
|
|
||||||
if (d != INT_MAX) /* If the third character is padding, the fourth must be too */
|
if (d != INT_MAX) { /* If the third character is padding, the fourth must be too */
|
||||||
return -EINVAL;
|
r = -EINVAL;
|
||||||
|
goto on_failure;
|
||||||
|
}
|
||||||
|
|
||||||
/* b == 00YY0000 */
|
/* b == 00YY0000 */
|
||||||
if (b & 15)
|
if (b & 15) {
|
||||||
return -EINVAL;
|
r = -EINVAL;
|
||||||
|
goto on_failure;
|
||||||
|
}
|
||||||
|
|
||||||
if (l > 0) /* Trailing rubbish? */
|
if (l > 0) { /* Trailing rubbish? */
|
||||||
return -ENAMETOOLONG;
|
r = -ENAMETOOLONG;
|
||||||
|
goto on_failure;
|
||||||
|
}
|
||||||
|
|
||||||
*(z++) = (uint8_t) a << 2 | (uint8_t) (b >> 4); /* XXXXXXYY */
|
*(z++) = (uint8_t) a << 2 | (uint8_t) (b >> 4); /* XXXXXXYY */
|
||||||
break;
|
break;
|
||||||
|
@ -749,11 +768,15 @@ int unbase64mem(const char *p, size_t l, void **ret, size_t *ret_size) {
|
||||||
|
|
||||||
if (d == INT_MAX) {
|
if (d == INT_MAX) {
|
||||||
/* c == 00ZZZZ00 */
|
/* c == 00ZZZZ00 */
|
||||||
if (c & 3)
|
if (c & 3) {
|
||||||
return -EINVAL;
|
r = -EINVAL;
|
||||||
|
goto on_failure;
|
||||||
|
}
|
||||||
|
|
||||||
if (l > 0) /* Trailing rubbish? */
|
if (l > 0) { /* Trailing rubbish? */
|
||||||
return -ENAMETOOLONG;
|
r = -ENAMETOOLONG;
|
||||||
|
goto on_failure;
|
||||||
|
}
|
||||||
|
|
||||||
*(z++) = (uint8_t) a << 2 | (uint8_t) b >> 4; /* XXXXXXYY */
|
*(z++) = (uint8_t) a << 2 | (uint8_t) b >> 4; /* XXXXXXYY */
|
||||||
*(z++) = (uint8_t) b << 4 | (uint8_t) c >> 2; /* YYYYZZZZ */
|
*(z++) = (uint8_t) b << 4 | (uint8_t) c >> 2; /* YYYYZZZZ */
|
||||||
|
@ -771,6 +794,12 @@ int unbase64mem(const char *p, size_t l, void **ret, size_t *ret_size) {
|
||||||
*ret = TAKE_PTR(buf);
|
*ret = TAKE_PTR(buf);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
on_failure:
|
||||||
|
if (secure)
|
||||||
|
explicit_bzero_safe(buf, len);
|
||||||
|
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hexdump(FILE *f, const void *p, size_t s) {
|
void hexdump(FILE *f, const void *p, size_t s) {
|
||||||
|
|
|
@ -33,6 +33,9 @@ ssize_t base64mem(const void *p, size_t l, char **out);
|
||||||
int base64_append(char **prefix, int plen,
|
int base64_append(char **prefix, int plen,
|
||||||
const void *p, size_t l,
|
const void *p, size_t l,
|
||||||
int margin, int width);
|
int margin, int width);
|
||||||
int unbase64mem(const char *p, size_t l, void **mem, size_t *len);
|
int unbase64mem_full(const char *p, size_t l, bool secure, void **mem, size_t *len);
|
||||||
|
static inline int unbase64mem(const char *p, size_t l, void **mem, size_t *len) {
|
||||||
|
return unbase64mem_full(p, l, false, mem, len);
|
||||||
|
}
|
||||||
|
|
||||||
void hexdump(FILE *f, const void *p, size_t s);
|
void hexdump(FILE *f, const void *p, size_t s);
|
||||||
|
|
Loading…
Reference in a new issue