use affinidi_tdk::messaging::ATM;
use vti_common::vault::VaultSecret;
pub enum UnsealError {
UnpackFailed(String),
MissingSender,
SenderMismatch { sender: String, caller: String },
CleartextInvalid(String),
}
pub async fn unseal_secret(
atm: &ATM,
caller_did: &str,
jwe: &str,
) -> Result<VaultSecret, UnsealError> {
let (msg, metadata) = atm
.unpack(jwe)
.await
.map_err(|e| UnsealError::UnpackFailed(e.to_string()))?;
let sender = vti_common::auth::bind_authcrypt_sender(&msg, &metadata).map_err(|e| match e {
vti_common::auth::AuthcryptError::NoFrom
| vti_common::auth::AuthcryptError::NoSenderKey => UnsealError::MissingSender,
other => UnsealError::UnpackFailed(other.message("sealed secret")),
})?;
if sender != caller_did {
return Err(UnsealError::SenderMismatch {
sender,
caller: caller_did.to_string(),
});
}
serde_json::from_value(msg.body).map_err(|e| UnsealError::CleartextInvalid(e.to_string()))
}
#[cfg(feature = "tsp")]
pub async fn unseal_tsp_secret(
transport: &crate::messaging::tsp_transport::TspTransport,
caller_did: &str,
message: &str,
) -> Result<VaultSecret, UnsealError> {
let (payload, sender_vid) = transport
.atm()
.tsp()
.unpack(transport.profile(), message)
.await
.map_err(|e| UnsealError::UnpackFailed(e.to_string()))?;
let sender = sender_vid
.split('#')
.next()
.unwrap_or(&sender_vid)
.to_string();
if sender != caller_did {
return Err(UnsealError::SenderMismatch {
sender,
caller: caller_did.to_string(),
});
}
serde_json::from_slice(&payload).map_err(|e| UnsealError::CleartextInvalid(e.to_string()))
}