From 4d892f864a1f47eb1aab23f1c70ccb143081849c Mon Sep 17 00:00:00 2001 From: Ummon Date: Fri, 21 Nov 2014 18:10:39 +0100 Subject: [PATCH] Fixes the code to the new Rust nightly build changes. --- lab1_rust/Cargo.lock | 34 +++++++++++++++- lab1_rust/Cargo.toml | 4 +- lab1_rust/src/crypto.rs | 4 +- lab1_rust/src/end_point.rs | 37 ++++++++--------- lab1_rust/src/main.rs | 28 ++++++------- lab1_rust/src/oracle_machine.rs | 9 +++-- lab1_rust/src/packet.rs | 71 +++++++++++++++++---------------- 7 files changed, 111 insertions(+), 76 deletions(-) diff --git a/lab1_rust/Cargo.lock b/lab1_rust/Cargo.lock index 38e35bb..fd2a459 100644 --- a/lab1_rust/Cargo.lock +++ b/lab1_rust/Cargo.lock @@ -2,11 +2,41 @@ name = "lab1_rust" version = "0.0.2" dependencies = [ - "openssl 0.0.1 (git+https://github.com/sfackler/rust-openssl.git?ref=1f1c30dd3a577b301bb85bf95f964227f84d73fd#1f1c30dd3a577b301bb85bf95f964227f84d73fd)", + "openssl 0.0.1 (git+https://github.com/sfackler/rust-openssl.git)", +] + +[[package]] +name = "libressl-pnacl-sys" +version = "2.0.1" +source = "git+https://github.com/DiamondLovesYou/libressl-pnacl-sys.git#9a42eeb52070ae0aa4f666d36198899e1e54cda5" +dependencies = [ + "pnacl-build-helper 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "openssl" version = "0.0.1" -source = "git+https://github.com/sfackler/rust-openssl.git?ref=1f1c30dd3a577b301bb85bf95f964227f84d73fd#1f1c30dd3a577b301bb85bf95f964227f84d73fd" +source = "git+https://github.com/sfackler/rust-openssl.git#33af6a0b7a1037945181db96cf4f6915457a3df6" +dependencies = [ + "libressl-pnacl-sys 2.0.1 (git+https://github.com/DiamondLovesYou/libressl-pnacl-sys.git)", + "openssl-sys 0.0.1 (git+https://github.com/sfackler/rust-openssl.git)", +] + +[[package]] +name = "openssl-sys" +version = "0.0.1" +source = "git+https://github.com/sfackler/rust-openssl.git#33af6a0b7a1037945181db96cf4f6915457a3df6" +dependencies = [ + "pkg-config 0.0.1 (git+https://github.com/alexcrichton/pkg-config-rs)", +] + +[[package]] +name = "pkg-config" +version = "0.0.1" +source = "git+https://github.com/alexcrichton/pkg-config-rs#d24a08d87d63df8dc9526c503944415b86719220" + +[[package]] +name = "pnacl-build-helper" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/lab1_rust/Cargo.toml b/lab1_rust/Cargo.toml index 1d1bc05..1f50cc1 100644 --- a/lab1_rust/Cargo.toml +++ b/lab1_rust/Cargo.toml @@ -12,4 +12,6 @@ name = "lab1_rust" [dependencies.openssl] git = "https://github.com/sfackler/rust-openssl.git" -rev = "1f1c30dd3a577b301bb85bf95f964227f84d73fd" +#git = "https://github.com/vhbit/rust-openssl.git" + +#rev = "1f1c30dd3a577b301bb85bf95f964227f84d73fd" diff --git a/lab1_rust/src/crypto.rs b/lab1_rust/src/crypto.rs index 2e8e046..cc217a6 100644 --- a/lab1_rust/src/crypto.rs +++ b/lab1_rust/src/crypto.rs @@ -6,8 +6,8 @@ use openssl::crypto::hmac::HMAC; use openssl::crypto::symm; // These aren't the keys you're looking for. -static KEY_A: &'static [u8] = [125, 31, 131, 118, 143, 180, 252, 53, 211, 217, 79, 240, 128, 91, 252, 87, 104, 236, 145, 198, 163, 203, 161, 12, 53, 56, 218, 40, 221, 95, 171, 140]; -static KEY_C: &'static [u8] = [75, 226, 88, 31, 223, 216, 182, 216, 178, 58, 59, 193, 245, 80, 254, 128, 125, 246, 246, 224, 194, 190, 123, 123, 10, 131, 217, 183, 112, 157, 166, 102]; +const KEY_A: &'static [u8] = &[125, 31, 131, 118, 143, 180, 252, 53, 211, 217, 79, 240, 128, 91, 252, 87, 104, 236, 145, 198, 163, 203, 161, 12, 53, 56, 218, 40, 221, 95, 171, 140]; +const KEY_C: &'static [u8] = &[75, 226, 88, 31, 223, 216, 182, 216, 178, 58, 59, 193, 245, 80, 254, 128, 125, 246, 246, 224, 194, 190, 123, 123, 10, 131, 217, 183, 112, 157, 166, 102]; /// Only returns the first ten bytes from HMAC-SHA256. pub fn compute_mac(data: &[u8]) -> [u8, ..10] { diff --git a/lab1_rust/src/end_point.rs b/lab1_rust/src/end_point.rs index bf8d4de..e7b0e32 100644 --- a/lab1_rust/src/end_point.rs +++ b/lab1_rust/src/end_point.rs @@ -2,7 +2,8 @@ use std::io; use std::io::{ MemWriter, Acceptor, Listener, TcpStream, IoResult, IoError, EndOfFile }; use std::io::net::tcp::{ TcpAcceptor, TcpListener }; use packet; -use packet::{ Packet, Command, Answer, Error, ReadingResult, PacketType }; +use packet::{ Packet, ReadingResult, PacketType }; +use packet::PacketType::{ Command, Answer, Error }; // Default timeout when waiting data on a stream (for instance: 'TcpStream::read'). static DEFAULT_TIMEOUT: Option = Some(500); // [ms]. @@ -54,7 +55,7 @@ impl Server { match end_point.read() { Ok(packet@Packet { t: Command(..), .. }) => { end_point.print("Server", format!("Valid command received: {}", packet)); - let answer = Answer(Packet::random_packet_data([])); + let answer = Answer(Packet::random_packet_data(&[])); match end_point.send(answer.clone()) { Ok(_) => end_point.print("Server", format!("Answer sent: {}", answer)), @@ -63,7 +64,7 @@ impl Server { } }, // Socket has been closed. - Err(packet::IOReadError(IoError { kind: EndOfFile, .. })) => { + Err(packet::ReadingError::IO(IoError { kind: EndOfFile, .. })) => { end_point.print("Server", format!("Connection closed: EOF")); return }, @@ -133,7 +134,7 @@ impl Client { fn raw_packet(timestamp: u64) -> Vec { let mut m = MemWriter::new(); - match (Packet { t: Command(Packet::random_packet_data([42])), timestamp: timestamp }).write(&mut m, packet::Weak) { + match (Packet { t: Command(Packet::random_packet_data(&[42])), timestamp: timestamp }).write(&mut m, packet::Variant::Weak) { Err(_) => vec!(), _ => m.unwrap() } @@ -143,7 +144,7 @@ impl Client { // 1) |client: &mut Client| -> bool { println!("Sending a valid packet..."); - client.send(Command(Packet::random_packet_data([42]))) + client.send(Command(Packet::random_packet_data(&[42]))) }, // 2) |client: &mut Client| -> bool { @@ -152,7 +153,7 @@ impl Client { let mut raw_packet = raw_packet(client.end_point.current_timestamp); raw_packet[2] = 0xEE; // Alter the type. match client.end_point.send_raw_with_result(raw_packet.as_slice()) { - Ok(Err(packet::IOReadError( IoError { kind: io::TimedOut, .. }))) => true, // OK: the server should not send any packet. + Ok(Err(packet::ReadingError::IO( IoError { kind: io::TimedOut, .. }))) => true, // OK: the server should not send any packet. other => { println!("Error: {}", other); false @@ -165,7 +166,7 @@ impl Client { client.end_point.current_timestamp += 1; let raw_packet = raw_packet(0); match client.end_point.send_raw_with_result(raw_packet.as_slice()) { - Ok(Err(packet::IOReadError( IoError { kind: io::TimedOut, .. }))) => true, // OK: the server should not send any packet. + Ok(Err(packet::ReadingError::IO( IoError { kind: io::TimedOut, .. }))) => true, // OK: the server should not send any packet. other => { println!("Error: {}", other); false @@ -182,7 +183,7 @@ impl Client { raw_packet[13] = 0xBE; raw_packet[14] = 0xEF; match client.end_point.send_raw_with_result(raw_packet.as_slice()) { - Ok(Ok(Packet { t: Error(packet::AuthError), .. })) => true, + Ok(Ok(Packet { t: Error(packet::ErrorType::Auth), .. })) => true, other => { println!("Error: {}", other); false @@ -194,7 +195,7 @@ impl Client { println!("Sending a packet with too small data..."); let command = Command(Packet::new_packet_data(0, Vec::from_elem(6, 0x00))); match client.end_point.send_with_result(command) { - Ok(Err(packet::IOReadError( IoError { kind: io::TimedOut, .. }))) => true, // OK: the server should not send any packet. + Ok(Err(packet::ReadingError::IO( IoError { kind: io::TimedOut, .. }))) => true, // OK: the server should not send any packet. other => { println!("Error: {}", other); false @@ -206,7 +207,7 @@ impl Client { println!("Sending a packet with too large data..."); let command = Command(Packet::new_packet_data(0, Vec::from_elem(40, 0x00))); match client.end_point.send_with_result(command) { - Ok(Err(packet::IOReadError( IoError { kind: io::TimedOut, .. }))) => true, // OK: the server should not send any packet. + Ok(Err(packet::ReadingError::IO( IoError { kind: io::TimedOut, .. }))) => true, // OK: the server should not send any packet. other => { println!("Error: {}", other); false @@ -218,13 +219,13 @@ impl Client { println!("Sending a packet with wrong padding (all 0)..."); client.end_point.current_timestamp += 1; let mut m = MemWriter::new(); - let raw_packet = match (Packet { t: Command(Packet::random_packet_data([42])), timestamp: client.end_point.current_timestamp }).write_with_padding_fun(&mut m, packet::Weak, |_, _| -> u8 { 0 }) { + let raw_packet = match (Packet { t: Command(Packet::random_packet_data(&[42])), timestamp: client.end_point.current_timestamp }).write_with_padding_fun(&mut m, packet::Variant::Weak, |_, _| -> u8 { 0 }) { Err(_) => vec!(), _ => m.unwrap() }; match client.end_point.send_raw_with_result(raw_packet.as_slice()) { - Ok(Ok(Packet { t: Error(packet::CryptError), .. })) => true, + Ok(Ok(Packet { t: Error(packet::ErrorType::Crypt), .. })) => true, other => { println!("Error: {}", other); false @@ -291,7 +292,7 @@ impl EndPoint { self.socket.set_timeout(DEFAULT_TIMEOUT); self.current_timestamp += 1; match (Packet { t: p, timestamp: self.current_timestamp }).write(&mut self.socket, self.variant) { - Err(packet::WriteIOError(e)) => Err(e), + Err(packet::WritingError::IO(e)) => Err(e), _ => Ok(()) } } @@ -309,20 +310,20 @@ impl EndPoint { Ok(packet) => { if packet.timestamp <= self.current_timestamp { println!("Error, timestamp mismatch, current timestamp: {}, packet received: {}", self.current_timestamp, packet); - Err(packet::InvalidTimestampError) + Err(packet::ReadingError::InvalidTimestamp) } else { self.current_timestamp = packet.timestamp + 1; Ok(packet) } }, - e @ Err(packet::PaddingError) => { + e @ Err(packet::ReadingError::Padding) => { self.current_timestamp += 1; - send_error(self, packet::CryptError); + send_error(self, packet::ErrorType::Crypt); e }, - e @ Err(packet::MACMismatchError) => { + e @ Err(packet::ReadingError::MACMismatch) => { self.current_timestamp += 1; - send_error(self, packet::AuthError); + send_error(self, packet::ErrorType::Auth); e }, other => diff --git a/lab1_rust/src/main.rs b/lab1_rust/src/main.rs index dbaebea..3beee95 100644 --- a/lab1_rust/src/main.rs +++ b/lab1_rust/src/main.rs @@ -28,7 +28,7 @@ fn do_oracle_attack(address: &str, variant: packet::Variant) { */ match oracle_machine::decipher(address, PORT, &xor_operand, &cipher_block, variant) { - Some(ref deciphered) if deciphered.as_slice() == expected_plain_block => { + Some(ref deciphered) if deciphered.as_slice() == &expected_plain_block => { println!("The oracle machine has found the plain block!:"); println!(" Expected block: {}", expected_plain_block.to_vec()); println!(" Decrypted block: {}", deciphered) @@ -64,18 +64,18 @@ fn mode() -> Mode { let args = os::args(); if args.iter().any(|a| a.as_slice() == "--help" || a.as_slice() == "-h") { - return Help + return Mode::Help } if args.len() <= 1 { - ServerAlone + Mode::ServerAlone } else { match args[1].as_slice() { - "genkey" => GenKey, - "tests" => Tests, - "oracle-weak" => OracleWeak, - "oracle-fixed" => OracleFixed, - _ => ServerAlone, + "genkey" => Mode::GenKey, + "tests" => Mode::Tests, + "oracle-weak" => Mode::OracleWeak, + "oracle-fixed" => Mode::OracleFixed, + _ => Mode::ServerAlone, } } } @@ -84,8 +84,8 @@ fn main() { let mode = mode(); match mode { - Help => print_usage(), - GenKey => + Mode::Help => print_usage(), + Mode::GenKey => match crypto::generate_key(256 / 8) { Ok(key) => println!("key: {}", key), Err(e) => println!("Unable to generate a key. Error: {}", e) @@ -94,14 +94,14 @@ fn main() { let address = "::1"; println!("Starting server on [{}]:{}...", address, PORT); - match Server::new(address, PORT, match mode { OracleFixed => packet::Fixed, _ => packet::Weak }) { + match Server::new(address, PORT, match mode { Mode::OracleFixed => packet::Variant::Fixed, _ => packet::Variant::Weak }) { Ok(mut server) => { println!("Server started"); match mode { - Tests => Client::start_tests(address, PORT, packet::Weak), - OracleWeak => do_oracle_attack(address, packet::Weak), - OracleFixed => do_oracle_attack(address, packet::Fixed), + Mode::Tests => Client::start_tests(address, PORT, packet::Variant::Weak), + Mode::OracleWeak => do_oracle_attack(address, packet::Variant::Weak), + Mode::OracleFixed => do_oracle_attack(address, packet::Variant::Fixed), _ => { println!("Press any key to quit"); io::stdin().read_line().ok().expect("Failed to read line"); diff --git a/lab1_rust/src/oracle_machine.rs b/lab1_rust/src/oracle_machine.rs index 8bf3933..018e2a5 100644 --- a/lab1_rust/src/oracle_machine.rs +++ b/lab1_rust/src/oracle_machine.rs @@ -3,7 +3,8 @@ use std::io::TcpStream; use std::iter::range_inclusive; use std::slice::bytes::copy_memory; use packet; -use packet::{ Packet, Error }; +use packet::Packet; +use packet::PacketType::Error; use end_point::EndPoint; /// Tries to decipher a ciphered data block by using the previous XOR operand and an oracle on the provided address and port. @@ -49,8 +50,8 @@ pub fn decipher(address: &str, port: u16, original_xor_operand: &[u8, ..16], cip forged_xor_operand(&mut final_packet)[byte] = v; - match end_point.send_raw_with_result(final_packet) { - Ok(Ok(p @ Packet { t: Error(packet::AuthError), .. })) => { + match end_point.send_raw_with_result(&final_packet) { + Ok(Ok(p @ Packet { t: Error(packet::ErrorType::Auth), .. })) => { println!("We received a MAC Error: {}", p); // If we already got a MAC mismatch for the first byte then @@ -79,7 +80,7 @@ pub fn decipher(address: &str, port: u16, original_xor_operand: &[u8, ..16], cip break; } }, - Ok(Ok(Packet { t: Error(packet::CryptError), .. })) => (), // Ignored case: the padding is wrong. + Ok(Ok(Packet { t: Error(packet::ErrorType::Crypt), .. })) => (), // Ignored case: the padding is wrong. other => { println!("Unexcepted response, aborting. {}", other); return None diff --git a/lab1_rust/src/packet.rs b/lab1_rust/src/packet.rs index fa13191..f453324 100644 --- a/lab1_rust/src/packet.rs +++ b/lab1_rust/src/packet.rs @@ -3,6 +3,7 @@ use std::fmt; use std::rand::{ Rng, StdRng, SeedableRng, distributions }; use std::rand::distributions::IndependentSample; use serialize::hex::{ ToHex }; +use self::PacketType::{ Command, Answer, Error }; use crypto; pub enum Variant { @@ -13,32 +14,32 @@ pub enum Variant { // There are all the errors that may occur when reading an encrypted and authenticated packet. #[deriving(Show)] pub enum ReadingError { - IOReadError(io::IoError), - UnknownPacketTypeError, // If the first byte is unknown. - UnconsistentEncryptedSizeError, - UnconsistentDataSizeError, // The data size is not valid. - UnconsistentMACSizeError, // The MAC hasn't the correct size. - MACMismatchError, // The uncrypted received data doesn't match to the received MAC. - PaddingError, // Padding format error. - DataError, // The data are invalid. - InvalidTimestampError + IO(io::IoError), + UnknownPacketType, // If the first byte is unknown. + UnconsistentEncryptedSize, + UnconsistentDataSize, // The data size is not valid. + UnconsistentMACSize, // The MAC hasn't the correct size. + MACMismatch, // The uncrypted received data doesn't match to the received MAC. + Padding, // Padding format error. + Data, // The data are invalid. + InvalidTimestamp } -// A macro to return a 'IOReadError' in case of error. +// A macro to return a 'Err(ReadingError::IO(..))' in case of error. macro_rules! try_read_io( - ($e:expr) => (match $e { Ok(e) => e, Err(e) => return Err(IOReadError(e)) }) + ($e:expr) => (match $e { Ok(e) => e, Err(e) => return Err(ReadingError::IO(e)) }) ) // There are all the errors that may occur when encrypting, authenticating and writing a packet. #[deriving(Show)] pub enum WritingError { - WriteIOError(io::IoError), - EncryptError, + IO(io::IoError), + Encrypt, } -// A macro to return a 'IOWritingError' in case of error. +// A macro to return a 'Err(WritingError::IO(..))' in case of error. macro_rules! try_write_io( - ($e:expr) => (match $e { Ok(e) => e, Err(e) => return Err(WriteIOError(e)) }) + ($e:expr) => (match $e { Ok(e) => e, Err(e) => return Err(WritingError::IO(e)) }) ) pub type ReadingResult = Result; @@ -56,8 +57,8 @@ pub struct PacketData { #[deriving(Show, Clone)] pub enum ErrorType { - CryptError, - AuthError + Crypt, + Auth } #[deriving(Clone)] @@ -159,12 +160,12 @@ impl Packet { } // Computes the MAC. It depends of the choosen variant. - let mac = crypto::compute_mac(data.slice_to(match variant { Weak => data_size, _ => data.len() })); + let mac = crypto::compute_mac(data.slice_to(match variant { Variant::Weak => data_size, _ => data.len() })); // Encrypts. let encrypted_data = match crypto::encrypt(data.as_slice(), iv_from_timestamp(self.timestamp).as_slice()) { Some(d) => d, - _ => return Err(EncryptError) + _ => return Err(WritingError::Encrypt) }; // Writes packet length. @@ -175,8 +176,8 @@ impl Packet { match self.t { Command(_) => 0x00, Answer(_) => 0xFF, - Error(CryptError) => 0x0A, - Error(AuthError) => 0x0B + Error(ErrorType::Crypt) => 0x0A, + Error(ErrorType::Auth) => 0x0B } )); @@ -187,7 +188,7 @@ impl Packet { try_write_io!(output.write(encrypted_data.as_slice())); // Writes the MAC. - try_write_io!(output.write(mac)); + try_write_io!(output.write(&mac)); Ok(()) } @@ -203,51 +204,51 @@ impl Packet { let packet_type = try_read_io!(input.read_u8()); if ![0x00, 0xFF, 0x0A, 0x0B].iter().any(|p| *p == packet_type) { consume(input, data_size as uint - 1); - return Err(UnknownPacketTypeError) + return Err(ReadingError::UnknownPacketType) } let timestamp = try_read_io!(input.read_be_u64()); let mut encrypted_data = Vec::from_elem(data_size as uint - FIXED_PACKET_SIZE, 0u8); if try_read_io!(input.read(encrypted_data.as_mut_slice_())) != encrypted_data.len() { - return Err(UnconsistentEncryptedSizeError) + return Err(ReadingError::UnconsistentEncryptedSize) } let mut data = match crypto::decrypt(encrypted_data.as_slice(), iv_from_timestamp(timestamp).as_slice()) { Some(d) => d, - _ => return Err(UnconsistentEncryptedSizeError) + _ => return Err(ReadingError::UnconsistentEncryptedSize) }; // Reads the MAC. let mut mac_read = [0u8, ..10]; - if try_read_io!(input.read(mac_read)) != mac_read.len() { - return Err(UnconsistentMACSizeError) + if try_read_io!(input.read(&mut mac_read)) != mac_read.len() { + return Err(ReadingError::UnconsistentMACSize) } - match variant { Fixed if mac_read != crypto::compute_mac(data.as_slice()) => return Err(MACMismatchError), _ => () }; + match variant { Variant::Fixed if mac_read != crypto::compute_mac(data.as_slice()) => return Err(ReadingError::MACMismatch), _ => () }; // Controls the size and the content of the padding then removes it. if packet_type == 0x00 || packet_type == 0xFF { match data.last() { Some(&padding_size) => { if padding_size as uint > data.len() || padding_size == 0 || data.slice_from(data.len() - padding_size as uint).iter().any(|b| *b != padding_size) { - return Err(PaddingError) + return Err(ReadingError::Padding) } let data_length = data.len() - padding_size as uint; data.truncate(data_length); }, None => - return Err(PaddingError) + return Err(ReadingError::Padding) } } - match variant { Weak if mac_read != crypto::compute_mac(data.as_slice()) => return Err(MACMismatchError), _ => () }; + match variant { Variant::Weak if mac_read != crypto::compute_mac(data.as_slice()) => return Err(ReadingError::MACMismatch), _ => () }; Ok(Packet { t: match packet_type { // Command or answer. 0x00 | 0xFF => { if data.len() < MIN_PAYLOAD_SIZE + 1 || data.len() > MAX_PAYLOAD_SIZE + 1 { - return Err(UnconsistentDataSizeError) + return Err(ReadingError::UnconsistentDataSize) } let pd = PacketData { id: data[0], payload: data.tail().to_vec() }; // match data.as_slice() { [id, payload..] => PacketData { id: id, payload: payload.to_vec() } }; match packet_type { 0x00 => Command(pd), _ => Answer(pd) } @@ -255,11 +256,11 @@ impl Packet { // Error. _ => { if data.len() != 16 { - return Err(UnconsistentDataSizeError) + return Err(ReadingError::UnconsistentDataSize) } else if data != Vec::from_elem(16, 0) { - return Err(DataError) + return Err(ReadingError::Data) } - match packet_type { 0x0A => Error(CryptError), _ => Error(AuthError) } + match packet_type { 0x0A => Error(ErrorType::Crypt), _ => Error(ErrorType::Auth) } } }, timestamp: timestamp -- 2.43.0