Finish challenge 16 and problem set 2.
This commit is contained in:
19
src/bytes.rs
19
src/bytes.rs
@@ -1,6 +1,6 @@
|
||||
#![allow(dead_code)]
|
||||
use rand::Rng;
|
||||
use std::fmt::Write; // need to import this trait
|
||||
use std::fmt::Write;
|
||||
|
||||
#[derive(PartialEq, PartialOrd, Debug)]
|
||||
pub struct Bytes(pub Vec<u8>);
|
||||
@@ -117,6 +117,23 @@ impl Bytes {
|
||||
return true;
|
||||
}
|
||||
|
||||
pub fn remove_pkcs7(&mut self, block_size: usize) -> () {
|
||||
if !self.has_valid_pkcs7(block_size) {
|
||||
return;
|
||||
}
|
||||
let Bytes(v) = self;
|
||||
let pad_byte_count = v[v.len() - 1];
|
||||
for _ in 0..(pad_byte_count as usize) {
|
||||
v.pop();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn flip_bit(&mut self, byte_index: usize, bit_index: usize) -> () {
|
||||
let Bytes(v) = self;
|
||||
let flip_mask: u8 = 0b1 << bit_index;
|
||||
v[byte_index] ^= flip_mask;
|
||||
}
|
||||
|
||||
pub fn xor(Bytes(a): &Bytes, Bytes(b): &Bytes) -> Bytes {
|
||||
Bytes(
|
||||
Iterator::zip(a.iter(), b.iter())
|
||||
|
||||
@@ -5,6 +5,7 @@ pub enum Token {
|
||||
Identifier(String),
|
||||
Equal,
|
||||
Ampersand,
|
||||
Semicolon,
|
||||
}
|
||||
|
||||
pub type Tokens = Vec<Token>;
|
||||
@@ -19,6 +20,9 @@ pub fn parse_key_value(text: &str) -> HashMap<String, String> {
|
||||
[Token::Identifier(key), Token::Equal, Token::Identifier(value), Token::Ampersand] => {
|
||||
result.insert(key.to_string(), value.to_string());
|
||||
}
|
||||
[Token::Identifier(key), Token::Equal, Token::Identifier(value), Token::Semicolon] => {
|
||||
result.insert(key.to_string(), value.to_string());
|
||||
}
|
||||
[Token::Identifier(key), Token::Equal, Token::Identifier(value)] => {
|
||||
result.insert(key.to_string(), value.to_string());
|
||||
}
|
||||
@@ -40,6 +44,8 @@ fn scan(code: &str, mut ix: usize, mut tokens: Tokens) -> Tokens {
|
||||
tokens.push(Token::Ampersand);
|
||||
} else if c == '=' {
|
||||
tokens.push(Token::Equal);
|
||||
} else if c == ';' {
|
||||
tokens.push(Token::Semicolon);
|
||||
} else {
|
||||
panic!("Unexpected char '{}' at index {}", c, ix);
|
||||
}
|
||||
@@ -62,4 +68,4 @@ fn scan_identifier(code: &str, mut ix: usize, mut tokens: Tokens) -> Tokens {
|
||||
scan(code, ix, tokens)
|
||||
}
|
||||
|
||||
const SPECIAL_CHARS: &[char] = &['.', '@'];
|
||||
const SPECIAL_CHARS: &[char] = &['.', '@', '%'];
|
||||
|
||||
34
src/set2.rs
34
src/set2.rs
@@ -411,5 +411,37 @@ pub fn challenge15() {
|
||||
}
|
||||
|
||||
pub fn challenge16() {
|
||||
println!("[xxxx] Challenge 16: TBD");
|
||||
fn encrypt(input: &str, key: &Bytes, iv: &Bytes) -> Bytes {
|
||||
let mut r = String::new();
|
||||
for c in input.chars() {
|
||||
if c == ';' || c == '=' {
|
||||
panic!("encrypt: invalid char {}", c);
|
||||
}
|
||||
}
|
||||
r.push_str("comment1=cooking%20MCs;userdata=");
|
||||
r.push_str(input);
|
||||
r.push_str(";comment2=%20like%20a%20pound%20of%20bacon");
|
||||
let mut cleartext = Bytes(r.as_bytes().to_vec());
|
||||
cleartext.pad_pkcs7(16);
|
||||
cbc::encrypt(&key, &iv, &cleartext)
|
||||
}
|
||||
|
||||
let iv = Bytes::random(16);
|
||||
let key = Bytes::random(16);
|
||||
|
||||
// 0 16 32 48 64
|
||||
// 0..34..78..bc..f0..34..78..bc..f0..34..78..bc..f0..34..78..bc..f0..34..78..bc..f
|
||||
// comment1=cooking%20MCs;userdata=xxx=x;admin=true;comment2=%20like%20a%20pound%20of%20bacon
|
||||
// flip_bit(2, '9') = '='; flip_bit(1, '9') = ';'
|
||||
let mut cipher = encrypt("xxx9x9admin9true", &key, &iv);
|
||||
cipher.flip_bit(19, 2); // results in flipping same bit in byte of the following block
|
||||
cipher.flip_bit(21, 1);
|
||||
cipher.flip_bit(27, 2);
|
||||
let mut cleartext = cbc::decrypt(&key, &iv, &cipher);
|
||||
cleartext.remove_pkcs7(16);
|
||||
let cleartext_stripped = Bytes(cleartext.0[32..].to_vec());
|
||||
let dict = parser::parse_key_value(&cleartext_stripped.to_utf8());
|
||||
let admin_status = dict.get("admin").unwrap();
|
||||
assert_eq!(admin_status, "true");
|
||||
println!("[okay] Challenge 16: admin={}", admin_status);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user