jwt_simple/algorithms/
es256.rs

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