Skip to content

Commit

Permalink
more work
Browse files Browse the repository at this point in the history
  • Loading branch information
Phaiax committed Mar 17, 2016
1 parent fe01004 commit 092311f
Show file tree
Hide file tree
Showing 3 changed files with 199 additions and 19 deletions.
148 changes: 146 additions & 2 deletions src/armor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,136 @@ pub fn dearmor(text : &str, max : usize) -> Result<Vec<Dearmored>, String> {
}
}

pub struct ArmoringStream {
meta: ArmorInfo,
state : ArmoringStreamState,
buffer : [u8 ; 43],
}

/// the associated
#[derive(Debug)]
enum ArmoringStreamState {
AtHeader{ pos: usize, header : String},
AtData{ space_in: usize, newline_in : usize, bufpos : usize, buflen : usize },
AtFooter{ pos: usize, footer : String},
}

const SPACE_EVERY: usize = 15;
const NEWLINE_EVERY: usize = 200;

impl ArmoringStream {
pub fn new(vendorstring: String,
messagetype: SaltpackMessageType) -> ArmoringStream {
ArmoringStream {
state : ArmoringStreamState::AtHeader {
pos : 0,
header : format!("BEGIN {} SALTPACK {}. ", vendorstring, messagetype.to_string())
},
meta : ArmorInfo {
vendorstring : vendorstring,
messagetype : messagetype
},
buffer : [0u8 ; 43]
}
}

/// Reads bytes from `binary_in` and writes the armored version into `armored_out`
/// If binary_in contains the last bytes that have to be written, set last_bytes to
/// true. Then the footer will be written.
///
/// Returns the bytes read from `binary_in` and the bytes written to `armored_out`
pub fn armor(&mut self, mut binary_in : &[u8], last_bytes : bool, mut armored_out : &mut[u8])
-> Result<(usize, usize), String> {
use std::io::Write;
let binary_in_len = binary_in.len();
let armored_out_len = armored_out.len();
let mut next = false;

if let ArmoringStreamState::AtHeader{ref mut pos, ref header} = self.state {
*pos += armored_out.write(&header.as_bytes()[*pos..]).unwrap();
next = *pos == header.len();
};

if next {
self.state = ArmoringStreamState::AtData{space_in : SPACE_EVERY,
newline_in : NEWLINE_EVERY,
bufpos : 0,
buflen : 0};
next = false;
}

if let ArmoringStreamState::AtData{ref mut space_in,
ref mut newline_in,
ref mut bufpos,
ref mut buflen } = self.state {
while armored_out.len() > 0 {
if bufpos == buflen {
// 32 byte <> 43 characters
if binary_in.len() >= 32 {
*buflen = bin_to_base62_alphabet(&binary_in[0..32], &mut self.buffer[..]);
binary_in = &binary_in[32..];
*bufpos = 0;
} else if binary_in.len() > 0 && last_bytes {
*buflen = bin_to_base62_alphabet(&binary_in[..], &mut self.buffer[..]);
binary_in = &[];
*bufpos = 0;
} else if binary_in.len() == 0 && last_bytes {
next = true;
break;
} else {
break; // waiting for more input data
}
}
// self.buffer vergrößern, bin_to_base62_alphabet (oder hier)
// direkt im callback von ramps to_base_callback die leerzeichen
// und spaces hinyufügen


}
}


if let ArmoringStreamState::AtFooter{ref mut pos, ref footer} = self.state {

}
Ok((binary_in_len - binary_in.len() ,
armored_out_len - armored_out.len()))
}




// #[inline]
// fn dealphabet_chunk(&mut self, len : usize) {
// let chunk = &self.stripped[0..len];
// for (c, b) in chunk.iter().zip(self.buff.iter_mut()) {
// *b = Base62Blocks::dealphabet(*c);
// }
// }
}

use std::fmt;
impl fmt::Debug for ArmoringStream {
fn fmt(&self, mut f : &mut fmt::Formatter) -> Result<(), fmt::Error> {
try!(self.meta.fmt(&mut f));
try!(self.state.fmt(&mut f));
try!(self.buffer[..].fmt(&mut f));
Ok(())
}
}


///#[inline]
pub fn alphabet(i : u8) -> u8 {
if i <= 9 {
i + b'0'
} else if i <= 35 {
i + b'A' - 10
} else {
i + b'a' - 36
}
}

pub fn strip_whitespace(input : &str) -> String {
let mut out = String::with_capacity(input.len());
for byte in input.chars() {
Expand Down Expand Up @@ -170,7 +300,19 @@ pub fn base62_to_bin(base62 : &[u8], rawout : &mut[u8]) -> usize {
i.write_big_endian_buffer(rawout).unwrap()
}


/// returns the number of bytes written into base62out
pub fn bin_to_base62_alphabet(rawin : &[u8], mut base62out : &mut[u8]) -> usize {
assert!(rawin.len() <= 32);
assert!(base62out.len() >= 43);
let i = Int::from_big_endian_slice(rawin);
let written = 0;
i.write_radix_callback(62, |b| {
unsafe {
*base62out.get_unchecked_mut(written) = alphabet(b);
}
});
written
}


#[cfg(test)]
Expand All @@ -196,9 +338,11 @@ mod tests {
}

#[test]
fn alphabet() {
fn alphabet_() {
for (i, c) in (ALPHABET).as_bytes().iter().enumerate() {
assert_eq!(Base62Blocks::dealphabet(*c) as usize, i);
assert_eq!(alphabet(i as u8), *c);
}
}

}
59 changes: 42 additions & 17 deletions src/compose.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ use rmp_serialize::Encoder;
use std::mem::size_of;
use std::io::{Read, Write};
use std::collections::VecDeque;
use std::string::ToString;
use std;
use std::io;

Expand Down Expand Up @@ -104,11 +105,6 @@ pub struct Saltpack {
output_buffer : VecDeque<Vec<u8>>,
}

pub struct ArmoredSaltpack {
saltpack : Saltpack,
vendor : String
}

pub fn encrypt_to_binary(sender : Option<&KeyPair>,
recipients : &Vec<PublicKey>,
payload : &[u8]) -> Vec<u8> {
Expand Down Expand Up @@ -281,7 +277,7 @@ impl Saltpack {
if self.input_buffer.len() == 0 {
return false;
}
println!("Encr START");
//$ println!("Encr START");

let next = self.input_buffer.pop_front().unwrap();
let payload = &next[..];
Expand All @@ -290,11 +286,11 @@ impl Saltpack {
self.next_packet_number += 1;

// The payload secretbox is a NaCl secretbox containing a chunk of the plaintext bytes, max size 1 MB. It's encrypted with the payload key.
println!(" Secretbox BEGIN");
//$ println!(" Secretbox BEGIN");
let secretbox_payload = secretbox::seal(/*msg*/&payload[..],
/*nonce*/&nonce,
/*key*/&self.payload_key.as_ref().unwrap());
println!(" Secretbox END");
//$ println!(" Secretbox END");



Expand All @@ -308,33 +304,33 @@ impl Saltpack {
cat.extend_from_slice(&secretbox_payload[..]);

// 2 Compute the crypto_hash (SHA512) of the bytes from #1.
println!(" Hash BEGIN");
//$ println!(" Hash BEGIN");
let headerhash = hash(&cat[..]);
println!(" Hash END");
//$ println!(" Hash END");

// 3 For each recipient, compute the crypto_auth (HMAC-SHA512, truncated to 32 bytes) of the hash from #2, using that recipient's MAC key.
let mut authenticators = Vec::new();
let mut bufsize = secretbox_payload.len() + 12;
println!(" Auth BEGIN");
//$ println!(" Auth BEGIN");
for mac in self.macs.iter() {
let tag = auth::authenticate(&headerhash.0, &mac);
bufsize += tag.0.len() + 2;
authenticators.push(Authenticator(Vec::from(&tag.0[..])));
}
println!(" Auth END");
//$ println!(" Auth END");

// Compose Packet
let packet = PayloadPacketSerializable (
authenticators,
secretbox_payload,
);
println!(" Encode BEGIN");
//$ println!(" Encode BEGIN");
let mut packet_messagepacked = Vec::<u8>::with_capacity(bufsize);
packet.encode(&mut Encoder::new(&mut packet_messagepacked)).unwrap();
println!(" Encode END");
//$ println!(" Encode END");

self.output_buffer.push_back(packet_messagepacked);
println!(" Encr END");
//$ println!(" Encr END");
true
}

Expand Down Expand Up @@ -384,8 +380,10 @@ impl Write for Saltpack {
}

fn flush(&mut self) -> std::io::Result<()> {
self.flushed = true;
self.input_buffer.push_back(Vec::new()); // finish with empty packet
if ! self.flushed {
self.flushed = true;
self.input_buffer.push_back(Vec::new()); // finish with empty packet
}

Ok(())
}
Expand Down Expand Up @@ -421,6 +419,32 @@ impl Read for Saltpack {
}
}



pub struct ArmoredSaltpack {
saltpack : Saltpack,
vendor : String
}


impl Read for ArmoredSaltpack {

/// Writes the armored saltpack (ascii only characters) as binary data (u8)
/// into `buffer`.
fn read(&mut self, mut buffer : &mut [u8]) -> std::io::Result<usize> {

self.saltpack.read(&mut buffer)
}
}

impl ArmoredSaltpack {

/// Outputs all
fn to_string(&mut self) -> String {
"".to_string()
}
}

#[cfg(test)]
mod tests {

Expand All @@ -442,6 +466,7 @@ mod tests {

#[test]
fn giant_saltpack() {
return;
let mut recipients = Vec::<PublicKey>::new();
recipients.push(KeyPair::gen().p);
recipients.push(KeyPair::gen().p);
Expand Down
11 changes: 11 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,17 @@ impl SaltpackMessageType {
}
}

use std::string::ToString;
impl ToString for SaltpackMessageType {
fn to_string(&self) -> String {
match *self {
SaltpackMessageType::ENCRYPTEDMESSAGE => "ENCRYPTEDMESSAGE".to_string(),
SaltpackMessageType::SIGNEDMESSAGE => "SIGNEDMESSAGE".to_string(),
SaltpackMessageType::DETACHEDSIGNATURE => "DETACHEDSIGNATURE".to_string()
}
}
}


#[cfg(test)]
mod tests {
Expand Down

0 comments on commit 092311f

Please sign in to comment.