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
|
//! Implementations of our useful traits, on external and parsing-mode types
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)
}
}
/// 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(())
}
}
}
|