Skip to main content

jwt_simple/algorithms/
es256k.rs

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