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 #[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}