pub use weft_licence_wire::{BindState, BindingRecord, SignedBinding, sign_binding};
use super::{LicenceError, MeshId};
use crate::workload_pkg::codec::hex_decode_exact;
use crate::workload_pkg::{KeyOrigin, TrustAnchors};
pub(crate) fn require_operator(anchors: &TrustAnchors, pk: &[u8; 32]) -> Result<(), LicenceError> {
match anchors.signer(pk) {
Some(k) if k.origin == KeyOrigin::Operator => Ok(()),
_ => Err(LicenceError::UntrustedKey),
}
}
pub fn verify_binding_member(
signed: &SignedBinding,
anchors: &TrustAnchors,
local: &MeshId,
) -> Result<BindingRecord, LicenceError> {
let rec = verify_binding_signature(signed, anchors)?;
if rec.mesh_id != local.to_hex() {
return Err(LicenceError::WrongMesh);
}
Ok(rec)
}
pub(crate) fn verify_binding_signature(
signed: &SignedBinding,
anchors: &TrustAnchors,
) -> Result<BindingRecord, LicenceError> {
let rec = weft_licence_wire::verify_binding_signature(signed, &|pk| {
require_operator(anchors, pk).is_ok()
})?;
for hex in [&rec.grant_pubkey, &rec.steward_pubkey] {
let pk = hex_decode_exact::<32>(hex).unwrap_or_default();
let anchored = anchors.signers.iter().chain(&anchors.cognitum).any(|k| k.public_key == pk);
if anchored {
return Err(LicenceError::Malformed("binding key is a trust anchor".into()));
}
}
Ok(rec)
}
pub trait BindingExtraCheck {
fn check(&self, record: &BindingRecord) -> Result<(), LicenceError>;
}
#[derive(Debug, Default, Clone, Copy)]
pub struct NoExtraChecks;
impl BindingExtraCheck for NoExtraChecks {
fn check(&self, _: &BindingRecord) -> Result<(), LicenceError> {
Ok(())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct AdmissionPosture {
pub enforce: bool,
pub verdict_source_bound: bool,
pub open_membership: bool,
}
impl AdmissionPosture {
pub fn check(&self) -> Result<(), LicenceError> {
if self.open_membership {
Err(LicenceError::BindingRefused("open_membership"))
} else if !self.enforce {
Err(LicenceError::BindingRefused("admission_not_enforce"))
} else if !self.verdict_source_bound {
Err(LicenceError::BindingRefused("no_verdict_source"))
} else {
Ok(())
}
}
}