mirror of
https://github.com/shadowsocks/shadowsocks-rust.git
synced 2026-02-09 01:59:16 +08:00
use digest algorithm from rust-crypto
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "shadowsocks-rust"
|
||||
version = "1.0.1"
|
||||
version = "1.0.2"
|
||||
authors = ["Y. T. CHUNG <zonyitoo@gmail.com>"]
|
||||
description = "shadowsocks is a fast tunnel proxy that helps you bypass firewalls."
|
||||
repository = "https://github.com/zonyitoo/shadowsocks-rust"
|
||||
|
||||
@@ -34,7 +34,7 @@ use crypto::rc4_md5;
|
||||
use crypto::dummy;
|
||||
use crypto::crypto::CryptoCipher;
|
||||
|
||||
use crypto::digest::{self, DigestType};
|
||||
use crypto::digest::{self, DigestType, Digest};
|
||||
|
||||
use openssl::crypto::symm;
|
||||
|
||||
@@ -225,31 +225,31 @@ impl CipherType {
|
||||
|
||||
/// Extends key to match the required key length
|
||||
pub fn bytes_to_key(&self, key: &[u8]) -> Vec<u8> {
|
||||
let iv_len = self.block_size();
|
||||
let iv_len = self.iv_size();
|
||||
let key_len = self.key_size();
|
||||
|
||||
let mut m: Vec<Vec<u8>> = Vec::with_capacity((key_len + iv_len) / DigestType::Md5.digest_len() + 1);
|
||||
let mut i = 0;
|
||||
while m.len() * DigestType::Md5.digest_len() < (key_len + iv_len) {
|
||||
let mut md5 = digest::with_type(DigestType::Md5);
|
||||
if i > 0 {
|
||||
let mut vkey = m[i - 1].clone();
|
||||
vkey.extend_from_slice(key);
|
||||
md5.update(&vkey[..]);
|
||||
} else {
|
||||
md5.update(key);
|
||||
}
|
||||
let mut digest = digest::with_type(DigestType::Md5);
|
||||
|
||||
m.push(md5.digest());
|
||||
i += 1
|
||||
let mut result = Vec::new();
|
||||
let mut m = Vec::new();
|
||||
let mut loop_count = 0;
|
||||
while loop_count * digest.digest_len() < (key_len + iv_len) {
|
||||
let mut vkey = m.clone();
|
||||
vkey.extend_from_slice(key);
|
||||
|
||||
digest.update(&vkey);
|
||||
|
||||
m.clear();
|
||||
digest.digest(&mut m);
|
||||
loop_count += 1;
|
||||
|
||||
digest.reset();
|
||||
|
||||
result.extend_from_slice(&m[..]);
|
||||
}
|
||||
|
||||
let whole = m.iter().fold(Vec::new(), |mut a, b| {
|
||||
a.extend_from_slice(b);
|
||||
a
|
||||
});
|
||||
let key = whole[0..key_len].to_vec();
|
||||
key
|
||||
result.resize(key_len, 0);
|
||||
result
|
||||
}
|
||||
|
||||
/// Symmetric crypto initialize vector size
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
|
||||
//! Message digest algorithm
|
||||
|
||||
use crypto::openssl;
|
||||
use rust_crypto::md5::Md5;
|
||||
use rust_crypto::sha1::Sha1;
|
||||
|
||||
/// Digest trait
|
||||
pub trait Digest: Send {
|
||||
@@ -29,7 +30,13 @@ pub trait Digest: Send {
|
||||
fn update(&mut self, data: &[u8]);
|
||||
|
||||
/// Generates digest
|
||||
fn digest(&mut self) -> Vec<u8>;
|
||||
fn digest(&mut self, buf: &mut Vec<u8>);
|
||||
|
||||
/// Length of digest
|
||||
fn digest_len(&self) -> usize;
|
||||
|
||||
/// Reset digest
|
||||
fn reset(&mut self);
|
||||
}
|
||||
|
||||
/// Type of defined digests
|
||||
@@ -40,22 +47,61 @@ pub enum DigestType {
|
||||
Sha,
|
||||
}
|
||||
|
||||
impl DigestType {
|
||||
/// Length of digest
|
||||
pub fn digest_len(&self) -> usize {
|
||||
match *self {
|
||||
DigestType::Md5 => 16,
|
||||
DigestType::Sha1 => 20,
|
||||
DigestType::Sha => 20,
|
||||
}
|
||||
/// Create digest with type
|
||||
pub fn with_type(t: DigestType) -> DigestVariant {
|
||||
match t {
|
||||
DigestType::Md5 => DigestVariant::Md5(Md5::new()),
|
||||
DigestType::Sha1 | DigestType::Sha => DigestVariant::Sha1(Sha1::new()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Create digest with type
|
||||
pub fn with_type(t: DigestType) -> Box<Digest + Send> {
|
||||
match t {
|
||||
DigestType::Md5 | DigestType::Sha1 | DigestType::Sha => {
|
||||
Box::new(openssl::OpenSSLDigest::new(t)) as Box<Digest + Send>
|
||||
/// Variant of supported digest
|
||||
pub enum DigestVariant {
|
||||
Md5(Md5),
|
||||
Sha1(Sha1),
|
||||
}
|
||||
|
||||
impl Digest for DigestVariant {
|
||||
fn update(&mut self, data: &[u8]) {
|
||||
use rust_crypto::digest::Digest;
|
||||
|
||||
match self {
|
||||
&mut DigestVariant::Md5(ref mut d) => d.input(data),
|
||||
&mut DigestVariant::Sha1(ref mut d) => d.input(data),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn digest(&mut self, buf: &mut Vec<u8>) {
|
||||
use rust_crypto::digest::Digest;
|
||||
|
||||
let output_bytes = match &*self {
|
||||
&DigestVariant::Md5(ref d) => d.output_bytes(),
|
||||
&DigestVariant::Sha1(ref d) => d.output_bytes(),
|
||||
};
|
||||
|
||||
let orig_len = buf.len();
|
||||
buf.resize(orig_len + output_bytes, 0);
|
||||
match self {
|
||||
&mut DigestVariant::Md5(ref mut d) => d.result(&mut buf[orig_len..]),
|
||||
&mut DigestVariant::Sha1(ref mut d) => d.result(&mut buf[orig_len..]),
|
||||
}
|
||||
}
|
||||
|
||||
fn digest_len(&self) -> usize {
|
||||
use rust_crypto::digest::Digest;
|
||||
|
||||
match self {
|
||||
&DigestVariant::Md5(ref d) => d.output_bytes(),
|
||||
&DigestVariant::Sha1(ref d) => d.output_bytes(),
|
||||
}
|
||||
}
|
||||
|
||||
fn reset(&mut self) {
|
||||
use rust_crypto::digest::Digest;
|
||||
|
||||
match self {
|
||||
&mut DigestVariant::Md5(ref mut d) => d.reset(),
|
||||
&mut DigestVariant::Sha1(ref mut d) => d.reset(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,17 +22,13 @@
|
||||
//! Cipher defined with Rust binding for libcrypto (OpenSSL)
|
||||
|
||||
use std::convert::From;
|
||||
use std::io::Write;
|
||||
|
||||
use crypto::cipher::{Cipher, CipherType, CipherResult};
|
||||
use crypto::cipher;
|
||||
|
||||
use crypto::digest::Digest;
|
||||
use crypto::digest;
|
||||
use crypto::CryptoMode;
|
||||
|
||||
use openssl::crypto::symm;
|
||||
use openssl::crypto::hash;
|
||||
|
||||
/// Core cipher of OpenSSL
|
||||
pub struct OpenSSLCrypto {
|
||||
@@ -148,34 +144,3 @@ impl Cipher for OpenSSLCipher {
|
||||
self.worker.finalize(out)
|
||||
}
|
||||
}
|
||||
|
||||
/// Digest provided by OpenSSL
|
||||
pub struct OpenSSLDigest {
|
||||
inner: hash::Hasher,
|
||||
}
|
||||
|
||||
impl OpenSSLDigest {
|
||||
/// Creates by type
|
||||
pub fn new(t: digest::DigestType) -> OpenSSLDigest {
|
||||
let t = match t {
|
||||
digest::DigestType::Md5 => hash::Type::MD5,
|
||||
digest::DigestType::Sha => hash::Type::SHA512,
|
||||
digest::DigestType::Sha1 => hash::Type::SHA1,
|
||||
};
|
||||
|
||||
OpenSSLDigest { inner: hash::Hasher::new(t).unwrap() }
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Send for OpenSSLDigest {}
|
||||
|
||||
impl Digest for OpenSSLDigest {
|
||||
fn update(&mut self, data: &[u8]) {
|
||||
let _ = self.inner.write(data);
|
||||
}
|
||||
|
||||
fn digest(&mut self) -> Vec<u8> {
|
||||
// TODO: Check error
|
||||
self.inner.finish().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,9 +21,9 @@
|
||||
|
||||
//! Rc4Md5 cipher definition
|
||||
|
||||
use crypto::openssl::{OpenSSLCrypto, OpenSSLDigest};
|
||||
use crypto::openssl::OpenSSLCrypto;
|
||||
use crypto::cipher::{Cipher, CipherType, CipherResult};
|
||||
use crypto::digest::{Digest, DigestType};
|
||||
use crypto::digest::{self, Digest, DigestType};
|
||||
use crypto::CryptoMode;
|
||||
|
||||
/// Rc4Md5 Cipher
|
||||
@@ -33,14 +33,13 @@ pub struct Rc4Md5Cipher {
|
||||
|
||||
impl Rc4Md5Cipher {
|
||||
pub fn new(key: &[u8], iv: &[u8], mode: CryptoMode) -> Rc4Md5Cipher {
|
||||
let mut md5_digest = OpenSSLDigest::new(DigestType::Md5);
|
||||
let mut md5_digest = digest::with_type(DigestType::Md5);
|
||||
md5_digest.update(key);
|
||||
md5_digest.update(iv);
|
||||
let key = md5_digest.digest();
|
||||
let mut key = Vec::new();
|
||||
md5_digest.digest(&mut key);
|
||||
|
||||
Rc4Md5Cipher {
|
||||
crypto: OpenSSLCrypto::new(CipherType::Rc4, &key[..], b"", mode)
|
||||
}
|
||||
Rc4Md5Cipher { crypto: OpenSSLCrypto::new(CipherType::Rc4, &key[..], b"", mode) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,14 +72,14 @@ mod test {
|
||||
let mut enc = Rc4Md5Cipher::new(key, &iv[..], CryptoMode::Encrypt);
|
||||
let mut encrypted_msg = Vec::new();
|
||||
enc.update(msg, &mut encrypted_msg)
|
||||
.and_then(|_| enc.finalize(&mut encrypted_msg))
|
||||
.unwrap();
|
||||
.and_then(|_| enc.finalize(&mut encrypted_msg))
|
||||
.unwrap();
|
||||
|
||||
let mut dec = Rc4Md5Cipher::new(key, &iv[..], CryptoMode::Decrypt);
|
||||
let mut decrypted_msg = Vec::new();
|
||||
dec.update(&encrypted_msg[..], &mut decrypted_msg)
|
||||
.and_then(|_| dec.finalize(&mut decrypted_msg))
|
||||
.unwrap();
|
||||
.and_then(|_| dec.finalize(&mut decrypted_msg))
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(msg, &decrypted_msg[..]);
|
||||
}
|
||||
|
||||
@@ -24,8 +24,7 @@
|
||||
use std::io::BufReader;
|
||||
|
||||
use crypto::cipher::{Cipher, CipherResult};
|
||||
use crypto::digest;
|
||||
use crypto::digest::DigestType;
|
||||
use crypto::digest::{self, DigestType, Digest};
|
||||
use crypto::CryptoMode;
|
||||
|
||||
use byteorder::{ReadBytesExt, LittleEndian};
|
||||
@@ -42,7 +41,8 @@ impl TableCipher {
|
||||
pub fn new(key: &[u8], mode: CryptoMode) -> TableCipher {
|
||||
let mut md5_digest = digest::with_type(DigestType::Md5);
|
||||
md5_digest.update(key);
|
||||
let key_digest = md5_digest.digest();
|
||||
let mut key_digest = Vec::new();
|
||||
md5_digest.digest(&mut key_digest);
|
||||
|
||||
let mut bufr = BufReader::new(&key_digest[..]);
|
||||
let a = bufr.read_u64::<LittleEndian>().unwrap();
|
||||
|
||||
Reference in New Issue
Block a user