rustic_core/commands/
key.rs1use derive_setters::Setters;
3
4use crate::{
5 backend::{FileType, WriteBackend, decrypt::DecryptWriteBackend},
6 crypto::{aespoly1305::Key, hasher::hash},
7 error::{ErrorKind, RusticError, RusticResult},
8 repofile::{KeyFile, KeyId},
9 repository::{Open, Repository},
10};
11
12#[cfg_attr(feature = "clap", derive(clap::Parser))]
13#[derive(Debug, Clone, Default, Setters)]
14#[setters(into)]
15#[non_exhaustive]
16pub struct KeyOptions {
18 #[cfg_attr(feature = "clap", clap(long))]
20 pub hostname: Option<String>,
21
22 #[cfg_attr(feature = "clap", clap(long))]
24 pub username: Option<String>,
25
26 #[cfg_attr(feature = "clap", clap(long))]
28 pub with_created: bool,
29}
30
31pub(crate) fn add_current_key_to_repo<S: Open>(
52 repo: &Repository<S>,
53 opts: &KeyOptions,
54 pass: &str,
55) -> RusticResult<KeyId> {
56 let key = repo.dbe().key();
57 add_key_to_repo(repo, opts, pass, *key)
58}
59
60pub(crate) fn init_key<S>(
77 repo: &Repository<S>,
78 opts: &KeyOptions,
79 pass: &str,
80) -> RusticResult<(Key, KeyId)> {
81 let key = Key::new();
83 Ok((key, add_key_to_repo(repo, opts, pass, key)?))
84}
85
86pub(crate) fn add_key_to_repo<S>(
103 repo: &Repository<S>,
104 opts: &KeyOptions,
105 pass: &str,
106 key: Key,
107) -> RusticResult<KeyId> {
108 let ko = opts.clone();
109 let keyfile = KeyFile::generate(key, &pass, ko.hostname, ko.username, ko.with_created)?;
110
111 let data = serde_json::to_vec(&keyfile).map_err(|err| {
112 RusticError::with_source(
113 ErrorKind::InputOutput,
114 "Failed to serialize keyfile to JSON.",
115 err,
116 )
117 })?;
118
119 let id = KeyId::from(hash(&data));
120
121 repo.be
122 .write_bytes(FileType::Key, &id, false, data.into())?;
123
124 Ok(id)
125}