use base64::Engine;
use sha2::{Digest, Sha256};
use super::header::{JadesError, JadesHeader};
const B64: base64::engine::general_purpose::GeneralPurpose =
base64::engine::general_purpose::URL_SAFE_NO_PAD;
#[derive(Debug, Clone)]
pub struct PreparedJades {
header_b64: String,
payload_b64: String,
signing_input: Vec<u8>,
}
impl PreparedJades {
#[must_use]
pub fn signing_input(&self) -> &[u8] {
&self.signing_input
}
#[must_use]
pub fn signing_input_sha256(&self) -> [u8; 32] {
Sha256::digest(&self.signing_input).into()
}
#[must_use]
pub fn assemble(self, signature: &[u8]) -> JadesSignature {
JadesSignature {
compact: format!(
"{}.{}.{}",
self.header_b64,
self.payload_b64,
B64.encode(signature)
),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct JadesSignature {
compact: String,
}
impl JadesSignature {
#[must_use]
pub fn as_str(&self) -> &str {
&self.compact
}
#[must_use]
pub fn into_string(self) -> String {
self.compact
}
}
impl std::fmt::Display for JadesSignature {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(&self.compact)
}
}
pub fn prepare(header: &JadesHeader, payload: &[u8]) -> Result<PreparedJades, JadesError> {
let header_b64 = B64.encode(header.to_json_bytes()?);
let payload_b64 = B64.encode(payload);
let signing_input = format!("{header_b64}.{payload_b64}").into_bytes();
Ok(PreparedJades {
header_b64,
payload_b64,
signing_input,
})
}