1use chrono::{offset::Utc, DateTime};
4use std::cmp::Ordering;
5use std::collections::{HashMap, HashSet};
6use std::marker::PhantomData;
7
8use crate::crypto::PublicKey;
9use crate::error::Error;
10use crate::metadata::{
11 Delegations, Metadata, MetadataPath, MetadataVersion, RawSignedMetadata, RawSignedMetadataSet,
12 RootMetadata, SnapshotMetadata, TargetDescription, TargetPath, TargetsMetadata,
13 TimestampMetadata,
14};
15use crate::pouf::Pouf;
16use crate::verify::{self, Verified};
17use crate::Result;
18
19#[derive(Debug)]
21pub struct Database<D: Pouf> {
22 trusted_root: Verified<RootMetadata>,
23 trusted_targets: Option<Verified<TargetsMetadata>>,
24 trusted_snapshot: Option<Verified<SnapshotMetadata>>,
25 trusted_timestamp: Option<Verified<TimestampMetadata>>,
26 trusted_delegations: HashMap<MetadataPath, Verified<TargetsMetadata>>,
27 pouf: PhantomData<D>,
28}
29
30impl<D: Pouf> Database<D> {
31 pub fn from_root_with_trusted_keys<'a, I>(
36 raw_root: &RawSignedMetadata<D, RootMetadata>,
37 root_threshold: u32,
38 root_keys: I,
39 ) -> Result<Self>
40 where
41 I: IntoIterator<Item = &'a PublicKey>,
42 {
43 let verified_root = {
44 let new_root = verify::verify_signatures(
46 &MetadataPath::root(),
47 raw_root,
48 root_threshold,
49 root_keys,
50 )?;
51
52 verify::verify_signatures(
54 &MetadataPath::root(),
55 raw_root,
56 new_root.root().threshold(),
57 new_root.keys().iter().filter_map(|(k, v)| {
58 if new_root.root().key_ids().contains(k) {
59 Some(v)
60 } else {
61 None
62 }
63 }),
64 )?
65 };
66
67 Ok(Database {
68 trusted_root: verified_root,
69 trusted_snapshot: None,
70 trusted_targets: None,
71 trusted_timestamp: None,
72 trusted_delegations: HashMap::new(),
73 pouf: PhantomData,
74 })
75 }
76
77 pub fn from_trusted_root(raw_root: &RawSignedMetadata<D, RootMetadata>) -> Result<Self> {
85 let verified_root = {
86 let unverified_root = raw_root.parse_untrusted()?.assume_valid()?;
89
90 verify::verify_signatures(
92 &MetadataPath::root(),
93 raw_root,
94 unverified_root.root().threshold(),
95 unverified_root.root_keys(),
96 )?
97 };
98
99 Ok(Database {
100 trusted_root: verified_root,
101 trusted_snapshot: None,
102 trusted_targets: None,
103 trusted_timestamp: None,
104 trusted_delegations: HashMap::new(),
105 pouf: PhantomData,
106 })
107 }
108
109 pub fn from_metadata_with_trusted_keys<'a, I>(
113 metadata_set: &RawSignedMetadataSet<D>,
114 root_threshold: u32,
115 root_keys: I,
116 ) -> Result<Self>
117 where
118 I: IntoIterator<Item = &'a PublicKey>,
119 {
120 Self::from_metadata_with_trusted_keys_and_start_time(
121 &Utc::now(),
122 metadata_set,
123 root_threshold,
124 root_keys,
125 )
126 }
127
128 pub fn from_metadata_with_trusted_keys_and_start_time<'a, I>(
132 start_time: &DateTime<Utc>,
133 metadata_set: &RawSignedMetadataSet<D>,
134 root_threshold: u32,
135 root_keys: I,
136 ) -> Result<Self>
137 where
138 I: IntoIterator<Item = &'a PublicKey>,
139 {
140 let mut db = if let Some(root) = metadata_set.root() {
141 Database::from_root_with_trusted_keys(root, root_threshold, root_keys)?
142 } else {
143 return Err(Error::MetadataNotFound {
144 path: MetadataPath::root(),
145 version: MetadataVersion::None,
146 });
147 };
148
149 db.update_metadata_after_root(start_time, metadata_set)?;
150
151 Ok(db)
152 }
153
154 pub fn from_trusted_metadata(metadata_set: &RawSignedMetadataSet<D>) -> Result<Self> {
162 Self::from_trusted_metadata_with_start_time(metadata_set, &Utc::now())
163 }
164
165 pub fn from_trusted_metadata_with_start_time(
173 metadata_set: &RawSignedMetadataSet<D>,
174 start_time: &DateTime<Utc>,
175 ) -> Result<Self> {
176 let mut db = if let Some(root) = metadata_set.root() {
177 Database::from_trusted_root(root)?
178 } else {
179 return Err(Error::MetadataNotFound {
180 path: MetadataPath::root(),
181 version: MetadataVersion::None,
182 });
183 };
184
185 db.update_metadata_after_root(start_time, metadata_set)?;
186
187 Ok(db)
188 }
189
190 pub fn trusted_root(&self) -> &Verified<RootMetadata> {
192 &self.trusted_root
193 }
194
195 pub fn trusted_targets(&self) -> Option<&Verified<TargetsMetadata>> {
197 self.trusted_targets.as_ref()
198 }
199
200 pub fn trusted_snapshot(&self) -> Option<&Verified<SnapshotMetadata>> {
202 self.trusted_snapshot.as_ref()
203 }
204
205 pub fn trusted_timestamp(&self) -> Option<&Verified<TimestampMetadata>> {
207 self.trusted_timestamp.as_ref()
208 }
209
210 pub fn trusted_delegations(&self) -> &HashMap<MetadataPath, Verified<TargetsMetadata>> {
212 &self.trusted_delegations
213 }
214
215 pub fn update_metadata(&mut self, metadata: &RawSignedMetadataSet<D>) -> Result<bool> {
217 self.update_metadata_with_start_time(metadata, &Utc::now())
218 }
219
220 pub fn update_metadata_with_start_time(
222 &mut self,
223 metadata: &RawSignedMetadataSet<D>,
224 start_time: &DateTime<Utc>,
225 ) -> Result<bool> {
226 let updated = if let Some(root) = metadata.root() {
227 self.update_root(root)?;
228 true
229 } else {
230 false
231 };
232
233 if self.update_metadata_after_root(start_time, metadata)? {
234 Ok(true)
235 } else {
236 Ok(updated)
237 }
238 }
239
240 fn update_metadata_after_root(
241 &mut self,
242 start_time: &DateTime<Utc>,
243 metadata_set: &RawSignedMetadataSet<D>,
244 ) -> Result<bool> {
245 let mut updated = false;
246 if let Some(timestamp) = metadata_set.timestamp() {
247 if self.update_timestamp(start_time, timestamp)?.is_some() {
248 updated = true;
249 }
250 }
251
252 if let Some(snapshot) = metadata_set.snapshot() {
253 if self.update_snapshot(start_time, snapshot)? {
254 updated = true;
255 }
256 }
257
258 if let Some(targets) = metadata_set.targets() {
259 if self.update_targets(start_time, targets)? {
260 updated = true;
261 }
262 }
263
264 Ok(updated)
265 }
266
267 pub fn update_root(&mut self, raw_root: &RawSignedMetadata<D, RootMetadata>) -> Result<()> {
269 let verified = {
270 let trusted_root = &self.trusted_root;
271
272 let new_root = verify::verify_signatures(
283 &MetadataPath::root(),
284 raw_root,
285 trusted_root.root().threshold(),
286 trusted_root.root_keys(),
287 )?;
288
289 let new_root = verify::verify_signatures(
291 &MetadataPath::root(),
292 raw_root,
293 new_root.root().threshold(),
294 new_root.root_keys(),
295 )?;
296
297 let next_root_version = trusted_root.version().checked_add(1).ok_or_else(|| {
309 Error::MetadataVersionMustBeSmallerThanMaxU32(MetadataPath::root())
310 })?;
311
312 if new_root.version() != next_root_version {
313 return Err(Error::AttemptedMetadataRollBack {
314 role: MetadataPath::root(),
315 trusted_version: trusted_root.version(),
316 new_version: new_root.version(),
317 });
318 }
319
320 new_root
338 };
339
340 self.purge_metadata();
352
353 self.trusted_root = verified;
359
360 Ok(())
361 }
362
363 pub fn update_timestamp(
367 &mut self,
368 start_time: &DateTime<Utc>,
369 raw_timestamp: &RawSignedMetadata<D, TimestampMetadata>,
370 ) -> Result<Option<&Verified<TimestampMetadata>>> {
371 let verified = {
372 let trusted_root = &self.trusted_root;
376
377 let new_timestamp = verify::verify_signatures(
386 &MetadataPath::timestamp(),
387 raw_timestamp,
388 trusted_root.timestamp().threshold(),
389 trusted_root.timestamp_keys(),
390 )?;
391
392 if let Some(trusted_timestamp) = &self.trusted_timestamp {
404 match new_timestamp.version().cmp(&trusted_timestamp.version()) {
405 Ordering::Less => {
406 return Err(Error::AttemptedMetadataRollBack {
407 role: MetadataPath::timestamp(),
408 trusted_version: trusted_timestamp.version(),
409 new_version: new_timestamp.version(),
410 });
411 }
412 Ordering::Equal => {
413 return Ok(None);
414 }
415 Ordering::Greater => {}
416 }
417 }
418
419 if let Some(trusted_snapshot) = &self.trusted_snapshot {
434 if trusted_snapshot.version() != new_timestamp.snapshot().version() {
435 self.trusted_snapshot = None;
436 }
437 }
438
439 if new_timestamp.expires() <= start_time {
449 return Err(Error::ExpiredMetadata {
450 path: MetadataPath::timestamp(),
451 expiration: *new_timestamp.expires(),
452 now: *start_time,
453 });
454 }
455
456 new_timestamp
457 };
458
459 self.trusted_timestamp = Some(verified);
460 Ok(self.trusted_timestamp.as_ref())
461 }
462
463 pub fn update_snapshot(
465 &mut self,
466 start_time: &DateTime<Utc>,
467 raw_snapshot: &RawSignedMetadata<D, SnapshotMetadata>,
468 ) -> Result<bool> {
469 let verified = {
470 let trusted_root = self.trusted_root_unexpired(start_time)?;
474 let trusted_timestamp = self.trusted_timestamp_unexpired(start_time)?;
475
476 if let Some(trusted_snapshot) = &self.trusted_snapshot {
477 match trusted_timestamp
478 .snapshot()
479 .version()
480 .cmp(&trusted_snapshot.version())
481 {
482 Ordering::Less => {
483 return Err(Error::AttemptedMetadataRollBack {
484 role: MetadataPath::snapshot(),
485 trusted_version: trusted_snapshot.version(),
486 new_version: trusted_timestamp.snapshot().version(),
487 });
488 }
489 Ordering::Equal => {
490 return Ok(false);
491 }
492 Ordering::Greater => {}
493 }
494 }
495
496 let new_snapshot = verify::verify_signatures(
522 &MetadataPath::snapshot(),
523 raw_snapshot,
524 trusted_root.snapshot().threshold(),
525 trusted_root.snapshot_keys(),
526 )?;
527
528 if new_snapshot.version() != trusted_timestamp.snapshot().version() {
533 return Err(Error::WrongMetadataVersion {
534 parent_role: MetadataPath::timestamp(),
535 child_role: MetadataPath::snapshot(),
536 expected_version: trusted_timestamp.snapshot().version(),
537 new_version: new_snapshot.version(),
538 });
539 }
540
541 if let Some(trusted_snapshot) = &self.trusted_snapshot {
553 if new_snapshot.version() < trusted_snapshot.version() {
554 return Err(Error::AttemptedMetadataRollBack {
555 role: MetadataPath::snapshot(),
556 trusted_version: trusted_snapshot.version(),
557 new_version: new_snapshot.version(),
558 });
559 }
560 }
561
562 new_snapshot
590 };
591
592 if self
594 .trusted_targets
595 .as_ref()
596 .map(|s| s.version())
597 .unwrap_or(0)
598 != verified
599 .meta()
600 .get(&MetadataPath::targets())
601 .map(|m| m.version())
602 .unwrap_or(0)
603 {
604 self.trusted_targets = None;
605 }
606
607 self.trusted_snapshot = Some(verified);
608
609 self.purge_delegations();
611
612 Ok(true)
613 }
614
615 fn purge_delegations(&mut self) {
616 let purge = {
617 let trusted_snapshot = match self.trusted_snapshot() {
618 Some(s) => s,
619 None => return,
620 };
621 let mut purge = HashSet::new();
622 for (role, trusted_definition) in trusted_snapshot.meta().iter() {
623 let trusted_delegation = match self.trusted_delegations.get(role) {
624 Some(d) => d,
625 None => continue,
626 };
627
628 if trusted_delegation.version() > trusted_definition.version() {
629 let _ = purge.insert(role.clone());
630 continue;
631 }
632 }
633
634 purge
635 };
636
637 for role in &purge {
638 let _ = self.trusted_delegations.remove(role);
639 }
640 }
641
642 pub fn update_targets(
644 &mut self,
645 start_time: &DateTime<Utc>,
646 raw_targets: &RawSignedMetadata<D, TargetsMetadata>,
647 ) -> Result<bool> {
648 let verified = {
649 let trusted_root = self.trusted_root_unexpired(start_time)?;
652 let trusted_targets_version = self.trusted_targets.as_ref().map(|t| t.version());
653
654 self.verify_target_or_delegated_target(
655 start_time,
656 &MetadataPath::targets(),
657 raw_targets,
658 trusted_root.targets().threshold(),
659 trusted_root.targets_keys(),
660 trusted_targets_version,
661 )?
662 };
663
664 if let Some(verified) = verified {
665 self.trusted_targets = Some(verified);
666 Ok(true)
667 } else {
668 Ok(false)
669 }
670 }
671
672 pub fn update_delegated_targets(
674 &mut self,
675 start_time: &DateTime<Utc>,
676 parent_role: &MetadataPath,
677 role: &MetadataPath,
678 raw_delegated_targets: &RawSignedMetadata<D, TargetsMetadata>,
679 ) -> Result<bool> {
680 let verified = {
681 let _ = self.trusted_root_unexpired(start_time)?;
684 let _ = self.trusted_snapshot_unexpired(start_time)?;
685 let trusted_targets = self.trusted_targets_unexpired(start_time)?;
686
687 if trusted_targets.delegations().is_empty() {
688 return Err(Error::UnauthorizedDelegation {
689 parent_role: parent_role.clone(),
690 child_role: role.clone(),
691 });
692 };
693
694 let (threshold, keys) = self
695 .find_delegation_threshold_and_keys(parent_role, role)?
696 .ok_or_else(|| Error::UnauthorizedDelegation {
697 parent_role: parent_role.clone(),
698 child_role: role.clone(),
699 })?;
700
701 let trusted_delegated_targets_version =
702 self.trusted_delegations.get(role).map(|t| t.version());
703
704 self.verify_target_or_delegated_target(
705 start_time,
706 role,
707 raw_delegated_targets,
708 threshold,
709 keys.into_iter(),
710 trusted_delegated_targets_version,
711 )?
712 };
713
714 if let Some(verified) = verified {
715 let _ = self.trusted_delegations.insert(role.clone(), verified);
716 Ok(true)
717 } else {
718 Ok(false)
719 }
720 }
721
722 fn verify_target_or_delegated_target<'a>(
723 &self,
724 start_time: &DateTime<Utc>,
725 role: &MetadataPath,
726 raw_targets: &RawSignedMetadata<D, TargetsMetadata>,
727 trusted_targets_threshold: u32,
728 trusted_targets_keys: impl Iterator<Item = &'a PublicKey>,
729 trusted_targets_version: Option<u32>,
730 ) -> Result<Option<Verified<TargetsMetadata>>> {
731 let trusted_snapshot = self.trusted_snapshot_unexpired(start_time)?;
734
735 let trusted_targets_description =
736 trusted_snapshot
737 .meta()
738 .get(role)
739 .ok_or_else(|| Error::MissingMetadataDescription {
740 parent_role: MetadataPath::snapshot(),
741 child_role: role.clone(),
742 })?;
743
744 let new_targets = verify::verify_signatures(
771 role,
772 raw_targets,
773 trusted_targets_threshold,
774 trusted_targets_keys,
775 )?;
776
777 if new_targets.version() != trusted_targets_description.version() {
784 return Err(Error::WrongMetadataVersion {
785 parent_role: MetadataPath::snapshot(),
786 child_role: role.clone(),
787 expected_version: trusted_targets_description.version(),
788 new_version: new_targets.version(),
789 });
790 }
791
792 if let Some(trusted_targets_version) = trusted_targets_version {
793 match new_targets.version().cmp(&trusted_targets_version) {
794 Ordering::Less => {
795 return Err(Error::AttemptedMetadataRollBack {
796 role: role.clone(),
797 trusted_version: trusted_targets_version,
798 new_version: new_targets.version(),
799 });
800 }
801 Ordering::Equal => {
802 return Ok(None);
803 }
804 Ordering::Greater => {}
805 }
806 }
807
808 if new_targets.expires() <= start_time {
818 return Err(Error::ExpiredMetadata {
819 path: role.clone(),
820 expiration: *new_targets.expires(),
821 now: *start_time,
822 });
823 }
824
825 Ok(Some(new_targets))
826 }
827
828 fn find_delegation_threshold_and_keys(
831 &self,
832 parent_role: &MetadataPath,
833 role: &MetadataPath,
834 ) -> Result<Option<(u32, Vec<&PublicKey>)>> {
835 let trusted_parent = if parent_role == &MetadataPath::targets() {
837 if let Some(trusted_targets) = self.trusted_targets() {
838 trusted_targets
839 } else {
840 return Err(Error::MetadataNotFound {
841 path: parent_role.clone(),
842 version: MetadataVersion::None,
843 });
844 }
845 } else if let Some(trusted_parent) = self.trusted_delegations.get(parent_role) {
846 trusted_parent
847 } else {
848 return Err(Error::MetadataNotFound {
849 path: parent_role.clone(),
850 version: MetadataVersion::None,
851 });
852 };
853
854 let trusted_delegations = trusted_parent.delegations();
856
857 for trusted_delegation in trusted_delegations.roles() {
858 if trusted_delegation.name() != role {
859 continue;
860 }
861
862 let authorized_keys = trusted_delegations
864 .keys()
865 .iter()
866 .filter_map(|(k, v)| {
867 if trusted_delegation.key_ids().contains(k) {
868 Some(v)
869 } else {
870 None
871 }
872 })
873 .collect();
874
875 return Ok(Some((trusted_delegation.threshold(), authorized_keys)));
876 }
877
878 Ok(None)
879 }
880
881 pub fn target_description(&self, target_path: &TargetPath) -> Result<TargetDescription> {
886 self.target_description_with_start_time(&Utc::now(), target_path)
887 }
888
889 pub fn target_description_with_start_time(
894 &self,
895 start_time: &DateTime<Utc>,
896 target_path: &TargetPath,
897 ) -> Result<TargetDescription> {
898 let _ = self.trusted_root_unexpired(start_time)?;
899 let _ = self.trusted_snapshot_unexpired(start_time)?;
900 let targets = self.trusted_targets_unexpired(start_time)?;
901
902 if let Some(d) = targets.targets().get(target_path) {
903 return Ok(d.clone());
904 }
905
906 fn lookup<'a, D: Pouf>(
907 start_time: &DateTime<Utc>,
908 tuf: &'a Database<D>,
909 default_terminate: bool,
910 current_depth: u32,
911 target_path: &TargetPath,
912 delegations: &'a Delegations,
913 parents: &[HashSet<TargetPath>],
914 visited: &mut HashSet<&'a MetadataPath>,
915 ) -> (bool, Option<TargetDescription>) {
916 for delegation in delegations.roles() {
917 if visited.contains(delegation.name()) {
918 return (delegation.terminating(), None);
919 }
920 let _ = visited.insert(delegation.name());
921
922 let mut new_parents = parents.to_owned();
923 new_parents.push(delegation.paths().clone());
924
925 if current_depth > 0 && !target_path.matches_chain(parents) {
926 return (delegation.terminating(), None);
927 }
928
929 let trusted_delegation = match tuf.trusted_delegations.get(delegation.name()) {
930 Some(trusted_delegation) => trusted_delegation,
931 None => return (delegation.terminating(), None),
932 };
933
934 if trusted_delegation.expires() <= start_time {
935 return (delegation.terminating(), None);
936 }
937
938 if let Some(target) = trusted_delegation.targets().get(target_path) {
939 return (delegation.terminating(), Some(target.clone()));
940 }
941
942 let trusted_child_delegations = trusted_delegation.delegations();
943
944 if !trusted_child_delegations.roles().is_empty() {
946 let mut new_parents = parents.to_vec();
947 new_parents.push(delegation.paths().clone());
948 let (term, res) = lookup(
949 start_time,
950 tuf,
951 delegation.terminating(),
952 current_depth + 1,
953 target_path,
954 trusted_child_delegations,
955 &new_parents,
956 visited,
957 );
958 if term {
959 return (true, res);
960 } else if res.is_some() {
961 return (term, res);
962 }
963 }
964 }
965 (default_terminate, None)
966 }
967
968 let delegations = targets.delegations();
969 if delegations.roles().is_empty() {
970 Err(Error::TargetNotFound(target_path.clone()))
971 } else {
972 let mut visited = HashSet::new();
973 lookup(
974 start_time,
975 self,
976 false,
977 0,
978 target_path,
979 delegations,
980 &[],
981 &mut visited,
982 )
983 .1
984 .ok_or_else(|| Error::TargetNotFound(target_path.clone()))
985 }
986 }
987
988 fn purge_metadata(&mut self) {
989 self.trusted_snapshot = None;
990 self.trusted_targets = None;
991 self.trusted_timestamp = None;
992 self.trusted_delegations.clear();
993 }
994
995 fn trusted_root_unexpired(&self, start_time: &DateTime<Utc>) -> Result<&RootMetadata> {
996 let trusted_root = &self.trusted_root;
997 if trusted_root.expires() <= start_time {
998 return Err(Error::ExpiredMetadata {
999 path: MetadataPath::root(),
1000 expiration: *trusted_root.expires(),
1001 now: *start_time,
1002 });
1003 }
1004 Ok(trusted_root)
1005 }
1006
1007 fn trusted_timestamp_unexpired(
1008 &self,
1009 start_time: &DateTime<Utc>,
1010 ) -> Result<&TimestampMetadata> {
1011 match self.trusted_timestamp {
1012 Some(ref trusted_timestamp) => {
1013 if trusted_timestamp.expires() <= start_time {
1014 return Err(Error::ExpiredMetadata {
1015 path: MetadataPath::timestamp(),
1016 expiration: *trusted_timestamp.expires(),
1017 now: *start_time,
1018 });
1019 }
1020 Ok(trusted_timestamp)
1021 }
1022 None => Err(Error::MetadataNotFound {
1023 path: MetadataPath::timestamp(),
1024 version: MetadataVersion::None,
1025 }),
1026 }
1027 }
1028
1029 fn trusted_snapshot_unexpired(&self, start_time: &DateTime<Utc>) -> Result<&SnapshotMetadata> {
1030 match self.trusted_snapshot {
1031 Some(ref trusted_snapshot) => {
1032 if trusted_snapshot.expires() <= start_time {
1033 return Err(Error::ExpiredMetadata {
1034 path: MetadataPath::snapshot(),
1035 expiration: *trusted_snapshot.expires(),
1036 now: *start_time,
1037 });
1038 }
1039 Ok(trusted_snapshot)
1040 }
1041 None => Err(Error::MetadataNotFound {
1042 path: MetadataPath::snapshot(),
1043 version: MetadataVersion::None,
1044 }),
1045 }
1046 }
1047
1048 fn trusted_targets_unexpired(&self, start_time: &DateTime<Utc>) -> Result<&TargetsMetadata> {
1049 match self.trusted_targets {
1050 Some(ref trusted_targets) => {
1051 if trusted_targets.expires() <= start_time {
1052 return Err(Error::ExpiredMetadata {
1053 path: MetadataPath::targets(),
1054 expiration: *trusted_targets.expires(),
1055 now: *start_time,
1056 });
1057 }
1058 Ok(trusted_targets)
1059 }
1060 None => Err(Error::MetadataNotFound {
1061 path: MetadataPath::targets(),
1062 version: MetadataVersion::None,
1063 }),
1064 }
1065 }
1066}
1067
1068impl<D: Pouf> Clone for Database<D> {
1069 fn clone(&self) -> Self {
1070 Self {
1071 trusted_root: self.trusted_root.clone(),
1072 trusted_targets: self.trusted_targets.clone(),
1073 trusted_snapshot: self.trusted_snapshot.clone(),
1074 trusted_timestamp: self.trusted_timestamp.clone(),
1075 trusted_delegations: self.trusted_delegations.clone(),
1076 pouf: PhantomData,
1077 }
1078 }
1079}
1080
1081#[cfg(test)]
1082mod test {
1083 use super::*;
1084 use crate::crypto::{Ed25519PrivateKey, HashAlgorithm, PrivateKey};
1085 use crate::metadata::{
1086 RawSignedMetadataSetBuilder, RootMetadataBuilder, SnapshotMetadataBuilder,
1087 TargetsMetadataBuilder, TimestampMetadataBuilder,
1088 };
1089 use crate::pouf::Pouf1;
1090 use assert_matches::assert_matches;
1091 use std::iter::once;
1092 use std::sync::LazyLock;
1093
1094 static KEYS: LazyLock<Vec<Ed25519PrivateKey>> = LazyLock::new(|| {
1095 let keys: &[&[u8]] = &[
1096 include_bytes!("../tests/ed25519/ed25519-1.pk8.der"),
1097 include_bytes!("../tests/ed25519/ed25519-2.pk8.der"),
1098 include_bytes!("../tests/ed25519/ed25519-3.pk8.der"),
1099 include_bytes!("../tests/ed25519/ed25519-4.pk8.der"),
1100 include_bytes!("../tests/ed25519/ed25519-5.pk8.der"),
1101 include_bytes!("../tests/ed25519/ed25519-6.pk8.der"),
1102 ];
1103 keys.iter()
1104 .map(|b| Ed25519PrivateKey::from_pkcs8(b).unwrap())
1105 .collect()
1106 });
1107
1108 #[test]
1109 fn root_trusted_keys_success() {
1110 let root = RootMetadataBuilder::new()
1111 .root_key(KEYS[0].public().clone())
1112 .snapshot_key(KEYS[0].public().clone())
1113 .targets_key(KEYS[0].public().clone())
1114 .timestamp_key(KEYS[0].public().clone())
1115 .signed::<Pouf1>(&KEYS[0])
1116 .unwrap();
1117 let raw_root = root.to_raw().unwrap();
1118
1119 assert_matches!(
1120 Database::from_root_with_trusted_keys(&raw_root, 1, once(KEYS[0].public())),
1121 Ok(_)
1122 );
1123 }
1124
1125 #[test]
1126 fn root_trusted_keys_failure() {
1127 let root = RootMetadataBuilder::new()
1128 .root_key(KEYS[0].public().clone())
1129 .snapshot_key(KEYS[0].public().clone())
1130 .targets_key(KEYS[0].public().clone())
1131 .timestamp_key(KEYS[0].public().clone())
1132 .signed::<Pouf1>(&KEYS[0])
1133 .unwrap();
1134 let raw_root = root.to_raw().unwrap();
1135
1136 assert_matches!(
1137 Database::from_root_with_trusted_keys(&raw_root, 1, once(KEYS[1].public())),
1138 Err(Error::MetadataMissingSignatures {
1139 role,
1140 number_of_valid_signatures: 0,
1141 threshold: 1,
1142 })
1143 if role == MetadataPath::root()
1144 );
1145 }
1146
1147 #[test]
1148 fn from_trusted_metadata_success() {
1149 let root = RootMetadataBuilder::new()
1150 .root_key(KEYS[0].public().clone())
1151 .snapshot_key(KEYS[0].public().clone())
1152 .targets_key(KEYS[0].public().clone())
1153 .timestamp_key(KEYS[0].public().clone())
1154 .signed::<Pouf1>(&KEYS[0])
1155 .unwrap()
1156 .to_raw()
1157 .unwrap();
1158
1159 let metadata = RawSignedMetadataSetBuilder::new().root(root).build();
1160
1161 assert_matches!(Database::from_trusted_metadata(&metadata), Ok(_));
1162 }
1163
1164 #[test]
1165 fn from_trusted_metadata_failure() {
1166 let root = RootMetadataBuilder::new()
1167 .root_key(KEYS[0].public().clone())
1168 .snapshot_key(KEYS[0].public().clone())
1169 .targets_key(KEYS[0].public().clone())
1170 .timestamp_key(KEYS[0].public().clone())
1171 .signed::<Pouf1>(&KEYS[1])
1172 .unwrap()
1173 .to_raw()
1174 .unwrap();
1175
1176 let metadata = RawSignedMetadataSetBuilder::new().root(root).build();
1177
1178 assert_matches!(
1179 Database::from_trusted_metadata(&metadata),
1180 Err(Error::MetadataMissingSignatures {
1181 role,
1182 number_of_valid_signatures: 0,
1183 threshold: 1,
1184 })
1185 if role == MetadataPath::root()
1186 );
1187 }
1188
1189 #[test]
1190 fn from_metadata_with_trusted_keys_success() {
1191 let root = RootMetadataBuilder::new()
1192 .root_key(KEYS[0].public().clone())
1193 .snapshot_key(KEYS[0].public().clone())
1194 .targets_key(KEYS[0].public().clone())
1195 .timestamp_key(KEYS[0].public().clone())
1196 .signed::<Pouf1>(&KEYS[0])
1197 .unwrap()
1198 .to_raw()
1199 .unwrap();
1200
1201 let metadata = RawSignedMetadataSetBuilder::new().root(root).build();
1202
1203 assert_matches!(
1204 Database::from_metadata_with_trusted_keys(&metadata, 1, once(KEYS[0].public())),
1205 Ok(_)
1206 );
1207 }
1208
1209 #[test]
1210 fn from_metadata_with_trusted_keys_failure() {
1211 let root = RootMetadataBuilder::new()
1212 .root_key(KEYS[0].public().clone())
1213 .snapshot_key(KEYS[0].public().clone())
1214 .targets_key(KEYS[0].public().clone())
1215 .timestamp_key(KEYS[0].public().clone())
1216 .signed::<Pouf1>(&KEYS[0])
1217 .unwrap()
1218 .to_raw()
1219 .unwrap();
1220
1221 let metadata = RawSignedMetadataSetBuilder::new().root(root).build();
1222
1223 assert_matches!(
1224 Database::from_metadata_with_trusted_keys(&metadata, 1, once(KEYS[1].public())),
1225 Err(Error::MetadataMissingSignatures {
1226 role,
1227 number_of_valid_signatures: 0,
1228 threshold: 1,
1229 })
1230 if role == MetadataPath::root()
1231 );
1232 }
1233
1234 #[test]
1235 fn good_root_rotation() {
1236 let raw_root = RootMetadataBuilder::new()
1237 .root_key(KEYS[0].public().clone())
1238 .snapshot_key(KEYS[0].public().clone())
1239 .targets_key(KEYS[0].public().clone())
1240 .timestamp_key(KEYS[0].public().clone())
1241 .signed::<Pouf1>(&KEYS[0])
1242 .unwrap()
1243 .to_raw()
1244 .unwrap();
1245
1246 let mut tuf = Database::from_trusted_root(&raw_root).unwrap();
1247
1248 let mut root = RootMetadataBuilder::new()
1249 .version(2)
1250 .root_key(KEYS[1].public().clone())
1251 .snapshot_key(KEYS[1].public().clone())
1252 .targets_key(KEYS[1].public().clone())
1253 .timestamp_key(KEYS[1].public().clone())
1254 .signed::<Pouf1>(&KEYS[1])
1255 .unwrap();
1256
1257 root.add_signature(&KEYS[0]).unwrap();
1259 let raw_root = root.to_raw().unwrap();
1260
1261 assert_matches!(tuf.update_root(&raw_root), Ok(()));
1262
1263 assert_matches!(
1265 tuf.update_root(&raw_root),
1266 Err(Error::AttemptedMetadataRollBack { role, trusted_version: 2, new_version: 2 })
1267 if role == MetadataPath::root()
1268 );
1269 }
1270
1271 #[test]
1272 fn no_cross_sign_root_rotation() {
1273 let raw_root = RootMetadataBuilder::new()
1274 .root_key(KEYS[0].public().clone())
1275 .snapshot_key(KEYS[0].public().clone())
1276 .targets_key(KEYS[0].public().clone())
1277 .timestamp_key(KEYS[0].public().clone())
1278 .signed::<Pouf1>(&KEYS[0])
1279 .unwrap()
1280 .to_raw()
1281 .unwrap();
1282
1283 let mut tuf = Database::from_trusted_root(&raw_root).unwrap();
1284
1285 let raw_root = RootMetadataBuilder::new()
1286 .root_key(KEYS[1].public().clone())
1287 .snapshot_key(KEYS[1].public().clone())
1288 .targets_key(KEYS[1].public().clone())
1289 .timestamp_key(KEYS[1].public().clone())
1290 .signed::<Pouf1>(&KEYS[1])
1291 .unwrap()
1292 .to_raw()
1293 .unwrap();
1294
1295 assert!(tuf.update_root(&raw_root).is_err());
1296 }
1297
1298 #[test]
1299 fn good_timestamp_update() {
1300 let now = Utc::now();
1301
1302 let raw_root = RootMetadataBuilder::new()
1303 .root_key(KEYS[0].public().clone())
1304 .snapshot_key(KEYS[1].public().clone())
1305 .targets_key(KEYS[1].public().clone())
1306 .timestamp_key(KEYS[1].public().clone())
1307 .signed::<Pouf1>(&KEYS[0])
1308 .unwrap()
1309 .to_raw()
1310 .unwrap();
1311
1312 let mut tuf = Database::from_trusted_root(&raw_root).unwrap();
1313
1314 let snapshot = SnapshotMetadataBuilder::new()
1315 .signed::<Pouf1>(&KEYS[1])
1316 .unwrap();
1317
1318 let timestamp =
1319 TimestampMetadataBuilder::from_snapshot(&snapshot, &[HashAlgorithm::Sha256])
1320 .unwrap()
1321 .signed::<Pouf1>(&KEYS[1])
1322 .unwrap();
1323 let raw_timestamp = timestamp.to_raw().unwrap();
1324
1325 assert_matches!(
1326 tuf.update_timestamp(&now, &raw_timestamp),
1327 Ok(Some(_parsed_timestamp))
1328 );
1329
1330 assert_matches!(tuf.update_timestamp(&now, &raw_timestamp), Ok(None))
1332 }
1333
1334 #[test]
1335 fn bad_timestamp_update_wrong_key() {
1336 let now = Utc::now();
1337
1338 let raw_root = RootMetadataBuilder::new()
1339 .root_key(KEYS[0].public().clone())
1340 .snapshot_key(KEYS[1].public().clone())
1341 .targets_key(KEYS[1].public().clone())
1342 .timestamp_key(KEYS[1].public().clone())
1343 .signed::<Pouf1>(&KEYS[0])
1344 .unwrap()
1345 .to_raw()
1346 .unwrap();
1347
1348 let mut tuf = Database::from_trusted_root(&raw_root).unwrap();
1349
1350 let snapshot = SnapshotMetadataBuilder::new()
1351 .signed::<Pouf1>(&KEYS[1])
1352 .unwrap();
1353
1354 let raw_timestamp =
1355 TimestampMetadataBuilder::from_snapshot(&snapshot, &[HashAlgorithm::Sha256])
1356 .unwrap()
1357 .signed::<Pouf1>(&KEYS[0])
1359 .unwrap()
1360 .to_raw()
1361 .unwrap();
1362
1363 assert!(tuf.update_timestamp(&now, &raw_timestamp).is_err())
1364 }
1365
1366 #[test]
1367 fn good_snapshot_update() {
1368 let now = Utc::now();
1369
1370 let raw_root = RootMetadataBuilder::new()
1371 .root_key(KEYS[0].public().clone())
1372 .snapshot_key(KEYS[1].public().clone())
1373 .targets_key(KEYS[2].public().clone())
1374 .timestamp_key(KEYS[2].public().clone())
1375 .signed::<Pouf1>(&KEYS[0])
1376 .unwrap()
1377 .to_raw()
1378 .unwrap();
1379
1380 let mut tuf = Database::from_trusted_root(&raw_root).unwrap();
1381
1382 let snapshot = SnapshotMetadataBuilder::new().signed(&KEYS[1]).unwrap();
1383 let raw_snapshot = snapshot.to_raw().unwrap();
1384
1385 let raw_timestamp =
1386 TimestampMetadataBuilder::from_snapshot(&snapshot, &[HashAlgorithm::Sha256])
1387 .unwrap()
1388 .signed::<Pouf1>(&KEYS[2])
1389 .unwrap()
1390 .to_raw()
1391 .unwrap();
1392
1393 tuf.update_timestamp(&now, &raw_timestamp).unwrap();
1394
1395 assert_matches!(tuf.update_snapshot(&now, &raw_snapshot), Ok(true));
1396
1397 assert_matches!(tuf.update_snapshot(&now, &raw_snapshot), Ok(false));
1399 }
1400
1401 #[test]
1402 fn bad_snapshot_update_wrong_key() {
1403 let now = Utc::now();
1404
1405 let raw_root = RootMetadataBuilder::new()
1406 .root_key(KEYS[0].public().clone())
1407 .snapshot_key(KEYS[1].public().clone())
1408 .targets_key(KEYS[2].public().clone())
1409 .timestamp_key(KEYS[2].public().clone())
1410 .signed::<Pouf1>(&KEYS[0])
1411 .unwrap()
1412 .to_raw()
1413 .unwrap();
1414
1415 let mut tuf = Database::from_trusted_root(&raw_root).unwrap();
1416
1417 let snapshot = SnapshotMetadataBuilder::new()
1418 .signed::<Pouf1>(&KEYS[2])
1419 .unwrap();
1420 let raw_snapshot = snapshot.to_raw().unwrap();
1421
1422 let raw_timestamp =
1423 TimestampMetadataBuilder::from_snapshot(&snapshot, &[HashAlgorithm::Sha256])
1424 .unwrap()
1425 .signed::<Pouf1>(&KEYS[2])
1427 .unwrap()
1428 .to_raw()
1429 .unwrap();
1430
1431 tuf.update_timestamp(&now, &raw_timestamp).unwrap();
1432
1433 assert!(tuf.update_snapshot(&now, &raw_snapshot).is_err());
1434 }
1435
1436 #[test]
1437 fn bad_snapshot_update_wrong_version() {
1438 let now = Utc::now();
1439
1440 let raw_root = RootMetadataBuilder::new()
1441 .root_key(KEYS[0].public().clone())
1442 .snapshot_key(KEYS[1].public().clone())
1443 .targets_key(KEYS[2].public().clone())
1444 .timestamp_key(KEYS[2].public().clone())
1445 .signed::<Pouf1>(&KEYS[0])
1446 .unwrap()
1447 .to_raw()
1448 .unwrap();
1449
1450 let mut tuf = Database::from_trusted_root(&raw_root).unwrap();
1451
1452 let snapshot = SnapshotMetadataBuilder::new()
1453 .version(2)
1454 .signed::<Pouf1>(&KEYS[2])
1455 .unwrap();
1456
1457 let raw_timestamp =
1458 TimestampMetadataBuilder::from_snapshot(&snapshot, &[HashAlgorithm::Sha256])
1459 .unwrap()
1460 .signed::<Pouf1>(&KEYS[2])
1461 .unwrap()
1462 .to_raw()
1463 .unwrap();
1464
1465 tuf.update_timestamp(&now, &raw_timestamp).unwrap();
1466
1467 let raw_snapshot = SnapshotMetadataBuilder::new()
1468 .version(1)
1469 .signed::<Pouf1>(&KEYS[1])
1470 .unwrap()
1471 .to_raw()
1472 .unwrap();
1473
1474 assert!(tuf.update_snapshot(&now, &raw_snapshot).is_err());
1475 }
1476
1477 #[test]
1478 fn good_targets_update() {
1479 let now = Utc::now();
1480
1481 let raw_root = RootMetadataBuilder::new()
1482 .root_key(KEYS[0].public().clone())
1483 .snapshot_key(KEYS[1].public().clone())
1484 .targets_key(KEYS[2].public().clone())
1485 .timestamp_key(KEYS[3].public().clone())
1486 .signed::<Pouf1>(&KEYS[0])
1487 .unwrap()
1488 .to_raw()
1489 .unwrap();
1490
1491 let mut tuf = Database::from_trusted_root(&raw_root).unwrap();
1492
1493 let signed_targets = TargetsMetadataBuilder::new()
1494 .signed::<Pouf1>(&KEYS[2])
1495 .unwrap();
1496 let raw_targets = signed_targets.to_raw().unwrap();
1497
1498 let snapshot = SnapshotMetadataBuilder::new()
1499 .insert_metadata(&signed_targets, &[HashAlgorithm::Sha256])
1500 .unwrap()
1501 .signed::<Pouf1>(&KEYS[1])
1502 .unwrap();
1503 let raw_snapshot = snapshot.to_raw().unwrap();
1504
1505 let raw_timestamp =
1506 TimestampMetadataBuilder::from_snapshot(&snapshot, &[HashAlgorithm::Sha256])
1507 .unwrap()
1508 .signed::<Pouf1>(&KEYS[3])
1509 .unwrap()
1510 .to_raw()
1511 .unwrap();
1512
1513 tuf.update_timestamp(&now, &raw_timestamp).unwrap();
1514 tuf.update_snapshot(&now, &raw_snapshot).unwrap();
1515
1516 assert_matches!(tuf.update_targets(&now, &raw_targets), Ok(true));
1517
1518 assert_matches!(tuf.update_targets(&now, &raw_targets), Ok(false));
1520 }
1521
1522 #[test]
1523 fn bad_targets_update_wrong_key() {
1524 let now = Utc::now();
1525
1526 let raw_root = RootMetadataBuilder::new()
1527 .root_key(KEYS[0].public().clone())
1528 .snapshot_key(KEYS[1].public().clone())
1529 .targets_key(KEYS[2].public().clone())
1530 .timestamp_key(KEYS[3].public().clone())
1531 .signed::<Pouf1>(&KEYS[0])
1532 .unwrap()
1533 .to_raw()
1534 .unwrap();
1535
1536 let mut tuf = Database::from_trusted_root(&raw_root).unwrap();
1537
1538 let signed_targets = TargetsMetadataBuilder::new()
1539 .signed::<Pouf1>(&KEYS[3])
1541 .unwrap();
1542 let raw_targets = signed_targets.to_raw().unwrap();
1543
1544 let snapshot = SnapshotMetadataBuilder::new()
1545 .insert_metadata(&signed_targets, &[HashAlgorithm::Sha256])
1546 .unwrap()
1547 .signed::<Pouf1>(&KEYS[1])
1548 .unwrap();
1549 let raw_snapshot = snapshot.to_raw().unwrap();
1550
1551 let raw_timestamp =
1552 TimestampMetadataBuilder::from_snapshot(&snapshot, &[HashAlgorithm::Sha256])
1553 .unwrap()
1554 .signed::<Pouf1>(&KEYS[3])
1555 .unwrap()
1556 .to_raw()
1557 .unwrap();
1558
1559 tuf.update_timestamp(&now, &raw_timestamp).unwrap();
1560 tuf.update_snapshot(&now, &raw_snapshot).unwrap();
1561
1562 assert!(tuf.update_targets(&now, &raw_targets).is_err());
1563 }
1564
1565 #[test]
1566 fn bad_targets_update_wrong_version() {
1567 let now = Utc::now();
1568
1569 let raw_root = RootMetadataBuilder::new()
1570 .root_key(KEYS[0].public().clone())
1571 .snapshot_key(KEYS[1].public().clone())
1572 .targets_key(KEYS[2].public().clone())
1573 .timestamp_key(KEYS[3].public().clone())
1574 .signed::<Pouf1>(&KEYS[0])
1575 .unwrap()
1576 .to_raw()
1577 .unwrap();
1578
1579 let mut tuf = Database::from_trusted_root(&raw_root).unwrap();
1580
1581 let signed_targets = TargetsMetadataBuilder::new()
1582 .version(2)
1583 .signed::<Pouf1>(&KEYS[2])
1584 .unwrap();
1585
1586 let snapshot = SnapshotMetadataBuilder::new()
1587 .insert_metadata(&signed_targets, &[HashAlgorithm::Sha256])
1588 .unwrap()
1589 .signed::<Pouf1>(&KEYS[1])
1590 .unwrap();
1591 let raw_snapshot = snapshot.to_raw().unwrap();
1592
1593 let raw_timestamp =
1594 TimestampMetadataBuilder::from_snapshot(&snapshot, &[HashAlgorithm::Sha256])
1595 .unwrap()
1596 .signed::<Pouf1>(&KEYS[3])
1597 .unwrap()
1598 .to_raw()
1599 .unwrap();
1600
1601 tuf.update_timestamp(&now, &raw_timestamp).unwrap();
1602 tuf.update_snapshot(&now, &raw_snapshot).unwrap();
1603
1604 let raw_targets = TargetsMetadataBuilder::new()
1605 .version(1)
1606 .signed::<Pouf1>(&KEYS[2])
1607 .unwrap()
1608 .to_raw()
1609 .unwrap();
1610
1611 assert!(tuf.update_targets(&now, &raw_targets).is_err());
1612 }
1613
1614 #[test]
1615 fn test_update_metadata_succeeds_with_good_metadata() {
1616 let raw_root1 = RootMetadataBuilder::new()
1617 .root_key(KEYS[0].public().clone())
1618 .targets_key(KEYS[1].public().clone())
1619 .snapshot_key(KEYS[2].public().clone())
1620 .timestamp_key(KEYS[3].public().clone())
1621 .signed::<Pouf1>(&KEYS[0])
1622 .unwrap()
1623 .to_raw()
1624 .unwrap();
1625
1626 let signed_targets1 = TargetsMetadataBuilder::new()
1627 .signed::<Pouf1>(&KEYS[1])
1628 .unwrap();
1629 let raw_targets1 = signed_targets1.to_raw().unwrap();
1630
1631 let snapshot1 = SnapshotMetadataBuilder::new()
1632 .insert_metadata(&signed_targets1, &[HashAlgorithm::Sha256])
1633 .unwrap()
1634 .signed::<Pouf1>(&KEYS[2])
1635 .unwrap();
1636 let raw_snapshot1 = snapshot1.to_raw().unwrap();
1637
1638 let raw_timestamp1 =
1639 TimestampMetadataBuilder::from_snapshot(&snapshot1, &[HashAlgorithm::Sha256])
1640 .unwrap()
1641 .signed::<Pouf1>(&KEYS[3])
1642 .unwrap()
1643 .to_raw()
1644 .unwrap();
1645
1646 let metadata1 = RawSignedMetadataSetBuilder::new()
1647 .root(raw_root1)
1648 .targets(raw_targets1)
1649 .snapshot(raw_snapshot1)
1650 .timestamp(raw_timestamp1)
1651 .build();
1652
1653 let mut tuf = Database::from_trusted_metadata(&metadata1).unwrap();
1654
1655 let raw_root2 = RootMetadataBuilder::new()
1656 .version(2)
1657 .root_key(KEYS[0].public().clone())
1658 .targets_key(KEYS[1].public().clone())
1659 .snapshot_key(KEYS[2].public().clone())
1660 .timestamp_key(KEYS[3].public().clone())
1661 .signed::<Pouf1>(&KEYS[0])
1662 .unwrap()
1663 .to_raw()
1664 .unwrap();
1665
1666 let signed_targets2 = TargetsMetadataBuilder::new()
1667 .version(2)
1668 .signed::<Pouf1>(&KEYS[1])
1669 .unwrap();
1670 let raw_targets2 = signed_targets2.to_raw().unwrap();
1671
1672 let snapshot2 = SnapshotMetadataBuilder::new()
1673 .version(2)
1674 .insert_metadata(&signed_targets2, &[HashAlgorithm::Sha256])
1675 .unwrap()
1676 .signed::<Pouf1>(&KEYS[2])
1677 .unwrap();
1678 let raw_snapshot2 = snapshot2.to_raw().unwrap();
1679
1680 let raw_timestamp2 =
1681 TimestampMetadataBuilder::from_snapshot(&snapshot2, &[HashAlgorithm::Sha256])
1682 .unwrap()
1683 .version(2)
1684 .signed::<Pouf1>(&KEYS[3])
1685 .unwrap()
1686 .to_raw()
1687 .unwrap();
1688
1689 let metadata2 = RawSignedMetadataSetBuilder::new()
1690 .root(raw_root2)
1691 .targets(raw_targets2)
1692 .snapshot(raw_snapshot2)
1693 .timestamp(raw_timestamp2)
1694 .build();
1695
1696 assert_matches!(tuf.update_metadata(&metadata2), Ok(true));
1697 }
1698
1699 #[test]
1700 fn test_update_metadata_fails_with_bad_metadata() {
1701 let raw_root1 = RootMetadataBuilder::new()
1702 .root_key(KEYS[0].public().clone())
1703 .targets_key(KEYS[1].public().clone())
1704 .snapshot_key(KEYS[2].public().clone())
1705 .timestamp_key(KEYS[3].public().clone())
1706 .signed::<Pouf1>(&KEYS[0])
1707 .unwrap()
1708 .to_raw()
1709 .unwrap();
1710
1711 let signed_targets1 = TargetsMetadataBuilder::new()
1712 .signed::<Pouf1>(&KEYS[1])
1713 .unwrap();
1714 let raw_targets1 = signed_targets1.to_raw().unwrap();
1715
1716 let snapshot1 = SnapshotMetadataBuilder::new()
1717 .insert_metadata(&signed_targets1, &[HashAlgorithm::Sha256])
1718 .unwrap()
1719 .signed::<Pouf1>(&KEYS[2])
1720 .unwrap();
1721 let raw_snapshot1 = snapshot1.to_raw().unwrap();
1722
1723 let raw_timestamp1 =
1724 TimestampMetadataBuilder::from_snapshot(&snapshot1, &[HashAlgorithm::Sha256])
1725 .unwrap()
1726 .signed::<Pouf1>(&KEYS[3])
1727 .unwrap()
1728 .to_raw()
1729 .unwrap();
1730
1731 let metadata1 = RawSignedMetadataSetBuilder::new()
1732 .root(raw_root1)
1733 .targets(raw_targets1)
1734 .snapshot(raw_snapshot1)
1735 .timestamp(raw_timestamp1)
1736 .build();
1737
1738 let mut tuf = Database::from_trusted_metadata(&metadata1).unwrap();
1739
1740 let raw_root2 = RootMetadataBuilder::new()
1741 .version(2)
1742 .root_key(KEYS[1].public().clone())
1743 .targets_key(KEYS[2].public().clone())
1744 .snapshot_key(KEYS[3].public().clone())
1745 .timestamp_key(KEYS[4].public().clone())
1746 .signed::<Pouf1>(&KEYS[1])
1747 .unwrap()
1748 .to_raw()
1749 .unwrap();
1750
1751 let signed_targets2 = TargetsMetadataBuilder::new()
1752 .version(2)
1753 .signed::<Pouf1>(&KEYS[1])
1754 .unwrap();
1755 let raw_targets2 = signed_targets2.to_raw().unwrap();
1756
1757 let snapshot2 = SnapshotMetadataBuilder::new()
1758 .version(2)
1759 .insert_metadata(&signed_targets2, &[HashAlgorithm::Sha256])
1760 .unwrap()
1761 .signed::<Pouf1>(&KEYS[2])
1762 .unwrap();
1763 let raw_snapshot2 = snapshot2.to_raw().unwrap();
1764
1765 let raw_timestamp2 =
1766 TimestampMetadataBuilder::from_snapshot(&snapshot2, &[HashAlgorithm::Sha256])
1767 .unwrap()
1768 .version(2)
1769 .signed::<Pouf1>(&KEYS[3])
1770 .unwrap()
1771 .to_raw()
1772 .unwrap();
1773
1774 let metadata2 = RawSignedMetadataSetBuilder::new()
1775 .root(raw_root2)
1776 .targets(raw_targets2)
1777 .snapshot(raw_snapshot2)
1778 .timestamp(raw_timestamp2)
1779 .build();
1780
1781 assert_matches!(
1782 tuf.update_metadata(&metadata2),
1783 Err(Error::MetadataMissingSignatures {
1784 role,
1785 number_of_valid_signatures: 0,
1786 threshold: 1,
1787 })
1788 if role == MetadataPath::root()
1789 );
1790 }
1791}