]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
jsonbuilder: add methods to encode values as base64
authorJason Ish <jason.ish@oisf.net>
Thu, 24 Jun 2021 16:20:09 +0000 (10:20 -0600)
committerVictor Julien <vjulien@oisf.net>
Tue, 11 Jan 2022 06:30:48 +0000 (07:30 +0100)
Add new methods to set a value as a base64 encoded string of
a byte array. This uses the Rust base64 crate and encodes
directly into the JsonBuilder buffer with no intermediate
buffer required.

jb_set_base64: set a field on an object
jb_append_base64: append a value to an array

rust/Cargo.toml.in
rust/src/jsonbuilder.rs

index 2f873e7a1a529464c654d709254c0199f7276f71..3f484c339ea8c51f5704fb866d2d80f3ef8d4cb8 100644 (file)
@@ -53,6 +53,7 @@ sha-1 = "~0.9.2"
 md-5 = "~0.9.1"
 regex = "~1.4.2"
 lazy_static = "~1.4.0"
+base64 = "~0.13.0"
 
 suricata-derive = { path = "./derive" }
 
index 82636176a3ce594295474497aca462bc0c9b7f85..993186c9eeb0c5874150065a96b57a726cf41fae 100644 (file)
@@ -304,6 +304,30 @@ impl JsonBuilder {
         }
     }
 
+    /// Add a string to an array.
+    pub fn append_base64(&mut self, val: &[u8]) -> Result<&mut Self, JsonError> {
+        match self.current_state() {
+            State::ArrayFirst => {
+                self.buf.push('"');
+                base64::encode_config_buf(val, base64::STANDARD, &mut self.buf);
+                self.buf.push('"');
+                self.set_state(State::ArrayNth);
+                Ok(self)
+            }
+            State::ArrayNth => {
+                self.buf.push(',');
+                self.buf.push('"');
+                base64::encode_config_buf(val, base64::STANDARD, &mut self.buf);
+                self.buf.push('"');
+                Ok(self)
+            }
+            _ => {
+                debug_validate_fail!("invalid state");
+                Err(JsonError::InvalidState)
+            }
+        }
+    }
+
     /// Add an unsigned integer to an array.
     pub fn append_uint(&mut self, val: u64) -> Result<&mut Self, JsonError> {
         match self.current_state() {
@@ -427,6 +451,29 @@ impl JsonBuilder {
         }
     }
 
+    /// Set a key and a string field as the base64 encoded string of the value.
+    pub fn set_base64(&mut self, key: &str, val: &[u8]) -> Result<&mut Self, JsonError> {
+        match self.current_state() {
+            State::ObjectNth => {
+                self.buf.push(',');
+            }
+            State::ObjectFirst => {
+                self.set_state(State::ObjectNth);
+            }
+            _ => {
+                debug_validate_fail!("invalid state");
+                return Err(JsonError::InvalidState);
+            }
+        }
+        self.buf.push('"');
+        self.buf.push_str(key);
+        self.buf.push_str("\":\"");
+        base64::encode_config_buf(val, base64::STANDARD, &mut self.buf);
+        self.buf.push('"');
+
+        Ok(self)
+    }
+
     /// Set a key and an unsigned integer type on an object.
     pub fn set_uint(&mut self, key: &str, val: u64) -> Result<&mut Self, JsonError> {
         match self.current_state() {
@@ -655,6 +702,20 @@ pub unsafe extern "C" fn jb_set_string_from_bytes(
     return false;
 }
 
+#[no_mangle]
+pub unsafe extern "C" fn jb_set_base64(
+    js: &mut JsonBuilder, key: *const c_char, bytes: *const u8, len: u32,
+) -> bool {
+    if bytes == std::ptr::null() || len == 0 {
+        return false;
+    }
+    if let Ok(key) = CStr::from_ptr(key).to_str() {
+        let val = std::slice::from_raw_parts(bytes, len as usize);
+        return js.set_base64(key, val).is_ok();
+    }
+    return false;
+}
+
 #[no_mangle]
 pub unsafe extern "C" fn jb_set_formatted(js: &mut JsonBuilder, formatted: *const c_char) -> bool {
     if let Ok(formatted) = CStr::from_ptr(formatted).to_str() {
@@ -700,6 +761,17 @@ pub unsafe extern "C" fn jb_append_string_from_bytes(
     return js.append_string_from_bytes(val).is_ok();
 }
 
+#[no_mangle]
+pub unsafe extern "C" fn jb_append_base64(
+    js: &mut JsonBuilder, bytes: *const u8, len: u32,
+) -> bool {
+    if bytes == std::ptr::null() || len == 0 {
+        return false;
+    }
+    let val = std::slice::from_raw_parts(bytes, len as usize);
+    return js.append_base64(val).is_ok();
+}
+
 #[no_mangle]
 pub unsafe extern "C" fn jb_append_uint(js: &mut JsonBuilder, val: u64) -> bool {
     return js.append_uint(val).is_ok();