Skip to main content

tuwunel_service/oauth/server/
jwk.rs

1use 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}