1use std::str;
91
92use sequoia_openpgp as openpgp;
93use openpgp::Result;
94use openpgp::packet::UserID;
95
96#[macro_use] mod log;
97#[macro_use] mod macros;
98
99pub mod store;
100pub use store::Store;
101pub use store::StoreUpdate;
102mod cert_store;
103pub use cert_store::CertStore;
104pub use cert_store::AccessMode;
105
106mod lazy_cert;
107pub use lazy_cert::LazyCert;
108
109const TRACE: bool = false;
110
111pub fn email_to_userid(email: &str) -> Result<UserID> {
128 let email_check = UserID::from(format!("<{}>", email));
129 match email_check.email() {
130 Ok(Some(email_check)) => {
131 if email != email_check {
132 return Err(anyhow::anyhow!(
133 "{:?} does not appear to be an email address",
134 email));
135 }
136 }
137 Ok(None) => {
138 return Err(anyhow::anyhow!(
139 "{:?} does not appear to be an email address",
140 email));
141 }
142 Err(err) => {
143 return Err(err.context(format!(
144 "{:?} does not appear to be an email address",
145 email)));
146 }
147 }
148
149 let userid = UserID::from(&email[..]);
150 match userid.email_normalized() {
151 Err(err) => {
152 Err(err.context(format!(
153 "'{}' is not a valid email address", email)))
154 }
155 Ok(None) => {
156 Err(anyhow::anyhow!("'{}' is not a valid email address", email))
157 }
158 Ok(Some(_email)) => {
159 Ok(userid)
160 }
161 }
162}
163
164#[cfg(test)]
165mod tests {
166 use super::*;
167
168 use std::path::PathBuf;
169 use std::str;
170 use std::sync::Arc;
171
172 use anyhow::Context;
173 pub fn print_error_chain(err: &anyhow::Error) {
175 let _ = write_error_chain_into(&mut std::io::stderr(), err);
176 }
177
178 fn write_error_chain_into(sink: &mut dyn std::io::Write, err: &anyhow::Error)
180 -> Result<()> {
181 writeln!(sink, " {}", err)?;
182 for cause in err.chain().skip(1) {
183 writeln!(sink, " because: {}", cause)?;
184 }
185 Ok(())
186 }
187
188 use openpgp::Fingerprint;
189 use openpgp::KeyHandle;
190 use openpgp::KeyID;
191 use openpgp::Cert;
192 use openpgp::parse::Parse;
193 use openpgp::policy::StandardPolicy;
194 use openpgp::serialize::Serialize;
195
196 use openpgp_cert_d as cert_d;
197
198 use store::Certs;
199 use store::Pep;
200 use store::StoreError;
201 use store::UserIDQueryParams;
202
203 fn certd_merge<'a>(new: &'a [u8], disk: Option<&[u8]>)
204 -> cert_d::Result<cert_d::MergeResult<'a>>
205 {
206 if let Some(disk) = disk {
207 let new = Cert::from_bytes(&new).expect("valid");
208 let disk = Cert::from_bytes(&disk).expect("valid");
209 let merged = new.merge_public(disk).expect("valid");
210 let mut bytes = Vec::new();
211 merged.serialize(&mut bytes).expect("valid");
212 Ok(bytes.into())
213 } else {
214 Ok(cert_d::MergeResult::DataRef(new))
215 }
216 }
217
218 include!("../tests/keyring.rs");
219
220 fn test_backend<'a, B>(backend: &B)
221 where B: Store<'a>
222 {
223 {
225 let mut got: Vec<Fingerprint> = backend.fingerprints().collect();
226 got.sort();
227 let mut expected: Vec<Fingerprint> = keyring::certs.iter()
228 .map(|c| c.fingerprint.parse::<Fingerprint>().expect("valid"))
229 .collect();
230 expected.sort();
231 expected.dedup();
232 assert_eq!(got.len(), expected.len());
233 assert_eq!(got, expected);
234 }
235
236 std::thread::yield_now();
237
238 {
240 let mut got: Vec<Fingerprint>
241 = backend.certs().map(|c| c.fingerprint()).collect();
242 got.sort();
243 let mut expected: Vec<Fingerprint> = keyring::certs.iter()
244 .map(|c| c.fingerprint.parse::<Fingerprint>().expect("valid"))
245 .collect();
246 expected.sort();
247 expected.dedup();
248 assert_eq!(got.len(), expected.len());
249 assert_eq!(got, expected);
250 }
251
252 std::thread::yield_now();
253
254 for handle in keyring::certs.iter() {
258 let fpr: Fingerprint = handle.fingerprint.parse().expect("valid");
259 let cert = handle.to_cert().expect("valid");
260 assert_eq!(fpr, cert.fingerprint(),
261 "{}", handle.base);
262 let keyid = KeyID::from(fpr.clone());
263
264 let got = backend.lookup_by_cert_fpr(&fpr).expect("present");
266 assert_eq!(got.fingerprint(), fpr,
267 "{}, by_cert_fpr, primary", handle.base);
268
269 for sk in cert.keys().subkeys() {
274 match backend.lookup_by_cert_fpr(&sk.key().fingerprint()) {
275 Ok(got) => {
276 assert_eq!(got.fingerprint(), sk.key().fingerprint());
278
279 assert!(
281 keyring::certs.iter().any(|c| {
282 c.fingerprint.parse::<Fingerprint>().unwrap()
283 == got.fingerprint()
284 }),
285 "{}, lookup_by_cert_fpr, subkey, unexpectedly got {}",
286 handle.base, got.fingerprint());
287 }
288 Err(err) => {
289 match err.downcast_ref::<StoreError>() {
290 Some(StoreError::NotFound(_)) => (),
291 _ => panic!("Expected StoreError::NotFound, \
292 got: {}",
293 err),
294 }
295 },
296 }
297
298 std::thread::yield_now();
299 }
300
301 let got = backend.lookup_by_cert(&KeyHandle::from(&keyid))
303 .expect("present");
304 assert!(got.iter()
306 .all(|c| {
307 c.keys().any(|k| k.keyid() == keyid)
308 }),
309 "{}, lookup_by_cert, keyid, primary",
310 handle.base);
311
312 assert!(got.into_iter().any(|c| c.fingerprint() == fpr),
315 "{}, lookup_by_cert, keyid, primary", handle.base);
316
317 for sk in cert.keys().subkeys() {
320 match backend.lookup_by_cert(&KeyHandle::from(sk.key().keyid())) {
321 Ok(got) => {
322 assert!(! got.is_empty());
326
327 for got in got.iter() {
329 assert_eq!(got.keyid(), sk.key().keyid());
330 }
331
332 for got in got.into_iter() {
334 assert!(
335 keyring::certs.iter().any(|c| {
336 c.fingerprint.parse::<Fingerprint>()
337 .unwrap()
338 == got.fingerprint()
339 }),
340 "{}, lookup_by_cert_fpr, subkey, \
341 unexpectedly got {}",
342 handle.base, got.fingerprint());
343 }
344 }
345 Err(err) => {
346 match err.downcast_ref::<StoreError>() {
347 Some(StoreError::NotFound(_)) => (),
348 _ => panic!("Expected StoreError::NotFound, \
349 got: {}",
350 err),
351 }
352 },
353 }
354
355 std::thread::yield_now();
356 }
357
358 let got = backend.lookup_by_cert_or_subkey(&KeyHandle::from(fpr.clone()))
360 .expect("present");
361 assert!(got.iter()
363 .all(|c| {
364 c.keys().any(|k| k.fingerprint() == fpr)
365 }),
366 "{}, lookup_by_cert_or_subkey, with fingerprint, primary",
367 handle.base);
368
369 assert!(got.into_iter().any(|c| c.fingerprint() == fpr),
372 "{}, lookup_by_cert_or_subkey, with fingerprint, primary",
373 handle.base);
374
375 for sk in cert.keys().subkeys() {
377 let got = backend.lookup_by_cert_or_subkey(
378 &KeyHandle::from(sk.key().fingerprint()))
379 .expect("present");
380 for got in got.iter() {
382 assert!(
383 got.keys().any(|k| k.fingerprint() == sk.key().fingerprint()),
384 "{}, lookup_by_cert_or_subkey({}), with fingerprint, subkey",
385 handle.base, sk.key().fingerprint());
386 }
387
388 assert!(got.into_iter().any(|c| c.fingerprint() == fpr),
391 "{}, lookup_by_cert_or_subkey({}), with fingerprint, subkey",
392 handle.base, sk.key().fingerprint());
393
394 std::thread::yield_now();
395 }
396
397
398 let got = backend.lookup_by_cert_or_subkey(&KeyHandle::from(keyid.clone()))
400 .expect("present");
401 for got in got.iter() {
403 assert!(
404 got.keys().any(|k| k.keyid() == keyid),
405 "{}, lookup_by_cert_or_subkey({}), with keyid, primary",
406 handle.base, keyid);
407 }
408
409 assert!(got.into_iter().any(|c| c.fingerprint() == fpr),
412 "{}, lookup_by_cert_or_subkey({}), with keyid, primary",
413 handle.base, keyid);
414
415 for sk in cert.keys().subkeys() {
417 let got = backend.lookup_by_cert_or_subkey(&KeyHandle::from(sk.key().keyid()))
418 .expect("present");
419 for got in got.iter() {
421 assert!(
422 got.keys().any(|k| k.keyid() == sk.key().keyid()),
423 "{}, lookup_by_cert_or_subkey({}), with keyid, subkey",
424 handle.base, sk.key().keyid());
425 }
426
427 assert!(got.into_iter().any(|c| c.fingerprint() == fpr),
430 "{}, lookup_by_cert_or_subkey({}), with keyid, subkey",
431 handle.base, sk.key().keyid());
432
433 std::thread::yield_now();
434 }
435
436
437 for ua in cert.userids() {
440 let userid = ua.userid();
441
442 let got = backend.lookup_by_userid(userid)
444 .expect(&format!("{}, lookup_by_userid({:?})",
445 handle.base, userid));
446 for got in got.iter() {
448 assert!(
449 got.userids().any(|u| &u == userid),
450 "{}, lookup_by_userid({:?})", handle.base, userid);
451 }
452
453 assert!(got.into_iter().any(|c| c.fingerprint() == fpr),
456 "{}, lookup_by_userid({:?})",
457 handle.base, userid);
458
459 let pattern = str::from_utf8(userid.value()).expect("utf-8");
462 let pattern = &pattern[1..pattern.len() - 1];
463 let pattern = pattern.to_uppercase();
464
465 let got = backend.grep_userid(&pattern)
468 .expect(&format!("{}, grep_userid({:?})",
469 handle.base, pattern));
470
471 let mut query = UserIDQueryParams::new();
473 query.set_email(false);
474 query.set_anchor_start(false);
475 query.set_anchor_end(false);
476 query.set_ignore_case(true);
477 for got in got.iter() {
478 assert!(
479 got.userids().any(|u| query.check(&u, &pattern)),
480 "{}, grep_userid({:?})", handle.base, pattern);
481 }
482
483 assert!(got.into_iter().any(|c| c.fingerprint() == fpr),
486 "{}, grep_userid({:?})", handle.base, pattern);
487
488 for (start, end, ignore_case) in
493 [(false, false, false),
494 (false, true, false),
496 (false, true, true),
497 ( true, false, false),
498 ( true, false, true),
499 ( true, true, false),
500 ( true, true, true)]
501 {
502 let result = backend.select_userid(
503 UserIDQueryParams::new()
504 .set_email(false)
505 .set_anchor_start(start)
506 .set_anchor_end(end)
507 .set_ignore_case(ignore_case),
508 &pattern);
509 match result {
510 Ok(got) => {
511 panic!("{}, select_userid({:?}) -> {}",
512 handle.base, pattern,
513 got.into_iter()
514 .map(|c| c.fingerprint().to_string())
515 .collect::<Vec<String>>()
516 .join(", "));
517 }
518 Err(err) => {
519 match err.downcast_ref::<StoreError>() {
520 Some(StoreError::NoMatches(_)) => (),
521 _ => panic!("{}, select_userid({:?}) -> {}",
522 handle.base, pattern, err),
523 }
524 }
525 }
526 }
527
528 let email = if let Ok(Some(email)) = userid.email() {
530 email
531 } else {
532 continue;
534 };
535
536 assert!(
540 backend.lookup_by_email(
541 str::from_utf8(userid.value()).expect("valid utf-8"))
542 .is_err(),
543 "{}, lookup_by_email({:?})", handle.base, userid);
544
545 let got = backend.lookup_by_email(&email)
547 .expect(&format!("{}, lookup_by_email({:?})",
548 handle.base, email));
549 let mut query = UserIDQueryParams::new();
551 query.set_email(true);
552 query.set_anchor_start(true);
553 query.set_anchor_end(true);
554 query.set_ignore_case(false);
555 for got in got.iter() {
556 assert!(
557 got.userids().any(|u| query.check(&u, &email)),
558 "{}, lookup_by_email({:?})",
559 handle.base, email);
560 }
561
562 assert!(got.into_iter().any(|c| c.fingerprint() == fpr),
565 "{}, lookup_by_email({:?})", handle.base, userid);
566
567 let pattern = &email[1..email.len() - 1];
570 let pattern = pattern.to_uppercase();
571
572 let got = backend.grep_email(&pattern)
575 .expect(&format!("{}, grep_email({:?})",
576 handle.base, pattern));
577 let mut query = UserIDQueryParams::new();
579 query.set_email(true);
580 query.set_anchor_start(false);
581 query.set_anchor_end(false);
582 query.set_ignore_case(true);
583 for got in got.iter() {
584 assert!(
585 got.userids().any(|u| query.check(&u, &pattern)),
586 "{}, grep_email({:?})", handle.base, pattern);
587 }
588
589 assert!(got.into_iter().any(|c| c.fingerprint() == fpr),
592 "{}, grep_email({:?})", handle.base, pattern);
593
594 for (start, end, ignore_case) in
599 [(false, false, false),
600 (false, true, false),
602 (false, true, true),
603 ( true, false, false),
604 ( true, false, true),
605 ( true, true, false),
606 ( true, true, true)]
607 {
608 let result = backend.select_userid(
609 UserIDQueryParams::new()
610 .set_email(true)
611 .set_anchor_start(start)
612 .set_anchor_end(end)
613 .set_ignore_case(ignore_case),
614 &pattern);
615 match result {
616 Ok(got) => {
617 panic!("{}, select_userid({:?}) -> {}",
618 handle.base, pattern,
619 got.into_iter()
620 .map(|c| c.fingerprint().to_string())
621 .collect::<Vec<String>>()
622 .join(", "));
623 }
624 Err(err) => {
625 match err.downcast_ref::<StoreError>() {
626 Some(StoreError::NoMatches(_)) => (),
627 _ => panic!("{}, select_userid({:?}) -> {}",
628 handle.base, pattern, err),
629 }
630 }
631 }
632 }
633
634
635
636 let domain = email.rsplit('@').next().expect("have an @");
638
639 assert!(
643 backend.lookup_by_email_domain(
644 str::from_utf8(userid.value()).expect("valid utf-8"))
645 .is_err(),
646 "{}, lookup_by_email_domain({:?})", handle.base, userid);
647 assert!(
649 backend.lookup_by_email_domain(&email).is_err(),
650 "{}, lookup_by_email_domain({:?})", handle.base, email);
651
652 let got = backend.lookup_by_email_domain(&domain)
654 .expect(&format!("{}, lookup_by_email_domain({:?})",
655 handle.base, domain));
656 let mut query = UserIDQueryParams::new();
658 query.set_email(true);
659 query.set_anchor_start(false);
660 query.set_anchor_end(true);
661 query.set_ignore_case(true);
662 let at_domain = format!("@{}", domain);
663 for got in got.iter() {
664 assert!(
665 got.userids().any(|u| query.check(&u, &at_domain)),
666 "{}, lookup_by_email_domain({:?})",
667 handle.base, domain);
668 }
669
670 assert!(got.into_iter().any(|c| c.fingerprint() == fpr),
673 "{}, lookup_by_email_domain({:?})",
674 handle.base, userid);
675
676 let pattern = domain.to_uppercase();
678 let got = backend.lookup_by_email_domain(&pattern)
679 .expect(&format!("{}, lookup_by_email_domain({:?})",
680 handle.base, pattern));
681 let mut query = UserIDQueryParams::new();
683 query.set_email(true);
684 query.set_anchor_start(false);
685 query.set_anchor_end(true);
686 query.set_ignore_case(true);
687 let at_domain = format!("@{}", pattern);
688 for got in got.iter() {
689 assert!(
690 got.userids().any(|u| query.check(&u, &at_domain)),
691 "{}, lookup_by_email_domain({:?})",
692 handle.base, domain);
693 }
694
695 assert!(got.into_iter().any(|c| c.fingerprint() == fpr),
698 "{}, lookup_by_email_domain({:?})",
699 handle.base, pattern);
700
701 let pattern = &domain[1..pattern.len() - 1];
703 let result = backend.lookup_by_email_domain(pattern);
704 match result {
705 Ok(got) => {
706 assert!(! got.is_empty());
710
711 assert!(
712 got.into_iter().all(|c| {
713 c.fingerprint() != fpr
714 }),
715 "{}, lookup_by_email_domain({:?}, unexpectedly got {}",
716 handle.base, pattern, fpr);
717 }
718 Err(err) => {
719 match err.downcast_ref::<StoreError>() {
720 Some(StoreError::NoMatches(_)) => (),
721 _ => panic!("{}, lookup_by_email_domain({:?}) -> {}",
722 handle.base, pattern, err),
723 }
724 }
725 }
726
727 std::thread::yield_now();
728 }
729 }
730
731 let sort_vec = |mut v: Vec<_>| -> Vec<_> {
736 v.sort();
737 v
738 };
739
740 assert_eq!(
742 sort_vec(backend.lookup_by_cert_or_subkey(
743 &"5989D7BE9908AE24799DF6CFBE678043781349F1"
744 .parse::<KeyHandle>().expect("valid"))
745 .expect("present")
746 .into_iter()
747 .map(|c| c.fingerprint())
748 .collect::<Vec<Fingerprint>>()),
749 sort_vec(
750 vec![
751 keyring::alice.fingerprint
752 .parse::<Fingerprint>().expect("valid"),
753 keyring::alice2_adopted_alice.fingerprint
754 .parse::<Fingerprint>().expect("valid"),
755 ]));
756
757 std::thread::yield_now();
758
759 {
761 let ed_fpr = "0C346B2B6241263F64E9C7CF1EA300797258A74E"
762 .parse::<Fingerprint>().expect("valid");
763 let ed_kh = KeyHandle::from(&ed_fpr);
764
765 assert_eq!(
766 sort_vec(backend.lookup_by_cert_or_subkey(&ed_kh)
767 .expect("present")
768 .into_iter()
769 .map(|c| c.fingerprint())
770 .collect::<Vec<Fingerprint>>()),
771 sort_vec(
772 vec![
773 keyring::ed.fingerprint
774 .parse::<Fingerprint>().expect("valid"),
775 ]));
776
777 let cert = backend.lookup_by_cert_fpr(&ed_fpr)
780 .expect("found cert");
781 assert_eq!(cert.fingerprint(), ed_fpr);
782
783 let certs = backend.lookup_by_cert(&ed_kh)
787 .expect("found cert");
788 assert_eq!(certs.len(), 1);
789 assert_eq!(certs[0].fingerprint(), ed_fpr);
790
791 let certs = backend.lookup_by_cert_or_subkey(&ed_kh)
792 .expect("found cert");
793 assert_eq!(certs.len(), 1);
794 assert_eq!(certs[0].fingerprint(), ed_fpr);
795
796 let certs = backend.certs();
797 assert_eq!(certs.filter(|c| c.fingerprint() == ed_fpr).count(),
798 1);
799
800 let fprs = backend.fingerprints();
801 assert_eq!(fprs.filter(|fpr| fpr == &ed_fpr).count(),
802 1);
803 }
804
805 assert_eq!(
809 sort_vec(backend.lookup_by_cert_or_subkey(
810 &"CD22D4BD99FF10FDA11A83D4213DCB92C95346CE"
811 .parse::<KeyHandle>().expect("valid"))
812 .expect("present")
813 .into_iter()
814 .map(|c| c.fingerprint())
815 .collect::<Vec<Fingerprint>>()),
816 sort_vec(
817 vec![
818 keyring::carol.fingerprint
819 .parse::<Fingerprint>().expect("valid"),
820 keyring::david.fingerprint
821 .parse::<Fingerprint>().expect("valid"),
822 ]));
823
824
825 match backend.lookup_by_cert_fpr(
827 &"0123 4567 89AB CDEF 0123 4567 89AB CDEF 0123 4567"
828 .parse::<Fingerprint>().expect("valid"))
829 {
830 Ok(cert) => panic!("lookup_by_cert_fpr(not present) -> {}",
831 cert.fingerprint()),
832 Err(err) => {
833 match err.downcast_ref::<StoreError>() {
834 Some(StoreError::NotFound(_)) => (),
835 _ => panic!("lookup_by_cert(not present) -> {}", err),
836 }
837 }
838 }
839
840 match backend.lookup_by_cert_or_subkey(
841 &"0123 4567 89AB CDEF 0123 4567 89AB CDEF 0123 4567"
842 .parse::<KeyHandle>().expect("valid"))
843 {
844 Ok(certs) => panic!("lookup_by_cert_or_subkey(not present) -> {}",
845 certs
846 .into_iter()
847 .map(|c| c.fingerprint().to_string())
848 .collect::<Vec<String>>()
849 .join(", ")),
850 Err(err) => {
851 match err.downcast_ref::<StoreError>() {
852 Some(StoreError::NotFound(_)) => (),
853 _ => panic!("lookup_by_cert(not present) -> {}", err),
854 }
855 }
856 }
857
858 std::thread::yield_now();
859
860 assert!(
861 backend.lookup_by_cert_or_subkey(
862 &"0123 4567 89AB CDEF 0123 4567 89AB CDEF"
863 .parse::<KeyHandle>().expect("valid"))
864 .is_err());
865
866 assert_eq!(
870 backend.lookup_by_email("hans@xn--bcher-kva.tld")
871 .expect("present")
872 .len(),
873 1);
874 assert_eq!(
876 backend.lookup_by_email("hans@bücher.tld")
877 .expect("present")
878 .into_iter()
879 .map(|c| c.fingerprint())
880 .collect::<Vec<Fingerprint>>(),
881 vec![ keyring::hans_puny_code.fingerprint
882 .parse::<Fingerprint>().expect("valid") ]);
883 assert_eq!(
885 backend.lookup_by_email("hans@bücher.tl")
886 .unwrap_or(Vec::new())
887 .len(),
888 0);
889
890 assert_eq!(
892 backend.lookup_by_email_domain("xn--bcher-kva.tld")
893 .expect("present")
894 .into_iter()
895 .map(|c| c.fingerprint())
896 .collect::<Vec<Fingerprint>>(),
897 vec![ keyring::hans_puny_code.fingerprint
898 .parse::<Fingerprint>().expect("valid") ]);
899 assert_eq!(
901 backend.lookup_by_email_domain("bücher.tld")
902 .expect("present")
903 .into_iter()
904 .map(|c| c.fingerprint())
905 .collect::<Vec<Fingerprint>>(),
906 vec![ keyring::hans_puny_code.fingerprint
907 .parse::<Fingerprint>().expect("valid") ]);
908
909
910 std::thread::yield_now();
911
912 assert_eq!(
915 backend.lookup_by_email_domain("company.com")
916 .expect("present")
917 .into_iter()
918 .map(|c| c.fingerprint())
919 .collect::<Vec<Fingerprint>>(),
920 vec![ keyring::una.fingerprint
921 .parse::<Fingerprint>().expect("valid") ]);
922 assert_eq!(
923 backend.lookup_by_email_domain("sub.company.com")
924 .expect("present")
925 .into_iter()
926 .map(|c| c.fingerprint())
927 .collect::<Vec<Fingerprint>>(),
928 vec![ keyring::steve.fingerprint
929 .parse::<Fingerprint>().expect("valid") ]);
930
931
932 assert_eq!(
934 sort_vec(backend.lookup_by_email_domain("verein.de")
935 .expect("present")
936 .into_iter()
937 .map(|c| c.fingerprint())
938 .collect::<Vec<Fingerprint>>()),
939 sort_vec(
940 vec![
941 keyring::alice2_adopted_alice.fingerprint
942 .parse::<Fingerprint>().expect("valid"),
943 keyring::carol.fingerprint
944 .parse::<Fingerprint>().expect("valid"),
945 ]));
946
947 assert_eq!(
949 sort_vec(backend.lookup_by_email_domain("VEREIN.DE")
950 .expect("present")
951 .into_iter()
952 .map(|c| c.fingerprint())
953 .collect::<Vec<Fingerprint>>()),
954 sort_vec(
955 vec![
956 keyring::alice2_adopted_alice.fingerprint
957 .parse::<Fingerprint>().expect("valid"),
958 keyring::carol.fingerprint
959 .parse::<Fingerprint>().expect("valid"),
960 ]));
961
962
963 assert_eq!(
970 backend.lookup_by_userid(
971 &UserID::from("Dad <peter@example.family>"))
972 .expect("present")
973 .len(),
974 1);
975
976 assert_eq!(
977 backend.grep_userid("Dad")
978 .expect("present")
979 .len(),
980 1);
981
982 assert_eq!(
983 backend.lookup_by_email("peter@example.family")
984 .expect("present")
985 .len(),
986 1);
987
988 assert_eq!(
989 backend.grep_email("eter@example.family")
990 .expect("present")
991 .len(),
992 1);
993
994 assert_eq!(
995 backend.lookup_by_email_domain("example.family")
996 .expect("present")
997 .len(),
998 1);
999 }
1000
1001 #[test]
1002 fn certd() -> Result<()> {
1003 use std::io::Read;
1004
1005 let path = tempfile::tempdir()?;
1006 let certd = cert_d::CertD::with_base_dir(&path)
1007 .map_err(|err| {
1008 let err = anyhow::Error::from(err)
1009 .context(format!("While opening the certd {:?}", path));
1010 print_error_chain(&err);
1011 err
1012 })?;
1013
1014 for cert in keyring::certs.iter() {
1015 let bytes = cert.bytes();
1016 let mut reader = openpgp::armor::Reader::from_bytes(
1017 &bytes,
1018 openpgp::armor::ReaderMode::VeryTolerant);
1019 let mut bytes = Vec::new();
1020 reader.read_to_end(&mut bytes)
1021 .expect(&format!("{}", cert.base));
1022
1023 certd
1024 .insert_data(&bytes, false, certd_merge)
1025 .with_context(|| {
1026 format!("{} ({})", cert.base, cert.fingerprint)
1027 })
1028 .expect("can insert");
1029 }
1030 drop (certd);
1031
1032 let certd = store::certd::CertD::open(&path).expect("exists");
1033 test_backend(&certd);
1034
1035 Ok(())
1036 }
1037
1038
1039 #[test]
1040 fn cert_store() -> Result<()> {
1041 use std::io::Read;
1042
1043 let path = tempfile::tempdir()?;
1044 let certd = cert_d::CertD::with_base_dir(&path)
1045 .map_err(|err| {
1046 let err = anyhow::Error::from(err)
1047 .context(format!("While opening the certd {:?}", path));
1048 print_error_chain(&err);
1049 err
1050 })?;
1051
1052 for cert in keyring::certs.iter() {
1053 let bytes = cert.bytes();
1054 let mut reader = openpgp::armor::Reader::from_bytes(
1055 &bytes,
1056 openpgp::armor::ReaderMode::VeryTolerant);
1057 let mut bytes = Vec::new();
1058 reader.read_to_end(&mut bytes)
1059 .expect(&format!("{}", cert.base));
1060
1061 certd
1062 .insert_data(&bytes, false, certd_merge)
1063 .with_context(|| {
1064 format!("{} ({})", cert.base, cert.fingerprint)
1065 })
1066 .expect("can insert");
1067 }
1068 drop(certd);
1069
1070 let cert_store = CertStore::open(&path).expect("exists");
1071 test_backend(&cert_store);
1072
1073 Ok(())
1074 }
1075
1076 #[test]
1077 fn cert_store_layered() -> Result<()> {
1078 use std::io::Read;
1079
1080 let mut paths: Vec<tempfile::TempDir> = Vec::new();
1082
1083 let mut cert_store = CertStore::empty();
1084
1085 for cert in keyring::certs.iter() {
1086 let path = tempfile::tempdir()?;
1087 let certd = cert_d::CertD::with_base_dir(&path)
1088 .map_err(|err| {
1089 let err = anyhow::Error::from(err)
1090 .context(format!("While opening the certd {:?}", path));
1091 print_error_chain(&err);
1092 err
1093 })?;
1094
1095 let bytes = cert.bytes();
1096 let mut reader = openpgp::armor::Reader::from_bytes(
1097 &bytes,
1098 openpgp::armor::ReaderMode::VeryTolerant);
1099 let mut bytes = Vec::new();
1100 reader.read_to_end(&mut bytes)
1101 .expect(&format!("{}", cert.base));
1102
1103 certd
1104 .insert_data(&bytes, false, certd_merge)
1105 .with_context(|| {
1106 format!("{} ({})", cert.base, cert.fingerprint)
1107 })
1108 .expect("can insert");
1109 drop(certd);
1110
1111 let certd = store::CertD::open(&path).expect("valid");
1112 cert_store.add_backend(Box::new(certd), AccessMode::Always);
1113
1114 paths.push(path);
1115 }
1116
1117 test_backend(&cert_store);
1118
1119 Ok(())
1120 }
1121
1122 #[test]
1123 fn certs() -> Result<()> {
1124 use std::io::Read;
1125
1126 let mut bytes = Vec::new();
1127 for cert in keyring::certs.iter() {
1128 let binary = cert.bytes();
1129 let mut reader = openpgp::armor::Reader::from_bytes(
1130 &binary,
1131 openpgp::armor::ReaderMode::VeryTolerant);
1132 reader.read_to_end(&mut bytes)
1133 .expect(&format!("{}", cert.base));
1134 }
1135
1136 let backend = store::Certs::from_bytes(&bytes)
1137 .expect("valid");
1138 test_backend(&backend);
1139
1140 Ok(())
1141 }
1142
1143 #[test]
1144 fn certd_with_prefetch() -> Result<()> {
1145 use std::io::Read;
1146
1147 let path = tempfile::tempdir()?;
1148 let certd = cert_d::CertD::with_base_dir(&path)
1149 .map_err(|err| {
1150 let err = anyhow::Error::from(err)
1151 .context(format!("While opening the certd {:?}", path));
1152 print_error_chain(&err);
1153 err
1154 })?;
1155
1156 for cert in keyring::certs.iter() {
1157 let bytes = cert.bytes();
1158 let mut reader = openpgp::armor::Reader::from_bytes(
1159 &bytes,
1160 openpgp::armor::ReaderMode::VeryTolerant);
1161 let mut bytes = Vec::new();
1162 reader.read_to_end(&mut bytes)
1163 .expect(&format!("{}", cert.base));
1164
1165 certd
1166 .insert_data(&bytes, false, certd_merge)
1167 .with_context(|| {
1168 format!("{} ({})", cert.base, cert.fingerprint)
1169 })
1170 .expect("can insert");
1171 }
1172 drop (certd);
1173
1174 let certd = store::CertD::open(&path).expect("exists");
1175 certd.prefetch_all();
1176 test_backend(&certd);
1177
1178 Ok(())
1179 }
1180
1181 #[test]
1182 fn certs_with_prefetch() -> Result<()> {
1183 use std::io::Read;
1184
1185 let mut bytes = Vec::new();
1186 for cert in keyring::certs.iter() {
1187 let binary = cert.bytes();
1188 let mut reader = openpgp::armor::Reader::from_bytes(
1189 &binary,
1190 openpgp::armor::ReaderMode::VeryTolerant);
1191 reader.read_to_end(&mut bytes)
1192 .expect(&format!("{}", cert.base));
1193 }
1194
1195 let backend = store::Certs::from_bytes(&bytes)
1196 .expect("valid");
1197 backend.prefetch_all();
1198 test_backend(&backend);
1199
1200 Ok(())
1201 }
1202
1203 #[test]
1204 fn keyrings() -> Result<()> {
1205 let mut cert_store = CertStore::empty();
1206
1207 let mut base = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
1208 base.push("tests");
1209
1210 cert_store.add_keyrings(
1211 keyring::certs.iter().map(|c| {
1212 PathBuf::from(&base).join(c.filename)
1213 }))?;
1214
1215 test_backend(&cert_store);
1216
1217 Ok(())
1218 }
1219
1220 #[test]
1221 fn certs_multithreaded() -> Result<()> {
1222 use std::io::Read;
1223
1224 let mut bytes = Vec::new();
1225 for cert in keyring::certs.iter() {
1226 let binary = cert.bytes();
1227 let mut reader = openpgp::armor::Reader::from_bytes(
1228 &binary,
1229 openpgp::armor::ReaderMode::VeryTolerant);
1230 reader.read_to_end(&mut bytes)
1231 .expect(&format!("{}", cert.base));
1232 }
1233
1234 let backend = store::Certs::from_bytes(&bytes)
1235 .expect("valid");
1236
1237 std::thread::scope(|s| {
1238 let threads = (0..4usize)
1239 .map(|_| {
1240 s.spawn(|| {
1241 std::thread::sleep(std::time::Duration::new(0, 10));
1244
1245 test_backend(&backend);
1246 })
1247 })
1248 .collect::<Vec<_>>();
1249
1250 threads.into_iter().for_each(|h| {
1251 h.join().expect("joined");
1252 });
1253 });
1254
1255 Ok(())
1256 }
1257
1258 #[test]
1259 fn pep() -> Result<()> {
1260 use std::io::Read;
1261
1262 let mut bytes = Vec::new();
1263 for cert in keyring::certs.iter() {
1264 let binary = cert.bytes();
1265 let mut reader = openpgp::armor::Reader::from_bytes(
1266 &binary,
1267 openpgp::armor::ReaderMode::VeryTolerant);
1268 reader.read_to_end(&mut bytes)
1269 .expect(&format!("{}", cert.base));
1270 }
1271
1272 let backend = Pep::from_bytes(&bytes).expect("valid");
1273 backend.prefetch_all();
1274 test_backend(&backend);
1275
1276 Ok(())
1277 }
1278
1279 fn test_store_update<'a, B>(backend: B) -> Result<()>
1283 where B: store::StoreUpdate<'a>
1284 {
1285 let p = &StandardPolicy::new();
1286
1287 let signing_cert =
1288 Cert::from_bytes(&keyring::halfling_signing.bytes())
1289 .expect("valid");
1290 let fpr = signing_cert.fingerprint();
1291
1292 assert_eq!(signing_cert.keys().count(), 3);
1294 let signing_vc = signing_cert.with_policy(p, None).expect("ok");
1295 let signing_fpr = signing_vc.keys().subkeys()
1296 .for_signing()
1297 .map(|ka| ka.key().fingerprint())
1298 .collect::<Vec<Fingerprint>>();
1299 assert_eq!(signing_fpr.len(), 1);
1300 let signing_fpr = KeyHandle::from(
1301 signing_fpr.into_iter().next().expect("have one"));
1302
1303 let auth_fpr = signing_vc.keys().subkeys()
1304 .for_authentication()
1305 .map(|ka| ka.key().fingerprint())
1306 .collect::<Vec<Fingerprint>>();
1307 assert_eq!(auth_fpr.len(), 1);
1308 let auth_fpr = KeyHandle::from(
1309 auth_fpr.into_iter().next().expect("have one"));
1310
1311 let encryption_cert =
1312 Cert::from_bytes(&keyring::halfling_encryption.bytes())
1313 .expect("valid");
1314 assert_eq!(fpr, encryption_cert.fingerprint());
1315
1316 assert_eq!(encryption_cert.keys().count(), 3);
1318 let encryption_vc = encryption_cert.with_policy(p, None).expect("ok");
1319 let encryption_fpr = encryption_vc.keys().subkeys()
1320 .for_transport_encryption()
1321 .map(|ka| ka.key().fingerprint())
1322 .collect::<Vec<Fingerprint>>();
1323 assert_eq!(encryption_fpr.len(), 1);
1324 let encryption_fpr = KeyHandle::from(
1325 encryption_fpr.into_iter().next().expect("have one"));
1326
1327 assert_ne!(signing_fpr, encryption_fpr);
1328
1329 let auth2_fpr = encryption_vc.keys().subkeys()
1330 .for_authentication()
1331 .map(|ka| ka.key().fingerprint())
1332 .collect::<Vec<Fingerprint>>();
1333 assert_eq!(auth2_fpr.len(), 1);
1334 let auth2_fpr = KeyHandle::from(
1335 auth2_fpr.into_iter().next().expect("have one"));
1336
1337 assert_eq!(auth_fpr, auth2_fpr);
1338
1339 let merged_cert = signing_cert.clone()
1340 .merge_public(encryption_cert.clone()).expect("ok");
1341
1342 let check = |backend: &B, have_enc: bool, cert: &Cert| {
1343 let r = backend.lookup_by_cert(&KeyHandle::from(fpr.clone())).unwrap();
1344 assert_eq!(r.len(), 1);
1345 assert_eq!(r[0].to_cert().expect("ok"), cert);
1346
1347 let r = backend.lookup_by_cert_or_subkey(&signing_fpr).unwrap();
1348 assert_eq!(r.len(), 1);
1349 assert_eq!(r[0].to_cert().expect("ok"), cert);
1350
1351 let r = backend.lookup_by_cert_or_subkey(&auth_fpr).unwrap();
1352 assert_eq!(r.len(), 1);
1353 assert_eq!(r[0].to_cert().expect("ok"), cert);
1354
1355 if have_enc {
1356 let r = backend.lookup_by_cert_or_subkey(&encryption_fpr).unwrap();
1357 assert_eq!(r.len(), 1);
1358 assert_eq!(r[0].to_cert().expect("ok"), cert);
1359 } else {
1360 assert!(backend.lookup_by_cert_or_subkey(&encryption_fpr).is_err());
1361 }
1362
1363 let r = backend.lookup_by_userid(
1364 &UserID::from("<regis@pup.com>")).unwrap();
1365 assert_eq!(r.len(), 1);
1366 assert_eq!(r[0].to_cert().expect("ok"), cert);
1367
1368 let r = backend.lookup_by_userid(
1369 &UserID::from("Halfling <signing@halfling.org>")).unwrap();
1370 assert_eq!(r.len(), 1);
1371 assert_eq!(r[0].to_cert().expect("ok"), cert);
1372
1373 if have_enc {
1374 let r = backend.lookup_by_userid(
1375 &UserID::from("Halfling <encryption@halfling.org>"))
1376 .unwrap();
1377 assert_eq!(r.len(), 1);
1378 assert_eq!(r[0].to_cert().expect("ok"), cert);
1379 } else {
1380 assert!(backend.lookup_by_cert_or_subkey(&encryption_fpr).is_err());
1381 }
1382 };
1383
1384 backend.update(Arc::new(LazyCert::from(signing_cert.clone())))
1386 .expect("ok");
1387 check(&backend, false, &signing_cert);
1388
1389 backend.update(Arc::new(LazyCert::from(encryption_cert.clone())))
1390 .expect("ok");
1391 check(&backend, true, &merged_cert);
1392
1393 backend.update(Arc::new(LazyCert::from(signing_cert.clone())))
1394 .expect("ok");
1395 check(&backend, true, &merged_cert);
1396
1397 Ok(())
1398 }
1399
1400 #[test]
1402 fn test_store_update_cert_store() -> Result<()> {
1403 let path = tempfile::tempdir()?;
1404 let cert_store = CertStore::open(&path).expect("exists");
1405 test_store_update(cert_store)
1406 }
1407
1408 #[test]
1410 fn test_store_update_certd() -> Result<()> {
1411 let path = tempfile::tempdir()?;
1412 let certs = store::CertD::open(&path)?;
1413 test_store_update(&certs)?;
1414
1415 assert_eq!(
1420 certs.load_stats.in_memory_loads(), 0);
1421 assert_eq!(
1422 certs.load_stats.persistent_index_scans(), 1);
1423 Ok(())
1424 }
1425
1426 #[test]
1428 fn test_store_update_certs() -> Result<()> {
1429 let certs = Certs::empty();
1430 test_store_update(certs)
1431 }
1432
1433 #[test]
1435 fn test_store_update_pep() -> Result<()> {
1436 let certs = Pep::empty()?;
1437 test_store_update(certs)
1438 }
1439
1440 #[test]
1441 fn test_store_multithreaded_update_cert_store() -> Result<()> {
1442 let path = tempfile::tempdir()?;
1443 let backend = CertStore::open(&path)?;
1444 test_store_multithreaded_update(backend)
1445 }
1446
1447 #[test]
1448 fn test_store_multithreaded_update_certd() -> Result<()> {
1449 let path = tempfile::tempdir()?;
1450 let backend = store::CertD::open(&path)?;
1451 test_store_multithreaded_update(backend)
1452 }
1453
1454 #[test]
1455 fn test_store_multithreaded_update_certs() -> Result<()> {
1456 let backend = store::Certs::empty();
1457 test_store_multithreaded_update(backend)
1458 }
1459
1460 #[test]
1461 fn test_store_multithreaded_update_pep() -> Result<()> {
1462 let backend = Pep::empty()?;
1463 test_store_multithreaded_update(backend)
1464 }
1465
1466 fn test_store_multithreaded_update<'a, B>(backend: B) -> Result<()>
1467 where B: store::StoreUpdate<'a> + Sync
1468 {
1469 let mut certs = Vec::new();
1470 for cert in keyring::certs.iter() {
1471 let cert = Cert::from_bytes(&cert.bytes()).expect("valid");
1472 certs.push(cert);
1473 }
1474
1475 let mut fprs: Vec<Fingerprint>
1476 = certs.iter().map(|cert| cert.fingerprint()).collect();
1477 fprs.sort();
1478 fprs.dedup();
1479
1480 std::thread::scope(|s| {
1481 let backend = &backend;
1482 let threads = certs.into_iter()
1483 .map(|cert| {
1484 s.spawn(move || {
1485 std::thread::sleep(std::time::Duration::new(0, 10));
1488
1489 let kh = cert.key_handle();
1490 backend.update(Arc::new(LazyCert::from(cert)))
1491 .expect("ok");
1492 assert!(backend.lookup_by_cert(&kh).is_ok());
1493 assert!(backend.lookup_by_cert_or_subkey(&kh).is_ok());
1494 })
1495 })
1496 .collect::<Vec<_>>();
1497
1498 threads.into_iter().for_each(|h| {
1499 h.join().expect("joined");
1500 });
1501 });
1502
1503 assert_eq!(backend.certs().count(), fprs.len());
1504
1505 Ok(())
1506 }
1507
1508}
1509