use async_trait::async_trait;
use chrono::Utc;
use crate::error::dpp::DppError;
use crate::ports::seal::SealPort;
use crate::seal::{
SealCapabilities, SealChecks, SealConformanceLevel, SealEnvelope, SealFormat, SealIndication,
SealMode, SealRequest, SealVerification, SealedEnvelope,
};
pub struct GhostSeal;
#[async_trait]
impl SealPort for GhostSeal {
async fn seal(&self, req: SealRequest) -> Result<SealedEnvelope, DppError> {
if !self.capabilities().can_produce(&req) {
return Err(DppError::Validation(
crate::field_error::ValidationErrors::message(format!(
"GhostSeal does not produce {:?}/{:?}",
req.sig_format, req.mode
)),
));
}
Ok(SealedEnvelope {
format: req.sig_format,
seal_value: format!(
"GHOST-SEAL-{}",
&req.payload_hash[..8.min(req.payload_hash.len())]
),
signing_cert_ref: None,
sealed_at: Utc::now(),
placeholder: true,
})
}
async fn verify(&self, env: &SealedEnvelope) -> Result<SealVerification, DppError> {
Ok(SealVerification {
indication: SealIndication::Indeterminate(
"placeholder seal: no validation was performed and none is possible".to_owned(),
),
checks: SealChecks::None,
placeholder: env.placeholder,
})
}
fn capabilities(&self) -> SealCapabilities {
SealCapabilities {
supported_formats: vec![
SealFormat::Jades,
SealFormat::Pades,
SealFormat::Cades,
SealFormat::Xades,
],
supported_modes: vec![SealMode::ProviderSeal, SealMode::OperatorSeal],
supported_levels: vec![
SealConformanceLevel::BaselineB,
SealConformanceLevel::BaselineT,
SealConformanceLevel::BaselineLt,
SealConformanceLevel::BaselineLta,
],
supported_envelopes: vec![
SealEnvelope::Detached,
SealEnvelope::Enveloping,
SealEnvelope::Attached,
SealEnvelope::Parallel,
SealEnvelope::Enveloped,
SealEnvelope::Certification,
SealEnvelope::Revision,
],
}
}
}