/ backend / src / api / openid / certs.rs
certs.rs
 1  use base64::Engine;
 2  use rocket::{serde::json::Json, State};
 3  use serde::Serialize;
 4  
 5  use crate::{
 6      api::common::headers::{AccessControlAllowOrigin, AccessControlAllowOriginVariant},
 7      util::config::Config,
 8  };
 9  
10  #[derive(Debug, Clone, Serialize)]
11  #[serde(rename_all = "SCREAMING_SNAKE_CASE")]
12  pub enum KeyType {
13      Rsa,
14  }
15  
16  #[derive(Debug, Clone, Serialize)]
17  #[allow(dead_code)]
18  pub enum KeyUsage {
19      #[serde(rename = "sig")]
20      Signing,
21      #[serde(rename = "enc")]
22      Encryption,
23  }
24  
25  #[derive(Debug, Clone, Serialize)]
26  #[serde(rename_all = "SCREAMING_SNAKE_CASE")]
27  pub enum Algorithm {
28      // RSASSA-PKCS1-v1_5 with the SHA-256 hash.
29      Rs256,
30  }
31  
32  #[derive(Debug, Clone, Serialize)]
33  pub struct CertKey {
34      #[serde(rename = "kty")]
35      key_type: KeyType,
36      #[serde(rename = "use")]
37      intended_usage: KeyUsage,
38      #[serde(rename = "alg")]
39      algorithm: Algorithm,
40      // We only support RSA for now, however,
41      // if other algorithms are to be supported in the future
42      // the following values will have be set dynamically as they are dependent on the algorithm.
43      e: String,
44      n: String,
45  }
46  
47  #[derive(Debug, Clone, Serialize)]
48  pub struct GetCertsResponseData {
49      keys: Vec<CertKey>,
50  }
51  
52  #[derive(Responder)]
53  pub enum GetCertsResponse {
54      #[response(status = 200)]
55      Success {
56          inner: Json<GetCertsResponseData>,
57          access_control_allow_origin: AccessControlAllowOrigin,
58      },
59  }
60  
61  #[get("/certs")]
62  pub async fn get_certs(config: &State<Config>) -> GetCertsResponse {
63      let e = base64::engine::general_purpose::URL_SAFE_NO_PAD
64          .encode(config.jwt_signing_key.e().to_vec());
65      let n = base64::engine::general_purpose::URL_SAFE_NO_PAD
66          .encode(config.jwt_signing_key.n().to_vec());
67  
68      GetCertsResponse::Success {
69          inner: Json(GetCertsResponseData {
70              keys: vec![CertKey {
71                  key_type: KeyType::Rsa,
72                  intended_usage: KeyUsage::Signing,
73                  algorithm: Algorithm::Rs256,
74                  e,
75                  n,
76              }],
77          }),
78          access_control_allow_origin: AccessControlAllowOriginVariant::Any.into(),
79      }
80  }