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 Es256,
22 Es384,
24 Es512,
26 Es256k,
28}
29
30impl EcdsaJwsAlgorithm {
31 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 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 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 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 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 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 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 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 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}