Skip to main content

jwt_simple/algorithms/
es384.rs

1use std::convert::{TryFrom, TryInto};
2
3use ct_codecs::{Base64UrlSafeNoPadding, Encoder};
4use p384::ecdsa::{self, signature::DigestVerifier as _, signature::RandomizedDigestSigner as _};
5use p384::elliptic_curve::Generate as _;
6use p384::pkcs8::{DecodePrivateKey, DecodePublicKey, EncodePrivateKey, EncodePublicKey};
7use p384::NonZeroScalar;
8use serde::{de::DeserializeOwned, Serialize};
9
10use crate::claims::*;
11use crate::common::*;
12#[cfg(feature = "cwt")]
13use crate::cwt_token::*;
14use crate::error::*;
15use crate::jwt_header::*;
16use crate::token::*;
17
18#[doc(hidden)]
19#[derive(Debug, Clone)]
20pub struct P384PublicKey(ecdsa::VerifyingKey);
21
22impl AsRef<ecdsa::VerifyingKey> for P384PublicKey {
23    fn as_ref(&self) -> &ecdsa::VerifyingKey {
24        &self.0
25    }
26}
27
28impl P384PublicKey {
29    pub fn from_bytes(raw: &[u8]) -> Result<Self, Error> {
30        let p384_pk =
31            ecdsa::VerifyingKey::from_sec1_bytes(raw).map_err(|_| JWTError::InvalidPublicKey)?;
32        Ok(P384PublicKey(p384_pk))
33    }
34
35    pub fn from_der(der: &[u8]) -> Result<Self, Error> {
36        let p384_pk = ecdsa::VerifyingKey::from_public_key_der(der)
37            .map_err(|_| JWTError::InvalidPublicKey)?;
38        Ok(P384PublicKey(p384_pk))
39    }
40
41    pub fn from_pem(pem: &str) -> Result<Self, Error> {
42        let p384_pk = ecdsa::VerifyingKey::from_public_key_pem(pem)
43            .map_err(|_| JWTError::InvalidPublicKey)?;
44        Ok(P384PublicKey(p384_pk))
45    }
46
47    pub fn to_bytes(&self) -> Vec<u8> {
48        self.0.to_sec1_point(true).as_bytes().to_vec()
49    }
50
51    pub fn to_bytes_uncompressed(&self) -> Vec<u8> {
52        self.0.to_sec1_point(false).as_bytes().to_vec()
53    }
54
55    pub fn to_der(&self) -> Result<Vec<u8>, Error> {
56        let p384_pk = p384::PublicKey::from(self.0);
57        Ok(p384_pk
58            .to_public_key_der()
59            .map_err(|_| JWTError::InvalidPublicKey)?
60            .as_ref()
61            .to_vec())
62    }
63
64    pub fn to_pem(&self) -> Result<String, Error> {
65        let p384_pk = p384::PublicKey::from(self.0);
66        Ok(p384_pk
67            .to_public_key_pem(Default::default())
68            .map_err(|_| JWTError::InvalidPublicKey)?)
69    }
70}
71
72#[doc(hidden)]
73pub struct P384KeyPair {
74    p384_sk: ecdsa::SigningKey,
75    metadata: Option<KeyMetadata>,
76}
77
78impl std::fmt::Debug for P384KeyPair {
79    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
80        write!(f, "EcKey")
81    }
82}
83
84impl AsRef<ecdsa::SigningKey> for P384KeyPair {
85    fn as_ref(&self) -> &ecdsa::SigningKey {
86        &self.p384_sk
87    }
88}
89
90impl P384KeyPair {
91    pub fn from_bytes(raw: &[u8]) -> Result<Self, Error> {
92        let raw: &p384::FieldBytes = raw.try_into().map_err(|_| JWTError::InvalidKeyPair)?;
93        let p384_sk = ecdsa::SigningKey::from_bytes(raw).map_err(|_| JWTError::InvalidKeyPair)?;
94        Ok(P384KeyPair {
95            p384_sk,
96            metadata: None,
97        })
98    }
99
100    pub fn from_der(der: &[u8]) -> Result<Self, Error> {
101        let p384_sk =
102            ecdsa::SigningKey::from_pkcs8_der(der).map_err(|_| JWTError::InvalidKeyPair)?;
103        Ok(P384KeyPair {
104            p384_sk,
105            metadata: None,
106        })
107    }
108
109    pub fn from_pem(pem: &str) -> Result<Self, Error> {
110        let p384_sk =
111            ecdsa::SigningKey::from_pkcs8_pem(pem).map_err(|_| JWTError::InvalidKeyPair)?;
112        Ok(P384KeyPair {
113            p384_sk,
114            metadata: None,
115        })
116    }
117
118    pub fn to_bytes(&self) -> Vec<u8> {
119        self.p384_sk.to_bytes().to_vec()
120    }
121
122    pub fn to_der(&self) -> Result<Vec<u8>, Error> {
123        let scalar = NonZeroScalar::from_repr(self.p384_sk.to_bytes());
124        if bool::from(scalar.is_none()) {
125            return Err(JWTError::InvalidKeyPair.into());
126        }
127        let p384_sk =
128            p384::SecretKey::from(NonZeroScalar::from_repr(scalar.unwrap().into()).unwrap());
129        Ok(p384_sk
130            .to_pkcs8_der()
131            .map_err(|_| JWTError::InvalidKeyPair)?
132            .as_bytes()
133            .to_vec())
134    }
135
136    pub fn to_pem(&self) -> Result<String, Error> {
137        let scalar = NonZeroScalar::from_repr(self.p384_sk.to_bytes());
138        if bool::from(scalar.is_none()) {
139            return Err(JWTError::InvalidKeyPair.into());
140        }
141        let p384_sk =
142            p384::SecretKey::from(NonZeroScalar::from_repr(scalar.unwrap().into()).unwrap());
143        Ok(p384_sk
144            .to_pkcs8_pem(Default::default())
145            .map_err(|_| JWTError::InvalidKeyPair)?
146            .to_string())
147    }
148
149    pub fn public_key(&self) -> P384PublicKey {
150        let p384_sk = self.p384_sk.verifying_key();
151        P384PublicKey(*p384_sk)
152    }
153
154    pub fn generate() -> Self {
155        let mut rng = rand::rng();
156        let p384_sk = ecdsa::SigningKey::generate_from_rng(&mut rng);
157        P384KeyPair {
158            p384_sk,
159            metadata: None,
160        }
161    }
162}
163
164pub trait ECDSAP384KeyPairLike {
165    fn jwt_alg_name() -> &'static str;
166    fn key_pair(&self) -> &P384KeyPair;
167    fn key_id(&self) -> &Option<String>;
168    fn metadata(&self) -> &Option<KeyMetadata>;
169    fn attach_metadata(&mut self, metadata: KeyMetadata) -> Result<(), Error>;
170
171    fn sign<CustomClaims: Serialize>(
172        &self,
173        claims: JWTClaims<CustomClaims>,
174    ) -> Result<String, Error> {
175        self.sign_with_options(claims, &Default::default())
176    }
177
178    fn sign_with_options<CustomClaims: Serialize>(
179        &self,
180        claims: JWTClaims<CustomClaims>,
181        opts: &HeaderOptions,
182    ) -> Result<String, Error> {
183        let jwt_header = JWTHeader::new(Self::jwt_alg_name().to_string(), self.key_id().clone())
184            .with_key_metadata(self.metadata())
185            .with_options(opts);
186        Token::build(&jwt_header, claims, |authenticated| {
187            let mut rng = rand::rng();
188            let signature: ecdsa::Signature = self
189                .key_pair()
190                .as_ref()
191                .sign_digest_with_rng(&mut rng, |digest: &mut hmac_sha512::sha384::Hash| {
192                    digest.update(authenticated.as_bytes())
193                });
194            Ok(signature.to_vec())
195        })
196    }
197}
198
199pub trait ECDSAP384PublicKeyLike {
200    fn jwt_alg_name() -> &'static str;
201    fn public_key(&self) -> &P384PublicKey;
202    fn key_id(&self) -> &Option<String>;
203    fn set_key_id(&mut self, key_id: String);
204
205    fn verify_token<CustomClaims: DeserializeOwned>(
206        &self,
207        token: &str,
208        options: Option<VerificationOptions>,
209    ) -> Result<JWTClaims<CustomClaims>, Error> {
210        Token::verify(
211            Self::jwt_alg_name(),
212            token,
213            options,
214            |authenticated, signature| {
215                let ecdsa_signature = ecdsa::Signature::try_from(signature)
216                    .map_err(|_| JWTError::InvalidSignature)?;
217                self.public_key()
218                    .as_ref()
219                    .verify_digest(
220                        |digest: &mut hmac_sha512::sha384::Hash| {
221                            digest.update(authenticated.as_bytes());
222                            Ok(())
223                        },
224                        &ecdsa_signature,
225                    )
226                    .map_err(|_| JWTError::InvalidSignature)?;
227                Ok(())
228            },
229            |_salt: Option<&[u8]>| Ok(()),
230        )
231    }
232
233    #[cfg(feature = "cwt")]
234    fn verify_cwt_token<CustomClaims: DeserializeOwned>(
235        &self,
236        token: &str,
237        options: Option<VerificationOptions>,
238    ) -> Result<JWTClaims<NoCustomClaims>, Error> {
239        CWTToken::verify(
240            Self::jwt_alg_name(),
241            token,
242            options,
243            |authenticated, signature| {
244                let ecdsa_signature = ecdsa::Signature::try_from(signature)
245                    .map_err(|_| JWTError::InvalidSignature)?;
246                self.public_key()
247                    .as_ref()
248                    .verify_digest(
249                        |digest: &mut hmac_sha512::sha384::Hash| {
250                            digest.update(authenticated.as_bytes());
251                            Ok(())
252                        },
253                        &ecdsa_signature,
254                    )
255                    .map_err(|_| JWTError::InvalidSignature)?;
256                Ok(())
257            },
258        )
259    }
260
261    /// Decode CWT token metadata that can be useful prior to signature/tag verification
262    #[cfg(feature = "cwt")]
263    fn decode_cwt_metadata(&self, token: impl AsRef<[u8]>) -> Result<TokenMetadata, Error> {
264        CWTToken::decode_metadata(token)
265    }
266
267    fn create_key_id(&mut self) -> &str {
268        self.set_key_id(
269            Base64UrlSafeNoPadding::encode_to_string(hmac_sha256::Hash::hash(
270                &self.public_key().to_bytes(),
271            ))
272            .unwrap(),
273        );
274        self.key_id().as_ref().map(|x| x.as_str()).unwrap()
275    }
276}
277
278pub struct ES384KeyPair {
279    key_pair: P384KeyPair,
280    key_id: Option<String>,
281}
282
283impl std::fmt::Debug for ES384KeyPair {
284    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
285        write!(f, "EcKey")
286    }
287}
288
289#[derive(Debug, Clone)]
290pub struct ES384PublicKey {
291    pk: P384PublicKey,
292    key_id: Option<String>,
293}
294
295impl ECDSAP384KeyPairLike for ES384KeyPair {
296    fn jwt_alg_name() -> &'static str {
297        "ES384"
298    }
299
300    fn key_pair(&self) -> &P384KeyPair {
301        &self.key_pair
302    }
303
304    fn key_id(&self) -> &Option<String> {
305        &self.key_id
306    }
307
308    fn metadata(&self) -> &Option<KeyMetadata> {
309        &self.key_pair.metadata
310    }
311
312    fn attach_metadata(&mut self, metadata: KeyMetadata) -> Result<(), Error> {
313        self.key_pair.metadata = Some(metadata);
314        Ok(())
315    }
316}
317
318impl ES384KeyPair {
319    pub fn from_bytes(raw: &[u8]) -> Result<Self, Error> {
320        Ok(ES384KeyPair {
321            key_pair: P384KeyPair::from_bytes(raw)?,
322            key_id: None,
323        })
324    }
325
326    pub fn from_der(der: &[u8]) -> Result<Self, Error> {
327        Ok(ES384KeyPair {
328            key_pair: P384KeyPair::from_der(der)?,
329            key_id: None,
330        })
331    }
332
333    pub fn from_pem(pem: &str) -> Result<Self, Error> {
334        Ok(ES384KeyPair {
335            key_pair: P384KeyPair::from_pem(pem)?,
336            key_id: None,
337        })
338    }
339
340    pub fn to_bytes(&self) -> Vec<u8> {
341        self.key_pair.to_bytes()
342    }
343
344    pub fn to_der(&self) -> Result<Vec<u8>, Error> {
345        self.key_pair.to_der()
346    }
347
348    pub fn to_pem(&self) -> Result<String, Error> {
349        self.key_pair.to_pem()
350    }
351
352    pub fn public_key(&self) -> ES384PublicKey {
353        ES384PublicKey {
354            pk: self.key_pair.public_key(),
355            key_id: self.key_id.clone(),
356        }
357    }
358
359    pub fn generate() -> Self {
360        ES384KeyPair {
361            key_pair: P384KeyPair::generate(),
362            key_id: None,
363        }
364    }
365
366    pub fn with_key_id(mut self, key_id: &str) -> Self {
367        self.key_id = Some(key_id.to_string());
368        self
369    }
370}
371
372impl ECDSAP384PublicKeyLike for ES384PublicKey {
373    fn jwt_alg_name() -> &'static str {
374        "ES384"
375    }
376
377    fn public_key(&self) -> &P384PublicKey {
378        &self.pk
379    }
380
381    fn key_id(&self) -> &Option<String> {
382        &self.key_id
383    }
384
385    fn set_key_id(&mut self, key_id: String) {
386        self.key_id = Some(key_id);
387    }
388}
389
390impl ES384PublicKey {
391    pub fn from_bytes(raw: &[u8]) -> Result<Self, Error> {
392        Ok(ES384PublicKey {
393            pk: P384PublicKey::from_bytes(raw)?,
394            key_id: None,
395        })
396    }
397
398    pub fn from_der(der: &[u8]) -> Result<Self, Error> {
399        Ok(ES384PublicKey {
400            pk: P384PublicKey::from_der(der)?,
401            key_id: None,
402        })
403    }
404
405    pub fn from_pem(pem: &str) -> Result<Self, Error> {
406        Ok(ES384PublicKey {
407            pk: P384PublicKey::from_pem(pem)?,
408            key_id: None,
409        })
410    }
411
412    pub fn to_bytes(&self) -> Vec<u8> {
413        self.pk.to_bytes()
414    }
415
416    pub fn to_der(&self) -> Result<Vec<u8>, Error> {
417        self.pk.to_der()
418    }
419
420    pub fn to_pem(&self) -> Result<String, Error> {
421        self.pk.to_pem()
422    }
423
424    pub fn with_key_id(mut self, key_id: &str) -> Self {
425        self.key_id = Some(key_id.to_string());
426        self
427    }
428}