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
use crate::{error::PskClientError, PskClient};
use hex;
use std::net::ToSocketAddrs;
const DEFAULT_PSK_CIPHERS: &[&str] = &[
"+VERS-TLS1.2",
"+ECDHE-PSK",
"+PSK",
"+AES-128-GCM",
"+AES-128-CBC",
"+AEAD",
"+SHA256",
"+SHA1",
"+CURVE-ALL",
"+COMP-NULL",
"+SIGN-ALL",
];
#[derive(Clone, Debug, PartialEq)]
pub struct PskClientBuilder<'a, H: ToSocketAddrs> {
host: H,
cipher_list: Vec<&'a str>,
identity: Option<String>,
key: Vec<u8>,
}
impl<'a, H: ToSocketAddrs> PskClientBuilder<'a, H> {
pub fn new(host: H) -> Self {
PskClientBuilder {
host,
cipher_list: DEFAULT_PSK_CIPHERS.to_vec(),
identity: None,
key: Vec::new(),
}
}
pub fn build(self) -> Result<PskClient, PskClientError> {
let host = match self.host.to_socket_addrs() {
Ok(mut hosts) => match hosts.next() {
Some(host) => host,
None => {
unreachable!("Impossible to have valid hosts but have none in the interator.")
}
},
Err(e) => return Err(PskClientError::NoValidHost(e)),
};
let mut identity = match self.identity {
Some(id) => id,
None => return Err(PskClientError::MissingIdentity),
};
identity.push_str("\0");
Ok(PskClient {
host,
ciphers: self.cipher_list.join(":"),
identity,
key: self.key,
})
}
#[must_use]
pub fn identity<S: Into<String>>(mut self, identity: S) -> Self {
self.identity = Some(identity.into());
self
}
#[must_use]
pub fn key<K: AsRef<[u8]>>(mut self, key: K) -> Self {
match hex::decode(key) {
Ok(key) => self.key = key,
Err(e) => panic!("{}", PskClientError::UnparseableKeyHex(e)),
};
self
}
pub fn cipher(mut self, cipher: &'a str) -> Self {
self.cipher_list.push(cipher);
self
}
pub fn reset_ciphers(mut self) -> Self {
self.cipher_list.clear();
self
}
}