Rustfmt
This commit is contained in:
parent
5c2410c38a
commit
bcd0dcafcb
|
|
@ -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
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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("")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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>);
|
||||
|
||||
|
|
|
|||
|
|
@ -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(|_| ())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()));
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(|_| ()) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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::*;
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue