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