Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add test for non-trivial KBS policy #703

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
817 changes: 425 additions & 392 deletions Cargo.lock

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion attestation-service/src/policy_engine/opa/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use anyhow::{Context, Result};
use async_trait::async_trait;
use base64::Engine;
use log::debug;
use log::{debug, warn};
use sha2::{Digest, Sha384};
use std::collections::HashMap;
use std::fs;
Expand Down Expand Up @@ -36,6 +36,8 @@ impl OPA {
if !default_policy_path.as_path().exists() {
fs::write(&default_policy_path, default_policy)
.map_err(PolicyError::WriteDefaultPolicyFailed)?;
} else {
warn!("Default policy file is already populated. Existing policy file will be used.");
}

Ok(Self { policy_dir_path })
Expand Down
3 changes: 3 additions & 0 deletions deps/verifier/src/sample/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ fn parse_tee_evidence(quote: &SampleTeeEvidence) -> Result<TeeEvidenceParsedClai
"svn": quote.svn,
"report_data": quote.report_data,
"init_data": quote.init_data,

// Generally TCB claims should originate from the attester.
"launch_digest": "abcde",
});

Ok(claims_map as TeeEvidenceParsedClaim)
Expand Down
3 changes: 3 additions & 0 deletions integration-tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ edition.workspace = true
kbs = { path = "../kbs" }
attestation-service = { path = "../attestation-service" }
kbs-client = { path = "../tools/kbs-client" }
reference-value-provider-service = { path = "../rvps" }

actix-web.workspace = true
actix-rt = "2.10.0"
anyhow.workspace = true
base64.workspace = true
env_logger.workspace = true
log.workspace = true
openssl.workspace = true
Expand All @@ -22,3 +24,4 @@ serde_json.workspace = true
serial_test.workspace = true
tempfile.workspace = true
tokio.workspace = true
tonic.workspace = true
130 changes: 116 additions & 14 deletions integration-tests/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use kbs::config::HttpServerConfig;
use kbs::config::KbsConfig;
use kbs::policy_engine::PolicyEngineConfig;
use kbs::token::AttestationTokenVerifierConfig;
use kbs::ApiServer;

use kbs::plugins::{
implementations::{resource::local_fs::LocalFsRepoDesc, RepositoryConfig},
Expand All @@ -16,17 +17,28 @@ use kbs::plugins::{

use attestation_service::{
config::Config,
rvps::{RvpsConfig, RvpsCrateConfig},
rvps::{grpc::RvpsRemoteConfig, RvpsConfig, RvpsCrateConfig},
token::{ear_broker, simple, AttestationTokenConfig},
};

use reference_value_provider_service::client as rvps_client;
use reference_value_provider_service::config::Config as RVPSConfig;
use reference_value_provider_service::rvps_api::reference_value_provider_service_server::ReferenceValueProviderServiceServer;
use reference_value_provider_service::storage::{local_json, ReferenceValueStorageConfig};
use reference_value_provider_service::{server::RvpsServer, Rvps};

use anyhow::{bail, Result};
use base64::{engine::general_purpose::STANDARD, Engine};
use log::info;
use openssl::pkey::PKey;
use std::io::Write;
use tempfile::{NamedTempFile, TempDir};
use serde_json::json;
use std::sync::Arc;
use tempfile::TempDir;
use tokio::sync::RwLock;
use tonic::transport::Server;

const KBS_URL: &str = "http://127.0.0.1:8080";
const RVPS_URL: &str = "http://127.0.0.1:50003";
const WAIT_TIME: u64 = 3000;

const ALLOW_ALL_POLICY: &str = "
Expand All @@ -42,45 +54,105 @@ const DENY_ALL_POLICY: &str = "
pub enum PolicyType {
AllowAll,
DenyAll,
//Custom(String),
Custom(String),
}

pub enum RvpsType {
Builtin,
Remote,
}

// Parameters that define test behavior (coming from rstest)
pub struct TestParameters {
pub attestation_token_type: String,
pub rvps_type: RvpsType,
}

// Internal state of tests
pub struct TestHarness {
pub kbs_config: KbsConfig,
auth_privkey: String,
kbs_server_handle: actix_web::dev::ServerHandle,
_work_dir: TempDir,

// Future tests will use some parameters at runtime
_test_parameters: TestParameters,
}

impl TestHarness {
pub fn new(test_parameters: TestParameters) -> Result<TestHarness> {
pub async fn new(test_parameters: TestParameters) -> Result<TestHarness> {
let auth_keypair = PKey::generate_ed25519()?;
let auth_pubkey = String::from_utf8(auth_keypair.public_key_to_pem()?)?;
let auth_privkey = String::from_utf8(auth_keypair.private_key_to_pem_pkcs8()?)?;

let work_dir = TempDir::new()?;
let resource_dir = TempDir::new()?;
let policy_path = NamedTempFile::new()?;
let resource_dir = work_dir
.path()
.join("resources")
.into_os_string()
.into_string()
.unwrap();
let as_policy_dir = work_dir
.path()
.join("as_policy")
.into_os_string()
.into_string()
.unwrap();
let kbs_policy_path = work_dir.path().join("kbs_policy");
let rv_path = work_dir
.path()
.join("reference_values")
.into_os_string()
.into_string()
.unwrap();
let auth_pubkey_path = work_dir.path().join("auth_pubkey");

let mut auth_pubkey_path = NamedTempFile::new()?;
auth_pubkey_path.write(auth_pubkey.as_bytes())?;
tokio::fs::write(auth_pubkey_path, auth_pubkey.as_bytes()).await?;

let attestation_token_config = match &test_parameters.attestation_token_type[..] {
"Ear" => AttestationTokenConfig::Ear(ear_broker::Configuration {
duration_min: 5,
policy_dir: as_policy_dir,
..Default::default()
}),
"Simple" => AttestationTokenConfig::Simple(simple::Configuration {
policy_dir: as_policy_dir,
..Default::default()
}),
"Simple" => AttestationTokenConfig::Simple(simple::Configuration::default()),
_ => bail!("Unknown attestation token type. Must be Simple or Ear"),
};

// Setup RVPS either remotely or builtin
let rvps_config = match &test_parameters.rvps_type {
RvpsType::Builtin => RvpsConfig::BuiltIn(RvpsCrateConfig {
storage: ReferenceValueStorageConfig::LocalJson(local_json::Config {
file_path: rv_path,
}),
..Default::default()
}),
RvpsType::Remote => {
info!("Starting Remote RVPS");
let service = Rvps::new(RVPSConfig {
storage: ReferenceValueStorageConfig::LocalJson(local_json::Config {
file_path: rv_path,
}),
..Default::default()
})?;
let inner = Arc::new(RwLock::new(service));
let rvps_server = RvpsServer::new(inner.clone());

let rvps_future = Server::builder()
.add_service(ReferenceValueProviderServiceServer::new(rvps_server))
.serve("127.0.0.1:50003".parse()?);

tokio::spawn(rvps_future);

RvpsConfig::GrpcRemote(RvpsRemoteConfig {
address: RVPS_URL.to_string(),
})
}
};

let kbs_config = KbsConfig {
attestation_token: AttestationTokenVerifierConfig {
trusted_certs_paths: vec![],
Expand All @@ -91,7 +163,7 @@ impl TestHarness {
attestation_service: AttestationConfig {
attestation_service: AttestationServiceConfig::CoCoASBuiltIn(Config {
work_dir: work_dir.path().to_path_buf(),
rvps_config: RvpsConfig::BuiltIn(RvpsCrateConfig::default()),
rvps_config,
attestation_token_broker: attestation_token_config,
}),
timeout: 5,
Expand All @@ -107,29 +179,44 @@ impl TestHarness {
insecure_api: true,
},
policy_engine: PolicyEngineConfig {
policy_path: policy_path.path().to_path_buf(),
policy_path: kbs_policy_path,
},
plugins: vec![PluginsConfig::ResourceStorage(RepositoryConfig::LocalFs(
LocalFsRepoDesc {
dir_path: resource_dir.path().to_str().unwrap().to_string(),
dir_path: resource_dir,
},
))],
};
// Spawn the KBS Server
let api_server = ApiServer::new(kbs_config.clone()).await?;

let kbs_server = api_server.server()?;
let kbs_handle = kbs_server.handle();

tokio::spawn(kbs_server);

Ok(TestHarness {
kbs_config,
auth_privkey,
kbs_server_handle: kbs_handle,
_work_dir: work_dir,
_test_parameters: test_parameters,
})
}

pub async fn cleanup(&self) -> Result<()> {
self.kbs_server_handle.stop(true).await;

Ok(())
}

pub async fn set_policy(&self, policy: PolicyType) -> Result<()> {
info!("TEST: Setting Resource Policy");

let policy_bytes = match policy {
PolicyType::AllowAll => ALLOW_ALL_POLICY.as_bytes().to_vec(),
PolicyType::DenyAll => DENY_ALL_POLICY.as_bytes().to_vec(),
//PolicyType::Custom(p) => p.into_bytes(),
PolicyType::Custom(p) => p.into_bytes(),
};

kbs_client::set_resource_policy(
Expand Down Expand Up @@ -171,4 +258,19 @@ impl TestHarness {
let duration = tokio::time::Duration::from_millis(WAIT_TIME);
tokio::time::sleep(duration).await;
}

pub async fn set_reference_value(&self, key: String, value: String) -> Result<()> {
let provenance = json!({key: [value]}).to_string();
let provenance = STANDARD.encode(provenance);

let message = json!({
"version": "0.1.0",
"type": "sample",
"payload": provenance
});

rvps_client::register("http://127.0.0.1:50003".to_string(), message.to_string()).await?;

Ok(())
}
}
Loading
Loading