use crate::{types::{Algorithm, Header, Claims}, jwk::Key, Error, Result};
fn to_jalg(a: Algorithm) -> jsonwebtoken::Algorithm {
use Algorithm::*;
match a {
HS256 => jsonwebtoken::Algorithm::HS256,
HS384 => jsonwebtoken::Algorithm::HS384,
HS512 => jsonwebtoken::Algorithm::HS512,
RS256 => jsonwebtoken::Algorithm::RS256,
RS384 => jsonwebtoken::Algorithm::RS384,
RS512 => jsonwebtoken::Algorithm::RS512,
ES256 => jsonwebtoken::Algorithm::ES256,
ES384 => jsonwebtoken::Algorithm::ES384,
ES512 => jsonwebtoken::Algorithm::ES384,
EdDSA => jsonwebtoken::Algorithm::EdDSA,
}
}
pub fn sign(header: &Header, claims: &Claims, key: &Key) -> Result<String> {
use jsonwebtoken::{Header as JHeader, EncodingKey, encode};
match header.alg {
Algorithm::HS256 | Algorithm::HS384 | Algorithm::HS512 => { #[cfg(not(feature="hs"))] return Err(Error::DisabledAlg("HS")); }
Algorithm::RS256 | Algorithm::RS384 | Algorithm::RS512 => { #[cfg(not(feature="rs"))] return Err(Error::DisabledAlg("RS")); }
Algorithm::ES256 | Algorithm::ES384 | Algorithm::ES512 => { #[cfg(not(feature="es"))] return Err(Error::DisabledAlg("ES")); }
Algorithm::EdDSA => { #[cfg(not(feature="eddsa"))] return Err(Error::DisabledAlg("EdDSA")); }
}
let mut h = JHeader::new(to_jalg(header.alg));
h.typ = Some(header.typ.clone().unwrap_or_else(|| "JWT".into()));
h.kid = header.kid.clone();
let enc = match key {
Key::Hs(shared) => EncodingKey::from_secret(shared),
Key::RsaPrivatePem(pem) => EncodingKey::from_rsa_pem(pem).map_err(|e| Error::Key(e.to_string()))?,
Key::EcPrivatePem(pem) => EncodingKey::from_ec_pem(pem).map_err(|e| Error::Key(e.to_string()))?,
Key::EdPrivatePem(pem) => EncodingKey::from_ed_pem(pem).map_err(|e| Error::Key(e.to_string()))?,
_ => return Err(Error::Key("private key required to sign".into())),
};
encode(&h, &claims.0, &enc).map_err(|e| Error::Internal(e.to_string()))
}
impl crate::types::Jwt {
pub fn sign(&self, key: &Key) -> Result<String> {
sign(&self.header, &self.claims, key)
}
}