use std::fmt;
use prikk_error::Result;
use prikk_object::{ObjectEnvelope, ObjectId, ObjectType};
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum SignatureEnvelopeSource {
Object {
object_type: ObjectType,
object_id: ObjectId,
},
ActiveWal {
sequence: u64,
object_id: ObjectId,
},
RefLog {
ref_name: String,
sequence: u64,
object_id: ObjectId,
},
}
impl fmt::Display for SignatureEnvelopeSource {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Object {
object_type,
object_id,
} => write!(formatter, "object {object_type} {object_id}"),
Self::ActiveWal {
sequence,
object_id,
} => write!(
formatter,
"active WAL sequence {sequence} object {object_id}"
),
Self::RefLog {
ref_name,
sequence,
object_id,
} => write!(
formatter,
"ref log {ref_name} sequence {sequence} object {object_id}"
),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct SignatureEnvelopeIssue {
pub code: &'static str,
pub source: SignatureEnvelopeSource,
pub message: String,
}
pub(crate) fn classify_signature_envelope(
envelope: &ObjectEnvelope,
source: SignatureEnvelopeSource,
) -> Result<Vec<SignatureEnvelopeIssue>> {
let conditions = envelope.signature_issues()?;
let mut issues = Vec::with_capacity(3);
if conditions.malformed_shape {
issues.push(issue(
"PRIKK-VERIFY-SIGNATURE-MALFORMED",
&source,
"format-1 envelope contains a signature with malformed algorithm shape",
));
}
if conditions.duplicate {
issues.push(issue(
"PRIKK-VERIFY-SIGNATURE-DUPLICATE",
&source,
"format-1 envelope contains a duplicate signature tuple",
));
}
if conditions.noncanonical_order {
issues.push(issue(
"PRIKK-VERIFY-SIGNATURE-NONCANONICAL-ORDER",
&source,
"format-1 envelope signatures are not in canonical order",
));
}
Ok(issues)
}
fn issue(
code: &'static str,
source: &SignatureEnvelopeSource,
message: &str,
) -> SignatureEnvelopeIssue {
SignatureEnvelopeIssue {
code,
source: source.clone(),
message: message.to_string(),
}
}