1extern crate libsodium_sys as ffi;
2
3use sodiumoxide::crypto::sign::*;
4use sodiumoxide::crypto::pwhash::*;
5use generichash::{self, BYTES};
6use std::fmt::{self, Formatter};
7use ::Result;
8use std::cmp;
9use std::io::{Cursor, Read};
10
11pub const KEYNUMBYTES: usize = 8;
12pub const TWOBYTES: usize = 2;
13pub const TR_COMMENT_PREFIX_LEN: usize = 17;
14pub const PK_B64_ENCODED_LEN: usize = 56;
15pub const PASSWORDMAXBYTES: usize = 1024;
16pub const COMMENTBYTES: usize = 1024;
17pub const TRUSTEDCOMMENTMAXBYTES: usize = 8192;
18pub const SIGALG: [u8; 2] = *b"Ed";
19pub const SIGALG_HASHED: [u8; 2] = *b"ED";
20pub const KDFALG: [u8; 2] = *b"Sc";
21pub const CHKALG: [u8; 2] = *b"B2";
22pub const COMMENT_PREFIX: &'static str = "untrusted comment: ";
23pub const DEFAULT_COMMENT: &'static str = "signature from rsign secret key";
24pub const SECRETKEY_DEFAULT_COMMENT: &'static str = "rsign encrypted secret key";
25pub const TRUSTED_COMMENT_PREFIX: &'static str = "trusted comment: ";
26pub const SIG_DEFAULT_CONFIG_DIR: &'static str = ".rsign";
27pub const SIG_DEFAULT_CONFIG_DIR_ENV_VAR: &'static str = "RSIGN_CONFIG_DIR";
28pub const SIG_DEFAULT_PKFILE: &'static str = "rsign.pub";
29pub const SIG_DEFAULT_SKFILE: &'static str = "rsign.key";
30pub const SIG_SUFFIX: &'static str = ".rsign";
31
32pub struct KeynumSK {
33 pub keynum: [u8; KEYNUMBYTES],
34 pub sk: [u8; SECRETKEYBYTES],
35 pub chk: [u8; BYTES],
36}
37
38impl Clone for KeynumSK {
39 fn clone(&self) -> KeynumSK {
40 KeynumSK {
41 keynum: self.keynum,
42 sk: self.sk,
43 chk: self.chk,
44 }
45 }
46}
47
48impl KeynumSK {
49 pub fn len(&self) -> usize {
50 use std::mem;
51 mem::size_of::<KeynumSK>()
52 }
53}
54
55impl fmt::Debug for KeynumSK {
56 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
57 for byte in self.sk.iter() {
58 try!(write!(f, "{:x}", byte))
59 }
60 Ok(())
61 }
62}
63
64impl cmp::PartialEq for KeynumSK {
65 fn eq(&self, other: &KeynumSK) -> bool {
66 use sodiumoxide::utils::memcmp;
67 memcmp(&self.sk, &other.sk)
68 }
69}
70impl cmp::Eq for KeynumSK {}
71
72pub struct SeckeyStruct {
73 pub sig_alg: [u8; TWOBYTES],
74 pub kdf_alg: [u8; TWOBYTES],
75 pub chk_alg: [u8; TWOBYTES],
76 pub kdf_salt: [u8; SALTBYTES],
77 pub kdf_opslimit_le: [u8; KEYNUMBYTES],
78 pub kdf_memlimit_le: [u8; KEYNUMBYTES],
79 pub keynum_sk: KeynumSK,
80}
81
82impl SeckeyStruct {
83 pub fn from(bytes_buf: &[u8]) -> Result<SeckeyStruct> {
84 let mut buf = Cursor::new(bytes_buf);
85 let mut sig_alg = [0u8; TWOBYTES];
86 let mut kdf_alg = [0u8; TWOBYTES];
87 let mut chk_alg = [0u8; TWOBYTES];
88 let mut kdf_salt = [0u8; SALTBYTES];
89 let mut ops_limit = [0u8; KEYNUMBYTES];
90 let mut mem_limit = [0u8; KEYNUMBYTES];
91 let mut keynum = [0u8; KEYNUMBYTES];
92 let mut sk = [0u8; SECRETKEYBYTES];
93 let mut chk = [0u8; BYTES];
94 buf.read(&mut sig_alg)?;
95 buf.read(&mut kdf_alg)?;
96 buf.read(&mut chk_alg)?;
97 buf.read(&mut kdf_salt)?;
98 buf.read(&mut ops_limit)?;
99 buf.read(&mut mem_limit)?;
100 buf.read(&mut keynum)?;
101 buf.read(&mut sk)?;
102 buf.read(&mut chk)?;
103
104 Ok(SeckeyStruct {
105 sig_alg: sig_alg,
106 kdf_alg: kdf_alg,
107 chk_alg: chk_alg,
108 kdf_salt: kdf_salt,
109 kdf_opslimit_le: ops_limit,
110 kdf_memlimit_le: mem_limit,
111 keynum_sk: KeynumSK {
112 keynum: keynum,
113 sk: sk,
114 chk: chk,
115 },
116 })
117 }
118 pub fn bytes(&self) -> Vec<u8> {
119 let mut iters = Vec::new();
120 iters.push(self.sig_alg.iter());
121 iters.push(self.kdf_alg.iter());
122 iters.push(self.chk_alg.iter());
123 iters.push(self.kdf_salt.iter());
124 iters.push(self.kdf_opslimit_le.iter());
125 iters.push(self.kdf_memlimit_le.iter());
126 iters.push(self.keynum_sk.keynum.iter());
127 iters.push(self.keynum_sk.sk.iter());
128 iters.push(self.keynum_sk.chk.iter());
129 let v: Vec<u8> = iters
130 .iter()
131 .flat_map(|b| {
132 let b = b.clone();
133 b.into_iter().cloned()
134 })
135 .collect();
136 v
137 }
138 pub fn write_checksum(&mut self) -> Result<()> {
139 let h = self.read_checksum()?;
140 self.keynum_sk.chk.copy_from_slice(&h[..]);
141 Ok(())
142 }
143
144 pub fn read_checksum(&self) -> Result<Vec<u8>> {
145 let state_sz = unsafe { ffi::crypto_generichash_statebytes() };
146 let mut state: Vec<u8> = vec![0;state_sz];
147 let ptr_state = state.as_mut_ptr() as *mut ffi::crypto_generichash_state;
148 generichash::init(ptr_state)?;
149 generichash::update(ptr_state, &self.sig_alg)?;
150 generichash::update(ptr_state, &self.keynum_sk.keynum)?;
151 generichash::update(ptr_state, &self.keynum_sk.sk)?;
152 let h = generichash::finalize(ptr_state)?;
153 Ok(Vec::from(&h[..]))
154 }
155
156 pub fn xor_keynum(&mut self, stream: &[u8]) {
157
158 let b8 = self.keynum_sk
159 .keynum
160 .iter_mut()
161 .zip(stream.iter())
162 .map(|(byte, stream)| *byte = *byte ^ *stream)
163 .count();
164
165 let b64 = self.keynum_sk
166 .sk
167 .iter_mut()
168 .zip(stream[b8..].iter())
169 .map(|(byte, stream)| *byte = *byte ^ *stream)
170 .count();
171
172 let _b32 = self.keynum_sk
173 .chk
174 .iter_mut()
175 .zip(stream[b8 + b64..].iter())
176 .map(|(byte, stream)| *byte = *byte ^ *stream)
177 .count();
178 }
179}
180
181impl fmt::Debug for SeckeyStruct {
182 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
183 for byte in self.keynum_sk.sk.iter() {
184 try!(write!(f, "{:x}", byte))
185 }
186 Ok(())
187 }
188}
189
190impl cmp::PartialEq for SeckeyStruct {
191 fn eq(&self, other: &SeckeyStruct) -> bool {
192 use sodiumoxide::utils::memcmp;
193 memcmp(&self.keynum_sk.sk, &other.keynum_sk.sk)
194 }
195}
196impl cmp::Eq for SeckeyStruct {}
197
198#[derive(Debug)]
199pub struct PubkeyStruct {
200 pub sig_alg: [u8; TWOBYTES],
201 pub keynum_pk: KeynumPK,
202}
203#[derive(Debug, Clone)]
204pub struct KeynumPK {
205 pub keynum: [u8; KEYNUMBYTES],
206 pub pk: [u8; PUBLICKEYBYTES],
207}
208
209impl cmp::PartialEq for PubkeyStruct {
210 fn eq(&self, other: &PubkeyStruct) -> bool {
211 use sodiumoxide::utils::memcmp;
212 memcmp(&self.keynum_pk.pk, &other.keynum_pk.pk)
213 }
214}
215impl cmp::Eq for PubkeyStruct {}
216
217impl PubkeyStruct {
218 pub fn len() -> usize {
219 use std::mem;
220 mem::size_of::<PubkeyStruct>()
221 }
222
223 pub fn from(buf: &[u8]) -> Result<PubkeyStruct> {
224 let mut buf = Cursor::new(buf);
225 let mut sig_alg = [0u8; TWOBYTES];
226 let mut keynum = [0u8; KEYNUMBYTES];
227 let mut pk = [0u8; PUBLICKEYBYTES];
228 buf.read(&mut sig_alg)?;
229 buf.read(&mut keynum)?;
230 buf.read(&mut pk)?;
231 Ok(PubkeyStruct {
232 sig_alg: sig_alg,
233 keynum_pk: KeynumPK {
234 keynum: keynum,
235 pk: pk,
236 },
237 })
238 }
239
240 pub fn bytes(&self) -> Vec<u8> {
241 let mut iters = Vec::new();
242 iters.push(self.sig_alg.iter());
243 iters.push(self.keynum_pk.keynum.iter());
244 iters.push(self.keynum_pk.pk.iter());
245 let v: Vec<u8> = iters
246 .iter()
247 .flat_map(|b| {
248 let b = b.clone();
249 b.into_iter().cloned()
250 })
251 .collect();
252 v
253 }
254}
255
256pub struct SigStruct {
257 pub sig_alg: [u8; TWOBYTES],
258 pub keynum: [u8; KEYNUMBYTES],
259 pub sig: [u8; SIGNATUREBYTES],
260}
261impl SigStruct {
262 pub fn len() -> usize {
263 use std::mem;
264 mem::size_of::<SigStruct>()
265 }
266 pub fn bytes(&self) -> Vec<u8> {
267 let mut iters = Vec::new();
268 iters.push(self.sig_alg.iter());
269 iters.push(self.keynum.iter());
270 iters.push(self.sig.iter());
271 let v: Vec<u8> = iters
272 .iter()
273 .flat_map(|b| {
274 let b = b.clone();
275 b.into_iter().cloned()
276 })
277 .collect();
278 v
279 }
280 pub fn from(bytes_buf: &[u8]) -> Result<SigStruct> {
281 let mut buf = Cursor::new(bytes_buf);
282 let mut sig_alg = [0u8; 2];
283 let mut keynum = [0u8; KEYNUMBYTES];
284 let mut sig = [0u8; SIGNATUREBYTES];
285 buf.read(&mut sig_alg)?;
286 buf.read(&mut keynum)?;
287 buf.read(&mut sig)?;
288 Ok(SigStruct {
289 sig_alg: sig_alg,
290 keynum: keynum,
291 sig: sig,
292 })
293 }
294}
295
296impl Default for SigStruct {
297 fn default() -> Self {
298 SigStruct {
299 sig_alg: [0u8; TWOBYTES],
300 keynum: [0u8; KEYNUMBYTES],
301 sig: [0u8; SIGNATUREBYTES],
302 }
303 }
304}