1use std::collections::HashSet;
4
5use serde_json::Value;
6
7use crate::functions::Function;
8use crate::interpreter::SearchResult;
9use crate::registry::register_if_enabled;
10use crate::{Context, Runtime, arg, defn};
11
12use crc32fast::Hasher as Crc32Hasher;
13use hmac::{Hmac, Mac};
14use md5::{Digest, Md5};
15use sha1::Sha1;
16use sha2::{Sha256, Sha512};
17
18type HmacMd5 = Hmac<Md5>;
20type HmacSha1 = Hmac<Sha1>;
21type HmacSha256 = Hmac<Sha256>;
22type HmacSha512 = Hmac<Sha512>;
23
24pub fn register_filtered(runtime: &mut Runtime, enabled: &HashSet<&str>) {
26 register_if_enabled(runtime, "md5", enabled, Box::new(Md5Fn::new()));
28 register_if_enabled(runtime, "sha1", enabled, Box::new(Sha1Fn::new()));
29 register_if_enabled(runtime, "sha256", enabled, Box::new(Sha256Fn::new()));
30 register_if_enabled(runtime, "sha512", enabled, Box::new(Sha512Fn::new()));
31
32 register_if_enabled(runtime, "hmac_md5", enabled, Box::new(HmacMd5Fn::new()));
34 register_if_enabled(runtime, "hmac_sha1", enabled, Box::new(HmacSha1Fn::new()));
35 register_if_enabled(
36 runtime,
37 "hmac_sha256",
38 enabled,
39 Box::new(HmacSha256Fn::new()),
40 );
41 register_if_enabled(
42 runtime,
43 "hmac_sha512",
44 enabled,
45 Box::new(HmacSha512Fn::new()),
46 );
47
48 register_if_enabled(runtime, "crc32", enabled, Box::new(Crc32Fn::new()));
50}
51
52defn!(Md5Fn, vec![arg!(string)], None);
57
58impl Function for Md5Fn {
59 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
60 self.signature.validate(args, ctx)?;
61
62 let input = args[0].as_str().ok_or_else(|| {
63 crate::JmespathError::from_ctx(
64 ctx,
65 crate::ErrorReason::Parse("Expected string argument".to_owned()),
66 )
67 })?;
68
69 let mut hasher = Md5::new();
70 hasher.update(input.as_bytes());
71 let result = hasher.finalize();
72 let hex_string = format!("{:x}", result);
73
74 Ok(Value::String(hex_string))
75 }
76}
77
78defn!(Sha1Fn, vec![arg!(string)], None);
83
84impl Function for Sha1Fn {
85 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
86 self.signature.validate(args, ctx)?;
87
88 let input = args[0].as_str().ok_or_else(|| {
89 crate::JmespathError::from_ctx(
90 ctx,
91 crate::ErrorReason::Parse("Expected string argument".to_owned()),
92 )
93 })?;
94
95 let mut hasher = Sha1::new();
96 hasher.update(input.as_bytes());
97 let result = hasher.finalize();
98 let hex_string = format!("{:x}", result);
99
100 Ok(Value::String(hex_string))
101 }
102}
103
104defn!(Sha256Fn, vec![arg!(string)], None);
109
110impl Function for Sha256Fn {
111 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
112 self.signature.validate(args, ctx)?;
113
114 let input = args[0].as_str().ok_or_else(|| {
115 crate::JmespathError::from_ctx(
116 ctx,
117 crate::ErrorReason::Parse("Expected string argument".to_owned()),
118 )
119 })?;
120
121 let mut hasher = Sha256::new();
122 hasher.update(input.as_bytes());
123 let result = hasher.finalize();
124 let hex_string = format!("{:x}", result);
125
126 Ok(Value::String(hex_string))
127 }
128}
129
130defn!(Sha512Fn, vec![arg!(string)], None);
135
136impl Function for Sha512Fn {
137 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
138 self.signature.validate(args, ctx)?;
139
140 let input = args[0].as_str().ok_or_else(|| {
141 crate::JmespathError::from_ctx(
142 ctx,
143 crate::ErrorReason::Parse("Expected string argument".to_owned()),
144 )
145 })?;
146
147 let mut hasher = Sha512::new();
148 hasher.update(input.as_bytes());
149 let result = hasher.finalize();
150 let hex_string = format!("{:x}", result);
151
152 Ok(Value::String(hex_string))
153 }
154}
155
156defn!(HmacMd5Fn, vec![arg!(string), arg!(string)], None);
161
162impl Function for HmacMd5Fn {
163 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
164 self.signature.validate(args, ctx)?;
165
166 let text = args[0].as_str().ok_or_else(|| {
167 crate::JmespathError::from_ctx(
168 ctx,
169 crate::ErrorReason::Parse("Expected string for text argument".to_owned()),
170 )
171 })?;
172
173 let key = args[1].as_str().ok_or_else(|| {
174 crate::JmespathError::from_ctx(
175 ctx,
176 crate::ErrorReason::Parse("Expected string for key argument".to_owned()),
177 )
178 })?;
179
180 let mut mac =
181 HmacMd5::new_from_slice(key.as_bytes()).expect("HMAC can take key of any size");
182 mac.update(text.as_bytes());
183 let result = mac.finalize();
184 let hex_string = format!("{:x}", result.into_bytes());
185
186 Ok(Value::String(hex_string))
187 }
188}
189
190defn!(HmacSha1Fn, vec![arg!(string), arg!(string)], None);
195
196impl Function for HmacSha1Fn {
197 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
198 self.signature.validate(args, ctx)?;
199
200 let text = args[0].as_str().ok_or_else(|| {
201 crate::JmespathError::from_ctx(
202 ctx,
203 crate::ErrorReason::Parse("Expected string for text argument".to_owned()),
204 )
205 })?;
206
207 let key = args[1].as_str().ok_or_else(|| {
208 crate::JmespathError::from_ctx(
209 ctx,
210 crate::ErrorReason::Parse("Expected string for key argument".to_owned()),
211 )
212 })?;
213
214 let mut mac =
215 HmacSha1::new_from_slice(key.as_bytes()).expect("HMAC can take key of any size");
216 mac.update(text.as_bytes());
217 let result = mac.finalize();
218 let hex_string = format!("{:x}", result.into_bytes());
219
220 Ok(Value::String(hex_string))
221 }
222}
223
224defn!(HmacSha256Fn, vec![arg!(string), arg!(string)], None);
229
230impl Function for HmacSha256Fn {
231 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
232 self.signature.validate(args, ctx)?;
233
234 let text = args[0].as_str().ok_or_else(|| {
235 crate::JmespathError::from_ctx(
236 ctx,
237 crate::ErrorReason::Parse("Expected string for text argument".to_owned()),
238 )
239 })?;
240
241 let key = args[1].as_str().ok_or_else(|| {
242 crate::JmespathError::from_ctx(
243 ctx,
244 crate::ErrorReason::Parse("Expected string for key argument".to_owned()),
245 )
246 })?;
247
248 let mut mac =
249 HmacSha256::new_from_slice(key.as_bytes()).expect("HMAC can take key of any size");
250 mac.update(text.as_bytes());
251 let result = mac.finalize();
252 let hex_string = format!("{:x}", result.into_bytes());
253
254 Ok(Value::String(hex_string))
255 }
256}
257
258defn!(HmacSha512Fn, vec![arg!(string), arg!(string)], None);
263
264impl Function for HmacSha512Fn {
265 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
266 self.signature.validate(args, ctx)?;
267
268 let text = args[0].as_str().ok_or_else(|| {
269 crate::JmespathError::from_ctx(
270 ctx,
271 crate::ErrorReason::Parse("Expected string for text argument".to_owned()),
272 )
273 })?;
274
275 let key = args[1].as_str().ok_or_else(|| {
276 crate::JmespathError::from_ctx(
277 ctx,
278 crate::ErrorReason::Parse("Expected string for key argument".to_owned()),
279 )
280 })?;
281
282 let mut mac =
283 HmacSha512::new_from_slice(key.as_bytes()).expect("HMAC can take key of any size");
284 mac.update(text.as_bytes());
285 let result = mac.finalize();
286 let hex_string = format!("{:x}", result.into_bytes());
287
288 Ok(Value::String(hex_string))
289 }
290}
291
292defn!(Crc32Fn, vec![arg!(string)], None);
297
298impl Function for Crc32Fn {
299 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
300 self.signature.validate(args, ctx)?;
301
302 let input = args[0].as_str().ok_or_else(|| {
303 crate::JmespathError::from_ctx(
304 ctx,
305 crate::ErrorReason::Parse("Expected string argument".to_owned()),
306 )
307 })?;
308
309 let mut hasher = Crc32Hasher::new();
310 hasher.update(input.as_bytes());
311 let checksum = hasher.finalize();
312
313 Ok(Value::Number(serde_json::Number::from(checksum)))
314 }
315}