aboutsummaryrefslogtreecommitdiffstats
path: root/src/libutil
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2015-01-28 16:21:00 +0000
committerVsevolod Stakhov <vsevolod@highsecure.ru>2015-01-28 16:21:00 +0000
commit976633feae742845a47aabe70dd93c547ba1876b (patch)
tree732d744d674876adc8532228b57d1876cd67c034 /src/libutil
parent75865261ebd5d2b70048273447c740a1629c89cb (diff)
downloadrspamd-976633feae742845a47aabe70dd93c547ba1876b.tar.gz
rspamd-976633feae742845a47aabe70dd93c547ba1876b.zip
Add base32 decoding routine.
Diffstat (limited to 'src/libutil')
-rw-r--r--src/libutil/util.c74
-rw-r--r--src/libutil/util.h8
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