diff --git a/src/cache/lru.rs b/src/cache/lru.rs index 969afbb..b9c9d65 100644 --- a/src/cache/lru.rs +++ b/src/cache/lru.rs @@ -212,10 +212,7 @@ where #[cfg(test)] mod test { use super::*; - use crate::{ - provider::Provider, signature::KeyRing, testing, SecretKeyEntry, SignatureRole, - VerificationStrategy, - }; + use crate::{provider::Provider, testing}; use std::{convert::TryFrom, sync::Arc}; use tokio::sync::Mutex; @@ -411,13 +408,9 @@ mod test { // Make sure all the create operations pass through let provider = TestProvider::default(); let cache = LruCache::new(10, provider.clone()); - let sk = SecretKeyEntry::new("TEST", vec![SignatureRole::Proxy]); let scaffold = testing::Scaffold::load("valid_v1").await; - let verified = VerificationStrategy::MultipleAttestation(vec![]) - .verify(scaffold.invoice.clone(), &KeyRing::default()) - .unwrap(); - let signed = crate::invoice::sign(verified, vec![(SignatureRole::Creator, &sk)]).unwrap(); + let signed = NoopSigned(NoopVerified(scaffold.invoice.clone())); cache .create_invoice(signed) .await diff --git a/src/invoice/mod.rs b/src/invoice/mod.rs index 790053f..8581200 100644 --- a/src/invoice/mod.rs +++ b/src/invoice/mod.rs @@ -447,13 +447,6 @@ mod test { let invoice: crate::Invoice = toml::from_str(invoice).expect("a nice clean parse"); - // Base case: No signature, no keyring should pass. - assert!(invoice.signature.is_none()); - let nokeys = KeyRing::default(); - let verified = VerificationStrategy::default() - .verify(invoice, &nokeys) - .expect("If no signature, then this should verify fine"); - // Create two signing keys. let signer_name1 = "Matt Butcher "; let signer_name2 = "Not Matt Butcher "; @@ -467,7 +460,7 @@ mod test { // Add two signatures let signed = sign( - verified, + invoice, vec![ (SignatureRole::Creator, &keypair1), (SignatureRole::Proxy, &keypair2), diff --git a/src/invoice/verification.rs b/src/invoice/verification.rs index 93dbe8c..12e9581 100644 --- a/src/invoice/verification.rs +++ b/src/invoice/verification.rs @@ -3,7 +3,7 @@ use crate::invoice::Signed; use super::signature::KeyRing; use super::{Invoice, Signature, SignatureError, SignatureRole}; use ed25519_dalek::{PublicKey, Signature as EdSignature}; -use tracing::{debug, info}; +use tracing::debug; use std::borrow::{Borrow, BorrowMut}; use std::fmt::Debug; @@ -193,8 +193,11 @@ impl VerificationStrategy { // Either the Creator or an Approver must be in the keyring match inv.signature.as_ref() { None => { - info!(id = %inv.bindle.id, "No signatures on invoice"); - Ok(VerifiedInvoice(invoice)) + debug!(id = %inv.bindle.id, "No signatures on invoice"); + Err(SignatureError::Unverified( + "No signatures found on invoice. At least one signature is required" + .to_string(), + )) } Some(signatures) => { let mut known_key = false; diff --git a/src/provider/file/mod.rs b/src/provider/file/mod.rs index 96b069f..1f554a7 100644 --- a/src/provider/file/mod.rs +++ b/src/provider/file/mod.rs @@ -647,9 +647,8 @@ impl Drop for PartFile { #[cfg(test)] mod test { use super::*; - use crate::invoice::signature::{KeyRing, SecretKeyEntry, SignatureRole}; - use crate::testing; - use crate::VerificationStrategy; + use crate::verification::NoopVerified; + use crate::{testing, NoopSigned}; use tempfile::tempdir; use tokio::io::AsyncReadExt; @@ -668,17 +667,6 @@ mod test { ); } - fn mock_secret_key() -> SecretKeyEntry { - SecretKeyEntry::new( - "Bogo Key", - vec![ - SignatureRole::Host, - SignatureRole::Proxy, - SignatureRole::Creator, - ], - ) - } - #[tokio::test] async fn test_should_create_yank_invoice() { // Create a temporary directory @@ -691,11 +679,7 @@ mod test { .await; let inv_name = scaffold.invoice.canonical_name(); - let sk = mock_secret_key(); - let verified = VerificationStrategy::MultipleAttestation(vec![]) - .verify(scaffold.invoice.clone(), &KeyRing::default()) - .unwrap(); - let signed = crate::invoice::sign(verified, vec![(SignatureRole::Creator, &sk)]).unwrap(); + let signed = NoopSigned(NoopVerified(scaffold.invoice.clone())); // Create an invoice let (_, missing) = store.create_invoice(signed).await.unwrap(); assert_eq!(1, missing.len()); @@ -732,11 +716,7 @@ mod test { ) .await; - let sk = mock_secret_key(); - let verified = VerificationStrategy::MultipleAttestation(vec![]) - .verify(scaffold.invoice.clone(), &KeyRing::default()) - .unwrap(); - let signed = crate::invoice::sign(verified, vec![(SignatureRole::Creator, &sk)]).unwrap(); + let signed = NoopSigned(NoopVerified(scaffold.invoice.clone())); assert!(store.create_invoice(signed).await.is_err()); } @@ -751,11 +731,7 @@ mod test { ) .await; - let sk = mock_secret_key(); - let verified = VerificationStrategy::MultipleAttestation(vec![]) - .verify(scaffold.invoice.clone(), &KeyRing::default()) - .unwrap(); - let signed = crate::invoice::sign(verified, vec![(SignatureRole::Creator, &sk)]).unwrap(); + let signed = NoopSigned(NoopVerified(scaffold.invoice.clone())); // Create the invoice so we can create a parcel store .create_invoice(signed) @@ -807,11 +783,7 @@ mod test { let scaffold = testing::Scaffold::load("valid_v1").await; - let sk = mock_secret_key(); - let verified = VerificationStrategy::MultipleAttestation(vec![]) - .verify(scaffold.invoice.clone(), &KeyRing::default()) - .unwrap(); - let signed = crate::invoice::sign(verified, vec![(SignatureRole::Creator, &sk)]).unwrap(); + let signed = NoopSigned(NoopVerified(scaffold.invoice.clone())); // Store an invoice first and then create the parcel for it store .create_invoice(signed) @@ -858,11 +830,7 @@ mod test { ) .await; - let sk = mock_secret_key(); - let verified = VerificationStrategy::MultipleAttestation(vec![]) - .verify(scaffold.invoice.clone(), &KeyRing::default()) - .unwrap(); - let signed = crate::invoice::sign(verified, vec![(SignatureRole::Creator, &sk)]).unwrap(); + let signed = NoopSigned(NoopVerified(scaffold.invoice.clone())); store .create_invoice(signed) .await @@ -895,18 +863,9 @@ mod test { ) .await; - let sk = mock_secret_key(); - - // We want two copies, since they will each get signed, and we don't want - // an error that they are already signed. - let verified = VerificationStrategy::MultipleAttestation(vec![]) - .verify(scaffold.invoice.clone(), &KeyRing::default()) - .unwrap(); - let signed1 = crate::invoice::sign(verified, vec![(SignatureRole::Creator, &sk)]).unwrap(); - let verified = VerificationStrategy::MultipleAttestation(vec![]) - .verify(scaffold.invoice.clone(), &KeyRing::default()) - .unwrap(); - let signed2 = crate::invoice::sign(verified, vec![(SignatureRole::Creator, &sk)]).unwrap(); + // We want two copies to try and write at the same time + let signed1 = NoopSigned(NoopVerified(scaffold.invoice.clone())); + let signed2 = NoopSigned(NoopVerified(scaffold.invoice.clone())); let (first, second) = tokio::join!(store.create_invoice(signed1), store.create_invoice(signed2)); diff --git a/src/server/mod.rs b/src/server/mod.rs index 1728482..bd2da17 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -98,13 +98,13 @@ mod test { use crate::authn::always::AlwaysAuthenticate; use crate::authz::always::AlwaysAuthorize; - use crate::invoice::{ - signature::{KeyRing, SecretKeyEntry}, - SignatureRole, VerificationStrategy, - }; + use crate::invoice::{signature::KeyRing, VerificationStrategy}; use crate::provider::Provider; use crate::search::StrictEngine; use crate::testing::{self, MockKeyStore}; + use crate::verification::NoopVerified; + use crate::NoopSigned; + use crate::{signature::SecretKeyStorage, SignatureRole}; use rstest::rstest; use testing::Scaffold; @@ -122,6 +122,8 @@ mod test { let bindles = testing::load_all_files().await; let (store, index, ks) = provider_setup.await; + let valid_v1 = bindles.get("valid_v1").expect("Missing scaffold"); + let api = super::routes::api( store, index, @@ -129,12 +131,9 @@ mod test { AlwaysAuthorize, ks, VerificationStrategy::default(), - KeyRing::default(), + valid_v1.keyring.clone(), ); - // Now that we can't upload parcels before invoices exist, we need to create a bindle that shares some parcels - - let valid_v1 = bindles.get("valid_v1").expect("Missing scaffold"); // Create an invoice pointing to those parcels and make sure the correct response is returned let res = warp::test::request() .method("POST") @@ -183,6 +182,15 @@ mod test { let mut inv = Scaffold::from(valid_v1.to_owned()).invoice; inv.bindle.id = "another.com/bindle/1.0.0".try_into().unwrap(); + inv.signature = None; + inv.sign( + SignatureRole::Creator, + valid_v1 + .keys + .get_first_matching(&SignatureRole::Creator) + .unwrap(), + ) + .unwrap(); let inv = toml::to_vec(&inv).expect("serialization shouldn't fail"); let res = warp::test::request() @@ -291,6 +299,7 @@ mod test { T: Provider + Clone + Send + Sync + 'static, { let (store, index, ks) = provider_setup.await; + let scaffold = testing::Scaffold::load("incomplete").await; let api = super::routes::api( store.clone(), @@ -299,19 +308,12 @@ mod test { AlwaysAuthorize, ks, VerificationStrategy::default(), - KeyRing::default(), + scaffold.keyring.clone(), ); - let sk = SecretKeyEntry::new("test", vec![SignatureRole::Host]); - // Insert an invoice - let scaffold = testing::Scaffold::load("incomplete").await; - let verified = VerificationStrategy::MultipleAttestation(vec![]) - .verify(scaffold.invoice.clone(), &KeyRing::default()) - .unwrap(); - let signed = crate::sign(verified, vec![(SignatureRole::Host, &sk)]).unwrap(); store - .create_invoice(signed) + .create_invoice(NoopSigned(NoopVerified(scaffold.invoice.clone()))) .await .expect("Should be able to insert invoice"); @@ -369,6 +371,9 @@ mod test { let bindles = testing::load_all_files().await; let (store, index, ks) = provider_setup.await; + let valid_raw = bindles.get("valid_v1").expect("Missing scaffold"); + let valid = testing::Scaffold::from(valid_raw.clone()); + let api = super::routes::api( store.clone(), index, @@ -376,17 +381,11 @@ mod test { AlwaysAuthorize, ks, VerificationStrategy::default(), - KeyRing::default(), + valid.keyring.clone(), ); - let valid_raw = bindles.get("valid_v1").expect("Missing scaffold"); - let valid = testing::Scaffold::from(valid_raw.clone()); - let sk = SecretKeyEntry::new("test", vec![SignatureRole::Host]); - let verified = VerificationStrategy::MultipleAttestation(vec![]) - .verify(valid.invoice.clone(), &KeyRing::default()) - .unwrap(); - let signed = crate::sign(verified, vec![(SignatureRole::Host, &sk)]).unwrap(); + store - .create_invoice(signed) + .create_invoice(NoopSigned(NoopVerified(valid.invoice.clone()))) .await .expect("Invoice create failure"); @@ -418,6 +417,7 @@ mod test { T: Provider + Clone + Send + Sync + 'static, { let (store, index, keystore) = provider_setup.await; + let scaffold = testing::Scaffold::load("valid_v1").await; let api = super::routes::api( store.clone(), @@ -426,19 +426,13 @@ mod test { AlwaysAuthorize, keystore.clone(), VerificationStrategy::default(), - KeyRing::default(), + scaffold.keyring.clone(), ); // Insert a parcel - let scaffold = testing::Scaffold::load("valid_v1").await; let parcel = scaffold.parcel_files.get("parcel").expect("Missing parcel"); let data = std::io::Cursor::new(parcel.data.clone()); - let sk = SecretKeyEntry::new("test", vec![SignatureRole::Host]); - let verified = VerificationStrategy::MultipleAttestation(vec![]) - .verify(scaffold.invoice.clone(), &KeyRing::default()) - .unwrap(); - let signed = crate::sign(verified, vec![(SignatureRole::Host, &sk)]).unwrap(); store - .create_invoice(signed) + .create_invoice(NoopSigned(NoopVerified(scaffold.invoice.clone()))) .await .expect("Unable to insert invoice into store"); store @@ -469,15 +463,9 @@ mod test { let scaffold = testing::Scaffold::load("invalid").await; - let sk = SecretKeyEntry::new("test", vec![SignatureRole::Host]); - let verified = VerificationStrategy::MultipleAttestation(vec![]) - .verify(scaffold.invoice.clone(), &KeyRing::default()) - .unwrap(); - let signed = crate::sign(verified, vec![(SignatureRole::Host, &sk)]).unwrap(); - // Create invoice first store - .create_invoice(signed) + .create_invoice(NoopSigned(NoopVerified(scaffold.invoice.clone()))) .await .expect("Unable to create invoice"); @@ -528,16 +516,10 @@ mod test { ); let bindles_to_insert = vec!["incomplete", "valid_v1", "valid_v2"]; - let sk = SecretKeyEntry::new("test", vec![SignatureRole::Host]); - for b in bindles_to_insert.into_iter() { let current = testing::Scaffold::load(b).await; - let verified = VerificationStrategy::MultipleAttestation(vec![]) - .verify(current.invoice.clone(), &KeyRing::default()) - .unwrap(); - let signed = crate::sign(verified, vec![(SignatureRole::Host, &sk)]).unwrap(); store - .create_invoice(signed) + .create_invoice(NoopSigned(NoopVerified(current.invoice.clone()))) .await .expect("Unable to create invoice"); } @@ -630,6 +612,7 @@ mod test { T: Provider + Clone + Send + Sync + 'static, { let (store, index, ks) = provider_setup.await; + let scaffold = testing::Scaffold::load("lotsa_parcels").await; let api = super::routes::api( store.clone(), @@ -638,17 +621,11 @@ mod test { AlwaysAuthorize, ks, VerificationStrategy::default(), - KeyRing::default(), + scaffold.keyring.clone(), ); - let scaffold = testing::Scaffold::load("lotsa_parcels").await; - let sk = SecretKeyEntry::new("test", vec![SignatureRole::Host]); - let verified = VerificationStrategy::MultipleAttestation(vec![]) - .verify(scaffold.invoice.clone(), &KeyRing::default()) - .unwrap(); - let signed = crate::sign(verified, vec![(SignatureRole::Host, &sk)]).unwrap(); store - .create_invoice(signed) + .create_invoice(NoopSigned(NoopVerified(scaffold.invoice.clone()))) .await .expect("Unable to load in invoice"); let parcel = scaffold @@ -710,6 +687,7 @@ mod test { T: Provider + Clone + Send + Sync + 'static, { let (store, index, ks) = provider_setup.await; + let scaffold = testing::RawScaffold::load("valid_v1").await; let api = super::routes::api( store, @@ -718,10 +696,9 @@ mod test { AlwaysAuthorize, ks, VerificationStrategy::default(), - KeyRing::default(), + scaffold.keyring.clone(), ); - let scaffold = testing::RawScaffold::load("valid_v1").await; // Create a valid invoice and make sure the returned invoice is signed let res = warp::test::request() .method("POST") @@ -761,6 +738,7 @@ mod test { T: Provider + Clone + Send + Sync + 'static, { let (store, index, ks) = provider_setup.await; + let scaffold = testing::RawScaffold::load("valid_v1").await; let api = super::routes::api( store, @@ -771,11 +749,9 @@ mod test { crate::authz::anonymous_get::AnonymousGet, ks, VerificationStrategy::default(), - KeyRing::default(), + scaffold.keyring.clone(), ); - let scaffold = testing::RawScaffold::load("valid_v1").await; - // Creating the invoice without a token should fail let res = warp::test::request() .method("POST") diff --git a/src/testing/mod.rs b/src/testing/mod.rs index 3073c65..6dfe1b2 100644 --- a/src/testing/mod.rs +++ b/src/testing/mod.rs @@ -11,10 +11,13 @@ use std::collections::HashMap; use std::path::{Path, PathBuf}; -use crate::invoice::signature::{SecretKeyEntry, SecretKeyStorage, SignatureRole}; +use crate::invoice::signature::{ + KeyRing, SecretKeyEntry, SecretKeyFile, SecretKeyStorage, SignatureRole, +}; use crate::provider::embedded::EmbeddedProvider; use crate::provider::file::FileProvider; use crate::search::StrictEngine; +use crate::signature::KeyRingLoader; use sha2::{Digest, Sha256}; use tempfile::tempdir; @@ -23,6 +26,9 @@ const SCAFFOLD_DIR: &str = "tests/scaffolds"; const INVOICE_FILE: &str = "invoice.toml"; const PARCEL_DIR: &str = "parcels"; const PARCEL_EXTENSION: &str = "dat"; +const KEYRING_FILE: &str = "keyring.toml"; +const SECRETS_FILE: &str = "secret_keys.toml"; +const KEYS_DIR: &str = "keys"; /// The environment variable name used for setting the scaffolds directory pub const SCAFFOLD_DIR_ENV: &str = "BINDLE_SCAFFOLD_DIR"; @@ -53,6 +59,8 @@ pub struct ParcelInfo { pub struct RawScaffold { pub invoice: Vec, pub parcel_files: HashMap, + pub keys: SecretKeyFile, + pub keyring: KeyRing, } impl RawScaffold { @@ -69,12 +77,29 @@ impl RawScaffold { .await .expect("unable to read invoice file"); + let keys_dir = scaffold_dir().join(KEYS_DIR); + + tokio::fs::metadata(&keys_dir) + .await + .expect("Unable to find keys directory"); + + let keys = SecretKeyFile::load_file(keys_dir.join(SECRETS_FILE)) + .await + .expect("Unable to load secret keys file"); + let keyring = keys_dir + .join(KEYRING_FILE) + .load() + .await + .expect("Unable to load keyring file"); + let files = match filter_files(&dir).await { Some(s) => s, None => { return RawScaffold { invoice, parcel_files: HashMap::new(), + keys, + keyring, } } }; @@ -106,6 +131,8 @@ impl RawScaffold { .await .into_iter() .collect(), + keys, + keyring, } } } @@ -118,6 +145,8 @@ impl From for RawScaffold { RawScaffold { invoice, parcel_files: s.parcel_files, + keys: s.keys, + keyring: s.keyring, } } } @@ -128,6 +157,8 @@ impl From for RawScaffold { pub struct Scaffold { pub invoice: crate::Invoice, pub parcel_files: HashMap, + pub keys: SecretKeyFile, + pub keyring: KeyRing, } impl Scaffold { @@ -148,6 +179,8 @@ impl From for Scaffold { Scaffold { invoice, parcel_files: raw.parcel_files, + keys: raw.keys, + keyring: raw.keyring, } } } diff --git a/test/data/keyring.toml b/test/data/keyring.toml new file mode 100644 index 0000000..ae26a29 --- /dev/null +++ b/test/data/keyring.toml @@ -0,0 +1,7 @@ +version = "1.0" + +[[key]] +label = "Starfleet Command " +roles = ["creator"] +key = "Kcs1TSFDkN+dED0Y6Np0fPBqmvUz0EAULIlUsnlU1sw=" +labelSignature = "zDVdD8J/RiW9pCWyEzEhgSehjnRIQk9kYbn+O79UwEaxFPQ/TP4HlxtojS0idmVbpziqeb9I5Y8kozuA8kbhAQ==" diff --git a/test/data/secret_keys.toml b/test/data/secret_keys.toml new file mode 100644 index 0000000..da6d1cb --- /dev/null +++ b/test/data/secret_keys.toml @@ -0,0 +1,6 @@ +version = "1.0" + +[[key]] +label = "Starfleet Command " +keypair = "Ii3Ou5nAZWaLaOsY9duTsVuTpOqvbrcd837ELsxPWhspyzVNIUOQ350QPRjo2nR88Gqa9TPQQBQsiVSyeVTWzA==" +roles = ["creator"] diff --git a/test/data/standalone/1927aefa8fdc8327499e918300e2e49ecb271321530cc5881fcd069ca8372dcd.tar.gz b/test/data/standalone/1927aefa8fdc8327499e918300e2e49ecb271321530cc5881fcd069ca8372dcd.tar.gz index 01c7e77..f04833a 100644 Binary files a/test/data/standalone/1927aefa8fdc8327499e918300e2e49ecb271321530cc5881fcd069ca8372dcd.tar.gz and b/test/data/standalone/1927aefa8fdc8327499e918300e2e49ecb271321530cc5881fcd069ca8372dcd.tar.gz differ diff --git a/test/data/standalone/1927aefa8fdc8327499e918300e2e49ecb271321530cc5881fcd069ca8372dcd/invoice.toml b/test/data/standalone/1927aefa8fdc8327499e918300e2e49ecb271321530cc5881fcd069ca8372dcd/invoice.toml index d259ea9..0b5efef 100644 --- a/test/data/standalone/1927aefa8fdc8327499e918300e2e49ecb271321530cc5881fcd069ca8372dcd/invoice.toml +++ b/test/data/standalone/1927aefa8fdc8327499e918300e2e49ecb271321530cc5881fcd069ca8372dcd/invoice.toml @@ -3,14 +3,22 @@ bindleVersion = "1.0.0" [bindle] name = "enterprise.com/warpcore" version = "1.0.0" -authors = ["Geordi La Forge "] description = "Warp core components" +authors = ["Geordi La Forge "] [annotations] engineering_location = "main" [[parcel]] -label.sha256 = "23f310b54076878fd4c36f0c60ec92011a8b406349b98dd37d08577d17397de5" -label.mediaType = "text/plain" -label.name = "isolinear_chip.txt" -label.size = 9 +[parcel.label] +sha256 = "23f310b54076878fd4c36f0c60ec92011a8b406349b98dd37d08577d17397de5" +mediaType = "text/plain" +name = "isolinear_chip.txt" +size = 9 + +[[signature]] +by = "Starfleet Command " +signature = "1oKW+2RXsE/lSXy3y+0MKKZDhnPModgTxfKuMSMMnVEZlgENIE9qOMTUrQga0QxSiAZiFH15fYkcveC8up8FDA==" +key = "Kcs1TSFDkN+dED0Y6Np0fPBqmvUz0EAULIlUsnlU1sw=" +role = "creator" +at = 1643928286 diff --git a/tests/client.rs b/tests/client.rs index d07c6ac..fa5be9a 100644 --- a/tests/client.rs +++ b/tests/client.rs @@ -6,7 +6,7 @@ use test_util::TestController; use std::convert::TryInto; -use bindle::testing; +use bindle::{signature::SecretKeyStorage, testing, SignatureRole}; use tokio_stream::StreamExt; @@ -164,6 +164,16 @@ async fn test_already_created() { // Make sure we can create an invoice where all parcels already exist let mut other_inv = scaffold.invoice.clone(); other_inv.bindle.id = "another.com/bindle/1.0.0".try_into().unwrap(); + other_inv.signature = None; + other_inv + .sign( + SignatureRole::Creator, + scaffold + .keys + .get_first_matching(&SignatureRole::Creator) + .unwrap(), + ) + .unwrap(); controller .client .create_invoice(other_inv) diff --git a/tests/scaffolds/README.md b/tests/scaffolds/README.md index 07a8712..0cf51d7 100644 --- a/tests/scaffolds/README.md +++ b/tests/scaffolds/README.md @@ -16,3 +16,11 @@ The `invoice.toml` file should contain the invoice, and the parcels directory sh the parcels you want to create that are connected to that invoice. Each parcel should have an opaque `.dat` file that contains the actual data to be uploaded for the parcel. If the `parcels` directory is non-existent, it will assume there are no parcels to upload. + +## Key management + +As Bindle requires signing and keyrings, you will need to sign your scaffolding invoices. A +`KeyRing` will be automatically loaded if the `keys` directory exists in the `scaffolds` directory +and that directory contains a `keyring.toml` file. Likewise, secret keys for signing will be loaded +automatically if the `keys` directory exists in the `scaffolds` directory and that directory +contains a `secret_keys.toml` file diff --git a/tests/scaffolds/incomplete/invoice.toml b/tests/scaffolds/incomplete/invoice.toml index 42d4a5e..2e06ca7 100644 --- a/tests/scaffolds/incomplete/invoice.toml +++ b/tests/scaffolds/incomplete/invoice.toml @@ -3,11 +3,19 @@ bindleVersion = "1.0.0" [bindle] name = "enterprise.com/bridge" version = "1.0.0" -authors = ["Jean-Luc Picard "] description = "Command deck" +authors = ["Jean-Luc Picard "] [[parcel]] -label.sha256 = "e1706ab0a39ac88094b6d54a3f5cdba41fe5a901" -label.mediaType = "text/plain" -label.name = "make_it_so.txt" -label.size = 11 +[parcel.label] +sha256 = "e1706ab0a39ac88094b6d54a3f5cdba41fe5a901" +mediaType = "text/plain" +name = "make_it_so.txt" +size = 11 + +[[signature]] +by = "Starfleet Command " +signature = "uDSLYZS/7Tbg5yb5WTj7m3Wm/QS/U7U4ncfg0u+bUaA2zViRHJskCjMyceQ4fpk43bGCCwQDKSIXLN5cVRLqDw==" +key = "Kcs1TSFDkN+dED0Y6Np0fPBqmvUz0EAULIlUsnlU1sw=" +role = "creator" +at = 1643927146 diff --git a/tests/scaffolds/invalid/invoice.toml b/tests/scaffolds/invalid/invoice.toml index d28dff2..8a0200f 100644 --- a/tests/scaffolds/invalid/invoice.toml +++ b/tests/scaffolds/invalid/invoice.toml @@ -3,14 +3,22 @@ bindleVersion = "1.0.0" [bindle] name = "enterprise.com/holodeck" version = "1.0.0" -authors = ["Enterprise Engineering "] description = "A diversionary room for those long voyages" +authors = ["Enterprise Engineering "] [annotations] broken = "yes" [[parcel]] -label.sha256 = "e1706ab0a39ac88094b6d54a3f5cdba41fe5a901" -label.mediaType = "text/plain" -label.name = "moriarty.txt" -label.size = 12345 +[parcel.label] +sha256 = "e1706ab0a39ac88094b6d54a3f5cdba41fe5a901" +mediaType = "text/plain" +name = "moriarty.txt" +size = 12345 + +[[signature]] +by = "Starfleet Command " +signature = "AS+BOQ4o1Dd9wxwX8hFfPsosplGvj7DpLq2lP0H1as1gcqmUpEm1/lD0ItOhcD/S+vPKUPes917+D0YpIsOpDQ==" +key = "Kcs1TSFDkN+dED0Y6Np0fPBqmvUz0EAULIlUsnlU1sw=" +role = "creator" +at = 1643927146 diff --git a/tests/scaffolds/keys/keyring.toml b/tests/scaffolds/keys/keyring.toml new file mode 100644 index 0000000..ae26a29 --- /dev/null +++ b/tests/scaffolds/keys/keyring.toml @@ -0,0 +1,7 @@ +version = "1.0" + +[[key]] +label = "Starfleet Command " +roles = ["creator"] +key = "Kcs1TSFDkN+dED0Y6Np0fPBqmvUz0EAULIlUsnlU1sw=" +labelSignature = "zDVdD8J/RiW9pCWyEzEhgSehjnRIQk9kYbn+O79UwEaxFPQ/TP4HlxtojS0idmVbpziqeb9I5Y8kozuA8kbhAQ==" diff --git a/tests/scaffolds/keys/secret_keys.toml b/tests/scaffolds/keys/secret_keys.toml new file mode 100644 index 0000000..da6d1cb --- /dev/null +++ b/tests/scaffolds/keys/secret_keys.toml @@ -0,0 +1,6 @@ +version = "1.0" + +[[key]] +label = "Starfleet Command " +keypair = "Ii3Ou5nAZWaLaOsY9duTsVuTpOqvbrcd837ELsxPWhspyzVNIUOQ350QPRjo2nR88Gqa9TPQQBQsiVSyeVTWzA==" +roles = ["creator"] diff --git a/tests/scaffolds/lotsa_parcels/invoice.toml b/tests/scaffolds/lotsa_parcels/invoice.toml index 4f4b979..bb3bcf5 100644 --- a/tests/scaffolds/lotsa_parcels/invoice.toml +++ b/tests/scaffolds/lotsa_parcels/invoice.toml @@ -3,27 +3,36 @@ bindleVersion = "1.0.0" [bindle] name = "enterprise.com/cargobay" version = "1.0.0" -authors = ["Miles O'Brien "] description = "The cargo bay manifest" +authors = ["Miles O'Brien "] [annotations] engineering_location = "main" [[parcel]] -label.sha256 = "23f310b54076878fd4c36f0c60ec92011a8b406349b98dd37d08577d17397de5" -label.mediaType = "text/plain" -label.name = "isolinear_chip.txt" -label.size = 9 +[parcel.label] +sha256 = "23f310b54076878fd4c36f0c60ec92011a8b406349b98dd37d08577d17397de5" +mediaType = "text/plain" +name = "isolinear_chip.txt" +size = 9 [[parcel]] -label.sha256 = "51534027079925942fdea13d4d088c7126f3e456364525b67d6ca0858d6587bc" -label.mediaType = "text/plain" -label.name = "barrel.txt" -label.size = 15 +[parcel.label] +sha256 = "51534027079925942fdea13d4d088c7126f3e456364525b67d6ca0858d6587bc" +mediaType = "text/plain" +name = "barrel.txt" +size = 15 [[parcel]] -label.sha256 = "a6e41416c2bee47e9b97900ba57de696cccc1920e331f5a0d490726a7938d8c6" -label.mediaType = "text/plain" -label.name = "crate.txt" -label.size = 14 +[parcel.label] +sha256 = "a6e41416c2bee47e9b97900ba57de696cccc1920e331f5a0d490726a7938d8c6" +mediaType = "text/plain" +name = "crate.txt" +size = 14 +[[signature]] +by = "Starfleet Command " +signature = "Nw+pLr5BHaGW5INKYYSr2q8lx6KQ91H8coFPvSZZrtI9OcmiXFiRSIfqhCidkFi36NrR4BHAROXfpyONkX4TBA==" +key = "Kcs1TSFDkN+dED0Y6Np0fPBqmvUz0EAULIlUsnlU1sw=" +role = "creator" +at = 1643927146 diff --git a/tests/scaffolds/valid_v1/invoice.toml b/tests/scaffolds/valid_v1/invoice.toml index d259ea9..8ed39f7 100644 --- a/tests/scaffolds/valid_v1/invoice.toml +++ b/tests/scaffolds/valid_v1/invoice.toml @@ -3,14 +3,22 @@ bindleVersion = "1.0.0" [bindle] name = "enterprise.com/warpcore" version = "1.0.0" -authors = ["Geordi La Forge "] description = "Warp core components" +authors = ["Geordi La Forge "] [annotations] engineering_location = "main" [[parcel]] -label.sha256 = "23f310b54076878fd4c36f0c60ec92011a8b406349b98dd37d08577d17397de5" -label.mediaType = "text/plain" -label.name = "isolinear_chip.txt" -label.size = 9 +[parcel.label] +sha256 = "23f310b54076878fd4c36f0c60ec92011a8b406349b98dd37d08577d17397de5" +mediaType = "text/plain" +name = "isolinear_chip.txt" +size = 9 + +[[signature]] +by = "Starfleet Command " +signature = "1oKW+2RXsE/lSXy3y+0MKKZDhnPModgTxfKuMSMMnVEZlgENIE9qOMTUrQga0QxSiAZiFH15fYkcveC8up8FDA==" +key = "Kcs1TSFDkN+dED0Y6Np0fPBqmvUz0EAULIlUsnlU1sw=" +role = "creator" +at = 1643927146 diff --git a/tests/scaffolds/valid_v2/invoice.toml b/tests/scaffolds/valid_v2/invoice.toml index aea4b96..bd24c8a 100644 --- a/tests/scaffolds/valid_v2/invoice.toml +++ b/tests/scaffolds/valid_v2/invoice.toml @@ -3,20 +3,29 @@ bindleVersion = "1.0.0" [bindle] name = "enterprise.com/warpcore" version = "2.0.0" -authors = ["Geordi La Forge "] description = "Warp core components" +authors = ["Geordi La Forge "] [annotations] engineering_location = "main" [[parcel]] -label.sha256 = "23f310b54076878fd4c36f0c60ec92011a8b406349b98dd37d08577d17397de5" -label.mediaType = "text/plain" -label.name = "isolinear_chip.txt" -label.size = 9 +[parcel.label] +sha256 = "23f310b54076878fd4c36f0c60ec92011a8b406349b98dd37d08577d17397de5" +mediaType = "text/plain" +name = "isolinear_chip.txt" +size = 9 [[parcel]] -label.sha256 = "5e244f1c791ee45ec9cc02b281e3b58524e757561e9dc39cdd7ec0f4d328a3d3" -label.mediaType = "text/plain" -label.name = "isolinear_chip_v2.txt" -label.size = 11 +[parcel.label] +sha256 = "5e244f1c791ee45ec9cc02b281e3b58524e757561e9dc39cdd7ec0f4d328a3d3" +mediaType = "text/plain" +name = "isolinear_chip_v2.txt" +size = 11 + +[[signature]] +by = "Starfleet Command " +signature = "ux0eZdwmiKxpP/zZEcabbOAVMbMg8AkR7AEjjpdbGGWcrRF2YwYSKURGYIIiHhGduo1dh5KL/5RK9KEVFSDeDg==" +key = "Kcs1TSFDkN+dED0Y6Np0fPBqmvUz0EAULIlUsnlU1sw=" +role = "creator" +at = 1643927146 diff --git a/tests/test_util.rs b/tests/test_util.rs index 59403e3..39e043e 100644 --- a/tests/test_util.rs +++ b/tests/test_util.rs @@ -3,7 +3,9 @@ use std::path::PathBuf; use std::sync::Arc; use bindle::client::{tokens::NoToken, Client}; -use bindle::signature::{KeyRing, KeyRingSaver, SecretKeyEntry, SecretKeyFile, SignatureRole}; +use bindle::signature::{ + KeyRing, KeyRingLoader, KeyRingSaver, SecretKeyEntry, SecretKeyFile, SignatureRole, +}; #[allow(dead_code)] pub const ENV_BINDLE_URL: &str = "BINDLE_URL"; @@ -14,6 +16,9 @@ pub const BINARY_NAME: &str = "bindle-server"; #[cfg(target_family = "windows")] pub const BINARY_NAME: &str = "bindle-server.exe"; +const SECRET_KEY_FILE: &str = "secret_keys.toml"; +const KEYRING_FILE: &str = "keyring.toml"; + pub struct TestController { pub client: Client, pub base_url: String, @@ -49,17 +54,29 @@ impl TestController { let address = format!("127.0.0.1:{}", get_random_port()); let base_url = format!("http://{}/v1/", address); + let test_data = PathBuf::from( + std::env::var("CARGO_MANIFEST_DIR").expect("Unable to get project directory"), + ) + .join("test/data"); + // Load the base keyring and secret key file + let mut secret_file = SecretKeyFile::load_file(test_data.join(SECRET_KEY_FILE)) + .await + .expect("Unable to load secret file"); + let mut keyring = test_data + .join(KEYRING_FILE) + .load() + .await + .expect("Unable to load keyring file"); + // Create the host key let secret_file_path = tempdir.path().join("secret_keys.toml"); let key = SecretKeyEntry::new("test ", vec![SignatureRole::Host]); - let mut secret_file = SecretKeyFile::default(); secret_file.key.push(key.clone()); secret_file .save_file(&secret_file_path) .await .expect("Unable to save host key"); - let mut keyring = KeyRing::default(); keyring.add_entry(key.try_into().unwrap()); let keyring_path = tempdir.path().join("keyring.toml"); @@ -79,6 +96,8 @@ impl TestController { tempdir.path().to_string_lossy().to_string().as_str(), "-i", address.as_str(), + "--keyring", + keyring_path.to_string_lossy().to_string().as_str(), ]) .env("BINDLE_SIGNING_KEYS", secret_file_path) .spawn()