diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2015-01-28 16:21:00 +0000 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2015-01-28 16:21:00 +0000 |
commit | 976633feae742845a47aabe70dd93c547ba1876b (patch) | |
tree | 732d744d674876adc8532228b57d1876cd67c034 /src/libutil | |
parent | 75865261ebd5d2b70048273447c740a1629c89cb (diff) | |
download | rspamd-976633feae742845a47aabe70dd93c547ba1876b.tar.gz rspamd-976633feae742845a47aabe70dd93c547ba1876b.zip |
Add base32 decoding routine.
Diffstat (limited to 'src/libutil')
-rw-r--r-- | src/libutil/util.c | 74 | ||||
-rw-r--r-- | src/libutil/util.h | 8 |
2 files changed, 82 insertions, 0 deletions
diff --git a/src/libutil/util.c b/src/libutil/util.c index 102bfc107..ccec534eb 100644 --- a/src/libutil/util.c +++ b/src/libutil/util.c @@ -2117,7 +2117,81 @@ rspamd_encode_base32 (guchar *in, gsize inlen) return out; } +static const guchar b32_dec[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x12, 0xff, 0x19, 0x1a, 0x1b, 0x1e, 0x1d, + 0x07, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x18, 0x01, 0x0c, 0x03, 0x08, 0x05, 0x06, + 0x1c, 0x15, 0x09, 0x0a, 0xff, 0x0b, 0x02, 0x10, + 0x0d, 0x0e, 0x04, 0x16, 0x11, 0x13, 0xff, 0x14, + 0x0f, 0x00, 0x17, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x18, 0x01, 0x0c, 0x03, 0x08, 0x05, 0x06, + 0x1c, 0x15, 0x09, 0x0a, 0xff, 0x0b, 0x02, 0x10, + 0x0d, 0x0e, 0x04, 0x16, 0x11, 0x13, 0xff, 0x14, + 0x0f, 0x00, 0x17, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff +}; + +guchar* +rspamd_decode_base32 (gchar *in, gsize inlen, gsize *outlen) +{ + guchar *res, decoded; + guchar c; + guint acc = 0U; + guint processed_bits = 0; + gsize olen = 0, i, allocated_len = inlen * 8 / 5 + 1; + + res = g_slice_alloc (allocated_len); + + for (i = 0; i < inlen; i ++) { + c = (guchar)in[i]; + + if (processed_bits >= 8) { + processed_bits -= 8; + res[olen++] = acc & 0xFF; + acc >>= 8; + } + + decoded = b32_dec[c]; + if (decoded == 0xff) { + g_slice_free1 (allocated_len, res); + return NULL; + } + + acc = (decoded << processed_bits) | acc; + processed_bits += 5; + } + + if (processed_bits > 0) { + res[olen++] = (acc & 0xFF); + } + + *outlen = olen; + + return res; +} +/* Required for tweetnacl */ void randombytes (guchar *buf, guint64 len) { diff --git a/src/libutil/util.h b/src/libutil/util.h index 62a28d474..23964fc07 100644 --- a/src/libutil/util.h +++ b/src/libutil/util.h @@ -426,4 +426,12 @@ void rspamd_ucl_emit_gstring (ucl_object_t *obj, */ gchar * rspamd_encode_base32 (guchar *in, gsize inlen); +/** + * Decode string using base32 encoding + * @param in input + * @param inlen input length + * @return freshly allocated base32 decoded value or NULL if input is invalid + */ +guchar* rspamd_decode_base32 (gchar *in, gsize inlen, gsize *outlen); + #endif |