1use crate::{types::{Algorithm, Header, Claims}, jwk::Key, Error, Result};
2
3fn to_jalg(a: Algorithm) -> jsonwebtoken::Algorithm {
5 use Algorithm::*;
6 match a {
7 HS256 => jsonwebtoken::Algorithm::HS256,
8 HS384 => jsonwebtoken::Algorithm::HS384,
9 HS512 => jsonwebtoken::Algorithm::HS512,
10 RS256 => jsonwebtoken::Algorithm::RS256,
11 RS384 => jsonwebtoken::Algorithm::RS384,
12 RS512 => jsonwebtoken::Algorithm::RS512,
13 ES256 => jsonwebtoken::Algorithm::ES256,
14 ES384 => jsonwebtoken::Algorithm::ES384,
15 ES512 => jsonwebtoken::Algorithm::ES384,
16 EdDSA => jsonwebtoken::Algorithm::EdDSA,
17 }
18}
19
20pub fn sign(header: &Header, claims: &Claims, key: &Key) -> Result<String> {
38 use jsonwebtoken::{Header as JHeader, EncodingKey, encode};
39
40 match header.alg {
41 Algorithm::HS256 | Algorithm::HS384 | Algorithm::HS512 => { #[cfg(not(feature="hs"))] return Err(Error::DisabledAlg("HS")); }
42 Algorithm::RS256 | Algorithm::RS384 | Algorithm::RS512 => { #[cfg(not(feature="rs"))] return Err(Error::DisabledAlg("RS")); }
43 Algorithm::ES256 | Algorithm::ES384 | Algorithm::ES512 => { #[cfg(not(feature="es"))] return Err(Error::DisabledAlg("ES")); }
44 Algorithm::EdDSA => { #[cfg(not(feature="eddsa"))] return Err(Error::DisabledAlg("EdDSA")); }
45 }
46
47 let mut h = JHeader::new(to_jalg(header.alg));
48 h.typ = Some(header.typ.clone().unwrap_or_else(|| "JWT".into()));
49 h.kid = header.kid.clone();
50
51 let enc = match key {
52 Key::Hs(shared) => EncodingKey::from_secret(shared),
53 Key::RsaPrivatePem(pem) => EncodingKey::from_rsa_pem(pem).map_err(|e| Error::Key(e.to_string()))?,
54 Key::EcPrivatePem(pem) => EncodingKey::from_ec_pem(pem).map_err(|e| Error::Key(e.to_string()))?,
55 Key::EdPrivatePem(pem) => EncodingKey::from_ed_pem(pem).map_err(|e| Error::Key(e.to_string()))?,
56 _ => return Err(Error::Key("private key required to sign".into())),
57 };
58
59 encode(&h, &claims.0, &enc).map_err(|e| Error::Internal(e.to_string()))
60}
61
62impl crate::types::Jwt {
63 pub fn sign(&self, key: &Key) -> Result<String> {
79 sign(&self.header, &self.claims, key)
80 }
81}