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        self.sign_with_options(claims, &Default::default())
145    }
146
147    fn sign_with_options<CustomClaims: Serialize + DeserializeOwned>(
148        &self,
149        claims: JWTClaims<CustomClaims>,
150        opts: &HeaderOptions,
151    ) -> Result<String, Error> {
152        let jwt_header = JWTHeader::new(Self::jwt_alg_name().to_string(), self.key_id().clone())
153            .with_key_metadata(self.metadata())
154            .with_options(opts);
155        Token::build(&jwt_header, claims, |authenticated| {
156            let noise = ed25519_compact::Noise::generate();
157            let signature = self.key_pair().as_ref().sk.sign(authenticated, Some(noise));
158            Ok(signature.to_vec())
159        })
160    }
161}
162
163pub trait EdDSAPublicKeyLike {
164    fn jwt_alg_name() -> &'static str;
165    fn public_key(&self) -> &Edwards25519PublicKey;
166    fn key_id(&self) -> &Option<String>;
167    fn set_key_id(&mut self, key_id: String);
168
169    fn verify_token<CustomClaims: Serialize + DeserializeOwned>(
170        &self,
171        token: &str,
172        options: Option<VerificationOptions>,
173    ) -> Result<JWTClaims<CustomClaims>, Error> {
174        Token::verify(
175            Self::jwt_alg_name(),
176            token,
177            options,
178            |authenticated, signature| {
179                let ed25519_signature = ed25519_compact::Signature::from_slice(signature)?;
180                self.public_key()
181                    .as_ref()
182                    .verify(authenticated, &ed25519_signature)
183                    .map_err(|_| JWTError::InvalidSignature)?;
184                Ok(())
185            },
186            |_salt: Option<&[u8]>| Ok(()),
187        )
188    }
189
190    #[cfg(feature = "cwt")]
191    fn verify_cwt_token<CustomClaims: Serialize + DeserializeOwned>(
192        &self,
193        token: &[u8],
194        options: Option<VerificationOptions>,
195    ) -> Result<JWTClaims<NoCustomClaims>, Error> {
196        CWTToken::verify(
197            Self::jwt_alg_name(),
198            token,
199            options,
200            |authenticated, signature| {
201                let ed25519_signature = ed25519_compact::Signature::from_slice(signature)?;
202                self.public_key()
203                    .as_ref()
204                    .verify(authenticated, &ed25519_signature)
205                    .map_err(|_| JWTError::InvalidSignature)?;
206                Ok(())
207            },
208        )
209    }
210
211    /// Decode CWT token metadata that can be useful prior to signature/tag verification
212    #[cfg(feature = "cwt")]
213    fn decode_cwt_metadata(&self, token: impl AsRef<[u8]>) -> Result<TokenMetadata, Error> {
214        CWTToken::decode_metadata(token)
215    }
216
217    fn create_key_id(&mut self) -> &str {
218        self.set_key_id(
219            Base64UrlSafeNoPadding::encode_to_string(hmac_sha256::Hash::hash(
220                &self.public_key().to_bytes(),
221            ))
222            .unwrap(),
223        );
224        self.key_id().as_ref().map(|x| x.as_str()).unwrap()
225    }
226}
227
228#[derive(Clone)]
229pub struct Ed25519KeyPair {
230    key_pair: Edwards25519KeyPair,
231    key_id: Option<String>,
232}
233
234#[derive(Debug, Clone)]
235pub struct Ed25519PublicKey {
236    pk: Edwards25519PublicKey,
237    key_id: Option<String>,
238}
239
240impl EdDSAKeyPairLike for Ed25519KeyPair {
241    fn jwt_alg_name() -> &'static str {
242        "EdDSA"
243    }
244
245    fn key_pair(&self) -> &Edwards25519KeyPair {
246        &self.key_pair
247    }
248
249    fn key_id(&self) -> &Option<String> {
250        &self.key_id
251    }
252
253    fn metadata(&self) -> &Option<KeyMetadata> {
254        &self.key_pair.metadata
255    }
256
257    fn attach_metadata(&mut self, metadata: KeyMetadata) -> Result<(), Error> {
258        self.key_pair.metadata = Some(metadata);
259        Ok(())
260    }
261}
262
263impl Ed25519KeyPair {
264    pub fn from_bytes(raw: &[u8]) -> Result<Self, Error> {
265        Ok(Ed25519KeyPair {
266            key_pair: Edwards25519KeyPair::from_bytes(raw)?,
267            key_id: None,
268        })
269    }
270
271    pub fn from_der(der: &[u8]) -> Result<Self, Error> {
272        Ok(Ed25519KeyPair {
273            key_pair: Edwards25519KeyPair::from_der(der)?,
274            key_id: None,
275        })
276    }
277
278    pub fn from_pem(pem: &str) -> Result<Self, Error> {
279        Ok(Ed25519KeyPair {
280            key_pair: Edwards25519KeyPair::from_pem(pem)?,
281            key_id: None,
282        })
283    }
284
285    pub fn to_bytes(&self) -> Vec<u8> {
286        self.key_pair.to_bytes()
287    }
288
289    pub fn to_der(&self) -> Vec<u8> {
290        self.key_pair.to_der()
291    }
292
293    pub fn to_pem(&self) -> String {
294        self.key_pair.to_pem()
295    }
296
297    pub fn public_key(&self) -> Ed25519PublicKey {
298        Ed25519PublicKey {
299            pk: self.key_pair.public_key(),
300            key_id: self.key_id.clone(),
301        }
302    }
303
304    pub fn generate() -> Self {
305        Ed25519KeyPair {
306            key_pair: Edwards25519KeyPair::generate(),
307            key_id: None,
308        }
309    }
310
311    pub fn with_key_id(mut self, key_id: &str) -> Self {
312        self.key_id = Some(key_id.to_string());
313        self
314    }
315}
316
317impl EdDSAPublicKeyLike for Ed25519PublicKey {
318    fn jwt_alg_name() -> &'static str {
319        "EdDSA"
320    }
321
322    fn public_key(&self) -> &Edwards25519PublicKey {
323        &self.pk
324    }
325
326    fn key_id(&self) -> &Option<String> {
327        &self.key_id
328    }
329
330    fn set_key_id(&mut self, key_id: String) {
331        self.key_id = Some(key_id);
332    }
333}
334
335impl Ed25519PublicKey {
336    pub fn from_bytes(raw: &[u8]) -> Result<Self, Error> {
337        Ok(Ed25519PublicKey {
338            pk: Edwards25519PublicKey::from_bytes(raw)?,
339            key_id: None,
340        })
341    }
342
343    pub fn from_der(der: &[u8]) -> Result<Self, Error> {
344        Ok(Ed25519PublicKey {
345            pk: Edwards25519PublicKey::from_der(der)?,
346            key_id: None,
347        })
348    }
349
350    pub fn from_pem(pem: &str) -> Result<Self, Error> {
351        Ok(Ed25519PublicKey {
352            pk: Edwards25519PublicKey::from_pem(pem)?,
353            key_id: None,
354        })
355    }
356
357    pub fn to_bytes(&self) -> Vec<u8> {
358        self.pk.to_bytes()
359    }
360
361    pub fn to_der(&self) -> Vec<u8> {
362        self.pk.to_der()
363    }
364
365    pub fn to_pem(&self) -> String {
366        self.pk.to_pem()
367    }
368
369    pub fn with_key_id(mut self, key_id: &str) -> Self {
370        self.key_id = Some(key_id.to_string());
371        self
372    }
373
374    pub fn sha1_thumbprint(&self) -> String {
375        Base64UrlSafeNoPadding::encode_to_string(SHA1::hash(&self.pk.to_der())).unwrap()
376    }
377
378    pub fn sha256_thumbprint(&self) -> String {
379        Base64UrlSafeNoPadding::encode_to_string(SHA256::hash(&self.pk.to_der())).unwrap()
380    }
381}