1use ct_codecs::{Base64UrlSafeNoPadding, Encoder};
2use hmac_sha1_compact::Hash as SHA1;
3use hmac_sha256::Hash as SHA256;
4use serde::{de::DeserializeOwned, Serialize};
5
6use crate::claims::*;
7use crate::common::*;
8#[cfg(feature = "cwt")]
9use crate::cwt_token::*;
10use crate::error::*;
11use crate::jwt_header::*;
12use crate::token::*;
13
14#[doc(hidden)]
15#[derive(Debug, Clone)]
16pub struct Edwards25519PublicKey(ed25519_compact::PublicKey);
17
18impl AsRef<ed25519_compact::PublicKey> for Edwards25519PublicKey {
19 fn as_ref(&self) -> &ed25519_compact::PublicKey {
20 &self.0
21 }
22}
23
24impl Edwards25519PublicKey {
25 pub fn from_bytes(raw: &[u8]) -> Result<Self, Error> {
26 let ed25519_pk = ed25519_compact::PublicKey::from_slice(raw);
27 Ok(Edwards25519PublicKey(
28 ed25519_pk.map_err(|_| JWTError::InvalidPublicKey)?,
29 ))
30 }
31
32 pub fn from_der(der: &[u8]) -> Result<Self, Error> {
33 let ed25519_pk = ed25519_compact::PublicKey::from_der(der);
34 Ok(Edwards25519PublicKey(
35 ed25519_pk.map_err(|_| JWTError::InvalidPublicKey)?,
36 ))
37 }
38
39 pub fn from_pem(pem: &str) -> Result<Self, Error> {
40 let ed25519_pk = ed25519_compact::PublicKey::from_pem(pem);
41 Ok(Edwards25519PublicKey(
42 ed25519_pk.map_err(|_| JWTError::InvalidPublicKey)?,
43 ))
44 }
45
46 pub fn to_bytes(&self) -> Vec<u8> {
47 self.0.as_ref().to_vec()
48 }
49
50 pub fn to_der(&self) -> Vec<u8> {
51 self.0.to_der()
52 }
53
54 pub fn to_pem(&self) -> String {
55 self.0.to_pem()
56 }
57}
58
59#[doc(hidden)]
60#[derive(Clone)]
61pub struct Edwards25519KeyPair {
62 ed25519_kp: ed25519_compact::KeyPair,
63 metadata: Option<KeyMetadata>,
64}
65
66impl AsRef<ed25519_compact::KeyPair> for Edwards25519KeyPair {
67 fn as_ref(&self) -> &ed25519_compact::KeyPair {
68 &self.ed25519_kp
69 }
70}
71
72impl Edwards25519KeyPair {
73 pub fn from_bytes(raw: &[u8]) -> Result<Self, Error> {
74 let ed25519_kp = ed25519_compact::KeyPair::from_slice(raw)?;
75 Ok(Edwards25519KeyPair {
76 ed25519_kp,
77 metadata: None,
78 })
79 }
80
81 pub fn from_der(der: &[u8]) -> Result<Self, Error> {
82 let ed25519_kp = match ed25519_compact::KeyPair::from_der(der) {
83 Ok(kp) => kp,
84 Err(_) => ed25519_compact::KeyPair::from_seed(
85 ed25519_compact::SecretKey::from_der(der)?.seed(),
86 ),
87 };
88 Ok(Edwards25519KeyPair {
89 ed25519_kp,
90 metadata: None,
91 })
92 }
93
94 pub fn from_pem(pem: &str) -> Result<Self, Error> {
95 let ed25519_kp = match ed25519_compact::KeyPair::from_pem(pem) {
96 Ok(kp) => kp,
97 Err(_) => ed25519_compact::KeyPair::from_seed(
98 ed25519_compact::SecretKey::from_pem(pem)?.seed(),
99 ),
100 };
101 Ok(Edwards25519KeyPair {
102 ed25519_kp,
103 metadata: None,
104 })
105 }
106
107 pub fn to_bytes(&self) -> Vec<u8> {
108 self.ed25519_kp.to_vec()
109 }
110
111 pub fn to_der(&self) -> Vec<u8> {
112 self.ed25519_kp.sk.to_der()
113 }
114
115 pub fn to_pem(&self) -> String {
116 self.ed25519_kp.to_pem()
117 }
118
119 pub fn public_key(&self) -> Edwards25519PublicKey {
120 let ed25519_pk = self.ed25519_kp.pk;
121 Edwards25519PublicKey(ed25519_pk)
122 }
123
124 pub fn generate() -> Self {
125 let ed25519_kp = ed25519_compact::KeyPair::from_seed(ed25519_compact::Seed::generate());
126 Edwards25519KeyPair {
127 ed25519_kp,
128 metadata: None,
129 }
130 }
131}
132
133pub trait EdDSAKeyPairLike {
134 fn jwt_alg_name() -> &'static str;
135 fn key_pair(&self) -> &Edwards25519KeyPair;
136 fn key_id(&self) -> &Option<String>;
137 fn metadata(&self) -> &Option<KeyMetadata>;
138 fn attach_metadata(&mut self, metadata: KeyMetadata) -> Result<(), Error>;
139
140 fn sign<CustomClaims: Serialize + DeserializeOwned>(
141 &self,
142 claims: JWTClaims<CustomClaims>,
143 ) -> Result<String, Error> {
144 let jwt_header = JWTHeader::new(Self::jwt_alg_name().to_string(), self.key_id().clone())
145 .with_metadata(self.metadata());
146 Token::build(&jwt_header, claims, |authenticated| {
147 let noise = ed25519_compact::Noise::generate();
148 let signature = self.key_pair().as_ref().sk.sign(authenticated, Some(noise));
149 Ok(signature.to_vec())
150 })
151 }
152}
153
154pub trait EdDSAPublicKeyLike {
155 fn jwt_alg_name() -> &'static str;
156 fn public_key(&self) -> &Edwards25519PublicKey;
157 fn key_id(&self) -> &Option<String>;
158 fn set_key_id(&mut self, key_id: String);
159
160 fn verify_token<CustomClaims: Serialize + DeserializeOwned>(
161 &self,
162 token: &str,
163 options: Option<VerificationOptions>,
164 ) -> Result<JWTClaims<CustomClaims>, Error> {
165 Token::verify(
166 Self::jwt_alg_name(),
167 token,
168 options,
169 |authenticated, signature| {
170 let ed25519_signature = ed25519_compact::Signature::from_slice(signature)?;
171 self.public_key()
172 .as_ref()
173 .verify(authenticated, &ed25519_signature)
174 .map_err(|_| JWTError::InvalidSignature)?;
175 Ok(())
176 },
177 )
178 }
179
180 #[cfg(feature = "cwt")]
181 fn verify_cwt_token<CustomClaims: Serialize + DeserializeOwned>(
182 &self,
183 token: &[u8],
184 options: Option<VerificationOptions>,
185 ) -> Result<JWTClaims<NoCustomClaims>, Error> {
186 CWTToken::verify(
187 Self::jwt_alg_name(),
188 token,
189 options,
190 |authenticated, signature| {
191 let ed25519_signature = ed25519_compact::Signature::from_slice(signature)?;
192 self.public_key()
193 .as_ref()
194 .verify(authenticated, &ed25519_signature)
195 .map_err(|_| JWTError::InvalidSignature)?;
196 Ok(())
197 },
198 )
199 }
200
201 fn create_key_id(&mut self) -> &str {
202 self.set_key_id(
203 Base64UrlSafeNoPadding::encode_to_string(hmac_sha256::Hash::hash(
204 &self.public_key().to_bytes(),
205 ))
206 .unwrap(),
207 );
208 self.key_id().as_ref().map(|x| x.as_str()).unwrap()
209 }
210}
211
212#[derive(Clone)]
213pub struct Ed25519KeyPair {
214 key_pair: Edwards25519KeyPair,
215 key_id: Option<String>,
216}
217
218#[derive(Debug, Clone)]
219pub struct Ed25519PublicKey {
220 pk: Edwards25519PublicKey,
221 key_id: Option<String>,
222}
223
224impl EdDSAKeyPairLike for Ed25519KeyPair {
225 fn jwt_alg_name() -> &'static str {
226 "EdDSA"
227 }
228
229 fn key_pair(&self) -> &Edwards25519KeyPair {
230 &self.key_pair
231 }
232
233 fn key_id(&self) -> &Option<String> {
234 &self.key_id
235 }
236
237 fn metadata(&self) -> &Option<KeyMetadata> {
238 &self.key_pair.metadata
239 }
240
241 fn attach_metadata(&mut self, metadata: KeyMetadata) -> Result<(), Error> {
242 self.key_pair.metadata = Some(metadata);
243 Ok(())
244 }
245}
246
247impl Ed25519KeyPair {
248 pub fn from_bytes(raw: &[u8]) -> Result<Self, Error> {
249 Ok(Ed25519KeyPair {
250 key_pair: Edwards25519KeyPair::from_bytes(raw)?,
251 key_id: None,
252 })
253 }
254
255 pub fn from_der(der: &[u8]) -> Result<Self, Error> {
256 Ok(Ed25519KeyPair {
257 key_pair: Edwards25519KeyPair::from_der(der)?,
258 key_id: None,
259 })
260 }
261
262 pub fn from_pem(pem: &str) -> Result<Self, Error> {
263 Ok(Ed25519KeyPair {
264 key_pair: Edwards25519KeyPair::from_pem(pem)?,
265 key_id: None,
266 })
267 }
268
269 pub fn to_bytes(&self) -> Vec<u8> {
270 self.key_pair.to_bytes()
271 }
272
273 pub fn to_der(&self) -> Vec<u8> {
274 self.key_pair.to_der()
275 }
276
277 pub fn to_pem(&self) -> String {
278 self.key_pair.to_pem()
279 }
280
281 pub fn public_key(&self) -> Ed25519PublicKey {
282 Ed25519PublicKey {
283 pk: self.key_pair.public_key(),
284 key_id: self.key_id.clone(),
285 }
286 }
287
288 pub fn generate() -> Self {
289 Ed25519KeyPair {
290 key_pair: Edwards25519KeyPair::generate(),
291 key_id: None,
292 }
293 }
294
295 pub fn with_key_id(mut self, key_id: &str) -> Self {
296 self.key_id = Some(key_id.to_string());
297 self
298 }
299}
300
301impl EdDSAPublicKeyLike for Ed25519PublicKey {
302 fn jwt_alg_name() -> &'static str {
303 "EdDSA"
304 }
305
306 fn public_key(&self) -> &Edwards25519PublicKey {
307 &self.pk
308 }
309
310 fn key_id(&self) -> &Option<String> {
311 &self.key_id
312 }
313
314 fn set_key_id(&mut self, key_id: String) {
315 self.key_id = Some(key_id);
316 }
317}
318
319impl Ed25519PublicKey {
320 pub fn from_bytes(raw: &[u8]) -> Result<Self, Error> {
321 Ok(Ed25519PublicKey {
322 pk: Edwards25519PublicKey::from_bytes(raw)?,
323 key_id: None,
324 })
325 }
326
327 pub fn from_der(der: &[u8]) -> Result<Self, Error> {
328 Ok(Ed25519PublicKey {
329 pk: Edwards25519PublicKey::from_der(der)?,
330 key_id: None,
331 })
332 }
333
334 pub fn from_pem(pem: &str) -> Result<Self, Error> {
335 Ok(Ed25519PublicKey {
336 pk: Edwards25519PublicKey::from_pem(pem)?,
337 key_id: None,
338 })
339 }
340
341 pub fn to_bytes(&self) -> Vec<u8> {
342 self.pk.to_bytes()
343 }
344
345 pub fn to_der(&self) -> Vec<u8> {
346 self.pk.to_der()
347 }
348
349 pub fn to_pem(&self) -> String {
350 self.pk.to_pem()
351 }
352
353 pub fn with_key_id(mut self, key_id: &str) -> Self {
354 self.key_id = Some(key_id.to_string());
355 self
356 }
357
358 pub fn sha1_thumbprint(&self) -> String {
359 Base64UrlSafeNoPadding::encode_to_string(SHA1::hash(&self.pk.to_der())).unwrap()
360 }
361
362 pub fn sha256_thumbprint(&self) -> String {
363 Base64UrlSafeNoPadding::encode_to_string(SHA256::hash(&self.pk.to_der())).unwrap()
364 }
365}