Crate nethsm_backup

source
Expand description

§NetHSM backup

A library to parse, decrypt, validate and browse NetHSM backups.

§Format

The backup format is an internal detail of the NetHSM. This library implements the version 0 format which should be supported even on newer devices.

The backup file consists of two formats: one outer, which contains unencrypted magic values and framing for the inner format. The inner format can be accessed after decrypting values within the outer one. Both of them are using similar primitives such as length-prefixed byte vectors.

Length-prefixed byte vectors are always encoded as 3 big-endian length bytes followed by the given number of bytes.

§Outer format

The outer format contains, in order, the header:

  • magic value: 15 bytes consisting of: _NETHSM_BACKUP_,
  • version tag: 1 byte, currently there’s only one version which is stored as a NUL byte (0x00).

and several length-prefixed values:

  • salt,
  • encrypted inner version,
  • encrypted domain key,
  • variable number of encrypted items.

§Inner format

The inner format is accessed by decrypting the outer format. The decryption key is derived using scrypt based on the passphrase provided by the user and the salt contained in the outer format.

The following values exist in the inner format:

  • version: inner format version, the only known value is 0x00, this is retrieved by decrypting encrypted inner version with the backup-version associated additional data,
  • domain key: decrypted inner domain key with domain-key as AAD,
  • items: decrypted key/values with the backup AAD, they are stored as a length-prefixed string for a key and a value which is stored as a rest of the decrypted value.

Sample list of inner format keys:

  • /.initialized
  • /authentication/.version
  • /authentication/admin
  • /authentication/backup1
  • /authentication/encoperator1
  • /authentication/metrics1
  • /authentication/namespace1~admin
  • /authentication/namespace1~operator
  • /authentication/namespace2~admin
  • /authentication/namespace2~operator
  • /authentication/operator1
  • /authentication/operator2
  • /config/backup-key
  • /config/backup-salt
  • /config/certificate
  • /config/private-key
  • /config/time-offset
  • /config/unlock-salt
  • /config/version
  • /domain-key/attended
  • /key/.version
  • /namespace/.version
  • /namespace/namespace1
  • /namespace/namespace2

A fresh list of values in a backup can be generated by running the integration test: cargo test -- --ignored --nocapture create_backup_and_decrypt_it

§Examples

Listing all fields in a backup file:

use std::collections::HashMap;

use nethsm_backup::Backup;

let backup = Backup::parse(std::fs::File::open("tests/nethsm.backup-file.bkp")?)?;
let decryptor = backup.decrypt(b"my-very-unsafe-backup-passphrase")?;

assert_eq!(decryptor.version()?, [0]);

for item in decryptor.items_iter() {
    let (key, value) = item?;
    println!("Found {key} with value: {value:X?}");
}

Dumping the value of one specified field (here /config/version):

use std::collections::HashMap;

use nethsm_backup::Backup;

let backup = Backup::parse(std::fs::File::open("tests/nethsm.backup-file.bkp")?)?;
let decryptor = backup.decrypt(b"my-very-unsafe-backup-passphrase")?;

assert_eq!(decryptor.version()?, [0]);

for (key, value) in decryptor
    .items_iter()
    .flat_map(|item| item.ok())
    .filter(|(key, _)| key == "/config/version")
{
    println!("Found {key} with value: {value:X?}");
}

Structs§

Enums§

  • Backup processing error.

Constants§

  • MAGIC 🔒
    Magic value that is contained in all NetHSM backups.

Functions§

  • Check if the reader contains correct MAGIC value.
  • Check if the reader contains version number that is understood.
  • read_field 🔒
    Read a byte vector from the underlying reader.
  • read_usize 🔒
    Read 3 bytes from the provided reader and interprets it as a usize.

Type Aliases§