parent
b41f3dd72f
commit
6ef819f971
11
README.md
11
README.md
|
|
@ -40,17 +40,6 @@ Rust install's libs folder. The default should be:
|
|||
respectively.
|
||||
5. Run `cargo build`.
|
||||
|
||||
###OS X
|
||||
|
||||
OS X is shipped with extremely outdated openssl. We recommend to update it. If you're using Homebrew it should be as easy as:
|
||||
|
||||
```bash
|
||||
brew install openssl
|
||||
brew link openssl --force
|
||||
```
|
||||
|
||||
Note that you need to execute `cargo clean` in your project directory to rebuild `rust-openssl` with the new version of `openssl`.
|
||||
|
||||
###Testing
|
||||
Several tests expect a local test server to be running to bounce requests off
|
||||
of. It's easy to do this. Open a separate terminal window and `cd` to the
|
||||
|
|
|
|||
|
|
@ -18,7 +18,8 @@ sslv2 = []
|
|||
aes_xts = []
|
||||
|
||||
[build-dependencies]
|
||||
pkg-config = "0.1.1"
|
||||
pkg-config = "0.2"
|
||||
gcc = "0.1"
|
||||
|
||||
[target.le32-unknown-nacl.dependencies]
|
||||
libressl-pnacl-sys = "2.1.0"
|
||||
|
|
|
|||
|
|
@ -1,44 +1,50 @@
|
|||
#![feature(core, collections, env)]
|
||||
#![feature(env)]
|
||||
|
||||
extern crate "pkg-config" as pkg_config;
|
||||
extern crate gcc;
|
||||
|
||||
use std::env;
|
||||
use std::default::Default;
|
||||
|
||||
fn main() {
|
||||
let target = env::var_string("TARGET").unwrap();
|
||||
let is_android = target.find_str("android").is_some();
|
||||
|
||||
// Without hackory, pkg-config will only look for host libraries.
|
||||
// So, abandon ship if we're cross compiling.
|
||||
if !is_android && !pkg_config::target_supported() {
|
||||
panic!("unsupported target");
|
||||
if target.contains("android") {
|
||||
let path = env::var_string("OPENSSL_PATH").ok()
|
||||
.expect("Android does not provide openssl libraries, please build them yourself \
|
||||
(instructions in the README) and provide their location through \
|
||||
$OPENSSL_PATH.");
|
||||
println!("cargo:rustc-flags=-L native={} -l crypto:static -l ssl:static", path);
|
||||
return;
|
||||
}
|
||||
|
||||
if pkg_config::find_library("openssl").is_err() {
|
||||
let mut flags = if is_android {
|
||||
" -l crypto:static -l ssl:static"
|
||||
} else {
|
||||
" -l crypto -l ssl"
|
||||
}.to_string();
|
||||
|
||||
let win_pos = target.find_str("windows")
|
||||
.or(target.find_str("win32"))
|
||||
.or(target.find_str("win64"));
|
||||
|
||||
// It's fun, but it looks like win32 and win64 both
|
||||
// have all the libs with 32 sufix
|
||||
if win_pos.is_some() {
|
||||
flags.push_str(" -l gdi32 -l wsock32");
|
||||
}
|
||||
|
||||
if is_android {
|
||||
let path = env::var_string("OPENSSL_PATH").ok()
|
||||
.expect("Android does not provide openssl libraries, please build them yourselves \
|
||||
(instructions in the README) and provide their location through \
|
||||
$OPENSSL_PATH.");
|
||||
flags.push_str(format!(" -L {}", path).as_slice());
|
||||
}
|
||||
|
||||
println!("cargo:rustc-flags={}", flags);
|
||||
if target.contains("win32") || target.contains("win64") {
|
||||
println!("cargo:rustc-flags=-l crypto -l ssl -l gdi32 -l wsock32");
|
||||
return;
|
||||
}
|
||||
|
||||
if pkg_config::Config::new().atleast_version("1.0.0").find("openssl").is_ok() {
|
||||
build_old_openssl_shim(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if pkg_config::find_library("openssl").is_ok() {
|
||||
build_old_openssl_shim(true);
|
||||
return;
|
||||
}
|
||||
|
||||
panic!("Unable to find openssl libraries");
|
||||
}
|
||||
|
||||
fn build_old_openssl_shim(is_old: bool) {
|
||||
let mut config: gcc::Config = Default::default();
|
||||
if is_old {
|
||||
config.definitions.push(("OLD_OPENSSL".to_string(), None));
|
||||
}
|
||||
|
||||
gcc::compile_library("libold_openssl_shim.a",
|
||||
&config,
|
||||
&["src/old_openssl_shim.c"]);
|
||||
let out_dir = env::var_string("OUT_DIR").unwrap();
|
||||
println!("cargo:rustc-flags=-L native={} -l old_openssl_shim:static", out_dir);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -382,12 +382,20 @@ extern "C" {
|
|||
pub fn EVP_PKEY_set1_RSA(k: *mut EVP_PKEY, r: *mut RSA) -> c_int;
|
||||
|
||||
pub fn HMAC_CTX_init(ctx: *mut HMAC_CTX);
|
||||
#[deprecated = "use HMAC_Init_ex_shim instead"]
|
||||
pub fn HMAC_Init_ex(ctx: *mut HMAC_CTX, key: *const u8, keylen: c_int, md: *const EVP_MD, imple: *const ENGINE) -> c_int;
|
||||
#[deprecated = "use HMAC_Final_shim instead"]
|
||||
pub fn HMAC_Final(ctx: *mut HMAC_CTX, output: *mut u8, len: *mut c_uint) -> c_int;
|
||||
#[deprecated = "use HMAC_Update_shim instead"]
|
||||
pub fn HMAC_Update(ctx: *mut HMAC_CTX, input: *const u8, len: c_uint) -> c_int;
|
||||
pub fn HMAC_CTX_cleanup(ctx: *mut HMAC_CTX);
|
||||
pub fn HMAC_CTX_copy(dst: *mut HMAC_CTX, src: *const HMAC_CTX) -> c_int;
|
||||
|
||||
// Pre-1.0 versions of these didn't return anything, so the shims bridge that gap
|
||||
pub fn HMAC_Init_ex_shim(ctx: *mut HMAC_CTX, key: *const u8, keylen: c_int, md: *const EVP_MD, imple: *const ENGINE) -> c_int;
|
||||
pub fn HMAC_Final_shim(ctx: *mut HMAC_CTX, output: *mut u8, len: *mut c_uint) -> c_int;
|
||||
pub fn HMAC_Update_shim(ctx: *mut HMAC_CTX, input: *const u8, len: c_uint) -> c_int;
|
||||
|
||||
|
||||
pub fn PEM_read_bio_X509(bio: *mut BIO, out: *mut *mut X509, callback: Option<PasswordCallback>,
|
||||
user_data: *mut c_void) -> *mut X509;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,49 @@
|
|||
#include <openssl/hmac.h>
|
||||
|
||||
#ifdef OLD_OPENSSL
|
||||
// Copied from openssl crypto/hmac/hmac.c
|
||||
int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx)
|
||||
{
|
||||
if (!EVP_MD_CTX_copy(&dctx->i_ctx, &sctx->i_ctx))
|
||||
goto err;
|
||||
if (!EVP_MD_CTX_copy(&dctx->o_ctx, &sctx->o_ctx))
|
||||
goto err;
|
||||
if (!EVP_MD_CTX_copy(&dctx->md_ctx, &sctx->md_ctx))
|
||||
goto err;
|
||||
memcpy(dctx->key, sctx->key, HMAC_MAX_MD_CBLOCK);
|
||||
dctx->key_length = sctx->key_length;
|
||||
dctx->md = sctx->md;
|
||||
return 1;
|
||||
err:
|
||||
return 0;
|
||||
}
|
||||
|
||||
int HMAC_Init_ex_shim(HMAC_CTX *ctx, const void *key, int key_len, const EVP_MD *md, ENGINE *impl) {
|
||||
HMAC_Init_ex(ctx, key, key_len, md, impl);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int HMAC_Update_shim(HMAC_CTX *ctx, const unsigned char *data, int len) {
|
||||
HMAC_Update(ctx, data, len);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int HMAC_Final_shim(HMAC_CTX *ctx, unsigned char *md, unsigned int *len) {
|
||||
HMAC_Final(ctx, md, len);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#else /* OLD_OPENSSL */
|
||||
|
||||
int HMAC_Init_ex_shim(HMAC_CTX *ctx, const void *key, int key_len, const EVP_MD *md, ENGINE *impl) {
|
||||
return HMAC_Init_ex(ctx, key, key_len, md, impl);
|
||||
}
|
||||
|
||||
int HMAC_Update_shim(HMAC_CTX *ctx, const unsigned char *data, int len) {
|
||||
return HMAC_Update(ctx, data, len);
|
||||
}
|
||||
|
||||
int HMAC_Final_shim(HMAC_CTX *ctx, unsigned char *md, unsigned int *len) {
|
||||
return HMAC_Final(ctx, md, len);
|
||||
}
|
||||
#endif /* OLD_OPENSSL */
|
||||
|
|
@ -87,9 +87,9 @@ impl HMAC {
|
|||
#[inline]
|
||||
fn init_once(&mut self, md: *const ffi::EVP_MD, key: &[u8]) {
|
||||
unsafe {
|
||||
let r = ffi::HMAC_Init_ex(&mut self.ctx,
|
||||
key.as_ptr(), key.len() as c_int,
|
||||
md, 0 as *const _);
|
||||
let r = ffi::HMAC_Init_ex_shim(&mut self.ctx,
|
||||
key.as_ptr(), key.len() as c_int,
|
||||
md, 0 as *const _);
|
||||
assert_eq!(r, 1);
|
||||
}
|
||||
self.state = Reset;
|
||||
|
|
@ -105,9 +105,9 @@ impl HMAC {
|
|||
// If the key and/or md is not supplied it's reused from the last time
|
||||
// avoiding redundant initializations
|
||||
unsafe {
|
||||
let r = ffi::HMAC_Init_ex(&mut self.ctx,
|
||||
0 as *const _, 0,
|
||||
0 as *const _, 0 as *const _);
|
||||
let r = ffi::HMAC_Init_ex_shim(&mut self.ctx,
|
||||
0 as *const _, 0,
|
||||
0 as *const _, 0 as *const _);
|
||||
assert_eq!(r, 1);
|
||||
}
|
||||
self.state = Reset;
|
||||
|
|
@ -119,8 +119,7 @@ impl HMAC {
|
|||
self.init();
|
||||
}
|
||||
unsafe {
|
||||
let r = ffi::HMAC_Update(&mut self.ctx, data.as_ptr(),
|
||||
data.len() as c_uint);
|
||||
let r = ffi::HMAC_Update_shim(&mut self.ctx, data.as_ptr(), data.len() as c_uint);
|
||||
assert_eq!(r, 1);
|
||||
}
|
||||
self.state = Updated;
|
||||
|
|
@ -135,7 +134,7 @@ impl HMAC {
|
|||
let mut res: Vec<u8> = repeat(0).take(md_len).collect();
|
||||
unsafe {
|
||||
let mut len = 0;
|
||||
let r = ffi::HMAC_Final(&mut self.ctx, res.as_mut_ptr(), &mut len);
|
||||
let r = ffi::HMAC_Final_shim(&mut self.ctx, res.as_mut_ptr(), &mut len);
|
||||
self.state = Finalized;
|
||||
assert_eq!(len as usize, md_len);
|
||||
assert_eq!(r, 1);
|
||||
|
|
|
|||
Loading…
Reference in New Issue