tuwunel_service/oauth/server/
jwk.rs1use base64::{Engine as _, engine::general_purpose::URL_SAFE_NO_PAD as b64};
2use ring::{
3 rand::SystemRandom,
4 signature::{self, EcdsaKeyPair, KeyPair},
5};
6use serde_json::{Value as JsonValue, json};
7use tuwunel_core::{Result, err};
8
9impl super::Server {
10 #[inline]
11 #[must_use]
12 pub fn jwks(&self) -> JsonValue {
13 json!({
14 "keys": [self.jwk.clone()],
15 })
16 }
17}
18
19pub(super) fn init_jwk(key_der: &[u8], key_id: &str) -> Result<JsonValue> {
20 let rng = SystemRandom::new();
21 let alg = &signature::ECDSA_P256_SHA256_FIXED_SIGNING;
22 let key_pair = EcdsaKeyPair::from_pkcs8(alg, key_der, &rng)
23 .map_err(|e| err!(error!("Failed to load ECDSA key: {e}")))?;
24
25 let public_bytes = key_pair.public_key().as_ref();
26
27 Ok(json!({
28 "kty": "EC",
29 "crv": "P-256",
30 "use": "sig",
31 "alg": "ES256",
32 "kid": key_id,
33 "x": b64.encode(&public_bytes[1..33]),
34 "y": b64.encode(&public_bytes[33..65]),
35 }))
36}