1use crate::{types::Algorithm, Error, Result};
2use serde::{Deserialize, Serialize};
3use base64ct::Encoding;
4
5#[derive(Debug, Clone)]
7pub enum Key {
8 Hs(Vec<u8>),
10 RsaPublicPem(Vec<u8>),
12 RsaPrivatePem(Vec<u8>),
14 EcPublicPem(Vec<u8>),
16 EcPrivatePem(Vec<u8>),
18 EdPublicPem(Vec<u8>),
20 EdPrivatePem(Vec<u8>),
22}
23impl Key {
24 pub fn hs(secret: impl AsRef<[u8]>) -> Self { Key::Hs(secret.as_ref().to_vec()) }
26 pub fn rsa_public_pem(pem: impl AsRef<[u8]>) -> Self { Key::RsaPublicPem(pem.as_ref().to_vec()) }
28 pub fn rsa_private_pem(pem: impl AsRef<[u8]>) -> Self { Key::RsaPrivatePem(pem.as_ref().to_vec()) }
30 pub fn ec_public_pem(pem: impl AsRef<[u8]>) -> Self { Key::EcPublicPem(pem.as_ref().to_vec()) }
32 pub fn ec_private_pem(pem: impl AsRef<[u8]>) -> Self { Key::EcPrivatePem(pem.as_ref().to_vec()) }
34 pub fn ed_public_pem(pem: impl AsRef<[u8]>) -> Self { Key::EdPublicPem(pem.as_ref().to_vec()) }
36 pub fn ed_private_pem(pem: impl AsRef<[u8]>) -> Self { Key::EdPrivatePem(pem.as_ref().to_vec()) }
38}
39
40#[derive(Debug, Clone, Serialize, Deserialize)]
42pub struct Jwk {
43 pub kty: String,
45 #[serde(default)]
47 pub kid: Option<String>,
48 #[serde(default)]
50 pub alg: Option<String>,
51 #[serde(default, rename = "use")]
53 pub use_: Option<String>,
54 #[serde(default)] pub n: Option<String>,
56 #[serde(default)] pub e: Option<String>,
58 #[serde(default)] pub d: Option<String>,
60 #[serde(default)] pub p: Option<String>,
62 #[serde(default)] pub q: Option<String>,
64 #[serde(default)] pub dp: Option<String>,
66 #[serde(default)] pub dq: Option<String>,
68 #[serde(default)] pub qi: Option<String>,
70 #[serde(default)] pub crv: Option<String>,
72 #[serde(default)] pub x: Option<String>,
74 #[serde(default)] pub y: Option<String>,
76 #[serde(default)] pub k: Option<String>,
78}
79
80#[derive(Debug, Clone, Serialize, Deserialize)]
82pub struct Jwks {
83 pub keys: Vec<Jwk>
85}
86
87impl Jwks {
88 pub fn from_str(s: &str) -> Result<Self> {
98 serde_json::from_str(s).map_err(|e| Error::Json(e.to_string()))
99 }
100 pub fn select_for(&self, kid: &str, alg: crate::types::Algorithm) -> Result<Key> {
116 let jwk = self.keys.iter().find(|k| k.kid.as_deref() == Some(kid)).ok_or(Error::KidNotFound)?;
117 jwk.to_key_for(alg)
118 }
119}
120
121impl Jwk {
122 pub fn to_key_for(&self, alg: Algorithm) -> Result<Key> {
141 match self.kty.as_str() {
142 "oct" => {
143 let k = self.k.as_ref().ok_or_else(|| Error::Key("oct missing k".into()))?;
144 let bytes = base64ct::Base64UrlUnpadded::decode_vec(k).map_err(|e| Error::Key(e.to_string()))?;
145 Ok(Key::Hs(bytes))
146 }
147 "RSA" => match alg {
148 Algorithm::RS256 | Algorithm::RS384 | Algorithm::RS512 => {
149 Err(Error::Key("RSA JWK to PEM conversion not implemented".into()))
150 }
151 _ => Err(Error::Key("RSA JWK used with non-RS alg".into())),
152 }
153 "EC" => match (self.crv.as_deref(), alg) {
154 (Some("P-256"), Algorithm::ES256) |
155 (Some("P-384"), Algorithm::ES384) |
156 (Some("P-521"), Algorithm::ES512) => {
157 Err(Error::Key("EC JWK to PEM conversion not implemented".into()))
158 }
159 _ => Err(Error::Key("EC JWK and alg mismatch or unsupported curve".into())),
160 }
161 "OKP" => match (self.crv.as_deref(), alg) {
162 (Some("Ed25519"), Algorithm::EdDSA) => {
163 Err(Error::Key("EdDSA JWK to PEM conversion not implemented".into()))
164 }
165 _ => Err(Error::Key("OKP JWK not Ed25519".into())),
166 }
167 _ => Err(Error::Key("unsupported kty".into())),
168 }
169 }
170}
171
172#[derive(Debug, Clone, Copy)]
174pub enum KeySource {
175 Auto
177}