mix/
lib.rs

1extern crate crypto;
2extern crate rand;
3extern crate base64;
4
5
6use std::str;
7
8use rand::{thread_rng, Rng};
9use base64::{encode, decode};
10use crypto::{symmetriccipher, buffer, aes, blockmodes};
11use crypto::buffer::{ReadBuffer, WriteBuffer, BufferResult};
12
13
14fn aes_256_ecb_encrypt(
15    data: &[u8],
16    key: &[u8],
17) -> Result<Vec<u8>, symmetriccipher::SymmetricCipherError> {
18    let mut encryptor = aes::ecb_encryptor(aes::KeySize::KeySize256, key, blockmodes::PkcsPadding);
19
20    let mut final_result = Vec::<u8>::new();
21    let mut read_buffer = buffer::RefReadBuffer::new(data);
22    let mut buffer = [0; 4096];
23    let mut write_buffer = buffer::RefWriteBuffer::new(&mut buffer);
24
25    loop {
26        let result = try!(encryptor.encrypt(&mut read_buffer, &mut write_buffer, true));
27
28        final_result.extend(
29            write_buffer
30                .take_read_buffer()
31                .take_remaining()
32                .iter()
33                .map(|&i| i),
34        );
35
36        match result {
37            BufferResult::BufferUnderflow => break,
38            BufferResult::BufferOverflow => {}
39        }
40    }
41
42    Ok(final_result)
43}
44
45
46fn aes_256_ecb_decrypt(
47    encrypted_data: &[u8],
48    key: &[u8],
49) -> Result<Vec<u8>, symmetriccipher::SymmetricCipherError> {
50    let mut decryptor = aes::ecb_decryptor(aes::KeySize::KeySize256, key, blockmodes::PkcsPadding);
51
52    let mut final_result = Vec::<u8>::new();
53    let mut read_buffer = buffer::RefReadBuffer::new(encrypted_data);
54    let mut buffer = [0; 4096];
55    let mut write_buffer = buffer::RefWriteBuffer::new(&mut buffer);
56
57    loop {
58        let result = try!(decryptor.decrypt(&mut read_buffer, &mut write_buffer, true));
59        final_result.extend(
60            write_buffer
61                .take_read_buffer()
62                .take_remaining()
63                .iter()
64                .map(|&i| i),
65        );
66        match result {
67            BufferResult::BufferUnderflow => break,
68            BufferResult::BufferOverflow => {}
69        }
70    }
71
72    Ok(final_result)
73}
74
75
76pub fn encrypt(buf: &[u8], key: &[u8]) -> Result<Vec<u8>, String> {
77    match aes_256_ecb_encrypt(buf, key) {
78        Ok(encrypted_data) => Ok(encode(encrypted_data.as_slice()).into_bytes()),
79        Err(e) => Err(format!("{:?}", e)),
80    }
81}
82
83
84pub fn decrypt(buf: &[u8], key: &[u8]) -> Result<Vec<u8>, String> {
85    match decode(buf) {
86        Ok(encrypted_data) => {
87            match aes_256_ecb_decrypt(encrypted_data.as_slice(), key) {
88                Ok(decrypted_data) => {
89                    Ok(decrypted_data)
90                }
91                Err(e) => Err(format!("{:?}", e)),
92            }
93        }
94        Err(e) => Err(format!("{}", e)),
95    }
96}
97
98
99pub fn genattr() -> String {
100    format!(
101        "\
102* filter=git-mix
103.gitattributes !filter
104"
105    )
106}
107
108
109pub fn gen(specifed: Option<&str>) -> String {
110    let key;
111
112    match specifed {
113        Some(s) => key = s.to_string(),
114        None => key = genkey(32),
115    }
116
117    format!(
118        "\
119[filter \"git-mix\"]
120    clean = git-mix encrypt --key {key}
121    smudge = git-mix decrypt --key {key}
122",
123        key = key
124    )
125}
126
127
128pub fn genkey(len: usize) -> String {
129    thread_rng().gen_ascii_chars().take(len).collect::<String>()
130}