Changes according the latest Rust nightly.
[crypto_lab1.git] / lab1_rust / src / oracle_machine.rs
index a5be2d7..71cee8a 100644 (file)
@@ -1,16 +1,17 @@
 use std::io;
-use std::io::{ TcpStream };
-use std::iter::{ range_inclusive };
+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;
 
-/// Try to decipher a ciphered data block by using the previous xor operand and an oracle on the provided address and port.
-/// May prints some message on the stdout.
-pub fn decipher(address: &str, port: u16, original_xor_operand: &[u8, ..16], cipherblock: &[u8, ..16], variant: packet::Variant) -> Option<Vec<u8>> {
+/// Tries to decipher a ciphered data block by using the previous XOR operand and an oracle on the provided address and port.
+/// May print some messages on stdout.
+pub fn decipher(address: &str, port: u16, original_xor_operand: &[u8; 16], cipher_block: &[u8; 16], variant: packet::Variant) -> Option<Vec<u8>> {
    let mut end_point = EndPoint::new(
-      match TcpStream::connect(address, port) {
+      match TcpStream::connect((address, port)) {
          Ok(s) => s,
          _ => {
             println!("Unable to connect to the oracle on [{}]:{}", address, port);
@@ -20,12 +21,13 @@ pub fn decipher(address: &str, port: u16, original_xor_operand: &[u8, ..16], cip
       variant,
    );
 
-   let mut final_packet = [0u8, ..2 + 1 + 8 + 32 + 10];
-   final_packet[1] = 1 + 8 + 32 + 10; // Data length.
-   copy_memory(final_packet.slice_mut(2 + 1 + 8 + 16, 2 + 1 + 8 + 32), cipherblock);
+   // Sees 'packet::Packet' documentation for a complete description about the binary packet structure.
+   let mut final_packet = [0u8; 2 + 1 + 8 + 32 + 10];
+   final_packet[1] = (final_packet.len() as u8) - 2; // Data length.
+   copy_memory(final_packet.slice_mut(2 + 1 + 8 + 16, 2 + 1 + 8 + 32), cipher_block);
 
-   let mut decipher_block = [0u8, ..16]; // The result.
-   let mut x_prime_block = [0u8, ..16]; // The cipher block ('cipherblock') after AES and before XOR.
+   let mut decipher_block = [0u816]; // The result.
+   let mut x_prime_block = [0u8; 16]; // The cipher block ('cipher_block') after AES and before XOR.
    let mut current_timestamp = 0u64;
    let mut first_byte = 0u8; // Used to save the first byte for the first iteration.
 
@@ -39,7 +41,7 @@ pub fn decipher(address: &str, port: u16, original_xor_operand: &[u8, ..16], cip
 
       for v in range_inclusive(0u8, 255) { // For each values of the current byte.
 
-         // Compute and write timestamp.
+         // Computes and writes timestamp.
          current_timestamp += 2;
          {
             let mut timestamp_writer = io::BufWriter::new(final_packet.slice_mut(2 + 1, 2 + 1 + 8));
@@ -48,11 +50,12 @@ 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 the second byte is incremented and the loop is replayed.
+               // If we already got a MAC mismatch for the first byte then
+               // the second byte is incremented and the main loop is replayed for the first byte.
                if byte == 15 && get_mac_mismatch_error {
                   forged_xor_operand(&mut final_packet)[14] += 1;
                   continue 'main_loop;
@@ -64,19 +67,20 @@ pub fn decipher(address: &str, port: u16, original_xor_operand: &[u8, ..16], cip
                x_prime_block[byte] = v ^ (padding_value as u8);
                decipher_block[byte] = x_prime_block[byte] ^ original_xor_operand[byte];
 
-               // We set the processed bytes of the forged XOR operand to have the next padding value.
+               // We set the processed bytes of the forged XOR operand to have the next padding value (2, 3, 4, etc..).
                for i in range(16 - padding_value, 16) {
                   forged_xor_operand(&mut final_packet)[i] = x_prime_block[i] ^ ((padding_value as u8) + 1);
                }
 
-               // Special case for the first byte: we have to test all the values.
+               // Special case for the first byte: we have to test all the values to avoid a valid padding
+               // which is not [.., 0x01], for instance [.., 0x02, 0x02]. It's a very rare case but not impossible.
                if byte == 15 {
                   first_byte = forged_xor_operand(&mut final_packet)[15];
                } else {
                   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