* Oracle machine finished.
[crypto_lab1.git] / lab1_rust / src / main.rs
1 #![feature(macro_rules)]
2
3 extern crate openssl;
4 extern crate serialize;
5
6 use std::io;
7 use std::os;
8
9 use end_point::{ Client, Server };
10
11 mod crypto;
12 mod packet;
13 mod end_point;
14 mod oracle_machine;
15
16 const PORT: u16 = 4221;
17
18 fn print_usage() {
19 println!(
20 r"{} [genkey | tests | oracle-weak | oracle-fixed]
21 genkey: Generate a 256 bits key
22 tests: launch some tests between a client and a weak server
23 oracle-weak: launch a padding oracle attack against a weak server
24 oracle-fixed: launch a padding oracle attack against a fixed server",
25 os::args()[0]
26 );
27 }
28
29 fn do_oracle_attack(address: &str, variant: packet::Variant) {
30 // 16 bytes encrypted data from 'Packet::random_packet_data([4])'.
31 let cypher_block: [u8, ..16] = [254, 9, 228, 149, 60, 42, 165, 34, 233, 75, 112, 57, 37, 9, 116, 103]; // Known by the attacker.
32 let xor_operand: [u8, ..16] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3]; // This is the IV or the previous 16 bytes cypherblock. In our case we took the IV.
33
34 let expected_clear_block: [u8, ..16] = [44, 92, 31, 98, 220, 84, 226, 53, 58, 94, 45, 25, 242, 6, 199, 1]; // To be found by the attacker.
35
36 match oracle_machine::decypher(address, PORT, &xor_operand, &cypher_block, variant) {
37 Some(ref decyphered) if decyphered.as_slice() == expected_clear_block => {
38 println!("The oracle machine has found the clear block!:");
39 println!(" Expected block: {}", expected_clear_block.to_vec());
40 println!(" Decrypted block: {}", decyphered)
41 }
42 Some(ref other) =>
43 println!("The oracle machine hasn't found the clear block: {}", other),
44 _ =>
45 println!("The oracle machine hasn't found the clear block"),
46 }
47 }
48
49 enum Mode {
50 Help,
51 ServerAlone,
52 GenKey,
53 Tests,
54 OracleWeak,
55 OracleFixed,
56 }
57
58 fn mode() -> Mode {
59 let args = os::args();
60
61 if args.iter().any(|a| a.as_slice() == "--help" || a.as_slice() == "-h") {
62 return Help
63 }
64
65 if args.len() <= 1 {
66 ServerAlone
67 } else {
68 match args[1].as_slice() {
69 "genkey" => GenKey,
70 "tests" => Tests,
71 "oracle-weak" => OracleWeak,
72 "oracle-fixed" => OracleFixed,
73 _ => ServerAlone,
74 }
75 }
76 }
77
78 fn main() {
79 let mode = mode();
80
81 match mode {
82 Help => print_usage(),
83 GenKey =>
84 match crypto::generate_key(256 / 8) {
85 Ok(key) => println!("key: {}", key),
86 Err(e) => println!("Unable to generate a key. Error: {}", e)
87 },
88 _ => {
89 let address = "::1";
90 println!("Starting server on [{}]:{}...", address, PORT);
91
92 match Server::new(address, PORT, match mode { OracleFixed => packet::Fixed, _ => packet::Weak }) {
93 Ok(mut server) => {
94 println!("Server started");
95
96 match mode {
97 Tests => Client::start_tests(address, PORT, packet::Weak),
98 OracleWeak => do_oracle_attack(address, packet::Weak),
99 OracleFixed => do_oracle_attack(address, packet::Fixed),
100 _ => {
101 println!("Press any key to quit");
102 io::stdin().read_line().ok().expect("Failed to read line");
103 }
104 }
105
106 server.close().ok().expect("Failed to close the server");
107 },
108 Err(e) =>
109 println!("Unable to create a new server. Error: {}", e)
110 }
111 }
112 }
113 }