parent
b41f3dd72f
commit
6ef819f971
11
README.md
11
README.md
|
|
@ -40,17 +40,6 @@ Rust install's libs folder. The default should be:
|
||||||
respectively.
|
respectively.
|
||||||
5. Run `cargo build`.
|
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
|
###Testing
|
||||||
Several tests expect a local test server to be running to bounce requests off
|
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
|
of. It's easy to do this. Open a separate terminal window and `cd` to the
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,8 @@ sslv2 = []
|
||||||
aes_xts = []
|
aes_xts = []
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
pkg-config = "0.1.1"
|
pkg-config = "0.2"
|
||||||
|
gcc = "0.1"
|
||||||
|
|
||||||
[target.le32-unknown-nacl.dependencies]
|
[target.le32-unknown-nacl.dependencies]
|
||||||
libressl-pnacl-sys = "2.1.0"
|
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 "pkg-config" as pkg_config;
|
||||||
|
extern crate gcc;
|
||||||
|
|
||||||
use std::env;
|
use std::env;
|
||||||
|
use std::default::Default;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let target = env::var_string("TARGET").unwrap();
|
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.
|
if target.contains("android") {
|
||||||
// So, abandon ship if we're cross compiling.
|
|
||||||
if !is_android && !pkg_config::target_supported() {
|
|
||||||
panic!("unsupported target");
|
|
||||||
}
|
|
||||||
|
|
||||||
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()
|
let path = env::var_string("OPENSSL_PATH").ok()
|
||||||
.expect("Android does not provide openssl libraries, please build them yourselves \
|
.expect("Android does not provide openssl libraries, please build them yourself \
|
||||||
(instructions in the README) and provide their location through \
|
(instructions in the README) and provide their location through \
|
||||||
$OPENSSL_PATH.");
|
$OPENSSL_PATH.");
|
||||||
flags.push_str(format!(" -L {}", path).as_slice());
|
println!("cargo:rustc-flags=-L native={} -l crypto:static -l ssl:static", path);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
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 EVP_PKEY_set1_RSA(k: *mut EVP_PKEY, r: *mut RSA) -> c_int;
|
||||||
|
|
||||||
pub fn HMAC_CTX_init(ctx: *mut HMAC_CTX);
|
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;
|
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;
|
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_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_cleanup(ctx: *mut HMAC_CTX);
|
||||||
pub fn HMAC_CTX_copy(dst: *mut HMAC_CTX, src: *const HMAC_CTX) -> c_int;
|
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>,
|
pub fn PEM_read_bio_X509(bio: *mut BIO, out: *mut *mut X509, callback: Option<PasswordCallback>,
|
||||||
user_data: *mut c_void) -> *mut X509;
|
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,7 +87,7 @@ impl HMAC {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn init_once(&mut self, md: *const ffi::EVP_MD, key: &[u8]) {
|
fn init_once(&mut self, md: *const ffi::EVP_MD, key: &[u8]) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let r = ffi::HMAC_Init_ex(&mut self.ctx,
|
let r = ffi::HMAC_Init_ex_shim(&mut self.ctx,
|
||||||
key.as_ptr(), key.len() as c_int,
|
key.as_ptr(), key.len() as c_int,
|
||||||
md, 0 as *const _);
|
md, 0 as *const _);
|
||||||
assert_eq!(r, 1);
|
assert_eq!(r, 1);
|
||||||
|
|
@ -105,7 +105,7 @@ impl HMAC {
|
||||||
// If the key and/or md is not supplied it's reused from the last time
|
// If the key and/or md is not supplied it's reused from the last time
|
||||||
// avoiding redundant initializations
|
// avoiding redundant initializations
|
||||||
unsafe {
|
unsafe {
|
||||||
let r = ffi::HMAC_Init_ex(&mut self.ctx,
|
let r = ffi::HMAC_Init_ex_shim(&mut self.ctx,
|
||||||
0 as *const _, 0,
|
0 as *const _, 0,
|
||||||
0 as *const _, 0 as *const _);
|
0 as *const _, 0 as *const _);
|
||||||
assert_eq!(r, 1);
|
assert_eq!(r, 1);
|
||||||
|
|
@ -119,8 +119,7 @@ impl HMAC {
|
||||||
self.init();
|
self.init();
|
||||||
}
|
}
|
||||||
unsafe {
|
unsafe {
|
||||||
let r = ffi::HMAC_Update(&mut self.ctx, data.as_ptr(),
|
let r = ffi::HMAC_Update_shim(&mut self.ctx, data.as_ptr(), data.len() as c_uint);
|
||||||
data.len() as c_uint);
|
|
||||||
assert_eq!(r, 1);
|
assert_eq!(r, 1);
|
||||||
}
|
}
|
||||||
self.state = Updated;
|
self.state = Updated;
|
||||||
|
|
@ -135,7 +134,7 @@ impl HMAC {
|
||||||
let mut res: Vec<u8> = repeat(0).take(md_len).collect();
|
let mut res: Vec<u8> = repeat(0).take(md_len).collect();
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut len = 0;
|
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;
|
self.state = Finalized;
|
||||||
assert_eq!(len as usize, md_len);
|
assert_eq!(len as usize, md_len);
|
||||||
assert_eq!(r, 1);
|
assert_eq!(r, 1);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue