use data_encoding::HEXUPPER;
use ring::digest::{Context, SHA256};
use crate::claims::{Claims, Token};
use crate::parser::ParsedModule;
use crate::{Error, WickComponent};
pub(crate) const SECTION_NAME: &str = "wick/claims@v1";
#[derive(Debug, Default, Clone)]
pub struct ClaimsOptions {
pub version: Option<String>,
pub expires_in_days: Option<u64>,
pub not_before_days: Option<u64>,
}
pub(crate) fn decode(bytes: &[u8]) -> Result<Token<WickComponent>, Error> {
let jwt = std::str::from_utf8(bytes)?;
let claims: Claims<WickComponent> = Claims::decode(jwt)?;
Ok(Token {
jwt: jwt.to_owned(),
claims,
})
}
pub(crate) fn hash(module: &ParsedModule, filter: &[&str]) -> Result<String, Error> {
let mut context = Context::new(&SHA256);
for payload in &module.1 {
use wasmparser::Payload::*;
let section = payload.as_section();
match payload {
Version { encoding, .. } => {
context.update(match encoding {
wasmparser::Encoding::Module => &wasm_encoder::Module::HEADER,
wasmparser::Encoding::Component => todo!(),
});
}
CustomSection(c) if (filter.contains(&c.name())) => {
}
_ => {
if let Some((id, range)) = section {
context.update(&id.to_le_bytes());
let bytes = &module.0[range];
context.update(&bytes.len().to_le_bytes());
context.update(bytes);
}
}
}
}
Ok(HEXUPPER.encode(context.finish().as_ref()))
}
#[cfg(test)]
mod test {
use anyhow::Result;
use super::*;
use crate::parser::ParsedModule;
#[rstest::rstest]
#[case(
"./test/1.v0.signed.wasm",
"90E5D03AF45BAE5EFC5841C196A2774BEB783E4E041E1D6D1421073765D47E50"
)]
#[case(
"./test/2.v0.signed.wasm",
"846CBC6E9D35321E0A81D150B1CCA2816EAD9E53DAF0AA12BD2FB44E19E7605C"
)]
#[case(
"./test/3.v0.signed.wasm",
"7A68971E61256D7B76FA580B2E17B173B943B1B737E65C5EB6AECA6D37312EEE"
)]
#[case(
"./test/4.v0.signed.wasm",
"8DD28458BE618E260A70390FAEB5E74160823F979A32F6167F3C3D3D1C2C08BB"
)]
fn test_signature(#[case] file: &str, #[case] expected_hash: &str) -> Result<()> {
let bytes = std::fs::read(file)?;
let module = ParsedModule::new(&bytes)?;
let hash = hash(&module, &[SECTION_NAME, crate::v0::SECTION_NAME])?;
assert_eq!(hash, expected_hash);
Ok(())
}
}