BasicOIDC/src/data/jwt_signer.rs
Pierre Hubert e35f890241
All checks were successful
continuous-integration/drone/push Build is passing
Update crate base64
2023-01-23 16:38:21 +01:00

54 lines
1.6 KiB
Rust

use jwt_simple::algorithms::RSAKeyPairLike;
use jwt_simple::claims::JWTClaims;
use jwt_simple::prelude::RS256KeyPair;
use serde::de::DeserializeOwned;
use serde::Serialize;
use base64::engine::general_purpose::URL_SAFE as BASE64_URL_URL_SAFE;
use base64::engine::general_purpose::URL_SAFE_NO_PAD as BASE64_URL_SAFE_NO_PAD;
use base64::Engine as _;
use crate::utils::err::Res;
use crate::utils::string_utils::rand_str;
/// Json Web Key <https://datatracker.ietf.org/doc/html/rfc7517>
#[derive(serde::Serialize, serde::Deserialize)]
pub struct JsonWebKey {
#[serde(rename = "alg")]
algorithm: String,
#[serde(rename = "kty")]
key_type: String,
#[serde(rename = "kid")]
key_id: String,
#[serde(rename = "n")]
modulus: String,
#[serde(rename = "e")]
public_exponent: String,
}
#[derive(Debug, Clone)]
pub struct JWTSigner(RS256KeyPair);
impl JWTSigner {
pub fn gen_from_memory() -> Res<Self> {
Ok(Self(
RS256KeyPair::generate(2048)?.with_key_id(&format!("key-{}", rand_str(15))),
))
}
pub fn get_json_web_key(&self) -> JsonWebKey {
let components = self.0.public_key().to_components();
JsonWebKey {
algorithm: "RS256".to_string(),
key_type: "RSA".to_string(),
key_id: self.0.key_id().as_ref().unwrap().to_string(),
public_exponent: BASE64_URL_URL_SAFE.encode(components.e),
modulus: BASE64_URL_SAFE_NO_PAD.encode(components.n),
}
}
pub fn sign_token<E: Serialize + DeserializeOwned>(&self, c: JWTClaims<E>) -> Res<String> {
Ok(self.0.sign(c)?)
}
}