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::algorithms::jwk::{
10 decode_secret, ec_export, ec_point, ec_point_matches, ec_thumbprint, Jwk, JwkDescriptor,
11 KeyRole, KeyType,
12};
13use crate::claims::*;
14use crate::common::*;
15#[cfg(feature = "cwt")]
16use crate::cwt_token::*;
17use crate::error::*;
18use crate::jwt_header::*;
19use crate::token::*;
20
21const ES256K_PUBLIC_JWK: JwkDescriptor = JwkDescriptor::new(
22 KeyType::Ec,
23 Some("secp256k1"),
24 "ES256K",
25 KeyRole::SignaturePublic,
26);
27const ES256K_PRIVATE_JWK: JwkDescriptor = ES256K_PUBLIC_JWK.with_role(KeyRole::SignaturePrivate);
28
29#[doc(hidden)]
30#[derive(Debug, Clone)]
31pub struct K256PublicKey(ecdsa::VerifyingKey);
32
33impl AsRef<ecdsa::VerifyingKey> for K256PublicKey {
34 fn as_ref(&self) -> &ecdsa::VerifyingKey {
35 &self.0
36 }
37}
38
39impl K256PublicKey {
40 pub(crate) fn from_jwk(jwk: &str) -> Result<(Self, Option<String>), Error> {
41 let jwk = Jwk::parse(jwk, &ES256K_PUBLIC_JWK)?;
42 let point = ec_point(&jwk, 32).ok_or(JWTError::InvalidPublicKey)?;
43 let pk = Self::from_bytes(&point)?;
44 Ok((pk, jwk.kid().map(Into::into)))
45 }
46
47 pub(crate) fn to_jwk(&self, key_id: Option<&str>) -> String {
48 ec_export(
49 &ES256K_PUBLIC_JWK,
50 &self.to_bytes_uncompressed(),
51 None,
52 key_id,
53 )
54 }
55
56 pub(crate) fn jwk_thumbprint(&self) -> String {
57 ec_thumbprint("secp256k1", &self.to_bytes_uncompressed())
58 }
59
60 pub fn from_bytes(raw: &[u8]) -> Result<Self, Error> {
61 let k256_pk =
62 ecdsa::VerifyingKey::from_sec1_bytes(raw).map_err(|_| JWTError::InvalidPublicKey)?;
63 Ok(K256PublicKey(k256_pk))
64 }
65
66 pub fn from_der(der: &[u8]) -> Result<Self, Error> {
67 let k256_pk = ecdsa::VerifyingKey::from_public_key_der(der)
68 .map_err(|_| JWTError::InvalidPublicKey)?;
69 Ok(K256PublicKey(k256_pk))
70 }
71
72 pub fn from_pem(pem: &str) -> Result<Self, Error> {
73 let k256_pk = ecdsa::VerifyingKey::from_public_key_pem(pem)
74 .map_err(|_| JWTError::InvalidPublicKey)?;
75 Ok(K256PublicKey(k256_pk))
76 }
77
78 pub fn to_bytes(&self) -> Vec<u8> {
79 self.0.to_sec1_point(false).as_bytes().to_vec()
80 }
81
82 pub fn to_bytes_uncompressed(&self) -> Vec<u8> {
83 self.0.to_sec1_point(false).as_bytes().to_vec()
84 }
85
86 pub fn to_der(&self) -> Result<Vec<u8>, Error> {
87 let k256_pk = k256::PublicKey::from(self.0);
88 Ok(k256_pk
89 .to_public_key_der()
90 .map_err(|_| JWTError::InvalidPublicKey)?
91 .as_ref()
92 .to_vec())
93 }
94
95 pub fn to_pem(&self) -> Result<String, Error> {
96 let k256_pk = k256::PublicKey::from(self.0);
97 Ok(k256_pk
98 .to_public_key_pem(Default::default())
99 .map_err(|_| JWTError::InvalidPublicKey)?)
100 }
101}
102
103#[doc(hidden)]
104pub struct K256KeyPair {
105 k256_sk: ecdsa::SigningKey,
106 metadata: Option<KeyMetadata>,
107}
108
109impl std::fmt::Debug for K256KeyPair {
110 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
111 write!(f, "EcKey")
112 }
113}
114
115impl AsRef<ecdsa::SigningKey> for K256KeyPair {
116 fn as_ref(&self) -> &ecdsa::SigningKey {
117 &self.k256_sk
118 }
119}
120
121impl K256KeyPair {
122 pub(crate) fn from_jwk(jwk: &str) -> Result<(Self, Option<String>), Error> {
123 let jwk = Jwk::parse(jwk, &ES256K_PRIVATE_JWK)?;
124 let d = decode_secret(jwk.d(), 32).ok_or(JWTError::InvalidKeyPair)?;
125 let key_pair = Self::from_bytes(&d)?;
126 ensure!(
127 ec_point_matches(&jwk, &key_pair.public_key().to_bytes_uncompressed()),
128 JWTError::InvalidKeyPair
129 );
130 Ok((key_pair, jwk.kid().map(Into::into)))
131 }
132
133 pub(crate) fn to_jwk(&self, key_id: Option<&str>) -> String {
134 let point = self.public_key().to_bytes_uncompressed();
135 let d = zeroize::Zeroizing::new(self.k256_sk.to_bytes().to_vec());
136 ec_export(&ES256K_PRIVATE_JWK, &point, Some(&d), key_id)
137 }
138
139 pub fn from_bytes(raw: &[u8]) -> Result<Self, Error> {
140 let raw: &k256::FieldBytes = raw.try_into().map_err(|_| JWTError::InvalidKeyPair)?;
141 let k256_sk = ecdsa::SigningKey::from_bytes(raw).map_err(|_| JWTError::InvalidKeyPair)?;
142 Ok(K256KeyPair {
143 k256_sk,
144 metadata: None,
145 })
146 }
147
148 pub fn from_der(der: &[u8]) -> Result<Self, Error> {
149 let k256_sk =
150 ecdsa::SigningKey::from_pkcs8_der(der).map_err(|_| JWTError::InvalidKeyPair)?;
151 Ok(K256KeyPair {
152 k256_sk,
153 metadata: None,
154 })
155 }
156
157 pub fn from_pem(pem: &str) -> Result<Self, Error> {
158 let k256_sk =
159 ecdsa::SigningKey::from_pkcs8_pem(pem).map_err(|_| JWTError::InvalidKeyPair)?;
160 Ok(K256KeyPair {
161 k256_sk,
162 metadata: None,
163 })
164 }
165
166 pub fn to_bytes(&self) -> Vec<u8> {
167 self.k256_sk.to_bytes().to_vec()
168 }
169
170 pub fn to_der(&self) -> Result<Vec<u8>, Error> {
171 let k256_sk = k256::SecretKey::from(&self.k256_sk);
172 Ok(k256_sk
173 .to_pkcs8_der()
174 .map_err(|_| JWTError::InvalidKeyPair)?
175 .as_bytes()
176 .to_vec())
177 }
178
179 pub fn to_pem(&self) -> Result<String, Error> {
180 let k256_sk = k256::SecretKey::from(&self.k256_sk);
181 Ok(k256_sk
182 .to_pkcs8_pem(Default::default())
183 .map_err(|_| JWTError::InvalidKeyPair)?
184 .to_string())
185 }
186
187 pub fn public_key(&self) -> K256PublicKey {
188 let k256_pk = self.k256_sk.verifying_key();
189 K256PublicKey(*k256_pk)
190 }
191
192 pub fn generate() -> Self {
193 let mut rng = rand::rng();
194 let k256_sk = ecdsa::SigningKey::generate_from_rng(&mut rng);
195 K256KeyPair {
196 k256_sk,
197 metadata: None,
198 }
199 }
200}
201
202pub trait ECDSAP256kKeyPairLike {
203 fn jwt_alg_name() -> &'static str;
204 fn key_pair(&self) -> &K256KeyPair;
205 fn key_id(&self) -> &Option<String>;
206 fn metadata(&self) -> &Option<KeyMetadata>;
207 fn attach_metadata(&mut self, metadata: KeyMetadata) -> Result<(), Error>;
208
209 fn sign<CustomClaims: Serialize>(
210 &self,
211 claims: JWTClaims<CustomClaims>,
212 ) -> Result<String, Error> {
213 self.sign_with_options(claims, &Default::default())
214 }
215
216 fn sign_with_options<CustomClaims: Serialize>(
217 &self,
218 claims: JWTClaims<CustomClaims>,
219 opts: &HeaderOptions,
220 ) -> Result<String, Error> {
221 let jwt_header = JWTHeader::new(Self::jwt_alg_name().to_string(), self.key_id().clone())
222 .with_key_metadata(self.metadata())
223 .with_options(opts);
224 Token::build(&jwt_header, claims, |authenticated| {
225 let mut rng = rand::rng();
226 let signature: ecdsa::Signature = self
227 .key_pair()
228 .as_ref()
229 .sign_digest_with_rng(&mut rng, |digest: &mut hmac_sha256::Hash| {
230 digest.update(authenticated.as_bytes())
231 });
232 Ok(signature.to_vec())
233 })
234 }
235}
236
237pub trait ECDSAP256kPublicKeyLike {
238 fn jwt_alg_name() -> &'static str;
239 fn public_key(&self) -> &K256PublicKey;
240 fn key_id(&self) -> &Option<String>;
241 fn set_key_id(&mut self, key_id: String);
242
243 fn verify_token<CustomClaims: DeserializeOwned>(
244 &self,
245 token: &str,
246 options: Option<VerificationOptions>,
247 ) -> Result<JWTClaims<CustomClaims>, Error> {
248 Token::verify(
249 Self::jwt_alg_name(),
250 token,
251 options,
252 |authenticated, signature| {
253 let ecdsa_signature = ecdsa::Signature::try_from(signature)
254 .map_err(|_| JWTError::InvalidSignature)?;
255 self.public_key()
256 .as_ref()
257 .verify_digest(
258 |digest: &mut hmac_sha256::Hash| {
259 digest.update(authenticated.as_bytes());
260 Ok(())
261 },
262 &ecdsa_signature,
263 )
264 .map_err(|_| JWTError::InvalidSignature)?;
265 Ok(())
266 },
267 |_salt: Option<&[u8]>| Ok(()),
268 )
269 }
270
271 #[cfg(feature = "cwt")]
272 fn verify_cwt_token<CustomClaims: DeserializeOwned>(
273 &self,
274 token: &[u8],
275 options: Option<VerificationOptions>,
276 ) -> Result<JWTClaims<NoCustomClaims>, Error> {
277 CWTToken::verify(
278 Self::jwt_alg_name(),
279 token,
280 options,
281 |authenticated, signature| {
282 let ecdsa_signature = ecdsa::Signature::try_from(signature)
283 .map_err(|_| JWTError::InvalidSignature)?;
284 self.public_key()
285 .as_ref()
286 .verify_digest(
287 |digest: &mut hmac_sha256::Hash| {
288 digest.update(authenticated.as_bytes());
289 Ok(())
290 },
291 &ecdsa_signature,
292 )
293 .map_err(|_| JWTError::InvalidSignature)?;
294 Ok(())
295 },
296 )
297 }
298
299 #[cfg(feature = "cwt")]
301 fn decode_cwt_metadata(&self, token: impl AsRef<[u8]>) -> Result<TokenMetadata, Error> {
302 CWTToken::decode_metadata(token)
303 }
304
305 fn create_key_id(&mut self) -> &str {
306 self.set_key_id(
307 Base64UrlSafeNoPadding::encode_to_string(hmac_sha256::Hash::hash(
308 &self.public_key().to_bytes(),
309 ))
310 .unwrap(),
311 );
312 self.key_id().as_ref().map(|x| x.as_str()).unwrap()
313 }
314}
315
316pub struct ES256kKeyPair {
317 key_pair: K256KeyPair,
318 key_id: Option<String>,
319}
320
321impl std::fmt::Debug for ES256kKeyPair {
322 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
323 write!(f, "EcKey")
324 }
325}
326
327#[derive(Debug, Clone)]
328pub struct ES256kPublicKey {
329 pk: K256PublicKey,
330 key_id: Option<String>,
331}
332
333impl ECDSAP256kKeyPairLike for ES256kKeyPair {
334 fn jwt_alg_name() -> &'static str {
335 "ES256K"
336 }
337
338 fn key_pair(&self) -> &K256KeyPair {
339 &self.key_pair
340 }
341
342 fn key_id(&self) -> &Option<String> {
343 &self.key_id
344 }
345
346 fn metadata(&self) -> &Option<KeyMetadata> {
347 &self.key_pair.metadata
348 }
349
350 fn attach_metadata(&mut self, metadata: KeyMetadata) -> Result<(), Error> {
351 self.key_pair.metadata = Some(metadata);
352 Ok(())
353 }
354}
355
356impl ES256kKeyPair {
357 pub fn from_bytes(raw: &[u8]) -> Result<Self, Error> {
358 Ok(ES256kKeyPair {
359 key_pair: K256KeyPair::from_bytes(raw)?,
360 key_id: None,
361 })
362 }
363
364 pub fn from_der(der: &[u8]) -> Result<Self, Error> {
365 Ok(ES256kKeyPair {
366 key_pair: K256KeyPair::from_der(der)?,
367 key_id: None,
368 })
369 }
370
371 pub fn from_pem(pem: &str) -> Result<Self, Error> {
372 Ok(ES256kKeyPair {
373 key_pair: K256KeyPair::from_pem(pem)?,
374 key_id: None,
375 })
376 }
377
378 pub fn to_bytes(&self) -> Vec<u8> {
379 self.key_pair.to_bytes()
380 }
381
382 pub fn to_der(&self) -> Result<Vec<u8>, Error> {
383 self.key_pair.to_der()
384 }
385
386 pub fn to_pem(&self) -> Result<String, Error> {
387 self.key_pair.to_pem()
388 }
389
390 pub fn public_key(&self) -> ES256kPublicKey {
391 ES256kPublicKey {
392 pk: self.key_pair.public_key(),
393 key_id: self.key_id.clone(),
394 }
395 }
396
397 pub fn generate() -> Self {
398 ES256kKeyPair {
399 key_pair: K256KeyPair::generate(),
400 key_id: None,
401 }
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
409 pub fn from_jwk(jwk: &str) -> Result<Self, Error> {
413 let (key_pair, key_id) = K256KeyPair::from_jwk(jwk)?;
414 Ok(ES256kKeyPair { key_pair, key_id })
415 }
416
417 pub fn to_jwk(&self) -> String {
421 self.key_pair.to_jwk(self.key_id.as_deref())
422 }
423
424 pub fn jwk_thumbprint(&self) -> String {
426 self.key_pair.public_key().jwk_thumbprint()
427 }
428}
429
430impl ECDSAP256kPublicKeyLike for ES256kPublicKey {
431 fn jwt_alg_name() -> &'static str {
432 "ES256K"
433 }
434
435 fn public_key(&self) -> &K256PublicKey {
436 &self.pk
437 }
438
439 fn key_id(&self) -> &Option<String> {
440 &self.key_id
441 }
442
443 fn set_key_id(&mut self, key_id: String) {
444 self.key_id = Some(key_id);
445 }
446}
447
448impl ES256kPublicKey {
449 pub fn from_bytes(raw: &[u8]) -> Result<Self, Error> {
450 Ok(ES256kPublicKey {
451 pk: K256PublicKey::from_bytes(raw)?,
452 key_id: None,
453 })
454 }
455
456 pub fn from_der(der: &[u8]) -> Result<Self, Error> {
457 Ok(ES256kPublicKey {
458 pk: K256PublicKey::from_der(der)?,
459 key_id: None,
460 })
461 }
462
463 pub fn from_pem(pem: &str) -> Result<Self, Error> {
464 Ok(ES256kPublicKey {
465 pk: K256PublicKey::from_pem(pem)?,
466 key_id: None,
467 })
468 }
469
470 pub fn to_bytes(&self) -> Vec<u8> {
471 self.pk.to_bytes()
472 }
473
474 pub fn to_der(&self) -> Result<Vec<u8>, Error> {
475 self.pk.to_der()
476 }
477
478 pub fn to_pem(&self) -> Result<String, Error> {
479 self.pk.to_pem()
480 }
481
482 pub fn with_key_id(mut self, key_id: &str) -> Self {
483 self.key_id = Some(key_id.to_string());
484 self
485 }
486
487 pub fn from_jwk(jwk: &str) -> Result<Self, Error> {
491 let (pk, key_id) = K256PublicKey::from_jwk(jwk)?;
492 Ok(ES256kPublicKey { pk, key_id })
493 }
494
495 pub fn to_jwk(&self) -> String {
497 self.pk.to_jwk(self.key_id.as_deref())
498 }
499
500 pub fn jwk_thumbprint(&self) -> String {
502 self.pk.jwk_thumbprint()
503 }
504}