Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
c015ae9
commit 6f6d3c9
Showing
9 changed files
with
1,016 additions
and
52 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
*.lock | ||
/target | ||
target/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
[package] | ||
name = "steven_openssl" | ||
version = "0.0.1" | ||
authors = [ "Thinkofdeath <thinkofdeath@spigotmc.org>" ] | ||
|
||
[dependencies] | ||
libc = "*" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,209 @@ | ||
#![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 | ||
} | ||
|
||
#[repr(C)] | ||
struct RSA; | ||
|
||
#[repr(C)] | ||
struct EVP_CIPHER_CTX; | ||
|
||
#[repr(C)] | ||
struct EVP_CIPHER; | ||
|
||
#[repr(C)] | ||
struct ENGINE; | ||
|
||
const RSA_PKCS1_PADDING : libc::c_int = 1; | ||
|
||
#[link(name = "crypto")] | ||
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: *mut EVP_CIPHER_CTX, | ||
|
||
block_size: usize, | ||
} | ||
|
||
impl EVPCipher { | ||
pub fn new(key: &Vec<u8>, iv: &Vec<u8>, decrypt: bool) -> EVPCipher { | ||
unsafe { | ||
let e = EVPCipher { | ||
internal: EVP_CIPHER_CTX_new(), | ||
block_size: EVP_CIPHER_block_size(EVP_aes_128_cfb8()) as usize, | ||
}; | ||
EVP_CIPHER_CTX_init(e.internal); | ||
if decrypt { | ||
if EVP_DecryptInit_ex(e.internal, EVP_aes_128_cfb8(), ptr::null_mut(), key.as_ptr(), iv.as_ptr()) == 0 { | ||
panic!("Init error"); | ||
} | ||
} else { | ||
if EVP_EncryptInit_ex(e.internal, 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, 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, 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); | ||
EVP_CIPHER_CTX_free(self.internal); | ||
} | ||
} | ||
} | ||
|
||
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: &Vec<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"); | ||
} | ||
} |
Oops, something went wrong.