Skip to main content

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