Drop steven_openssl in favor of using the openssl crate (Closes #31)

This commit is contained in:
Thinkofname 2016-04-05 19:35:58 +01:00
parent 40170953eb
commit f8e2d0333e
9 changed files with 27 additions and 341 deletions

1
Cargo.lock generated
View File

@ -10,6 +10,7 @@ dependencies = [
"image 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
"sdl2 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)",

View File

@ -19,16 +19,13 @@ log = "0.3.5"
cgmath = "0.7.0"
lazy_static = "0.1.15"
collision = {git = "https://github.com/csherratt/collision-rs", rev = "f80825e"}
openssl = "0.7.8"
# clippy = "*"
[dependencies.steven_gl]
path = "./gl"
version = "0"
[dependencies.steven_openssl]
path = "./openssl"
version = "0"
[dependencies.steven_resources]
path = "./resources"
version = "0"

105
openssl/Cargo.lock generated
View File

@ -1,105 +0,0 @@
[root]
name = "steven_openssl"
version = "0.0.1"
dependencies = [
"libc 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "advapi32-sys"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "gdi32-sys"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "libc"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "libc"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "libressl-pnacl-sys"
version = "2.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"pnacl-build-helper 1.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "openssl-sys"
version = "0.7.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"gdi32-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"libressl-pnacl-sys 2.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"user32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "pkg-config"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "pnacl-build-helper"
version = "1.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"tempdir 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand"
version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"advapi32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tempdir"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rand 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "user32-sys"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "winapi"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi-build"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"

View File

@ -1,8 +0,0 @@
[package]
name = "steven_openssl"
version = "0.0.1"
authors = [ "Thinkofdeath <thinkofdeath@spigotmc.org>" ]
[dependencies]
libc = "0.2"
openssl-sys = "0.7.6"

View File

@ -1,207 +0,0 @@
#![feature(unique)]
#![allow(dead_code)]
extern crate libc;
use std::mem;
use std::ptr;
#[repr(C)]
#[allow(non_snake_case)]
struct SHA_CTX {
h0: libc::c_uint,
h1: libc::c_uint,
h2: libc::c_uint,
h3: libc::c_uint,
h4: libc::c_uint,
N1: libc::c_uint,
NH: libc::c_uint,
data: [libc::c_uint; 16],
num: libc::c_uint
}
enum RSA{}
#[allow(non_camel_case_types)]
enum EVP_CIPHER_CTX{}
#[allow(non_camel_case_types)]
enum EVP_CIPHER{}
enum ENGINE{}
const RSA_PKCS1_PADDING : libc::c_int = 1;
extern {
fn SHA1_Init(c: *mut SHA_CTX) -> libc::c_int;
fn SHA1_Update(c: *mut SHA_CTX, data: *const u8, len: libc::size_t) -> libc::c_int;
fn SHA1_Final(md: *const u8, c: *mut SHA_CTX) -> libc::c_int;
fn d2i_RSA_PUBKEY(a: *mut *mut RSA, data: *const *const u8, len: libc::c_int) -> *mut RSA;
fn RSA_free(rsa: *mut RSA);
fn RSA_size(rsa: *mut RSA) -> libc::c_int;
fn RSA_public_encrypt(flen: libc::c_int, from: *const u8, to: *mut u8, rsa: *mut RSA, padding: libc::c_int) -> libc::c_int;
fn RAND_bytes(buf: *mut u8, len: libc::c_int) -> libc::c_int;
fn EVP_CIPHER_CTX_init(a: *mut EVP_CIPHER_CTX);
fn EVP_EncryptInit_ex(ctx: *mut EVP_CIPHER_CTX, cipher: *const EVP_CIPHER, engine: *mut ENGINE, key: *const u8, iv: *const u8) -> libc::c_int;
fn EVP_DecryptInit_ex(ctx: *mut EVP_CIPHER_CTX, cipher: *const EVP_CIPHER, engine: *mut ENGINE, key: *const u8, iv: *const u8) -> libc::c_int;
fn EVP_EncryptUpdate(ctx: *mut EVP_CIPHER_CTX, out: *mut u8, outl: *mut libc::c_int, input: *const u8, inl: libc::c_int) -> libc::c_int;
fn EVP_DecryptUpdate(ctx: *mut EVP_CIPHER_CTX, out: *mut u8, outl: *mut libc::c_int, input: *const u8, inl: libc::c_int) -> libc::c_int;
fn EVP_aes_128_cfb8() -> *const EVP_CIPHER;
fn EVP_CIPHER_block_size(cipher: *const EVP_CIPHER) -> libc::c_int;
fn EVP_CIPHER_CTX_free(ctx: *mut EVP_CIPHER_CTX);
fn EVP_CIPHER_CTX_cleanup(ctx: *mut EVP_CIPHER_CTX) -> libc::c_int;
fn EVP_CIPHER_CTX_new() -> *mut EVP_CIPHER_CTX;
}
pub struct EVPCipher {
internal: ptr::Unique<EVP_CIPHER_CTX>,
block_size: usize,
}
impl EVPCipher {
pub fn new(key: &[u8], iv: &[u8], decrypt: bool) -> EVPCipher {
unsafe {
let mut e = EVPCipher {
internal: ptr::Unique::new(EVP_CIPHER_CTX_new()),
block_size: EVP_CIPHER_block_size(EVP_aes_128_cfb8()) as usize,
};
EVP_CIPHER_CTX_init(e.internal.get_mut());
if decrypt {
if EVP_DecryptInit_ex(e.internal.get_mut(), EVP_aes_128_cfb8(), ptr::null_mut(), key.as_ptr(), iv.as_ptr()) == 0 {
panic!("Init error");
}
} else {
if EVP_EncryptInit_ex(e.internal.get_mut(), EVP_aes_128_cfb8(), ptr::null_mut(), key.as_ptr(), iv.as_ptr()) == 0 {
panic!("Init error");
}
}
e
}
}
pub fn decrypt(&mut self, data: &[u8]) -> Vec<u8> {
unsafe {
let mut out = Vec::with_capacity(data.len());
let mut out_len: libc::c_int = 0;
if EVP_DecryptUpdate(self.internal.get_mut(), out.as_mut_ptr(), &mut out_len, data.as_ptr(), data.len() as libc::c_int) == 0 {
panic!("Decrypt error")
}
out.set_len(out_len as usize);
out
}
}
pub fn encrypt(&mut self, data: &[u8]) -> Vec<u8> {
unsafe {
let mut out = Vec::with_capacity(data.len());
let mut out_len: libc::c_int = 0;
if EVP_EncryptUpdate(self.internal.get_mut(), out.as_mut_ptr(), &mut out_len, data.as_ptr(), data.len() as libc::c_int) == 0 {
panic!("Encrypt error")
}
out.set_len(out_len as usize);
out
}
}
}
impl Drop for EVPCipher {
fn drop(&mut self) {
unsafe {
EVP_CIPHER_CTX_cleanup(self.internal.get_mut());
EVP_CIPHER_CTX_free(self.internal.get_mut());
}
}
}
pub fn gen_random(len: usize) -> Vec<u8> {
unsafe {
let mut data = Vec::with_capacity(len);
data.set_len(len);
RAND_bytes(data.as_mut_ptr(), len as libc::c_int);
data
}
}
pub struct PublicKey {
rsa: *mut RSA
}
impl PublicKey {
pub fn new(data: &[u8]) -> PublicKey {
unsafe {
let cert = d2i_RSA_PUBKEY(ptr::null_mut(), &data.as_ptr(), data.len() as libc::c_int);
if cert.is_null() {
panic!("Error");
}
PublicKey { rsa: cert }
}
}
pub fn encrypt(&mut self, data: &Vec<u8>) -> Vec<u8> {
unsafe {
let size = RSA_size(self.rsa) as usize;
let mut out = Vec::with_capacity(size);
out.set_len(size);
RSA_public_encrypt(data.len() as libc::c_int, data.as_ptr(), out.as_mut_ptr(), self.rsa, RSA_PKCS1_PADDING);
out
}
}
}
impl Drop for PublicKey {
fn drop(&mut self) {
unsafe {
RSA_free(self.rsa);
}
}
}
pub struct SHA1 {
internal: SHA_CTX,
}
impl SHA1 {
pub fn new() -> SHA1 {
unsafe {
let mut s : SHA1 = mem::uninitialized();
if SHA1_Init(&mut s.internal) == 0 {
panic!("error init sha1");
}
s
}
}
pub fn update(&mut self, data: &[u8]) {
unsafe {
if SHA1_Update(&mut self.internal, data.as_ptr(), data.len() as libc::size_t) == 0 {
panic!("sha1 error");
}
}
}
pub fn bytes(mut self) -> Vec<u8> {
unsafe {
let mut dst = Vec::with_capacity(20);
dst.set_len(20);
if SHA1_Final(dst.as_mut_ptr(), &mut self.internal) == 0 {
panic!("sha1 error");
}
dst
}
}
}
#[cfg(test)]
mod test {
use super::{SHA1};
#[test]
fn test_sha1() {
let mut sha1 = SHA1::new();
sha1.update(b"Hello world");
assert!(sha1.bytes().iter().map(|b| format!("{:02X}", b)).collect::<Vec<String>>().connect("") == "7B502C3A1F48C8609AE212CDFB639DEE39673F5E");
}
}

View File

@ -21,7 +21,7 @@ extern crate image;
extern crate time;
extern crate byteorder;
extern crate serde_json;
extern crate steven_openssl as openssl;
extern crate openssl;
extern crate hyper;
extern crate flate2;
extern crate rand;

View File

@ -14,7 +14,7 @@
#![allow(dead_code)]
use openssl;
use openssl::crypto::symm;
use serde_json;
use hyper;
@ -720,13 +720,16 @@ pub struct Conn {
direction: Direction,
pub state: State,
cipher: Option<openssl::EVPCipher>,
cipher: Option<symm::Crypter>,
compression_threshold: i32,
compression_read: Option<ZlibDecoder<io::Cursor<Vec<u8>>>>,
compression_write: Option<ZlibEncoder<io::Cursor<Vec<u8>>>>,
}
// Needed because symm::Crypter isn't send
unsafe impl Send for Conn {}
impl Conn {
pub fn new(target: &str) -> Result<Conn, Error> {
// TODO SRV record support
@ -832,7 +835,9 @@ impl Conn {
}
pub fn enable_encyption(&mut self, key: &[u8], decrypt: bool) {
self.cipher = Option::Some(openssl::EVPCipher::new(key, key, decrypt));
let cipher = symm::Crypter::new(symm::Type::AES_128_CFB8);
cipher.init(if decrypt { symm::Mode::Decrypt } else { symm::Mode::Encrypt }, key, key);
self.cipher = Option::Some(cipher);
}
pub fn set_compresssion(&mut self, threshold: i32) {
@ -940,7 +945,7 @@ impl Read for Conn {
Option::None => self.stream.read(buf),
Option::Some(cipher) => {
let ret = try!(self.stream.read(buf));
let data = cipher.decrypt(&buf[..ret]);
let data = cipher.update(&buf[..ret]);
for i in 0..ret {
buf[i] = data[i];
}
@ -955,7 +960,7 @@ impl Write for Conn {
match self.cipher.as_mut() {
Option::None => self.stream.write(buf),
Option::Some(cipher) => {
let data = cipher.encrypt(buf);
let data = cipher.update(buf);
try!(self.stream.write_all(&data[..]));
Ok(buf.len())
}

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use openssl;
use openssl::crypto::hash;
use serde_json;
use serde_json::builder::ObjectBuilder;
use hyper;
@ -101,11 +101,12 @@ impl Profile {
}
pub fn join_server(&self, server_id: &str, shared_key: &[u8], public_key: &[u8]) -> Result<(), super::Error> {
let mut sha1 = openssl::SHA1::new();
sha1.update(server_id.as_bytes());
sha1.update(shared_key);
sha1.update(public_key);
let mut hash = sha1.bytes();
use std::io::Write;
let mut sha1 = hash::Hasher::new(hash::Type::SHA1);
sha1.write_all(server_id.as_bytes()).unwrap();
sha1.write_all(shared_key).unwrap();
sha1.write_all(public_key).unwrap();
let mut hash = sha1.finish();
// Mojang uses a hex method which allows for
// negatives so we have to account for that.

View File

@ -23,7 +23,6 @@ use std::collections::HashMap;
use std::hash::BuildHasherDefault;
use types::hash::FNVHash;
use resources;
use openssl;
use console;
use render;
use auth;
@ -99,6 +98,8 @@ macro_rules! handle_packet {
impl Server {
pub fn connect(resources: Arc<RwLock<resources::Manager>>, console: Arc<Mutex<console::Console>>, address: &str) -> Result<Server, protocol::Error> {
use openssl::crypto::pkey;
use openssl::crypto::rand::rand_bytes;
let mut conn = try!(protocol::Conn::new(address));
let profile = {
@ -148,11 +149,12 @@ impl Server {
};
}
let mut key = openssl::PublicKey::new(&packet.public_key.data);
let shared = openssl::gen_random(16);
let mut key = pkey::PKey::new();
key.load_pub(&packet.public_key.data);
let shared = rand_bytes(16);
let shared_e = key.encrypt(&shared);
let token_e = key.encrypt(&packet.verify_token.data);
let shared_e = key.public_encrypt_with_padding(&shared, pkey::EncryptionPadding::PKCS1v15);
let token_e = key.public_encrypt_with_padding(&packet.verify_token.data, pkey::EncryptionPadding::PKCS1v15);
try!(profile.join_server(&packet.server_id, &shared, &packet.public_key.data));