secure_exec_sidecar_core/
bridge_bytes.rs1use base64::Engine;
2use serde_json::{json, Value};
3
4pub fn encoded_bytes_value(bytes: &[u8]) -> Value {
5 json!({
6 "__agentOSType": "bytes",
7 "base64": base64::engine::general_purpose::STANDARD.encode(bytes),
8 })
9}
10
11pub fn decode_encoded_bytes_value(value: &Value) -> Result<Vec<u8>, String> {
12 let Some(base64_value) = value
13 .get("__agentOSType")
14 .and_then(Value::as_str)
15 .filter(|kind| *kind == "bytes")
16 .and_then(|_| value.get("base64"))
17 .and_then(Value::as_str)
18 else {
19 return Err(String::from("must be a string or encoded bytes payload"));
20 };
21
22 decode_base64(base64_value)
23}
24
25pub fn bridge_buffer_value(bytes: &[u8]) -> Value {
26 json!({
27 "__type": "buffer",
28 "value": base64::engine::general_purpose::STANDARD.encode(bytes),
29 })
30}
31
32pub fn decode_bridge_buffer_value(value: &Value) -> Result<Vec<u8>, String> {
33 let base64_value = value
34 .as_object()
35 .filter(|object| object.get("__type").and_then(Value::as_str) == Some("buffer"))
36 .and_then(|object| object.get("value"))
37 .and_then(Value::as_str)
38 .ok_or_else(|| String::from("must be a serialized bridge buffer"))?;
39
40 decode_base64(base64_value)
41}
42
43pub fn decode_base64(value: &str) -> Result<Vec<u8>, String> {
44 base64::engine::general_purpose::STANDARD
45 .decode(value)
46 .map_err(|error| format!("contains invalid base64: {error}"))
47}
48
49#[cfg(test)]
50mod tests {
51 use super::*;
52
53 #[test]
54 fn round_trips_encoded_bytes_payload() {
55 let value = encoded_bytes_value(b"hello");
56
57 assert_eq!(decode_encoded_bytes_value(&value), Ok(b"hello".to_vec()));
58 }
59
60 #[test]
61 fn round_trips_bridge_buffer_payload() {
62 let value = bridge_buffer_value(b"secret");
63
64 assert_eq!(decode_bridge_buffer_value(&value), Ok(b"secret".to_vec()));
65 }
66
67 #[test]
68 fn rejects_wrong_payload_shapes() {
69 assert_eq!(
70 decode_encoded_bytes_value(&json!({ "__agentOSType": "text", "base64": "aGk=" })),
71 Err(String::from("must be a string or encoded bytes payload"))
72 );
73 assert_eq!(
74 decode_bridge_buffer_value(&json!({ "__type": "bytes", "value": "aGk=" })),
75 Err(String::from("must be a serialized bridge buffer"))
76 );
77 }
78
79 #[test]
80 fn labels_invalid_base64() {
81 assert!(decode_base64("not base64!")
82 .expect_err("invalid base64 should fail")
83 .starts_with("contains invalid base64:"));
84 }
85}