use serde::ser::Serialize;
use crate::crypto;
use crate::errors::Result;
use crate::header::Header;
use crate::serialization::b64_encode_part;
use base64::{engine::general_purpose::STANDARD, Engine};
#[derive(Debug, Clone, PartialEq)]
pub enum EncodingKey {
Hmac(Vec<u8>),
Rsa(Box<rsa::RsaPrivateKey>),
}
impl EncodingKey {
pub fn from_hmac_secret(secret: &[u8]) -> Self {
EncodingKey::Hmac(secret.to_vec())
}
pub fn from_base64_hmac_secret(secret: &str) -> Result<Self> {
Ok(EncodingKey::Hmac(STANDARD.decode(secret)?))
}
pub fn from_rsa(key: rsa::RsaPrivateKey) -> Result<Self> {
Ok(EncodingKey::Rsa(Box::new(key)))
}
}
pub fn encode<T: Serialize>(header: &Header, claims: &T, key: &EncodingKey) -> Result<String> {
crypto::validate_matching_key(key, header.alg)?;
let encoded_header = b64_encode_part(&header)?;
let encoded_claims = b64_encode_part(&claims)?;
let message = [encoded_header.as_ref(), encoded_claims.as_ref()].join(".");
let signature = crypto::sign(&message, key, header.alg)?;
Ok([message, signature].join("."))
}