]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
base64: add Base64Mode enum
authorShivani Bhardwaj <shivanib134@gmail.com>
Thu, 12 May 2022 18:00:00 +0000 (23:30 +0530)
committerVictor Julien <vjulien@oisf.net>
Mon, 6 Jun 2022 19:01:23 +0000 (21:01 +0200)
(cherry picked from commit 9131d1d85715c817a22d2a987f4a01cf42e07757)

src/datasets.c
src/detect-base64-decode.c
src/runmode-unittests.c
src/util-base64.c
src/util-base64.h
src/util-decode-mime.c

index 5da15d904ff25a06ffc71f7089f16b87510508cc..922820285429a13e4346f67cab523a37afb7a541 100644 (file)
@@ -324,7 +324,8 @@ static int DatasetLoadString(Dataset *set)
 
             // coverity[alloc_strlen : FALSE]
             uint8_t decoded[strlen(line)];
-            uint32_t len = DecodeBase64(decoded, (const uint8_t *)line, strlen(line), 1);
+            uint32_t len =
+                    DecodeBase64(decoded, (const uint8_t *)line, strlen(line), BASE64_MODE_STRICT);
             if (len == 0)
                 FatalError(SC_ERR_FATAL, "bad base64 encoding %s/%s",
                         set->name, set->load);
@@ -341,7 +342,8 @@ static int DatasetLoadString(Dataset *set)
 
             // coverity[alloc_strlen : FALSE]
             uint8_t decoded[strlen(line)];
-            uint32_t len = DecodeBase64(decoded, (const uint8_t *)line, strlen(line), 1);
+            uint32_t len =
+                    DecodeBase64(decoded, (const uint8_t *)line, strlen(line), BASE64_MODE_STRICT);
             if (len == 0)
                 FatalError(SC_ERR_FATAL, "bad base64 encoding %s/%s",
                         set->name, set->load);
@@ -1151,7 +1153,8 @@ int DatasetAddSerialized(Dataset *set, const char *string)
         case DATASET_TYPE_STRING: {
             // coverity[alloc_strlen : FALSE]
             uint8_t decoded[strlen(string)];
-            uint32_t len = DecodeBase64(decoded, (const uint8_t *)string, strlen(string), 1);
+            uint32_t len = DecodeBase64(
+                    decoded, (const uint8_t *)string, strlen(string), BASE64_MODE_STRICT);
             if (len == 0) {
                 return -2;
             }
@@ -1233,7 +1236,8 @@ int DatasetRemoveSerialized(Dataset *set, const char *string)
         case DATASET_TYPE_STRING: {
             // coverity[alloc_strlen : FALSE]
             uint8_t decoded[strlen(string)];
-            uint32_t len = DecodeBase64(decoded, (const uint8_t *)string, strlen(string), 1);
+            uint32_t len = DecodeBase64(
+                    decoded, (const uint8_t *)string, strlen(string), BASE64_MODE_STRICT);
             if (len == 0) {
                 return -2;
             }
index 2e047979fd802b441a18bad2fcb52d9200333045..fa9703806b4c533c0bf05c7eb0bc8bf10f89e0d8 100644 (file)
@@ -87,8 +87,8 @@ int DetectBase64DecodeDoMatch(DetectEngineThreadCtx *det_ctx, const Signature *s
     PrintRawDataFp(stdout, payload, decode_len);
 #endif
 
-    det_ctx->base64_decoded_len = DecodeBase64(det_ctx->base64_decoded,
-        payload, decode_len, 0);
+    det_ctx->base64_decoded_len =
+            DecodeBase64(det_ctx->base64_decoded, payload, decode_len, BASE64_MODE_RELAX);
     SCLogDebug("Decoded %d bytes from base64 data.",
         det_ctx->base64_decoded_len);
 #if 0
index a35d8f1d1b691bb5956ebcd7ad0d3121d61ad5d6..d4a53e80b72f1ed83991f211808725cb67de36f7 100644 (file)
@@ -177,6 +177,7 @@ static void RegisterUnittests(void)
     ThreadMacrosRegisterTests();
     UtilSpmSearchRegistertests();
     UtilActionRegisterTests();
+    Base64RegisterTests();
     SCClassConfRegisterTests();
     SCThresholdConfRegisterTests();
     SCRConfRegisterTests();
index bea92d52bb4bed9eae19c56c003cd70fbe738be5..5c6e0ac6e20544a7803929ae055110ebd38da4f2 100644 (file)
@@ -23,7 +23,7 @@
  */
 
 #include "util-base64.h"
-
+#include "util-unittest.h"
 /* Constants */
 #define BASE64_TABLE_MAX  122
 
@@ -88,8 +88,7 @@ static inline void DecodeBase64Block(uint8_t ascii[ASCII_BLOCK], uint8_t b64[B64
  *
  * \return Number of bytes decoded, or 0 if no data is decoded or it fails
  */
-uint32_t DecodeBase64(uint8_t *dest, const uint8_t *src, uint32_t len,
-    int strict)
+uint32_t DecodeBase64(uint8_t *dest, const uint8_t *src, uint32_t len, Base64Mode mode)
 {
     int val;
     uint32_t padding = 0, numDecoded = 0, bbidx = 0, valid = 1, i;
@@ -102,11 +101,13 @@ uint32_t DecodeBase64(uint8_t *dest, const uint8_t *src, uint32_t len,
         /* Get decimal representation */
         val = GetBase64Value(src[i]);
         if (val < 0) {
-
+            if (mode == BASE64_MODE_RFC2045 && src[i] == ' ') {
+                continue;
+            }
             /* Invalid character found, so decoding fails */
             if (src[i] != '=') {
                 valid = 0;
-                if (strict) {
+                if (mode != BASE64_MODE_RELAX) {
                     numDecoded = 0;
                 }
                 break;
@@ -149,3 +150,28 @@ uint32_t DecodeBase64(uint8_t *dest, const uint8_t *src, uint32_t len,
 
     return numDecoded;
 }
+
+#ifdef UNITTESTS
+
+static int DecodeString(void)
+{
+    /*
+     * SGV sbG8= : Hello
+     * SGVsbG8gV29ybGQ= : Hello World
+     * */
+
+    const char *src = "SGVs bG8 gV29y bGQ=";
+    uint8_t *dst = SCMalloc(sizeof(src) * 30);
+    int res = DecodeBase64(dst, (const uint8_t *)src, 30, 1);
+    printf("%d\n", res);
+    printf("dst str = \"%s\"", (const char *)dst);
+    FAIL_IF(res <= 0);
+    SCFree(dst);
+    PASS;
+}
+
+void Base64RegisterTests(void)
+{
+    UtRegisterTest("DecodeString", DecodeString);
+}
+#endif
index 7c8bed626261054a0d54ef07e4567b9d89d05a75..2de0275ce561b082eef320f552dd7086b7e3f2eb 100644 (file)
 #define ASCII_BLOCK         3
 #define B64_BLOCK           4
 
+typedef enum {
+    BASE64_MODE_RELAX,
+    BASE64_MODE_RFC2045, /* SPs are allowed during transfer but must be skipped by Decoder */
+    BASE64_MODE_STRICT,
+} Base64Mode;
+
 /* Function prototypes */
-uint32_t DecodeBase64(uint8_t *dest, const uint8_t *src, uint32_t len,
-    int strict);
+uint32_t DecodeBase64(uint8_t *dest, const uint8_t *src, uint32_t len, Base64Mode mode);
+
+#endif
 
+#ifdef UNITTESTS
+void Base64RegisterTests(void);
 #endif
index d7573b53ca3180d8715daca2d79262f918764bed..8386ee1d12dbc79e8b29186e1e796536662bdaaa 100644 (file)
@@ -1235,8 +1235,8 @@ static uint8_t ProcessBase64Remainder(const uint8_t *buf, uint32_t len,
 
     /* Only decode if divisible by 4 */
     if (state->bvr_len == B64_BLOCK || force) {
-        remdec = DecodeBase64(state->data_chunk + state->data_chunk_len,
-                              state->bvremain, state->bvr_len, 1);
+        remdec = DecodeBase64(state->data_chunk + state->data_chunk_len, state->bvremain,
+                state->bvr_len, BASE64_MODE_RFC2045);
         if (remdec > 0) {
 
             /* Track decoded length */
@@ -1337,8 +1337,8 @@ static int ProcessBase64BodyLine(const uint8_t *buf, uint32_t len,
 
             SCLogDebug("Decoding: %u", len - rem1 - rem2);
 
-            numDecoded = DecodeBase64(state->data_chunk + state->data_chunk_len,
-                    buf + offset, tobuf, 1);
+            numDecoded = DecodeBase64(state->data_chunk + state->data_chunk_len, buf + offset,
+                    tobuf, BASE64_MODE_RFC2045);
             if (numDecoded > 0) {
 
                 /* Track decoded length */
@@ -2948,7 +2948,7 @@ static int MimeBase64DecodeTest01(void)
     if (dst == NULL)
         return 0;
 
-    ret = DecodeBase64(dst, (const uint8_t *)base64msg, strlen(base64msg), 1);
+    ret = DecodeBase64(dst, (const uint8_t *)base64msg, strlen(base64msg), BASE64_MODE_RFC2045);
 
     if (memcmp(dst, msg, strlen(msg)) == 0) {
         ret = 1;