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];
+/// Only returns the first ten bytes.
pub fn compute_mac(data: &[u8]) -> [u8, ..10] {
let mut hmac = HMAC(SHA256, KEY_A);
hmac.update(data);
result
}
+/// Encrypt may fail if the provided data size isn't a multiple of 16.
pub fn encrypt(plaindata: &[u8], iv: &[u8]) -> Option<Vec<u8>> {
let c = symm::Crypter::new(symm::AES_256_CBC);
c.init(symm::Encrypt, KEY_C, iv.to_vec());
c.pad(false); // Padding disabled!
- let mut r = c.update(plaindata);
+ let r = c.update(plaindata);
let rest = c.finalize();
if rest.is_empty() {
Some(r)
}
}
+/// Decrypt may fail if the provided data size isn't a multiple of 16.
pub fn decrypt(cypherdata: &[u8], iv: &[u8]) -> Option<Vec<u8>> {
let c = symm::Crypter::new(symm::AES_256_CBC);
c.init(symm::Decrypt, KEY_C, iv.to_vec());
c.pad(false); // Padding disabled!
- let mut r = c.update(cypherdata);
+ let r = c.update(cypherdata);
let rest = c.finalize();
if rest.is_empty() {
Some(r)
end_point: EndPoint,
}
-struct EndPoint {
+pub struct EndPoint {
socket: TcpStream,
current_timestamp: u64
}
for stream in acceptor.incoming() {
match stream {
Ok(stream) => spawn(proc() {
- Server::handle_client(EndPoint { socket: stream, current_timestamp: 0 });
+ Server::handle_client(EndPoint::new(stream));
}),
_ => return
}
}
impl EndPoint {
+ pub fn new(socket: TcpStream) -> EndPoint {
+ EndPoint { socket: socket, current_timestamp: 0 }
+ }
+
fn close(&mut self) -> IoResult<()> {
try!(self.socket.close_read());
try!(self.socket.close_write());
mod crypto;
mod packet;
mod end_point;
+mod oracle_machine;
const PORT: u16 = 4221;
fn print_usage() {
- println!("{} <genkey> | <tests> | ...", os::args()[0]);
+ println!(
+ r"{} genkey | tests | oracle-weak | oracle-fixed
+ genkey: Generate a 256 bits key
+ tests: launch some tests between a client and a weak server
+ oracle-weak: launch a padding oracle attack against a weak server
+ oracle-fixed: launch a padding oracle attack against a fixed server",
+ os::args()[0]
+ );
}
fn main() {
Ok(mut server) => {
println!("Server started");
- Client::start_tests("::1", PORT);
+ if args.len() > 1 && args[1].as_slice() == "tests" {
+ Client::start_tests("::1", PORT);
+ }
println!("Press any key to quit");
io::stdin().read_line().ok().expect("Failed to read line");
--- /dev/null
+use std::io;
+use std::io::{ TcpStream };
+use end_point::EndPoint;
+
+/// Try to decypher a cyphered data block by using an oracle on the provided address and port.
+/// May prints some message on the stdout.
+pub fn decypher(address: &str, port: u16, cypherblock: [u8, ..16]) -> Option<Vec<u8>> {
+ let end_point = EndPoint::new(
+ match TcpStream::connect(address, port) {
+ Ok(s) => s,
+ _ => {
+ println!("Unable to connect to the oracle on {}:{}", address, port);
+ return None
+ }
+ }
+ );
+
+ None
+}