Skip to main content

josekit/jws/alg/
ecdsa.rs

1use std::fmt::Display;
2use std::ops::Deref;
3
4use anyhow::bail;
5use openssl::hash::MessageDigest;
6use openssl::pkey::{PKey, Private, Public};
7use openssl::sign::{Signer, Verifier};
8
9use crate::jwk::{
10    alg::ec::{EcCurve, EcKeyPair},
11    Jwk,
12};
13use crate::jws::{JwsAlgorithm, JwsSigner, JwsVerifier};
14use crate::util::der::{DerBuilder, DerReader, DerType};
15use crate::util::{self, HashAlgorithm};
16use crate::{JoseError, Value};
17
18#[derive(Debug, Eq, PartialEq, Copy, Clone)]
19pub enum EcdsaJwsAlgorithm {
20    /// ECDSA using P-256 and SHA-256
21    Es256,
22    /// ECDSA using P-384 and SHA-384
23    Es384,
24    /// ECDSA using P-521 and SHA-512
25    Es512,
26    /// ECDSA using secp256k1 curve and SHA-256
27    Es256k,
28}
29
30impl EcdsaJwsAlgorithm {
31    /// Generate ECDSA key pair.
32    pub fn generate_key_pair(&self) -> Result<EcKeyPair, JoseError> {
33        let mut key_pair = EcKeyPair::generate(self.curve())?;
34        key_pair.set_algorithm(Some(self.name()));
35        Ok(key_pair)
36    }
37
38    /// Create a EcDSA key pair from a private key that is a DER encoded PKCS#8 PrivateKeyInfo or ECPrivateKey.
39    ///
40    /// # Arguments
41    /// * `input` - A private key that is a DER encoded PKCS#8 PrivateKeyInfo or ECPrivateKey.
42    pub fn key_pair_from_der(&self, input: impl AsRef<[u8]>) -> Result<EcKeyPair, JoseError> {
43        let mut key_pair = EcKeyPair::from_der(input, Some(self.curve()))?;
44        key_pair.set_algorithm(Some(self.name()));
45        Ok(key_pair)
46    }
47
48    /// Create a EcDSA key pair from a private key of common or traditinal PEM format.
49    ///
50    /// Common PEM format is a DER and base64 encoded PKCS#8 PrivateKeyInfo
51    /// that surrounded by "-----BEGIN/END PRIVATE KEY----".
52    ///
53    /// Traditional PEM format is a DER and base64 encoded ECPrivateKey
54    /// that surrounded by "-----BEGIN/END EC PRIVATE KEY----".
55    ///
56    /// # Arguments
57    /// * `input` - A private key of common or traditinal PEM format.
58    pub fn key_pair_from_pem(&self, input: impl AsRef<[u8]>) -> Result<EcKeyPair, JoseError> {
59        let mut key_pair = EcKeyPair::from_pem(input.as_ref(), Some(self.curve()))?;
60        key_pair.set_algorithm(Some(self.name()));
61        Ok(key_pair)
62    }
63
64    /// Return a signer from a private key that is a DER encoded PKCS#8 PrivateKeyInfo or ECPrivateKey.
65    ///
66    /// # Arguments
67    /// * `input` - A private key that is a DER encoded PKCS#8 PrivateKeyInfo or ECPrivateKey.
68    pub fn signer_from_der(&self, input: impl AsRef<[u8]>) -> Result<EcdsaJwsSigner, JoseError> {
69        let key_pair = self.key_pair_from_der(input.as_ref())?;
70        Ok(EcdsaJwsSigner {
71            algorithm: self.clone(),
72            private_key: key_pair.into_private_key(),
73            key_id: None,
74        })
75    }
76
77    /// Return a signer from a private key of common or traditinal PEM format.
78    ///
79    /// Common PEM format is a DER and base64 encoded PKCS#8 PrivateKeyInfo
80    /// that surrounded by "-----BEGIN/END PRIVATE KEY----".
81    ///
82    /// Traditional PEM format is a DER and base64 encoded ECPrivateKey
83    /// that surrounded by "-----BEGIN/END EC PRIVATE KEY----".
84    ///
85    /// # Arguments
86    /// * `input` - A private key of common or traditinal PEM format.
87    pub fn signer_from_pem(&self, input: impl AsRef<[u8]>) -> Result<EcdsaJwsSigner, JoseError> {
88        let key_pair = self.key_pair_from_pem(input.as_ref())?;
89        Ok(EcdsaJwsSigner {
90            algorithm: self.clone(),
91            private_key: key_pair.into_private_key(),
92            key_id: None,
93        })
94    }
95
96    /// Return a signer from a private key that is formatted by a JWK of EC type.
97    ///
98    /// # Arguments
99    /// * `jwk` - A private key that is formatted by a JWK of EC type.
100    pub fn signer_from_jwk(&self, jwk: &Jwk) -> Result<EcdsaJwsSigner, JoseError> {
101        (|| -> anyhow::Result<EcdsaJwsSigner> {
102            match jwk.key_use() {
103                Some(val) if val == "sig" => {}
104                None => {}
105                Some(val) => bail!("A parameter use must be sig: {}", val),
106            }
107            if !jwk.is_for_key_operation("sign") {
108                bail!("A parameter key_ops must contains sign.");
109            }
110            match jwk.algorithm() {
111                Some(val) if val == self.name() => {}
112                Some(val) => bail!("A parameter alg must be {} but {}", self.name(), val),
113                None => {}
114            }
115            match jwk.curve() {
116                Some(val) if val == self.curve().name() => {}
117                Some(val) => bail!("A parameter crv must be {} but {}", self.name(), val),
118                None => bail!("A parameter crv is required."),
119            }
120
121            let key_pair = EcKeyPair::from_jwk(jwk)?;
122            let private_key = key_pair.into_private_key();
123            let key_id = jwk.key_id().map(|val| val.to_string());
124
125            Ok(EcdsaJwsSigner {
126                algorithm: self.clone(),
127                private_key,
128                key_id,
129            })
130        })()
131        .map_err(|err| JoseError::InvalidKeyFormat(err))
132    }
133
134    /// Return a verifier from a public key that is a DER encoded SubjectPublicKeyInfo.
135    ///
136    /// # Arguments
137    /// * `input` - A public key that is a DER encoded SubjectPublicKeyInfo.
138    pub fn verifier_from_der(
139        &self,
140        input: impl AsRef<[u8]>,
141    ) -> Result<EcdsaJwsVerifier, JoseError> {
142        (|| -> anyhow::Result<EcdsaJwsVerifier> {
143            let spki_der = match EcKeyPair::detect_pkcs8(input.as_ref(), true) {
144                Some(curve) if curve == self.curve() => input.as_ref(),
145                Some(curve) => bail!("The curve is mismatched: {}", curve),
146                None => {
147                    bail!("The ECDSA public key must be wrapped by SubjectPublicKeyInfo format.")
148                }
149            };
150
151            let public_key = PKey::public_key_from_der(spki_der)?;
152
153            Ok(EcdsaJwsVerifier {
154                algorithm: self.clone(),
155                public_key,
156                key_id: None,
157            })
158        })()
159        .map_err(|err| JoseError::InvalidKeyFormat(err))
160    }
161
162    /// Return a verifier from a key of common PEM format.
163    ///
164    /// Common PEM format is a DER and base64 encoded SubjectPublicKeyInfo
165    /// that surrounded by "-----BEGIN/END PUBLIC KEY----".
166    ///
167    /// # Arguments
168    /// * `input` - A public key of common or traditional PEM format.
169    pub fn verifier_from_pem(
170        &self,
171        input: impl AsRef<[u8]>,
172    ) -> Result<EcdsaJwsVerifier, JoseError> {
173        (|| -> anyhow::Result<EcdsaJwsVerifier> {
174            let (alg, data) = util::parse_pem(input.as_ref())?;
175
176            let spki = match alg.as_str() {
177                "PUBLIC KEY" => {
178                    if let None = EcKeyPair::detect_pkcs8(&data, true) {
179                        bail!("PEM contents is expected SubjectPublicKeyInfo wrapped key.");
180                    }
181                    &data
182                }
183                alg => bail!("Inappropriate algorithm: {}", alg),
184            };
185
186            let public_key = PKey::public_key_from_der(spki)?;
187
188            Ok(EcdsaJwsVerifier {
189                algorithm: self.clone(),
190                public_key,
191                key_id: None,
192            })
193        })()
194        .map_err(|err| JoseError::InvalidKeyFormat(err))
195    }
196
197    /// Return a verifier from a public key that is formatted by a JWK of EC type.
198    ///
199    /// # Arguments
200    /// * `jwk` - A public key that is formatted by a JWK of EC type.
201    pub fn verifier_from_jwk(&self, jwk: &Jwk) -> Result<EcdsaJwsVerifier, JoseError> {
202        (|| -> anyhow::Result<EcdsaJwsVerifier> {
203            let curve = self.curve();
204
205            match jwk.key_type() {
206                val if val == "EC" => {}
207                val => bail!("A parameter kty must be EC: {}", val),
208            }
209            match jwk.key_use() {
210                Some(val) if val == "sig" => {}
211                None => {}
212                Some(val) => bail!("A parameter use must be sig: {}", val),
213            }
214            if !jwk.is_for_key_operation("verify") {
215                bail!("A parameter key_ops must contains verify.");
216            }
217            match jwk.algorithm() {
218                Some(val) if val == self.name() => {}
219                None => {}
220                Some(val) => bail!("A parameter alg must be {} but {}", self.name(), val),
221            }
222            match jwk.parameter("crv") {
223                Some(Value::String(val)) if val == curve.name() => {}
224                Some(Value::String(val)) => {
225                    bail!("A parameter crv must be {} but {}", curve.name(), val)
226                }
227                Some(_) => bail!("A parameter crv must be a string."),
228                None => bail!("A parameter crv is required."),
229            }
230            let x = match jwk.parameter("x") {
231                Some(Value::String(val)) => util::decode_base64_urlsafe_no_pad(val)?,
232                Some(_) => bail!("A parameter x must be a string."),
233                None => bail!("A parameter x is required."),
234            };
235            let y = match jwk.parameter("y") {
236                Some(Value::String(val)) => util::decode_base64_urlsafe_no_pad(val)?,
237                Some(_) => bail!("A parameter y must be a string."),
238                None => bail!("A parameter y is required."),
239            };
240
241            let mut vec = Vec::with_capacity(1 + x.len() + y.len());
242            vec.push(0x04);
243            vec.extend_from_slice(&x);
244            vec.extend_from_slice(&y);
245
246            let pkcs8 = EcKeyPair::to_pkcs8(&vec, true, self.curve());
247            let public_key = PKey::public_key_from_der(&pkcs8)?;
248            let key_id = jwk.key_id().map(|val| val.to_string());
249
250            Ok(EcdsaJwsVerifier {
251                algorithm: self.clone(),
252                public_key,
253                key_id,
254            })
255        })()
256        .map_err(|err| JoseError::InvalidKeyFormat(err))
257    }
258
259    fn curve(&self) -> EcCurve {
260        match self {
261            Self::Es256 => EcCurve::P256,
262            Self::Es384 => EcCurve::P384,
263            Self::Es512 => EcCurve::P521,
264            Self::Es256k => EcCurve::Secp256k1,
265        }
266    }
267
268    fn signature_len(&self) -> usize {
269        match self {
270            Self::Es256 | Self::Es256k => 64,
271            Self::Es384 => 96,
272            Self::Es512 => 132,
273        }
274    }
275
276    fn hash_algorithm(&self) -> HashAlgorithm {
277        match self {
278            Self::Es256 => HashAlgorithm::Sha256,
279            Self::Es384 => HashAlgorithm::Sha384,
280            Self::Es512 => HashAlgorithm::Sha512,
281            Self::Es256k => HashAlgorithm::Sha256,
282        }
283    }
284}
285
286impl JwsAlgorithm for EcdsaJwsAlgorithm {
287    fn name(&self) -> &str {
288        match self {
289            Self::Es256 => "ES256",
290            Self::Es384 => "ES384",
291            Self::Es512 => "ES512",
292            Self::Es256k => "ES256K",
293        }
294    }
295
296    fn box_clone(&self) -> Box<dyn JwsAlgorithm> {
297        Box::new(self.clone())
298    }
299}
300
301impl Display for EcdsaJwsAlgorithm {
302    fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
303        fmt.write_str(self.name())
304    }
305}
306
307impl Deref for EcdsaJwsAlgorithm {
308    type Target = dyn JwsAlgorithm;
309
310    fn deref(&self) -> &Self::Target {
311        self
312    }
313}
314
315#[derive(Debug, Clone)]
316pub struct EcdsaJwsSigner {
317    algorithm: EcdsaJwsAlgorithm,
318    private_key: PKey<Private>,
319    key_id: Option<String>,
320}
321
322impl EcdsaJwsSigner {
323    pub fn set_key_id(&mut self, value: impl Into<String>) {
324        self.key_id = Some(value.into());
325    }
326
327    pub fn remove_key_id(&mut self) {
328        self.key_id = None;
329    }
330}
331
332impl JwsSigner for EcdsaJwsSigner {
333    fn algorithm(&self) -> &dyn JwsAlgorithm {
334        &self.algorithm
335    }
336
337    fn signature_len(&self) -> usize {
338        self.algorithm.signature_len()
339    }
340
341    fn key_id(&self) -> Option<&str> {
342        match &self.key_id {
343            Some(val) => Some(val.as_ref()),
344            None => None,
345        }
346    }
347
348    fn sign(&self, message: &[u8]) -> Result<Vec<u8>, JoseError> {
349        (|| -> anyhow::Result<Vec<u8>> {
350            let md = match &self.algorithm.hash_algorithm() {
351                HashAlgorithm::Sha1 => MessageDigest::sha1(),
352                HashAlgorithm::Sha256 => MessageDigest::sha256(),
353                HashAlgorithm::Sha384 => MessageDigest::sha384(),
354                HashAlgorithm::Sha512 => MessageDigest::sha512(),
355            };
356            let mut signer = Signer::new(md, &self.private_key)?;
357            signer.update(message)?;
358            let der_signature = signer.sign_to_vec()?;
359
360            let signature_len = self.signature_len();
361            let sep = signature_len / 2;
362
363            let mut signature = Vec::with_capacity(signature_len);
364            let mut reader = DerReader::from_bytes(&der_signature);
365            match reader.next()? {
366                Some(DerType::Sequence) => {}
367                _ => unreachable!("A generated signature is invalid."),
368            }
369            match reader.next()? {
370                Some(DerType::Integer) => {
371                    signature.extend_from_slice(&reader.to_be_bytes(false, sep));
372                }
373                _ => unreachable!("A generated signature is invalid."),
374            }
375            match reader.next()? {
376                Some(DerType::Integer) => {
377                    signature.extend_from_slice(&reader.to_be_bytes(false, sep));
378                }
379                _ => unreachable!("A generated signature is invalid."),
380            }
381
382            Ok(signature)
383        })()
384        .map_err(|err| JoseError::InvalidSignature(err))
385    }
386
387    fn box_clone(&self) -> Box<dyn JwsSigner> {
388        Box::new(self.clone())
389    }
390}
391
392impl Deref for EcdsaJwsSigner {
393    type Target = dyn JwsSigner;
394
395    fn deref(&self) -> &Self::Target {
396        self
397    }
398}
399
400#[derive(Debug, Clone)]
401pub struct EcdsaJwsVerifier {
402    algorithm: EcdsaJwsAlgorithm,
403    public_key: PKey<Public>,
404    key_id: Option<String>,
405}
406
407impl EcdsaJwsVerifier {
408    pub fn set_key_id(&mut self, value: impl Into<String>) {
409        self.key_id = Some(value.into());
410    }
411
412    pub fn remove_key_id(&mut self) {
413        self.key_id = None;
414    }
415}
416
417impl JwsVerifier for EcdsaJwsVerifier {
418    fn algorithm(&self) -> &dyn JwsAlgorithm {
419        &self.algorithm
420    }
421
422    fn key_id(&self) -> Option<&str> {
423        match &self.key_id {
424            Some(val) => Some(val.as_ref()),
425            None => None,
426        }
427    }
428
429    fn verify(&self, message: &[u8], signature: &[u8]) -> Result<(), JoseError> {
430        (|| -> anyhow::Result<()> {
431            let signature_len = self.algorithm.signature_len();
432            if signature.len() != signature_len {
433                bail!(
434                    "A signature size must be {}: {}",
435                    signature_len,
436                    signature.len()
437                );
438            }
439
440            let mut der_builder = DerBuilder::new();
441            der_builder.begin(DerType::Sequence);
442            {
443                let sep = signature_len / 2;
444
445                let zeros = signature[..sep].iter().take_while(|b| **b == 0).count();
446                der_builder.append_integer_from_be_slice(&signature[zeros..sep], true);
447                let zeros = signature[sep..].iter().take_while(|b| **b == 0).count();
448                der_builder.append_integer_from_be_slice(&signature[(sep + zeros)..], true);
449            }
450            der_builder.end();
451            let der_signature = der_builder.build();
452
453            let md = match &self.algorithm.hash_algorithm() {
454                HashAlgorithm::Sha1 => MessageDigest::sha1(),
455                HashAlgorithm::Sha256 => MessageDigest::sha256(),
456                HashAlgorithm::Sha384 => MessageDigest::sha384(),
457                HashAlgorithm::Sha512 => MessageDigest::sha512(),
458            };
459            let mut verifier = Verifier::new(md, &self.public_key)?;
460            verifier.update(message)?;
461            if !verifier.verify(&der_signature)? {
462                bail!("The signature does not match.");
463            }
464            Ok(())
465        })()
466        .map_err(|err| JoseError::InvalidSignature(err))
467    }
468
469    fn box_clone(&self) -> Box<dyn JwsVerifier> {
470        Box::new(self.clone())
471    }
472}
473
474impl Deref for EcdsaJwsVerifier {
475    type Target = dyn JwsVerifier;
476
477    fn deref(&self) -> &Self::Target {
478        self
479    }
480}
481
482#[cfg(test)]
483mod tests {
484    use super::*;
485
486    use anyhow::Result;
487    use std::fs;
488    use std::path::PathBuf;
489
490    #[test]
491    fn sign_and_verify_ecdsa_generated_der() -> Result<()> {
492        let input = b"abcde12345";
493
494        for alg in &[
495            EcdsaJwsAlgorithm::Es256,
496            EcdsaJwsAlgorithm::Es384,
497            EcdsaJwsAlgorithm::Es512,
498            EcdsaJwsAlgorithm::Es256k,
499        ] {
500            let key_pair = alg.generate_key_pair()?;
501
502            let signer = alg.signer_from_der(&key_pair.to_der_private_key())?;
503            let signature = signer.sign(input)?;
504
505            let verifier = alg.verifier_from_der(&key_pair.to_der_public_key())?;
506            verifier.verify(input, &signature)?;
507        }
508
509        Ok(())
510    }
511
512    #[test]
513    fn sign_and_verify_ecdsa_generated_raw() -> Result<()> {
514        let input = b"abcde12345";
515
516        for alg in &[
517            EcdsaJwsAlgorithm::Es256,
518            EcdsaJwsAlgorithm::Es384,
519            EcdsaJwsAlgorithm::Es512,
520            EcdsaJwsAlgorithm::Es256k,
521        ] {
522            let key_pair = alg.generate_key_pair()?;
523
524            let signer = alg.signer_from_der(&key_pair.to_raw_private_key())?;
525            let signature = signer.sign(input)?;
526
527            let verifier = alg.verifier_from_der(&key_pair.to_der_public_key())?;
528            verifier.verify(input, &signature)?;
529        }
530
531        Ok(())
532    }
533
534    #[test]
535    fn sign_and_verify_ecdsa_generated_pem() -> Result<()> {
536        let input = b"abcde12345";
537
538        for alg in &[
539            EcdsaJwsAlgorithm::Es256,
540            EcdsaJwsAlgorithm::Es384,
541            EcdsaJwsAlgorithm::Es512,
542            EcdsaJwsAlgorithm::Es256k,
543        ] {
544            let key_pair = alg.generate_key_pair()?;
545
546            let signer = alg.signer_from_pem(&key_pair.to_pem_private_key())?;
547            let signature = signer.sign(input)?;
548
549            let verifier = alg.verifier_from_pem(&key_pair.to_pem_public_key())?;
550            verifier.verify(input, &signature)?;
551        }
552
553        Ok(())
554    }
555
556    #[test]
557    fn sign_and_verify_ecdsa_generated_traditional_pem() -> Result<()> {
558        let input = b"abcde12345";
559
560        for alg in &[
561            EcdsaJwsAlgorithm::Es256,
562            EcdsaJwsAlgorithm::Es384,
563            EcdsaJwsAlgorithm::Es512,
564            EcdsaJwsAlgorithm::Es256k,
565        ] {
566            let key_pair = alg.generate_key_pair()?;
567
568            let signer = alg.signer_from_pem(&key_pair.to_traditional_pem_private_key())?;
569            let signature = signer.sign(input)?;
570
571            let verifier = alg.verifier_from_pem(&key_pair.to_pem_public_key())?;
572            verifier.verify(input, &signature)?;
573        }
574
575        Ok(())
576    }
577
578    #[test]
579    fn sign_and_verify_ecdsa_generated_jwk() -> Result<()> {
580        let input = b"abcde12345";
581
582        for alg in &[
583            EcdsaJwsAlgorithm::Es256,
584            EcdsaJwsAlgorithm::Es384,
585            EcdsaJwsAlgorithm::Es512,
586            EcdsaJwsAlgorithm::Es256k,
587        ] {
588            let key_pair = alg.generate_key_pair()?;
589
590            let signer = alg.signer_from_jwk(&key_pair.to_jwk_private_key())?;
591            let signature = signer.sign(input)?;
592
593            let verifier = alg.verifier_from_jwk(&key_pair.to_jwk_public_key())?;
594            verifier.verify(input, &signature)?;
595        }
596
597        Ok(())
598    }
599
600    #[test]
601    fn sign_and_verify_ecdsa_jwt() -> Result<()> {
602        let input = b"abcde12345";
603
604        for alg in &[
605            EcdsaJwsAlgorithm::Es256,
606            EcdsaJwsAlgorithm::Es384,
607            EcdsaJwsAlgorithm::Es512,
608            EcdsaJwsAlgorithm::Es256k,
609        ] {
610            let private_key = load_file(match alg {
611                EcdsaJwsAlgorithm::Es256 => "jwk/EC_P-256_private.jwk",
612                EcdsaJwsAlgorithm::Es384 => "jwk/EC_P-384_private.jwk",
613                EcdsaJwsAlgorithm::Es512 => "jwk/EC_P-521_private.jwk",
614                EcdsaJwsAlgorithm::Es256k => "jwk/EC_secp256k1_private.jwk",
615            })?;
616            let public_key = load_file(match alg {
617                EcdsaJwsAlgorithm::Es256 => "jwk/EC_P-256_public.jwk",
618                EcdsaJwsAlgorithm::Es384 => "jwk/EC_P-384_public.jwk",
619                EcdsaJwsAlgorithm::Es512 => "jwk/EC_P-521_public.jwk",
620                EcdsaJwsAlgorithm::Es256k => "jwk/EC_secp256k1_public.jwk",
621            })?;
622
623            let signer = alg.signer_from_jwk(&Jwk::from_bytes(&private_key)?)?;
624            let signature = signer.sign(input)?;
625
626            let verifier = alg.verifier_from_jwk(&Jwk::from_bytes(&public_key)?)?;
627            verifier.verify(input, &signature)?;
628        }
629
630        Ok(())
631    }
632
633    #[test]
634    fn sign_and_verify_ecdsa_pkcs8_pem() -> Result<()> {
635        let input = b"abcde12345";
636
637        for alg in &[
638            EcdsaJwsAlgorithm::Es256,
639            EcdsaJwsAlgorithm::Es384,
640            EcdsaJwsAlgorithm::Es512,
641            EcdsaJwsAlgorithm::Es256k,
642        ] {
643            println!("{}", alg);
644
645            let private_key = load_file(match alg {
646                EcdsaJwsAlgorithm::Es256 => "pem/EC_P-256_private.pem",
647                EcdsaJwsAlgorithm::Es384 => "pem/EC_P-384_private.pem",
648                EcdsaJwsAlgorithm::Es512 => "pem/EC_P-521_private.pem",
649                EcdsaJwsAlgorithm::Es256k => "pem/EC_secp256k1_private.pem",
650            })?;
651            let public_key = load_file(match alg {
652                EcdsaJwsAlgorithm::Es256 => "pem/EC_P-256_public.pem",
653                EcdsaJwsAlgorithm::Es384 => "pem/EC_P-384_public.pem",
654                EcdsaJwsAlgorithm::Es512 => "pem/EC_P-521_public.pem",
655                EcdsaJwsAlgorithm::Es256k => "pem/EC_secp256k1_public.pem",
656            })?;
657
658            let signer = alg.signer_from_pem(&private_key)?;
659            let signature = signer.sign(input)?;
660
661            let verifier = alg.verifier_from_pem(&public_key)?;
662            verifier.verify(input, &signature)?;
663        }
664
665        Ok(())
666    }
667
668    #[test]
669    fn sign_and_verify_ecdsa_pkcs8_der() -> Result<()> {
670        let input = b"abcde12345";
671
672        for alg in &[
673            EcdsaJwsAlgorithm::Es256,
674            EcdsaJwsAlgorithm::Es384,
675            EcdsaJwsAlgorithm::Es512,
676            EcdsaJwsAlgorithm::Es256k,
677        ] {
678            let private_key = load_file(match alg {
679                EcdsaJwsAlgorithm::Es256 => "der/EC_P-256_pkcs8_private.der",
680                EcdsaJwsAlgorithm::Es384 => "der/EC_P-384_pkcs8_private.der",
681                EcdsaJwsAlgorithm::Es512 => "der/EC_P-521_pkcs8_private.der",
682                EcdsaJwsAlgorithm::Es256k => "der/EC_secp256k1_pkcs8_private.der",
683            })?;
684            let public_key = load_file(match alg {
685                EcdsaJwsAlgorithm::Es256 => "der/EC_P-256_spki_public.der",
686                EcdsaJwsAlgorithm::Es384 => "der/EC_P-384_spki_public.der",
687                EcdsaJwsAlgorithm::Es512 => "der/EC_P-521_spki_public.der",
688                EcdsaJwsAlgorithm::Es256k => "der/EC_secp256k1_spki_public.der",
689            })?;
690
691            let signer = alg.signer_from_der(&private_key)?;
692            let signature = signer.sign(input)?;
693
694            let verifier = alg.verifier_from_der(&public_key)?;
695            verifier.verify(input, &signature)?;
696        }
697
698        Ok(())
699    }
700
701    #[test]
702    fn sign_and_verify_ecdsa_mismatch() -> Result<()> {
703        let input = b"abcde12345";
704
705        for alg in &[
706            EcdsaJwsAlgorithm::Es256,
707            EcdsaJwsAlgorithm::Es384,
708            EcdsaJwsAlgorithm::Es512,
709            EcdsaJwsAlgorithm::Es256k,
710        ] {
711            let signer_key_pair = alg.generate_key_pair()?;
712            let verifier_key_pair = alg.generate_key_pair()?;
713
714            let signer = alg.signer_from_der(&signer_key_pair.to_der_private_key())?;
715            let signature = signer.sign(input)?;
716
717            let verifier = alg.verifier_from_der(&verifier_key_pair.to_der_public_key())?;
718            verifier
719                .verify(input, &signature)
720                .expect_err("Unmatched signature did not fail");
721        }
722
723        Ok(())
724    }
725
726    fn load_file(path: &str) -> Result<Vec<u8>> {
727        let mut pb = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
728        pb.push("data");
729        pb.push(path);
730
731        let data = fs::read(&pb)?;
732        Ok(data)
733    }
734}