| extern crate data_encoding; |
| extern crate serde; |
| #[macro_use] |
| extern crate serde_derive; |
| extern crate serde_json as json; |
| extern crate tempdir; |
| extern crate tuf; |
| |
| use data_encoding::HEXLOWER; |
| use std::fs::{self, File, DirBuilder}; |
| use std::io::Read; |
| use std::path::PathBuf; |
| use tempdir::TempDir; |
| use tuf::{Tuf, Config, Error, RemoteRepo}; |
| use tuf::meta::{Key, KeyValue, KeyType}; |
| |
| |
| fn load_vector_meta() -> String { |
| let path = PathBuf::from(env!("CARGO_MANIFEST_DIR")) |
| .join("tests") |
| .join("tuf-test-vectors") |
| .join("tuf") |
| .join("vector-meta.json"); |
| let mut file = File::open(path).expect("couldn't open vector meta"); |
| let mut buf = String::new(); |
| file.read_to_string(&mut buf).expect("couldn't read vector meta"); |
| buf |
| } |
| |
| #[derive(Deserialize)] |
| struct VectorMeta { |
| vectors: Vec<VectorMetaEntry>, |
| } |
| |
| #[derive(Deserialize)] |
| struct VectorMetaEntry { |
| repo: String, |
| error: Option<String>, |
| root_keys: Vec<RootKeyData>, |
| } |
| |
| #[derive(Deserialize)] |
| struct RootKeyData { |
| path: String, |
| #[serde(rename = "type")] |
| typ: String, |
| } |
| |
| fn run_test_vector(test_path: &str) { |
| let temp_dir = TempDir::new("rust-tuf").expect("couldn't make temp dir"); |
| let temp_path = temp_dir.into_path(); |
| |
| println!("Temp dir is: {:?}", temp_path); |
| |
| let vector_meta: VectorMeta = json::from_str(&load_vector_meta()) |
| .expect("couldn't deserializd meta"); |
| |
| let test_vector = vector_meta.vectors |
| .iter() |
| .filter(|v| v.repo == test_path) |
| .collect::<Vec<&VectorMetaEntry>>() |
| .pop() |
| .expect(format!("No repo named {}", test_path).as_str()); |
| |
| let vector_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")) |
| .join("tests") |
| .join("tuf-test-vectors") |
| .join("tuf") |
| .join(test_vector.repo.clone()); |
| |
| println!("The test vector path is: {}", |
| vector_path.to_string_lossy().into_owned()); |
| |
| let root_keys = test_vector.root_keys |
| .iter() |
| .map(|k| { |
| let file_path = vector_path.join("keys").join(k.path.clone()); |
| let mut file = File::open(file_path).expect("couldn't open file"); |
| let mut key = String::new(); |
| file.read_to_string(&mut key).expect("couldn't read key"); |
| |
| match k.typ.as_ref() { |
| "ed25519" => { |
| let val = HEXLOWER.decode(key.replace("\n", "").as_ref()) |
| .expect("key value not hex"); |
| Key { |
| typ: KeyType::Ed25519, |
| value: KeyValue(val), |
| } |
| } |
| x => panic!("unknown key type: {}", x), |
| } |
| }) |
| .collect(); |
| |
| let config = Config::build() |
| .remote(RemoteRepo::File(vector_path.join("repo"))) |
| .local_path(temp_path.clone()) |
| .finish() |
| .expect("bad config"); |
| |
| match (Tuf::from_root_keys(root_keys, config), &test_vector.error) { |
| (Ok(ref tuf), &None) => { |
| assert_eq!(tuf.list_targets(), vec!["targets/file.txt".to_string()]); |
| // first time pulls remote |
| assert_eq!(tuf.fetch_target("targets/file.txt").map(|_| ()), Ok(())); |
| assert!(temp_path.join("targets").join("targets").join("file.txt").exists()); |
| // second time pulls local |
| assert_eq!(tuf.fetch_target("targets/file.txt").map(|_| ()), Ok(())); |
| } |
| |
| (Ok(ref tuf), &Some(ref err)) if err == &"TargetHashMismatch".to_string() => { |
| assert_eq!(tuf.fetch_target("targets/file.txt").map(|_| ()), |
| Err(Error::TargetHashMismatch)); |
| } |
| |
| (Ok(ref tuf), &Some(ref err)) if err == &"OversizedTarget".to_string() => { |
| assert_eq!(tuf.fetch_target("targets/file.txt").map(|_| ()), |
| Err(Error::OversizedTarget)); |
| } |
| |
| (Err(Error::ExpiredMetadata(ref role)), &Some(ref err)) |
| if err.starts_with("ExpiredMetadata::") => { |
| assert!(err.to_lowercase() |
| .ends_with(role.to_string().as_str()), |
| format!("Role: {}, err: {}", role, err)) |
| } |
| |
| (Err(Error::UnmetThreshold(ref role)), &Some(ref err)) |
| if err.starts_with("UnmetThreshold::") => { |
| assert!(err.to_lowercase() |
| .ends_with(role.to_string().as_str()), |
| format!("Role: {}, err: {}", role, err)) |
| } |
| |
| (Err(Error::MetadataHashMismatch(ref role)), &Some(ref err)) |
| if err.starts_with("MetadataHashMismatch::") => { |
| assert!(err.to_lowercase() |
| .ends_with(role.to_string().as_str()), |
| format!("Role: {}, err: {}", role, err)) |
| } |
| |
| (Err(Error::OversizedMetadata(ref role)), &Some(ref err)) |
| if err.starts_with("OversizedMetadata::") => { |
| assert!(err.to_lowercase() |
| .ends_with(role.to_string().as_str()), |
| format!("Role: {}, err: {}", role, err)) |
| } |
| |
| // we're using a json error because the threshold is checked in the deserializer |
| // this may need to change in the future |
| (Err(Error::Json(ref msg)), &Some(ref err)) if err.starts_with("IllegalThreshold::") => { |
| let role = err.split("::").last().unwrap(); |
| |
| assert!(msg.contains("threshold"), |
| format!("Role: {}, err: {}", role, err)); |
| assert!(err.to_lowercase() |
| .contains(role.to_lowercase().as_str()), |
| format!("Role: {}, err: {}", role, err)) |
| } |
| |
| x => panic!("Unexpected failures: {:?}", x), |
| } |
| } |
| |
| #[test] |
| fn vector_001() { |
| run_test_vector("001") |
| } |
| |
| #[test] |
| fn vector_002() { |
| run_test_vector("002") |
| } |
| |
| #[ignore] |
| fn vector_003() { |
| run_test_vector("003") |
| } |
| |
| #[ignore] |
| fn vector_004() { |
| run_test_vector("004") |
| } |
| |
| #[test] |
| fn vector_005() { |
| run_test_vector("005") |
| } |
| |
| #[ignore] |
| fn vector_006() { |
| run_test_vector("006") |
| } |
| |
| #[test] |
| fn vector_007() { |
| run_test_vector("007") |
| } |
| |
| #[test] |
| fn vector_008() { |
| run_test_vector("008") |
| } |
| |
| #[test] |
| fn vector_009() { |
| run_test_vector("009") |
| } |
| |
| #[test] |
| fn vector_010() { |
| run_test_vector("010") |
| } |
| |
| #[test] |
| fn vector_011() { |
| run_test_vector("011") |
| } |
| |
| #[test] |
| fn vector_012() { |
| run_test_vector("012") |
| } |
| |
| #[test] |
| fn vector_013() { |
| run_test_vector("013") |
| } |
| |
| #[test] |
| fn vector_014() { |
| run_test_vector("014") |
| } |
| |
| #[test] |
| fn vector_015() { |
| run_test_vector("015") |
| } |
| |
| #[test] |
| fn vector_016() { |
| run_test_vector("016") |
| } |
| |
| #[test] |
| fn vector_017() { |
| run_test_vector("017") |
| } |
| |
| #[test] |
| fn vector_018() { |
| run_test_vector("018") |
| } |
| |
| #[test] |
| fn vector_019() { |
| run_test_vector("019") |
| } |
| |
| #[test] |
| fn vector_020() { |
| run_test_vector("020") |
| } |
| |
| #[test] |
| fn vector_021() { |
| run_test_vector("021") |
| } |
| |
| #[test] |
| fn vector_022() { |
| run_test_vector("022") |
| } |
| |
| #[test] |
| fn vector_023() { |
| run_test_vector("023") |
| } |
| |
| #[test] |
| fn vector_024() { |
| run_test_vector("024") |
| } |
| |
| #[test] |
| fn vector_025() { |
| run_test_vector("025") |
| } |
| |
| #[test] |
| fn vector_026() { |
| run_test_vector("026") |
| } |
| |
| #[ignore] |
| fn vector_027() { |
| run_test_vector("027") |
| } |
| |
| #[ignore] |
| fn vector_028() { |
| run_test_vector("028") |
| } |
| |
| #[test] |
| fn vector_029() { |
| run_test_vector("029") |
| } |
| |
| #[test] |
| fn vector_030() { |
| run_test_vector("030") |
| } |
| |
| #[test] |
| fn vector_031() { |
| run_test_vector("031") |
| } |
| |
| #[test] |
| fn vector_032() { |
| run_test_vector("032") |
| } |
| |
| #[test] |
| fn vector_033() { |
| run_test_vector("033") |
| } |
| |
| #[test] |
| fn vector_034() { |
| run_test_vector("034") |
| } |