chore: seed sgclaw rust baseline
This commit is contained in:
48
src/security/hmac.rs
Normal file
48
src/security/hmac.rs
Normal file
@@ -0,0 +1,48 @@
|
||||
use hmac::{Hmac, Mac};
|
||||
use serde_json::Value;
|
||||
use sha2::{Digest, Sha256};
|
||||
|
||||
use crate::pipe::Action;
|
||||
use crate::security::SecurityError;
|
||||
|
||||
type HmacSha256 = Hmac<Sha256>;
|
||||
|
||||
pub fn derive_session_key(hmac_seed: &str) -> Result<Vec<u8>, SecurityError> {
|
||||
let seed = hex::decode(hmac_seed)?;
|
||||
if seed.is_empty() {
|
||||
return Err(SecurityError::InvalidSeed(
|
||||
"hmac_seed must not be empty".to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
let mut hasher = Sha256::new();
|
||||
hasher.update(seed);
|
||||
hasher.update(b"sgclaw-session-v1");
|
||||
Ok(hasher.finalize().to_vec())
|
||||
}
|
||||
|
||||
pub fn sign_command(
|
||||
session_key: &[u8],
|
||||
seq: u64,
|
||||
action: &Action,
|
||||
params: &Value,
|
||||
expected_domain: &str,
|
||||
) -> Result<String, SecurityError> {
|
||||
if session_key.is_empty() {
|
||||
return Err(SecurityError::InvalidSeed(
|
||||
"session key must not be empty".to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
let mut mac = HmacSha256::new_from_slice(session_key)
|
||||
.map_err(|err| SecurityError::Hmac(err.to_string()))?;
|
||||
mac.update(seq.to_string().as_bytes());
|
||||
mac.update(b"|");
|
||||
mac.update(action.as_str().as_bytes());
|
||||
mac.update(b"|");
|
||||
mac.update(expected_domain.as_bytes());
|
||||
mac.update(b"|");
|
||||
mac.update(serde_json::to_string(params)?.as_bytes());
|
||||
|
||||
Ok(hex::encode(mac.finalize().into_bytes()))
|
||||
}
|
||||
Reference in New Issue
Block a user