jwt_simple/algorithms/
eddsa.rs

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}