use crate::error::NetworkError;
use crate::StreamHeader;
use crypto::{
aessafe::{AesSafe128DecryptorX8, AesSafe128EncryptorX8},
symmetriccipher::{BlockDecryptorX8, BlockEncryptorX8},
};
use rand::rngs::OsRng;
use rsa::{PaddingScheme, PublicKey, RSAPrivateKey, RSAPublicKey};
pub fn header_peak(key: &[u8], input: &[u8]) -> Result<StreamHeader, NetworkError>{
let decryptor = AesSafe128DecryptorX8::new(key);
let mut header_vec = Vec::with_capacity(128);
unsafe { header_vec.set_len(128) }
decryptor.decrypt_block_x8(&input[0..128], &mut header_vec);
let remote_header = StreamHeader::from_raw_padded(&header_vec)?;
Ok(remote_header)
}
pub fn asym_aes_encrypt(
pub_key: &RSAPublicKey,
mut header: StreamHeader,
input: &[u8],
) -> Result<Vec<u8>, NetworkError> {
assert!(input.len() < (65536));
let mut output = Vec::new();
let mut rng = OsRng;
let mut data = Vec::new();
data.extend_from_slice(&input);
let rem: u8 = 128 - ((input.len() % 128) as u8);
let mut aes_padding = Vec::with_capacity(rem as usize);
unsafe {
aes_padding.set_len(rem as usize);
}
data.append(&mut aes_padding);
assert_eq!(data.len() % 128, 0);
let encryptor = AesSafe128EncryptorX8::new(header.key());
header.set_remander(rem);
header.set_packet_len(data.len());
let key = header.to_raw();
assert!(key.len() < 246);
let padding = PaddingScheme::new_pkcs1v15_encrypt();
let mut enc_key = pub_key.encrypt(&mut rng, padding, &key)?;
output.append(&mut enc_key);
let full_len = input.len() + rem as usize;
for index in (0..full_len).step_by(128) {
let mut read_data: [u8; 128] = [0; 128];
encryptor.encrypt_block_x8(&data[index..index + 128], &mut read_data[..]);
output.extend_from_slice(&read_data);
}
Ok(output)
}
pub fn aes_inplace_decrypt(
priv_key: &RSAPrivateKey,
input: &mut Vec<u8>,
) -> Result<StreamHeader, NetworkError> {
let padding = PaddingScheme::new_pkcs1v15_encrypt();
let header = StreamHeader::from_raw(&priv_key.decrypt(padding, &input[0..256])?)?;
let rem = header.remander();
let data_len = header.packet_len();
let decryptor = AesSafe128DecryptorX8::new(header.key());
for index in (0..data_len).step_by(128) {
let (outbuf, inbuf) = input.split_at_mut(index + 256);
decryptor.decrypt_block_x8(&inbuf[0..128], &mut outbuf[index..index + 128]);
}
input.truncate(input.len() - (rem as usize + 256));
Ok(header)
}
pub fn asym_aes_decrypt(
priv_key: &RSAPrivateKey,
input: &[u8],
) -> Result<(Vec<u8>, StreamHeader), NetworkError> {
let mut output = Vec::new();
let padding = PaddingScheme::new_pkcs1v15_encrypt();
let mut header = StreamHeader::from_raw(&priv_key.decrypt(padding, &input[0..256])?)?;
println!("header: {:?}", header);
let rem = header.remander();
let data_len = header.packet_len();
println!("packet len in asym: {}", data_len);
let decryptor = AesSafe128DecryptorX8::new(header.key());
let mut read_data: [u8; 128] = [0; 128];
for index in (256..data_len + 256).step_by(128) {
decryptor.decrypt_block_x8(&input[index..index + 128], &mut read_data[..]);
output.extend_from_slice(&read_data);
}
let newlen = output.len() - (rem as usize);
output.truncate(newlen);
if (newlen + rem as usize + 256) < input.len() {
let (next_packet, stream_header) =
asym_aes_decrypt(priv_key, &input[data_len + 256..input.len()])?;
header = stream_header;
output.extend_from_slice(&next_packet);
}
Ok((output, header))
}
pub(crate) fn database_aes_decrypt(key: &[u8], outbuf: &mut Vec<u8>) {
if outbuf.is_empty() || key.is_empty() {
return;
}
let remander = outbuf[outbuf.len() - 1];
let decryptor = AesSafe128DecryptorX8::new(key);
let mut temp_vec = Vec::with_capacity(128);
outbuf.truncate(outbuf.len() - 1);
for index in (0..outbuf.len()).step_by(128) {
unsafe { temp_vec.set_len(128) }
decryptor.decrypt_block_x8(&outbuf[index..index + 128], &mut temp_vec[0..128]);
std::io::copy(&mut &temp_vec[..], &mut &mut outbuf[index..index + 128]).unwrap();
temp_vec.clear();
}
outbuf.truncate(outbuf.len() - remander as usize);
}
pub(crate) fn database_aes_encrypt(key: &[u8], outbuf: &mut Vec<u8>) {
if outbuf.is_empty() || key.is_empty() {
return;
}
let remander = 128 - (outbuf.len() % 128);
let encryptor = AesSafe128EncryptorX8::new(key);
let mut temp_vec = Vec::with_capacity(128);
let mut rem_vec = Vec::with_capacity(remander);
unsafe { rem_vec.set_len(remander) };
outbuf.extend_from_slice(&rem_vec);
for index in (0..outbuf.len()).step_by(128) {
temp_vec.extend_from_slice(&outbuf[index..index + 128]);
encryptor.encrypt_block_x8(&temp_vec, &mut outbuf[index..index + 128]);
temp_vec.clear();
}
outbuf.push(remander as u8);
}
pub fn sym_aes_encrypt(header_ref: &StreamHeader, input: &[u8]) -> Vec<u8> {
let mut header = header_ref.clone();
let mut output = Vec::new();
let remander: u8 = 128 - (input.len() % 128) as u8;
let mut rem_vec = Vec::with_capacity(remander as usize);
unsafe { rem_vec.set_len(remander as usize) }
let key = header.key();
let encryptor = AesSafe128EncryptorX8::new(key);
let mut data = Vec::with_capacity(input.len() + 128);
header.set_packet_len(input.len());
header.set_remander(remander);
data.extend_from_slice(&header.to_raw_padded());
data.extend_from_slice(input);
data.extend_from_slice(&rem_vec);
let full_len = input.len();
for index in (0..full_len + 128).step_by(128) {
let mut read_data: [u8; 128] = [0; 128];
encryptor.encrypt_block_x8(&data[index..index + 128], &mut read_data[..]);
output.extend_from_slice(&read_data);
}
output
}
pub fn sym_aes_decrypt(
header: &StreamHeader,
input: &[u8],
) -> Result<(Vec<u8>, StreamHeader, Vec<usize>), NetworkError> {
println!("sym decrypt");
let mut indexes = Vec::new();
let decryptor = AesSafe128DecryptorX8::new(header.key());
let mut header_vec = Vec::with_capacity(128);
unsafe { header_vec.set_len(128) }
let mut output = Vec::new();
decryptor.decrypt_block_x8(&input[0..128], &mut header_vec);
let remote_header = StreamHeader::from_raw_padded(&header_vec)?;
let rem = remote_header.remander();
let data_len = remote_header.packet_len();
let mut read_data: [u8; 128] = [0; 128];
for index in (128..data_len + 128).step_by(128) {
decryptor.decrypt_block_x8(&input[index..index + 128], &mut read_data[..]);
output.extend_from_slice(&read_data);
}
let newlen = output.len() - (rem as usize);
output.truncate(newlen);
indexes.push(data_len);
if (newlen + rem as usize + 128) < input.len() {
let (next_packet, second_header, rec_indexes) =
sym_aes_decrypt(header, &input[data_len + (rem as usize) + 128..input.len()])?;
indexes.extend_from_slice(&rec_indexes);
output.extend_from_slice(&next_packet);
if second_header.peer_hash() != remote_header.peer_hash() {
return Err(NetworkError::ConnectionDenied(
"headers don't match in decryption".to_string(),
));
}
}
Ok((output, remote_header, indexes))
}
#[test]
fn sym_encrypt_test() {
use crate::random_string;
use rand::Rng;
use std::time::SystemTime;
for _ in 0..100 {
let time = SystemTime::now();
let mut rng = rand::thread_rng();
let ffloat: f64 = rng.gen();
let instr = random_string((ffloat * 65410f64) as usize);
let key = random_string(16).into_bytes();
let mut inbuf = instr.clone().into_bytes();
let peer_hash = random_string(50);
let mut header =
StreamHeader::with_key(&random_string(50), &peer_hash, key.clone(), inbuf.len());
let mut output = sym_aes_encrypt(&mut header, &mut inbuf);
let sfloat: f64 = rng.gen();
let second_str = random_string((sfloat * 65410f64) as usize);
let mut second_buf = second_str.clone().into_bytes();
let mut second_header =
StreamHeader::with_key(&random_string(50), &peer_hash, key, second_buf.len());
output.extend_from_slice(&sym_aes_encrypt(&mut second_header, &mut second_buf));
let (inbuf, _stream_header, indexes) = sym_aes_decrypt(&header, &output).unwrap();
let remstr = instr.into_bytes();
let remsecstr = second_str.into_bytes();
assert_eq!(remstr.len(), *indexes.get(0).unwrap());
assert_eq!(remstr, inbuf[0..*indexes.get(0).unwrap()].to_vec());
assert_eq!(remsecstr.len(), *indexes.get(1).unwrap());
assert_eq!(
remsecstr[0..256].to_vec(),
inbuf[*indexes.get(0).unwrap()..*indexes.get(0).unwrap() + 256].to_vec()
);
let elapsed = time.elapsed().unwrap().as_millis();
println!("elapsed: {}", elapsed);
assert!(500 > elapsed);
}
}
#[test]
fn asym_encrypt_test() {
use std::time::SystemTime;
let time = SystemTime::now();
use crate::random_string;
let stream_header = StreamHeader::new(&random_string(50), &random_string(50), 0);
let private_key = crate::get_private_key();
let public_key = RSAPublicKey::from(&private_key);
let instr = random_string(65535 - 256);
let indata = instr.clone().into_bytes();
let mut outvec = asym_aes_encrypt(&public_key, stream_header.clone(), &indata).unwrap();
let second_string = random_string(353);
let secindata = second_string.clone().into_bytes();
outvec.extend_from_slice(&asym_aes_encrypt(&public_key, stream_header, &secindata).unwrap());
let (outvec, _header) = asym_aes_decrypt(&private_key, &mut outvec).unwrap();
assert_eq!(indata, outvec[0..indata.len()].to_vec());
assert_eq!(
second_string.into_bytes(),
outvec[indata.len()..outvec.len()].to_vec()
);
let elapsed = time.elapsed().unwrap().as_millis();
println!("{}", elapsed);
assert!(600 > elapsed);
}