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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
|
//! Implementations of our useful traits, on external and parsing-mode types
use tor_basic_utils::intern::Intern;
use super::*;
impl ItemArgument for str {
fn write_arg_onto(&self, out: &mut ItemEncoder<'_>) -> Result<(), Bug> {
// Implements this
// https://gitlab.torproject.org/tpo/core/torspec/-/merge_requests/106
if self.is_empty() || self.chars().any(|c| !c.is_ascii_graphic()) {
return Err(internal!(
"invalid netdoc keyword line argument syntax {:?}",
self
));
}
out.args_raw_nonempty(&self);
Ok(())
}
}
impl ItemArgument for &str {
fn write_arg_onto(&self, out: &mut ItemEncoder<'_>) -> Result<(), Bug> {
<str as ItemArgument>::write_arg_onto(self, out)
}
}
impl ItemArgument for Iso8601TimeSp {
// Unlike the macro'd formats, contains a space while still being one argument
fn write_arg_onto(&self, out: &mut ItemEncoder<'_>) -> Result<(), Bug> {
let arg = self.to_string();
out.args_raw_nonempty(&arg.as_str());
Ok(())
}
}
impl ItemValueEncodable for Void {
fn write_item_value_onto(&self, _out: ItemEncoder) -> Result<(), Bug> {
void::unreachable(*self)
}
}
impl ItemObjectEncodable for Void {
fn label(&self) -> &str {
void::unreachable(*self)
}
fn write_object_onto(&self, _: &mut Vec<u8>) -> Result<(), Bug> {
void::unreachable(*self)
}
}
impl<T: NetdocEncodable> NetdocEncodable for Arc<T> {
fn encode_unsigned(&self, out: &mut NetdocEncoder) -> Result<(), Bug> {
<T as NetdocEncodable>::encode_unsigned(self, out)
}
}
impl<T: NetdocEncodableFields> NetdocEncodableFields for Arc<T> {
fn encode_fields(&self, out: &mut NetdocEncoder) -> Result<(), Bug> {
<T as NetdocEncodableFields>::encode_fields(self, out)
}
}
impl<T: ItemValueEncodable> ItemValueEncodable for Arc<T> {
fn write_item_value_onto(&self, out: ItemEncoder) -> Result<(), Bug> {
<T as ItemValueEncodable>::write_item_value_onto(self, out)
}
}
impl<T: ItemArgument> ItemArgument for Arc<T> {
fn write_arg_onto(&self, out: &mut ItemEncoder<'_>) -> Result<(), Bug> {
<T as ItemArgument>::write_arg_onto(self, out)
}
}
impl<T: ItemObjectEncodable> ItemObjectEncodable for Arc<T> {
fn label(&self) -> &str {
<T as ItemObjectEncodable>::label(self)
}
fn write_object_onto(&self, b: &mut Vec<u8>) -> Result<(), Bug> {
<T as ItemObjectEncodable>::write_object_onto(self, b)
}
}
impl<T: NetdocEncodable> NetdocEncodable for Intern<T> {
fn encode_unsigned(&self, out: &mut NetdocEncoder) -> Result<(), Bug> {
<T as NetdocEncodable>::encode_unsigned(self, out)
}
}
impl<T: NetdocEncodableFields> NetdocEncodableFields for Intern<T> {
fn encode_fields(&self, out: &mut NetdocEncoder) -> Result<(), Bug> {
<T as NetdocEncodableFields>::encode_fields(self, out)
}
}
impl<T: ItemValueEncodable> ItemValueEncodable for Intern<T> {
fn write_item_value_onto(&self, out: ItemEncoder) -> Result<(), Bug> {
<T as ItemValueEncodable>::write_item_value_onto(self, out)
}
}
impl<T: ItemArgument> ItemArgument for Intern<T> {
fn write_arg_onto(&self, out: &mut ItemEncoder<'_>) -> Result<(), Bug> {
<T as ItemArgument>::write_arg_onto(self, out)
}
}
impl<T: ItemObjectEncodable> ItemObjectEncodable for Intern<T> {
fn label(&self) -> &str {
<T as ItemObjectEncodable>::label(self)
}
fn write_object_onto(&self, b: &mut Vec<u8>) -> Result<(), Bug> {
<T as ItemObjectEncodable>::write_object_onto(self, b)
}
}
/// Types related to RSA keys
mod rsa {
use super::*;
use tor_llcrypto::pk::rsa::PublicKey;
impl ItemObjectEncodable for PublicKey {
fn label(&self) -> &str {
"RSA PUBLIC KEY"
}
fn write_object_onto(&self, b: &mut Vec<u8>) -> Result<(), Bug> {
b.extend(self.to_der());
Ok(())
}
}
impl ItemValueEncodable for PublicKey {
fn write_item_value_onto(&self, out: ItemEncoder) -> Result<(), Bug> {
out.object(self);
Ok(())
}
}
}
/// Protocol versions (from `tor-protover`)
pub(crate) mod protovers {
use super::*;
use tor_protover::Protocols;
impl ItemValueEncodable for Protocols {
fn write_item_value_onto(&self, mut out: ItemEncoder) -> Result<(), Bug> {
out.args_raw_string(&self);
Ok(())
}
}
}
/// HS POW
#[cfg(feature = "hs-pow-full")]
mod hs_pow {
use super::*;
use tor_hscrypto::pow::v1;
impl ItemArgument for v1::Seed {
fn write_arg_onto(&self, out: &mut ItemEncoder<'_>) -> Result<(), Bug> {
let mut seed_bytes = vec![];
tor_bytes::Writer::write(&mut seed_bytes, &self)?;
out.add_arg(&Base64Unpadded::encode_string(&seed_bytes));
Ok(())
}
}
impl ItemArgument for v1::Effort {
fn write_arg_onto(&self, out: &mut ItemEncoder<'_>) -> Result<(), Bug> {
out.add_arg(&<Self as Into<u32>>::into(*self));
Ok(())
}
}
}
|