Skip to main content

jwt_simple/algorithms/
es256k.rs

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