jwt_simple/algorithms/
es384.rs

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