use thiserror::Error;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ExportSensitivity {
PlaintextPrivate,
Public,
Encrypted,
}
#[derive(Debug, Error, PartialEq, Eq)]
pub enum ExportDenied {
#[error(
"exporting an unencrypted private key requires an interactive confirmation; \
it is refused non-interactively so AUTHS_PASSPHRASE alone cannot authorize a key dump (AUTHS-E5910)"
)]
ConfirmationRequired,
}
pub fn authorize_key_export(
sensitivity: ExportSensitivity,
interactive: bool,
confirmed: bool,
) -> Result<(), ExportDenied> {
match sensitivity {
ExportSensitivity::PlaintextPrivate if !(interactive && confirmed) => {
Err(ExportDenied::ConfirmationRequired)
}
_ => Ok(()),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn plaintext_private_export_refused_when_not_interactively_confirmed() {
assert_eq!(
authorize_key_export(ExportSensitivity::PlaintextPrivate, false, false),
Err(ExportDenied::ConfirmationRequired),
);
assert_eq!(
authorize_key_export(ExportSensitivity::PlaintextPrivate, false, true),
Err(ExportDenied::ConfirmationRequired),
);
}
#[test]
fn plaintext_private_export_allowed_when_interactively_confirmed() {
assert!(authorize_key_export(ExportSensitivity::PlaintextPrivate, true, true).is_ok());
}
#[test]
fn public_and_encrypted_exports_are_never_gated() {
assert!(authorize_key_export(ExportSensitivity::Public, false, false).is_ok());
assert!(authorize_key_export(ExportSensitivity::Encrypted, false, false).is_ok());
}
}