1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
extern crate crypto;
extern crate rand;
extern crate base64;


use std::str;

use rand::{thread_rng, Rng};
use base64::{encode, decode};
use crypto::{symmetriccipher, buffer, aes, blockmodes};
use crypto::buffer::{ReadBuffer, WriteBuffer, BufferResult};


fn aes_256_ecb_encrypt(
    data: &[u8],
    key: &[u8],
) -> Result<Vec<u8>, symmetriccipher::SymmetricCipherError> {
    let mut encryptor = aes::ecb_encryptor(aes::KeySize::KeySize256, key, blockmodes::PkcsPadding);

    let mut final_result = Vec::<u8>::new();
    let mut read_buffer = buffer::RefReadBuffer::new(data);
    let mut buffer = [0; 4096];
    let mut write_buffer = buffer::RefWriteBuffer::new(&mut buffer);

    loop {
        let result = try!(encryptor.encrypt(&mut read_buffer, &mut write_buffer, true));

        final_result.extend(
            write_buffer
                .take_read_buffer()
                .take_remaining()
                .iter()
                .map(|&i| i),
        );

        match result {
            BufferResult::BufferUnderflow => break,
            BufferResult::BufferOverflow => {}
        }
    }

    Ok(final_result)
}


fn aes_256_ecb_decrypt(
    encrypted_data: &[u8],
    key: &[u8],
) -> Result<Vec<u8>, symmetriccipher::SymmetricCipherError> {
    let mut decryptor = aes::ecb_decryptor(aes::KeySize::KeySize256, key, blockmodes::PkcsPadding);

    let mut final_result = Vec::<u8>::new();
    let mut read_buffer = buffer::RefReadBuffer::new(encrypted_data);
    let mut buffer = [0; 4096];
    let mut write_buffer = buffer::RefWriteBuffer::new(&mut buffer);

    loop {
        let result = try!(decryptor.decrypt(&mut read_buffer, &mut write_buffer, true));
        final_result.extend(
            write_buffer
                .take_read_buffer()
                .take_remaining()
                .iter()
                .map(|&i| i),
        );
        match result {
            BufferResult::BufferUnderflow => break,
            BufferResult::BufferOverflow => {}
        }
    }

    Ok(final_result)
}


pub fn encrypt(buf: &[u8], key: &[u8]) -> Result<String, String> {
    match aes_256_ecb_encrypt(buf, key) {
        Ok(encrypted_data) => Ok(encode(encrypted_data.as_slice())),
        Err(e) => Err(format!("{:?}", e)),
    }
}


pub fn decrypt(buf: &[u8], key: &[u8]) -> Result<String, String> {
    match decode(buf) {
        Ok(encrypted_data) => {
            match aes_256_ecb_decrypt(encrypted_data.as_slice(), key) {
                Ok(decrypted_data) => {
                    let plain = str::from_utf8(decrypted_data.as_slice()).unwrap();
                    Ok(plain.to_string())
                }
                Err(e) => Err(format!("{:?}", e)),
            }
        }
        Err(e) => Err(format!("{}", e)),
    }
}


pub fn gen(specifed: Option<&str>) -> String {
    let key;

    match specifed {
        Some(s) => key = s.to_string(),
        None => key = genkey(32),
    }

    format!(
        "\
[filter = \"git-mix\"]
    clean = git-mix encrypt --key {key}
    smudge = git-mix decrypt --key {key}
",
        key = key
    )
}


pub fn genkey(len: usize) -> String {
    thread_rng().gen_ascii_chars().take(len).collect::<String>()
}