nethsm/backup.rs
1//! Backup handling.
2
3use std::io::Read;
4
5use crate::Passphrase;
6
7/// Validates a [backup].
8///
9/// Parses a previously created backup file. If `passphrase` is
10/// [`Some`], additionally decrypts the backup and verifies the
11/// encrypted backup version number.
12///
13/// # Errors
14///
15/// Returns an [`nethsm_backup::Error`] if validating a [backup] fails:
16/// * the magic number is missing in the file
17/// * the version number is unknown
18/// * the provided passphrase is incorrect
19///
20/// # Examples
21///
22/// ```no_run
23/// use nethsm::{
24/// Connection,
25/// ConnectionSecurity,
26/// Credentials,
27/// NetHsm,
28/// Passphrase,
29/// validate_backup,
30/// };
31///
32/// # fn main() -> testresult::TestResult {
33/// // create a connection with a user in the Backup role
34/// let nethsm = NetHsm::new(
35/// Connection::new(
36/// "https://example.org/api/v1".try_into()?,
37/// ConnectionSecurity::Unsafe,
38/// ),
39/// Some(Credentials::new(
40/// "backup1".parse()?,
41/// Some(Passphrase::new("passphrase".to_string())),
42/// )),
43/// None,
44/// None,
45/// )?;
46///
47/// // create a backup and write it to file
48/// std::fs::write("nethsm.bkp", nethsm.backup()?)?;
49///
50/// // check for consistency only
51/// validate_backup(&mut std::fs::File::open("nethsm.bkp")?, None)?;
52///
53/// // check for correct passphrase by decrypting and validating the encrypted backup version
54/// validate_backup(
55/// &mut std::fs::File::open("nethsm.bkp")?,
56/// Passphrase::new("a sample password".into()),
57/// )?;
58/// # Ok(())
59/// # }
60/// ```
61/// [backup]: https://docs.nitrokey.com/nethsm/administration#backup
62pub fn validate_backup(
63 reader: &mut impl Read,
64 passphrase: impl Into<Option<Passphrase>>,
65) -> Result<(), nethsm_backup::Error> {
66 let passphrase = passphrase.into();
67 let backup = nethsm_backup::Backup::parse(reader)?;
68 if let Some(passphrase) = passphrase {
69 let decryptor = backup.decrypt(passphrase.expose_borrowed().as_bytes())?;
70 let version = decryptor.version()?;
71 if version.len() != 1 || version[0] != 0 {
72 return Err(nethsm_backup::Error::BadVersion {
73 highest_supported_version: 0,
74 backup_version: version,
75 });
76 }
77 }
78 Ok(())
79}