keygate_jwt/algorithms/
es384.rs

1use std::convert::TryFrom;
2
3use base64ct::{Base64UrlUnpadded, Encoding};
4use p384::ecdsa::{self, signature::DigestVerifier as _, signature::RandomizedDigestSigner as _};
5use p384::pkcs8::{DecodePrivateKey, DecodePublicKey, EncodePrivateKey, EncodePublicKey};
6use p384::NonZeroScalar;
7use serde::{de::DeserializeOwned, Serialize};
8use sha2::{Digest, Sha384};
9
10use crate::claims::*;
11use crate::common::*;
12use crate::error::*;
13use crate::jwt_header::*;
14use crate::token::*;
15
16#[doc(hidden)]
17#[derive(Debug, Clone)]
18pub struct P384PublicKey(ecdsa::VerifyingKey);
19
20impl AsRef<ecdsa::VerifyingKey> for P384PublicKey {
21    fn as_ref(&self) -> &ecdsa::VerifyingKey {
22        &self.0
23    }
24}
25
26impl P384PublicKey {
27    pub fn from_bytes(raw: &[u8]) -> Result<Self, JWTError> {
28        let p384_pk =
29            ecdsa::VerifyingKey::from_sec1_bytes(raw).map_err(|_| JWTError::InvalidPublicKey)?;
30        Ok(P384PublicKey(p384_pk))
31    }
32
33    pub fn from_der(der: &[u8]) -> Result<Self, JWTError> {
34        let p384_pk = ecdsa::VerifyingKey::from_public_key_der(der)
35            .map_err(|_| JWTError::InvalidPublicKey)?;
36        Ok(P384PublicKey(p384_pk))
37    }
38
39    pub fn from_pem(pem: &str) -> Result<Self, JWTError> {
40        let p384_pk = ecdsa::VerifyingKey::from_public_key_pem(pem)
41            .map_err(|_| JWTError::InvalidPublicKey)?;
42        Ok(P384PublicKey(p384_pk))
43    }
44
45    pub fn to_bytes(&self) -> Vec<u8> {
46        self.0.to_encoded_point(true).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>, JWTError> {
54        let p384_pk = p384::PublicKey::from(self.0);
55        Ok(p384_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, JWTError> {
63        let p384_pk = p384::PublicKey::from(self.0);
64        p384_pk
65            .to_public_key_pem(Default::default())
66            .map_err(|_| JWTError::InvalidPublicKey)
67    }
68}
69
70#[doc(hidden)]
71pub struct P384KeyPair {
72    p384_sk: ecdsa::SigningKey,
73    metadata: Option<KeyMetadata>,
74}
75
76impl AsRef<ecdsa::SigningKey> for P384KeyPair {
77    fn as_ref(&self) -> &ecdsa::SigningKey {
78        &self.p384_sk
79    }
80}
81
82impl P384KeyPair {
83    pub fn from_bytes(raw: &[u8]) -> Result<Self, JWTError> {
84        let p384_sk =
85            ecdsa::SigningKey::from_bytes(raw.into()).map_err(|_| JWTError::InvalidKeyPair)?;
86        Ok(P384KeyPair {
87            p384_sk,
88            metadata: None,
89        })
90    }
91
92    pub fn from_der(der: &[u8]) -> Result<Self, JWTError> {
93        let p384_sk =
94            ecdsa::SigningKey::from_pkcs8_der(der).map_err(|_| JWTError::InvalidKeyPair)?;
95        Ok(P384KeyPair {
96            p384_sk,
97            metadata: None,
98        })
99    }
100
101    pub fn from_pem(pem: &str) -> Result<Self, JWTError> {
102        let p384_sk =
103            ecdsa::SigningKey::from_pkcs8_pem(pem).map_err(|_| JWTError::InvalidKeyPair)?;
104        Ok(P384KeyPair {
105            p384_sk,
106            metadata: None,
107        })
108    }
109
110    pub fn to_bytes(&self) -> Vec<u8> {
111        self.p384_sk.to_bytes().to_vec()
112    }
113
114    pub fn to_der(&self) -> Result<Vec<u8>, JWTError> {
115        let scalar = NonZeroScalar::from_repr(self.p384_sk.to_bytes());
116        if bool::from(scalar.is_none()) {
117            return Err(JWTError::InvalidKeyPair);
118        }
119        let p384_sk =
120            p384::SecretKey::from(NonZeroScalar::from_repr(scalar.unwrap().into()).unwrap());
121        Ok(p384_sk
122            .to_pkcs8_der()
123            .map_err(|_| JWTError::InvalidKeyPair)?
124            .as_bytes()
125            .to_vec())
126    }
127
128    pub fn to_pem(&self) -> Result<String, JWTError> {
129        let scalar = NonZeroScalar::from_repr(self.p384_sk.to_bytes());
130        if bool::from(scalar.is_none()) {
131            return Err(JWTError::InvalidKeyPair);
132        }
133        let p384_sk =
134            p384::SecretKey::from(NonZeroScalar::from_repr(scalar.unwrap().into()).unwrap());
135        Ok(p384_sk
136            .to_pkcs8_pem(Default::default())
137            .map_err(|_| JWTError::InvalidKeyPair)?
138            .to_string())
139    }
140
141    pub fn public_key(&self) -> P384PublicKey {
142        let p384_sk = self.p384_sk.verifying_key();
143        P384PublicKey(*p384_sk)
144    }
145
146    pub fn generate() -> Self {
147        let mut rng = rand::thread_rng();
148        let p384_sk = ecdsa::SigningKey::random(&mut rng);
149        P384KeyPair {
150            p384_sk,
151            metadata: None,
152        }
153    }
154}
155
156pub trait ECDSAP384KeyPairLike {
157    fn jwt_alg_name() -> &'static str;
158    fn key_pair(&self) -> &P384KeyPair;
159    fn key_id(&self) -> &Option<String>;
160    fn metadata(&self) -> &Option<KeyMetadata>;
161    fn attach_metadata(&mut self, metadata: KeyMetadata) -> Result<(), JWTError>;
162
163    fn sign<CustomClaims: Serialize + DeserializeOwned>(
164        &self,
165        claims: JWTClaims<CustomClaims>,
166    ) -> Result<String, JWTError> {
167        let jwt_header = JWTHeader::new(Self::jwt_alg_name().to_string(), self.key_id().clone())
168            .with_metadata(self.metadata());
169        Token::build(&jwt_header, claims, |authenticated| {
170            let mut digest = Sha384::new();
171            digest.update(authenticated.as_bytes());
172            let mut rng = rand::thread_rng();
173            let signature: ecdsa::Signature = self
174                .key_pair()
175                .as_ref()
176                .sign_digest_with_rng(&mut rng, digest);
177            Ok(signature.to_vec())
178        })
179    }
180}
181
182pub trait ECDSAP384PublicKeyLike {
183    fn jwt_alg_name() -> &'static str;
184    fn public_key(&self) -> &P384PublicKey;
185    fn key_id(&self) -> &Option<String>;
186    fn set_key_id(&mut self, key_id: String);
187
188    fn verify_token<CustomClaims: Serialize + DeserializeOwned>(
189        &self,
190        token: &str,
191        options: Option<VerificationOptions>,
192    ) -> Result<JWTClaims<CustomClaims>, JWTError> {
193        Token::verify(
194            Self::jwt_alg_name(),
195            token,
196            options,
197            |authenticated, signature| {
198                let ecdsa_signature = ecdsa::Signature::try_from(signature)
199                    .map_err(|_| JWTError::InvalidSignature)?;
200                let mut digest = Sha384::new();
201                digest.update(authenticated.as_bytes());
202                self.public_key()
203                    .as_ref()
204                    .verify_digest(digest, &ecdsa_signature)
205                    .map_err(|_| JWTError::InvalidSignature)?;
206                Ok(())
207            },
208        )
209    }
210
211    fn create_key_id(&mut self) -> Result<String, JWTError> {
212        let mut hasher = sha2::Sha256::new();
213        hasher.update(self.public_key().to_bytes());
214        let key_id = Base64UrlUnpadded::encode_string(&hasher.finalize());
215        self.set_key_id(key_id.clone());
216        Ok(key_id)
217    }
218}
219
220pub struct ES384KeyPair {
221    key_pair: P384KeyPair,
222    key_id: Option<String>,
223}
224
225#[derive(Debug, Clone)]
226pub struct ES384PublicKey {
227    pk: P384PublicKey,
228    key_id: Option<String>,
229}
230
231impl ECDSAP384KeyPairLike for ES384KeyPair {
232    fn jwt_alg_name() -> &'static str {
233        "ES384"
234    }
235
236    fn key_pair(&self) -> &P384KeyPair {
237        &self.key_pair
238    }
239
240    fn key_id(&self) -> &Option<String> {
241        &self.key_id
242    }
243
244    fn metadata(&self) -> &Option<KeyMetadata> {
245        &self.key_pair.metadata
246    }
247
248    fn attach_metadata(&mut self, metadata: KeyMetadata) -> Result<(), JWTError> {
249        self.key_pair.metadata = Some(metadata);
250        Ok(())
251    }
252}
253
254impl ES384KeyPair {
255    pub fn from_bytes(raw: &[u8]) -> Result<Self, JWTError> {
256        Ok(ES384KeyPair {
257            key_pair: P384KeyPair::from_bytes(raw)?,
258            key_id: None,
259        })
260    }
261
262    pub fn from_der(der: &[u8]) -> Result<Self, JWTError> {
263        Ok(ES384KeyPair {
264            key_pair: P384KeyPair::from_der(der)?,
265            key_id: None,
266        })
267    }
268
269    pub fn from_pem(pem: &str) -> Result<Self, JWTError> {
270        Ok(ES384KeyPair {
271            key_pair: P384KeyPair::from_pem(pem)?,
272            key_id: None,
273        })
274    }
275
276    pub fn to_bytes(&self) -> Vec<u8> {
277        self.key_pair.to_bytes()
278    }
279
280    pub fn to_der(&self) -> Result<Vec<u8>, JWTError> {
281        self.key_pair.to_der()
282    }
283
284    pub fn to_pem(&self) -> Result<String, JWTError> {
285        self.key_pair.to_pem()
286    }
287
288    pub fn public_key(&self) -> ES384PublicKey {
289        ES384PublicKey {
290            pk: self.key_pair.public_key(),
291            key_id: self.key_id.clone(),
292        }
293    }
294
295    pub fn generate() -> Self {
296        ES384KeyPair {
297            key_pair: P384KeyPair::generate(),
298            key_id: None,
299        }
300    }
301
302    pub fn with_key_id(mut self, key_id: &str) -> Self {
303        self.key_id = Some(key_id.to_string());
304        self
305    }
306}
307
308impl ECDSAP384PublicKeyLike for ES384PublicKey {
309    fn jwt_alg_name() -> &'static str {
310        "ES384"
311    }
312
313    fn public_key(&self) -> &P384PublicKey {
314        &self.pk
315    }
316
317    fn key_id(&self) -> &Option<String> {
318        &self.key_id
319    }
320
321    fn set_key_id(&mut self, key_id: String) {
322        self.key_id = Some(key_id);
323    }
324}
325
326impl ES384PublicKey {
327    pub fn from_bytes(raw: &[u8]) -> Result<Self, JWTError> {
328        Ok(ES384PublicKey {
329            pk: P384PublicKey::from_bytes(raw)?,
330            key_id: None,
331        })
332    }
333
334    pub fn from_der(der: &[u8]) -> Result<Self, JWTError> {
335        Ok(ES384PublicKey {
336            pk: P384PublicKey::from_der(der)?,
337            key_id: None,
338        })
339    }
340
341    pub fn from_pem(pem: &str) -> Result<Self, JWTError> {
342        Ok(ES384PublicKey {
343            pk: P384PublicKey::from_pem(pem)?,
344            key_id: None,
345        })
346    }
347
348    pub fn to_bytes(&self) -> Vec<u8> {
349        self.pk.to_bytes()
350    }
351
352    pub fn to_der(&self) -> Result<Vec<u8>, JWTError> {
353        self.pk.to_der()
354    }
355
356    pub fn to_pem(&self) -> Result<String, JWTError> {
357        self.pk.to_pem()
358    }
359
360    pub fn with_key_id(mut self, key_id: &str) -> Self {
361        self.key_id = Some(key_id.to_string());
362        self
363    }
364}