rsign/
types.rs

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}