1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
|
use std::process::Output;
use assert_cmd::cargo::cargo_bin_cmd;
use crate::util::create_state_dir_entry;
/// Path to a test specific configuration.
const CFG_PATH: &str = "./tests/testcases/keys/keys.in/keys.toml";
/// Path to a test specific configuration that includes a CTor keystore
const CFG_PATH_WITH_CTOR: &str = "./tests/testcases/keys/conf/keys.toml";
/// A client of an `ArtiNativeKeystore`
const CLIENT_KEY: &str = " Keystore ID: arti
Role: ks_hsc_desc_enc
Summary: Descriptor decryption key
KeystoreItemType: X25519StaticKeypair
Location: client/mnyizjj7m3hpcr7i5afph3zt7maa65johyu2ruis6z7cmnjmaj3h6tad/ks_hsc_desc_enc.x25519_private
Extra info:
- hs_id: […]tad.onion
";
/// An unrecognized entry of an `ArtiNativeKeystore`
const UNRECOGNIZED_ENTRY: &str = " Unrecognized entry
Keystore ID: arti
Location: hss/allium-cepa/unrecognized-entry
Error: Key has invalid path: hss/allium-cepa/unrecognized-entry
";
/// The long term identity of an `ArtiNativeKeystore`
const ID_KEY: &str = " Keystore ID: arti
Role: ks_hs_id
Summary: Long-term identity keypair
KeystoreItemType: Ed25519ExpandedKeypair
Location: hss/allium-cepa/ks_hs_id.ed25519_expanded_private
Extra info:
- nickname: allium-cepa
";
/// An unrecognized path in an `ArtiNativeKeystore`
const UNRECOGNIZED_PATH: &str =
" Unrecognized path unrecognized-path-dir/ks_hs_id.ed25519_expanded_private";
/// The secret key of an `CTorServiceKeystore`
const CTOR_SECRET: &str = "Keystore ID: ctor
Role: ks_hs_id
Summary: Long-term identity keypair
KeystoreItemType: Ed25519ExpandedKeypair
Location: hs_ed25519_secret_key
";
/// The public key of a `CTorServiceKeystore`
const CTOR_PUBLIC: &str = "Keystore ID: ctor
Role: kp_hs_id
Summary: Public part of the identity key
KeystoreItemType: Ed25519PublicKey
Location: hs_ed25519_public_key
";
/// The hostname file of a `CTorServiceKeystore`
const CTOR_HOSTNAME: &str = " Unrecognized entry
Keystore ID: ctor
Location: hostname
Error: Key hostname is malformed
";
/// An unrecognized entry in a `CTorServiceKeystore`
const CTOR_UNRECOGNIZED_ENTRY: &str = " Unrecognized entry
Keystore ID: ctor
Location: hs_unrecognized_entry
Error: Key hs_unrecognized_entry is malformed
";
/// The output relative to all the keys present in the test `ArtiNativeKeystore`.
pub(super) const LIST_OUTPUT_ARTI: &[&str] =
&[CLIENT_KEY, UNRECOGNIZED_ENTRY, ID_KEY, UNRECOGNIZED_PATH];
/// The output relative to all the keys present
/// in the test `CTorServiceKeystore`.
///
// TODO: The hostname file of the ctor keystore is not
// currently handled correctly and is erroneously represented
// as an unrecognized entry. This should be fixed.
pub(super) const LIST_OUTPUT_CTOR: &[&str] = &[
CTOR_HOSTNAME,
CTOR_SECRET,
CTOR_PUBLIC,
CTOR_UNRECOGNIZED_ENTRY,
];
/// A struct that represents the subcommand `keys list`.
#[derive(Debug, Clone, Default, Eq, PartialEq, derive_builder::Builder)]
pub(super) struct KeysListCmd {
/// Use [`with_arti`] to include a populated `ArtiNativeKeystore`.
#[builder(default)]
with_arti: bool,
/// Use [`with_ctor`] to include a populated `CTorServiceKeystore`.
#[builder(default)]
with_ctor: bool,
/// Use [`keystore`] to pass a `-k <KEYSTORE_ID>` flag to the command.
#[builder(default)]
keystore: Option<String>,
}
impl KeysListCmd {
/// Execute the command and return its output as an [`Output`].
pub(super) fn output(&self) -> std::io::Result<Output> {
let mut cmd = cargo_bin_cmd!("arti");
if self.with_ctor {
cmd.args(["-c", CFG_PATH_WITH_CTOR]);
} else {
cmd.args(["-c", CFG_PATH]);
}
// When [`with_arti`] is set to false, the default configured state directory,
// which holds an Arti-native keystore with both valid and invalid entries,
// will be replaced by a new, temporary, empty directory.
let state_dir;
if !self.with_arti {
state_dir = tempfile::TempDir::new().unwrap();
let state_dir_path = state_dir.path().to_path_buf();
let state_dir_path = state_dir_path.to_str().unwrap();
let opt = create_state_dir_entry(state_dir_path);
cmd.args(["-o", &opt]);
}
cmd.args(["keys", "list"]);
if let Some(keystore_id) = &self.keystore {
cmd.args(["-k", keystore_id]);
}
cmd.output()
}
}
/// A struct that represents the subcommand `keys list-keystores`.
#[derive(Debug, Clone, Default, Eq, PartialEq, derive_builder::Builder)]
pub(super) struct KeysListKeystoreCmd {
/// Use [`with_ctor`] to include a `CTorServiceKeystore` in the configuration.
#[builder(default)]
with_ctor: bool,
}
impl KeysListKeystoreCmd {
/// Execute the command and return its output as an [`Output`].
pub(super) fn output(&self) -> std::io::Result<Output> {
let mut cmd = cargo_bin_cmd!("arti");
if self.with_ctor {
cmd.args(["-c", CFG_PATH_WITH_CTOR]);
} else {
cmd.args(["-c", CFG_PATH]);
}
cmd.args(["keys", "list-keystores"]);
cmd.output()
}
}
|