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