-
Notifications
You must be signed in to change notification settings - Fork 621
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add: builtin NASL hash functions (#1616)
* Add: builtin NASL hash functions Jira: SC-1049 * Fix: update h2 to 0.3.26 for fixing RUSTSEC-2024-0332 * Fix: hexstr() builtin nasl function for `Data` type
- Loading branch information
Showing
8 changed files
with
632 additions
and
145 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
// SPDX-FileCopyrightText: 2024 Greenbone AG | ||
// | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
|
||
use digest::Digest; | ||
use md2::Md2; | ||
use md4::Md4; | ||
use md5::Md5; | ||
use nasl_builtin_utils::error::FunctionErrorKind; | ||
use ripemd::Ripemd160; | ||
use sha1::Sha1; | ||
use sha2::{Sha256, Sha512}; | ||
|
||
use crate::NaslFunction; | ||
use nasl_builtin_utils::{Context, Register}; | ||
use nasl_syntax::NaslValue; | ||
|
||
fn nasl_hash<D: Digest>(register: &Register) -> Result<NaslValue, FunctionErrorKind> | ||
where | ||
D::OutputSize: std::ops::Add, | ||
<D::OutputSize as std::ops::Add>::Output: digest::generic_array::ArrayLength<u8>, | ||
{ | ||
let positional = register.positional(); | ||
if positional.is_empty() { | ||
return Ok(NaslValue::Null) | ||
}; | ||
let data = match &positional[0] { | ||
NaslValue::String(x) => x.as_bytes(), | ||
NaslValue::Data(x) => x, | ||
NaslValue::Null => return Ok(NaslValue::Null), | ||
x => return Err(("data", "string", x).into()), | ||
}; | ||
|
||
let mut hash = D::new(); | ||
hash.update(data); | ||
Ok(NaslValue::Data(hash.finalize().as_slice().to_vec())) | ||
} | ||
|
||
/// NASL function to get MD2 hash | ||
pub fn hash_md2<K>(register: &Register, _: &Context<K>) -> Result<NaslValue, FunctionErrorKind> { | ||
nasl_hash::<Md2>(register) | ||
} | ||
|
||
/// NASL function to get MD4 hash | ||
pub fn hash_md4<K>(register: &Register, _: &Context<K>) -> Result<NaslValue, FunctionErrorKind> { | ||
nasl_hash::<Md4>(register) | ||
} | ||
|
||
/// NASL function to get MD5 hash | ||
pub fn hash_md5<K>(register: &Register, _: &Context<K>) -> Result<NaslValue, FunctionErrorKind> { | ||
nasl_hash::<Md5>(register) | ||
} | ||
|
||
/// NASL function to get SHA1 hash | ||
pub fn hash_sha1<K>(register: &Register, _: &Context<K>) -> Result<NaslValue, FunctionErrorKind> { | ||
nasl_hash::<Sha1>(register) | ||
} | ||
|
||
/// NASL function to get SHA256 hash | ||
pub fn hash_sha256<K>(register: &Register, _: &Context<K>) -> Result<NaslValue, FunctionErrorKind> { | ||
nasl_hash::<Sha256>(register) | ||
} | ||
|
||
/// NASL function to get SHA512 hash | ||
pub fn hash_sha512<K>(register: &Register, _: &Context<K>) -> Result<NaslValue, FunctionErrorKind> { | ||
nasl_hash::<Sha512>(register) | ||
} | ||
|
||
/// NASL function to get RIPemd160 hash | ||
pub fn hash_ripemd160<K>( | ||
register: &Register, | ||
_: &Context<K>, | ||
) -> Result<NaslValue, FunctionErrorKind> { | ||
nasl_hash::<Ripemd160>(register) | ||
} | ||
|
||
/// Returns found function for key or None when not found | ||
pub fn lookup<K>(key: &str) -> Option<NaslFunction<K>> { | ||
match key { | ||
"MD2" => Some(hash_md2), | ||
"MD4" => Some(hash_md4), | ||
"MD5" => Some(hash_md5), | ||
"RIPEMD160" => Some(hash_ripemd160), | ||
"SHA1" => Some(hash_sha1), | ||
"SHA256" => Some(hash_sha256), | ||
"SHA512" => Some(hash_sha512), | ||
_ => None, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,174 @@ | ||
// SPDX-FileCopyrightText: 2024 Greenbone AG | ||
// | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
|
||
mod helper; | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use nasl_interpreter::*; | ||
|
||
#[test] | ||
fn hash_md5() { | ||
let code = r#" | ||
a = MD5("hola mundo"); | ||
a = MD5('hola mundo'); | ||
a = MD5(); | ||
"#; | ||
let mut register = Register::default(); | ||
let binding = ContextBuilder::default(); | ||
let context = binding.build(); | ||
let mut interpreter = Interpreter::new(&mut register, &context); | ||
let mut parser = | ||
parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); | ||
assert_eq!( | ||
parser.next(), | ||
Some(Ok(NaslValue::Data( | ||
[10, 208, 102, 165, 210, 159, 63, 42, 42, 28, 124, 23, 221, 8, 42, 121].to_vec() | ||
))) | ||
); | ||
assert_eq!( | ||
parser.next(), | ||
Some(Ok(NaslValue::Data( | ||
[10, 208, 102, 165, 210, 159, 63, 42, 42, 28, 124, 23, 221, 8, 42, 121].to_vec() | ||
))) | ||
); | ||
assert_eq!( | ||
parser.next(), | ||
Some(Ok(NaslValue::Null)) | ||
); | ||
} | ||
|
||
#[test] | ||
fn hash_md4() { | ||
let code = r#" | ||
MD4("hola mundo"); | ||
"#; | ||
let mut register = Register::default(); | ||
let binding = ContextBuilder::default(); | ||
let context = binding.build(); | ||
let mut interpreter = Interpreter::new(&mut register, &context); | ||
let mut parser = | ||
parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); | ||
assert_eq!( | ||
parser.next(), | ||
Some(Ok(NaslValue::Data( | ||
[150, 189, 216, 54, 225, 218, 147, 16, 141, 155, 247, 14, 153, 134, 239, 236] | ||
.to_vec() | ||
))) | ||
); | ||
} | ||
|
||
#[test] | ||
fn hash_md2() { | ||
let code = r#" | ||
MD2("hola mundo"); | ||
"#; | ||
let mut register = Register::default(); | ||
let binding = ContextBuilder::default(); | ||
let context = binding.build(); | ||
let mut interpreter = Interpreter::new(&mut register, &context); | ||
let mut parser = | ||
parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); | ||
assert_eq!( | ||
parser.next(), | ||
Some(Ok(NaslValue::Data( | ||
[45, 30, 74, 180, 247, 157, 181, 203, 252, 239, 123, 54, 5, 214, 55, 45].to_vec() | ||
))) | ||
); | ||
} | ||
|
||
#[test] | ||
fn hash_sha1() { | ||
let code = r#" | ||
SHA1("hola mundo"); | ||
"#; | ||
let mut register = Register::default(); | ||
let binding = ContextBuilder::default(); | ||
let context = binding.build(); | ||
let mut interpreter = Interpreter::new(&mut register, &context); | ||
let mut parser = | ||
parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); | ||
assert_eq!( | ||
parser.next(), | ||
Some(Ok(NaslValue::Data( | ||
[ | ||
69, 149, 103, 211, 189, 228, 65, 139, 127, 227, 2, 255, 152, 9, 196, 176, 190, | ||
250, 247, 221 | ||
] | ||
.to_vec() | ||
))) | ||
); | ||
} | ||
#[test] | ||
|
||
fn hash_sha256() { | ||
let code = r#" | ||
SHA256("hola mundo"); | ||
"#; | ||
let mut register = Register::default(); | ||
let binding = ContextBuilder::default(); | ||
let context = binding.build(); | ||
let mut interpreter = Interpreter::new(&mut register, &context); | ||
let mut parser = | ||
parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); | ||
assert_eq!( | ||
parser.next(), | ||
Some(Ok(NaslValue::Data( | ||
[ | ||
11, 137, 65, 102, 211, 51, 100, 53, 200, 0, 190, 163, 111, 242, 27, 41, 234, | ||
168, 1, 165, 47, 88, 76, 0, 108, 73, 40, 154, 13, 207, 110, 47 | ||
] | ||
.to_vec() | ||
))) | ||
); | ||
} | ||
|
||
#[test] | ||
fn hash_sha512() { | ||
let code = r#" | ||
SHA512("hola mundo"); | ||
"#; | ||
let mut register = Register::default(); | ||
let binding = ContextBuilder::default(); | ||
let context = binding.build(); | ||
let mut interpreter = Interpreter::new(&mut register, &context); | ||
let mut parser = | ||
parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); | ||
assert_eq!( | ||
parser.next(), | ||
Some(Ok(NaslValue::Data( | ||
[ | ||
227, 97, 236, 195, 31, 42, 172, 32, 102, 163, 16, 61, 59, 20, 220, 99, 181, | ||
152, 75, 2, 143, 159, 45, 9, 222, 230, 116, 96, 206, 39, 2, 188, 129, 103, 58, | ||
207, 88, 16, 155, 85, 51, 36, 133, 44, 98, 162, 39, 217, 167, 93, 76, 47, 104, | ||
101, 128, 39, 15, 225, 67, 4, 143, 71, 195, 60 | ||
] | ||
.to_vec() | ||
))) | ||
); | ||
} | ||
|
||
#[test] | ||
fn hash_ripemd160() { | ||
let code = r#" | ||
RIPEMD160("hola mundo"); | ||
"#; | ||
let mut register = Register::default(); | ||
let binding = ContextBuilder::default(); | ||
let context = binding.build(); | ||
let mut interpreter = Interpreter::new(&mut register, &context); | ||
let mut parser = | ||
parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); | ||
assert_eq!( | ||
parser.next(), | ||
Some(Ok(NaslValue::Data( | ||
[ | ||
224, 38, 197, 40, 255, 116, 162, 102, 178, 240, 158, 34, 193, 190, 227, 99, 44, | ||
6, 233, 21 | ||
] | ||
.to_vec() | ||
))) | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters