Skip to content

Commit

Permalink
Merge pull request #8 from klutzy/update
Browse files Browse the repository at this point in the history
Update for upstream changes
  • Loading branch information
klutzy committed Mar 18, 2015
2 parents 697982c + 0aebf70 commit 7e1525f
Show file tree
Hide file tree
Showing 23 changed files with 630 additions and 393 deletions.
24 changes: 16 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,26 @@ NIST P-256 [ECDHE][tls-ecc] and [chacha20-poly1305][tls-chacha20-poly1305].
```Rust
extern crate suruga;

use std::old_io::net::tcp::TcpStream;
use std::vec::Vec;
use std::io::prelude::*;
use std::net::TcpStream;

fn main() {
let stream = TcpStream::connect("www.google.com:443").unwrap();
let mut client = suruga::TlsClient::from_tcp(stream).unwrap();
client.write(b"GET / HTTP/1.1\r\nHost: www.google.com\r\n\r\n").unwrap();
test().unwrap();
}

fn test() -> suruga::tls_result::TlsResult<()> {
let stream = try!(TcpStream::connect("www.google.com:443"));
let mut client = try!(suruga::TlsClient::from_tcp(stream));
let _len = try!(client.write(b"GET / HTTP/1.1\r\nHost: www.google.com\r\n\r\n"));

let mut msg = vec![0u8; 100];
client.read(msg.as_mut_slice()).unwrap();
let msg = String::from_utf8_lossy(msg.as_slice());
try!(client.read(&mut msg));
let msg = String::from_utf8_lossy(&msg);
println!("msg: {}", msg);
client.close().unwrap();

try!(client.close());

Ok(())
}
```

Expand Down
25 changes: 25 additions & 0 deletions examples/google.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#![feature(net)]

extern crate suruga;

use std::io::prelude::*;
use std::net::TcpStream;

fn main() {
test().unwrap();
}

fn test() -> suruga::tls_result::TlsResult<()> {
let stream = try!(TcpStream::connect("www.google.com:443"));
let mut client = try!(suruga::TlsClient::from_tcp(stream));
let _len = try!(client.write(b"GET / HTTP/1.1\r\nHost: www.google.com\r\n\r\n"));

let mut msg = vec![0u8; 100];
try!(client.read(&mut msg));
let msg = String::from_utf8_lossy(&msg);
println!("msg: {}", msg);

try!(client.close());

Ok(())
}
1 change: 1 addition & 0 deletions src/alert.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use util::{ReadExt, WriteExt};
use tls_result::{TlsResult, TlsError, TlsErrorKind};
use tls_item::TlsItem;

Expand Down
20 changes: 10 additions & 10 deletions src/cipher/chacha20_poly1305.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,22 @@ fn compute_mac(poly_key: &[u8], encrypted: &[u8], ad: &[u8]) -> [u8; MAC_LEN] {
// note that in draft-agl-tls-chacha20poly1305-01 length is first
fn push_all_with_len(vec: &mut Vec<u8>, data: &[u8]) {
vec.push_all(data);
vec.push_all(&u64_le_array(data.len() as u64)[]);
vec.push_all(&u64_le_array(data.len() as u64));
}

push_all_with_len(&mut msg, ad);
push_all_with_len(&mut msg, encrypted);

let mut r = [0u8; MAC_LEN];
for i in (0us..MAC_LEN) {
for i in (0..MAC_LEN) {
r[i] = poly_key[i];
}
let mut k = [0u8; MAC_LEN];
for i in (0us..MAC_LEN) {
for i in (0..MAC_LEN) {
k[i] = poly_key[MAC_LEN + i];
}

poly1305::authenticate(&msg[], &r, &k)
poly1305::authenticate(&msg, &r, &k)
}

struct ChaCha20Poly1305Encryptor {
Expand All @@ -47,12 +47,12 @@ struct ChaCha20Poly1305Encryptor {

impl Encryptor for ChaCha20Poly1305Encryptor {
fn encrypt(&mut self, nonce: &[u8], data: &[u8], ad: &[u8]) -> Vec<u8> {
let mut chacha20 = ChaCha20::new(&self.key[], nonce);
let mut chacha20 = ChaCha20::new(&self.key, nonce);
let poly1305_key = chacha20.next();

let mut encrypted = chacha20.encrypt(data);
let mac = compute_mac(&poly1305_key[], &encrypted[], ad);
encrypted.push_all(&mac[]);
let mac = compute_mac(&poly1305_key, &encrypted, ad);
encrypted.push_all(&mac);

encrypted
}
Expand All @@ -72,17 +72,17 @@ impl Decryptor for ChaCha20Poly1305Decryptor {
let encrypted = &data[..(enc_len - MAC_LEN)];
let mac_expected = &data[(enc_len - MAC_LEN)..];

let mut chacha20 = ChaCha20::new(&self.key[], nonce);
let mut chacha20 = ChaCha20::new(&self.key, nonce);
let poly1305_key = chacha20.next();

let mac_computed = compute_mac(&poly1305_key[], &encrypted[], ad);
let mac_computed = compute_mac(&poly1305_key, &encrypted, ad);

// SECRET
// even if `mac_computed != mac_expected`, decrypt the data to prevent timing attack.
let plain = chacha20.encrypt(encrypted);

let mut diff = 0u8;
for i in (0us..MAC_LEN) {
for i in (0..MAC_LEN) {
diff |= mac_computed[i] ^ mac_expected[i];
}

Expand Down
16 changes: 9 additions & 7 deletions src/cipher/ecdhe.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use std::io::Cursor;
use rand::{Rng, OsRng};
use std::old_io::BufReader;

use crypto::wrapping::Wrapping as W;
use util::{ReadExt, WriteExt};
use tls_result::TlsResult;
use tls_result::TlsErrorKind::IllegalParameter;
use tls_item::TlsItem;
Expand Down Expand Up @@ -35,10 +37,10 @@ pub struct EllipticDiffieHellman;

impl KeyExchange for EllipticDiffieHellman {
fn compute_keys(&self, data: &[u8], rng: &mut OsRng) -> TlsResult<(Vec<u8>, Vec<u8>)> {
let mut reader = BufReader::new(data);
let mut reader = Cursor::new(data);
let ecdh_params: EcdheServerKeyExchange = try!(TlsItem::tls_read(&mut reader));

let gy = &*ecdh_params.params.public;
let gy = &ecdh_params.params.public;
let gy = p256::NPoint256::from_uncompressed_bytes(gy);
let gy = match gy {
None => {
Expand All @@ -51,12 +53,12 @@ impl KeyExchange for EllipticDiffieHellman {
fn get_random_x(rng: &mut OsRng) -> p256::int256::Int256 {
loop {
let mut x = p256::int256::ZERO;
for i in 0us..8 {
x.v[i] = rng.next_u32();
for i in 0..8 {
x.v[i] = W(rng.next_u32());
}
let xx = x.reduce_once(0);
let xx = x.reduce_once(W(0));
let x_is_okay = xx.compare(&x);
if x_is_okay == 0 {
if x_is_okay == W(0) {
return x;
}
}
Expand Down
9 changes: 5 additions & 4 deletions src/cipher/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use rand::OsRng;

use util::{ReadExt, WriteExt};
use tls_result::TlsResult;
use tls_result::TlsErrorKind::UnexpectedMessage;
use tls_item::TlsItem;
Expand Down Expand Up @@ -52,7 +53,7 @@ macro_rules! cipher_suite {
pub fn new_aead(&self) -> Box<Aead> {
match *self {
$(
CipherSuite::$id => box $cipher as Box<Aead>,
CipherSuite::$id => Box::new($cipher) as Box<Aead>,
)+
CipherSuite::UnknownCipherSuite => unreachable!(),
}
Expand All @@ -61,7 +62,7 @@ macro_rules! cipher_suite {
pub fn new_kex(&self) -> Box<KeyExchange> {
match *self {
$(
CipherSuite::$id => box $kex as Box<KeyExchange>,
CipherSuite::$id => Box::new($kex) as Box<KeyExchange>,
)+
CipherSuite::UnknownCipherSuite => unreachable!(),
}
Expand All @@ -72,7 +73,7 @@ macro_rules! cipher_suite {
}

impl TlsItem for CipherSuite {
fn tls_write<W: Writer>(&self, writer: &mut W) -> TlsResult<()> {
fn tls_write<W: WriteExt>(&self, writer: &mut W) -> TlsResult<()> {
$(
if *self == CipherSuite::$id {
try!(writer.write_u8($v1));
Expand All @@ -84,7 +85,7 @@ macro_rules! cipher_suite {
return tls_err!(UnexpectedMessage, "unexpected CipherSuite: {:?}", self);
}

fn tls_read<R: Reader>(reader: &mut R) -> TlsResult<CipherSuite> {
fn tls_read<R: ReadExt>(reader: &mut R) -> TlsResult<CipherSuite> {
let id1 = try!(reader.read_u8());
let id2 = try!(reader.read_u8());
$(
Expand Down
28 changes: 14 additions & 14 deletions src/cipher/prf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ pub fn hmac_sha256(key: &[u8], msg: &[u8]) -> [u8; 32] {

let mut i_msg = [0x36u8; B].to_vec();
let mut o_msg = [0x5cu8; B].to_vec();
for i in (0us..key.len()) {
for i in (0..key.len()) {
i_msg[i] ^= key[i];
o_msg[i] ^= key[i];
}

i_msg.push_all(msg);
let h_i = sha256(&i_msg[]);
o_msg.push_all(&h_i[]);
let h_o = sha256(&o_msg[]);
let h_i = sha256(&i_msg);
o_msg.push_all(&h_i);
let h_o = sha256(&o_msg);

h_o
}
Expand All @@ -37,7 +37,7 @@ pub struct Prf {

impl Prf {
pub fn new(secret: Vec<u8>, seed: Vec<u8>) -> Prf {
let a1 = hmac_sha256(&secret[], &seed[]);
let a1 = hmac_sha256(&secret, &seed);

Prf {
secret: secret,
Expand All @@ -50,9 +50,9 @@ impl Prf {
// get 32-byte pseudorandom number.
fn next_block(&mut self) -> [u8; 32] {
let mut input = self.a.to_vec();
input.push_all(&self.seed[]);
let next = hmac_sha256(&self.secret[], &input[]);
self.a = hmac_sha256(&self.secret[], &self.a[]);
input.push_all(&self.seed);
let next = hmac_sha256(&self.secret, &input);
self.a = hmac_sha256(&self.secret, &self.a);

next
}
Expand All @@ -78,7 +78,7 @@ impl Prf {
let next_block = self.next_block();
let slice_len = size - ret.len();
if slice_len > 32 {
ret.push_all(&next_block[]);
ret.push_all(&next_block);
} else {
ret.push_all(&next_block[..slice_len]);
self.buf = next_block[slice_len..].to_vec();
Expand Down Expand Up @@ -128,7 +128,7 @@ mod test {

for &(key, input, expected) in VALUES.iter() {
let actual = hmac_sha256(key, input);
assert_eq!(&actual[], expected);
assert_eq!(&actual, expected);
}
}

Expand All @@ -137,8 +137,8 @@ mod test {
let ret1 = {
let mut prf = Prf::new(Vec::new(), Vec::new());
let mut ret = Vec::new();
for _ in 0us..100 {
ret.push_all(&prf.get_bytes(1)[]);
for _ in 0..100 {
ret.push_all(&prf.get_bytes(1));
}
ret
};
Expand All @@ -153,8 +153,8 @@ mod test {
let ret3 = {
let mut prf = Prf::new(Vec::new(), Vec::new());
let mut b = prf.get_bytes(33);
b.push_all(&prf.get_bytes(33)[]);
b.push_all(&prf.get_bytes(100 - 33 * 2)[]);
b.push_all(&prf.get_bytes(33));
b.push_all(&prf.get_bytes(100 - 33 * 2));
b
};

Expand Down
Loading

0 comments on commit 7e1525f

Please sign in to comment.