mod authorizer;
mod compiled_policies;
pub use compiled_policies::{CompiledPolicies, CompiledPolicy, CompiledPolicySet};
mod compiler;
mod enforcer;
mod extractor;
mod verifier;
use crate::err::{Error, Result};
use crate::symcc::{concretizer::Env, solver::Solver, SymCompiler};
use crate::Asserts;
use extractor::extract_opt;
pub use verifier::{
verify_always_allows_opt, verify_always_denies_opt, verify_always_matches_opt,
verify_disjoint_opt, verify_equivalent_opt, verify_implies_opt, verify_matches_disjoint_opt,
verify_matches_equivalent_opt, verify_matches_implies_opt, verify_never_errors_opt,
verify_never_matches_opt,
};
impl<S: Solver> SymCompiler<S> {
pub async fn sat_asserts_opt<'a>(
&mut self,
asserts: &Asserts,
cpss: impl IntoIterator<Item = &'a CompiledPolicies<'a>> + Clone,
) -> Result<Option<Env>> {
match cpss.clone().into_iter().next() {
None => Err(Error::NoPolicies),
Some(cps) => match self.check_sat_asserts(asserts, cps.symenv()).await? {
None => Ok(None),
Some(interp) => Ok(Some(extract_opt(cpss, &interp)?)),
},
}
}
pub async fn check_never_errors_opt(&mut self, policy: &CompiledPolicy) -> Result<bool> {
self.check_unsat_asserts(&verify_never_errors_opt(policy), &policy.symenv)
.await
}
pub async fn check_never_errors_with_counterexample_opt(
&mut self,
policy: &CompiledPolicy,
) -> Result<Option<Env>> {
self.sat_asserts_opt(
&verify_never_errors_opt(policy),
std::iter::once(&CompiledPolicies::Policy(policy)),
)
.await
}
pub async fn check_always_matches_opt(&mut self, policy: &CompiledPolicy) -> Result<bool> {
self.check_unsat_asserts(&verify_always_matches_opt(policy), &policy.symenv)
.await
}
pub async fn check_always_matches_with_counterexample_opt(
&mut self,
policy: &CompiledPolicy,
) -> Result<Option<Env>> {
self.sat_asserts_opt(
&verify_always_matches_opt(policy),
std::iter::once(&CompiledPolicies::Policy(policy)),
)
.await
}
pub async fn check_never_matches_opt(&mut self, policy: &CompiledPolicy) -> Result<bool> {
self.check_unsat_asserts(&verify_never_matches_opt(policy), &policy.symenv)
.await
}
pub async fn check_never_matches_with_counterexample_opt(
&mut self,
policy: &CompiledPolicy,
) -> Result<Option<Env>> {
self.sat_asserts_opt(
&verify_never_matches_opt(policy),
std::iter::once(&CompiledPolicies::Policy(policy)),
)
.await
}
pub async fn check_matches_equivalent_opt(
&mut self,
policy1: &CompiledPolicy,
policy2: &CompiledPolicy,
) -> Result<bool> {
self.check_unsat_asserts(
&verify_matches_equivalent_opt(policy1, policy2),
&policy1.symenv,
)
.await
}
pub async fn check_matches_equivalent_with_counterexample_opt(
&mut self,
policy1: &CompiledPolicy,
policy2: &CompiledPolicy,
) -> Result<Option<Env>> {
self.sat_asserts_opt(
&verify_matches_equivalent_opt(policy1, policy2),
[
&CompiledPolicies::Policy(policy1),
&CompiledPolicies::Policy(policy2),
],
)
.await
}
pub async fn check_matches_implies_opt(
&mut self,
policy1: &CompiledPolicy,
policy2: &CompiledPolicy,
) -> Result<bool> {
self.check_unsat_asserts(
&verify_matches_implies_opt(policy1, policy2),
&policy1.symenv,
)
.await
}
pub async fn check_matches_implies_with_counterexample_opt(
&mut self,
policy1: &CompiledPolicy,
policy2: &CompiledPolicy,
) -> Result<Option<Env>> {
self.sat_asserts_opt(
&verify_matches_implies_opt(policy1, policy2),
[
&CompiledPolicies::Policy(policy1),
&CompiledPolicies::Policy(policy2),
],
)
.await
}
pub async fn check_matches_disjoint_opt(
&mut self,
policy1: &CompiledPolicy,
policy2: &CompiledPolicy,
) -> Result<bool> {
self.check_unsat_asserts(
&verify_matches_disjoint_opt(policy1, policy2),
&policy1.symenv,
)
.await
}
pub async fn check_matches_disjoint_with_counterexample_opt(
&mut self,
policy1: &CompiledPolicy,
policy2: &CompiledPolicy,
) -> Result<Option<Env>> {
self.sat_asserts_opt(
&verify_matches_disjoint_opt(policy1, policy2),
[
&CompiledPolicies::Policy(policy1),
&CompiledPolicies::Policy(policy2),
],
)
.await
}
pub async fn check_implies_opt(
&mut self,
policies1: &CompiledPolicySet,
policies2: &CompiledPolicySet,
) -> Result<bool> {
self.check_unsat_asserts(&verify_implies_opt(policies1, policies2), &policies1.symenv)
.await
}
pub async fn check_implies_with_counterexample_opt(
&mut self,
policies1: &CompiledPolicySet,
policies2: &CompiledPolicySet,
) -> Result<Option<Env>> {
self.sat_asserts_opt(
&verify_implies_opt(policies1, policies2),
[
&CompiledPolicies::PolicySet(policies1),
&CompiledPolicies::PolicySet(policies2),
],
)
.await
}
pub async fn check_always_allows_opt(&mut self, policies: &CompiledPolicySet) -> Result<bool> {
self.check_unsat_asserts(&verify_always_allows_opt(policies), &policies.symenv)
.await
}
pub async fn check_always_allows_with_counterexample_opt(
&mut self,
policies: &CompiledPolicySet,
) -> Result<Option<Env>> {
self.sat_asserts_opt(
&verify_always_allows_opt(policies),
std::iter::once(&CompiledPolicies::PolicySet(policies)),
)
.await
}
pub async fn check_always_denies_opt(&mut self, policies: &CompiledPolicySet) -> Result<bool> {
self.check_unsat_asserts(&verify_always_denies_opt(policies), &policies.symenv)
.await
}
pub async fn check_always_denies_with_counterexample_opt(
&mut self,
policies: &CompiledPolicySet,
) -> Result<Option<Env>> {
self.sat_asserts_opt(
&verify_always_denies_opt(policies),
std::iter::once(&CompiledPolicies::PolicySet(policies)),
)
.await
}
pub async fn check_equivalent_opt(
&mut self,
policies1: &CompiledPolicySet,
policies2: &CompiledPolicySet,
) -> Result<bool> {
self.check_unsat_asserts(
&verify_equivalent_opt(policies1, policies2),
&policies1.symenv,
)
.await
}
pub async fn check_equivalent_with_counterexample_opt(
&mut self,
policies1: &CompiledPolicySet,
policies2: &CompiledPolicySet,
) -> Result<Option<Env>> {
self.sat_asserts_opt(
&verify_equivalent_opt(policies1, policies2),
[
&CompiledPolicies::PolicySet(policies1),
&CompiledPolicies::PolicySet(policies2),
],
)
.await
}
pub async fn check_disjoint_opt(
&mut self,
policies1: &CompiledPolicySet,
policies2: &CompiledPolicySet,
) -> Result<bool> {
self.check_unsat_asserts(
&verify_disjoint_opt(policies1, policies2),
&policies1.symenv,
)
.await
}
pub async fn check_disjoint_with_counterexample_opt(
&mut self,
policies1: &CompiledPolicySet,
policies2: &CompiledPolicySet,
) -> Result<Option<Env>> {
self.sat_asserts_opt(
&verify_disjoint_opt(policies1, policies2),
[
&CompiledPolicies::PolicySet(policies1),
&CompiledPolicies::PolicySet(policies2),
],
)
.await
}
}