80551f88afb33ed56d1ab7d13c5a822662843ae8
[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 do_oracle_attack(address: &str, variant: packet::Variant) {
19 // 16 bytes encrypted data from 'Packet::random_packet_data([4])'.
20 let cipher_block = [191, 192, 149, 84, 202, 163, 109, 230, 173, 249, 170, 248, 83, 60, 228, 111]; // Known by the attacker.
21 let xor_operand = [213, 29, 217, 187, 93, 103, 76, 129, 233, 142, 98, 83, 69, 50, 97, 91]; // This is the IV or the previous 16 bytes cipherblock. In our case we took the previous block.
22 let expected_plain_block = [242, 93, 12, 22, 8, 164, 4, 77, 200, 120, 189, 71, 75, 189, 2, 2]; // To be found by the attacker.
23
24 /* Another sample with an IV instead of a previous block.
25 let cipher_block: [u8, ..16] = [254, 9, 228, 149, 60, 42, 165, 34, 233, 75, 112, 57, 37, 9, 116, 103];
26 let xor_operand: [u8, ..16] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3]; IV.
27 let expected_plain_block: [u8, ..16] = [44, 92, 31, 98, 220, 84, 226, 53, 58, 94, 45, 25, 242, 6, 199, 1];
28 */
29
30 match oracle_machine::decipher(address, PORT, &xor_operand, &cipher_block, variant) {
31 Some(ref deciphered) if deciphered.as_slice() == expected_plain_block => {
32 println!("The oracle machine has found the plain block!:");
33 println!(" Expected block: {}", expected_plain_block.to_vec());
34 println!(" Decrypted block: {}", deciphered)
35 }
36 Some(ref other) =>
37 println!("The oracle machine hasn't found the plain block: {}", other),
38 _ =>
39 println!("The oracle machine hasn't found the plain block"),
40 }
41 }
42
43 fn print_usage() {
44 println!(
45 r"{} [genkey | tests | oracle-weak | oracle-fixed]
46 genkey: Generate a 256 bits key
47 tests: launch some tests between a client and a weak server
48 oracle-weak: launch a padding oracle attack against a weak server
49 oracle-fixed: launch a padding oracle attack against a fixed server",
50 os::args()[0]
51 );
52 }
53
54 enum Mode {
55 Help,
56 ServerAlone,
57 GenKey,
58 Tests,
59 OracleWeak,
60 OracleFixed,
61 }
62
63 fn mode() -> Mode {
64 let args = os::args();
65
66 if args.iter().any(|a| a.as_slice() == "--help" || a.as_slice() == "-h") {
67 return Mode::Help
68 }
69
70 if args.len() <= 1 {
71 Mode::ServerAlone
72 } else {
73 match args[1].as_slice() {
74 "genkey" => Mode::GenKey,
75 "tests" => Mode::Tests,
76 "oracle-weak" => Mode::OracleWeak,
77 "oracle-fixed" => Mode::OracleFixed,
78 _ => Mode::ServerAlone,
79 }
80 }
81 }
82
83 fn main() {
84 let mode = mode();
85
86 match mode {
87 Mode::Help => print_usage(),
88 Mode::GenKey =>
89 match crypto::generate_key(256 / 8) {
90 Ok(key) => println!("key: {}", key),
91 Err(e) => println!("Unable to generate a key. Error: {}", e)
92 },
93 _ => {
94 let address = "::1";
95 println!("Starting server on [{}]:{}...", address, PORT);
96
97 match Server::new(address, PORT, match mode { Mode::OracleFixed => packet::Variant::Fixed, _ => packet::Variant::Weak }) {
98 Ok(mut server) => {
99 println!("Server started");
100
101 match mode {
102 Mode::Tests => Client::start_tests(address, PORT, packet::Variant::Weak),
103 Mode::OracleWeak => do_oracle_attack(address, packet::Variant::Weak),
104 Mode::OracleFixed => do_oracle_attack(address, packet::Variant::Fixed),
105 _ => {
106 println!("Press any key to quit");
107 io::stdin().read_line().ok().expect("Failed to read line");
108 }
109 }
110
111 server.close().ok().expect("Failed to close the server");
112 },
113 Err(e) =>
114 println!("Unable to create a new server. Error: {}", e)
115 }
116 }
117 }
118 }