engine/snapshot/migration/
mod.rs1mod error;
5mod v2;
6mod v3;
7
8use std::{
9 fs::{File, OpenOptions},
10 io::{Read, Write},
11 path::Path,
12};
13
14use crypto::{
15 ciphers::{chacha::XChaCha20Poly1305, traits::Aead},
16 hashes::{blake2b, Digest},
17 keys::{age, x25519},
18};
19
20pub use self::error::Error;
23use crate::snapshot::{compress, decompress};
24use zeroize::Zeroizing;
25
26pub enum Version<'a> {
27 V2 {
28 path: &'a Path,
29 key: &'a [u8; 32],
30 aad: &'a [u8],
31 },
32 V3 {
33 path: &'a Path,
34 password: &'a [u8],
35 },
36}
37
38impl<'a> Version<'a> {
39 pub fn v2(path: &'a Path, key: &'a [u8; 32], aad: &'a [u8]) -> Self {
40 Self::V2 { path, key, aad }
41 }
42
43 pub fn v3(path: &'a Path, password: &'a [u8]) -> Self {
44 Self::V3 { path, password }
45 }
46}
47
48const MAGIC: [u8; 5] = [0x50, 0x41, 0x52, 0x54, 0x49];
50
51#[inline]
52fn guard<E>(cond: bool, err: E) -> Result<(), E> {
53 if cond {
54 Ok(())
55 } else {
56 Err(err)
57 }
58}
59
60fn migrate_from_v2_to_v3(
61 v2_path: &Path,
62 v2_key: &[u8; 32],
63 v2_aad: &[u8],
64 v3_path: &Path,
65 v3_pwd: &[u8],
66) -> Result<(), Error> {
67 let v = v2::read_snapshot(v2_path, v2_key, v2_aad)?;
68 v3::write_snapshot(&v[..], v3_path, v3_pwd)
69}
70
71pub fn migrate(prev: Version, next: Version) -> Result<(), Error> {
72 match (prev, next) {
73 (
74 Version::V2 {
75 path: v2_path,
76 key: v2_key,
77 aad: v2_aad,
78 },
79 Version::V3 {
80 path: v3_path,
81 password: v3_pwd,
82 },
83 ) => migrate_from_v2_to_v3(v2_path, v2_key, v2_aad, v3_path, v3_pwd),
84 _ => Err(Error::BadMigrationVersion),
85 }
86}