This commit is contained in:
Steven Fackler 2017-07-15 21:46:11 -07:00
parent 5c2410c38a
commit bcd0dcafcb
39 changed files with 4303 additions and 2526 deletions

View File

@ -11,19 +11,21 @@ use std::panic::{self, AssertUnwindSafe};
use std::process::Command;
// The set of `OPENSSL_NO_<FOO>`s that we care about.
const DEFINES: &'static [&'static str] = &["OPENSSL_NO_BUF_FREELISTS",
"OPENSSL_NO_COMP",
"OPENSSL_NO_EC",
"OPENSSL_NO_EC2M",
"OPENSSL_NO_ENGINE",
"OPENSSL_NO_KRB5",
"OPENSSL_NO_NEXTPROTONEG",
"OPENSSL_NO_PSK",
"OPENSSL_NO_RFC3779",
"OPENSSL_NO_SHA",
"OPENSSL_NO_SRP",
"OPENSSL_NO_SSL3_METHOD",
"OPENSSL_NO_TLSEXT"];
const DEFINES: &'static [&'static str] = &[
"OPENSSL_NO_BUF_FREELISTS",
"OPENSSL_NO_COMP",
"OPENSSL_NO_EC",
"OPENSSL_NO_EC2M",
"OPENSSL_NO_ENGINE",
"OPENSSL_NO_KRB5",
"OPENSSL_NO_NEXTPROTONEG",
"OPENSSL_NO_PSK",
"OPENSSL_NO_RFC3779",
"OPENSSL_NO_SHA",
"OPENSSL_NO_SRP",
"OPENSSL_NO_SSL3_METHOD",
"OPENSSL_NO_TLSEXT",
];
enum Version {
Openssl110,
@ -52,16 +54,22 @@ fn main() {
};
if !Path::new(&lib_dir).exists() {
panic!("OpenSSL library directory does not exist: {}",
lib_dir.to_string_lossy());
panic!(
"OpenSSL library directory does not exist: {}",
lib_dir.to_string_lossy()
);
}
if !Path::new(&include_dir).exists() {
panic!("OpenSSL include directory does not exist: {}",
include_dir.to_string_lossy());
panic!(
"OpenSSL include directory does not exist: {}",
include_dir.to_string_lossy()
);
}
println!("cargo:rustc-link-search=native={}",
lib_dir.to_string_lossy());
println!(
"cargo:rustc-link-search=native={}",
lib_dir.to_string_lossy()
);
println!("cargo:include={}", include_dir.to_string_lossy());
let version = validate_headers(&[include_dir.clone().into()]);
@ -103,7 +111,8 @@ fn find_openssl_dir(target: &str) -> OsString {
try_pkg_config();
let mut msg = format!("
let mut msg = format!(
"
Could not find directory of OpenSSL installation, and this `-sys` crate cannot
proceed without this knowledge. If OpenSSL is installed and this crate had
@ -119,14 +128,16 @@ and include information about your system as well as this message.
openssl-sys = {}
",
host,
target,
env!("CARGO_PKG_VERSION"));
host,
target,
env!("CARGO_PKG_VERSION")
);
if host.contains("apple-darwin") && target.contains("apple-darwin") {
let system = Path::new("/usr/lib/libssl.0.9.8.dylib");
if system.exists() {
msg.push_str(&format!("
msg.push_str(&format!(
"
It looks like you're compiling on macOS, where the system contains a version of
OpenSSL 0.9.8. This crate no longer supports OpenSSL 0.9.8.
@ -137,24 +148,28 @@ install the `openssl` package, or as a maintainer you can use the openssl-sys
Unfortunately though the compile cannot continue, so aborting.
"));
"
));
}
}
if host.contains("unknown-linux") && target.contains("unknown-linux-gnu") {
if Command::new("pkg-config").output().is_err() {
msg.push_str(&format!("
msg.push_str(&format!(
"
It looks like you're compiling on Linux and also targeting Linux. Currently this
requires the `pkg-config` utility to find OpenSSL but unfortunately `pkg-config`
could not be found. If you have OpenSSL installed you can likely fix this by
installing `pkg-config`.
"));
"
));
}
}
if host.contains("windows") && target.contains("windows-gnu") {
msg.push_str(&format!("
msg.push_str(&format!(
"
It looks like you're compiling for MinGW but you may not have either OpenSSL or
pkg-config installed. You can install these two dependencies with:
@ -162,11 +177,13 @@ pkg-config installed. You can install these two dependencies with:
and try building this crate again.
"));
"
));
}
if host.contains("windows") && target.contains("windows-msvc") {
msg.push_str(&format!("
msg.push_str(&format!(
"
It looks like you're compiling for MSVC but we couldn't detect an OpenSSL
installation. If there isn't one installed then you can try the rust-openssl
README for more information about how to download precompiled binaries of
@ -174,7 +191,8 @@ OpenSSL:
https://github.com/sfackler/rust-openssl#windows
"));
"
));
}
panic!(msg);
@ -198,9 +216,9 @@ fn try_pkg_config() {
return;
}
let lib = match pkg_config::Config::new()
.print_system_libs(false)
.find("openssl") {
let lib = match pkg_config::Config::new().print_system_libs(false).find(
"openssl",
) {
Ok(lib) => lib,
Err(e) => {
println!("run pkg_config fail: {:?}", e);
@ -236,8 +254,9 @@ fn validate_headers(include_dirs: &[PathBuf]) -> Version {
path.push("expando.c");
let mut file = BufWriter::new(File::create(&path).unwrap());
write!(file,
"\
write!(
file,
"\
#include <openssl/opensslv.h>
#include <openssl/opensslconf.h>
@ -270,18 +289,19 @@ RUST_OPENSSL_101
#else
RUST_OPENSSL_OLD
#endif
")
.unwrap();
"
).unwrap();
for define in DEFINES {
write!(file,
"\
write!(
file,
"\
#ifdef {define}
RUST_{define}
#endif
",
define = define)
.unwrap();
define = define
).unwrap();
}
file.flush().unwrap();
@ -295,7 +315,8 @@ RUST_{define}
let expanded = match panic::catch_unwind(AssertUnwindSafe(|| gcc.file(&path).expand())) {
Ok(expanded) => expanded,
Err(_) => {
panic!("
panic!(
"
Failed to find OpenSSL development headers.
You can try fixing this setting the `OPENSSL_DIR` environment variable
@ -312,7 +333,8 @@ specific to your distribution:
See rust-openssl README for more information:
https://github.com/sfackler/rust-openssl#linux
");
"
);
}
};
let expanded = String::from_utf8(expanded).unwrap();
@ -381,13 +403,15 @@ See rust-openssl README for more information:
println!("cargo:version=101");
Version::Openssl101
} else {
panic!("
panic!(
"
This crate is only compatible with OpenSSL 1.0.1, 1.0.2, and 1.1.0, or LibreSSL
2.5.0, 2.5.1, 2.5.2, 2.5.3, and 2.5.4, but a different version of OpenSSL was
found. The build is now aborting due to this version mismatch.
");
"
);
}
}
@ -413,23 +437,22 @@ fn determine_mode(libdir: &Path, libs: &[&str]) -> &'static str {
.map(|e| e.file_name())
.filter_map(|e| e.into_string().ok())
.collect::<HashSet<_>>();
let can_static =
libs.iter()
.all(|l| {
files.contains(&format!("lib{}.a", l)) || files.contains(&format!("{}.lib", l))
});
let can_dylib = libs.iter()
.all(|l| {
files.contains(&format!("lib{}.so", l)) || files.contains(&format!("{}.dll", l)) ||
files.contains(&format!("lib{}.dylib", l))
});
let can_static = libs.iter().all(|l| {
files.contains(&format!("lib{}.a", l)) || files.contains(&format!("{}.lib", l))
});
let can_dylib = libs.iter().all(|l| {
files.contains(&format!("lib{}.so", l)) || files.contains(&format!("{}.dll", l)) ||
files.contains(&format!("lib{}.dylib", l))
});
match (can_static, can_dylib) {
(true, false) => return "static",
(false, true) => return "dylib",
(false, false) => {
panic!("OpenSSL libdir at `{}` does not contain the required files \
panic!(
"OpenSSL libdir at `{}` does not contain the required files \
to either statically or dynamically link OpenSSL",
libdir.display());
libdir.display()
);
}
(true, true) => {}
}

File diff suppressed because it is too large Load Diff

View File

@ -148,13 +148,15 @@ pub struct EVP_PKEY {
#[repr(C)]
pub struct BIO {
pub method: *mut ::BIO_METHOD,
pub callback: Option<unsafe extern "C" fn(*mut ::BIO,
c_int,
*const c_char,
c_int,
c_long,
c_long)
-> c_long>,
pub callback: Option<
unsafe extern "C" fn(*mut ::BIO,
c_int,
*const c_char,
c_int,
c_long,
c_long)
-> c_long,
>,
pub cb_arg: *mut c_char,
pub init: c_int,
pub shutdown: c_int,
@ -192,23 +194,28 @@ pub struct EVP_CIPHER {
pub key_len: c_int,
pub iv_len: c_int,
pub flags: c_ulong,
pub init: Option<unsafe extern "C" fn(*mut ::EVP_CIPHER_CTX,
*const c_uchar,
*const c_uchar,
c_int)
-> c_int>,
pub do_cipher: Option<unsafe extern "C" fn(*mut ::EVP_CIPHER_CTX,
*mut c_uchar,
*const c_uchar,
size_t)
-> c_int>,
pub init: Option<
unsafe extern "C" fn(*mut ::EVP_CIPHER_CTX,
*const c_uchar,
*const c_uchar,
c_int)
-> c_int,
>,
pub do_cipher: Option<
unsafe extern "C" fn(*mut ::EVP_CIPHER_CTX,
*mut c_uchar,
*const c_uchar,
size_t)
-> c_int,
>,
pub cleanup: Option<unsafe extern "C" fn(*mut ::EVP_CIPHER_CTX) -> c_int>,
pub ctx_size: c_int,
pub set_asn1_parameters:
Option<unsafe extern "C" fn(*mut ::EVP_CIPHER_CTX, *mut ::ASN1_TYPE) -> c_int>,
pub get_asn1_parameters:
Option<unsafe extern "C" fn(*mut ::EVP_CIPHER_CTX, *mut ::ASN1_TYPE) -> c_int>,
pub ctrl: Option<unsafe extern "C" fn(*mut ::EVP_CIPHER_CTX, c_int, c_int, *mut c_void) -> c_int>,
pub ctrl:
Option<unsafe extern "C" fn(*mut ::EVP_CIPHER_CTX, c_int, c_int, *mut c_void) -> c_int>,
pub app_data: *mut c_void,
}
@ -369,8 +376,8 @@ pub const CRYPTO_LOCK_SSL_CTX: c_int = 12;
pub const CRYPTO_LOCK_SSL_SESSION: c_int = 14;
static mut MUTEXES: *mut Vec<Mutex<()>> = 0 as *mut Vec<Mutex<()>>;
static mut GUARDS: *mut Vec<Option<MutexGuard<'static, ()>>> =
0 as *mut Vec<Option<MutexGuard<'static, ()>>>;
static mut GUARDS: *mut Vec<Option<MutexGuard<'static, ()>>> = 0 as
*mut Vec<Option<MutexGuard<'static, ()>>>;
unsafe extern "C" fn locking_function(mode: c_int, n: c_int, _file: *const c_char, _line: c_int) {
let mutex = &(*MUTEXES)[n as usize];
@ -378,9 +385,7 @@ unsafe extern "C" fn locking_function(mode: c_int, n: c_int, _file: *const c_cha
if mode & ::CRYPTO_LOCK != 0 {
(*GUARDS)[n as usize] = Some(mutex.lock().unwrap());
} else {
&(*GUARDS)[n as usize]
.take()
.expect("lock already unlocked");
&(*GUARDS)[n as usize].take().expect("lock already unlocked");
}
}
@ -388,23 +393,23 @@ pub fn init() {
static INIT: Once = ONCE_INIT;
INIT.call_once(|| unsafe {
SSL_library_init();
SSL_load_error_strings();
OPENSSL_add_all_algorithms_noconf();
SSL_library_init();
SSL_load_error_strings();
OPENSSL_add_all_algorithms_noconf();
let num_locks = ::CRYPTO_num_locks();
let mut mutexes = Box::new(Vec::new());
for _ in 0..num_locks {
mutexes.push(Mutex::new(()));
}
MUTEXES = mem::transmute(mutexes);
let guards: Box<Vec<Option<MutexGuard<()>>>> =
Box::new((0..num_locks).map(|_| None).collect());
GUARDS = mem::transmute(guards);
let num_locks = ::CRYPTO_num_locks();
let mut mutexes = Box::new(Vec::new());
for _ in 0..num_locks {
mutexes.push(Mutex::new(()));
}
MUTEXES = mem::transmute(mutexes);
let guards: Box<Vec<Option<MutexGuard<()>>>> =
Box::new((0..num_locks).map(|_| None).collect());
GUARDS = mem::transmute(guards);
CRYPTO_set_locking_callback(locking_function);
set_id_callback();
})
CRYPTO_set_locking_callback(locking_function);
set_id_callback();
})
}
#[cfg(unix)]
@ -424,17 +429,21 @@ fn set_id_callback() {}
// macros
pub unsafe fn SSL_CTX_set_ecdh_auto(ctx: *mut SSL_CTX, onoff: c_int) -> c_int {
::SSL_CTX_ctrl(ctx,
SSL_CTRL_SET_ECDH_AUTO,
onoff as c_long,
ptr::null_mut()) as c_int
::SSL_CTX_ctrl(
ctx,
SSL_CTRL_SET_ECDH_AUTO,
onoff as c_long,
ptr::null_mut(),
) as c_int
}
pub unsafe fn SSL_set_ecdh_auto(ssl: *mut ::SSL, onoff: c_int) -> c_int {
::SSL_ctrl(ssl,
SSL_CTRL_SET_ECDH_AUTO,
onoff as c_long,
ptr::null_mut()) as c_int
::SSL_ctrl(
ssl,
SSL_CTRL_SET_ECDH_AUTO,
onoff as c_long,
ptr::null_mut(),
) as c_int
}
pub unsafe fn SSL_session_reused(ssl: *mut ::SSL) -> c_int {
@ -458,36 +467,38 @@ extern "C" {
pub fn CRYPTO_malloc(num: c_int, file: *const c_char, line: c_int) -> *mut c_void;
pub fn CRYPTO_free(buf: *mut c_void);
pub fn CRYPTO_num_locks() -> c_int;
pub fn CRYPTO_set_locking_callback(func: unsafe extern "C" fn(mode: c_int,
n: c_int,
file: *const c_char,
line: c_int));
pub fn CRYPTO_set_locking_callback(
func: unsafe extern "C" fn(mode: c_int, n: c_int, file: *const c_char, line: c_int),
);
pub fn CRYPTO_set_id_callback(func: unsafe extern "C" fn() -> c_ulong);
pub fn ERR_load_crypto_strings();
pub fn RSA_generate_key(modsz: c_int,
e: c_ulong,
cb: Option<extern "C" fn(c_int, c_int, *mut c_void)>,
cbarg: *mut c_void)
-> *mut RSA;
pub fn RSA_generate_key(
modsz: c_int,
e: c_ulong,
cb: Option<extern "C" fn(c_int, c_int, *mut c_void)>,
cbarg: *mut c_void,
) -> *mut RSA;
pub fn OCSP_cert_to_id(dgst: *const ::EVP_MD,
subject: *mut ::X509,
issuer: *mut ::X509)
-> *mut ::OCSP_CERTID;
pub fn OCSP_cert_to_id(
dgst: *const ::EVP_MD,
subject: *mut ::X509,
issuer: *mut ::X509,
) -> *mut ::OCSP_CERTID;
pub fn PKCS12_create(pass: *mut c_char,
friendly_name: *mut c_char,
pkey: *mut EVP_PKEY,
cert: *mut X509,
ca: *mut stack_st_X509,
nid_key: c_int,
nid_cert: c_int,
iter: c_int,
mac_iter: c_int,
keytype: c_int)
-> *mut PKCS12;
pub fn PKCS12_create(
pass: *mut c_char,
friendly_name: *mut c_char,
pkey: *mut EVP_PKEY,
cert: *mut X509,
ca: *mut stack_st_X509,
nid_key: c_int,
nid_cert: c_int,
iter: c_int,
mac_iter: c_int,
keytype: c_int,
) -> *mut PKCS12;
pub fn SSL_library_init() -> c_int;
pub fn SSL_load_error_strings();
@ -499,66 +510,73 @@ extern "C" {
pub fn TLSv1_1_method() -> *const ::SSL_METHOD;
pub fn TLSv1_2_method() -> *const ::SSL_METHOD;
pub fn DTLSv1_method() -> *const ::SSL_METHOD;
pub fn SSL_get_ex_new_index(argl: c_long,
argp: *mut c_void,
new_func: Option<::CRYPTO_EX_new>,
dup_func: Option<::CRYPTO_EX_dup>,
free_func: Option<::CRYPTO_EX_free>)
-> c_int;
pub fn SSL_set_tmp_ecdh_callback(ssl: *mut ::SSL,
ecdh: unsafe extern "C" fn(ssl: *mut ::SSL,
is_export: c_int,
keylength: c_int)
-> *mut ::EC_KEY);
pub fn SSL_get_ex_new_index(
argl: c_long,
argp: *mut c_void,
new_func: Option<::CRYPTO_EX_new>,
dup_func: Option<::CRYPTO_EX_dup>,
free_func: Option<::CRYPTO_EX_free>,
) -> c_int;
pub fn SSL_set_tmp_ecdh_callback(
ssl: *mut ::SSL,
ecdh: unsafe extern "C" fn(ssl: *mut ::SSL, is_export: c_int, keylength: c_int)
-> *mut ::EC_KEY,
);
pub fn SSL_CIPHER_get_version(cipher: *const ::SSL_CIPHER) -> *mut c_char;
pub fn SSL_CTX_get_ex_new_index(argl: c_long,
argp: *mut c_void,
new_func: Option<::CRYPTO_EX_new>,
dup_func: Option<::CRYPTO_EX_dup>,
free_func: Option<::CRYPTO_EX_free>)
-> c_int;
pub fn SSL_CTX_set_tmp_ecdh_callback(ctx: *mut ::SSL_CTX,
ecdh: unsafe extern "C" fn(ssl: *mut ::SSL,
is_export: c_int,
keylength: c_int)
-> *mut ::EC_KEY);
pub fn SSL_CTX_get_ex_new_index(
argl: c_long,
argp: *mut c_void,
new_func: Option<::CRYPTO_EX_new>,
dup_func: Option<::CRYPTO_EX_dup>,
free_func: Option<::CRYPTO_EX_free>,
) -> c_int;
pub fn SSL_CTX_set_tmp_ecdh_callback(
ctx: *mut ::SSL_CTX,
ecdh: unsafe extern "C" fn(ssl: *mut ::SSL, is_export: c_int, keylength: c_int)
-> *mut ::EC_KEY,
);
pub fn X509_get_subject_name(x: *mut ::X509) -> *mut ::X509_NAME;
pub fn X509_set_notAfter(x: *mut ::X509, tm: *const ::ASN1_TIME) -> c_int;
pub fn X509_set_notBefore(x: *mut ::X509, tm: *const ::ASN1_TIME) -> c_int;
pub fn X509_get_ext_d2i(x: *mut ::X509,
nid: c_int,
crit: *mut c_int,
idx: *mut c_int)
-> *mut c_void;
pub fn X509_NAME_add_entry_by_NID(x: *mut ::X509_NAME,
field: c_int,
ty: c_int,
bytes: *mut c_uchar,
len: c_int,
loc: c_int,
set: c_int)
-> c_int;
pub fn X509_get_ext_d2i(
x: *mut ::X509,
nid: c_int,
crit: *mut c_int,
idx: *mut c_int,
) -> *mut c_void;
pub fn X509_NAME_add_entry_by_NID(
x: *mut ::X509_NAME,
field: c_int,
ty: c_int,
bytes: *mut c_uchar,
len: c_int,
loc: c_int,
set: c_int,
) -> c_int;
pub fn X509_NAME_get_entry(n: *mut ::X509_NAME, loc: c_int) -> *mut ::X509_NAME_ENTRY;
pub fn X509_NAME_ENTRY_get_data(ne: *mut ::X509_NAME_ENTRY) -> *mut ::ASN1_STRING;
pub fn X509_STORE_CTX_get_chain(ctx: *mut ::X509_STORE_CTX) -> *mut stack_st_X509;
pub fn X509V3_EXT_nconf_nid(conf: *mut ::CONF,
ctx: *mut ::X509V3_CTX,
ext_nid: c_int,
value: *mut c_char)
-> *mut ::X509_EXTENSION;
pub fn X509V3_EXT_nconf(conf: *mut ::CONF,
ctx: *mut ::X509V3_CTX,
name: *mut c_char,
value: *mut c_char)
-> *mut ::X509_EXTENSION;
pub fn X509V3_EXT_nconf_nid(
conf: *mut ::CONF,
ctx: *mut ::X509V3_CTX,
ext_nid: c_int,
value: *mut c_char,
) -> *mut ::X509_EXTENSION;
pub fn X509V3_EXT_nconf(
conf: *mut ::CONF,
ctx: *mut ::X509V3_CTX,
name: *mut c_char,
value: *mut c_char,
) -> *mut ::X509_EXTENSION;
pub fn ASN1_STRING_to_UTF8(out: *mut *mut c_uchar, s: *mut ::ASN1_STRING) -> c_int;
pub fn ASN1_STRING_data(x: *mut ::ASN1_STRING) -> *mut c_uchar;
pub fn CRYPTO_add_lock(pointer: *mut c_int,
amount: c_int,
type_: c_int,
file: *const c_char,
line: c_int)
-> c_int;
pub fn CRYPTO_add_lock(
pointer: *mut c_int,
amount: c_int,
type_: c_int,
file: *const c_char,
line: c_int,
) -> c_int;
pub fn EVP_MD_CTX_create() -> *mut EVP_MD_CTX;
pub fn EVP_MD_CTX_destroy(ctx: *mut EVP_MD_CTX);
pub fn EVP_PKEY_bits(key: *mut EVP_PKEY) -> c_int;

View File

@ -28,13 +28,15 @@ pub struct SSL {
s3: *mut c_void,
d1: *mut c_void,
read_ahead: c_int,
msg_callback: Option<unsafe extern "C" fn(c_int,
c_int,
c_int,
*const c_void,
size_t,
*mut SSL,
*mut c_void)>,
msg_callback: Option<
unsafe extern "C" fn(c_int,
c_int,
c_int,
*const c_void,
size_t,
*mut SSL,
*mut c_void),
>,
msg_callback_arg: *mut c_void,
hit: c_int,
param: *mut c_void,

View File

@ -141,13 +141,15 @@ pub struct EVP_PKEY {
#[repr(C)]
pub struct BIO {
pub method: *mut ::BIO_METHOD,
pub callback: Option<unsafe extern "C" fn(*mut ::BIO,
c_int,
*const c_char,
c_int,
c_long,
c_long)
-> c_long>,
pub callback: Option<
unsafe extern "C" fn(*mut ::BIO,
c_int,
*const c_char,
c_int,
c_long,
c_long)
-> c_long,
>,
pub cb_arg: *mut c_char,
pub init: c_int,
pub shutdown: c_int,
@ -186,23 +188,28 @@ pub struct EVP_CIPHER {
pub key_len: c_int,
pub iv_len: c_int,
pub flags: c_ulong,
pub init: Option<unsafe extern "C" fn(*mut ::EVP_CIPHER_CTX,
*const c_uchar,
*const c_uchar,
c_int)
-> c_int>,
pub do_cipher: Option<unsafe extern "C" fn(*mut ::EVP_CIPHER_CTX,
*mut c_uchar,
*const c_uchar,
size_t)
-> c_int>,
pub init: Option<
unsafe extern "C" fn(*mut ::EVP_CIPHER_CTX,
*const c_uchar,
*const c_uchar,
c_int)
-> c_int,
>,
pub do_cipher: Option<
unsafe extern "C" fn(*mut ::EVP_CIPHER_CTX,
*mut c_uchar,
*const c_uchar,
size_t)
-> c_int,
>,
pub cleanup: Option<unsafe extern "C" fn(*mut ::EVP_CIPHER_CTX) -> c_int>,
pub ctx_size: c_int,
pub set_asn1_parameters:
Option<unsafe extern "C" fn(*mut ::EVP_CIPHER_CTX, *mut ::ASN1_TYPE) -> c_int>,
pub get_asn1_parameters:
Option<unsafe extern "C" fn(*mut ::EVP_CIPHER_CTX, *mut ::ASN1_TYPE) -> c_int>,
pub ctrl: Option<unsafe extern "C" fn(*mut ::EVP_CIPHER_CTX, c_int, c_int, *mut c_void) -> c_int>,
pub ctrl:
Option<unsafe extern "C" fn(*mut ::EVP_CIPHER_CTX, c_int, c_int, *mut c_void) -> c_int>,
pub app_data: *mut c_void,
}
@ -355,13 +362,15 @@ pub struct SSL {
s3: *mut c_void,
d1: *mut c_void,
read_ahead: c_int,
msg_callback: Option<unsafe extern "C" fn(c_int,
c_int,
c_int,
*const c_void,
size_t,
*mut SSL,
*mut c_void)>,
msg_callback: Option<
unsafe extern "C" fn(c_int,
c_int,
c_int,
*const c_void,
size_t,
*mut SSL,
*mut c_void),
>,
msg_callback_arg: *mut c_void,
hit: c_int,
param: *mut c_void,
@ -387,13 +396,15 @@ pub struct SSL {
#[cfg(not(osslconf = "OPENSSL_NO_KRB5"))]
kssl_ctx: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_PSK"))]
psk_client_callback: Option<unsafe extern "C" fn(*mut SSL,
*const c_char,
*mut c_char,
c_uint,
*mut c_uchar,
c_uint)
-> c_uint>,
psk_client_callback: Option<
unsafe extern "C" fn(*mut SSL,
*const c_char,
*mut c_char,
c_uint,
*mut c_uchar,
c_uint)
-> c_uint,
>,
#[cfg(not(osslconf = "OPENSSL_NO_PSK"))]
psk_server_callback:
Option<unsafe extern "C" fn(*mut SSL, *const c_char, *mut c_uchar, c_uint) -> c_uint>,
@ -726,8 +737,8 @@ pub const CRYPTO_LOCK_SSL_CTX: c_int = 12;
pub const CRYPTO_LOCK_SSL_SESSION: c_int = 14;
static mut MUTEXES: *mut Vec<Mutex<()>> = 0 as *mut Vec<Mutex<()>>;
static mut GUARDS: *mut Vec<Option<MutexGuard<'static, ()>>> =
0 as *mut Vec<Option<MutexGuard<'static, ()>>>;
static mut GUARDS: *mut Vec<Option<MutexGuard<'static, ()>>> = 0 as
*mut Vec<Option<MutexGuard<'static, ()>>>;
unsafe extern "C" fn locking_function(mode: c_int, n: c_int, _file: *const c_char, _line: c_int) {
let mutex = &(*MUTEXES)[n as usize];
@ -735,9 +746,7 @@ unsafe extern "C" fn locking_function(mode: c_int, n: c_int, _file: *const c_cha
if mode & ::CRYPTO_LOCK != 0 {
(*GUARDS)[n as usize] = Some(mutex.lock().unwrap());
} else {
&(*GUARDS)[n as usize]
.take()
.expect("lock already unlocked");
&(*GUARDS)[n as usize].take().expect("lock already unlocked");
}
}
@ -745,23 +754,23 @@ pub fn init() {
static INIT: Once = ONCE_INIT;
INIT.call_once(|| unsafe {
SSL_library_init();
SSL_load_error_strings();
OPENSSL_add_all_algorithms_noconf();
SSL_library_init();
SSL_load_error_strings();
OPENSSL_add_all_algorithms_noconf();
let num_locks = ::CRYPTO_num_locks();
let mut mutexes = Box::new(Vec::new());
for _ in 0..num_locks {
mutexes.push(Mutex::new(()));
}
MUTEXES = mem::transmute(mutexes);
let guards: Box<Vec<Option<MutexGuard<()>>>> =
Box::new((0..num_locks).map(|_| None).collect());
GUARDS = mem::transmute(guards);
let num_locks = ::CRYPTO_num_locks();
let mut mutexes = Box::new(Vec::new());
for _ in 0..num_locks {
mutexes.push(Mutex::new(()));
}
MUTEXES = mem::transmute(mutexes);
let guards: Box<Vec<Option<MutexGuard<()>>>> =
Box::new((0..num_locks).map(|_| None).collect());
GUARDS = mem::transmute(guards);
CRYPTO_set_locking_callback(locking_function);
set_id_callback();
})
CRYPTO_set_locking_callback(locking_function);
set_id_callback();
})
}
#[cfg(unix)]
@ -782,18 +791,22 @@ fn set_id_callback() {}
#[cfg(ossl102)]
pub unsafe fn SSL_CTX_set_ecdh_auto(ctx: *mut SSL_CTX, onoff: c_int) -> c_int {
::SSL_CTX_ctrl(ctx,
SSL_CTRL_SET_ECDH_AUTO,
onoff as c_long,
ptr::null_mut()) as c_int
::SSL_CTX_ctrl(
ctx,
SSL_CTRL_SET_ECDH_AUTO,
onoff as c_long,
ptr::null_mut(),
) as c_int
}
#[cfg(ossl102)]
pub unsafe fn SSL_set_ecdh_auto(ssl: *mut ::SSL, onoff: c_int) -> c_int {
::SSL_ctrl(ssl,
SSL_CTRL_SET_ECDH_AUTO,
onoff as c_long,
ptr::null_mut()) as c_int
::SSL_ctrl(
ssl,
SSL_CTRL_SET_ECDH_AUTO,
onoff as c_long,
ptr::null_mut(),
) as c_int
}
pub unsafe fn SSL_session_reused(ssl: *mut ::SSL) -> c_int {
@ -817,36 +830,38 @@ extern "C" {
pub fn CRYPTO_malloc(num: c_int, file: *const c_char, line: c_int) -> *mut c_void;
pub fn CRYPTO_free(buf: *mut c_void);
pub fn CRYPTO_num_locks() -> c_int;
pub fn CRYPTO_set_locking_callback(func: unsafe extern "C" fn(mode: c_int,
n: c_int,
file: *const c_char,
line: c_int));
pub fn CRYPTO_set_locking_callback(
func: unsafe extern "C" fn(mode: c_int, n: c_int, file: *const c_char, line: c_int),
);
pub fn CRYPTO_set_id_callback(func: unsafe extern "C" fn() -> c_ulong);
pub fn ERR_load_crypto_strings();
pub fn RSA_generate_key(modsz: c_int,
e: c_ulong,
cb: Option<extern "C" fn(c_int, c_int, *mut c_void)>,
cbarg: *mut c_void)
-> *mut RSA;
pub fn RSA_generate_key(
modsz: c_int,
e: c_ulong,
cb: Option<extern "C" fn(c_int, c_int, *mut c_void)>,
cbarg: *mut c_void,
) -> *mut RSA;
pub fn OCSP_cert_to_id(dgst: *const ::EVP_MD,
subject: *mut ::X509,
issuer: *mut ::X509)
-> *mut ::OCSP_CERTID;
pub fn OCSP_cert_to_id(
dgst: *const ::EVP_MD,
subject: *mut ::X509,
issuer: *mut ::X509,
) -> *mut ::OCSP_CERTID;
pub fn PKCS12_create(pass: *mut c_char,
friendly_name: *mut c_char,
pkey: *mut EVP_PKEY,
cert: *mut X509,
ca: *mut stack_st_X509,
nid_key: c_int,
nid_cert: c_int,
iter: c_int,
mac_iter: c_int,
keytype: c_int)
-> *mut PKCS12;
pub fn PKCS12_create(
pass: *mut c_char,
friendly_name: *mut c_char,
pkey: *mut EVP_PKEY,
cert: *mut X509,
ca: *mut stack_st_X509,
nid_key: c_int,
nid_cert: c_int,
iter: c_int,
mac_iter: c_int,
keytype: c_int,
) -> *mut PKCS12;
pub fn SSL_library_init() -> c_int;
pub fn SSL_load_error_strings();
@ -862,77 +877,88 @@ extern "C" {
pub fn DTLSv1_method() -> *const ::SSL_METHOD;
#[cfg(ossl102)]
pub fn DTLSv1_2_method() -> *const ::SSL_METHOD;
pub fn SSL_get_ex_new_index(argl: c_long,
argp: *mut c_void,
new_func: Option<::CRYPTO_EX_new>,
dup_func: Option<::CRYPTO_EX_dup>,
free_func: Option<::CRYPTO_EX_free>)
-> c_int;
pub fn SSL_set_tmp_ecdh_callback(ssl: *mut ::SSL,
ecdh: unsafe extern "C" fn(ssl: *mut ::SSL,
is_export: c_int,
keylength: c_int)
-> *mut ::EC_KEY);
pub fn SSL_get_ex_new_index(
argl: c_long,
argp: *mut c_void,
new_func: Option<::CRYPTO_EX_new>,
dup_func: Option<::CRYPTO_EX_dup>,
free_func: Option<::CRYPTO_EX_free>,
) -> c_int;
pub fn SSL_set_tmp_ecdh_callback(
ssl: *mut ::SSL,
ecdh: unsafe extern "C" fn(ssl: *mut ::SSL, is_export: c_int, keylength: c_int)
-> *mut ::EC_KEY,
);
pub fn SSL_CIPHER_get_version(cipher: *const ::SSL_CIPHER) -> *mut c_char;
pub fn SSL_CTX_get_ex_new_index(argl: c_long,
argp: *mut c_void,
new_func: Option<::CRYPTO_EX_new>,
dup_func: Option<::CRYPTO_EX_dup>,
free_func: Option<::CRYPTO_EX_free>)
-> c_int;
pub fn SSL_CTX_set_tmp_ecdh_callback(ctx: *mut ::SSL_CTX,
ecdh: unsafe extern "C" fn(ssl: *mut ::SSL,
is_export: c_int,
keylength: c_int)
-> *mut ::EC_KEY);
pub fn SSL_CTX_get_ex_new_index(
argl: c_long,
argp: *mut c_void,
new_func: Option<::CRYPTO_EX_new>,
dup_func: Option<::CRYPTO_EX_dup>,
free_func: Option<::CRYPTO_EX_free>,
) -> c_int;
pub fn SSL_CTX_set_tmp_ecdh_callback(
ctx: *mut ::SSL_CTX,
ecdh: unsafe extern "C" fn(ssl: *mut ::SSL, is_export: c_int, keylength: c_int)
-> *mut ::EC_KEY,
);
pub fn X509_get_subject_name(x: *mut ::X509) -> *mut ::X509_NAME;
pub fn X509_set_notAfter(x: *mut ::X509, tm: *const ::ASN1_TIME) -> c_int;
pub fn X509_set_notBefore(x: *mut ::X509, tm: *const ::ASN1_TIME) -> c_int;
pub fn X509_get_ext_d2i(x: *mut ::X509,
nid: c_int,
crit: *mut c_int,
idx: *mut c_int)
-> *mut c_void;
pub fn X509_NAME_add_entry_by_NID(x: *mut ::X509_NAME,
field: c_int,
ty: c_int,
bytes: *mut c_uchar,
len: c_int,
loc: c_int,
set: c_int)
-> c_int;
pub fn X509_get_ext_d2i(
x: *mut ::X509,
nid: c_int,
crit: *mut c_int,
idx: *mut c_int,
) -> *mut c_void;
pub fn X509_NAME_add_entry_by_NID(
x: *mut ::X509_NAME,
field: c_int,
ty: c_int,
bytes: *mut c_uchar,
len: c_int,
loc: c_int,
set: c_int,
) -> c_int;
#[cfg(not(ossl101))]
pub fn X509_get0_signature(psig: *mut *mut ::ASN1_BIT_STRING,
palg: *mut *mut ::X509_ALGOR,
x: *const ::X509);
pub fn X509_get0_signature(
psig: *mut *mut ::ASN1_BIT_STRING,
palg: *mut *mut ::X509_ALGOR,
x: *const ::X509,
);
#[cfg(not(ossl101))]
pub fn X509_get_signature_nid(x: *const X509) -> c_int;
#[cfg(not(ossl101))]
pub fn X509_ALGOR_get0(paobj: *mut *mut ::ASN1_OBJECT,
pptype: *mut c_int,
ppval: *mut *mut c_void,
alg: *mut ::X509_ALGOR);
pub fn X509_ALGOR_get0(
paobj: *mut *mut ::ASN1_OBJECT,
pptype: *mut c_int,
ppval: *mut *mut c_void,
alg: *mut ::X509_ALGOR,
);
pub fn X509_NAME_get_entry(n: *mut ::X509_NAME, loc: c_int) -> *mut ::X509_NAME_ENTRY;
pub fn X509_NAME_ENTRY_get_data(ne: *mut ::X509_NAME_ENTRY) -> *mut ::ASN1_STRING;
pub fn X509_STORE_CTX_get_chain(ctx: *mut ::X509_STORE_CTX) -> *mut stack_st_X509;
pub fn X509V3_EXT_nconf_nid(conf: *mut ::CONF,
ctx: *mut ::X509V3_CTX,
ext_nid: c_int,
value: *mut c_char)
-> *mut ::X509_EXTENSION;
pub fn X509V3_EXT_nconf(conf: *mut ::CONF,
ctx: *mut ::X509V3_CTX,
name: *mut c_char,
value: *mut c_char)
-> *mut ::X509_EXTENSION;
pub fn X509V3_EXT_nconf_nid(
conf: *mut ::CONF,
ctx: *mut ::X509V3_CTX,
ext_nid: c_int,
value: *mut c_char,
) -> *mut ::X509_EXTENSION;
pub fn X509V3_EXT_nconf(
conf: *mut ::CONF,
ctx: *mut ::X509V3_CTX,
name: *mut c_char,
value: *mut c_char,
) -> *mut ::X509_EXTENSION;
pub fn ASN1_STRING_to_UTF8(out: *mut *mut c_uchar, s: *mut ::ASN1_STRING) -> c_int;
pub fn ASN1_STRING_data(x: *mut ::ASN1_STRING) -> *mut c_uchar;
pub fn CRYPTO_add_lock(pointer: *mut c_int,
amount: c_int,
type_: c_int,
file: *const c_char,
line: c_int)
-> c_int;
pub fn CRYPTO_add_lock(
pointer: *mut c_int,
amount: c_int,
type_: c_int,
file: *const c_char,
line: c_int,
) -> c_int;
pub fn EVP_MD_CTX_create() -> *mut EVP_MD_CTX;
pub fn EVP_MD_CTX_destroy(ctx: *mut EVP_MD_CTX);
pub fn EVP_PKEY_bits(key: *mut EVP_PKEY) -> c_int;

View File

@ -62,8 +62,8 @@ pub fn init() {
static INIT: Once = ONCE_INIT;
INIT.call_once(|| unsafe {
OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, ptr::null_mut());
})
OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, ptr::null_mut());
})
}
extern "C" {
@ -89,10 +89,11 @@ extern "C" {
pub fn HMAC_CTX_new() -> *mut HMAC_CTX;
pub fn HMAC_CTX_free(ctx: *mut HMAC_CTX);
pub fn OCSP_cert_to_id(dgst: *const ::EVP_MD,
subject: *const ::X509,
issuer: *const ::X509)
-> *mut ::OCSP_CERTID;
pub fn OCSP_cert_to_id(
dgst: *const ::EVP_MD,
subject: *const ::X509,
issuer: *const ::X509,
) -> *mut ::OCSP_CERTID;
pub fn TLS_method() -> *const ::SSL_METHOD;
pub fn DTLS_method() -> *const ::SSL_METHOD;
@ -100,75 +101,90 @@ extern "C" {
pub fn X509_get_subject_name(x: *const ::X509) -> *mut ::X509_NAME;
pub fn X509_set1_notAfter(x: *mut ::X509, tm: *const ::ASN1_TIME) -> c_int;
pub fn X509_set1_notBefore(x: *mut ::X509, tm: *const ::ASN1_TIME) -> c_int;
pub fn X509_get_ext_d2i(x: *const ::X509,
nid: c_int,
crit: *mut c_int,
idx: *mut c_int)
-> *mut c_void;
pub fn X509_NAME_add_entry_by_NID(x: *mut ::X509_NAME,
field: c_int,
ty: c_int,
bytes: *const c_uchar,
len: c_int,
loc: c_int,
set: c_int)
-> c_int;
pub fn X509_get_ext_d2i(
x: *const ::X509,
nid: c_int,
crit: *mut c_int,
idx: *mut c_int,
) -> *mut c_void;
pub fn X509_NAME_add_entry_by_NID(
x: *mut ::X509_NAME,
field: c_int,
ty: c_int,
bytes: *const c_uchar,
len: c_int,
loc: c_int,
set: c_int,
) -> c_int;
pub fn X509_get_signature_nid(x: *const X509) -> c_int;
pub fn X509_ALGOR_get0(paobj: *mut *const ::ASN1_OBJECT,
pptype: *mut c_int,
ppval: *mut *const c_void,
alg: *const ::X509_ALGOR);
pub fn X509_ALGOR_get0(
paobj: *mut *const ::ASN1_OBJECT,
pptype: *mut c_int,
ppval: *mut *const c_void,
alg: *const ::X509_ALGOR,
);
pub fn X509_NAME_get_entry(n: *const ::X509_NAME, loc: c_int) -> *mut ::X509_NAME_ENTRY;
pub fn X509_NAME_ENTRY_get_data(ne: *const ::X509_NAME_ENTRY) -> *mut ::ASN1_STRING;
pub fn X509V3_EXT_nconf_nid(conf: *mut ::CONF,
ctx: *mut ::X509V3_CTX,
ext_nid: c_int,
value: *const c_char)
-> *mut ::X509_EXTENSION;
pub fn X509V3_EXT_nconf(conf: *mut ::CONF,
ctx: *mut ::X509V3_CTX,
name: *const c_char,
value: *const c_char)
-> *mut ::X509_EXTENSION;
pub fn X509V3_EXT_nconf_nid(
conf: *mut ::CONF,
ctx: *mut ::X509V3_CTX,
ext_nid: c_int,
value: *const c_char,
) -> *mut ::X509_EXTENSION;
pub fn X509V3_EXT_nconf(
conf: *mut ::CONF,
ctx: *mut ::X509V3_CTX,
name: *const c_char,
value: *const c_char,
) -> *mut ::X509_EXTENSION;
pub fn ASN1_STRING_to_UTF8(out: *mut *mut c_uchar, s: *const ::ASN1_STRING) -> c_int;
pub fn BN_is_negative(b: *const ::BIGNUM) -> c_int;
pub fn EVP_CIPHER_key_length(cipher: *const EVP_CIPHER) -> c_int;
pub fn EVP_CIPHER_block_size(cipher: *const EVP_CIPHER) -> c_int;
pub fn EVP_CIPHER_iv_length(cipher: *const EVP_CIPHER) -> c_int;
pub fn EVP_PBE_scrypt(pass: *const c_char,
passlen: size_t,
salt: *const c_uchar,
saltlen: size_t,
N: u64,
r: u64,
p: u64,
maxmem: u64,
key: *mut c_uchar,
keylen: size_t)
-> c_int;
pub fn DSA_get0_pqg(d: *const ::DSA,
p: *mut *const ::BIGNUM,
q: *mut *const ::BIGNUM,
q: *mut *const ::BIGNUM);
pub fn DSA_get0_key(d: *const ::DSA,
pub_key: *mut *const ::BIGNUM,
priv_key: *mut *const ::BIGNUM);
pub fn RSA_get0_key(r: *const ::RSA,
n: *mut *const ::BIGNUM,
e: *mut *const ::BIGNUM,
d: *mut *const ::BIGNUM);
pub fn EVP_PBE_scrypt(
pass: *const c_char,
passlen: size_t,
salt: *const c_uchar,
saltlen: size_t,
N: u64,
r: u64,
p: u64,
maxmem: u64,
key: *mut c_uchar,
keylen: size_t,
) -> c_int;
pub fn DSA_get0_pqg(
d: *const ::DSA,
p: *mut *const ::BIGNUM,
q: *mut *const ::BIGNUM,
q: *mut *const ::BIGNUM,
);
pub fn DSA_get0_key(
d: *const ::DSA,
pub_key: *mut *const ::BIGNUM,
priv_key: *mut *const ::BIGNUM,
);
pub fn RSA_get0_key(
r: *const ::RSA,
n: *mut *const ::BIGNUM,
e: *mut *const ::BIGNUM,
d: *mut *const ::BIGNUM,
);
pub fn RSA_get0_factors(r: *const ::RSA, p: *mut *const ::BIGNUM, q: *mut *const ::BIGNUM);
pub fn RSA_set0_key(r: *mut ::RSA,
n: *mut ::BIGNUM,
e: *mut ::BIGNUM,
d: *mut ::BIGNUM)
-> c_int;
pub fn RSA_set0_key(
r: *mut ::RSA,
n: *mut ::BIGNUM,
e: *mut ::BIGNUM,
d: *mut ::BIGNUM,
) -> c_int;
pub fn RSA_set0_factors(r: *mut ::RSA, p: *mut ::BIGNUM, q: *mut ::BIGNUM) -> c_int;
pub fn RSA_set0_crt_params(r: *mut ::RSA,
dmp1: *mut ::BIGNUM,
dmq1: *mut ::BIGNUM,
iqmp: *mut ::BIGNUM)
-> c_int;
pub fn RSA_set0_crt_params(
r: *mut ::RSA,
dmp1: *mut ::BIGNUM,
dmq1: *mut ::BIGNUM,
iqmp: *mut ::BIGNUM,
) -> c_int;
pub fn ASN1_STRING_get0_data(x: *const ::ASN1_STRING) -> *const c_uchar;
pub fn OPENSSL_sk_num(stack: *const ::OPENSSL_STACK) -> c_int;
pub fn OPENSSL_sk_value(stack: *const ::OPENSSL_STACK, idx: c_int) -> *mut c_void;
@ -177,53 +193,62 @@ extern "C" {
pub fn SSL_CTX_clear_options(ctx: *mut ::SSL_CTX, op: c_ulong) -> c_ulong;
pub fn X509_getm_notAfter(x: *const ::X509) -> *mut ::ASN1_TIME;
pub fn X509_getm_notBefore(x: *const ::X509) -> *mut ::ASN1_TIME;
pub fn X509_get0_signature(psig: *mut *const ::ASN1_BIT_STRING,
palg: *mut *const ::X509_ALGOR,
x: *const ::X509);
pub fn DH_set0_pqg(dh: *mut ::DH,
p: *mut ::BIGNUM,
q: *mut ::BIGNUM,
g: *mut ::BIGNUM)
-> c_int;
pub fn X509_get0_signature(
psig: *mut *const ::ASN1_BIT_STRING,
palg: *mut *const ::X509_ALGOR,
x: *const ::X509,
);
pub fn DH_set0_pqg(
dh: *mut ::DH,
p: *mut ::BIGNUM,
q: *mut ::BIGNUM,
g: *mut ::BIGNUM,
) -> c_int;
pub fn BIO_set_init(a: *mut ::BIO, init: c_int);
pub fn BIO_set_data(a: *mut ::BIO, data: *mut c_void);
pub fn BIO_get_data(a: *mut ::BIO) -> *mut c_void;
pub fn BIO_meth_new(type_: c_int, name: *const c_char) -> *mut ::BIO_METHOD;
pub fn BIO_meth_free(biom: *mut ::BIO_METHOD);
pub fn BIO_meth_set_write(biom: *mut ::BIO_METHOD,
write: unsafe extern "C" fn(*mut ::BIO, *const c_char, c_int)
-> c_int)
-> c_int;
pub fn BIO_meth_set_read(biom: *mut ::BIO_METHOD,
read: unsafe extern "C" fn(*mut ::BIO, *mut c_char, c_int) -> c_int)
-> c_int;
pub fn BIO_meth_set_puts(biom: *mut ::BIO_METHOD,
read: unsafe extern "C" fn(*mut ::BIO, *const c_char) -> c_int)
-> c_int;
pub fn BIO_meth_set_ctrl(biom: *mut ::BIO_METHOD,
read: unsafe extern "C" fn(*mut ::BIO, c_int, c_long, *mut c_void)
-> c_long)
-> c_int;
pub fn BIO_meth_set_create(biom: *mut ::BIO_METHOD,
create: unsafe extern "C" fn(*mut ::BIO) -> c_int)
-> c_int;
pub fn BIO_meth_set_destroy(biom: *mut ::BIO_METHOD,
destroy: unsafe extern "C" fn(*mut ::BIO) -> c_int)
-> c_int;
pub fn CRYPTO_get_ex_new_index(class_index: c_int,
argl: c_long,
argp: *mut c_void,
new_func: Option<::CRYPTO_EX_new>,
dup_func: Option<::CRYPTO_EX_dup>,
free_func: Option<::CRYPTO_EX_free>)
-> c_int;
pub fn BIO_meth_set_write(
biom: *mut ::BIO_METHOD,
write: unsafe extern "C" fn(*mut ::BIO, *const c_char, c_int) -> c_int,
) -> c_int;
pub fn BIO_meth_set_read(
biom: *mut ::BIO_METHOD,
read: unsafe extern "C" fn(*mut ::BIO, *mut c_char, c_int) -> c_int,
) -> c_int;
pub fn BIO_meth_set_puts(
biom: *mut ::BIO_METHOD,
read: unsafe extern "C" fn(*mut ::BIO, *const c_char) -> c_int,
) -> c_int;
pub fn BIO_meth_set_ctrl(
biom: *mut ::BIO_METHOD,
read: unsafe extern "C" fn(*mut ::BIO, c_int, c_long, *mut c_void) -> c_long,
) -> c_int;
pub fn BIO_meth_set_create(
biom: *mut ::BIO_METHOD,
create: unsafe extern "C" fn(*mut ::BIO) -> c_int,
) -> c_int;
pub fn BIO_meth_set_destroy(
biom: *mut ::BIO_METHOD,
destroy: unsafe extern "C" fn(*mut ::BIO) -> c_int,
) -> c_int;
pub fn CRYPTO_get_ex_new_index(
class_index: c_int,
argl: c_long,
argp: *mut c_void,
new_func: Option<::CRYPTO_EX_new>,
dup_func: Option<::CRYPTO_EX_dup>,
free_func: Option<::CRYPTO_EX_free>,
) -> c_int;
pub fn X509_up_ref(x: *mut X509) -> c_int;
pub fn SSL_CTX_up_ref(x: *mut SSL_CTX) -> c_int;
pub fn SSL_session_reused(ssl: *mut SSL) -> c_int;
pub fn SSL_SESSION_get_master_key(session: *const SSL_SESSION,
out: *mut c_uchar,
outlen: size_t)
-> size_t;
pub fn SSL_SESSION_get_master_key(
session: *const SSL_SESSION,
out: *mut c_uchar,
outlen: size_t,
) -> size_t;
pub fn SSL_SESSION_up_ref(ses: *mut SSL_SESSION) -> c_int;
pub fn X509_get0_extensions(req: *const ::X509) -> *const stack_st_X509_EXTENSION;
pub fn X509_STORE_CTX_get0_chain(ctx: *mut ::X509_STORE_CTX) -> *mut stack_st_X509;
@ -236,22 +261,25 @@ extern "C" {
pub fn OPENSSL_init_ssl(opts: u64, settings: *const OPENSSL_INIT_SETTINGS) -> c_int;
pub fn OPENSSL_sk_new_null() -> *mut ::OPENSSL_STACK;
pub fn OPENSSL_sk_free(st: *mut ::OPENSSL_STACK);
pub fn OPENSSL_sk_pop_free(st: *mut ::OPENSSL_STACK,
free: Option<unsafe extern "C" fn(*mut c_void)>);
pub fn OPENSSL_sk_pop_free(
st: *mut ::OPENSSL_STACK,
free: Option<unsafe extern "C" fn(*mut c_void)>,
);
pub fn OPENSSL_sk_push(st: *mut ::OPENSSL_STACK, data: *const c_void) -> c_int;
pub fn OPENSSL_sk_pop(st: *mut ::OPENSSL_STACK) -> *mut c_void;
pub fn PKCS12_create(pass: *const c_char,
friendly_name: *const c_char,
pkey: *mut EVP_PKEY,
cert: *mut X509,
ca: *mut stack_st_X509,
nid_key: c_int,
nid_cert: c_int,
iter: c_int,
mac_iter: c_int,
keytype: c_int)
-> *mut PKCS12;
pub fn PKCS12_create(
pass: *const c_char,
friendly_name: *const c_char,
pkey: *mut EVP_PKEY,
cert: *mut X509,
ca: *mut stack_st_X509,
nid_key: c_int,
nid_cert: c_int,
iter: c_int,
mac_iter: c_int,
keytype: c_int,
) -> *mut PKCS12;
pub fn X509_REQ_get_version(req: *const X509_REQ) -> c_long;
pub fn X509_REQ_get_subject_name(req: *const X509_REQ) -> *mut ::X509_NAME;
}

View File

@ -23,9 +23,11 @@ impl AesKey {
assert!(key.len() <= c_int::max_value() as usize / 8);
let mut aes_key = mem::uninitialized();
let r = ffi::AES_set_encrypt_key(key.as_ptr() as *const _,
key.len() as c_int * 8,
&mut aes_key);
let r = ffi::AES_set_encrypt_key(
key.as_ptr() as *const _,
key.len() as c_int * 8,
&mut aes_key,
);
if r == 0 {
Ok(AesKey(aes_key))
} else {
@ -44,9 +46,11 @@ impl AesKey {
assert!(key.len() <= c_int::max_value() as usize / 8);
let mut aes_key = mem::uninitialized();
let r = ffi::AES_set_decrypt_key(key.as_ptr() as *const _,
key.len() as c_int * 8,
&mut aes_key);
let r = ffi::AES_set_decrypt_key(
key.as_ptr() as *const _,
key.len() as c_int * 8,
&mut aes_key,
);
if r == 0 {
Ok(AesKey(aes_key))
@ -73,12 +77,14 @@ pub fn aes_ige(in_: &[u8], out: &mut [u8], key: &AesKey, iv: &mut [u8], mode: Mo
Mode::Encrypt => ffi::AES_ENCRYPT,
Mode::Decrypt => ffi::AES_DECRYPT,
};
ffi::AES_ige_encrypt(in_.as_ptr() as *const _,
out.as_mut_ptr() as *mut _,
in_.len(),
&key.0,
iv.as_mut_ptr() as *mut _,
mode);
ffi::AES_ige_encrypt(
in_.as_ptr() as *const _,
out.as_mut_ptr() as *mut _,
in_.len(),
&key.0,
iv.as_mut_ptr() as *mut _,
mode,
);
}
}

View File

@ -24,7 +24,10 @@ impl fmt::Display for Asn1GeneralizedTimeRef {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
unsafe {
let mem_bio = try!(MemBio::new());
try!(cvt(ffi::ASN1_GENERALIZEDTIME_print(mem_bio.as_ptr(), self.as_ptr())));
try!(cvt(ffi::ASN1_GENERALIZEDTIME_print(
mem_bio.as_ptr(),
self.as_ptr(),
)));
write!(f, "{}", str::from_utf8_unchecked(mem_bio.get_buf()))
}
}
@ -104,16 +107,11 @@ foreign_type! {
impl Asn1IntegerRef {
pub fn get(&self) -> i64 {
unsafe {
::ffi::ASN1_INTEGER_get(self.as_ptr()) as i64
}
unsafe { ::ffi::ASN1_INTEGER_get(self.as_ptr()) as i64 }
}
pub fn set(&mut self, value: i32) -> Result<(), ErrorStack>
{
unsafe {
cvt(::ffi::ASN1_INTEGER_set(self.as_ptr(), value as c_long)).map(|_| ())
}
pub fn set(&mut self, value: i32) -> Result<(), ErrorStack> {
unsafe { cvt(::ffi::ASN1_INTEGER_set(self.as_ptr(), value as c_long)).map(|_| ()) }
}
}
@ -146,9 +144,7 @@ foreign_type! {
impl Asn1ObjectRef {
/// Returns the NID associated with this OID.
pub fn nid(&self) -> Nid {
unsafe {
Nid::from_raw(ffi::OBJ_obj2nid(self.as_ptr()))
}
unsafe { Nid::from_raw(ffi::OBJ_obj2nid(self.as_ptr())) }
}
}
@ -156,10 +152,12 @@ impl fmt::Display for Asn1ObjectRef {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
unsafe {
let mut buf = [0; 80];
let len = ffi::OBJ_obj2txt(buf.as_mut_ptr() as *mut _,
buf.len() as c_int,
self.as_ptr(),
0);
let len = ffi::OBJ_obj2txt(
buf.as_mut_ptr() as *mut _,
buf.len() as c_int,
self.as_ptr(),
0,
);
let s = try!(str::from_utf8(&buf[..len as usize]).map_err(|_| fmt::Error));
fmt.write_str(s)
}

View File

@ -22,8 +22,12 @@ impl<'a> MemBioSlice<'a> {
ffi::init();
assert!(buf.len() <= c_int::max_value() as usize);
let bio =
unsafe { try!(cvt_p(BIO_new_mem_buf(buf.as_ptr() as *const _, buf.len() as c_int))) };
let bio = unsafe {
try!(cvt_p(BIO_new_mem_buf(
buf.as_ptr() as *const _,
buf.len() as c_int,
)))
};
Ok(MemBioSlice(bio, PhantomData))
}

View File

@ -23,8 +23,8 @@ use ffi::{get_rfc2409_prime_768 as BN_get_rfc2409_prime_768,
#[cfg(ossl110)]
use ffi::{BN_get_rfc2409_prime_768, BN_get_rfc2409_prime_1024, BN_get_rfc3526_prime_1536,
BN_get_rfc3526_prime_2048, BN_get_rfc3526_prime_3072, BN_get_rfc3526_prime_4096,
BN_get_rfc3526_prime_6144, BN_get_rfc3526_prime_8192};
BN_get_rfc3526_prime_2048, BN_get_rfc3526_prime_3072, BN_get_rfc3526_prime_4096,
BN_get_rfc3526_prime_6144, BN_get_rfc3526_prime_8192};
/// Options for the most significant bits of a randomly generated `BigNum`.
pub struct MsbOption(c_int);
@ -225,13 +225,25 @@ impl BigNumRef {
/// * `msb`: The desired properties of the number.
/// * `odd`: If `true`, the generated number will be odd.
pub fn rand(&mut self, bits: i32, msb: MsbOption, odd: bool) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::BN_rand(self.as_ptr(), bits.into(), msb.0, odd as c_int)).map(|_| ()) }
unsafe {
cvt(ffi::BN_rand(
self.as_ptr(),
bits.into(),
msb.0,
odd as c_int,
)).map(|_| ())
}
}
/// The cryptographically weak counterpart to `rand`.
pub fn pseudo_rand(&mut self, bits: i32, msb: MsbOption, odd: bool) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::BN_pseudo_rand(self.as_ptr(), bits.into(), msb.0, odd as c_int)).map(|_| ())
cvt(ffi::BN_pseudo_rand(
self.as_ptr(),
bits.into(),
msb.0,
odd as c_int,
)).map(|_| ())
}
}
@ -243,78 +255,94 @@ impl BigNumRef {
/// * `safe`: If true, returns a "safe" prime `p` so that `(p-1)/2` is also prime.
/// * `add`/`rem`: If `add` is set to `Some(add)`, `p % add == rem` will hold, where `p` is the
/// generated prime and `rem` is `1` if not specified (`None`).
pub fn generate_prime(&mut self,
bits: i32,
safe: bool,
add: Option<&BigNumRef>,
rem: Option<&BigNumRef>)
-> Result<(), ErrorStack> {
pub fn generate_prime(
&mut self,
bits: i32,
safe: bool,
add: Option<&BigNumRef>,
rem: Option<&BigNumRef>,
) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::BN_generate_prime_ex(self.as_ptr(),
bits as c_int,
safe as c_int,
add.map(|n| n.as_ptr()).unwrap_or(ptr::null_mut()),
rem.map(|n| n.as_ptr()).unwrap_or(ptr::null_mut()),
ptr::null_mut()))
.map(|_| ())
cvt(ffi::BN_generate_prime_ex(
self.as_ptr(),
bits as c_int,
safe as c_int,
add.map(|n| n.as_ptr()).unwrap_or(ptr::null_mut()),
rem.map(|n| n.as_ptr()).unwrap_or(ptr::null_mut()),
ptr::null_mut(),
)).map(|_| ())
}
}
/// Places the result of `a * b` in `self`.
pub fn checked_mul(&mut self,
a: &BigNumRef,
b: &BigNumRef,
ctx: &mut BigNumContextRef)
-> Result<(), ErrorStack> {
unsafe { cvt(ffi::BN_mul(self.as_ptr(), a.as_ptr(), b.as_ptr(), ctx.as_ptr())).map(|_| ()) }
pub fn checked_mul(
&mut self,
a: &BigNumRef,
b: &BigNumRef,
ctx: &mut BigNumContextRef,
) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::BN_mul(
self.as_ptr(),
a.as_ptr(),
b.as_ptr(),
ctx.as_ptr(),
)).map(|_| ())
}
}
/// Places the result of `a / b` in `self`.
pub fn checked_div(&mut self,
a: &BigNumRef,
b: &BigNumRef,
ctx: &mut BigNumContextRef)
-> Result<(), ErrorStack> {
pub fn checked_div(
&mut self,
a: &BigNumRef,
b: &BigNumRef,
ctx: &mut BigNumContextRef,
) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::BN_div(self.as_ptr(),
ptr::null_mut(),
a.as_ptr(),
b.as_ptr(),
ctx.as_ptr()))
.map(|_| ())
cvt(ffi::BN_div(
self.as_ptr(),
ptr::null_mut(),
a.as_ptr(),
b.as_ptr(),
ctx.as_ptr(),
)).map(|_| ())
}
}
/// Places the result of `a % b` in `self`.
pub fn checked_rem(&mut self,
a: &BigNumRef,
b: &BigNumRef,
ctx: &mut BigNumContextRef)
-> Result<(), ErrorStack> {
pub fn checked_rem(
&mut self,
a: &BigNumRef,
b: &BigNumRef,
ctx: &mut BigNumContextRef,
) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::BN_div(ptr::null_mut(),
self.as_ptr(),
a.as_ptr(),
b.as_ptr(),
ctx.as_ptr()))
.map(|_| ())
cvt(ffi::BN_div(
ptr::null_mut(),
self.as_ptr(),
a.as_ptr(),
b.as_ptr(),
ctx.as_ptr(),
)).map(|_| ())
}
}
/// Places the result of `a / b` in `self` and `a % b` in `rem`.
pub fn div_rem(&mut self,
rem: &mut BigNumRef,
a: &BigNumRef,
b: &BigNumRef,
ctx: &mut BigNumContextRef)
-> Result<(), ErrorStack> {
pub fn div_rem(
&mut self,
rem: &mut BigNumRef,
a: &BigNumRef,
b: &BigNumRef,
ctx: &mut BigNumContextRef,
) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::BN_div(self.as_ptr(),
rem.as_ptr(),
a.as_ptr(),
b.as_ptr(),
ctx.as_ptr()))
.map(|_| ())
cvt(ffi::BN_div(
self.as_ptr(),
rem.as_ptr(),
a.as_ptr(),
b.as_ptr(),
ctx.as_ptr(),
)).map(|_| ())
}
}
@ -324,107 +352,164 @@ impl BigNumRef {
}
/// Places the result of `a mod m` in `self`.
pub fn nnmod(&mut self,
a: &BigNumRef,
m: &BigNumRef,
ctx: &mut BigNumContextRef)
-> Result<(), ErrorStack> {
pub fn nnmod(
&mut self,
a: &BigNumRef,
m: &BigNumRef,
ctx: &mut BigNumContextRef,
) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::BN_nnmod(self.as_ptr(), a.as_ptr(), m.as_ptr(), ctx.as_ptr())).map(|_| ())
cvt(ffi::BN_nnmod(
self.as_ptr(),
a.as_ptr(),
m.as_ptr(),
ctx.as_ptr(),
)).map(|_| ())
}
}
/// Places the result of `(a + b) mod m` in `self`.
pub fn mod_add(&mut self,
a: &BigNumRef,
b: &BigNumRef,
m: &BigNumRef,
ctx: &mut BigNumContextRef)
-> Result<(), ErrorStack> {
pub fn mod_add(
&mut self,
a: &BigNumRef,
b: &BigNumRef,
m: &BigNumRef,
ctx: &mut BigNumContextRef,
) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::BN_mod_add(self.as_ptr(), a.as_ptr(), b.as_ptr(), m.as_ptr(), ctx.as_ptr()))
.map(|_| ())
cvt(ffi::BN_mod_add(
self.as_ptr(),
a.as_ptr(),
b.as_ptr(),
m.as_ptr(),
ctx.as_ptr(),
)).map(|_| ())
}
}
/// Places the result of `(a - b) mod m` in `self`.
pub fn mod_sub(&mut self,
a: &BigNumRef,
b: &BigNumRef,
m: &BigNumRef,
ctx: &mut BigNumContextRef)
-> Result<(), ErrorStack> {
pub fn mod_sub(
&mut self,
a: &BigNumRef,
b: &BigNumRef,
m: &BigNumRef,
ctx: &mut BigNumContextRef,
) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::BN_mod_sub(self.as_ptr(), a.as_ptr(), b.as_ptr(), m.as_ptr(), ctx.as_ptr()))
.map(|_| ())
cvt(ffi::BN_mod_sub(
self.as_ptr(),
a.as_ptr(),
b.as_ptr(),
m.as_ptr(),
ctx.as_ptr(),
)).map(|_| ())
}
}
/// Places the result of `(a * b) mod m` in `self`.
pub fn mod_mul(&mut self,
a: &BigNumRef,
b: &BigNumRef,
m: &BigNumRef,
ctx: &mut BigNumContextRef)
-> Result<(), ErrorStack> {
pub fn mod_mul(
&mut self,
a: &BigNumRef,
b: &BigNumRef,
m: &BigNumRef,
ctx: &mut BigNumContextRef,
) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::BN_mod_mul(self.as_ptr(), a.as_ptr(), b.as_ptr(), m.as_ptr(), ctx.as_ptr()))
.map(|_| ())
cvt(ffi::BN_mod_mul(
self.as_ptr(),
a.as_ptr(),
b.as_ptr(),
m.as_ptr(),
ctx.as_ptr(),
)).map(|_| ())
}
}
/// Places the result of `a² mod m` in `self`.
pub fn mod_sqr(&mut self,
a: &BigNumRef,
m: &BigNumRef,
ctx: &mut BigNumContextRef)
-> Result<(), ErrorStack> {
pub fn mod_sqr(
&mut self,
a: &BigNumRef,
m: &BigNumRef,
ctx: &mut BigNumContextRef,
) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::BN_mod_sqr(self.as_ptr(), a.as_ptr(), m.as_ptr(), ctx.as_ptr())).map(|_| ())
cvt(ffi::BN_mod_sqr(
self.as_ptr(),
a.as_ptr(),
m.as_ptr(),
ctx.as_ptr(),
)).map(|_| ())
}
}
/// Places the result of `a^p` in `self`.
pub fn exp(&mut self,
a: &BigNumRef,
p: &BigNumRef,
ctx: &mut BigNumContextRef)
-> Result<(), ErrorStack> {
unsafe { cvt(ffi::BN_exp(self.as_ptr(), a.as_ptr(), p.as_ptr(), ctx.as_ptr())).map(|_| ()) }
pub fn exp(
&mut self,
a: &BigNumRef,
p: &BigNumRef,
ctx: &mut BigNumContextRef,
) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::BN_exp(
self.as_ptr(),
a.as_ptr(),
p.as_ptr(),
ctx.as_ptr(),
)).map(|_| ())
}
}
/// Places the result of `a^p mod m` in `self`.
pub fn mod_exp(&mut self,
a: &BigNumRef,
p: &BigNumRef,
m: &BigNumRef,
ctx: &mut BigNumContextRef)
-> Result<(), ErrorStack> {
pub fn mod_exp(
&mut self,
a: &BigNumRef,
p: &BigNumRef,
m: &BigNumRef,
ctx: &mut BigNumContextRef,
) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::BN_mod_exp(self.as_ptr(), a.as_ptr(), p.as_ptr(), m.as_ptr(), ctx.as_ptr()))
.map(|_| ())
cvt(ffi::BN_mod_exp(
self.as_ptr(),
a.as_ptr(),
p.as_ptr(),
m.as_ptr(),
ctx.as_ptr(),
)).map(|_| ())
}
}
/// Places the inverse of `a` modulo `n` in `self`.
pub fn mod_inverse(&mut self,
a: &BigNumRef,
n: &BigNumRef,
ctx: &mut BigNumContextRef)
-> Result<(), ErrorStack> {
pub fn mod_inverse(
&mut self,
a: &BigNumRef,
n: &BigNumRef,
ctx: &mut BigNumContextRef,
) -> Result<(), ErrorStack> {
unsafe {
cvt_p(ffi::BN_mod_inverse(self.as_ptr(), a.as_ptr(), n.as_ptr(), ctx.as_ptr()))
.map(|_| ())
cvt_p(ffi::BN_mod_inverse(
self.as_ptr(),
a.as_ptr(),
n.as_ptr(),
ctx.as_ptr(),
)).map(|_| ())
}
}
/// Places the greatest common denominator of `a` and `b` in `self`.
pub fn gcd(&mut self,
a: &BigNumRef,
b: &BigNumRef,
ctx: &mut BigNumContextRef)
-> Result<(), ErrorStack> {
unsafe { cvt(ffi::BN_gcd(self.as_ptr(), a.as_ptr(), b.as_ptr(), ctx.as_ptr())).map(|_| ()) }
pub fn gcd(
&mut self,
a: &BigNumRef,
b: &BigNumRef,
ctx: &mut BigNumContextRef,
) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::BN_gcd(
self.as_ptr(),
a.as_ptr(),
b.as_ptr(),
ctx.as_ptr(),
)).map(|_| ())
}
}
/// Checks whether `self` is prime.
@ -434,8 +519,12 @@ impl BigNumRef {
/// Returns `true` if `self` is prime with an error probability of less than `0.25 ^ checks`.
pub fn is_prime(&self, checks: i32, ctx: &mut BigNumContextRef) -> Result<bool, ErrorStack> {
unsafe {
cvt_n(ffi::BN_is_prime_ex(self.as_ptr(), checks.into(), ctx.as_ptr(), ptr::null_mut()))
.map(|r| r != 0)
cvt_n(ffi::BN_is_prime_ex(
self.as_ptr(),
checks.into(),
ctx.as_ptr(),
ptr::null_mut(),
)).map(|r| r != 0)
}
}
@ -448,18 +537,20 @@ impl BigNumRef {
/// # Return Value
///
/// Returns `true` if `self` is prime with an error probability of less than `0.25 ^ checks`.
pub fn is_prime_fasttest(&self,
checks: i32,
ctx: &mut BigNumContextRef,
do_trial_division: bool)
-> Result<bool, ErrorStack> {
pub fn is_prime_fasttest(
&self,
checks: i32,
ctx: &mut BigNumContextRef,
do_trial_division: bool,
) -> Result<bool, ErrorStack> {
unsafe {
cvt_n(ffi::BN_is_prime_fasttest_ex(self.as_ptr(),
checks.into(),
ctx.as_ptr(),
do_trial_division as c_int,
ptr::null_mut()))
.map(|r| r != 0)
cvt_n(ffi::BN_is_prime_fasttest_ex(
self.as_ptr(),
checks.into(),
ctx.as_ptr(),
do_trial_division as c_int,
ptr::null_mut(),
)).map(|r| r != 0)
}
}
@ -639,8 +730,11 @@ impl BigNum {
unsafe {
ffi::init();
assert!(n.len() <= c_int::max_value() as usize);
cvt_p(ffi::BN_bin2bn(n.as_ptr(), n.len() as c_int, ptr::null_mut()))
.map(|p| BigNum::from_ptr(p))
cvt_p(ffi::BN_bin2bn(
n.as_ptr(),
n.len() as c_int,
ptr::null_mut(),
)).map(|p| BigNum::from_ptr(p))
}
}
}
@ -936,8 +1030,7 @@ mod tests {
#[test]
fn test_rand_range() {
let range = BigNum::from_u32(909829283).unwrap();
let mut result = BigNum::from_dec_str(
&range.to_dec_str().unwrap()).unwrap();
let mut result = BigNum::from_dec_str(&range.to_dec_str().unwrap()).unwrap();
range.rand_range(&mut result).unwrap();
assert!(result >= BigNum::from_u32(0).unwrap() && result < range);
}
@ -945,8 +1038,7 @@ mod tests {
#[test]
fn test_pseudo_rand_range() {
let range = BigNum::from_u32(909829283).unwrap();
let mut result = BigNum::from_dec_str(
&range.to_dec_str().unwrap()).unwrap();
let mut result = BigNum::from_dec_str(&range.to_dec_str().unwrap()).unwrap();
range.pseudo_rand_range(&mut result).unwrap();
assert!(result >= BigNum::from_u32(0).unwrap() && result < range);
}

View File

@ -26,7 +26,12 @@ impl Dh {
unsafe {
init();
let dh = Dh(try!(cvt_p(ffi::DH_new())));
try!(cvt(compat::DH_set0_pqg(dh.0, p.as_ptr(), q.as_ptr(), g.as_ptr())));
try!(cvt(compat::DH_set0_pqg(
dh.0,
p.as_ptr(),
q.as_ptr(),
g.as_ptr(),
)));
mem::forget((p, g, q));
Ok(dh)
}
@ -65,11 +70,12 @@ mod compat {
use ffi;
use libc::c_int;
pub unsafe fn DH_set0_pqg(dh: *mut ffi::DH,
p: *mut ffi::BIGNUM,
q: *mut ffi::BIGNUM,
g: *mut ffi::BIGNUM)
-> c_int {
pub unsafe fn DH_set0_pqg(
dh: *mut ffi::DH,
p: *mut ffi::BIGNUM,
q: *mut ffi::BIGNUM,
g: *mut ffi::BIGNUM,
) -> c_int {
(*dh).p = p;
(*dh).q = q;
(*dh).g = g;
@ -98,7 +104,8 @@ mod tests {
#[test]
fn test_dh() {
let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
let p = BigNum::from_hex_str("87A8E61DB4B6663CFFBBD19C651959998CEEF608660DD0F25D2CEED4435\
let p = BigNum::from_hex_str(
"87A8E61DB4B6663CFFBBD19C651959998CEEF608660DD0F25D2CEED4435\
E3B00E00DF8F1D61957D4FAF7DF4561B2AA3016C3D91134096FAA3BF429\
6D830E9A7C209E0C6497517ABD5A8A9D306BCF67ED91F9E6725B4758C02\
2E0B1EF4275BF7B6C5BFC11D45F9088B941F54EB1E59BB8BC39A0BF1230\
@ -106,9 +113,10 @@ mod tests {
A51BFA4AB3AD8347796524D8EF6A167B5A41825D967E144E5140564251C\
CACB83E6B486F6B3CA3F7971506026C0B857F689962856DED4010ABD0BE\
621C3A3960A54E710C375F26375D7014103A4B54330C198AF126116D227\
6E11715F693877FAD7EF09CADB094AE91E1A1597")
.unwrap();
let g = BigNum::from_hex_str("3FB32C9B73134D0B2E77506660EDBD484CA7B18F21EF205407F4793A1A0\
6E11715F693877FAD7EF09CADB094AE91E1A1597",
).unwrap();
let g = BigNum::from_hex_str(
"3FB32C9B73134D0B2E77506660EDBD484CA7B18F21EF205407F4793A1A0\
BA12510DBC15077BE463FFF4FED4AAC0BB555BE3A6C1B0C6B47B1BC3773\
BF7E8C6F62901228F8C28CBB18A55AE31341000A650196F931C77A57F2D\
DF463E5E9EC144B777DE62AAAB8A8628AC376D282D6ED3864E67982428E\
@ -116,11 +124,12 @@ mod tests {
FE83B9C80D052B985D182EA0ADB2A3B7313D3FE14C8484B1E052588B9B7\
D2BBD2DF016199ECD06E1557CD0915B3353BBB64E0EC377FD028370DF92\
B52C7891428CDC67EB6184B523D1DB246C32F63078490F00EF8D647D148\
D47954515E2327CFEF98C582664B4C0F6CC41659")
.unwrap();
let q = BigNum::from_hex_str("8CF83642A709A097B447997640129DA299B1A47D1EB3750BA308B0FE64F\
5FBD3")
.unwrap();
D47954515E2327CFEF98C582664B4C0F6CC41659",
).unwrap();
let q = BigNum::from_hex_str(
"8CF83642A709A097B447997640129DA299B1A47D1EB3750BA308B0FE64F\
5FBD3",
).unwrap();
let dh = Dh::from_params(p, g, q).unwrap();
ctx.set_tmp_dh(&dh).unwrap();
}

View File

@ -81,13 +81,15 @@ impl Dsa {
pub fn generate(bits: u32) -> Result<Dsa, ErrorStack> {
unsafe {
let dsa = Dsa(try!(cvt_p(ffi::DSA_new())));
try!(cvt(ffi::DSA_generate_parameters_ex(dsa.0,
bits as c_int,
ptr::null(),
0,
ptr::null_mut(),
ptr::null_mut(),
ptr::null_mut())));
try!(cvt(ffi::DSA_generate_parameters_ex(
dsa.0,
bits as c_int,
ptr::null(),
0,
ptr::null_mut(),
ptr::null_mut(),
ptr::null_mut(),
)));
try!(cvt(ffi::DSA_generate_key(dsa.0)));
Ok(dsa)
}
@ -100,7 +102,8 @@ impl Dsa {
#[deprecated(since = "0.9.2", note = "use private_key_from_pem_callback")]
pub fn private_key_from_pem_cb<F>(buf: &[u8], pass_cb: F) -> Result<Dsa, ErrorStack>
where F: FnOnce(&mut [c_char]) -> usize
where
F: FnOnce(&mut [c_char]) -> usize,
{
ffi::init();
let mut cb = CallbackState::new(pass_cb);
@ -108,10 +111,12 @@ impl Dsa {
unsafe {
let cb_ptr = &mut cb as *mut _ as *mut c_void;
let dsa = try!(cvt_p(ffi::PEM_read_bio_DSAPrivateKey(mem_bio.as_ptr(),
ptr::null_mut(),
Some(invoke_passwd_cb_old::<F>),
cb_ptr)));
let dsa = try!(cvt_p(ffi::PEM_read_bio_DSAPrivateKey(
mem_bio.as_ptr(),
ptr::null_mut(),
Some(invoke_passwd_cb_old::<F>),
cb_ptr,
)));
Ok(Dsa(dsa))
}
}
@ -174,7 +179,8 @@ mod test {
#[test]
fn test_to_password() {
let key = Dsa::generate(2048).unwrap();
let pem = key.private_key_to_pem_passphrase(Cipher::aes_128_cbc(), b"foobar").unwrap();
let pem = key.private_key_to_pem_passphrase(Cipher::aes_128_cbc(), b"foobar")
.unwrap();
Dsa::private_key_from_pem_passphrase(&pem, b"foobar").unwrap();
assert!(Dsa::private_key_from_pem_passphrase(&pem, b"fizzbuzz").is_err());
}
@ -184,11 +190,10 @@ mod test {
let mut password_queried = false;
let key = include_bytes!("../test/dsa-encrypted.pem");
Dsa::private_key_from_pem_callback(key, |password| {
password_queried = true;
password[..6].copy_from_slice(b"mypass");
Ok(6)
})
.unwrap();
password_queried = true;
password[..6].copy_from_slice(b"mypass");
Ok(6)
}).unwrap();
assert!(password_queried);
}

View File

@ -49,37 +49,41 @@ impl EcGroup {
impl EcGroupRef {
/// Places the components of a curve over a prime field in the provided `BigNum`s.
pub fn components_gfp(&self,
p: &mut BigNumRef,
a: &mut BigNumRef,
b: &mut BigNumRef,
ctx: &mut BigNumContextRef)
-> Result<(), ErrorStack> {
pub fn components_gfp(
&self,
p: &mut BigNumRef,
a: &mut BigNumRef,
b: &mut BigNumRef,
ctx: &mut BigNumContextRef,
) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::EC_GROUP_get_curve_GFp(self.as_ptr(),
p.as_ptr(),
a.as_ptr(),
b.as_ptr(),
ctx.as_ptr()))
.map(|_| ())
cvt(ffi::EC_GROUP_get_curve_GFp(
self.as_ptr(),
p.as_ptr(),
a.as_ptr(),
b.as_ptr(),
ctx.as_ptr(),
)).map(|_| ())
}
}
/// Places the components of a curve over a binary field in the provided `BigNum`s.
#[cfg(not(osslconf = "OPENSSL_NO_EC2M"))]
pub fn components_gf2m(&self,
p: &mut BigNumRef,
a: &mut BigNumRef,
b: &mut BigNumRef,
ctx: &mut BigNumContextRef)
-> Result<(), ErrorStack> {
pub fn components_gf2m(
&self,
p: &mut BigNumRef,
a: &mut BigNumRef,
b: &mut BigNumRef,
ctx: &mut BigNumContextRef,
) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::EC_GROUP_get_curve_GF2m(self.as_ptr(),
p.as_ptr(),
a.as_ptr(),
b.as_ptr(),
ctx.as_ptr()))
.map(|_| ())
cvt(ffi::EC_GROUP_get_curve_GF2m(
self.as_ptr(),
p.as_ptr(),
a.as_ptr(),
b.as_ptr(),
ctx.as_ptr(),
)).map(|_| ())
}
}
@ -89,12 +93,17 @@ impl EcGroupRef {
}
/// Places the order of the curve in the provided `BigNum`.
pub fn order(&self,
order: &mut BigNumRef,
ctx: &mut BigNumContextRef)
-> Result<(), ErrorStack> {
pub fn order(
&self,
order: &mut BigNumRef,
ctx: &mut BigNumContextRef,
) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::EC_GROUP_get_order(self.as_ptr(), order.as_ptr(), ctx.as_ptr())).map(|_| ())
cvt(ffi::EC_GROUP_get_order(
self.as_ptr(),
order.as_ptr(),
ctx.as_ptr(),
)).map(|_| ())
}
}
@ -120,106 +129,123 @@ foreign_type! {
impl EcPointRef {
/// Computes `a + b`, storing the result in `self`.
pub fn add(&mut self,
group: &EcGroupRef,
a: &EcPointRef,
b: &EcPointRef,
ctx: &mut BigNumContextRef)
-> Result<(), ErrorStack> {
pub fn add(
&mut self,
group: &EcGroupRef,
a: &EcPointRef,
b: &EcPointRef,
ctx: &mut BigNumContextRef,
) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::EC_POINT_add(group.as_ptr(),
self.as_ptr(),
a.as_ptr(),
b.as_ptr(),
ctx.as_ptr()))
.map(|_| ())
cvt(ffi::EC_POINT_add(
group.as_ptr(),
self.as_ptr(),
a.as_ptr(),
b.as_ptr(),
ctx.as_ptr(),
)).map(|_| ())
}
}
/// Computes `q * m`, storing the result in `self`.
pub fn mul(&mut self,
group: &EcGroupRef,
q: &EcPointRef,
m: &BigNumRef,
ctx: &BigNumContextRef)
-> Result<(), ErrorStack> {
pub fn mul(
&mut self,
group: &EcGroupRef,
q: &EcPointRef,
m: &BigNumRef,
ctx: &BigNumContextRef,
) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::EC_POINT_mul(group.as_ptr(),
self.as_ptr(),
ptr::null(),
q.as_ptr(),
m.as_ptr(),
ctx.as_ptr()))
.map(|_| ())
cvt(ffi::EC_POINT_mul(
group.as_ptr(),
self.as_ptr(),
ptr::null(),
q.as_ptr(),
m.as_ptr(),
ctx.as_ptr(),
)).map(|_| ())
}
}
/// Computes `generator * n`, storing the result ing `self`.
pub fn mul_generator(&mut self,
group: &EcGroupRef,
n: &BigNumRef,
ctx: &BigNumContextRef)
-> Result<(), ErrorStack> {
pub fn mul_generator(
&mut self,
group: &EcGroupRef,
n: &BigNumRef,
ctx: &BigNumContextRef,
) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::EC_POINT_mul(group.as_ptr(),
self.as_ptr(),
n.as_ptr(),
ptr::null(),
ptr::null(),
ctx.as_ptr()))
.map(|_| ())
cvt(ffi::EC_POINT_mul(
group.as_ptr(),
self.as_ptr(),
n.as_ptr(),
ptr::null(),
ptr::null(),
ctx.as_ptr(),
)).map(|_| ())
}
}
/// Computes `generator * n + q * m`, storing the result in `self`.
pub fn mul_full(&mut self,
group: &EcGroupRef,
n: &BigNumRef,
q: &EcPointRef,
m: &BigNumRef,
ctx: &mut BigNumContextRef)
-> Result<(), ErrorStack> {
pub fn mul_full(
&mut self,
group: &EcGroupRef,
n: &BigNumRef,
q: &EcPointRef,
m: &BigNumRef,
ctx: &mut BigNumContextRef,
) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::EC_POINT_mul(group.as_ptr(),
self.as_ptr(),
n.as_ptr(),
q.as_ptr(),
m.as_ptr(),
ctx.as_ptr()))
.map(|_| ())
cvt(ffi::EC_POINT_mul(
group.as_ptr(),
self.as_ptr(),
n.as_ptr(),
q.as_ptr(),
m.as_ptr(),
ctx.as_ptr(),
)).map(|_| ())
}
}
/// Inverts `self`.
pub fn invert(&mut self, group: &EcGroupRef, ctx: &BigNumContextRef) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::EC_POINT_invert(group.as_ptr(), self.as_ptr(), ctx.as_ptr())).map(|_| ())
cvt(ffi::EC_POINT_invert(
group.as_ptr(),
self.as_ptr(),
ctx.as_ptr(),
)).map(|_| ())
}
}
/// Serializes the point to a binary representation.
pub fn to_bytes(&self,
group: &EcGroupRef,
form: PointConversionForm,
ctx: &mut BigNumContextRef)
-> Result<Vec<u8>, ErrorStack> {
pub fn to_bytes(
&self,
group: &EcGroupRef,
form: PointConversionForm,
ctx: &mut BigNumContextRef,
) -> Result<Vec<u8>, ErrorStack> {
unsafe {
let len = ffi::EC_POINT_point2oct(group.as_ptr(),
self.as_ptr(),
form.0,
ptr::null_mut(),
0,
ctx.as_ptr());
let len = ffi::EC_POINT_point2oct(
group.as_ptr(),
self.as_ptr(),
form.0,
ptr::null_mut(),
0,
ctx.as_ptr(),
);
if len == 0 {
return Err(ErrorStack::get());
}
let mut buf = vec![0; len];
let len = ffi::EC_POINT_point2oct(group.as_ptr(),
self.as_ptr(),
form.0,
buf.as_mut_ptr(),
len,
ctx.as_ptr());
let len = ffi::EC_POINT_point2oct(
group.as_ptr(),
self.as_ptr(),
form.0,
buf.as_mut_ptr(),
len,
ctx.as_ptr(),
);
if len == 0 {
Err(ErrorStack::get())
} else {
@ -229,16 +255,19 @@ impl EcPointRef {
}
/// Determines if this point is equal to another.
pub fn eq(&self,
group: &EcGroupRef,
other: &EcPointRef,
ctx: &mut BigNumContextRef)
-> Result<bool, ErrorStack> {
pub fn eq(
&self,
group: &EcGroupRef,
other: &EcPointRef,
ctx: &mut BigNumContextRef,
) -> Result<bool, ErrorStack> {
unsafe {
let res = try!(cvt_n(ffi::EC_POINT_cmp(group.as_ptr(),
self.as_ptr(),
other.as_ptr(),
ctx.as_ptr())));
let res = try!(cvt_n(ffi::EC_POINT_cmp(
group.as_ptr(),
self.as_ptr(),
other.as_ptr(),
ctx.as_ptr(),
)));
Ok(res == 0)
}
}
@ -250,17 +279,20 @@ impl EcPoint {
unsafe { cvt_p(ffi::EC_POINT_new(group.as_ptr())).map(EcPoint) }
}
pub fn from_bytes(group: &EcGroupRef,
buf: &[u8],
ctx: &mut BigNumContextRef)
-> Result<EcPoint, ErrorStack> {
pub fn from_bytes(
group: &EcGroupRef,
buf: &[u8],
ctx: &mut BigNumContextRef,
) -> Result<EcPoint, ErrorStack> {
let point = try!(EcPoint::new(group));
unsafe {
try!(cvt(ffi::EC_POINT_oct2point(group.as_ptr(),
point.as_ptr(),
buf.as_ptr(),
buf.len(),
ctx.as_ptr())));
try!(cvt(ffi::EC_POINT_oct2point(
group.as_ptr(),
point.as_ptr(),
buf.as_ptr(),
buf.len(),
ctx.as_ptr(),
)));
}
Ok(point)
}
@ -354,7 +386,10 @@ impl EcKey {
/// let point = EcPoint::from_bytes(&group, &public_key, &mut ctx).unwrap();
/// let key = EcKey::from_public_key(&group, &point);
/// ```
pub fn from_public_key(group: &EcGroupRef, public_key: &EcPointRef) -> Result<EcKey, ErrorStack> {
pub fn from_public_key(
group: &EcGroupRef,
public_key: &EcPointRef,
) -> Result<EcKey, ErrorStack> {
let mut builder = try!(EcKeyBuilder::new());
try!(builder.set_group(group));
try!(builder.set_public_key(public_key));
@ -406,23 +441,23 @@ impl EcKeyBuilder {
impl EcKeyBuilderRef {
pub fn set_group(&mut self, group: &EcGroupRef) -> Result<&mut EcKeyBuilderRef, ErrorStack> {
unsafe {
cvt(ffi::EC_KEY_set_group(self.as_ptr(), group.as_ptr())).map(|_| self)
}
unsafe { cvt(ffi::EC_KEY_set_group(self.as_ptr(), group.as_ptr())).map(|_| self) }
}
pub fn set_public_key(&mut self,
public_key: &EcPointRef)
-> Result<&mut EcKeyBuilderRef, ErrorStack> {
pub fn set_public_key(
&mut self,
public_key: &EcPointRef,
) -> Result<&mut EcKeyBuilderRef, ErrorStack> {
unsafe {
cvt(ffi::EC_KEY_set_public_key(self.as_ptr(), public_key.as_ptr())).map(|_| self)
cvt(ffi::EC_KEY_set_public_key(
self.as_ptr(),
public_key.as_ptr(),
)).map(|_| self)
}
}
pub fn generate_key(&mut self) -> Result<&mut EcKeyBuilderRef, ErrorStack> {
unsafe {
cvt(ffi::EC_KEY_generate_key(self.as_ptr())).map(|_| self)
}
unsafe { cvt(ffi::EC_KEY_generate_key(self.as_ptr())).map(|_| self) }
}
}
@ -464,7 +499,9 @@ mod test {
let key = EcKey::generate(&group).unwrap();
let point = key.public_key().unwrap();
let mut ctx = BigNumContext::new().unwrap();
let bytes = point.to_bytes(&group, POINT_CONVERSION_COMPRESSED, &mut ctx).unwrap();
let bytes = point
.to_bytes(&group, POINT_CONVERSION_COMPRESSED, &mut ctx)
.unwrap();
let point2 = EcPoint::from_bytes(&group, &bytes, &mut ctx).unwrap();
assert!(point.eq(&group, &point2, &mut ctx).unwrap());
}
@ -475,8 +512,14 @@ mod test {
let key = EcKey::generate(&group).unwrap();
let mut ctx = BigNumContext::new().unwrap();
let mut public_key = EcPoint::new(&group).unwrap();
public_key.mul_generator(&group, key.private_key().unwrap(), &mut ctx).unwrap();
assert!(public_key.eq(&group, key.public_key().unwrap(), &mut ctx).unwrap());
public_key
.mul_generator(&group, key.private_key().unwrap(), &mut ctx)
.unwrap();
assert!(
public_key
.eq(&group, key.public_key().unwrap(), &mut ctx)
.unwrap()
);
}
#[test]
@ -484,7 +527,10 @@ mod test {
let group = EcGroup::from_curve_name(nid::X9_62_PRIME256V1).unwrap();
let key = EcKey::generate(&group).unwrap();
let mut ctx = BigNumContext::new().unwrap();
let bytes = key.public_key().unwrap().to_bytes(&group, POINT_CONVERSION_COMPRESSED, &mut ctx).unwrap();
let bytes = key.public_key()
.unwrap()
.to_bytes(&group, POINT_CONVERSION_COMPRESSED, &mut ctx)
.unwrap();
drop(key);
let public_key = EcPoint::from_bytes(&group, &bytes, &mut ctx).unwrap();

View File

@ -210,7 +210,13 @@ impl fmt::Display for Error {
Some(r) => try!(write!(fmt, ":{}", r)),
None => try!(write!(fmt, ":reason({})", ffi::ERR_GET_FUNC(self.code()))),
}
write!(fmt, ":{}:{}:{}", self.file(), self.line(), self.data().unwrap_or(""))
write!(
fmt,
":{}:{}:{}",
self.file(),
self.line(),
self.data().unwrap_or("")
)
}
}

View File

@ -137,7 +137,11 @@ impl Hasher {
try!(self.init());
}
unsafe {
try!(cvt(ffi::EVP_DigestUpdate(self.ctx, data.as_ptr() as *mut _, data.len())));
try!(cvt(ffi::EVP_DigestUpdate(
self.ctx,
data.as_ptr() as *mut _,
data.len(),
)));
}
self.state = Updated;
Ok(())
@ -158,7 +162,11 @@ impl Hasher {
unsafe {
let mut len = ffi::EVP_MAX_MD_SIZE;
let mut buf = [0; ffi::EVP_MAX_MD_SIZE as usize];
try!(cvt(ffi::EVP_DigestFinal_ex(self.ctx, buf.as_mut_ptr(), &mut len)));
try!(cvt(ffi::EVP_DigestFinal_ex(
self.ctx,
buf.as_mut_ptr(),
&mut len,
)));
self.state = Finalized;
Ok(DigestBytes {
buf: buf,
@ -290,19 +298,24 @@ mod tests {
// Test vectors from http://www.nsrl.nist.gov/testdata/
#[allow(non_upper_case_globals)]
const md5_tests: [(&'static str, &'static str); 13] =
[("", "d41d8cd98f00b204e9800998ecf8427e"),
("7F", "83acb6e67e50e31db6ed341dd2de1595"),
("EC9C", "0b07f0d4ca797d8ac58874f887cb0b68"),
("FEE57A", "e0d583171eb06d56198fc0ef22173907"),
("42F497E0", "7c430f178aefdf1487fee7144e9641e2"),
("C53B777F1C", "75ef141d64cb37ec423da2d9d440c925"),
("89D5B576327B", "ebbaf15eb0ed784c6faa9dc32831bf33"),
("5D4CCE781EB190", "ce175c4b08172019f05e6b5279889f2c"),
("81901FE94932D7B9", "cd4d2f62b8cdb3a0cf968a735a239281"),
("C9FFDEE7788EFB4EC9", "e0841a231ab698db30c6c0f3f246c014"),
("66AC4B7EBA95E53DC10B", "a3b3cea71910d9af56742aa0bb2fe329"),
("A510CD18F7A56852EB0319", "577e216843dd11573574d3fb209b97d8"),
("AAED18DBE8938C19ED734A8D", "6f80fb775f27e0a4ce5c2f42fc72c5f1")];
[
("", "d41d8cd98f00b204e9800998ecf8427e"),
("7F", "83acb6e67e50e31db6ed341dd2de1595"),
("EC9C", "0b07f0d4ca797d8ac58874f887cb0b68"),
("FEE57A", "e0d583171eb06d56198fc0ef22173907"),
("42F497E0", "7c430f178aefdf1487fee7144e9641e2"),
("C53B777F1C", "75ef141d64cb37ec423da2d9d440c925"),
("89D5B576327B", "ebbaf15eb0ed784c6faa9dc32831bf33"),
("5D4CCE781EB190", "ce175c4b08172019f05e6b5279889f2c"),
("81901FE94932D7B9", "cd4d2f62b8cdb3a0cf968a735a239281"),
("C9FFDEE7788EFB4EC9", "e0841a231ab698db30c6c0f3f246c014"),
("66AC4B7EBA95E53DC10B", "a3b3cea71910d9af56742aa0bb2fe329"),
("A510CD18F7A56852EB0319", "577e216843dd11573574d3fb209b97d8"),
(
"AAED18DBE8938C19ED734A8D",
"6f80fb775f27e0a4ce5c2f42fc72c5f1",
),
];
#[test]
fn test_md5() {
@ -322,7 +335,8 @@ mod tests {
#[test]
fn test_finish_twice() {
let mut h = Hasher::new(MessageDigest::md5()).unwrap();
h.write_all(&Vec::from_hex(md5_tests[6].0).unwrap()).unwrap();
h.write_all(&Vec::from_hex(md5_tests[6].0).unwrap())
.unwrap();
h.finish2().unwrap();
let res = h.finish2().unwrap();
let null = hash2(MessageDigest::md5(), &[]).unwrap();
@ -353,7 +367,8 @@ mod tests {
println!("Clone a finished hasher");
let mut h3 = h1.clone();
h3.write_all(&Vec::from_hex(md5_tests[i + 1].0).unwrap()).unwrap();
h3.write_all(&Vec::from_hex(md5_tests[i + 1].0).unwrap())
.unwrap();
let res = h3.finish2().unwrap();
assert_eq!(res.to_hex(), md5_tests[i + 1].1);
}
@ -369,8 +384,12 @@ mod tests {
#[test]
fn test_sha256() {
let tests = [("616263",
"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad")];
let tests = [
(
"616263",
"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad",
),
];
for test in tests.iter() {
hash_test(MessageDigest::sha256(), test);

View File

@ -13,9 +13,11 @@ use ffi;
pub fn eq(a: &[u8], b: &[u8]) -> bool {
assert!(a.len() == b.len());
let ret = unsafe {
ffi::CRYPTO_memcmp(a.as_ptr() as *const _,
b.as_ptr() as *const _,
a.len() as size_t)
ffi::CRYPTO_memcmp(
a.as_ptr() as *const _,
b.as_ptr() as *const _,
a.len() as size_t,
)
};
ret == 0
}

View File

@ -126,11 +126,12 @@ impl<'a> Status<'a> {
/// very old responses.
pub fn check_validity(&self, nsec: u32, maxsec: Option<u32>) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::OCSP_check_validity(self.this_update.as_ptr(),
self.next_update.as_ptr(),
nsec as c_long,
maxsec.map(|n| n as c_long).unwrap_or(-1)))
.map(|_| ())
cvt(ffi::OCSP_check_validity(
self.this_update.as_ptr(),
self.next_update.as_ptr(),
nsec as c_long,
maxsec.map(|n| n as c_long).unwrap_or(-1),
)).map(|_| ())
}
}
}
@ -148,14 +149,19 @@ impl OcspBasicResponseRef {
///
/// The `certs` parameter contains a set of certificates that will be searched when locating the
/// OCSP response signing certificate. Some responders do not include this in the response.
pub fn verify(&self,
certs: &StackRef<X509>,
store: &X509StoreRef,
flags: Flag)
-> Result<(), ErrorStack> {
pub fn verify(
&self,
certs: &StackRef<X509>,
store: &X509StoreRef,
flags: Flag,
) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::OCSP_basic_verify(self.as_ptr(), certs.as_ptr(), store.as_ptr(), flags.bits()))
.map(|_| ())
cvt(ffi::OCSP_basic_verify(
self.as_ptr(),
certs.as_ptr(),
store.as_ptr(),
flags.bits(),
)).map(|_| ())
}
}
@ -168,13 +174,15 @@ impl OcspBasicResponseRef {
let mut this_update = ptr::null_mut();
let mut next_update = ptr::null_mut();
let r = ffi::OCSP_resp_find_status(self.as_ptr(),
id.as_ptr(),
&mut status,
&mut reason,
&mut revocation_time,
&mut this_update,
&mut next_update);
let r = ffi::OCSP_resp_find_status(
self.as_ptr(),
id.as_ptr(),
&mut status,
&mut reason,
&mut revocation_time,
&mut this_update,
&mut next_update,
);
if r == 1 {
let revocation_time = if revocation_time.is_null() {
None
@ -205,13 +213,17 @@ foreign_type! {
impl OcspCertId {
/// Constructs a certificate ID for certificate `subject`.
pub fn from_cert(digest: MessageDigest,
subject: &X509Ref,
issuer: &X509Ref)
-> Result<OcspCertId, ErrorStack> {
pub fn from_cert(
digest: MessageDigest,
subject: &X509Ref,
issuer: &X509Ref,
) -> Result<OcspCertId, ErrorStack> {
unsafe {
cvt_p(ffi::OCSP_cert_to_id(digest.as_ptr(), subject.as_ptr(), issuer.as_ptr()))
.map(OcspCertId)
cvt_p(ffi::OCSP_cert_to_id(
digest.as_ptr(),
subject.as_ptr(),
issuer.as_ptr(),
)).map(OcspCertId)
}
}
}
@ -228,15 +240,17 @@ impl OcspResponse {
/// Creates an OCSP response from the status and optional body.
///
/// A body should only be provided if `status` is `RESPONSE_STATUS_SUCCESSFUL`.
pub fn create(status: OcspResponseStatus,
body: Option<&OcspBasicResponseRef>)
-> Result<OcspResponse, ErrorStack> {
pub fn create(
status: OcspResponseStatus,
body: Option<&OcspBasicResponseRef>,
) -> Result<OcspResponse, ErrorStack> {
unsafe {
ffi::init();
cvt_p(ffi::OCSP_response_create(status.as_raw(),
body.map(|r| r.as_ptr()).unwrap_or(ptr::null_mut())))
.map(OcspResponse)
cvt_p(ffi::OCSP_response_create(
status.as_raw(),
body.map(|r| r.as_ptr()).unwrap_or(ptr::null_mut()),
)).map(OcspResponse)
}
}
@ -248,18 +262,14 @@ impl OcspResponseRef {
/// Returns the status of the response.
pub fn status(&self) -> OcspResponseStatus {
unsafe {
OcspResponseStatus(ffi::OCSP_response_status(self.as_ptr()))
}
unsafe { OcspResponseStatus(ffi::OCSP_response_status(self.as_ptr())) }
}
/// Returns the basic response.
///
/// This will only succeed if `status()` returns `RESPONSE_STATUS_SUCCESSFUL`.
pub fn basic(&self) -> Result<OcspBasicResponse, ErrorStack> {
unsafe {
cvt_p(ffi::OCSP_response_get1_basic(self.as_ptr())).map(OcspBasicResponse)
}
unsafe { cvt_p(ffi::OCSP_response_get1_basic(self.as_ptr())).map(OcspBasicResponse) }
}
}

View File

@ -34,11 +34,13 @@ impl Pkcs12Ref {
let mut cert = ptr::null_mut();
let mut chain = ptr::null_mut();
try!(cvt(ffi::PKCS12_parse(self.as_ptr(),
pass.as_ptr(),
&mut pkey,
&mut cert,
&mut chain)));
try!(cvt(ffi::PKCS12_parse(
self.as_ptr(),
pass.as_ptr(),
&mut pkey,
&mut cert,
&mut chain,
)));
let pkey = PKey::from_ptr(pkey);
let cert = X509::from_ptr(cert);
@ -140,17 +142,21 @@ impl Pkcs12Builder {
/// * `friendly_name` - user defined name for the certificate
/// * `pkey` - key to store
/// * `cert` - certificate to store
pub fn build(self,
password: &str,
friendly_name: &str,
pkey: &PKeyRef,
cert: &X509) -> Result<Pkcs12, ErrorStack> {
pub fn build(
self,
password: &str,
friendly_name: &str,
pkey: &PKeyRef,
cert: &X509,
) -> Result<Pkcs12, ErrorStack> {
unsafe {
let pass = CString::new(password).unwrap();
let friendly_name = CString::new(friendly_name).unwrap();
let pkey = pkey.as_ptr();
let cert = cert.as_ptr();
let ca = self.ca.as_ref().map(|ca| ca.as_ptr()).unwrap_or(ptr::null_mut());
let ca = self.ca.as_ref().map(|ca| ca.as_ptr()).unwrap_or(
ptr::null_mut(),
);
let nid_key = self.nid_key.as_raw();
let nid_cert = self.nid_cert.as_raw();
@ -159,17 +165,18 @@ impl Pkcs12Builder {
// https://www.openssl.org/docs/man1.0.2/crypto/PKCS12_create.html
let keytype = 0;
cvt_p(ffi::PKCS12_create(pass.as_ptr() as *const _ as *mut _,
friendly_name.as_ptr() as *const _ as *mut _,
pkey,
cert,
ca,
nid_key,
nid_cert,
self.iter,
self.mac_iter,
keytype))
.map(Pkcs12)
cvt_p(ffi::PKCS12_create(
pass.as_ptr() as *const _ as *mut _,
friendly_name.as_ptr() as *const _ as *mut _,
pkey,
cert,
ca,
nid_key,
nid_cert,
self.iter,
self.mac_iter,
keytype,
)).map(Pkcs12)
}
}
}
@ -194,12 +201,23 @@ mod test {
let pkcs12 = Pkcs12::from_der(der).unwrap();
let parsed = pkcs12.parse("mypass").unwrap();
assert_eq!(parsed.cert.fingerprint(MessageDigest::sha1()).unwrap().to_hex(),
"59172d9313e84459bcff27f967e79e6e9217e584");
assert_eq!(
parsed
.cert
.fingerprint(MessageDigest::sha1())
.unwrap()
.to_hex(),
"59172d9313e84459bcff27f967e79e6e9217e584"
);
assert_eq!(parsed.chain.len(), 1);
assert_eq!(parsed.chain[0].fingerprint(MessageDigest::sha1()).unwrap().to_hex(),
"c0cbdf7cdd03c9773e5468e1f6d2da7d5cbb1875");
assert_eq!(
parsed.chain[0]
.fingerprint(MessageDigest::sha1())
.unwrap()
.to_hex(),
"c0cbdf7cdd03c9773e5468e1f6d2da7d5cbb1875"
);
}
#[test]
@ -219,15 +237,20 @@ mod test {
let pkey = PKey::from_rsa(rsa).unwrap();
let mut name = X509Name::builder().unwrap();
name.append_entry_by_nid(nid::COMMONNAME, subject_name).unwrap();
name.append_entry_by_nid(nid::COMMONNAME, subject_name)
.unwrap();
let name = name.build();
let key_usage = KeyUsage::new().digital_signature().build().unwrap();;
let key_usage = KeyUsage::new().digital_signature().build().unwrap();
let mut builder = X509::builder().unwrap();
builder.set_version(2).unwrap();
builder.set_not_before(&Asn1Time::days_from_now(0).unwrap()).unwrap();
builder.set_not_after(&Asn1Time::days_from_now(365).unwrap()).unwrap();
builder
.set_not_before(&Asn1Time::days_from_now(0).unwrap())
.unwrap();
builder
.set_not_after(&Asn1Time::days_from_now(365).unwrap())
.unwrap();
builder.set_subject_name(&name).unwrap();
builder.set_issuer_name(&name).unwrap();
builder.append_extension(key_usage).unwrap();
@ -236,13 +259,18 @@ mod test {
let cert = builder.build();
let pkcs12_builder = Pkcs12::builder();
let pkcs12 = pkcs12_builder.build("mypass", subject_name, &pkey, &cert).unwrap();
let pkcs12 = pkcs12_builder
.build("mypass", subject_name, &pkey, &cert)
.unwrap();
let der = pkcs12.to_der().unwrap();
let pkcs12 = Pkcs12::from_der(&der).unwrap();
let parsed = pkcs12.parse("mypass").unwrap();
assert_eq!(parsed.cert.fingerprint(MessageDigest::sha1()).unwrap(), cert.fingerprint(MessageDigest::sha1()).unwrap());
assert_eq!(
parsed.cert.fingerprint(MessageDigest::sha1()).unwrap(),
cert.fingerprint(MessageDigest::sha1()).unwrap()
);
assert!(parsed.pkey.public_eq(&pkey));
}
}

View File

@ -23,12 +23,13 @@ pub struct KeyIvPair {
///
/// New applications should not use this and instead use
/// `pbkdf2_hmac` or another more modern key derivation algorithm.
pub fn bytes_to_key(cipher: Cipher,
digest: MessageDigest,
data: &[u8],
salt: Option<&[u8]>,
count: i32)
-> Result<KeyIvPair, ErrorStack> {
pub fn bytes_to_key(
cipher: Cipher,
digest: MessageDigest,
data: &[u8],
salt: Option<&[u8]>,
count: i32,
) -> Result<KeyIvPair, ErrorStack> {
unsafe {
assert!(data.len() <= c_int::max_value() as usize);
let salt_ptr = match salt {
@ -46,53 +47,61 @@ pub fn bytes_to_key(cipher: Cipher,
let cipher = cipher.as_ptr();
let digest = digest.as_ptr();
let len = try!(cvt(ffi::EVP_BytesToKey(cipher,
digest,
salt_ptr,
ptr::null(),
data.len() as c_int,
count.into(),
ptr::null_mut(),
ptr::null_mut())));
let len = try!(cvt(ffi::EVP_BytesToKey(
cipher,
digest,
salt_ptr,
ptr::null(),
data.len() as c_int,
count.into(),
ptr::null_mut(),
ptr::null_mut(),
)));
let mut key = vec![0; len as usize];
let iv_ptr = iv.as_mut().map(|v| v.as_mut_ptr()).unwrap_or(ptr::null_mut());
let iv_ptr = iv.as_mut().map(|v| v.as_mut_ptr()).unwrap_or(
ptr::null_mut(),
);
try!(cvt(ffi::EVP_BytesToKey(cipher,
digest,
salt_ptr,
data.as_ptr(),
data.len() as c_int,
count as c_int,
key.as_mut_ptr(),
iv_ptr)));
try!(cvt(ffi::EVP_BytesToKey(
cipher,
digest,
salt_ptr,
data.as_ptr(),
data.len() as c_int,
count as c_int,
key.as_mut_ptr(),
iv_ptr,
)));
Ok(KeyIvPair { key: key, iv: iv })
}
}
/// Derives a key from a password and salt using the PBKDF2-HMAC algorithm with a digest function.
pub fn pbkdf2_hmac(pass: &[u8],
salt: &[u8],
iter: usize,
hash: MessageDigest,
key: &mut [u8])
-> Result<(), ErrorStack> {
pub fn pbkdf2_hmac(
pass: &[u8],
salt: &[u8],
iter: usize,
hash: MessageDigest,
key: &mut [u8],
) -> Result<(), ErrorStack> {
unsafe {
assert!(pass.len() <= c_int::max_value() as usize);
assert!(salt.len() <= c_int::max_value() as usize);
assert!(key.len() <= c_int::max_value() as usize);
ffi::init();
cvt(ffi::PKCS5_PBKDF2_HMAC(pass.as_ptr() as *const _,
pass.len() as c_int,
salt.as_ptr(),
salt.len() as c_int,
iter as c_int,
hash.as_ptr(),
key.len() as c_int,
key.as_mut_ptr()))
.map(|_| ())
cvt(ffi::PKCS5_PBKDF2_HMAC(
pass.as_ptr() as *const _,
pass.len() as c_int,
salt.as_ptr(),
salt.len() as c_int,
iter as c_int,
hash.as_ptr(),
key.len() as c_int,
key.as_mut_ptr(),
)).map(|_| ())
}
}
@ -100,27 +109,29 @@ pub fn pbkdf2_hmac(pass: &[u8],
///
/// Requires the `v110` feature and OpenSSL 1.1.0.
#[cfg(all(feature = "v110", ossl110))]
pub fn scrypt(pass: &[u8],
salt: &[u8],
n: u64,
r: u64,
p: u64,
maxmem: u64,
key: &mut [u8])
-> Result<(), ErrorStack> {
pub fn scrypt(
pass: &[u8],
salt: &[u8],
n: u64,
r: u64,
p: u64,
maxmem: u64,
key: &mut [u8],
) -> Result<(), ErrorStack> {
unsafe {
ffi::init();
cvt(ffi::EVP_PBE_scrypt(pass.as_ptr() as *const _,
pass.len(),
salt.as_ptr() as *const _,
salt.len(),
n,
r,
p,
maxmem,
key.as_mut_ptr() as *mut _,
key.len()))
.map(|_| ())
cvt(ffi::EVP_PBE_scrypt(
pass.as_ptr() as *const _,
pass.len(),
salt.as_ptr() as *const _,
salt.len(),
n,
r,
p,
maxmem,
key.as_mut_ptr() as *mut _,
key.len(),
)).map(|_| ())
}
}
@ -136,21 +147,58 @@ mod tests {
let mut buf = [0; 16];
super::pbkdf2_hmac(b"passwd", b"salt", 1, MessageDigest::sha256(), &mut buf).unwrap();
assert_eq!(buf,
&[0x55_u8, 0xac_u8, 0x04_u8, 0x6e_u8, 0x56_u8, 0xe3_u8, 0x08_u8, 0x9f_u8,
0xec_u8, 0x16_u8, 0x91_u8, 0xc2_u8, 0x25_u8, 0x44_u8, 0xb6_u8, 0x05_u8]
[..]);
assert_eq!(
buf,
&[
0x55_u8,
0xac_u8,
0x04_u8,
0x6e_u8,
0x56_u8,
0xe3_u8,
0x08_u8,
0x9f_u8,
0xec_u8,
0x16_u8,
0x91_u8,
0xc2_u8,
0x25_u8,
0x44_u8,
0xb6_u8,
0x05_u8,
]
[..]
);
super::pbkdf2_hmac(b"Password",
b"NaCl",
80000,
MessageDigest::sha256(),
&mut buf)
.unwrap();
assert_eq!(buf,
&[0x4d_u8, 0xdc_u8, 0xd8_u8, 0xf6_u8, 0x0b_u8, 0x98_u8, 0xbe_u8, 0x21_u8,
0x83_u8, 0x0c_u8, 0xee_u8, 0x5e_u8, 0xf2_u8, 0x27_u8, 0x01_u8, 0xf9_u8]
[..]);
super::pbkdf2_hmac(
b"Password",
b"NaCl",
80000,
MessageDigest::sha256(),
&mut buf,
).unwrap();
assert_eq!(
buf,
&[
0x4d_u8,
0xdc_u8,
0xd8_u8,
0xf6_u8,
0x0b_u8,
0x98_u8,
0xbe_u8,
0x21_u8,
0x83_u8,
0x0c_u8,
0xee_u8,
0x5e_u8,
0xf2_u8,
0x27_u8,
0x01_u8,
0xf9_u8,
]
[..]
);
}
// Test vectors from
@ -160,80 +208,341 @@ mod tests {
let mut buf = [0; 64];
super::pbkdf2_hmac(b"password", b"NaCL", 1, MessageDigest::sha512(), &mut buf).unwrap();
assert_eq!(&buf[..],
&[0x73_u8, 0xde_u8, 0xcf_u8, 0xa5_u8, 0x8a_u8, 0xa2_u8, 0xe8_u8, 0x4f_u8,
0x94_u8, 0x77_u8, 0x1a_u8, 0x75_u8, 0x73_u8, 0x6b_u8, 0xb8_u8, 0x8b_u8,
0xd3_u8, 0xc7_u8, 0xb3_u8, 0x82_u8, 0x70_u8, 0xcf_u8, 0xb5_u8, 0x0c_u8,
0xb3_u8, 0x90_u8, 0xed_u8, 0x78_u8, 0xb3_u8, 0x05_u8, 0x65_u8, 0x6a_u8,
0xf8_u8, 0x14_u8, 0x8e_u8, 0x52_u8, 0x45_u8, 0x2b_u8, 0x22_u8, 0x16_u8,
0xb2_u8, 0xb8_u8, 0x09_u8, 0x8b_u8, 0x76_u8, 0x1f_u8, 0xc6_u8, 0x33_u8,
0x60_u8, 0x60_u8, 0xa0_u8, 0x9f_u8, 0x76_u8, 0x41_u8, 0x5e_u8, 0x9f_u8,
0x71_u8, 0xea_u8, 0x47_u8, 0xf9_u8, 0xe9_u8, 0x06_u8, 0x43_u8, 0x06_u8]
[..]);
assert_eq!(
&buf[..],
&[
0x73_u8,
0xde_u8,
0xcf_u8,
0xa5_u8,
0x8a_u8,
0xa2_u8,
0xe8_u8,
0x4f_u8,
0x94_u8,
0x77_u8,
0x1a_u8,
0x75_u8,
0x73_u8,
0x6b_u8,
0xb8_u8,
0x8b_u8,
0xd3_u8,
0xc7_u8,
0xb3_u8,
0x82_u8,
0x70_u8,
0xcf_u8,
0xb5_u8,
0x0c_u8,
0xb3_u8,
0x90_u8,
0xed_u8,
0x78_u8,
0xb3_u8,
0x05_u8,
0x65_u8,
0x6a_u8,
0xf8_u8,
0x14_u8,
0x8e_u8,
0x52_u8,
0x45_u8,
0x2b_u8,
0x22_u8,
0x16_u8,
0xb2_u8,
0xb8_u8,
0x09_u8,
0x8b_u8,
0x76_u8,
0x1f_u8,
0xc6_u8,
0x33_u8,
0x60_u8,
0x60_u8,
0xa0_u8,
0x9f_u8,
0x76_u8,
0x41_u8,
0x5e_u8,
0x9f_u8,
0x71_u8,
0xea_u8,
0x47_u8,
0xf9_u8,
0xe9_u8,
0x06_u8,
0x43_u8,
0x06_u8,
]
[..]
);
super::pbkdf2_hmac(b"pass\0word",
b"sa\0lt",
1,
MessageDigest::sha512(),
&mut buf)
.unwrap();
assert_eq!(&buf[..],
&[0x71_u8, 0xa0_u8, 0xec_u8, 0x84_u8, 0x2a_u8, 0xbd_u8, 0x5c_u8, 0x67_u8,
0x8b_u8, 0xcf_u8, 0xd1_u8, 0x45_u8, 0xf0_u8, 0x9d_u8, 0x83_u8, 0x52_u8,
0x2f_u8, 0x93_u8, 0x36_u8, 0x15_u8, 0x60_u8, 0x56_u8, 0x3c_u8, 0x4d_u8,
0x0d_u8, 0x63_u8, 0xb8_u8, 0x83_u8, 0x29_u8, 0x87_u8, 0x10_u8, 0x90_u8,
0xe7_u8, 0x66_u8, 0x04_u8, 0xa4_u8, 0x9a_u8, 0xf0_u8, 0x8f_u8, 0xe7_u8,
0xc9_u8, 0xf5_u8, 0x71_u8, 0x56_u8, 0xc8_u8, 0x79_u8, 0x09_u8, 0x96_u8,
0xb2_u8, 0x0f_u8, 0x06_u8, 0xbc_u8, 0x53_u8, 0x5e_u8, 0x5a_u8, 0xb5_u8,
0x44_u8, 0x0d_u8, 0xf7_u8, 0xe8_u8, 0x78_u8, 0x29_u8, 0x6f_u8, 0xa7_u8]
[..]);
super::pbkdf2_hmac(
b"pass\0word",
b"sa\0lt",
1,
MessageDigest::sha512(),
&mut buf,
).unwrap();
assert_eq!(
&buf[..],
&[
0x71_u8,
0xa0_u8,
0xec_u8,
0x84_u8,
0x2a_u8,
0xbd_u8,
0x5c_u8,
0x67_u8,
0x8b_u8,
0xcf_u8,
0xd1_u8,
0x45_u8,
0xf0_u8,
0x9d_u8,
0x83_u8,
0x52_u8,
0x2f_u8,
0x93_u8,
0x36_u8,
0x15_u8,
0x60_u8,
0x56_u8,
0x3c_u8,
0x4d_u8,
0x0d_u8,
0x63_u8,
0xb8_u8,
0x83_u8,
0x29_u8,
0x87_u8,
0x10_u8,
0x90_u8,
0xe7_u8,
0x66_u8,
0x04_u8,
0xa4_u8,
0x9a_u8,
0xf0_u8,
0x8f_u8,
0xe7_u8,
0xc9_u8,
0xf5_u8,
0x71_u8,
0x56_u8,
0xc8_u8,
0x79_u8,
0x09_u8,
0x96_u8,
0xb2_u8,
0x0f_u8,
0x06_u8,
0xbc_u8,
0x53_u8,
0x5e_u8,
0x5a_u8,
0xb5_u8,
0x44_u8,
0x0d_u8,
0xf7_u8,
0xe8_u8,
0x78_u8,
0x29_u8,
0x6f_u8,
0xa7_u8,
]
[..]
);
super::pbkdf2_hmac(b"passwordPASSWORDpassword",
b"salt\0\0\0",
50,
MessageDigest::sha512(),
&mut buf)
.unwrap();
assert_eq!(&buf[..],
&[0x01_u8, 0x68_u8, 0x71_u8, 0xa4_u8, 0xc4_u8, 0xb7_u8, 0x5f_u8, 0x96_u8,
0x85_u8, 0x7f_u8, 0xd2_u8, 0xb9_u8, 0xf8_u8, 0xca_u8, 0x28_u8, 0x02_u8,
0x3b_u8, 0x30_u8, 0xee_u8, 0x2a_u8, 0x39_u8, 0xf5_u8, 0xad_u8, 0xca_u8,
0xc8_u8, 0xc9_u8, 0x37_u8, 0x5f_u8, 0x9b_u8, 0xda_u8, 0x1c_u8, 0xcd_u8,
0x1b_u8, 0x6f_u8, 0x0b_u8, 0x2f_u8, 0xc3_u8, 0xad_u8, 0xda_u8, 0x50_u8,
0x54_u8, 0x12_u8, 0xe7_u8, 0x9d_u8, 0x89_u8, 0x00_u8, 0x56_u8, 0xc6_u8,
0x2e_u8, 0x52_u8, 0x4c_u8, 0x7d_u8, 0x51_u8, 0x15_u8, 0x4b_u8, 0x1a_u8,
0x85_u8, 0x34_u8, 0x57_u8, 0x5b_u8, 0xd0_u8, 0x2d_u8, 0xee_u8, 0x39_u8]
[..]);
super::pbkdf2_hmac(
b"passwordPASSWORDpassword",
b"salt\0\0\0",
50,
MessageDigest::sha512(),
&mut buf,
).unwrap();
assert_eq!(
&buf[..],
&[
0x01_u8,
0x68_u8,
0x71_u8,
0xa4_u8,
0xc4_u8,
0xb7_u8,
0x5f_u8,
0x96_u8,
0x85_u8,
0x7f_u8,
0xd2_u8,
0xb9_u8,
0xf8_u8,
0xca_u8,
0x28_u8,
0x02_u8,
0x3b_u8,
0x30_u8,
0xee_u8,
0x2a_u8,
0x39_u8,
0xf5_u8,
0xad_u8,
0xca_u8,
0xc8_u8,
0xc9_u8,
0x37_u8,
0x5f_u8,
0x9b_u8,
0xda_u8,
0x1c_u8,
0xcd_u8,
0x1b_u8,
0x6f_u8,
0x0b_u8,
0x2f_u8,
0xc3_u8,
0xad_u8,
0xda_u8,
0x50_u8,
0x54_u8,
0x12_u8,
0xe7_u8,
0x9d_u8,
0x89_u8,
0x00_u8,
0x56_u8,
0xc6_u8,
0x2e_u8,
0x52_u8,
0x4c_u8,
0x7d_u8,
0x51_u8,
0x15_u8,
0x4b_u8,
0x1a_u8,
0x85_u8,
0x34_u8,
0x57_u8,
0x5b_u8,
0xd0_u8,
0x2d_u8,
0xee_u8,
0x39_u8,
]
[..]
);
}
#[test]
fn bytes_to_key() {
let salt = [16_u8, 34_u8, 19_u8, 23_u8, 141_u8, 4_u8, 207_u8, 221_u8];
let data = [143_u8, 210_u8, 75_u8, 63_u8, 214_u8, 179_u8, 155_u8, 241_u8, 242_u8, 31_u8,
154_u8, 56_u8, 198_u8, 145_u8, 192_u8, 64_u8, 2_u8, 245_u8, 167_u8, 220_u8,
55_u8, 119_u8, 233_u8, 136_u8, 139_u8, 27_u8, 71_u8, 242_u8, 119_u8, 175_u8,
65_u8, 207_u8];
let data = [
143_u8,
210_u8,
75_u8,
63_u8,
214_u8,
179_u8,
155_u8,
241_u8,
242_u8,
31_u8,
154_u8,
56_u8,
198_u8,
145_u8,
192_u8,
64_u8,
2_u8,
245_u8,
167_u8,
220_u8,
55_u8,
119_u8,
233_u8,
136_u8,
139_u8,
27_u8,
71_u8,
242_u8,
119_u8,
175_u8,
65_u8,
207_u8,
];
let expected_key = vec![249_u8, 115_u8, 114_u8, 97_u8, 32_u8, 213_u8, 165_u8, 146_u8,
58_u8, 87_u8, 234_u8, 3_u8, 43_u8, 250_u8, 97_u8, 114_u8, 26_u8,
98_u8, 245_u8, 246_u8, 238_u8, 177_u8, 229_u8, 161_u8, 183_u8,
224_u8, 174_u8, 3_u8, 6_u8, 244_u8, 236_u8, 255_u8];
let expected_iv = vec![4_u8, 223_u8, 153_u8, 219_u8, 28_u8, 142_u8, 234_u8, 68_u8, 227_u8,
69_u8, 98_u8, 107_u8, 208_u8, 14_u8, 236_u8, 60_u8];
let expected_key = vec![
249_u8,
115_u8,
114_u8,
97_u8,
32_u8,
213_u8,
165_u8,
146_u8,
58_u8,
87_u8,
234_u8,
3_u8,
43_u8,
250_u8,
97_u8,
114_u8,
26_u8,
98_u8,
245_u8,
246_u8,
238_u8,
177_u8,
229_u8,
161_u8,
183_u8,
224_u8,
174_u8,
3_u8,
6_u8,
244_u8,
236_u8,
255_u8,
];
let expected_iv = vec![
4_u8,
223_u8,
153_u8,
219_u8,
28_u8,
142_u8,
234_u8,
68_u8,
227_u8,
69_u8,
98_u8,
107_u8,
208_u8,
14_u8,
236_u8,
60_u8,
];
assert_eq!(super::bytes_to_key(Cipher::aes_256_cbc(),
MessageDigest::sha1(),
&data,
Some(&salt),
1)
.unwrap(),
super::KeyIvPair {
key: expected_key,
iv: Some(expected_iv),
});
assert_eq!(
super::bytes_to_key(
Cipher::aes_256_cbc(),
MessageDigest::sha1(),
&data,
Some(&salt),
1,
).unwrap(),
super::KeyIvPair {
key: expected_key,
iv: Some(expected_iv),
}
);
}
#[test]
@ -247,7 +556,15 @@ mod tests {
f0fcf62d49705242a9af9e61e85dc0d651e40dfcf017b45575887";
let mut actual = [0; 64];
super::scrypt(pass.as_bytes(), salt.as_bytes(), 16384, 8, 1, 0, &mut actual).unwrap();
super::scrypt(
pass.as_bytes(),
salt.as_bytes(),
16384,
8,
1,
0,
&mut actual,
).unwrap();
assert_eq!((&actual[..]).to_hex(), expected);
}
}

View File

@ -84,7 +84,11 @@ impl PKey {
unsafe {
let evp = try!(cvt_p(ffi::EVP_PKEY_new()));
let pkey = PKey(evp);
try!(cvt(ffi::EVP_PKEY_assign(pkey.0, ffi::EVP_PKEY_RSA, rsa.as_ptr() as *mut _)));
try!(cvt(ffi::EVP_PKEY_assign(
pkey.0,
ffi::EVP_PKEY_RSA,
rsa.as_ptr() as *mut _,
)));
mem::forget(rsa);
Ok(pkey)
}
@ -95,7 +99,11 @@ impl PKey {
unsafe {
let evp = try!(cvt_p(ffi::EVP_PKEY_new()));
let pkey = PKey(evp);
try!(cvt(ffi::EVP_PKEY_assign(pkey.0, ffi::EVP_PKEY_DSA, dsa.as_ptr() as *mut _)));
try!(cvt(ffi::EVP_PKEY_assign(
pkey.0,
ffi::EVP_PKEY_DSA,
dsa.as_ptr() as *mut _,
)));
mem::forget(dsa);
Ok(pkey)
}
@ -106,7 +114,11 @@ impl PKey {
unsafe {
let evp = try!(cvt_p(ffi::EVP_PKEY_new()));
let pkey = PKey(evp);
try!(cvt(ffi::EVP_PKEY_assign(pkey.0, ffi::EVP_PKEY_DH, dh.as_ptr() as *mut _)));
try!(cvt(ffi::EVP_PKEY_assign(
pkey.0,
ffi::EVP_PKEY_DH,
dh.as_ptr() as *mut _,
)));
mem::forget(dh);
Ok(pkey)
}
@ -117,7 +129,11 @@ impl PKey {
unsafe {
let evp = try!(cvt_p(ffi::EVP_PKEY_new()));
let pkey = PKey(evp);
try!(cvt(ffi::EVP_PKEY_assign(pkey.0, ffi::EVP_PKEY_EC, ec_key.as_ptr() as *mut _)));
try!(cvt(ffi::EVP_PKEY_assign(
pkey.0,
ffi::EVP_PKEY_EC,
ec_key.as_ptr() as *mut _,
)));
mem::forget(ec_key);
Ok(pkey)
}
@ -130,10 +146,12 @@ impl PKey {
pub fn hmac(key: &[u8]) -> Result<PKey, ErrorStack> {
unsafe {
assert!(key.len() <= c_int::max_value() as usize);
let key = try!(cvt_p(ffi::EVP_PKEY_new_mac_key(ffi::EVP_PKEY_HMAC,
ptr::null_mut(),
key.as_ptr() as *const _,
key.len() as c_int)));
let key = try!(cvt_p(ffi::EVP_PKEY_new_mac_key(
ffi::EVP_PKEY_HMAC,
ptr::null_mut(),
key.as_ptr() as *const _,
key.len() as c_int,
)));
Ok(PKey(key))
}
}
@ -149,17 +167,19 @@ impl PKey {
/// The callback should copy the password into the provided buffer and return the number of
/// bytes written.
pub fn private_key_from_pkcs8_callback<F>(der: &[u8], callback: F) -> Result<PKey, ErrorStack>
where F: FnOnce(&mut [u8]) -> Result<usize, ErrorStack>
where
F: FnOnce(&mut [u8]) -> Result<usize, ErrorStack>,
{
unsafe {
ffi::init();
let mut cb = CallbackState::new(callback);
let bio = try!(MemBioSlice::new(der));
cvt_p(ffi::d2i_PKCS8PrivateKey_bio(bio.as_ptr(),
ptr::null_mut(),
Some(invoke_passwd_cb::<F>),
&mut cb as *mut _ as *mut _))
.map(PKey)
cvt_p(ffi::d2i_PKCS8PrivateKey_bio(
bio.as_ptr(),
ptr::null_mut(),
Some(invoke_passwd_cb::<F>),
&mut cb as *mut _ as *mut _,
)).map(PKey)
}
}
@ -169,33 +189,38 @@ impl PKey {
/// # Panics
///
/// Panics if `passphrase` contains an embedded null.
pub fn private_key_from_pkcs8_passphrase(der: &[u8],
passphrase: &[u8])
-> Result<PKey, ErrorStack> {
pub fn private_key_from_pkcs8_passphrase(
der: &[u8],
passphrase: &[u8],
) -> Result<PKey, ErrorStack> {
unsafe {
ffi::init();
let bio = try!(MemBioSlice::new(der));
let passphrase = CString::new(passphrase).unwrap();
cvt_p(ffi::d2i_PKCS8PrivateKey_bio(bio.as_ptr(),
ptr::null_mut(),
None,
passphrase.as_ptr() as *const _ as *mut _))
.map(PKey)
cvt_p(ffi::d2i_PKCS8PrivateKey_bio(
bio.as_ptr(),
ptr::null_mut(),
None,
passphrase.as_ptr() as *const _ as *mut _,
)).map(PKey)
}
}
#[deprecated(since = "0.9.2", note = "use private_key_from_pem_callback")]
pub fn private_key_from_pem_cb<F>(buf: &[u8], pass_cb: F) -> Result<PKey, ErrorStack>
where F: FnOnce(&mut [c_char]) -> usize
where
F: FnOnce(&mut [c_char]) -> usize,
{
ffi::init();
let mut cb = CallbackState::new(pass_cb);
let mem_bio = try!(MemBioSlice::new(buf));
unsafe {
let evp = try!(cvt_p(ffi::PEM_read_bio_PrivateKey(mem_bio.as_ptr(),
ptr::null_mut(),
Some(invoke_passwd_cb_old::<F>),
&mut cb as *mut _ as *mut c_void)));
let evp = try!(cvt_p(ffi::PEM_read_bio_PrivateKey(
mem_bio.as_ptr(),
ptr::null_mut(),
Some(invoke_passwd_cb_old::<F>),
&mut cb as *mut _ as *mut c_void,
)));
Ok(PKey::from_ptr(evp))
}
}
@ -224,7 +249,10 @@ impl PKeyCtx {
impl PKeyCtxRef {
pub fn set_rsa_padding(&mut self, pad: Padding) -> Result<(), ErrorStack> {
unsafe {
try!(cvt(ffi::EVP_PKEY_CTX_set_rsa_padding(self.as_ptr(), pad.as_raw())));
try!(cvt(ffi::EVP_PKEY_CTX_set_rsa_padding(
self.as_ptr(),
pad.as_raw(),
)));
}
Ok(())
}
@ -232,7 +260,9 @@ impl PKeyCtxRef {
pub fn rsa_padding(&self) -> Result<Padding, ErrorStack> {
let mut pad: c_int = 0;
unsafe {
try!(cvt(ffi::EVP_PKEY_CTX_get_rsa_padding(self.as_ptr(), &mut pad)));
try!(cvt(
ffi::EVP_PKEY_CTX_get_rsa_padding(self.as_ptr(), &mut pad),
));
};
Ok(Padding::from_raw(pad))
}
@ -246,17 +276,31 @@ impl PKeyCtxRef {
pub fn derive_set_peer(&mut self, peer: &PKeyRef) -> Result<(), ErrorStack> {
unsafe {
try!(cvt(ffi::EVP_PKEY_derive_set_peer(self.as_ptr(), peer.as_ptr())));
try!(cvt(
ffi::EVP_PKEY_derive_set_peer(self.as_ptr(), peer.as_ptr()),
));
}
Ok(())
}
pub fn derive(&mut self) -> Result<Vec<u8>, ErrorStack> {
let mut len: size_t = 0;
unsafe { try!(cvt(ffi::EVP_PKEY_derive(self.as_ptr(), ptr::null_mut(), &mut len))); }
unsafe {
try!(cvt(ffi::EVP_PKEY_derive(
self.as_ptr(),
ptr::null_mut(),
&mut len,
)));
}
let mut key = vec![0u8; len];
unsafe { try!(cvt(ffi::EVP_PKEY_derive(self.as_ptr(), key.as_mut_ptr(), &mut len))); }
unsafe {
try!(cvt(ffi::EVP_PKEY_derive(
self.as_ptr(),
key.as_mut_ptr(),
&mut len,
)));
}
Ok(key)
}
}
@ -276,7 +320,8 @@ mod tests {
fn test_to_password() {
let rsa = Rsa::generate(2048).unwrap();
let pkey = PKey::from_rsa(rsa).unwrap();
let pem = pkey.private_key_to_pem_passphrase(Cipher::aes_128_cbc(), b"foobar").unwrap();
let pem = pkey.private_key_to_pem_passphrase(Cipher::aes_128_cbc(), b"foobar")
.unwrap();
PKey::private_key_from_pem_passphrase(&pem, b"foobar").unwrap();
assert!(PKey::private_key_from_pem_passphrase(&pem, b"fizzbuzz").is_err());
}
@ -292,11 +337,10 @@ mod tests {
let mut password_queried = false;
let key = include_bytes!("../test/pkcs8.der");
PKey::private_key_from_pkcs8_callback(key, |password| {
password_queried = true;
password[..6].copy_from_slice(b"mypass");
Ok(6)
})
.unwrap();
password_queried = true;
password[..6].copy_from_slice(b"mypass");
Ok(6)
}).unwrap();
assert!(password_queried);
}

View File

@ -45,8 +45,11 @@ impl RsaRef {
private_key_to_der!(ffi::i2d_RSAPrivateKey);
public_key_to_der!(ffi::i2d_RSA_PUBKEY);
to_der_inner!(/// Serializes the public key to DER-encoded PKCS#1.
public_key_to_der_pkcs1, ffi::i2d_RSAPublicKey);
to_der_inner!(
/// Serializes the public key to DER-encoded PKCS#1.
public_key_to_der_pkcs1,
ffi::i2d_RSAPublicKey
);
// FIXME should return u32
pub fn size(&self) -> usize {
@ -63,21 +66,24 @@ impl RsaRef {
///
/// Panics if `self` has no private components, or if `to` is smaller
/// than `self.size()`.
pub fn private_decrypt(&self,
from: &[u8],
to: &mut [u8],
padding: Padding)
-> Result<usize, ErrorStack> {
pub fn private_decrypt(
&self,
from: &[u8],
to: &mut [u8],
padding: Padding,
) -> Result<usize, ErrorStack> {
assert!(self.d().is_some(), "private components missing");
assert!(from.len() <= i32::max_value() as usize);
assert!(to.len() >= self.size());
unsafe {
let len = try!(cvt_n(ffi::RSA_private_decrypt(from.len() as c_int,
from.as_ptr(),
to.as_mut_ptr(),
self.as_ptr(),
padding.0)));
let len = try!(cvt_n(ffi::RSA_private_decrypt(
from.len() as c_int,
from.as_ptr(),
to.as_mut_ptr(),
self.as_ptr(),
padding.0,
)));
Ok(len as usize)
}
}
@ -88,21 +94,24 @@ impl RsaRef {
///
/// Panics if `self` has no private components, or if `to` is smaller
/// than `self.size()`.
pub fn private_encrypt(&self,
from: &[u8],
to: &mut [u8],
padding: Padding)
-> Result<usize, ErrorStack> {
pub fn private_encrypt(
&self,
from: &[u8],
to: &mut [u8],
padding: Padding,
) -> Result<usize, ErrorStack> {
assert!(self.d().is_some(), "private components missing");
assert!(from.len() <= i32::max_value() as usize);
assert!(to.len() >= self.size());
unsafe {
let len = try!(cvt_n(ffi::RSA_private_encrypt(from.len() as c_int,
from.as_ptr(),
to.as_mut_ptr(),
self.as_ptr(),
padding.0)));
let len = try!(cvt_n(ffi::RSA_private_encrypt(
from.len() as c_int,
from.as_ptr(),
to.as_mut_ptr(),
self.as_ptr(),
padding.0,
)));
Ok(len as usize)
}
}
@ -112,20 +121,23 @@ impl RsaRef {
/// # Panics
///
/// Panics if `to` is smaller than `self.size()`.
pub fn public_decrypt(&self,
from: &[u8],
to: &mut [u8],
padding: Padding)
-> Result<usize, ErrorStack> {
pub fn public_decrypt(
&self,
from: &[u8],
to: &mut [u8],
padding: Padding,
) -> Result<usize, ErrorStack> {
assert!(from.len() <= i32::max_value() as usize);
assert!(to.len() >= self.size());
unsafe {
let len = try!(cvt_n(ffi::RSA_public_decrypt(from.len() as c_int,
from.as_ptr(),
to.as_mut_ptr(),
self.as_ptr(),
padding.0)));
let len = try!(cvt_n(ffi::RSA_public_decrypt(
from.len() as c_int,
from.as_ptr(),
to.as_mut_ptr(),
self.as_ptr(),
padding.0,
)));
Ok(len as usize)
}
}
@ -135,20 +147,23 @@ impl RsaRef {
/// # Panics
///
/// Panics if `to` is smaller than `self.size()`.
pub fn public_encrypt(&self,
from: &[u8],
to: &mut [u8],
padding: Padding)
-> Result<usize, ErrorStack> {
pub fn public_encrypt(
&self,
from: &[u8],
to: &mut [u8],
padding: Padding,
) -> Result<usize, ErrorStack> {
assert!(from.len() <= i32::max_value() as usize);
assert!(to.len() >= self.size());
unsafe {
let len = try!(cvt_n(ffi::RSA_public_encrypt(from.len() as c_int,
from.as_ptr(),
to.as_mut_ptr(),
self.as_ptr(),
padding.0)));
let len = try!(cvt_n(ffi::RSA_public_encrypt(
from.len() as c_int,
from.as_ptr(),
to.as_mut_ptr(),
self.as_ptr(),
padding.0,
)));
Ok(len as usize)
}
}
@ -215,32 +230,41 @@ impl Rsa {
pub fn from_public_components(n: BigNum, e: BigNum) -> Result<Rsa, ErrorStack> {
unsafe {
let rsa = Rsa(try!(cvt_p(ffi::RSA_new())));
try!(cvt(compat::set_key(rsa.0,
n.as_ptr(),
e.as_ptr(),
ptr::null_mut())));
try!(cvt(compat::set_key(
rsa.0,
n.as_ptr(),
e.as_ptr(),
ptr::null_mut(),
)));
mem::forget((n, e));
Ok(rsa)
}
}
pub fn from_private_components(n: BigNum,
e: BigNum,
d: BigNum,
p: BigNum,
q: BigNum,
dp: BigNum,
dq: BigNum,
qi: BigNum)
-> Result<Rsa, ErrorStack> {
pub fn from_private_components(
n: BigNum,
e: BigNum,
d: BigNum,
p: BigNum,
q: BigNum,
dp: BigNum,
dq: BigNum,
qi: BigNum,
) -> Result<Rsa, ErrorStack> {
unsafe {
let rsa = Rsa(try!(cvt_p(ffi::RSA_new())));
try!(cvt(compat::set_key(rsa.0, n.as_ptr(), e.as_ptr(), d.as_ptr())));
try!(cvt(
compat::set_key(rsa.0, n.as_ptr(), e.as_ptr(), d.as_ptr()),
));
mem::forget((n, e, d));
try!(cvt(compat::set_factors(rsa.0, p.as_ptr(), q.as_ptr())));
mem::forget((p, q));
try!(cvt(compat::set_crt_params(rsa.0, dp.as_ptr(), dq.as_ptr(),
qi.as_ptr())));
try!(cvt(compat::set_crt_params(
rsa.0,
dp.as_ptr(),
dq.as_ptr(),
qi.as_ptr(),
)));
mem::forget((dp, dq, qi));
Ok(rsa)
}
@ -254,7 +278,12 @@ impl Rsa {
unsafe {
let rsa = Rsa(try!(cvt_p(ffi::RSA_new())));
let e = try!(BigNum::from_u32(ffi::RSA_F4 as u32));
try!(cvt(ffi::RSA_generate_key_ex(rsa.0, bits as c_int, e.as_ptr(), ptr::null_mut())));
try!(cvt(ffi::RSA_generate_key_ex(
rsa.0,
bits as c_int,
e.as_ptr(),
ptr::null_mut(),
)));
Ok(rsa)
}
}
@ -265,12 +294,17 @@ impl Rsa {
public_key_from_pem!(Rsa, ffi::PEM_read_bio_RSA_PUBKEY);
public_key_from_der!(Rsa, ffi::d2i_RSA_PUBKEY);
from_der_inner!(/// Deserializes a public key from DER-encoded PKCS#1 data.
public_key_from_der_pkcs1, Rsa, ffi::d2i_RSAPublicKey);
from_der_inner!(
/// Deserializes a public key from DER-encoded PKCS#1 data.
public_key_from_der_pkcs1,
Rsa,
ffi::d2i_RSAPublicKey
);
#[deprecated(since = "0.9.2", note = "use private_key_from_pem_callback")]
pub fn private_key_from_pem_cb<F>(buf: &[u8], pass_cb: F) -> Result<Rsa, ErrorStack>
where F: FnOnce(&mut [c_char]) -> usize
where
F: FnOnce(&mut [c_char]) -> usize,
{
ffi::init();
let mut cb = CallbackState::new(pass_cb);
@ -278,10 +312,12 @@ impl Rsa {
unsafe {
let cb_ptr = &mut cb as *mut _ as *mut c_void;
let rsa = try!(cvt_p(ffi::PEM_read_bio_RSAPrivateKey(mem_bio.as_ptr(),
ptr::null_mut(),
Some(invoke_passwd_cb_old::<F>),
cb_ptr)));
let rsa = try!(cvt_p(ffi::PEM_read_bio_RSAPrivateKey(
mem_bio.as_ptr(),
ptr::null_mut(),
Some(invoke_passwd_cb_old::<F>),
cb_ptr,
)));
Ok(Rsa(rsa))
}
}
@ -320,11 +356,12 @@ mod compat {
ffi::RSA_set0_factors(r, p, q)
}
pub unsafe fn set_crt_params(r: *mut RSA,
dmp1: *mut BIGNUM,
dmq1: *mut BIGNUM,
iqmp: *mut BIGNUM)
-> c_int {
pub unsafe fn set_crt_params(
r: *mut RSA,
dmp1: *mut BIGNUM,
dmq1: *mut BIGNUM,
iqmp: *mut BIGNUM,
) -> c_int {
ffi::RSA_set0_crt_params(r, dmp1, dmq1, iqmp)
}
}
@ -355,11 +392,12 @@ mod compat {
1 // TODO: is this right? should it be 0? what's success?
}
pub unsafe fn set_crt_params(r: *mut RSA,
dmp1: *mut BIGNUM,
dmq1: *mut BIGNUM,
iqmp: *mut BIGNUM)
-> c_int {
pub unsafe fn set_crt_params(
r: *mut RSA,
dmp1: *mut BIGNUM,
dmq1: *mut BIGNUM,
iqmp: *mut BIGNUM,
) -> c_int {
(*r).dmp1 = dmp1;
(*r).dmq1 = dmq1;
(*r).iqmp = iqmp;
@ -384,11 +422,10 @@ mod test {
let mut password_queried = false;
let key = include_bytes!("../test/rsa-encrypted.pem");
Rsa::private_key_from_pem_callback(key, |password| {
password_queried = true;
password[..6].copy_from_slice(b"mypass");
Ok(6)
})
.unwrap();
password_queried = true;
password[..6].copy_from_slice(b"mypass");
Ok(6)
}).unwrap();
assert!(password_queried);
}
@ -396,7 +433,8 @@ mod test {
#[test]
fn test_to_password() {
let key = Rsa::generate(2048).unwrap();
let pem = key.private_key_to_pem_passphrase(Cipher::aes_128_cbc(), b"foobar").unwrap();
let pem = key.private_key_to_pem_passphrase(Cipher::aes_128_cbc(), b"foobar")
.unwrap();
Rsa::private_key_from_pem_passphrase(&pem, b"foobar").unwrap();
assert!(Rsa::private_key_from_pem_passphrase(&pem, b"fizzbuzz").is_err());
}
@ -408,13 +446,17 @@ mod test {
let mut result = vec![0; public_key.size()];
let original_data = b"This is test";
let len = public_key.public_encrypt(original_data, &mut result, PKCS1_PADDING).unwrap();
let len = public_key
.public_encrypt(original_data, &mut result, PKCS1_PADDING)
.unwrap();
assert_eq!(len, 256);
let pkey = include_bytes!("../test/rsa.pem");
let private_key = Rsa::private_key_from_pem(pkey).unwrap();
let mut dec_result = vec![0; private_key.size()];
let len = private_key.private_decrypt(&result, &mut dec_result, PKCS1_PADDING).unwrap();
let len = private_key
.private_decrypt(&result, &mut dec_result, PKCS1_PADDING)
.unwrap();
assert_eq!(&dec_result[..len], original_data);
}
@ -430,7 +472,8 @@ mod test {
let mut emesg = vec![0; k0.size()];
k0.private_encrypt(&msg, &mut emesg, PKCS1_PADDING).unwrap();
let mut dmesg = vec![0; k1.size()];
let len = k1.public_decrypt(&emesg, &mut dmesg, PKCS1_PADDING).unwrap();
let len = k1.public_decrypt(&emesg, &mut dmesg, PKCS1_PADDING)
.unwrap();
assert_eq!(msg, &dmesg[..len]);
}
@ -445,7 +488,8 @@ mod test {
let mut emesg = vec![0; k0.size()];
k0.public_encrypt(&msg, &mut emesg, PKCS1_PADDING).unwrap();
let mut dmesg = vec![0; k1.size()];
let len = k1.private_decrypt(&emesg, &mut dmesg, PKCS1_PADDING).unwrap();
let len = k1.private_decrypt(&emesg, &mut dmesg, PKCS1_PADDING)
.unwrap();
assert_eq!(msg, &dmesg[..len]);
}
}

View File

@ -99,11 +99,13 @@ impl<'a> Signer<'a> {
let ctx = try!(cvt_p(EVP_MD_CTX_new()));
let mut pctx: *mut ffi::EVP_PKEY_CTX = ptr::null_mut();
let r = ffi::EVP_DigestSignInit(ctx,
&mut pctx,
type_.as_ptr(),
ptr::null_mut(),
pkey.as_ptr());
let r = ffi::EVP_DigestSignInit(
ctx,
&mut pctx,
type_.as_ptr(),
ptr::null_mut(),
pkey.as_ptr(),
);
if r != 1 {
EVP_MD_CTX_free(ctx);
return Err(ErrorStack::get());
@ -129,16 +131,28 @@ impl<'a> Signer<'a> {
pub fn update(&mut self, buf: &[u8]) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::EVP_DigestUpdate(self.md_ctx, buf.as_ptr() as *const _, buf.len())).map(|_| ())
cvt(ffi::EVP_DigestUpdate(
self.md_ctx,
buf.as_ptr() as *const _,
buf.len(),
)).map(|_| ())
}
}
pub fn finish(&self) -> Result<Vec<u8>, ErrorStack> {
unsafe {
let mut len = 0;
try!(cvt(ffi::EVP_DigestSignFinal(self.md_ctx, ptr::null_mut(), &mut len)));
try!(cvt(ffi::EVP_DigestSignFinal(
self.md_ctx,
ptr::null_mut(),
&mut len,
)));
let mut buf = vec![0; len];
try!(cvt(ffi::EVP_DigestSignFinal(self.md_ctx, buf.as_mut_ptr() as *mut _, &mut len)));
try!(cvt(ffi::EVP_DigestSignFinal(
self.md_ctx,
buf.as_mut_ptr() as *mut _,
&mut len,
)));
// The advertised length is not always equal to the real length for things like DSA
buf.truncate(len);
Ok(buf)
@ -179,11 +193,13 @@ impl<'a> Verifier<'a> {
let ctx = try!(cvt_p(EVP_MD_CTX_new()));
let mut pctx: *mut ffi::EVP_PKEY_CTX = ptr::null_mut();
let r = ffi::EVP_DigestVerifyInit(ctx,
&mut pctx,
type_.as_ptr(),
ptr::null_mut(),
pkey.as_ptr());
let r = ffi::EVP_DigestVerifyInit(
ctx,
&mut pctx,
type_.as_ptr(),
ptr::null_mut(),
pkey.as_ptr(),
);
if r != 1 {
EVP_MD_CTX_free(ctx);
return Err(ErrorStack::get());
@ -209,13 +225,18 @@ impl<'a> Verifier<'a> {
pub fn update(&mut self, buf: &[u8]) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::EVP_DigestUpdate(self.md_ctx, buf.as_ptr() as *const _, buf.len())).map(|_| ())
cvt(ffi::EVP_DigestUpdate(
self.md_ctx,
buf.as_ptr() as *const _,
buf.len(),
)).map(|_| ())
}
}
pub fn finish(&self, signature: &[u8]) -> Result<bool, ErrorStack> {
unsafe {
let r = EVP_DigestVerifyFinal(self.md_ctx, signature.as_ptr() as *const _, signature.len());
let r =
EVP_DigestVerifyFinal(self.md_ctx, signature.as_ptr() as *const _, signature.len());
match r {
1 => Ok(true),
0 => {
@ -244,10 +265,11 @@ use ffi::EVP_DigestVerifyFinal;
#[cfg(ossl101)]
#[allow(bad_style)]
unsafe fn EVP_DigestVerifyFinal(ctx: *mut ffi::EVP_MD_CTX,
sigret: *const ::libc::c_uchar,
siglen: ::libc::size_t)
-> ::libc::c_int {
unsafe fn EVP_DigestVerifyFinal(
ctx: *mut ffi::EVP_MD_CTX,
sigret: *const ::libc::c_uchar,
siglen: ::libc::size_t,
) -> ::libc::c_int {
ffi::EVP_DigestVerifyFinal(ctx, sigret as *mut _, siglen)
}
@ -264,29 +286,382 @@ mod test {
use dsa::Dsa;
use pkey::PKey;
static INPUT: &'static [u8] =
&[101, 121, 74, 104, 98, 71, 99, 105, 79, 105, 74, 83, 85, 122, 73, 49, 78, 105, 74, 57,
46, 101, 121, 74, 112, 99, 51, 77, 105, 79, 105, 74, 113, 98, 50, 85, 105, 76, 65, 48,
75, 73, 67, 74, 108, 101, 72, 65, 105, 79, 106, 69, 122, 77, 68, 65, 52, 77, 84, 107,
122, 79, 68, 65, 115, 68, 81, 111, 103, 73, 109, 104, 48, 100, 72, 65, 54, 76, 121, 57,
108, 101, 71, 70, 116, 99, 71, 120, 108, 76, 109, 78, 118, 98, 83, 57, 112, 99, 49, 57,
121, 98, 50, 57, 48, 73, 106, 112, 48, 99, 110, 86, 108, 102, 81];
static INPUT: &'static [u8] = &[
101,
121,
74,
104,
98,
71,
99,
105,
79,
105,
74,
83,
85,
122,
73,
49,
78,
105,
74,
57,
46,
101,
121,
74,
112,
99,
51,
77,
105,
79,
105,
74,
113,
98,
50,
85,
105,
76,
65,
48,
75,
73,
67,
74,
108,
101,
72,
65,
105,
79,
106,
69,
122,
77,
68,
65,
52,
77,
84,
107,
122,
79,
68,
65,
115,
68,
81,
111,
103,
73,
109,
104,
48,
100,
72,
65,
54,
76,
121,
57,
108,
101,
71,
70,
116,
99,
71,
120,
108,
76,
109,
78,
118,
98,
83,
57,
112,
99,
49,
57,
121,
98,
50,
57,
48,
73,
106,
112,
48,
99,
110,
86,
108,
102,
81,
];
static SIGNATURE: &'static [u8] =
&[112, 46, 33, 137, 67, 232, 143, 209, 30, 181, 216, 45, 191, 120, 69, 243, 65, 6, 174,
27, 129, 255, 247, 115, 17, 22, 173, 209, 113, 125, 131, 101, 109, 66, 10, 253, 60, 150,
238, 221, 115, 162, 102, 62, 81, 102, 104, 123, 0, 11, 135, 34, 110, 1, 135, 237, 16,
115, 249, 69, 229, 130, 173, 252, 239, 22, 216, 90, 121, 142, 232, 198, 109, 219, 61,
184, 151, 91, 23, 208, 148, 2, 190, 237, 213, 217, 217, 112, 7, 16, 141, 178, 129, 96,
213, 248, 4, 12, 167, 68, 87, 98, 184, 31, 190, 127, 249, 217, 46, 10, 231, 111, 36,
242, 91, 51, 187, 230, 244, 74, 230, 30, 177, 4, 10, 203, 32, 4, 77, 62, 249, 18, 142,
212, 1, 48, 121, 91, 212, 189, 59, 65, 238, 202, 208, 102, 171, 101, 25, 129, 253, 228,
141, 247, 127, 55, 45, 195, 139, 159, 175, 221, 59, 239, 177, 139, 93, 163, 204, 60, 46,
176, 47, 158, 58, 65, 214, 18, 202, 173, 21, 145, 18, 115, 160, 95, 35, 185, 232, 56,
250, 175, 132, 157, 105, 132, 41, 239, 90, 30, 136, 121, 130, 54, 195, 212, 14, 96, 69,
34, 165, 68, 200, 242, 122, 122, 45, 184, 6, 99, 209, 108, 247, 202, 234, 86, 222, 64,
92, 178, 33, 90, 69, 178, 194, 85, 102, 181, 90, 193, 167, 72, 160, 112, 223, 200, 163,
42, 70, 149, 67, 208, 25, 238, 251, 71];
static SIGNATURE: &'static [u8] = &[
112,
46,
33,
137,
67,
232,
143,
209,
30,
181,
216,
45,
191,
120,
69,
243,
65,
6,
174,
27,
129,
255,
247,
115,
17,
22,
173,
209,
113,
125,
131,
101,
109,
66,
10,
253,
60,
150,
238,
221,
115,
162,
102,
62,
81,
102,
104,
123,
0,
11,
135,
34,
110,
1,
135,
237,
16,
115,
249,
69,
229,
130,
173,
252,
239,
22,
216,
90,
121,
142,
232,
198,
109,
219,
61,
184,
151,
91,
23,
208,
148,
2,
190,
237,
213,
217,
217,
112,
7,
16,
141,
178,
129,
96,
213,
248,
4,
12,
167,
68,
87,
98,
184,
31,
190,
127,
249,
217,
46,
10,
231,
111,
36,
242,
91,
51,
187,
230,
244,
74,
230,
30,
177,
4,
10,
203,
32,
4,
77,
62,
249,
18,
142,
212,
1,
48,
121,
91,
212,
189,
59,
65,
238,
202,
208,
102,
171,
101,
25,
129,
253,
228,
141,
247,
127,
55,
45,
195,
139,
159,
175,
221,
59,
239,
177,
139,
93,
163,
204,
60,
46,
176,
47,
158,
58,
65,
214,
18,
202,
173,
21,
145,
18,
115,
160,
95,
35,
185,
232,
56,
250,
175,
132,
157,
105,
132,
41,
239,
90,
30,
136,
121,
130,
54,
195,
212,
14,
96,
69,
34,
165,
68,
200,
242,
122,
122,
45,
184,
6,
99,
209,
108,
247,
202,
234,
86,
222,
64,
92,
178,
33,
90,
69,
178,
194,
85,
102,
181,
90,
193,
167,
72,
160,
112,
223,
200,
163,
42,
70,
149,
67,
208,
25,
238,
251,
71,
];
#[test]
fn rsa_sign() {
@ -296,7 +671,10 @@ mod test {
let mut signer = Signer::new(MessageDigest::sha256(), &pkey).unwrap();
assert_eq!(signer.pkey_ctx_mut().rsa_padding().unwrap(), PKCS1_PADDING);
signer.pkey_ctx_mut().set_rsa_padding(PKCS1_PADDING).unwrap();
signer
.pkey_ctx_mut()
.set_rsa_padding(PKCS1_PADDING)
.unwrap();
signer.update(INPUT).unwrap();
let result = signer.finish().unwrap();
@ -310,7 +688,10 @@ mod test {
let pkey = PKey::from_rsa(private_key).unwrap();
let mut verifier = Verifier::new(MessageDigest::sha256(), &pkey).unwrap();
assert_eq!(verifier.pkey_ctx_mut().rsa_padding().unwrap(), PKCS1_PADDING);
assert_eq!(
verifier.pkey_ctx_mut().rsa_padding().unwrap(),
PKCS1_PADDING
);
verifier.update(INPUT).unwrap();
assert!(verifier.finish(SIGNATURE).unwrap());
}
@ -390,29 +771,45 @@ mod test {
fn hmac_md5() {
// test vectors from RFC 2202
let tests: [(Vec<u8>, Vec<u8>, Vec<u8>); 7] =
[(iter::repeat(0x0b_u8).take(16).collect(),
b"Hi There".to_vec(),
Vec::from_hex("9294727a3638bb1c13f48ef8158bfc9d").unwrap()),
(b"Jefe".to_vec(),
b"what do ya want for nothing?".to_vec(),
Vec::from_hex("750c783e6ab0b503eaa86e310a5db738").unwrap()),
(iter::repeat(0xaa_u8).take(16).collect(),
iter::repeat(0xdd_u8).take(50).collect(),
Vec::from_hex("56be34521d144c88dbb8c733f0e8b3f6").unwrap()),
(Vec::from_hex("0102030405060708090a0b0c0d0e0f10111213141516171819").unwrap(),
iter::repeat(0xcd_u8).take(50).collect(),
Vec::from_hex("697eaf0aca3a3aea3a75164746ffaa79").unwrap()),
(iter::repeat(0x0c_u8).take(16).collect(),
b"Test With Truncation".to_vec(),
Vec::from_hex("56461ef2342edc00f9bab995690efd4c").unwrap()),
(iter::repeat(0xaa_u8).take(80).collect(),
b"Test Using Larger Than Block-Size Key - Hash Key First".to_vec(),
Vec::from_hex("6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd").unwrap()),
(iter::repeat(0xaa_u8).take(80).collect(),
b"Test Using Larger Than Block-Size Key \
[
(
iter::repeat(0x0b_u8).take(16).collect(),
b"Hi There".to_vec(),
Vec::from_hex("9294727a3638bb1c13f48ef8158bfc9d").unwrap(),
),
(
b"Jefe".to_vec(),
b"what do ya want for nothing?".to_vec(),
Vec::from_hex("750c783e6ab0b503eaa86e310a5db738").unwrap(),
),
(
iter::repeat(0xaa_u8).take(16).collect(),
iter::repeat(0xdd_u8).take(50).collect(),
Vec::from_hex("56be34521d144c88dbb8c733f0e8b3f6").unwrap(),
),
(
Vec::from_hex("0102030405060708090a0b0c0d0e0f10111213141516171819").unwrap(),
iter::repeat(0xcd_u8).take(50).collect(),
Vec::from_hex("697eaf0aca3a3aea3a75164746ffaa79").unwrap(),
),
(
iter::repeat(0x0c_u8).take(16).collect(),
b"Test With Truncation".to_vec(),
Vec::from_hex("56461ef2342edc00f9bab995690efd4c").unwrap(),
),
(
iter::repeat(0xaa_u8).take(80).collect(),
b"Test Using Larger Than Block-Size Key - Hash Key First".to_vec(),
Vec::from_hex("6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd").unwrap(),
),
(
iter::repeat(0xaa_u8).take(80).collect(),
b"Test Using Larger Than Block-Size Key \
and Larger Than One Block-Size Data"
.to_vec(),
Vec::from_hex("6f630fad67cda0ee1fb1f562db3aa53e").unwrap())];
.to_vec(),
Vec::from_hex("6f630fad67cda0ee1fb1f562db3aa53e").unwrap(),
),
];
test_hmac(MessageDigest::md5(), &tests);
}
@ -421,29 +818,45 @@ mod test {
fn hmac_sha1() {
// test vectors from RFC 2202
let tests: [(Vec<u8>, Vec<u8>, Vec<u8>); 7] =
[(iter::repeat(0x0b_u8).take(20).collect(),
b"Hi There".to_vec(),
Vec::from_hex("b617318655057264e28bc0b6fb378c8ef146be00").unwrap()),
(b"Jefe".to_vec(),
b"what do ya want for nothing?".to_vec(),
Vec::from_hex("effcdf6ae5eb2fa2d27416d5f184df9c259a7c79").unwrap()),
(iter::repeat(0xaa_u8).take(20).collect(),
iter::repeat(0xdd_u8).take(50).collect(),
Vec::from_hex("125d7342b9ac11cd91a39af48aa17b4f63f175d3").unwrap()),
(Vec::from_hex("0102030405060708090a0b0c0d0e0f10111213141516171819").unwrap(),
iter::repeat(0xcd_u8).take(50).collect(),
Vec::from_hex("4c9007f4026250c6bc8414f9bf50c86c2d7235da").unwrap()),
(iter::repeat(0x0c_u8).take(20).collect(),
b"Test With Truncation".to_vec(),
Vec::from_hex("4c1a03424b55e07fe7f27be1d58bb9324a9a5a04").unwrap()),
(iter::repeat(0xaa_u8).take(80).collect(),
b"Test Using Larger Than Block-Size Key - Hash Key First".to_vec(),
Vec::from_hex("aa4ae5e15272d00e95705637ce8a3b55ed402112").unwrap()),
(iter::repeat(0xaa_u8).take(80).collect(),
b"Test Using Larger Than Block-Size Key \
[
(
iter::repeat(0x0b_u8).take(20).collect(),
b"Hi There".to_vec(),
Vec::from_hex("b617318655057264e28bc0b6fb378c8ef146be00").unwrap(),
),
(
b"Jefe".to_vec(),
b"what do ya want for nothing?".to_vec(),
Vec::from_hex("effcdf6ae5eb2fa2d27416d5f184df9c259a7c79").unwrap(),
),
(
iter::repeat(0xaa_u8).take(20).collect(),
iter::repeat(0xdd_u8).take(50).collect(),
Vec::from_hex("125d7342b9ac11cd91a39af48aa17b4f63f175d3").unwrap(),
),
(
Vec::from_hex("0102030405060708090a0b0c0d0e0f10111213141516171819").unwrap(),
iter::repeat(0xcd_u8).take(50).collect(),
Vec::from_hex("4c9007f4026250c6bc8414f9bf50c86c2d7235da").unwrap(),
),
(
iter::repeat(0x0c_u8).take(20).collect(),
b"Test With Truncation".to_vec(),
Vec::from_hex("4c1a03424b55e07fe7f27be1d58bb9324a9a5a04").unwrap(),
),
(
iter::repeat(0xaa_u8).take(80).collect(),
b"Test Using Larger Than Block-Size Key - Hash Key First".to_vec(),
Vec::from_hex("aa4ae5e15272d00e95705637ce8a3b55ed402112").unwrap(),
),
(
iter::repeat(0xaa_u8).take(80).collect(),
b"Test Using Larger Than Block-Size Key \
and Larger Than One Block-Size Data"
.to_vec(),
Vec::from_hex("e8e99d0f45237d786d6bbaa7965c7808bbff1a91").unwrap())];
.to_vec(),
Vec::from_hex("e8e99d0f45237d786d6bbaa7965c7808bbff1a91").unwrap(),
),
];
test_hmac(MessageDigest::sha1(), &tests);
}

View File

@ -71,7 +71,7 @@ unsafe fn state<'a, S: 'a>(bio: *mut BIO) -> &'a mut StreamState<S> {
&mut *(compat::BIO_get_data(bio) as *mut _)
}
unsafe extern fn bwrite<S: Write>(bio: *mut BIO, buf: *const c_char, len: c_int) -> c_int {
unsafe extern "C" fn bwrite<S: Write>(bio: *mut BIO, buf: *const c_char, len: c_int) -> c_int {
BIO_clear_retry_flags(bio);
let state = state::<S>(bio);
@ -93,7 +93,7 @@ unsafe extern fn bwrite<S: Write>(bio: *mut BIO, buf: *const c_char, len: c_int)
}
}
unsafe extern fn bread<S: Read>(bio: *mut BIO, buf: *mut c_char, len: c_int) -> c_int {
unsafe extern "C" fn bread<S: Read>(bio: *mut BIO, buf: *mut c_char, len: c_int) -> c_int {
BIO_clear_retry_flags(bio);
let state = state::<S>(bio);
@ -123,15 +123,16 @@ fn retriable_error(err: &io::Error) -> bool {
}
}
unsafe extern fn bputs<S: Write>(bio: *mut BIO, s: *const c_char) -> c_int {
unsafe extern "C" fn bputs<S: Write>(bio: *mut BIO, s: *const c_char) -> c_int {
bwrite::<S>(bio, s, strlen(s) as c_int)
}
unsafe extern fn ctrl<S: Write>(bio: *mut BIO,
cmd: c_int,
_num: c_long,
_ptr: *mut c_void)
-> c_long {
unsafe extern "C" fn ctrl<S: Write>(
bio: *mut BIO,
cmd: c_int,
_num: c_long,
_ptr: *mut c_void,
) -> c_long {
if cmd == BIO_CTRL_FLUSH {
let state = state::<S>(bio);
@ -151,7 +152,7 @@ unsafe extern fn ctrl<S: Write>(bio: *mut BIO,
}
}
unsafe extern fn create(bio: *mut BIO) -> c_int {
unsafe extern "C" fn create(bio: *mut BIO) -> c_int {
compat::BIO_set_init(bio, 0);
compat::BIO_set_num(bio, 0);
compat::BIO_set_data(bio, ptr::null_mut());
@ -159,7 +160,7 @@ unsafe extern fn create(bio: *mut BIO) -> c_int {
1
}
unsafe extern fn destroy<S>(bio: *mut BIO) -> c_int {
unsafe extern "C" fn destroy<S>(bio: *mut BIO) -> c_int {
if bio.is_null() {
return 0;
}

View File

@ -40,7 +40,7 @@ fn ctx(method: SslMethod) -> Result<SslContextBuilder, ErrorStack> {
ctx.set_options(opts);
let mode = ssl::SSL_MODE_AUTO_RETRY | ssl::SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
ssl::SSL_MODE_ENABLE_PARTIAL_WRITE;
ssl::SSL_MODE_ENABLE_PARTIAL_WRITE;
ctx.set_mode(mode);
Ok(ctx)
@ -57,9 +57,11 @@ impl SslConnectorBuilder {
let mut ctx = try!(ctx(method));
try!(ctx.set_default_verify_paths());
// From https://github.com/python/cpython/blob/c30098c8c6014f3340a369a31df9c74bdbacc269/Lib/ssl.py#L191
try!(ctx.set_cipher_list("ECDH+AESGCM:ECDH+CHACHA20:DH+AESGCM:DH+CHACHA20:ECDH+AES256:\
try!(ctx.set_cipher_list(
"ECDH+AESGCM:ECDH+CHACHA20:DH+AESGCM:DH+CHACHA20:ECDH+AES256:\
DH+AES256:ECDH+AES128:DH+AES:ECDH+HIGH:DH+HIGH:RSA+AESGCM:\
RSA+AES:RSA+HIGH:!aNULL:!eNULL:!MD5:!3DES"));
RSA+AES:RSA+HIGH:!aNULL:!eNULL:!MD5:!3DES",
));
setup_verify(&mut ctx);
Ok(SslConnectorBuilder(ctx))
@ -96,7 +98,8 @@ impl SslConnector {
///
/// The domain is used for SNI and hostname verification.
pub fn connect<S>(&self, domain: &str, stream: S) -> Result<SslStream<S>, HandshakeError<S>>
where S: Read + Write
where
S: Read + Write,
{
try!(self.configure()).connect(domain, stream)
}
@ -140,7 +143,8 @@ impl ConnectConfiguration {
///
/// The domain is used for SNI and hostname verification.
pub fn connect<S>(mut self, domain: &str, stream: S) -> Result<SslStream<S>, HandshakeError<S>>
where S: Read + Write
where
S: Read + Write,
{
try!(self.0.set_hostname(domain));
try!(setup_verify_hostname(&mut self.0, domain));
@ -176,13 +180,15 @@ impl SslAcceptorBuilder {
/// recommendations. See its [documentation][docs] for more details on specifics.
///
/// [docs]: https://wiki.mozilla.org/Security/Server_Side_TLS
pub fn mozilla_intermediate<I>(method: SslMethod,
private_key: &PKeyRef,
certificate: &X509Ref,
chain: I)
-> Result<SslAcceptorBuilder, ErrorStack>
where I: IntoIterator,
I::Item: AsRef<X509Ref>
pub fn mozilla_intermediate<I>(
method: SslMethod,
private_key: &PKeyRef,
certificate: &X509Ref,
chain: I,
) -> Result<SslAcceptorBuilder, ErrorStack>
where
I: IntoIterator,
I::Item: AsRef<X509Ref>,
{
let builder = try!(SslAcceptorBuilder::mozilla_intermediate_raw(method));
builder.finish_setup(private_key, certificate, chain)
@ -194,13 +200,15 @@ impl SslAcceptorBuilder {
/// See its [documentation][docs] for more details on specifics.
///
/// [docs]: https://wiki.mozilla.org/Security/Server_Side_TLS
pub fn mozilla_modern<I>(method: SslMethod,
private_key: &PKeyRef,
certificate: &X509Ref,
chain: I)
-> Result<SslAcceptorBuilder, ErrorStack>
where I: IntoIterator,
I::Item: AsRef<X509Ref>
pub fn mozilla_modern<I>(
method: SslMethod,
private_key: &PKeyRef,
certificate: &X509Ref,
chain: I,
) -> Result<SslAcceptorBuilder, ErrorStack>
where
I: IntoIterator,
I::Item: AsRef<X509Ref>,
{
let builder = try!(SslAcceptorBuilder::mozilla_modern_raw(method));
builder.finish_setup(private_key, certificate, chain)
@ -212,7 +220,8 @@ impl SslAcceptorBuilder {
let dh = try!(Dh::from_pem(DHPARAM_PEM.as_bytes()));
try!(ctx.set_tmp_dh(&dh));
try!(setup_curves(&mut ctx));
try!(ctx.set_cipher_list("ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:\
try!(ctx.set_cipher_list(
"ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:\
ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:\
ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:\
DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:\
@ -225,7 +234,8 @@ impl SslAcceptorBuilder {
ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:\
EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:\
AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:\
DES-CBC3-SHA:!DSS"));
DES-CBC3-SHA:!DSS",
));
Ok(SslAcceptorBuilder(ctx))
}
@ -233,21 +243,25 @@ impl SslAcceptorBuilder {
pub fn mozilla_modern_raw(method: SslMethod) -> Result<SslAcceptorBuilder, ErrorStack> {
let mut ctx = try!(ctx(method));
try!(setup_curves(&mut ctx));
try!(ctx.set_cipher_list("ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:\
try!(ctx.set_cipher_list(
"ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:\
ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:\
ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:\
ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:\
ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256"));
ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256",
));
Ok(SslAcceptorBuilder(ctx))
}
fn finish_setup<I>(mut self,
private_key: &PKeyRef,
certificate: &X509Ref,
chain: I)
-> Result<SslAcceptorBuilder, ErrorStack>
where I: IntoIterator,
I::Item: AsRef<X509Ref>
fn finish_setup<I>(
mut self,
private_key: &PKeyRef,
certificate: &X509Ref,
chain: I,
) -> Result<SslAcceptorBuilder, ErrorStack>
where
I: IntoIterator,
I::Item: AsRef<X509Ref>,
{
try!(self.0.set_private_key(private_key));
try!(self.0.set_certificate(certificate));
@ -303,7 +317,8 @@ pub struct SslAcceptor(SslContext);
impl SslAcceptor {
/// Initiates a server-side TLS session on a stream.
pub fn accept<S>(&self, stream: S) -> Result<SslStream<S>, HandshakeError<S>>
where S: Read + Write
where
S: Read + Write,
{
let ssl = try!(Ssl::new(&self.0));
ssl.accept(stream)
@ -320,7 +335,7 @@ fn setup_verify(ctx: &mut SslContextBuilder) {
ctx.set_verify_callback(SSL_VERIFY_PEER, |p, x509| {
let hostname = match x509.ssl() {
Ok(Some(ssl)) => ssl.ex_data(*HOSTNAME_IDX),
_ => None
_ => None,
};
match hostname {
Some(hostname) => verify::verify_callback(hostname, p, x509),
@ -352,10 +367,11 @@ mod verify {
use x509::{X509StoreContextRef, X509Ref, X509NameRef, GeneralName};
use stack::Stack;
pub fn verify_callback(domain: &str,
preverify_ok: bool,
x509_ctx: &X509StoreContextRef)
-> bool {
pub fn verify_callback(
domain: &str,
preverify_ok: bool,
x509_ctx: &X509StoreContextRef,
) -> bool {
if !preverify_ok || x509_ctx.error_depth() != 0 {
return preverify_ok;
}
@ -497,14 +513,16 @@ mod verify {
match (expected, actual.len()) {
(&IpAddr::V4(ref addr), 4) => actual == addr.octets(),
(&IpAddr::V6(ref addr), 16) => {
let segments = [((actual[0] as u16) << 8) | actual[1] as u16,
((actual[2] as u16) << 8) | actual[3] as u16,
((actual[4] as u16) << 8) | actual[5] as u16,
((actual[6] as u16) << 8) | actual[7] as u16,
((actual[8] as u16) << 8) | actual[9] as u16,
((actual[10] as u16) << 8) | actual[11] as u16,
((actual[12] as u16) << 8) | actual[13] as u16,
((actual[14] as u16) << 8) | actual[15] as u16];
let segments = [
((actual[0] as u16) << 8) | actual[1] as u16,
((actual[2] as u16) << 8) | actual[3] as u16,
((actual[4] as u16) << 8) | actual[5] as u16,
((actual[6] as u16) << 8) | actual[7] as u16,
((actual[8] as u16) << 8) | actual[9] as u16,
((actual[10] as u16) << 8) | actual[11] as u16,
((actual[12] as u16) << 8) | actual[13] as u16,
((actual[14] as u16) << 8) | actual[15] as u16,
];
segments == addr.segments()
}
_ => false,

View File

@ -251,18 +251,18 @@ lazy_static! {
// when context is freed
fn get_callback_idx<T: Any + 'static>() -> c_int {
*INDEXES
.lock()
.unwrap()
.entry(TypeId::of::<T>())
.or_insert_with(|| get_new_idx::<T>())
.lock()
.unwrap()
.entry(TypeId::of::<T>())
.or_insert_with(|| get_new_idx::<T>())
}
fn get_ssl_callback_idx<T: Any + 'static>() -> c_int {
*SSL_INDEXES
.lock()
.unwrap()
.entry(TypeId::of::<T>())
.or_insert_with(|| get_new_ssl_idx::<T>())
.lock()
.unwrap()
.entry(TypeId::of::<T>())
.or_insert_with(|| get_new_ssl_idx::<T>())
}
lazy_static! {
@ -274,12 +274,14 @@ lazy_static! {
static ref ALPN_PROTOS_IDX: c_int = get_new_idx::<Vec<u8>>();
}
unsafe extern "C" fn free_data_box<T>(_parent: *mut c_void,
ptr: *mut c_void,
_ad: *mut ffi::CRYPTO_EX_DATA,
_idx: c_int,
_argl: c_long,
_argp: *mut c_void) {
unsafe extern "C" fn free_data_box<T>(
_parent: *mut c_void,
ptr: *mut c_void,
_ad: *mut ffi::CRYPTO_EX_DATA,
_idx: c_int,
_argl: c_long,
_argp: *mut c_void,
) {
if !ptr.is_null() {
Box::<T>::from_raw(ptr as *mut T);
}
@ -366,13 +368,16 @@ impl SslContextBuilder {
/// Configures the certificate verification method for new connections and
/// registers a verification callback.
pub fn set_verify_callback<F>(&mut self, mode: SslVerifyMode, verify: F)
where F: Fn(bool, &X509StoreContextRef) -> bool + Any + 'static + Sync + Send
where
F: Fn(bool, &X509StoreContextRef) -> bool + Any + 'static + Sync + Send,
{
unsafe {
let verify = Box::new(verify);
ffi::SSL_CTX_set_ex_data(self.as_ptr(),
get_callback_idx::<F>(),
mem::transmute(verify));
ffi::SSL_CTX_set_ex_data(
self.as_ptr(),
get_callback_idx::<F>(),
mem::transmute(verify),
);
ffi::SSL_CTX_set_verify(self.as_ptr(), mode.bits as c_int, Some(raw_verify::<F>));
}
}
@ -382,13 +387,16 @@ impl SslContextBuilder {
/// Obtain the server name with `servername` then set the corresponding context
/// with `set_ssl_context`
pub fn set_servername_callback<F>(&mut self, callback: F)
where F: Fn(&mut SslRef) -> Result<(), SniError> + Any + 'static + Sync + Send
where
F: Fn(&mut SslRef) -> Result<(), SniError> + Any + 'static + Sync + Send,
{
unsafe {
let callback = Box::new(callback);
ffi::SSL_CTX_set_ex_data(self.as_ptr(),
get_callback_idx::<F>(),
mem::transmute(callback));
ffi::SSL_CTX_set_ex_data(
self.as_ptr(),
get_callback_idx::<F>(),
mem::transmute(callback),
);
let f: extern "C" fn(_, _, _) -> _ = raw_sni::<F>;
let f: extern "C" fn() = mem::transmute(f);
ffi::SSL_CTX_set_tlsext_servername_callback(self.as_ptr(), Some(f));
@ -409,7 +417,10 @@ impl SslContextBuilder {
pub fn set_verify_cert_store(&mut self, cert_store: X509Store) -> Result<(), ErrorStack> {
unsafe {
let ptr = cert_store.as_ptr();
try!(cvt(ffi::SSL_CTX_set0_verify_cert_store(self.as_ptr(), ptr) as c_int));
try!(cvt(
ffi::SSL_CTX_set0_verify_cert_store(self.as_ptr(), ptr) as
c_int,
));
mem::forget(cert_store);
Ok(())
@ -434,32 +445,41 @@ impl SslContextBuilder {
}
pub fn set_tmp_dh_callback<F>(&mut self, callback: F)
where F: Fn(&mut SslRef, bool, u32) -> Result<Dh, ErrorStack> + Any + 'static + Sync + Send
where
F: Fn(&mut SslRef, bool, u32) -> Result<Dh, ErrorStack> + Any + 'static + Sync + Send,
{
unsafe {
let callback = Box::new(callback);
ffi::SSL_CTX_set_ex_data(self.as_ptr(),
get_callback_idx::<F>(),
Box::into_raw(callback) as *mut c_void);
ffi::SSL_CTX_set_ex_data(
self.as_ptr(),
get_callback_idx::<F>(),
Box::into_raw(callback) as *mut c_void,
);
let f: unsafe extern "C" fn(_, _, _) -> _ = raw_tmp_dh::<F>;
ffi::SSL_CTX_set_tmp_dh_callback(self.as_ptr(), f);
}
}
pub fn set_tmp_ecdh(&mut self, key: &EcKeyRef) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::SSL_CTX_set_tmp_ecdh(self.as_ptr(), key.as_ptr()) as c_int).map(|_| ()) }
unsafe {
cvt(ffi::SSL_CTX_set_tmp_ecdh(self.as_ptr(), key.as_ptr()) as
c_int).map(|_| ())
}
}
/// Requires the `v101` feature and OpenSSL 1.0.1, or the `v102` feature and OpenSSL 1.0.2.
#[cfg(any(all(feature = "v101", ossl101), all(feature = "v102", ossl102)))]
pub fn set_tmp_ecdh_callback<F>(&mut self, callback: F)
where F: Fn(&mut SslRef, bool, u32) -> Result<EcKey, ErrorStack> + Any + 'static + Sync + Send
where
F: Fn(&mut SslRef, bool, u32) -> Result<EcKey, ErrorStack> + Any + 'static + Sync + Send,
{
unsafe {
let callback = Box::new(callback);
ffi::SSL_CTX_set_ex_data(self.as_ptr(),
get_callback_idx::<F>(),
Box::into_raw(callback) as *mut c_void);
ffi::SSL_CTX_set_ex_data(
self.as_ptr(),
get_callback_idx::<F>(),
Box::into_raw(callback) as *mut c_void,
);
let f: unsafe extern "C" fn(_, _, _) -> _ = raw_tmp_ecdh::<F>;
ffi::SSL_CTX_set_tmp_ecdh_callback(self.as_ptr(), f);
}
@ -478,10 +498,11 @@ impl SslContextBuilder {
pub fn set_ca_file<P: AsRef<Path>>(&mut self, file: P) -> Result<(), ErrorStack> {
let file = CString::new(file.as_ref().as_os_str().to_str().unwrap()).unwrap();
unsafe {
cvt(ffi::SSL_CTX_load_verify_locations(self.as_ptr(),
file.as_ptr() as *const _,
ptr::null()))
.map(|_| ())
cvt(ffi::SSL_CTX_load_verify_locations(
self.as_ptr(),
file.as_ptr() as *const _,
ptr::null(),
)).map(|_| ())
}
}
@ -506,24 +527,27 @@ impl SslContextBuilder {
pub fn set_session_id_context(&mut self, sid_ctx: &[u8]) -> Result<(), ErrorStack> {
unsafe {
assert!(sid_ctx.len() <= c_uint::max_value() as usize);
cvt(ffi::SSL_CTX_set_session_id_context(self.as_ptr(),
sid_ctx.as_ptr(),
sid_ctx.len() as c_uint))
.map(|_| ())
cvt(ffi::SSL_CTX_set_session_id_context(
self.as_ptr(),
sid_ctx.as_ptr(),
sid_ctx.len() as c_uint,
)).map(|_| ())
}
}
/// Loads a certificate from a file.
pub fn set_certificate_file<P: AsRef<Path>>(&mut self,
file: P,
file_type: X509FileType)
-> Result<(), ErrorStack> {
pub fn set_certificate_file<P: AsRef<Path>>(
&mut self,
file: P,
file_type: X509FileType,
) -> Result<(), ErrorStack> {
let file = CString::new(file.as_ref().as_os_str().to_str().unwrap()).unwrap();
unsafe {
cvt(ffi::SSL_CTX_use_certificate_file(self.as_ptr(),
file.as_ptr() as *const _,
file_type.as_raw()))
.map(|_| ())
cvt(ffi::SSL_CTX_use_certificate_file(
self.as_ptr(),
file.as_ptr() as *const _,
file_type.as_raw(),
)).map(|_| ())
}
}
@ -532,13 +556,16 @@ impl SslContextBuilder {
/// The file should contain a sequence of PEM-formatted certificates, the first being the leaf
/// certificate, and the remainder forming the chain of certificates up to and including the
/// trusted root certificate.
pub fn set_certificate_chain_file<P: AsRef<Path>>(&mut self,
file: P)
-> Result<(), ErrorStack> {
pub fn set_certificate_chain_file<P: AsRef<Path>>(
&mut self,
file: P,
) -> Result<(), ErrorStack> {
let file = CString::new(file.as_ref().as_os_str().to_str().unwrap()).unwrap();
unsafe {
cvt(ffi::SSL_CTX_use_certificate_chain_file(self.as_ptr(), file.as_ptr() as *const _))
.map(|_| ())
cvt(ffi::SSL_CTX_use_certificate_chain_file(
self.as_ptr(),
file.as_ptr() as *const _,
)).map(|_| ())
}
}
@ -553,23 +580,28 @@ impl SslContextBuilder {
/// `set_certificate` to a trusted root.
pub fn add_extra_chain_cert(&mut self, cert: X509) -> Result<(), ErrorStack> {
unsafe {
try!(cvt(ffi::SSL_CTX_add_extra_chain_cert(self.as_ptr(), cert.as_ptr()) as c_int));
try!(cvt(ffi::SSL_CTX_add_extra_chain_cert(
self.as_ptr(),
cert.as_ptr(),
) as c_int));
mem::forget(cert);
Ok(())
}
}
/// Loads the private key from a file.
pub fn set_private_key_file<P: AsRef<Path>>(&mut self,
file: P,
file_type: X509FileType)
-> Result<(), ErrorStack> {
pub fn set_private_key_file<P: AsRef<Path>>(
&mut self,
file: P,
file_type: X509FileType,
) -> Result<(), ErrorStack> {
let file = CString::new(file.as_ref().as_os_str().to_str().unwrap()).unwrap();
unsafe {
cvt(ffi::SSL_CTX_use_PrivateKey_file(self.as_ptr(),
file.as_ptr() as *const _,
file_type.as_raw()))
.map(|_| ())
cvt(ffi::SSL_CTX_use_PrivateKey_file(
self.as_ptr(),
file.as_ptr() as *const _,
file_type.as_raw(),
)).map(|_| ())
}
}
@ -584,8 +616,10 @@ impl SslContextBuilder {
pub fn set_cipher_list(&mut self, cipher_list: &str) -> Result<(), ErrorStack> {
let cipher_list = CString::new(cipher_list).unwrap();
unsafe {
cvt(ffi::SSL_CTX_set_cipher_list(self.as_ptr(), cipher_list.as_ptr() as *const _))
.map(|_| ())
cvt(ffi::SSL_CTX_set_cipher_list(
self.as_ptr(),
cipher_list.as_ptr() as *const _,
)).map(|_| ())
}
}
@ -597,7 +631,7 @@ impl SslContextBuilder {
self._set_ecdh_auto(onoff)
}
#[cfg(any(ossl102,libressl))]
#[cfg(any(ossl102, libressl))]
fn _set_ecdh_auto(&mut self, onoff: bool) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::SSL_CTX_set_ecdh_auto(self.as_ptr(), onoff as c_int)).map(|_| ()) }
}
@ -627,20 +661,26 @@ impl SslContextBuilder {
unsafe {
// Attach the protocol list to the OpenSSL context structure,
// so that we can refer to it within the callback.
try!(cvt(ffi::SSL_CTX_set_ex_data(self.as_ptr(),
*NPN_PROTOS_IDX,
Box::into_raw(protocols) as *mut c_void)));
try!(cvt(ffi::SSL_CTX_set_ex_data(
self.as_ptr(),
*NPN_PROTOS_IDX,
Box::into_raw(protocols) as *mut c_void,
)));
// Now register the callback that performs the default protocol
// matching based on the client-supported list of protocols that
// has been saved.
ffi::SSL_CTX_set_next_proto_select_cb(self.as_ptr(),
raw_next_proto_select_cb,
ptr::null_mut());
ffi::SSL_CTX_set_next_proto_select_cb(
self.as_ptr(),
raw_next_proto_select_cb,
ptr::null_mut(),
);
// Also register the callback to advertise these protocols, if a server socket is
// created with the context.
ffi::SSL_CTX_set_next_protos_advertised_cb(self.as_ptr(),
raw_next_protos_advertise_cb,
ptr::null_mut());
ffi::SSL_CTX_set_next_protos_advertised_cb(
self.as_ptr(),
raw_next_protos_advertise_cb,
ptr::null_mut(),
);
Ok(())
}
}
@ -658,9 +698,11 @@ impl SslContextBuilder {
let protocols: Box<Vec<u8>> = Box::new(ssl_encode_byte_strings(protocols));
unsafe {
// Set the context's internal protocol list for use if we are a server
let r = ffi::SSL_CTX_set_alpn_protos(self.as_ptr(),
protocols.as_ptr(),
protocols.len() as c_uint);
let r = ffi::SSL_CTX_set_alpn_protos(
self.as_ptr(),
protocols.as_ptr(),
protocols.len() as c_uint,
);
// fun fact, SSL_CTX_set_alpn_protos has a reversed return code D:
if r != 0 {
return Err(ErrorStack::get());
@ -670,9 +712,11 @@ impl SslContextBuilder {
// ssl ctx's ex_data so that we can configure a function to free it later. In the
// future, it might make sense to pull this into our internal struct Ssl instead of
// leaning on openssl and using function pointers.
try!(cvt(ffi::SSL_CTX_set_ex_data(self.as_ptr(),
*ALPN_PROTOS_IDX,
Box::into_raw(protocols) as *mut c_void)));
try!(cvt(ffi::SSL_CTX_set_ex_data(
self.as_ptr(),
*ALPN_PROTOS_IDX,
Box::into_raw(protocols) as *mut c_void,
)));
// Now register the callback that performs the default protocol
// matching based on the client-supported list of protocols that
@ -711,15 +755,21 @@ impl SslContextBuilder {
/// response of `Ok(true)` indicates that the OCSP status should be returned to the client, and
/// `Ok(false)` indicates that the status should not be returned to the client.
pub fn set_status_callback<F>(&mut self, callback: F) -> Result<(), ErrorStack>
where F: Fn(&mut SslRef) -> Result<bool, ErrorStack> + Any + 'static + Sync + Send
where
F: Fn(&mut SslRef) -> Result<bool, ErrorStack> + Any + 'static + Sync + Send,
{
unsafe {
let callback = Box::new(callback);
ffi::SSL_CTX_set_ex_data(self.as_ptr(),
get_callback_idx::<F>(),
Box::into_raw(callback) as *mut c_void);
ffi::SSL_CTX_set_ex_data(
self.as_ptr(),
get_callback_idx::<F>(),
Box::into_raw(callback) as *mut c_void,
);
let f: unsafe extern "C" fn(_, _) -> _ = raw_tlsext_status::<F>;
cvt(ffi::SSL_CTX_set_tlsext_status_cb(self.as_ptr(), Some(f)) as c_int).map(|_| ())
cvt(ffi::SSL_CTX_set_tlsext_status_cb(
self.as_ptr(),
Some(f),
) as c_int).map(|_| ())
}
}
@ -730,13 +780,20 @@ impl SslContextBuilder {
/// must be written as a null-terminated C string.
#[cfg(not(osslconf = "OPENSSL_NO_PSK"))]
pub fn set_psk_callback<F>(&mut self, callback: F)
where F: Fn(&mut SslRef, Option<&[u8]>, &mut [u8], &mut [u8]) -> Result<usize, ErrorStack> + Any + 'static + Sync + Send
where
F: Fn(&mut SslRef, Option<&[u8]>, &mut [u8], &mut [u8]) -> Result<usize, ErrorStack>
+ Any
+ 'static
+ Sync
+ Send,
{
unsafe {
let callback = Box::new(callback);
ffi::SSL_CTX_set_ex_data(self.as_ptr(),
get_callback_idx::<F>(),
mem::transmute(callback));
ffi::SSL_CTX_set_ex_data(
self.as_ptr(),
get_callback_idx::<F>(),
mem::transmute(callback),
);
ffi::SSL_CTX_set_psk_client_callback(self.as_ptr(), Some(raw_psk::<F>))
}
}
@ -745,7 +802,11 @@ impl SslContextBuilder {
pub fn set_ex_data<T>(&mut self, index: Index<SslContext, T>, data: T) {
unsafe {
let data = Box::new(data);
ffi::SSL_CTX_set_ex_data(self.as_ptr(), index.as_raw(), Box::into_raw(data) as *mut c_void);
ffi::SSL_CTX_set_ex_data(
self.as_ptr(),
index.as_raw(),
Box::into_raw(data) as *mut c_void,
);
}
}
@ -794,7 +855,7 @@ impl SslContext {
/// index.
pub fn new_ex_index<T>() -> Result<Index<SslContext, T>, ErrorStack>
where
T: 'static + Sync + Send
T: 'static + Sync + Send,
{
unsafe {
ffi::init();
@ -1023,7 +1084,7 @@ impl Ssl {
/// index.
pub fn new_ex_index<T>() -> Result<Index<Ssl, T>, ErrorStack>
where
T: 'static + Sync + Send
T: 'static + Sync + Send,
{
unsafe {
ffi::init();
@ -1078,13 +1139,16 @@ impl SslRef {
/// to the certificate chain. It should return `true` if the certificate
/// chain is valid and `false` otherwise.
pub fn set_verify_callback<F>(&mut self, mode: SslVerifyMode, verify: F)
where F: Fn(bool, &X509StoreContextRef) -> bool + Any + 'static + Sync + Send
where
F: Fn(bool, &X509StoreContextRef) -> bool + Any + 'static + Sync + Send,
{
unsafe {
let verify = Box::new(verify);
ffi::SSL_set_ex_data(self.as_ptr(),
get_ssl_callback_idx::<F>(),
mem::transmute(verify));
ffi::SSL_set_ex_data(
self.as_ptr(),
get_ssl_callback_idx::<F>(),
mem::transmute(verify),
);
ffi::SSL_set_verify(self.as_ptr(), mode.bits as c_int, Some(ssl_raw_verify::<F>));
}
}
@ -1094,13 +1158,16 @@ impl SslRef {
}
pub fn set_tmp_dh_callback<F>(&mut self, callback: F)
where F: Fn(&mut SslRef, bool, u32) -> Result<Dh, ErrorStack> + Any + 'static + Sync + Send
where
F: Fn(&mut SslRef, bool, u32) -> Result<Dh, ErrorStack> + Any + 'static + Sync + Send,
{
unsafe {
let callback = Box::new(callback);
ffi::SSL_set_ex_data(self.as_ptr(),
get_ssl_callback_idx::<F>(),
Box::into_raw(callback) as *mut c_void);
ffi::SSL_set_ex_data(
self.as_ptr(),
get_ssl_callback_idx::<F>(),
Box::into_raw(callback) as *mut c_void,
);
let f: unsafe extern "C" fn(_, _, _) -> _ = raw_tmp_dh_ssl::<F>;
ffi::SSL_set_tmp_dh_callback(self.as_ptr(), f);
}
@ -1113,13 +1180,16 @@ impl SslRef {
/// Requires the `v101` feature and OpenSSL 1.0.1, or the `v102` feature and OpenSSL 1.0.2.
#[cfg(any(all(feature = "v101", ossl101), all(feature = "v102", ossl102)))]
pub fn set_tmp_ecdh_callback<F>(&mut self, callback: F)
where F: Fn(&mut SslRef, bool, u32) -> Result<EcKey, ErrorStack> + Any + 'static + Sync + Send
where
F: Fn(&mut SslRef, bool, u32) -> Result<EcKey, ErrorStack> + Any + 'static + Sync + Send,
{
unsafe {
let callback = Box::new(callback);
ffi::SSL_set_ex_data(self.as_ptr(),
get_ssl_callback_idx::<F>(),
Box::into_raw(callback) as *mut c_void);
ffi::SSL_set_ex_data(
self.as_ptr(),
get_ssl_callback_idx::<F>(),
Box::into_raw(callback) as *mut c_void,
);
let f: unsafe extern "C" fn(_, _, _) -> _ = raw_tmp_ecdh_ssl::<F>;
ffi::SSL_set_tmp_ecdh_callback(self.as_ptr(), f);
}
@ -1169,8 +1239,10 @@ impl SslRef {
pub fn set_hostname(&mut self, hostname: &str) -> Result<(), ErrorStack> {
let cstr = CString::new(hostname).unwrap();
unsafe {
cvt(ffi::SSL_set_tlsext_host_name(self.as_ptr(), cstr.as_ptr() as *mut _) as c_int)
.map(|_| ())
cvt(ffi::SSL_set_tlsext_host_name(
self.as_ptr(),
cstr.as_ptr() as *mut _,
) as c_int).map(|_| ())
}
}
@ -1285,7 +1357,9 @@ impl SslRef {
return None;
}
let meth = ffi::SSL_COMP_get_name(ptr);
Some(str::from_utf8(CStr::from_ptr(meth as *const _).to_bytes()).unwrap())
Some(
str::from_utf8(CStr::from_ptr(meth as *const _).to_bytes()).unwrap(),
)
}
}
@ -1302,7 +1376,9 @@ impl SslRef {
return None;
}
Some(str::from_utf8(CStr::from_ptr(name as *const _).to_bytes()).unwrap())
Some(
str::from_utf8(CStr::from_ptr(name as *const _).to_bytes()).unwrap(),
)
}
}
@ -1367,7 +1443,10 @@ impl SslRef {
/// Sets the status response a client wishes the server to reply with.
pub fn set_status_type(&mut self, type_: StatusType) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::SSL_set_tlsext_status_type(self.as_ptr(), type_.as_raw()) as c_int).map(|_| ())
cvt(ffi::SSL_set_tlsext_status_type(
self.as_ptr(),
type_.as_raw(),
) as c_int).map(|_| ())
}
}
@ -1389,15 +1468,17 @@ impl SslRef {
pub fn set_ocsp_status(&mut self, response: &[u8]) -> Result<(), ErrorStack> {
unsafe {
assert!(response.len() <= c_int::max_value() as usize);
let p = try!(cvt_p(ffi::CRYPTO_malloc(response.len() as _,
concat!(file!(), "\0").as_ptr() as *const _,
line!() as c_int)));
let p = try!(cvt_p(ffi::CRYPTO_malloc(
response.len() as _,
concat!(file!(), "\0").as_ptr() as *const _,
line!() as c_int,
)));
ptr::copy_nonoverlapping(response.as_ptr(), p as *mut u8, response.len());
cvt(ffi::SSL_set_tlsext_status_ocsp_resp(self.as_ptr(),
p as *mut c_uchar,
response.len() as c_long) as
c_int)
.map(|_| ())
cvt(ffi::SSL_set_tlsext_status_ocsp_resp(
self.as_ptr(),
p as *mut c_uchar,
response.len() as c_long,
) as c_int).map(|_| ())
}
}
@ -1410,7 +1491,11 @@ impl SslRef {
pub fn set_ex_data<T>(&mut self, index: Index<Ssl, T>, data: T) {
unsafe {
let data = Box::new(data);
ffi::SSL_set_ex_data(self.as_ptr(), index.as_raw(), Box::into_raw(data) as *mut c_void);
ffi::SSL_set_ex_data(
self.as_ptr(),
index.as_raw(),
Box::into_raw(data) as *mut c_void,
);
}
}
@ -1451,7 +1536,8 @@ impl Ssl {
/// OpenSSL's default configuration is insecure. It is highly recommended to use
/// `SslConnector` rather than `Ssl` directly, as it manages that configuration.
pub fn connect<S>(self, stream: S) -> Result<SslStream<S>, HandshakeError<S>>
where S: Read + Write
where
S: Read + Write,
{
let mut stream = SslStream::new_base(self, stream);
let ret = unsafe { ffi::SSL_connect(stream.ssl.as_ptr()) };
@ -1462,15 +1548,15 @@ impl Ssl {
e @ Error::WantWrite(_) |
e @ Error::WantRead(_) => {
Err(HandshakeError::Interrupted(MidHandshakeSslStream {
stream: stream,
error: e,
}))
stream: stream,
error: e,
}))
}
err => {
Err(HandshakeError::Failure(MidHandshakeSslStream {
stream: stream,
error: err,
}))
stream: stream,
error: err,
}))
}
}
}
@ -1483,7 +1569,8 @@ impl Ssl {
/// OpenSSL's default configuration is insecure. It is highly recommended to use
/// `SslAcceptor` rather than `Ssl` directly, as it manages that configuration.
pub fn accept<S>(self, stream: S) -> Result<SslStream<S>, HandshakeError<S>>
where S: Read + Write
where
S: Read + Write,
{
let mut stream = SslStream::new_base(self, stream);
let ret = unsafe { ffi::SSL_accept(stream.ssl.as_ptr()) };
@ -1494,15 +1581,15 @@ impl Ssl {
e @ Error::WantWrite(_) |
e @ Error::WantRead(_) => {
Err(HandshakeError::Interrupted(MidHandshakeSslStream {
stream: stream,
error: e,
}))
stream: stream,
error: e,
}))
}
err => {
Err(HandshakeError::Failure(MidHandshakeSslStream {
stream: stream,
error: err,
}))
stream: stream,
error: err,
}))
}
}
}
@ -1571,7 +1658,8 @@ pub struct SslStream<S> {
}
impl<S> fmt::Debug for SslStream<S>
where S: fmt::Debug
where
S: fmt::Debug,
{
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.debug_struct("SslStream")
@ -1672,8 +1760,10 @@ impl<S> SslStream<S> {
match self.get_bio_error() {
Some(err) => Error::Stream(err),
None => {
Error::Stream(io::Error::new(io::ErrorKind::ConnectionAborted,
"unexpected EOF observed"))
Error::Stream(io::Error::new(
io::ErrorKind::ConnectionAborted,
"unexpected EOF observed",
))
}
}
} else {
@ -1685,8 +1775,10 @@ impl<S> SslStream<S> {
let err = match self.get_bio_error() {
Some(err) => err,
None => {
io::Error::new(io::ErrorKind::Other,
"BUG: got an SSL_ERROR_WANT_WRITE with no error in the BIO")
io::Error::new(
io::ErrorKind::Other,
"BUG: got an SSL_ERROR_WANT_WRITE with no error in the BIO",
)
}
};
Error::WantWrite(err)
@ -1695,15 +1787,19 @@ impl<S> SslStream<S> {
let err = match self.get_bio_error() {
Some(err) => err,
None => {
io::Error::new(io::ErrorKind::Other,
"BUG: got an SSL_ERROR_WANT_WRITE with no error in the BIO")
io::Error::new(
io::ErrorKind::Other,
"BUG: got an SSL_ERROR_WANT_WRITE with no error in the BIO",
)
}
};
Error::WantRead(err)
}
err => {
Error::Stream(io::Error::new(io::ErrorKind::InvalidData,
format!("unexpected error {}", err)))
Error::Stream(io::Error::new(
io::ErrorKind::InvalidData,
format!("unexpected error {}", err),
))
}
}
}
@ -1760,13 +1856,12 @@ impl<S: Read + Write> Read for SslStream<S> {
impl<S: Read + Write> Write for SslStream<S> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.ssl_write(buf)
.map_err(|e| match e {
Error::Stream(e) => e,
Error::WantRead(e) => e,
Error::WantWrite(e) => e,
e => io::Error::new(io::ErrorKind::Other, e),
})
self.ssl_write(buf).map_err(|e| match e {
Error::Stream(e) => e,
Error::WantRead(e) => e,
Error::WantWrite(e) => e,
e => io::Error::new(io::ErrorKind::Other, e),
})
}
fn flush(&mut self) -> io::Result<()> {
@ -1795,21 +1890,25 @@ mod compat {
SSL_SESSION_get_master_key, SSL_is_server, SSL_SESSION_up_ref};
pub unsafe fn get_new_idx(f: ffi::CRYPTO_EX_free) -> c_int {
ffi::CRYPTO_get_ex_new_index(ffi::CRYPTO_EX_INDEX_SSL_CTX,
0,
ptr::null_mut(),
None,
None,
Some(f))
ffi::CRYPTO_get_ex_new_index(
ffi::CRYPTO_EX_INDEX_SSL_CTX,
0,
ptr::null_mut(),
None,
None,
Some(f),
)
}
pub unsafe fn get_new_ssl_idx(f: ffi::CRYPTO_EX_free) -> c_int {
ffi::CRYPTO_get_ex_new_index(ffi::CRYPTO_EX_INDEX_SSL,
0,
ptr::null_mut(),
None,
None,
Some(f))
ffi::CRYPTO_get_ex_new_index(
ffi::CRYPTO_EX_INDEX_SSL,
0,
ptr::null_mut(),
None,
None,
Some(f),
)
}
pub fn tls_method() -> *const ffi::SSL_METHOD {
@ -1834,17 +1933,21 @@ mod compat {
}
pub unsafe fn SSL_CTX_set_options(ctx: *const ffi::SSL_CTX, op: c_ulong) -> c_ulong {
ffi::SSL_CTX_ctrl(ctx as *mut _,
ffi::SSL_CTRL_OPTIONS,
op as c_long,
ptr::null_mut()) as c_ulong
ffi::SSL_CTX_ctrl(
ctx as *mut _,
ffi::SSL_CTRL_OPTIONS,
op as c_long,
ptr::null_mut(),
) as c_ulong
}
pub unsafe fn SSL_CTX_clear_options(ctx: *const ffi::SSL_CTX, op: c_ulong) -> c_ulong {
ffi::SSL_CTX_ctrl(ctx as *mut _,
ffi::SSL_CTRL_CLEAR_OPTIONS,
op as c_long,
ptr::null_mut()) as c_ulong
ffi::SSL_CTX_ctrl(
ctx as *mut _,
ffi::SSL_CTRL_CLEAR_OPTIONS,
op as c_long,
ptr::null_mut(),
) as c_ulong
}
pub unsafe fn get_new_idx(f: ffi::CRYPTO_EX_free) -> c_int {
@ -1856,18 +1959,21 @@ mod compat {
}
pub unsafe fn SSL_CTX_up_ref(ssl: *mut ffi::SSL_CTX) -> libc::c_int {
ffi::CRYPTO_add_lock(&mut (*ssl).references,
1,
ffi::CRYPTO_LOCK_SSL_CTX,
"mod.rs\0".as_ptr() as *const _,
line!() as libc::c_int);
ffi::CRYPTO_add_lock(
&mut (*ssl).references,
1,
ffi::CRYPTO_LOCK_SSL_CTX,
"mod.rs\0".as_ptr() as *const _,
line!() as libc::c_int,
);
0
}
pub unsafe fn SSL_SESSION_get_master_key(session: *const ffi::SSL_SESSION,
out: *mut c_uchar,
mut outlen: size_t)
-> size_t {
pub unsafe fn SSL_SESSION_get_master_key(
session: *const ffi::SSL_SESSION,
out: *mut c_uchar,
mut outlen: size_t,
) -> size_t {
if outlen == 0 {
return (*session).master_key_length as size_t;
}
@ -1891,11 +1997,13 @@ mod compat {
}
pub unsafe fn SSL_SESSION_up_ref(ses: *mut ffi::SSL_SESSION) -> c_int {
ffi::CRYPTO_add_lock(&mut (*ses).references,
1,
ffi::CRYPTO_LOCK_SSL_CTX,
"mod.rs\0".as_ptr() as *const _,
line!() as libc::c_int);
ffi::CRYPTO_add_lock(
&mut (*ses).references,
1,
ffi::CRYPTO_LOCK_SSL_CTX,
"mod.rs\0".as_ptr() as *const _,
line!() as libc::c_int,
);
0
}
}

View File

@ -19,8 +19,8 @@ use hash::MessageDigest;
use ocsp::{OcspResponse, RESPONSE_STATUS_UNAUTHORIZED};
use ssl;
use ssl::{SslMethod, HandshakeError, SslContext, SslStream, Ssl, ShutdownResult,
SslConnectorBuilder, SslAcceptorBuilder, Error, SSL_VERIFY_PEER, SSL_VERIFY_NONE,
STATUS_TYPE_OCSP};
SslConnectorBuilder, SslAcceptorBuilder, Error, SSL_VERIFY_PEER, SSL_VERIFY_NONE,
STATUS_TYPE_OCSP};
use x509::{X509StoreContext, X509, X509Name, X509_FILETYPE_PEM};
#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))]
use x509::verify::X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS;
@ -75,11 +75,13 @@ impl Server {
if let Some(mut input) = input {
thread::spawn(move || input(stdin));
}
(Server {
p: child,
_temp: td,
},
addr)
(
Server {
p: child,
_temp: td,
},
addr,
)
}
fn new_tcp(args: &[&str]) -> (Server, TcpStream) {
@ -102,26 +104,31 @@ impl Server {
#[allow(dead_code)]
fn new_alpn() -> (Server, TcpStream) {
Server::new_tcp(&["-www",
"-nextprotoneg",
"http/1.1,spdy/3.1",
"-alpn",
"http/1.1,spdy/3.1"])
Server::new_tcp(
&[
"-www",
"-nextprotoneg",
"http/1.1,spdy/3.1",
"-alpn",
"http/1.1,spdy/3.1",
],
)
}
fn new_dtlsv1<I>(input: I) -> (Server, UdpConnected)
where I: IntoIterator<Item = &'static str>,
I::IntoIter: Send + 'static
where
I: IntoIterator<Item = &'static str>,
I::IntoIter: Send + 'static,
{
let mut input = input.into_iter();
let (s, addr) = Server::spawn(&["-dtls1"],
Some(Box::new(move |mut io| {
for s in input.by_ref() {
let (s, addr) = Server::spawn(
&["-dtls1"],
Some(Box::new(move |mut io| for s in input.by_ref() {
if io.write_all(s.as_bytes()).is_err() {
break;
}
}
})));
})),
);
// Need to wait for the UDP socket to get bound in our child process,
// but don't currently have a great way to do that so just wait for a
// bit.
@ -199,9 +206,10 @@ macro_rules! run_test(
);
);
run_test!(new_ctx, |method, _| {
SslContext::builder(method).unwrap();
});
run_test!(
new_ctx,
|method, _| { SslContext::builder(method).unwrap(); }
);
run_test!(verify_untrusted, |method, stream| {
let mut ctx = SslContext::builder(method).unwrap();
@ -325,10 +333,10 @@ run_test!(verify_trusted_get_error_err, |method, stream| {
run_test!(verify_callback_data, |method, stream| {
let mut ctx = SslContext::builder(method).unwrap();
// Node id was generated as SHA256 hash of certificate "test/cert.pem"
// in DER format.
// Command: openssl x509 -in test/cert.pem -outform DER | openssl dgst -sha256
// Please update if "test/cert.pem" will ever change
// Node id was generated as SHA256 hash of certificate "test/cert.pem"
// in DER format.
// Command: openssl x509 -in test/cert.pem -outform DER | openssl dgst -sha256
// Please update if "test/cert.pem" will ever change
let node_hash_str = "59172d9313e84459bcff27f967e79e6e9217e584";
let node_id = Vec::from_hex(node_hash_str).unwrap();
ctx.set_verify_callback(SSL_VERIFY_PEER, move |_preverify_ok, x509_ctx| {
@ -395,8 +403,10 @@ fn test_write_hits_stream() {
let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
ctx.set_verify(SSL_VERIFY_PEER);
ctx.set_certificate_file(&Path::new("test/cert.pem"), X509_FILETYPE_PEM).unwrap();
ctx.set_private_key_file(&Path::new("test/key.pem"), X509_FILETYPE_PEM).unwrap();
ctx.set_certificate_file(&Path::new("test/cert.pem"), X509_FILETYPE_PEM)
.unwrap();
ctx.set_private_key_file(&Path::new("test/key.pem"), X509_FILETYPE_PEM)
.unwrap();
let stream = listener.accept().unwrap().0;
let mut stream = Ssl::new(&ctx.build()).unwrap().accept(stream).unwrap();
@ -488,7 +498,9 @@ fn test_read() {
let mut stream = Ssl::new(&ctx.build()).unwrap().connect(tcp).unwrap();
stream.write_all("GET /\r\n\r\n".as_bytes()).unwrap();
stream.flush().unwrap();
io::copy(&mut stream, &mut io::sink()).ok().expect("read error");
io::copy(&mut stream, &mut io::sink()).ok().expect(
"read error",
);
}
#[test]
@ -521,8 +533,10 @@ fn test_state() {
let ctx = SslContext::builder(SslMethod::tls()).unwrap();
let stream = Ssl::new(&ctx.build()).unwrap().connect(tcp).unwrap();
assert_eq!(stream.ssl().state_string(), "SSLOK ");
assert_eq!(stream.ssl().state_string_long(),
"SSL negotiation finished successfully");
assert_eq!(
stream.ssl().state_string_long(),
"SSL negotiation finished successfully"
);
}
/// Tests that connecting with the client using ALPN, but the server not does not
@ -670,8 +684,10 @@ fn test_npn_server_advertise_multiple() {
let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
ctx.set_verify(SSL_VERIFY_PEER);
ctx.set_npn_protocols(&[b"http/1.1", b"spdy/3.1"]).unwrap();
assert!(ctx.set_certificate_file(&Path::new("test/cert.pem"), X509_FILETYPE_PEM)
.is_ok());
assert!(
ctx.set_certificate_file(&Path::new("test/cert.pem"), X509_FILETYPE_PEM)
.is_ok()
);
ctx.set_private_key_file(&Path::new("test/key.pem"), X509_FILETYPE_PEM)
.unwrap();
ctx.build()
@ -711,8 +727,10 @@ fn test_alpn_server_advertise_multiple() {
let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
ctx.set_verify(SSL_VERIFY_PEER);
ctx.set_alpn_protocols(&[b"http/1.1", b"spdy/3.1"]).unwrap();
assert!(ctx.set_certificate_file(&Path::new("test/cert.pem"), X509_FILETYPE_PEM)
.is_ok());
assert!(
ctx.set_certificate_file(&Path::new("test/cert.pem"), X509_FILETYPE_PEM)
.is_ok()
);
ctx.set_private_key_file(&Path::new("test/key.pem"), X509_FILETYPE_PEM)
.unwrap();
ctx.build()
@ -752,8 +770,10 @@ fn test_alpn_server_select_none() {
let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
ctx.set_verify(SSL_VERIFY_PEER);
ctx.set_alpn_protocols(&[b"http/1.1", b"spdy/3.1"]).unwrap();
assert!(ctx.set_certificate_file(&Path::new("test/cert.pem"), X509_FILETYPE_PEM)
.is_ok());
assert!(
ctx.set_certificate_file(&Path::new("test/cert.pem"), X509_FILETYPE_PEM)
.is_ok()
);
ctx.set_private_key_file(&Path::new("test/key.pem"), X509_FILETYPE_PEM)
.unwrap();
ctx.build()
@ -990,7 +1010,11 @@ fn flush_panic() {
let stream = ExplodingStream(stream);
let ctx = SslContext::builder(SslMethod::tls()).unwrap();
let mut stream = Ssl::new(&ctx.build()).unwrap().connect(stream).ok().unwrap();
let mut stream = Ssl::new(&ctx.build())
.unwrap()
.connect(stream)
.ok()
.unwrap();
let _ = stream.flush();
}
@ -1040,7 +1064,9 @@ fn verify_valid_hostname() {
ctx.set_verify(SSL_VERIFY_PEER);
let mut ssl = Ssl::new(&ctx.build()).unwrap();
ssl.param_mut().set_hostflags(X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
ssl.param_mut().set_hostflags(
X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS,
);
ssl.param_mut().set_host("google.com").unwrap();
let s = TcpStream::connect("google.com:443").unwrap();
@ -1063,7 +1089,9 @@ fn verify_invalid_hostname() {
ctx.set_verify(SSL_VERIFY_PEER);
let mut ssl = Ssl::new(&ctx.build()).unwrap();
ssl.param_mut().set_hostflags(X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
ssl.param_mut().set_hostflags(
X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS,
);
ssl.param_mut().set_host("foobar.com").unwrap();
let s = TcpStream::connect("google.com:443").unwrap();
@ -1143,7 +1171,10 @@ fn connector_client_server_mozilla_intermediate() {
});
let mut connector = SslConnectorBuilder::new(SslMethod::tls()).unwrap();
connector.builder_mut().set_ca_file("test/root-ca.pem").unwrap();
connector
.builder_mut()
.set_ca_file("test/root-ca.pem")
.unwrap();
let connector = connector.build();
let stream = TcpStream::connect(("127.0.0.1", port)).unwrap();
@ -1175,7 +1206,10 @@ fn connector_client_server_mozilla_modern() {
});
let mut connector = SslConnectorBuilder::new(SslMethod::tls()).unwrap();
connector.builder_mut().set_ca_file("test/root-ca.pem").unwrap();
connector
.builder_mut()
.set_ca_file("test/root-ca.pem")
.unwrap();
let connector = connector.build();
let stream = TcpStream::connect(("127.0.0.1", port)).unwrap();
@ -1196,8 +1230,10 @@ fn shutdown() {
thread::spawn(move || {
let stream = listener.accept().unwrap().0;
let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
ctx.set_certificate_file(&Path::new("test/cert.pem"), X509_FILETYPE_PEM).unwrap();
ctx.set_private_key_file(&Path::new("test/key.pem"), X509_FILETYPE_PEM).unwrap();
ctx.set_certificate_file(&Path::new("test/cert.pem"), X509_FILETYPE_PEM)
.unwrap();
ctx.set_private_key_file(&Path::new("test/key.pem"), X509_FILETYPE_PEM)
.unwrap();
let ssl = Ssl::new(&ctx.build()).unwrap();
let mut stream = ssl.accept(stream).unwrap();
@ -1249,11 +1285,13 @@ fn tmp_dh_callback() {
let listener = TcpListener::bind("127.0.0.1:0").unwrap();
let port = listener.local_addr().unwrap().port();
thread::spawn(move ||{
thread::spawn(move || {
let stream = listener.accept().unwrap().0;
let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
ctx.set_certificate_file(&Path::new("test/cert.pem"), X509_FILETYPE_PEM).unwrap();
ctx.set_private_key_file(&Path::new("test/key.pem"), X509_FILETYPE_PEM).unwrap();
ctx.set_certificate_file(&Path::new("test/cert.pem"), X509_FILETYPE_PEM)
.unwrap();
ctx.set_private_key_file(&Path::new("test/key.pem"), X509_FILETYPE_PEM)
.unwrap();
ctx.set_tmp_dh_callback(|_, _, _| {
CALLED_BACK.store(true, Ordering::SeqCst);
let dh = include_bytes!("../../../test/dhparams.pem");
@ -1283,11 +1321,13 @@ fn tmp_ecdh_callback() {
let listener = TcpListener::bind("127.0.0.1:0").unwrap();
let port = listener.local_addr().unwrap().port();
thread::spawn(move ||{
thread::spawn(move || {
let stream = listener.accept().unwrap().0;
let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
ctx.set_certificate_file(&Path::new("test/cert.pem"), X509_FILETYPE_PEM).unwrap();
ctx.set_private_key_file(&Path::new("test/key.pem"), X509_FILETYPE_PEM).unwrap();
ctx.set_certificate_file(&Path::new("test/cert.pem"), X509_FILETYPE_PEM)
.unwrap();
ctx.set_private_key_file(&Path::new("test/key.pem"), X509_FILETYPE_PEM)
.unwrap();
ctx.set_tmp_ecdh_callback(|_, _, _| {
CALLED_BACK.store(true, Ordering::SeqCst);
EcKey::new_by_curve_name(nid::X9_62_PRIME256V1)
@ -1312,11 +1352,13 @@ fn tmp_dh_callback_ssl() {
let listener = TcpListener::bind("127.0.0.1:0").unwrap();
let port = listener.local_addr().unwrap().port();
thread::spawn(move ||{
thread::spawn(move || {
let stream = listener.accept().unwrap().0;
let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
ctx.set_certificate_file(&Path::new("test/cert.pem"), X509_FILETYPE_PEM).unwrap();
ctx.set_private_key_file(&Path::new("test/key.pem"), X509_FILETYPE_PEM).unwrap();
ctx.set_certificate_file(&Path::new("test/cert.pem"), X509_FILETYPE_PEM)
.unwrap();
ctx.set_private_key_file(&Path::new("test/key.pem"), X509_FILETYPE_PEM)
.unwrap();
let mut ssl = Ssl::new(&ctx.build()).unwrap();
ssl.set_tmp_dh_callback(|_, _, _| {
CALLED_BACK.store(true, Ordering::SeqCst);
@ -1346,11 +1388,13 @@ fn tmp_ecdh_callback_ssl() {
let listener = TcpListener::bind("127.0.0.1:0").unwrap();
let port = listener.local_addr().unwrap().port();
thread::spawn(move ||{
thread::spawn(move || {
let stream = listener.accept().unwrap().0;
let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
ctx.set_certificate_file(&Path::new("test/cert.pem"), X509_FILETYPE_PEM).unwrap();
ctx.set_private_key_file(&Path::new("test/key.pem"), X509_FILETYPE_PEM).unwrap();
ctx.set_certificate_file(&Path::new("test/cert.pem"), X509_FILETYPE_PEM)
.unwrap();
ctx.set_private_key_file(&Path::new("test/key.pem"), X509_FILETYPE_PEM)
.unwrap();
let mut ssl = Ssl::new(&ctx.build()).unwrap();
ssl.set_tmp_ecdh_callback(|_, _, _| {
CALLED_BACK.store(true, Ordering::SeqCst);
@ -1402,8 +1446,10 @@ fn status_callbacks() {
let guard = thread::spawn(move || {
let stream = listener.accept().unwrap().0;
let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
ctx.set_certificate_file(&Path::new("test/cert.pem"), X509_FILETYPE_PEM).unwrap();
ctx.set_private_key_file(&Path::new("test/key.pem"), X509_FILETYPE_PEM).unwrap();
ctx.set_certificate_file(&Path::new("test/cert.pem"), X509_FILETYPE_PEM)
.unwrap();
ctx.set_private_key_file(&Path::new("test/key.pem"), X509_FILETYPE_PEM)
.unwrap();
ctx.set_status_callback(|ssl| {
CALLED_BACK_SERVER.store(true, Ordering::SeqCst);
let response = OcspResponse::create(RESPONSE_STATUS_UNAUTHORIZED, None).unwrap();

View File

@ -15,12 +15,13 @@ mod imp {
}
}
pub unsafe fn select<F: AsRawFd>(max: &F,
read: *mut fd_set,
write: *mut fd_set,
error: *mut fd_set,
timeout_ms: u32)
-> io::Result<bool> {
pub unsafe fn select<F: AsRawFd>(
max: &F,
read: *mut fd_set,
write: *mut fd_set,
error: *mut fd_set,
timeout_ms: u32,
) -> io::Result<bool> {
let mut timeout = libc::timeval {
tv_sec: (timeout_ms / 1000) as libc::time_t,
tv_usec: (timeout_ms % 1000 * 1000) as libc::suseconds_t,
@ -52,12 +53,13 @@ mod imp {
set.fd_count += 1;
}
pub unsafe fn select<F: AsRawSocket>(_max: &F,
read: *mut fd_set,
write: *mut fd_set,
error: *mut fd_set,
timeout_ms: u32)
-> io::Result<bool> {
pub unsafe fn select<F: AsRawSocket>(
_max: &F,
read: *mut fd_set,
write: *mut fd_set,
error: *mut fd_set,
timeout_ms: u32,
) -> io::Result<bool> {
let mut timeout = winsock2::timeval {
tv_sec: (timeout_ms / 1000) as c_long,
tv_usec: (timeout_ms % 1000 * 1000) as c_long,

View File

@ -86,8 +86,11 @@ impl<T: Stackable> ForeignType for Stack<T> {
#[inline]
unsafe fn from_ptr(ptr: *mut T::StackType) -> Stack<T> {
assert!(!ptr.is_null(), "Must not instantiate a Stack from a null-ptr - use Stack::new() in \
that case");
assert!(
!ptr.is_null(),
"Must not instantiate a Stack from a null-ptr - use Stack::new() in \
that case"
);
Stack(ptr)
}
@ -217,7 +220,9 @@ impl<T: Stackable> StackRef<T> {
/// Pushes a value onto the top of the stack.
pub fn push(&mut self, data: T) -> Result<(), ErrorStack> {
unsafe {
try!(cvt(OPENSSL_sk_push(self.as_stack(), data.as_ptr() as *mut _)));
try!(cvt(
OPENSSL_sk_push(self.as_stack(), data.as_ptr() as *mut _),
));
mem::forget(data);
Ok(())
}
@ -292,7 +297,8 @@ impl<'a, T: Stackable> iter::IntoIterator for &'a mut Stack<T> {
/// An iterator over the stack's contents.
pub struct Iter<'a, T: Stackable>
where T: 'a
where
T: 'a,
{
stack: &'a StackRef<T>,
pos: usize,

View File

@ -74,7 +74,9 @@ unsafe fn free(buf: *mut c_char) {
#[cfg(ossl110)]
unsafe fn free(buf: *mut c_char) {
::ffi::CRYPTO_free(buf as *mut c_void,
concat!(file!(), "\0").as_ptr() as *const c_char,
line!() as ::libc::c_int);
::ffi::CRYPTO_free(
buf as *mut c_void,
concat!(file!(), "\0").as_ptr() as *const c_char,
line!() as ::libc::c_int,
);
}

View File

@ -164,11 +164,12 @@ impl Crypter {
/// # Panics
///
/// Panics if an IV is required by the cipher but not provided.
pub fn new(t: Cipher,
mode: Mode,
key: &[u8],
iv: Option<&[u8]>)
-> Result<Crypter, ErrorStack> {
pub fn new(
t: Cipher,
mode: Mode,
key: &[u8],
iv: Option<&[u8]>,
) -> Result<Crypter, ErrorStack> {
ffi::init();
unsafe {
@ -183,37 +184,46 @@ impl Crypter {
Mode::Decrypt => 0,
};
try!(cvt(ffi::EVP_CipherInit_ex(crypter.ctx,
t.as_ptr(),
ptr::null_mut(),
ptr::null_mut(),
ptr::null_mut(),
mode)));
try!(cvt(ffi::EVP_CipherInit_ex(
crypter.ctx,
t.as_ptr(),
ptr::null_mut(),
ptr::null_mut(),
ptr::null_mut(),
mode,
)));
assert!(key.len() <= c_int::max_value() as usize);
try!(cvt(ffi::EVP_CIPHER_CTX_set_key_length(crypter.ctx, key.len() as c_int)));
try!(cvt(ffi::EVP_CIPHER_CTX_set_key_length(
crypter.ctx,
key.len() as c_int,
)));
let key = key.as_ptr() as *mut _;
let iv = match (iv, t.iv_len()) {
(Some(iv), Some(len)) => {
if iv.len() != len {
assert!(iv.len() <= c_int::max_value() as usize);
try!(cvt(ffi::EVP_CIPHER_CTX_ctrl(crypter.ctx,
ffi::EVP_CTRL_GCM_SET_IVLEN,
iv.len() as c_int,
ptr::null_mut())));
try!(cvt(ffi::EVP_CIPHER_CTX_ctrl(
crypter.ctx,
ffi::EVP_CTRL_GCM_SET_IVLEN,
iv.len() as c_int,
ptr::null_mut(),
)));
}
iv.as_ptr() as *mut _
}
(Some(_), None) | (None, None) => ptr::null_mut(),
(None, Some(_)) => panic!("an IV is required for this cipher"),
};
try!(cvt(ffi::EVP_CipherInit_ex(crypter.ctx,
ptr::null(),
ptr::null_mut(),
key,
iv,
mode)));
try!(cvt(ffi::EVP_CipherInit_ex(
crypter.ctx,
ptr::null(),
ptr::null_mut(),
key,
iv,
mode,
)));
Ok(crypter)
}
@ -236,11 +246,12 @@ impl Crypter {
unsafe {
assert!(tag.len() <= c_int::max_value() as usize);
// NB: this constant is actually more general than just GCM.
cvt(ffi::EVP_CIPHER_CTX_ctrl(self.ctx,
ffi::EVP_CTRL_GCM_SET_TAG,
tag.len() as c_int,
tag.as_ptr() as *mut _))
.map(|_| ())
cvt(ffi::EVP_CIPHER_CTX_ctrl(
self.ctx,
ffi::EVP_CTRL_GCM_SET_TAG,
tag.len() as c_int,
tag.as_ptr() as *mut _,
)).map(|_| ())
}
}
@ -253,12 +264,13 @@ impl Crypter {
unsafe {
assert!(input.len() <= c_int::max_value() as usize);
let mut len = 0;
cvt(ffi::EVP_CipherUpdate(self.ctx,
ptr::null_mut(),
&mut len,
input.as_ptr(),
input.len() as c_int))
.map(|_| ())
cvt(ffi::EVP_CipherUpdate(
self.ctx,
ptr::null_mut(),
&mut len,
input.as_ptr(),
input.len() as c_int,
)).map(|_| ())
}
}
@ -280,11 +292,13 @@ impl Crypter {
let mut outl = output.len() as c_int;
let inl = input.len() as c_int;
try!(cvt(ffi::EVP_CipherUpdate(self.ctx,
output.as_mut_ptr(),
&mut outl,
input.as_ptr(),
inl)));
try!(cvt(ffi::EVP_CipherUpdate(
self.ctx,
output.as_mut_ptr(),
&mut outl,
input.as_ptr(),
inl,
)));
Ok(outl as usize)
}
@ -305,7 +319,11 @@ impl Crypter {
assert!(output.len() >= self.block_size);
let mut outl = cmp::min(output.len(), c_int::max_value() as usize) as c_int;
try!(cvt(ffi::EVP_CipherFinal(self.ctx, output.as_mut_ptr(), &mut outl)));
try!(cvt(ffi::EVP_CipherFinal(
self.ctx,
output.as_mut_ptr(),
&mut outl,
)));
Ok(outl as usize)
}
@ -322,11 +340,12 @@ impl Crypter {
pub fn get_tag(&self, tag: &mut [u8]) -> Result<(), ErrorStack> {
unsafe {
assert!(tag.len() <= c_int::max_value() as usize);
cvt(ffi::EVP_CIPHER_CTX_ctrl(self.ctx,
ffi::EVP_CTRL_GCM_GET_TAG,
tag.len() as c_int,
tag.as_mut_ptr() as *mut _))
.map(|_| ())
cvt(ffi::EVP_CIPHER_CTX_ctrl(
self.ctx,
ffi::EVP_CTRL_GCM_GET_TAG,
tag.len() as c_int,
tag.as_mut_ptr() as *mut _,
)).map(|_| ())
}
}
}
@ -339,36 +358,39 @@ impl Drop for Crypter {
}
}
/**
#[doc = /**
* Encrypts data, using the specified crypter type in encrypt mode with the
* specified key and iv; returns the resulting (encrypted) data.
*/
pub fn encrypt(t: Cipher,
key: &[u8],
iv: Option<&[u8]>,
data: &[u8])
-> Result<Vec<u8>, ErrorStack> {
*/]
pub fn encrypt(
t: Cipher,
key: &[u8],
iv: Option<&[u8]>,
data: &[u8],
) -> Result<Vec<u8>, ErrorStack> {
cipher(t, Mode::Encrypt, key, iv, data)
}
/**
#[doc = /**
* Decrypts data, using the specified crypter type in decrypt mode with the
* specified key and iv; returns the resulting (decrypted) data.
*/
pub fn decrypt(t: Cipher,
key: &[u8],
iv: Option<&[u8]>,
data: &[u8])
-> Result<Vec<u8>, ErrorStack> {
*/]
pub fn decrypt(
t: Cipher,
key: &[u8],
iv: Option<&[u8]>,
data: &[u8],
) -> Result<Vec<u8>, ErrorStack> {
cipher(t, Mode::Decrypt, key, iv, data)
}
fn cipher(t: Cipher,
mode: Mode,
key: &[u8],
iv: Option<&[u8]>,
data: &[u8])
-> Result<Vec<u8>, ErrorStack> {
fn cipher(
t: Cipher,
mode: Mode,
key: &[u8],
iv: Option<&[u8]>,
data: &[u8],
) -> Result<Vec<u8>, ErrorStack> {
let mut c = try!(Crypter::new(t, mode, key, iv));
let mut out = vec![0; data.len() + t.block_size()];
let count = try!(c.update(data, &mut out));
@ -385,13 +407,14 @@ fn cipher(t: Cipher,
/// The size of the `tag` buffer indicates the required size of the tag. While some ciphers support
/// a range of tag sizes, it is recommended to pick the maximum size. For AES GCM, this is 16 bytes,
/// for example.
pub fn encrypt_aead(t: Cipher,
key: &[u8],
iv: Option<&[u8]>,
aad: &[u8],
data: &[u8],
tag: &mut [u8])
-> Result<Vec<u8>, ErrorStack> {
pub fn encrypt_aead(
t: Cipher,
key: &[u8],
iv: Option<&[u8]>,
aad: &[u8],
data: &[u8],
tag: &mut [u8],
) -> Result<Vec<u8>, ErrorStack> {
let mut c = try!(Crypter::new(t, Mode::Encrypt, key, iv));
let mut out = vec![0; data.len() + t.block_size()];
try!(c.aad_update(aad));
@ -406,13 +429,14 @@ pub fn encrypt_aead(t: Cipher,
///
/// Additional Authenticated Data can be provided in the `aad` field, and the authentication tag
/// should be provided in the `tag` field.
pub fn decrypt_aead(t: Cipher,
key: &[u8],
iv: Option<&[u8]>,
aad: &[u8],
data: &[u8],
tag: &[u8])
-> Result<Vec<u8>, ErrorStack> {
pub fn decrypt_aead(
t: Cipher,
key: &[u8],
iv: Option<&[u8]>,
aad: &[u8],
data: &[u8],
tag: &[u8],
) -> Result<Vec<u8>, ErrorStack> {
let mut c = try!(Crypter::new(t, Mode::Decrypt, key, iv));
let mut out = vec![0; data.len() + t.block_size()];
try!(c.aad_update(aad));
@ -456,19 +480,82 @@ mod tests {
// http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
#[test]
fn test_aes_256_ecb() {
let k0 = [0x00u8, 0x01u8, 0x02u8, 0x03u8, 0x04u8, 0x05u8, 0x06u8, 0x07u8, 0x08u8, 0x09u8,
0x0au8, 0x0bu8, 0x0cu8, 0x0du8, 0x0eu8, 0x0fu8, 0x10u8, 0x11u8, 0x12u8, 0x13u8,
0x14u8, 0x15u8, 0x16u8, 0x17u8, 0x18u8, 0x19u8, 0x1au8, 0x1bu8, 0x1cu8, 0x1du8,
0x1eu8, 0x1fu8];
let p0 = [0x00u8, 0x11u8, 0x22u8, 0x33u8, 0x44u8, 0x55u8, 0x66u8, 0x77u8, 0x88u8, 0x99u8,
0xaau8, 0xbbu8, 0xccu8, 0xddu8, 0xeeu8, 0xffu8];
let c0 = [0x8eu8, 0xa2u8, 0xb7u8, 0xcau8, 0x51u8, 0x67u8, 0x45u8, 0xbfu8, 0xeau8, 0xfcu8,
0x49u8, 0x90u8, 0x4bu8, 0x49u8, 0x60u8, 0x89u8];
let mut c = super::Crypter::new(super::Cipher::aes_256_ecb(),
super::Mode::Encrypt,
&k0,
None)
.unwrap();
let k0 = [
0x00u8,
0x01u8,
0x02u8,
0x03u8,
0x04u8,
0x05u8,
0x06u8,
0x07u8,
0x08u8,
0x09u8,
0x0au8,
0x0bu8,
0x0cu8,
0x0du8,
0x0eu8,
0x0fu8,
0x10u8,
0x11u8,
0x12u8,
0x13u8,
0x14u8,
0x15u8,
0x16u8,
0x17u8,
0x18u8,
0x19u8,
0x1au8,
0x1bu8,
0x1cu8,
0x1du8,
0x1eu8,
0x1fu8,
];
let p0 = [
0x00u8,
0x11u8,
0x22u8,
0x33u8,
0x44u8,
0x55u8,
0x66u8,
0x77u8,
0x88u8,
0x99u8,
0xaau8,
0xbbu8,
0xccu8,
0xddu8,
0xeeu8,
0xffu8,
];
let c0 = [
0x8eu8,
0xa2u8,
0xb7u8,
0xcau8,
0x51u8,
0x67u8,
0x45u8,
0xbfu8,
0xeau8,
0xfcu8,
0x49u8,
0x90u8,
0x4bu8,
0x49u8,
0x60u8,
0x89u8,
];
let mut c = super::Crypter::new(
super::Cipher::aes_256_ecb(),
super::Mode::Encrypt,
&k0,
None,
).unwrap();
c.pad(false);
let mut r0 = vec![0; c0.len() + super::Cipher::aes_256_ecb().block_size()];
let count = c.update(&p0, &mut r0).unwrap();
@ -476,11 +563,12 @@ mod tests {
r0.truncate(count + rest);
assert_eq!(r0.to_hex(), c0.to_hex());
let mut c = super::Crypter::new(super::Cipher::aes_256_ecb(),
super::Mode::Decrypt,
&k0,
None)
.unwrap();
let mut c = super::Crypter::new(
super::Cipher::aes_256_ecb(),
super::Mode::Decrypt,
&k0,
None,
).unwrap();
c.pad(false);
let mut p1 = vec![0; r0.len() + super::Cipher::aes_256_ecb().block_size()];
let count = c.update(&r0, &mut p1).unwrap();
@ -491,20 +579,82 @@ mod tests {
#[test]
fn test_aes_256_cbc_decrypt() {
let iv = [4_u8, 223_u8, 153_u8, 219_u8, 28_u8, 142_u8, 234_u8, 68_u8, 227_u8, 69_u8,
98_u8, 107_u8, 208_u8, 14_u8, 236_u8, 60_u8];
let data = [143_u8, 210_u8, 75_u8, 63_u8, 214_u8, 179_u8, 155_u8, 241_u8, 242_u8, 31_u8,
154_u8, 56_u8, 198_u8, 145_u8, 192_u8, 64_u8, 2_u8, 245_u8, 167_u8, 220_u8,
55_u8, 119_u8, 233_u8, 136_u8, 139_u8, 27_u8, 71_u8, 242_u8, 119_u8, 175_u8,
65_u8, 207_u8];
let ciphered_data = [0x4a_u8, 0x2e_u8, 0xe5_u8, 0x6_u8, 0xbf_u8, 0xcf_u8, 0xf2_u8,
0xd7_u8, 0xea_u8, 0x2d_u8, 0xb1_u8, 0x85_u8, 0x6c_u8, 0x93_u8,
0x65_u8, 0x6f_u8];
let mut cr = super::Crypter::new(super::Cipher::aes_256_cbc(),
super::Mode::Decrypt,
&data,
Some(&iv))
.unwrap();
let iv = [
4_u8,
223_u8,
153_u8,
219_u8,
28_u8,
142_u8,
234_u8,
68_u8,
227_u8,
69_u8,
98_u8,
107_u8,
208_u8,
14_u8,
236_u8,
60_u8,
];
let data = [
143_u8,
210_u8,
75_u8,
63_u8,
214_u8,
179_u8,
155_u8,
241_u8,
242_u8,
31_u8,
154_u8,
56_u8,
198_u8,
145_u8,
192_u8,
64_u8,
2_u8,
245_u8,
167_u8,
220_u8,
55_u8,
119_u8,
233_u8,
136_u8,
139_u8,
27_u8,
71_u8,
242_u8,
119_u8,
175_u8,
65_u8,
207_u8,
];
let ciphered_data = [
0x4a_u8,
0x2e_u8,
0xe5_u8,
0x6_u8,
0xbf_u8,
0xcf_u8,
0xf2_u8,
0xd7_u8,
0xea_u8,
0x2d_u8,
0xb1_u8,
0x85_u8,
0x6c_u8,
0x93_u8,
0x65_u8,
0x6f_u8,
];
let mut cr = super::Crypter::new(
super::Cipher::aes_256_cbc(),
super::Mode::Decrypt,
&data,
Some(&iv),
).unwrap();
cr.pad(false);
let mut unciphered_data = vec![0; data.len() + super::Cipher::aes_256_cbc().block_size()];
let count = cr.update(&ciphered_data, &mut unciphered_data).unwrap();
@ -529,9 +679,11 @@ mod tests {
println!("Computed: {}", computed.to_hex());
println!("Expected: {}", expected.to_hex());
if computed.len() != expected.len() {
println!("Lengths differ: {} in computed vs {} expected",
computed.len(),
expected.len());
println!(
"Lengths differ: {} in computed vs {} expected",
computed.len(),
expected.len()
);
}
panic!("test failure");
}
@ -558,9 +710,11 @@ mod tests {
println!("Computed: {}", computed.to_hex());
println!("Expected: {}", expected.to_hex());
if computed.len() != expected.len() {
println!("Lengths differ: {} in computed vs {} expected",
computed.len(),
expected.len());
println!(
"Lengths differ: {} in computed vs {} expected",
computed.len(),
expected.len()
);
}
panic!("test failure");
}
@ -742,41 +896,40 @@ mod tests {
#[test]
fn test_aes128_gcm() {
let key = "0e00c76561d2bd9b40c3c15427e2b08f";
let iv =
"492cadaccd3ca3fbc9cf9f06eb3325c4e159850b0dbe98199b89b7af528806610b6f63998e1eae80c348e7\
let iv = "492cadaccd3ca3fbc9cf9f06eb3325c4e159850b0dbe98199b89b7af528806610b6f63998e1eae80c348e7\
4cbb921d8326631631fc6a5d304f39166daf7ea15fa1977f101819adb510b50fe9932e12c5a85aa3fd1e73\
d8d760af218be829903a77c63359d75edd91b4f6ed5465a72662f5055999e059e7654a8edc921aa0d496";
let pt =
"fef03c2d7fb15bf0d2df18007d99f967c878ad59359034f7bb2c19af120685d78e32f6b8b83b032019956c\
let pt = "fef03c2d7fb15bf0d2df18007d99f967c878ad59359034f7bb2c19af120685d78e32f6b8b83b032019956c\
a9c0195721476b85";
let aad =
"d8f1163d8c840292a2b2dacf4ac7c36aff8733f18fabb4fa5594544125e03d1e6e5d6d0fd61656c8d8f327\
let aad = "d8f1163d8c840292a2b2dacf4ac7c36aff8733f18fabb4fa5594544125e03d1e6e5d6d0fd61656c8d8f327\
c92839ae5539bb469c9257f109ebff85aad7bd220fdaa95c022dbd0c7bb2d878ad504122c943045d3c5eba\
8f1f56c0";
let ct =
"4f6cf471be7cbd2575cd5a1747aea8fe9dea83e51936beac3e68f66206922060c697ffa7af80ad6bb68f2c\
let ct = "4f6cf471be7cbd2575cd5a1747aea8fe9dea83e51936beac3e68f66206922060c697ffa7af80ad6bb68f2c\
f4fc97416ee52abe";
let tag = "e20b6655";
// this tag is smaller than you'd normally want, but I pulled this test from the part of
// the NIST test vectors that cover 4 byte tags.
let mut actual_tag = [0; 4];
let out = encrypt_aead(Cipher::aes_128_gcm(),
&Vec::from_hex(key).unwrap(),
Some(&Vec::from_hex(iv).unwrap()),
&Vec::from_hex(aad).unwrap(),
&Vec::from_hex(pt).unwrap(),
&mut actual_tag)
.unwrap();
let out = encrypt_aead(
Cipher::aes_128_gcm(),
&Vec::from_hex(key).unwrap(),
Some(&Vec::from_hex(iv).unwrap()),
&Vec::from_hex(aad).unwrap(),
&Vec::from_hex(pt).unwrap(),
&mut actual_tag,
).unwrap();
assert_eq!(ct, out.to_hex());
assert_eq!(tag, actual_tag.to_hex());
let out = decrypt_aead(Cipher::aes_128_gcm(),
&Vec::from_hex(key).unwrap(),
Some(&Vec::from_hex(iv).unwrap()),
&Vec::from_hex(aad).unwrap(),
&Vec::from_hex(ct).unwrap(),
&Vec::from_hex(tag).unwrap()).unwrap();
let out = decrypt_aead(
Cipher::aes_128_gcm(),
&Vec::from_hex(key).unwrap(),
Some(&Vec::from_hex(iv).unwrap()),
&Vec::from_hex(aad).unwrap(),
&Vec::from_hex(ct).unwrap(),
&Vec::from_hex(tag).unwrap(),
).unwrap();
assert_eq!(pt, out.to_hex());
}
@ -808,23 +961,25 @@ mod tests {
let tag = "1ae10b594f09e26a7e902ecbd0600691";
let mut actual_tag = [0; 16];
let out = encrypt_aead(Cipher::chacha20_poly1305(),
&Vec::from_hex(key).unwrap(),
Some(&Vec::from_hex(iv).unwrap()),
&Vec::from_hex(aad).unwrap(),
&Vec::from_hex(pt).unwrap(),
&mut actual_tag)
.unwrap();
let out = encrypt_aead(
Cipher::chacha20_poly1305(),
&Vec::from_hex(key).unwrap(),
Some(&Vec::from_hex(iv).unwrap()),
&Vec::from_hex(aad).unwrap(),
&Vec::from_hex(pt).unwrap(),
&mut actual_tag,
).unwrap();
assert_eq!(ct, out.to_hex());
assert_eq!(tag, actual_tag.to_hex());
let out = decrypt_aead(Cipher::chacha20_poly1305(),
&Vec::from_hex(key).unwrap(),
Some(&Vec::from_hex(iv).unwrap()),
&Vec::from_hex(aad).unwrap(),
&Vec::from_hex(ct).unwrap(),
&Vec::from_hex(tag).unwrap())
.unwrap();
let out = decrypt_aead(
Cipher::chacha20_poly1305(),
&Vec::from_hex(key).unwrap(),
Some(&Vec::from_hex(iv).unwrap()),
&Vec::from_hex(aad).unwrap(),
&Vec::from_hex(ct).unwrap(),
&Vec::from_hex(tag).unwrap(),
).unwrap();
assert_eq!(pt, out.to_hex());
}
}

View File

@ -35,12 +35,14 @@ impl<F> Drop for CallbackState<F> {
}
}
pub unsafe extern fn invoke_passwd_cb_old<F>(buf: *mut c_char,
size: c_int,
_rwflag: c_int,
cb_state: *mut c_void)
-> c_int
where F: FnOnce(&mut [c_char]) -> usize
pub unsafe extern "C" fn invoke_passwd_cb_old<F>(
buf: *mut c_char,
size: c_int,
_rwflag: c_int,
cb_state: *mut c_void,
) -> c_int
where
F: FnOnce(&mut [c_char]) -> usize,
{
let callback = &mut *(cb_state as *mut CallbackState<F>);
@ -61,12 +63,14 @@ pub unsafe extern fn invoke_passwd_cb_old<F>(buf: *mut c_char,
/// Password callback function, passed to private key loading functions.
///
/// `cb_state` is expected to be a pointer to a `CallbackState`.
pub unsafe extern fn invoke_passwd_cb<F>(buf: *mut c_char,
size: c_int,
_rwflag: c_int,
cb_state: *mut c_void)
-> c_int
where F: FnOnce(&mut [u8]) -> Result<usize, ErrorStack>
pub unsafe extern "C" fn invoke_passwd_cb<F>(
buf: *mut c_char,
size: c_int,
_rwflag: c_int,
cb_state: *mut c_void,
) -> c_int
where
F: FnOnce(&mut [u8]) -> Result<usize, ErrorStack>,
{
let callback = &mut *(cb_state as *mut CallbackState<F>);

View File

@ -36,10 +36,11 @@ impl X509VerifyParamRef {
pub fn set_host(&mut self, host: &str) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::X509_VERIFY_PARAM_set1_host(self.as_ptr(),
host.as_ptr() as *const _,
host.len()))
.map(|_| ())
cvt(ffi::X509_VERIFY_PARAM_set1_host(
self.as_ptr(),
host.as_ptr() as *const _,
host.len(),
)).map(|_| ())
}
}
}

View File

@ -54,28 +54,48 @@ pub fn number() -> i64 {
/// The text variant of the version number and the release date. For example, "OpenSSL 0.9.5a 1 Apr 2000".
pub fn version() -> &'static str {
unsafe { CStr::from_ptr(OpenSSL_version(OPENSSL_VERSION)).to_str().unwrap() }
unsafe {
CStr::from_ptr(OpenSSL_version(OPENSSL_VERSION))
.to_str()
.unwrap()
}
}
/// The compiler flags set for the compilation process in the form "compiler: ..." if available or
/// "compiler: information not available" otherwise.
pub fn c_flags() -> &'static str {
unsafe { CStr::from_ptr(OpenSSL_version(OPENSSL_CFLAGS)).to_str().unwrap() }
unsafe {
CStr::from_ptr(OpenSSL_version(OPENSSL_CFLAGS))
.to_str()
.unwrap()
}
}
/// The date of the build process in the form "built on: ..." if available or "built on: date not available" otherwise.
pub fn built_on() -> &'static str {
unsafe { CStr::from_ptr(OpenSSL_version(OPENSSL_BUILT_ON)).to_str().unwrap() }
unsafe {
CStr::from_ptr(OpenSSL_version(OPENSSL_BUILT_ON))
.to_str()
.unwrap()
}
}
/// The "Configure" target of the library build in the form "platform: ..." if available or "platform: information not available" otherwise.
pub fn platform() -> &'static str {
unsafe { CStr::from_ptr(OpenSSL_version(OPENSSL_PLATFORM)).to_str().unwrap() }
unsafe {
CStr::from_ptr(OpenSSL_version(OPENSSL_PLATFORM))
.to_str()
.unwrap()
}
}
/// The "OPENSSLDIR" setting of the library build in the form "OPENSSLDIR: "..."" if available or "OPENSSLDIR: N/A" otherwise.
pub fn dir() -> &'static str {
unsafe { CStr::from_ptr(OpenSSL_version(OPENSSL_DIR)).to_str().unwrap() }
unsafe {
CStr::from_ptr(OpenSSL_version(OPENSSL_DIR))
.to_str()
.unwrap()
}
}
/// This test ensures that we do not segfault when calling the functions of this module
@ -90,9 +110,13 @@ fn test_versions() {
println!("Dir: '{}'", dir());
#[cfg(not(libressl))]
fn expected_name() -> &'static str { "OpenSSL" }
fn expected_name() -> &'static str {
"OpenSSL"
}
#[cfg(libressl)]
fn expected_name() -> &'static str { "LibreSSL" }
fn expected_name() -> &'static str {
"LibreSSL"
}
assert!(number() > 0);
assert!(version().starts_with(expected_name()));

View File

@ -8,7 +8,7 @@ use x509::{X509v3Context, X509Extension};
///
/// See the `Extension` documentation for more information on the different
/// variants.
#[derive(Clone,Hash,PartialEq,Eq)]
#[derive(Clone, Hash, PartialEq, Eq)]
#[deprecated(since = "0.9.7", note = "use X509Builder and X509ReqBuilder instead")]
pub enum ExtensionType {
KeyUsage,
@ -113,12 +113,20 @@ impl ToString for Extension {
&Extension::KeyUsage(ref purposes) => join(purposes.iter(), ","),
&Extension::ExtKeyUsage(ref purposes) => join(purposes.iter(), ","),
&Extension::SubjectAltName(ref names) => {
join(names.iter().map(|&(ref opt, ref val)| opt.to_string() + ":" + &val),
",")
join(
names.iter().map(|&(ref opt, ref val)| {
opt.to_string() + ":" + &val
}),
",",
)
}
&Extension::IssuerAltName(ref names) => {
join(names.iter().map(|&(ref opt, ref val)| opt.to_string() + ":" + &val),
",")
join(
names.iter().map(|&(ref opt, ref val)| {
opt.to_string() + ":" + &val
}),
",",
)
}
&Extension::OtherNid(_, ref value) => value.clone(),
&Extension::OtherStr(_, ref value) => value.clone(),
@ -126,7 +134,7 @@ impl ToString for Extension {
}
}
#[derive(Clone,Copy)]
#[derive(Clone, Copy)]
#[deprecated(since = "0.9.7", note = "use X509Builder and X509ReqBuilder instead")]
pub enum KeyUsageOption {
DigitalSignature,
@ -361,10 +369,30 @@ impl KeyUsage {
let mut value = String::new();
let mut first = true;
append(&mut value, &mut first, self.critical, "critical");
append(&mut value, &mut first, self.digital_signature, "digitalSignature");
append(&mut value, &mut first, self.non_repudiation, "nonRepudiation");
append(&mut value, &mut first, self.key_encipherment, "keyEncipherment");
append(&mut value, &mut first, self.data_encipherment, "dataEncipherment");
append(
&mut value,
&mut first,
self.digital_signature,
"digitalSignature",
);
append(
&mut value,
&mut first,
self.non_repudiation,
"nonRepudiation",
);
append(
&mut value,
&mut first,
self.key_encipherment,
"keyEncipherment",
);
append(
&mut value,
&mut first,
self.data_encipherment,
"dataEncipherment",
);
append(&mut value, &mut first, self.key_agreement, "keyAgreement");
append(&mut value, &mut first, self.key_cert_sign, "keyCertSign");
append(&mut value, &mut first, self.crl_sign, "cRLSign");
@ -476,7 +504,12 @@ impl ExtendedKeyUsage {
append(&mut value, &mut first, self.server_auth, "serverAuth");
append(&mut value, &mut first, self.client_auth, "clientAuth");
append(&mut value, &mut first, self.code_signing, "codeSigning");
append(&mut value, &mut first, self.email_protection, "emailProtection");
append(
&mut value,
&mut first,
self.email_protection,
"emailProtection",
);
append(&mut value, &mut first, self.time_stamping, "timeStamping");
append(&mut value, &mut first, self.ms_code_ind, "msCodeInd");
append(&mut value, &mut first, self.ms_code_com, "msCodeCom");
@ -497,9 +530,7 @@ pub struct SubjectKeyIdentifier {
impl SubjectKeyIdentifier {
pub fn new() -> SubjectKeyIdentifier {
SubjectKeyIdentifier {
critical: false,
}
SubjectKeyIdentifier { critical: false }
}
pub fn critical(&mut self) -> &mut SubjectKeyIdentifier {

View File

@ -165,7 +165,8 @@ impl X509Generator {
/// ```
#[deprecated(since = "0.9.7", note = "use X509Builder and X509ReqBuilder instead")]
pub fn add_names<I>(mut self, attrs: I) -> X509Generator
where I: IntoIterator<Item = (String, String)>
where
I: IntoIterator<Item = (String, String)>,
{
self.names.extend(attrs);
self
@ -201,7 +202,8 @@ impl X509Generator {
/// ```
#[deprecated(since = "0.9.7", note = "use X509Builder and X509ReqBuilder instead")]
pub fn add_extensions<I>(mut self, exts: I) -> X509Generator
where I: IntoIterator<Item = extension::Extension>
where
I: IntoIterator<Item = extension::Extension>,
{
for ext in exts {
self.extensions.add(ext);
@ -251,14 +253,21 @@ impl X509Generator {
let extension = match exttype.get_nid() {
Some(nid) => {
let ctx = builder.x509v3_context(None, None);
try!(X509Extension::new_nid(None, Some(&ctx), nid, &ext.to_string()))
try!(X509Extension::new_nid(
None,
Some(&ctx),
nid,
&ext.to_string(),
))
}
None => {
let ctx = builder.x509v3_context(None, None);
try!(X509Extension::new(None,
Some(&ctx),
&exttype.get_name().unwrap(),
&ext.to_string()))
try!(X509Extension::new(
None,
Some(&ctx),
&exttype.get_name().unwrap(),
&ext.to_string(),
))
}
};
try!(builder.append_extension(extension));
@ -277,18 +286,24 @@ impl X509Generator {
};
unsafe {
let req = try!(cvt_p(ffi::X509_to_X509_REQ(cert.as_ptr(),
ptr::null_mut(),
ptr::null())));
let req = try!(cvt_p(ffi::X509_to_X509_REQ(
cert.as_ptr(),
ptr::null_mut(),
ptr::null(),
)));
let req = X509Req::from_ptr(req);
let exts = compat::X509_get0_extensions(cert.as_ptr());
if exts != ptr::null_mut() {
try!(cvt(ffi::X509_REQ_add_extensions(req.as_ptr(), exts as *mut _)));
try!(cvt(
ffi::X509_REQ_add_extensions(req.as_ptr(), exts as *mut _),
));
}
let hash_fn = self.hash_type.as_ptr();
try!(cvt(ffi::X509_REQ_sign(req.as_ptr(), p_key.as_ptr(), hash_fn)));
try!(cvt(
ffi::X509_REQ_sign(req.as_ptr(), p_key.as_ptr(), hash_fn),
));
Ok(req)
}
@ -326,17 +341,23 @@ impl X509Builder {
}
/// Sets the serial number of the certificate.
pub fn set_serial_number(&mut self,
serial_number: &Asn1IntegerRef)
-> Result<(), ErrorStack> {
pub fn set_serial_number(&mut self, serial_number: &Asn1IntegerRef) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::X509_set_serialNumber(self.0.as_ptr(), serial_number.as_ptr())).map(|_| ())
cvt(ffi::X509_set_serialNumber(
self.0.as_ptr(),
serial_number.as_ptr(),
)).map(|_| ())
}
}
/// Sets the issuer name of the certificate.
pub fn set_issuer_name(&mut self, issuer_name: &X509NameRef) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::X509_set_issuer_name(self.0.as_ptr(), issuer_name.as_ptr())).map(|_| ()) }
unsafe {
cvt(ffi::X509_set_issuer_name(
self.0.as_ptr(),
issuer_name.as_ptr(),
)).map(|_| ())
}
}
/// Sets the subject name of the certificate.
@ -359,7 +380,10 @@ impl X509Builder {
/// ```
pub fn set_subject_name(&mut self, subject_name: &X509NameRef) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::X509_set_subject_name(self.0.as_ptr(), subject_name.as_ptr())).map(|_| ())
cvt(ffi::X509_set_subject_name(
self.0.as_ptr(),
subject_name.as_ptr(),
)).map(|_| ())
}
}
@ -371,10 +395,11 @@ impl X509Builder {
/// Returns a context object which is needed to create certain X509 extension values.
///
/// Set `issuer` to `None` if the certificate will be self-signed.
pub fn x509v3_context<'a>(&'a self,
issuer: Option<&'a X509Ref>,
conf: Option<&'a ConfRef>)
-> X509v3Context<'a> {
pub fn x509v3_context<'a>(
&'a self,
issuer: Option<&'a X509Ref>,
conf: Option<&'a ConfRef>,
) -> X509v3Context<'a> {
unsafe {
let mut ctx = mem::zeroed();
@ -383,7 +408,14 @@ impl X509Builder {
None => self.0.as_ptr(),
};
let subject = self.0.as_ptr();
ffi::X509V3_set_ctx(&mut ctx, issuer, subject, ptr::null_mut(), ptr::null_mut(), 0);
ffi::X509V3_set_ctx(
&mut ctx,
issuer,
subject,
ptr::null_mut(),
ptr::null_mut(),
0,
);
// nodb case taken care of since we zeroed ctx above
if let Some(conf) = conf {
@ -397,7 +429,9 @@ impl X509Builder {
/// Adds an X509 extension value to the certificate.
pub fn append_extension(&mut self, extension: X509Extension) -> Result<(), ErrorStack> {
unsafe {
try!(cvt(ffi::X509_add_ext(self.0.as_ptr(), extension.as_ptr(), -1)));
try!(cvt(
ffi::X509_add_ext(self.0.as_ptr(), extension.as_ptr(), -1),
));
mem::forget(extension);
Ok(())
}
@ -433,10 +467,12 @@ impl X509Ref {
/// Returns this certificate's SAN entries, if they exist.
pub fn subject_alt_names(&self) -> Option<Stack<GeneralName>> {
unsafe {
let stack = ffi::X509_get_ext_d2i(self.as_ptr(),
ffi::NID_subject_alt_name,
ptr::null_mut(),
ptr::null_mut());
let stack = ffi::X509_get_ext_d2i(
self.as_ptr(),
ffi::NID_subject_alt_name,
ptr::null_mut(),
ptr::null_mut(),
);
if stack.is_null() {
return None;
}
@ -458,7 +494,12 @@ impl X509Ref {
let evp = hash_type.as_ptr();
let mut len = ffi::EVP_MAX_MD_SIZE;
let mut buf = vec![0u8; len as usize];
try!(cvt(ffi::X509_digest(self.as_ptr(), evp, buf.as_mut_ptr() as *mut _, &mut len)));
try!(cvt(ffi::X509_digest(
self.as_ptr(),
evp,
buf.as_mut_ptr() as *mut _,
&mut len,
)));
buf.truncate(len as usize);
Ok(buf)
}
@ -505,9 +546,7 @@ impl X509Ref {
/// Returns the list of OCSP responder URLs specified in the certificate's Authority Information
/// Access field.
pub fn ocsp_responders(&self) -> Result<Stack<OpensslString>, ErrorStack> {
unsafe {
cvt_p(ffi::X509_get1_ocsp(self.as_ptr())).map(|p| Stack::from_ptr(p))
}
unsafe { cvt_p(ffi::X509_get1_ocsp(self.as_ptr())).map(|p| Stack::from_ptr(p)) }
}
/// Checks that this certificate issued `subject`.
@ -553,14 +592,13 @@ impl X509 {
let mut certs = vec![];
loop {
let r = ffi::PEM_read_bio_X509(bio.as_ptr(),
ptr::null_mut(),
None,
ptr::null_mut());
let r =
ffi::PEM_read_bio_X509(bio.as_ptr(), ptr::null_mut(), None, ptr::null_mut());
if r.is_null() {
let err = ffi::ERR_peek_last_error();
if ffi::ERR_GET_LIB(err) == ffi::ERR_LIB_PEM
&& ffi::ERR_GET_REASON(err) == ffi::PEM_R_NO_START_LINE {
if ffi::ERR_GET_LIB(err) == ffi::ERR_LIB_PEM &&
ffi::ERR_GET_REASON(err) == ffi::PEM_R_NO_START_LINE
{
ffi::ERR_clear_error();
break;
}
@ -633,11 +671,12 @@ impl X509Extension {
/// provided.
///
/// See the extension module for builder types which will construct certain common extensions.
pub fn new(conf: Option<&ConfRef>,
context: Option<&X509v3Context>,
name: &str,
value: &str)
-> Result<X509Extension, ErrorStack> {
pub fn new(
conf: Option<&ConfRef>,
context: Option<&X509v3Context>,
name: &str,
value: &str,
) -> Result<X509Extension, ErrorStack> {
let name = CString::new(name).unwrap();
let value = CString::new(value).unwrap();
unsafe {
@ -658,11 +697,12 @@ impl X509Extension {
/// be provided.
///
/// See the extension module for builder types which will construct certain common extensions.
pub fn new_nid(conf: Option<&ConfRef>,
context: Option<&X509v3Context>,
name: Nid,
value: &str)
-> Result<X509Extension, ErrorStack> {
pub fn new_nid(
conf: Option<&ConfRef>,
context: Option<&X509v3Context>,
name: Nid,
value: &str,
) -> Result<X509Extension, ErrorStack> {
let value = CString::new(value).unwrap();
unsafe {
ffi::init();
@ -690,28 +730,30 @@ impl X509NameBuilder {
unsafe {
let field = CString::new(field).unwrap();
assert!(value.len() <= c_int::max_value() as usize);
cvt(ffi::X509_NAME_add_entry_by_txt(self.0.as_ptr(),
field.as_ptr() as *mut _,
ffi::MBSTRING_UTF8,
value.as_ptr(),
value.len() as c_int,
-1,
0))
.map(|_| ())
cvt(ffi::X509_NAME_add_entry_by_txt(
self.0.as_ptr(),
field.as_ptr() as *mut _,
ffi::MBSTRING_UTF8,
value.as_ptr(),
value.len() as c_int,
-1,
0,
)).map(|_| ())
}
}
pub fn append_entry_by_nid(&mut self, field: Nid, value: &str) -> Result<(), ErrorStack> {
unsafe {
assert!(value.len() <= c_int::max_value() as usize);
cvt(ffi::X509_NAME_add_entry_by_NID(self.0.as_ptr(),
field.as_raw(),
ffi::MBSTRING_UTF8,
value.as_ptr() as *mut _,
value.len() as c_int,
-1,
0))
.map(|_| ())
cvt(ffi::X509_NAME_add_entry_by_NID(
self.0.as_ptr(),
field.as_raw(),
ffi::MBSTRING_UTF8,
value.as_ptr() as *mut _,
value.len() as c_int,
-1,
0,
)).map(|_| ())
}
}
@ -739,9 +781,7 @@ impl X509Name {
/// This is commonly used in conjunction with `SslContextBuilder::set_client_ca_list`.
pub fn load_client_ca_file<P: AsRef<Path>>(file: P) -> Result<Stack<X509Name>, ErrorStack> {
let file = CString::new(file.as_ref().as_os_str().to_str().unwrap()).unwrap();
unsafe {
cvt_p(ffi::SSL_load_client_CA_file(file.as_ptr())).map(|p| Stack::from_ptr(p))
}
unsafe { cvt_p(ffi::SSL_load_client_CA_file(file.as_ptr())).map(|p| Stack::from_ptr(p)) }
}
}
@ -819,7 +859,10 @@ impl X509ReqBuilder {
pub fn set_subject_name(&mut self, subject_name: &X509NameRef) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::X509_REQ_set_subject_name(self.0.as_ptr(), subject_name.as_ptr())).map(|_| ())
cvt(ffi::X509_REQ_set_subject_name(
self.0.as_ptr(),
subject_name.as_ptr(),
)).map(|_| ())
}
}
@ -827,18 +870,18 @@ impl X509ReqBuilder {
unsafe { cvt(ffi::X509_REQ_set_pubkey(self.0.as_ptr(), key.as_ptr())).map(|_| ()) }
}
pub fn x509v3_context<'a>(&'a self,
conf: Option<&'a ConfRef>)
-> X509v3Context<'a> {
pub fn x509v3_context<'a>(&'a self, conf: Option<&'a ConfRef>) -> X509v3Context<'a> {
unsafe {
let mut ctx = mem::zeroed();
ffi::X509V3_set_ctx(&mut ctx,
ptr::null_mut(),
ptr::null_mut(),
self.0.as_ptr(),
ptr::null_mut(),
0);
ffi::X509V3_set_ctx(
&mut ctx,
ptr::null_mut(),
ptr::null_mut(),
self.0.as_ptr(),
ptr::null_mut(),
0,
);
// nodb case taken care of since we zeroed ctx above
if let Some(conf) = conf {
@ -849,16 +892,26 @@ impl X509ReqBuilder {
}
}
pub fn add_extensions(&mut self,
extensions: &StackRef<X509Extension>)
-> Result<(), ErrorStack> {
pub fn add_extensions(
&mut self,
extensions: &StackRef<X509Extension>,
) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::X509_REQ_add_extensions(self.0.as_ptr(), extensions.as_ptr())).map(|_| ())
cvt(ffi::X509_REQ_add_extensions(
self.0.as_ptr(),
extensions.as_ptr(),
)).map(|_| ())
}
}
pub fn sign(&mut self, key: &PKeyRef, hash: MessageDigest) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::X509_REQ_sign(self.0.as_ptr(), key.as_ptr(), hash.as_ptr())).map(|_| ()) }
unsafe {
cvt(ffi::X509_REQ_sign(
self.0.as_ptr(),
key.as_ptr(),
hash.as_ptr(),
)).map(|_| ())
}
}
pub fn build(self) -> X509Req {
@ -883,10 +936,12 @@ impl X509Req {
pub fn from_pem(buf: &[u8]) -> Result<X509Req, ErrorStack> {
let mem_bio = try!(MemBioSlice::new(buf));
unsafe {
let handle = try!(cvt_p(ffi::PEM_read_bio_X509_REQ(mem_bio.as_ptr(),
ptr::null_mut(),
None,
ptr::null_mut())));
let handle = try!(cvt_p(ffi::PEM_read_bio_X509_REQ(
mem_bio.as_ptr(),
ptr::null_mut(),
None,
ptr::null_mut(),
)));
Ok(X509Req::from_ptr(handle))
}
}
@ -898,11 +953,8 @@ impl X509ReqRef {
to_pem!(ffi::PEM_write_bio_X509_REQ);
to_der!(ffi::i2d_X509_REQ);
pub fn version(&self) -> i32
{
unsafe {
compat::X509_REQ_get_version(self.as_ptr()) as i32
}
pub fn version(&self) -> i32 {
unsafe { compat::X509_REQ_get_version(self.as_ptr()) as i32 }
}
pub fn subject_name(&self) -> &X509NameRef {
@ -1130,15 +1182,18 @@ mod compat {
}
pub unsafe fn X509_up_ref(x: *mut ffi::X509) {
ffi::CRYPTO_add_lock(&mut (*x).references,
1,
ffi::CRYPTO_LOCK_X509,
"mod.rs\0".as_ptr() as *const _,
line!() as c_int);
ffi::CRYPTO_add_lock(
&mut (*x).references,
1,
ffi::CRYPTO_LOCK_X509,
"mod.rs\0".as_ptr() as *const _,
line!() as c_int,
);
}
pub unsafe fn X509_get0_extensions(cert: *const ffi::X509)
-> *const ffi::stack_st_X509_EXTENSION {
pub unsafe fn X509_get0_extensions(
cert: *const ffi::X509,
) -> *const ffi::stack_st_X509_EXTENSION {
let info = (*cert).cert_info;
if info.is_null() {
0 as *mut _
@ -1147,19 +1202,19 @@ mod compat {
}
}
pub unsafe fn X509_REQ_get_version(x: *mut ffi::X509_REQ) -> ::libc::c_long
{
pub unsafe fn X509_REQ_get_version(x: *mut ffi::X509_REQ) -> ::libc::c_long {
::ffi::ASN1_INTEGER_get((*(*x).req_info).version)
}
pub unsafe fn X509_REQ_get_subject_name(x: *mut ffi::X509_REQ) -> *mut ::ffi::X509_NAME
{
pub unsafe fn X509_REQ_get_subject_name(x: *mut ffi::X509_REQ) -> *mut ::ffi::X509_NAME {
(*(*x).req_info).subject
}
pub unsafe fn X509_get0_signature(psig: *mut *const ffi::ASN1_BIT_STRING,
palg: *mut *const ffi::X509_ALGOR,
x: *const ffi::X509) {
pub unsafe fn X509_get0_signature(
psig: *mut *const ffi::ASN1_BIT_STRING,
palg: *mut *const ffi::X509_ALGOR,
x: *const ffi::X509,
) {
if !psig.is_null() {
*psig = (*x).signature;
}
@ -1168,10 +1223,12 @@ mod compat {
}
}
pub unsafe fn X509_ALGOR_get0(paobj: *mut *const ffi::ASN1_OBJECT,
pptype: *mut c_int,
pval: *mut *mut c_void,
alg: *const ffi::X509_ALGOR) {
pub unsafe fn X509_ALGOR_get0(
paobj: *mut *const ffi::ASN1_OBJECT,
pptype: *mut c_int,
pval: *mut *mut c_void,
alg: *const ffi::X509_ALGOR,
) {
if !paobj.is_null() {
*paobj = (*alg).algorithm;
}

View File

@ -50,9 +50,7 @@ impl X509StoreBuilderRef {
/// environment variables if present, or defaults specified at OpenSSL
/// build time otherwise.
pub fn set_default_paths(&mut self) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::X509_STORE_set_default_paths(self.as_ptr())).map(|_| ())
}
unsafe { cvt(ffi::X509_STORE_set_default_paths(self.as_ptr())).map(|_| ()) }
}
}

View File

@ -23,12 +23,22 @@ fn get_generator() -> X509Generator {
.add_name("CN".to_string(), "test_me".to_string())
.set_sign_hash(MessageDigest::sha1())
.add_extension(Extension::KeyUsage(vec![DigitalSignature, KeyEncipherment]))
.add_extension(Extension::ExtKeyUsage(vec![ClientAuth,
ServerAuth,
ExtKeyUsageOption::Other("2.999.1".to_owned())]))
.add_extension(Extension::SubjectAltName(vec![(SAN::DNS, "example.com".to_owned())]))
.add_extension(Extension::OtherNid(nid::BASIC_CONSTRAINTS, "critical,CA:TRUE".to_owned()))
.add_extension(Extension::OtherStr("2.999.2".to_owned(), "ASN1:UTF8:example value".to_owned()))
.add_extension(Extension::ExtKeyUsage(vec![
ClientAuth,
ServerAuth,
ExtKeyUsageOption::Other("2.999.1".to_owned()),
]))
.add_extension(Extension::SubjectAltName(
vec![(SAN::DNS, "example.com".to_owned())],
))
.add_extension(Extension::OtherNid(
nid::BASIC_CONSTRAINTS,
"critical,CA:TRUE".to_owned(),
))
.add_extension(Extension::OtherStr(
"2.999.2".to_owned(),
"ASN1:UTF8:example value".to_owned(),
))
}
fn pkey() -> PKey {
@ -44,8 +54,10 @@ fn test_cert_gen() {
// FIXME: check data in result to be correct, needs implementation
// of X509 getters
assert_eq!(pkey.public_key_to_pem().unwrap(),
cert.public_key().unwrap().public_key_to_pem().unwrap());
assert_eq!(
pkey.public_key_to_pem().unwrap(),
cert.public_key().unwrap().public_key_to_pem().unwrap()
);
}
/// SubjectKeyIdentifier must be added before AuthorityKeyIdentifier or OpenSSL
@ -55,8 +67,14 @@ fn test_cert_gen() {
fn test_cert_gen_extension_ordering() {
let pkey = pkey();
get_generator()
.add_extension(Extension::OtherNid(nid::SUBJECT_KEY_IDENTIFIER, "hash".to_owned()))
.add_extension(Extension::OtherNid(nid::AUTHORITY_KEY_IDENTIFIER, "keyid:always".to_owned()))
.add_extension(Extension::OtherNid(
nid::SUBJECT_KEY_IDENTIFIER,
"hash".to_owned(),
))
.add_extension(Extension::OtherNid(
nid::AUTHORITY_KEY_IDENTIFIER,
"keyid:always".to_owned(),
))
.sign(&pkey)
.expect("Failed to generate cert with order-dependent extensions");
}
@ -67,8 +85,14 @@ fn test_cert_gen_extension_ordering() {
fn test_cert_gen_extension_bad_ordering() {
let pkey = pkey();
let result = get_generator()
.add_extension(Extension::OtherNid(nid::AUTHORITY_KEY_IDENTIFIER, "keyid:always".to_owned()))
.add_extension(Extension::OtherNid(nid::SUBJECT_KEY_IDENTIFIER, "hash".to_owned()))
.add_extension(Extension::OtherNid(
nid::AUTHORITY_KEY_IDENTIFIER,
"keyid:always".to_owned(),
))
.add_extension(Extension::OtherNid(
nid::SUBJECT_KEY_IDENTIFIER,
"hash".to_owned(),
))
.sign(&pkey);
assert!(result.is_err());
@ -82,7 +106,11 @@ fn test_req_gen() {
let reqpem = req.to_pem().unwrap();
let req = X509Req::from_pem(&reqpem).ok().expect("Failed to load PEM");
let cn = (*req).subject_name().entries_by_nid(nid::COMMONNAME).next().unwrap();
let cn = (*req)
.subject_name()
.entries_by_nid(nid::COMMONNAME)
.next()
.unwrap();
assert_eq!(0, (*req).version());
assert_eq!(cn.data().as_slice(), b"test_me");
@ -140,7 +168,10 @@ fn test_nid_values() {
let cn = subject.entries_by_nid(nid::COMMONNAME).next().unwrap();
assert_eq!(cn.data().as_slice(), b"example.com");
let email = subject.entries_by_nid(nid::PKCS9_EMAILADDRESS).next().unwrap();
let email = subject
.entries_by_nid(nid::PKCS9_EMAILADDRESS)
.next()
.unwrap();
assert_eq!(email.data().as_slice(), b"test@example.com");
let friendly = subject.entries_by_nid(nid::FRIENDLYNAME).next().unwrap();
@ -165,10 +196,11 @@ fn test_subject_alt_name() {
let subject_alt_names = cert.subject_alt_names().unwrap();
assert_eq!(3, subject_alt_names.len());
assert_eq!(Some("foobar.com"), subject_alt_names[0].dnsname());
assert_eq!(subject_alt_names[1].ipaddress(),
Some(&[127, 0, 0, 1][..]));
assert_eq!(subject_alt_names[2].ipaddress(),
Some(&b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01"[..]));
assert_eq!(subject_alt_names[1].ipaddress(), Some(&[127, 0, 0, 1][..]));
assert_eq!(
subject_alt_names[2].ipaddress(),
Some(&b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01"[..])
);
}
#[test]
@ -178,12 +210,18 @@ fn test_subject_alt_name_iter() {
let subject_alt_names = cert.subject_alt_names().unwrap();
let mut subject_alt_names_iter = subject_alt_names.iter();
assert_eq!(subject_alt_names_iter.next().unwrap().dnsname(),
Some("foobar.com"));
assert_eq!(subject_alt_names_iter.next().unwrap().ipaddress(),
Some(&[127, 0, 0, 1][..]));
assert_eq!(subject_alt_names_iter.next().unwrap().ipaddress(),
Some(&b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01"[..]));
assert_eq!(
subject_alt_names_iter.next().unwrap().dnsname(),
Some("foobar.com")
);
assert_eq!(
subject_alt_names_iter.next().unwrap().ipaddress(),
Some(&[127, 0, 0, 1][..])
);
assert_eq!(
subject_alt_names_iter.next().unwrap().ipaddress(),
Some(&b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01"[..])
);
assert!(subject_alt_names_iter.next().is_none());
}
@ -192,24 +230,35 @@ fn x509_builder() {
let pkey = pkey();
let mut name = X509Name::builder().unwrap();
name.append_entry_by_nid(nid::COMMONNAME, "foobar.com").unwrap();
name.append_entry_by_nid(nid::COMMONNAME, "foobar.com")
.unwrap();
let name = name.build();
let mut builder = X509::builder().unwrap();
builder.set_version(2).unwrap();
builder.set_subject_name(&name).unwrap();
builder.set_issuer_name(&name).unwrap();
builder.set_not_before(&Asn1Time::days_from_now(0).unwrap()).unwrap();
builder.set_not_after(&Asn1Time::days_from_now(365).unwrap()).unwrap();
builder
.set_not_before(&Asn1Time::days_from_now(0).unwrap())
.unwrap();
builder
.set_not_after(&Asn1Time::days_from_now(365).unwrap())
.unwrap();
builder.set_pubkey(&pkey).unwrap();
let mut serial = BigNum::new().unwrap();;
let mut serial = BigNum::new().unwrap();
serial.rand(128, MSB_MAYBE_ZERO, false).unwrap();
builder.set_serial_number(&serial.to_asn1_integer().unwrap()).unwrap();
builder
.set_serial_number(&serial.to_asn1_integer().unwrap())
.unwrap();
let basic_constraints = BasicConstraints::new().critical().ca().build().unwrap();
builder.append_extension(basic_constraints).unwrap();
let key_usage = KeyUsage::new().digital_signature().key_encipherment().build().unwrap();
let key_usage = KeyUsage::new()
.digital_signature()
.key_encipherment()
.build()
.unwrap();
builder.append_extension(key_usage).unwrap();
let ext_key_usage = ExtendedKeyUsage::new()
.client_auth()
@ -239,7 +288,10 @@ fn x509_builder() {
assert!(pkey.public_eq(&x509.public_key().unwrap()));
let cn = x509.subject_name().entries_by_nid(nid::COMMONNAME).next().unwrap();
let cn = x509.subject_name()
.entries_by_nid(nid::COMMONNAME)
.next()
.unwrap();
assert_eq!("foobar.com".as_bytes(), cn.data().as_slice());
}
@ -248,7 +300,8 @@ fn x509_req_builder() {
let pkey = pkey();
let mut name = X509Name::builder().unwrap();
name.append_entry_by_nid(nid::COMMONNAME, "foobar.com").unwrap();
name.append_entry_by_nid(nid::COMMONNAME, "foobar.com")
.unwrap();
let name = name.build();
let mut builder = X509Req::builder().unwrap();
@ -257,7 +310,11 @@ fn x509_req_builder() {
builder.set_pubkey(&pkey).unwrap();
let mut extensions = Stack::new().unwrap();
let key_usage = KeyUsage::new().digital_signature().key_encipherment().build().unwrap();
let key_usage = KeyUsage::new()
.digital_signature()
.key_encipherment()
.build()
.unwrap();
extensions.push(key_usage).unwrap();
let subject_alternative_name = SubjectAlternativeName::new()
.dns("example.com")
@ -275,10 +332,20 @@ fn test_stack_from_pem() {
let certs = X509::stack_from_pem(certs).unwrap();
assert_eq!(certs.len(), 2);
assert_eq!(certs[0].fingerprint(MessageDigest::sha1()).unwrap().to_hex(),
"59172d9313e84459bcff27f967e79e6e9217e584");
assert_eq!(certs[1].fingerprint(MessageDigest::sha1()).unwrap().to_hex(),
"c0cbdf7cdd03c9773e5468e1f6d2da7d5cbb1875");
assert_eq!(
certs[0]
.fingerprint(MessageDigest::sha1())
.unwrap()
.to_hex(),
"59172d9313e84459bcff27f967e79e6e9217e584"
);
assert_eq!(
certs[1]
.fingerprint(MessageDigest::sha1())
.unwrap()
.to_hex(),
"c0cbdf7cdd03c9773e5468e1f6d2da7d5cbb1875"
);
}
#[test]
@ -317,14 +384,16 @@ fn signature() {
let cert = include_bytes!("../../test/cert.pem");
let cert = X509::from_pem(cert).unwrap();
let signature = cert.signature();
assert_eq!(signature.as_slice().to_hex(),
"4af607b889790b43470442cfa551cdb8b6d0b0340d2958f76b9e3ef6ad4992230cead6842587f0ecad5\
assert_eq!(
signature.as_slice().to_hex(),
"4af607b889790b43470442cfa551cdb8b6d0b0340d2958f76b9e3ef6ad4992230cead6842587f0ecad5\
78e6e11a221521e940187e3d6652de14e84e82f6671f097cc47932e022add3c0cb54a26bf27fa84c107\
4971caa6bee2e42d34a5b066c427f2d452038082b8073993399548088429de034fdd589dcfb0dd33be7\
ebdfdf698a28d628a89568881d658151276bde333600969502c4e62e1d3470a683364dfb241f78d310a\
89c119297df093eb36b7fd7540224f488806780305d1e79ffc938fe2275441726522ab36d88348e6c51\
f13dcc46b5e1cdac23c974fd5ef86aa41e91c9311655090a52333bc79687c748d833595d4c5f987508f\
e121997410d37c");
e121997410d37c"
);
let algorithm = cert.signature_algorithm();
assert_eq!(algorithm.object().nid(), nid::SHA256WITHRSAENCRYPTION);
assert_eq!(algorithm.object().to_string(), "sha256WithRSAEncryption");

View File

@ -2,4 +2,4 @@
//!
//! Requires the `v102` or `v110` features and OpenSSL 1.0.2 or 1.1.0.
pub use ::verify::*;
pub use verify::*;

View File

@ -27,7 +27,12 @@ fn main() {
} else if let Ok(version) = env::var("DEP_OPENSSL_VERSION") {
cfg.cfg(&format!("ossl{}", version), None);
}
if let (Ok(version), Ok(patch)) = (env::var("DEP_OPENSSL_VERSION"), env::var("DEP_OPENSSL_PATCH")) {
if let (Ok(version), Ok(patch)) =
(
env::var("DEP_OPENSSL_VERSION"),
env::var("DEP_OPENSSL_PATCH"),
)
{
cfg.cfg(&format!("ossl{}{}", version, patch), None);
}
if let Ok(vars) = env::var("DEP_OPENSSL_CONF") {
@ -37,21 +42,21 @@ fn main() {
}
cfg.header("openssl/comp.h")
.header("openssl/dh.h")
.header("openssl/ossl_typ.h")
.header("openssl/stack.h")
.header("openssl/x509.h")
.header("openssl/bio.h")
.header("openssl/x509v3.h")
.header("openssl/safestack.h")
.header("openssl/hmac.h")
.header("openssl/ssl.h")
.header("openssl/err.h")
.header("openssl/rand.h")
.header("openssl/pkcs12.h")
.header("openssl/bn.h")
.header("openssl/aes.h")
.header("openssl/ocsp.h");
.header("openssl/dh.h")
.header("openssl/ossl_typ.h")
.header("openssl/stack.h")
.header("openssl/x509.h")
.header("openssl/bio.h")
.header("openssl/x509v3.h")
.header("openssl/safestack.h")
.header("openssl/hmac.h")
.header("openssl/ssl.h")
.header("openssl/err.h")
.header("openssl/rand.h")
.header("openssl/pkcs12.h")
.header("openssl/bn.h")
.header("openssl/aes.h")
.header("openssl/ocsp.h");
cfg.type_name(|s, is_struct| {
// Add some `*` on some callback parameters to get function pointer to
// typecheck in C, especially on MSVC.
@ -62,7 +67,9 @@ fn main() {
} else if s == "_STACK" {
format!("struct stack_st")
// This logic should really be cleaned up
} else if is_struct && s != "point_conversion_form_t" && s.chars().next().unwrap().is_lowercase() {
} else if is_struct && s != "point_conversion_form_t" &&
s.chars().next().unwrap().is_lowercase()
{
format!("struct {}", s)
} else {
format!("{}", s)
@ -71,13 +78,9 @@ fn main() {
cfg.skip_type(|s| {
// function pointers are declared without a `*` in openssl so their
// sizeof is 1 which isn't what we want.
s == "PasswordCallback" ||
s == "bio_info_cb" ||
s.starts_with("CRYPTO_EX_")
});
cfg.skip_struct(|s| {
s == "ProbeResult"
s == "PasswordCallback" || s == "bio_info_cb" || s.starts_with("CRYPTO_EX_")
});
cfg.skip_struct(|s| s == "ProbeResult");
cfg.skip_fn(move |s| {
s == "CRYPTO_memcmp" || // uses volatile
@ -91,23 +94,17 @@ fn main() {
});
cfg.skip_field_type(|s, field| {
(s == "EVP_PKEY" && field == "pkey") || // union
(s == "GENERAL_NAME" && field == "d") // union
(s == "GENERAL_NAME" && field == "d") // union
});
cfg.skip_signededness(|s| {
s.ends_with("_cb") ||
s.ends_with("_CB") ||
s.ends_with("_cb_fn") ||
s.starts_with("CRYPTO_") ||
s == "PasswordCallback"
s.ends_with("_cb") || s.ends_with("_CB") || s.ends_with("_cb_fn") ||
s.starts_with("CRYPTO_") || s == "PasswordCallback"
});
cfg.field_name(|_s, field| {
if field == "type_" {
format!("type")
} else {
format!("{}", field)
}
cfg.field_name(|_s, field| if field == "type_" {
format!("type")
} else {
format!("{}", field)
});
cfg.fn_cname(|rust, link_name| link_name.unwrap_or(rust).to_string());
cfg.generate("../openssl-sys/src/lib.rs", "all.rs");
}