Merge branch 'release-v0.7.2' into release
This commit is contained in:
commit
cf075d8e6b
|
|
@ -9,7 +9,7 @@ os:
|
|||
- linux
|
||||
env:
|
||||
global:
|
||||
- FEATURES="tlsv1_2 tlsv1_1 dtlsv1 dtlsv1_2 sslv2 sslv3 aes_xts aes_ctr npn alpn rfc5114 ecdh_auto"
|
||||
- FEATURES="tlsv1_2 tlsv1_1 dtlsv1 dtlsv1_2 sslv2 sslv3 aes_xts aes_ctr npn alpn rfc5114 ecdh_auto pkcs5_pbkdf2_hmac"
|
||||
before_install:
|
||||
- (test $TRAVIS_OS_NAME == "osx" || ./openssl/test/build.sh)
|
||||
script:
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
[](https://travis-ci.org/sfackler/rust-openssl)
|
||||
|
||||
[Documentation](https://sfackler.github.io/rust-openssl/doc/v0.7.1/openssl).
|
||||
[Documentation](https://sfackler.github.io/rust-openssl/doc/v0.7.2/openssl).
|
||||
|
||||
## Building
|
||||
|
||||
|
|
@ -25,7 +25,9 @@ sudo pacman -S openssl
|
|||
|
||||
OpenSSL 0.9.8 is preinstalled on OSX. Some features are only available when
|
||||
linking against OpenSSL 1.0.0 or greater; see below on how to point
|
||||
rust-openssl to a separate installation.
|
||||
rust-openssl to a separate installation. OSX releases starting at 10.11, "El
|
||||
Capitan", no longer include OpenSSL headers which will prevent the `openssl`
|
||||
crate from compiling.
|
||||
|
||||
### Windows
|
||||
|
||||
|
|
|
|||
|
|
@ -8,10 +8,10 @@ environment:
|
|||
- TARGET: x86_64-pc-windows-msvc
|
||||
BITS: 64
|
||||
install:
|
||||
- ps: Start-FileDownload "http://slproweb.com/download/Win${env:BITS}OpenSSL-1_0_2d.exe"
|
||||
- Win%BITS%OpenSSL-1_0_2d.exe /SILENT /VERYSILENT /SP- /DIR="C:\OpenSSL"
|
||||
- ps: Start-FileDownload "https://static.rust-lang.org/dist/rust-nightly-${env:TARGET}.exe"
|
||||
- rust-nightly-%TARGET%.exe /VERYSILENT /NORESTART /DIR="C:\Program Files (x86)\Rust"
|
||||
- ps: Start-FileDownload "http://slproweb.com/download/Win${env:BITS}OpenSSL-1_0_2e.exe"
|
||||
- Win%BITS%OpenSSL-1_0_2e.exe /SILENT /VERYSILENT /SP- /DIR="C:\OpenSSL"
|
||||
- ps: Start-FileDownload "https://static.rust-lang.org/dist/rust-1.5.0-${env:TARGET}.exe"
|
||||
- rust-1.5.0-%TARGET%.exe /VERYSILENT /NORESTART /DIR="C:\Program Files (x86)\Rust"
|
||||
- SET PATH=%PATH%;C:\Program Files (x86)\Rust\bin
|
||||
- SET PATH=%PATH%;C:\MinGW\bin
|
||||
- rustc -V
|
||||
|
|
|
|||
|
|
@ -1,13 +1,11 @@
|
|||
[package]
|
||||
name = "openssl-sys-extras"
|
||||
version = "0.7.1"
|
||||
version = "0.7.2"
|
||||
authors = ["Steven Fackler <sfackler@gmail.com>"]
|
||||
license = "MIT"
|
||||
description = "Extra FFI bindings to OpenSSL that require a C shim"
|
||||
repository = "https://github.com/sfackler/rust-openssl"
|
||||
documentation = "https://sfackler.github.io/rust-openssl/doc/v0.7.1/openssl_sys_extras"
|
||||
|
||||
links = "openssl_shim"
|
||||
documentation = "https://sfackler.github.io/rust-openssl/doc/v0.7.2/openssl_sys_extras"
|
||||
build = "build.rs"
|
||||
|
||||
[features]
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
#![allow(non_upper_case_globals, non_snake_case)]
|
||||
#![doc(html_root_url="https://sfackler.github.io/rust-openssl/doc/v0.7.0")]
|
||||
#![doc(html_root_url="https://sfackler.github.io/rust-openssl/doc/v0.7.2")]
|
||||
|
||||
extern crate openssl_sys;
|
||||
extern crate libc;
|
||||
|
||||
use libc::{c_int, c_uint, c_long, c_char};
|
||||
use libc::{c_int, c_uint, c_long, c_char, c_void};
|
||||
use openssl_sys::{HMAC_CTX, EVP_MD, ENGINE, SSL_CTX, BIO, X509, stack_st_X509_EXTENSION, SSL, DH};
|
||||
|
||||
macro_rules! import_options {
|
||||
|
|
@ -49,6 +49,14 @@ extern {
|
|||
pub fn BIO_set_nbio(b: *mut BIO, enabled: c_long) -> c_long;
|
||||
#[link_name = "BIO_set_mem_eof_return_shim"]
|
||||
pub fn BIO_set_mem_eof_return(b: *mut BIO, v: c_int);
|
||||
#[link_name = "BIO_clear_retry_flags_shim"]
|
||||
pub fn BIO_clear_retry_flags(b: *mut BIO);
|
||||
#[link_name = "BIO_set_retry_read_shim"]
|
||||
pub fn BIO_set_retry_read(b: *mut BIO);
|
||||
#[link_name = "BIO_set_retry_write_shim"]
|
||||
pub fn BIO_set_retry_write(b: *mut BIO);
|
||||
#[link_name = "BIO_flush"]
|
||||
pub fn BIO_flush(b: *mut BIO) -> c_long;
|
||||
pub fn SSL_CTX_set_options_shim(ctx: *mut SSL_CTX, options: c_long) -> c_long;
|
||||
pub fn SSL_CTX_get_options_shim(ctx: *mut SSL_CTX) -> c_long;
|
||||
pub fn SSL_CTX_clear_options_shim(ctx: *mut SSL_CTX, options: c_long) -> c_long;
|
||||
|
|
@ -65,4 +73,8 @@ extern {
|
|||
pub fn SSL_CTX_set_tmp_dh(s: *mut SSL, dh: *const DH) -> c_long;
|
||||
#[link_name = "X509_get_extensions_shim"]
|
||||
pub fn X509_get_extensions(x: *mut X509) -> *mut stack_st_X509_EXTENSION;
|
||||
#[link_name = "SSL_CTX_set_tlsext_servername_callback_shim"]
|
||||
pub fn SSL_CTX_set_tlsext_servername_callback(ssl: *mut SSL_CTX, callback: Option<extern fn()>);
|
||||
#[link_name = "SSL_CTX_set_tlsext_servername_arg_shim"]
|
||||
pub fn SSL_CTX_set_tlsext_servername_arg(ssl: *mut SSL_CTX, arg: *const c_void);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -91,6 +91,22 @@ void BIO_set_mem_eof_return_shim(BIO *b, int v) {
|
|||
BIO_set_mem_eof_return(b, v);
|
||||
}
|
||||
|
||||
void BIO_clear_retry_flags_shim(BIO *b) {
|
||||
BIO_clear_retry_flags(b);
|
||||
}
|
||||
|
||||
void BIO_set_retry_read_shim(BIO *b) {
|
||||
BIO_set_retry_read(b);
|
||||
}
|
||||
|
||||
void BIO_set_retry_write_shim(BIO *b) {
|
||||
BIO_set_retry_write(b);
|
||||
}
|
||||
|
||||
long BIO_flush_shim(BIO *b) {
|
||||
return BIO_flush(b);
|
||||
}
|
||||
|
||||
long SSL_CTX_set_options_shim(SSL_CTX *ctx, long options) {
|
||||
return SSL_CTX_set_options(ctx, options);
|
||||
}
|
||||
|
|
@ -115,6 +131,14 @@ long SSL_CTX_set_tmp_dh_shim(SSL_CTX *ctx, DH *dh) {
|
|||
return SSL_CTX_set_tmp_dh(ctx, dh);
|
||||
}
|
||||
|
||||
long SSL_CTX_set_tlsext_servername_callback_shim(SSL_CTX *ctx, int (*callback)(SSL_CTX *, int *, void*)) {
|
||||
return SSL_CTX_set_tlsext_servername_callback(ctx, callback);
|
||||
}
|
||||
|
||||
long SSL_CTX_set_tlsext_servername_arg_shim(SSL_CTX *ctx, void* arg) {
|
||||
return SSL_CTX_set_tlsext_servername_arg(ctx, arg);
|
||||
}
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
int SSL_CTX_set_ecdh_auto_shim(SSL_CTX *ctx, int onoff) {
|
||||
return SSL_CTX_set_ecdh_auto(ctx, onoff);
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
[package]
|
||||
name = "openssl-sys"
|
||||
version = "0.7.1"
|
||||
version = "0.7.2"
|
||||
authors = ["Alex Crichton <alex@alexcrichton.com>",
|
||||
"Steven Fackler <sfackler@gmail.com>"]
|
||||
license = "MIT"
|
||||
description = "FFI bindings to OpenSSL"
|
||||
repository = "https://github.com/sfackler/rust-openssl"
|
||||
documentation = "https://sfackler.github.io/rust-openssl/doc/v0.7.1/openssl_sys"
|
||||
|
||||
documentation = "https://sfackler.github.io/rust-openssl/doc/v0.7.2/openssl_sys"
|
||||
links = "openssl"
|
||||
build = "build.rs"
|
||||
|
||||
|
|
@ -23,6 +22,7 @@ aes_ctr = []
|
|||
npn = []
|
||||
alpn = []
|
||||
rfc5114 = []
|
||||
pkcs5_pbkdf2_hmac = []
|
||||
|
||||
[dependencies]
|
||||
libc = "0.2"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#![allow(non_camel_case_types, non_upper_case_globals, non_snake_case)]
|
||||
#![allow(dead_code)]
|
||||
#![doc(html_root_url="https://sfackler.github.io/rust-openssl/doc/v0.7.1")]
|
||||
#![doc(html_root_url="https://sfackler.github.io/rust-openssl/doc/v0.7.2")]
|
||||
|
||||
extern crate libc;
|
||||
|
||||
|
|
@ -15,11 +15,8 @@ use std::sync::{Once, ONCE_INIT};
|
|||
pub type ASN1_INTEGER = c_void;
|
||||
pub type ASN1_STRING = c_void;
|
||||
pub type ASN1_TIME = c_void;
|
||||
pub type BIO = c_void;
|
||||
pub type BIO_METHOD = c_void;
|
||||
pub type BN_CTX = c_void;
|
||||
pub type COMP_METHOD = c_void;
|
||||
pub type CRYPTO_EX_DATA = c_void;
|
||||
pub type DH = c_void;
|
||||
pub type ENGINE = c_void;
|
||||
pub type EVP_CIPHER = c_void;
|
||||
|
|
@ -39,6 +36,65 @@ pub type X509_NAME_ENTRY = c_void;
|
|||
pub type X509_REQ = c_void;
|
||||
pub type X509_STORE_CTX = c_void;
|
||||
pub type stack_st_X509_EXTENSION = c_void;
|
||||
pub type stack_st_void = c_void;
|
||||
pub type bio_st = c_void;
|
||||
|
||||
pub type bio_info_cb = Option<unsafe extern "C" fn(*mut BIO,
|
||||
c_int,
|
||||
*const c_char,
|
||||
c_int,
|
||||
c_long,
|
||||
c_long)>;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
#[allow(raw_pointer_derive)]
|
||||
pub struct BIO_METHOD {
|
||||
pub type_: c_int,
|
||||
pub name: *const c_char,
|
||||
pub bwrite: Option<unsafe extern "C" fn(*mut BIO, *const c_char, c_int) -> c_int>,
|
||||
pub bread: Option<unsafe extern "C" fn(*mut BIO, *mut c_char, c_int) -> c_int>,
|
||||
pub bputs: Option<unsafe extern "C" fn(*mut BIO, *const c_char) -> c_int>,
|
||||
pub bgets: Option<unsafe extern "C" fn(*mut BIO, *mut c_char, c_int) -> c_int>,
|
||||
pub ctrl: Option<unsafe extern "C" fn(*mut BIO, c_int, c_long, *mut c_void) -> c_long>,
|
||||
pub create: Option<unsafe extern "C" fn(*mut BIO) -> c_int>,
|
||||
pub destroy: Option<unsafe extern "C" fn(*mut BIO) -> c_int>,
|
||||
pub callback_ctrl: Option<unsafe extern "C" fn(*mut BIO, c_int, bio_info_cb) -> c_long>,
|
||||
}
|
||||
|
||||
// so we can create static BIO_METHODs
|
||||
unsafe impl Sync for BIO_METHOD {}
|
||||
|
||||
#[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 cb_arg: *mut c_char,
|
||||
pub init: c_int,
|
||||
pub shutdown: c_int,
|
||||
pub flags: c_int,
|
||||
pub retry_reason: c_int,
|
||||
pub num: c_int,
|
||||
pub ptr: *mut c_void,
|
||||
pub next_bio: *mut BIO,
|
||||
pub prev_bio: *mut BIO,
|
||||
pub references: c_int,
|
||||
pub num_read: c_ulong,
|
||||
pub num_write: c_ulong,
|
||||
pub ex_data: CRYPTO_EX_DATA,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct CRYPTO_EX_DATA {
|
||||
pub sk: *mut stack_st_void,
|
||||
pub dummy: c_int,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct EVP_MD_CTX {
|
||||
|
|
@ -116,7 +172,10 @@ pub type PasswordCallback = extern "C" fn(buf: *mut c_char, size: c_int,
|
|||
rwflag: c_int, user_data: *mut c_void)
|
||||
-> c_int;
|
||||
|
||||
pub const BIO_TYPE_NONE: c_int = 0;
|
||||
|
||||
pub const BIO_CTRL_EOF: c_int = 2;
|
||||
pub const BIO_CTRL_FLUSH: c_int = 11;
|
||||
pub const BIO_C_SET_BUF_MEM_EOF_RETURN: c_int = 130;
|
||||
|
||||
pub const CRYPTO_LOCK: c_int = 1;
|
||||
|
|
@ -135,6 +194,8 @@ pub const PKCS5_SALT_LEN: c_int = 8;
|
|||
pub const SSL_CTRL_OPTIONS: c_int = 32;
|
||||
pub const SSL_CTRL_CLEAR_OPTIONS: c_int = 77;
|
||||
|
||||
pub const SSL_CTRL_SET_TLSEXT_SERVERNAME_CB: c_int = 53;
|
||||
pub const SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG: c_int = 54;
|
||||
pub const SSL_CTRL_SET_TLSEXT_HOSTNAME: c_int = 55;
|
||||
pub const SSL_CTRL_EXTRA_CHAIN_CERT: c_int = 14;
|
||||
|
||||
|
|
@ -478,7 +539,11 @@ extern "C" {
|
|||
salt: *const u8, saltlen: c_int,
|
||||
iter: c_int, keylen: c_int,
|
||||
out: *mut u8) -> c_int;
|
||||
|
||||
#[cfg(feature = "pkcs5_pbkdf2_hmac")]
|
||||
pub fn PKCS5_PBKDF2_HMAC(pass: *const u8, passlen: c_int,
|
||||
salt: *const u8, saltlen: c_int,
|
||||
iter: c_int, digest: *const EVP_MD, keylen: c_int,
|
||||
out: *mut u8) -> c_int;
|
||||
|
||||
pub fn RAND_bytes(buf: *mut u8, num: c_int) -> c_int;
|
||||
|
||||
|
|
@ -532,12 +597,15 @@ extern "C" {
|
|||
pub fn SSL_write(ssl: *mut SSL, buf: *const c_void, num: c_int) -> c_int;
|
||||
pub fn SSL_get_ex_data_X509_STORE_CTX_idx() -> c_int;
|
||||
pub fn SSL_get_SSL_CTX(ssl: *mut SSL) -> *mut SSL_CTX;
|
||||
pub fn SSL_set_SSL_CTX(ssl: *mut SSL, ctx: *mut SSL_CTX) -> *mut SSL_CTX;
|
||||
pub fn SSL_get_current_compression(ssl: *mut SSL) -> *const COMP_METHOD;
|
||||
pub fn SSL_get_peer_certificate(ssl: *mut SSL) -> *mut X509;
|
||||
pub fn SSL_get_ssl_method(ssl: *mut SSL) -> *const SSL_METHOD;
|
||||
pub fn SSL_state_string(ssl: *mut SSL) -> *const c_char;
|
||||
pub fn SSL_state_string_long(ssl: *mut SSL) -> *const c_char;
|
||||
|
||||
pub fn SSL_get_servername(ssl: *const SSL, name_type: c_long) -> *const c_char;
|
||||
|
||||
pub fn SSL_COMP_get_name(comp: *const COMP_METHOD) -> *const c_char;
|
||||
|
||||
pub fn SSL_CTX_new(method: *const SSL_METHOD) -> *mut SSL_CTX;
|
||||
|
|
@ -566,7 +634,6 @@ extern "C" {
|
|||
|
||||
pub fn SSL_CTX_set_cipher_list(ssl: *mut SSL_CTX, s: *const c_char) -> c_int;
|
||||
|
||||
pub fn SSL_CTX_ctrl(ssl: *mut SSL_CTX, cmd: c_int, larg: c_long, parg: *mut c_void) -> c_long;
|
||||
#[cfg(feature = "npn")]
|
||||
pub fn SSL_CTX_set_next_protos_advertised_cb(ssl: *mut SSL_CTX,
|
||||
cb: extern "C" fn(ssl: *mut SSL,
|
||||
|
|
|
|||
|
|
@ -1,13 +1,14 @@
|
|||
[package]
|
||||
name = "openssl"
|
||||
version = "0.7.1"
|
||||
version = "0.7.2"
|
||||
authors = ["Steven Fackler <sfackler@gmail.com>"]
|
||||
license = "Apache-2.0"
|
||||
description = "OpenSSL bindings"
|
||||
repository = "https://github.com/sfackler/rust-openssl"
|
||||
documentation = "https://sfackler.github.io/rust-openssl/doc/v0.7.1/openssl"
|
||||
documentation = "https://sfackler.github.io/rust-openssl/doc/v0.7.2/openssl"
|
||||
readme = "../README.md"
|
||||
keywords = ["crypto", "tls", "ssl", "dtls"]
|
||||
build = "build.rs"
|
||||
|
||||
[features]
|
||||
tlsv1_2 = ["openssl-sys/tlsv1_2"]
|
||||
|
|
@ -22,6 +23,7 @@ npn = ["openssl-sys/npn"]
|
|||
alpn = ["openssl-sys/alpn"]
|
||||
rfc5114 = ["openssl-sys/rfc5114"]
|
||||
ecdh_auto = ["openssl-sys-extras/ecdh_auto"]
|
||||
pkcs5_pbkdf2_hmac = ["openssl-sys/pkcs5_pbkdf2_hmac"]
|
||||
|
||||
[dependencies]
|
||||
bitflags = ">= 0.2, < 0.4"
|
||||
|
|
@ -30,6 +32,9 @@ libc = "0.2"
|
|||
openssl-sys = { version = "0.7.1", path = "../openssl-sys" }
|
||||
openssl-sys-extras = { version = "0.7.1", path = "../openssl-sys-extras" }
|
||||
|
||||
[build-dependencies]
|
||||
gcc = "0.3"
|
||||
|
||||
[dev-dependencies]
|
||||
rustc-serialize = "0.3"
|
||||
net2 = "0.2.16"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
extern crate gcc;
|
||||
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
|
||||
fn main() {
|
||||
let mut config = gcc::Config::new();
|
||||
|
||||
if let Some(paths) = env::var_os("DEP_OPENSSL_INCLUDE") {
|
||||
for path in env::split_paths(&paths) {
|
||||
config.include(PathBuf::from(path));
|
||||
}
|
||||
}
|
||||
|
||||
config.file("src/c_helpers.c").compile("libc_helpers.a");
|
||||
}
|
||||
|
|
@ -89,7 +89,7 @@ impl BigNum {
|
|||
pub fn from_dec_str(s: &str) -> Result<BigNum, SslError> {
|
||||
BigNum::new().and_then(|v| unsafe {
|
||||
let c_str = CString::new(s.as_bytes()).unwrap();
|
||||
try_ssl!(ffi::BN_dec2bn(v.raw_ptr(), c_str.as_ptr()));
|
||||
try_ssl!(ffi::BN_dec2bn(v.raw_ptr(), c_str.as_ptr() as *const _));
|
||||
Ok(v)
|
||||
})
|
||||
}
|
||||
|
|
@ -97,7 +97,7 @@ impl BigNum {
|
|||
pub fn from_hex_str(s: &str) -> Result<BigNum, SslError> {
|
||||
BigNum::new().and_then(|v| unsafe {
|
||||
let c_str = CString::new(s.as_bytes()).unwrap();
|
||||
try_ssl!(ffi::BN_hex2bn(v.raw_ptr(), c_str.as_ptr()));
|
||||
try_ssl!(ffi::BN_hex2bn(v.raw_ptr(), c_str.as_ptr() as *const _));
|
||||
Ok(v)
|
||||
})
|
||||
}
|
||||
|
|
@ -421,7 +421,7 @@ impl BigNum {
|
|||
unsafe {
|
||||
let buf = ffi::BN_bn2dec(self.raw());
|
||||
assert!(!buf.is_null());
|
||||
let str = String::from_utf8(CStr::from_ptr(buf).to_bytes().to_vec()).unwrap();
|
||||
let str = String::from_utf8(CStr::from_ptr(buf as *const _).to_bytes().to_vec()).unwrap();
|
||||
ffi::CRYPTO_free(buf as *mut c_void);
|
||||
str
|
||||
}
|
||||
|
|
@ -431,7 +431,7 @@ impl BigNum {
|
|||
unsafe {
|
||||
let buf = ffi::BN_bn2hex(self.raw());
|
||||
assert!(!buf.is_null());
|
||||
let str = String::from_utf8(CStr::from_ptr(buf).to_bytes().to_vec()).unwrap();
|
||||
let str = String::from_utf8(CStr::from_ptr(buf as *const _).to_bytes().to_vec()).unwrap();
|
||||
ffi::CRYPTO_free(buf as *mut c_void);
|
||||
str
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
#include <openssl/ssl.h>
|
||||
|
||||
void rust_SSL_clone(SSL *ssl) {
|
||||
CRYPTO_add(&ssl->references, 1, CRYPTO_LOCK_SSL);
|
||||
}
|
||||
|
||||
void rust_SSL_CTX_clone(SSL_CTX *ctx) {
|
||||
CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX);
|
||||
}
|
||||
|
|
@ -88,6 +88,43 @@ pub fn pbkdf2_hmac_sha1(pass: &str, salt: &[u8], iter: usize, keylen: usize) ->
|
|||
}
|
||||
}
|
||||
|
||||
/// Derives a key from a password and salt using the PBKDF2-HMAC-SHA256 algorithm.
|
||||
#[cfg(feature = "pkcs5_pbkdf2_hmac")]
|
||||
pub fn pbkdf2_hmac_sha256(pass: &str, salt: &[u8], iter: usize, keylen: usize) -> Vec<u8> {
|
||||
pbkdf2_hmac_sha(pass, salt, iter, unsafe { ffi::EVP_sha256() }, keylen)
|
||||
}
|
||||
|
||||
/// Derives a key from a password and salt using the PBKDF2-HMAC-SHA512 algorithm.
|
||||
#[cfg(feature = "pkcs5_pbkdf2_hmac")]
|
||||
pub fn pbkdf2_hmac_sha512(pass: &str, salt: &[u8], iter: usize, keylen: usize) -> Vec<u8> {
|
||||
pbkdf2_hmac_sha(pass, salt, iter, unsafe { ffi::EVP_sha512() }, keylen)
|
||||
}
|
||||
|
||||
/// Derives a key from a password and salt using the PBKDF2-HMAC algorithm with a digest function.
|
||||
#[cfg(feature = "pkcs5_pbkdf2_hmac")]
|
||||
fn pbkdf2_hmac_sha(pass: &str, salt: &[u8], iter: usize, digest: *const ffi::EVP_MD, keylen: usize) -> Vec<u8> {
|
||||
unsafe {
|
||||
assert!(iter >= 1);
|
||||
assert!(keylen >= 1);
|
||||
|
||||
let mut out = Vec::with_capacity(keylen);
|
||||
|
||||
ffi::init();
|
||||
|
||||
let r = ffi::PKCS5_PBKDF2_HMAC(
|
||||
pass.as_ptr(), pass.len() as c_int,
|
||||
salt.as_ptr(), salt.len() as c_int,
|
||||
iter as c_int, digest, keylen as c_int,
|
||||
out.as_mut_ptr());
|
||||
|
||||
if r != 1 { panic!(); }
|
||||
|
||||
out.set_len(keylen);
|
||||
|
||||
out
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crypto::hash;
|
||||
|
|
@ -183,6 +220,108 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
// Test vectors from
|
||||
// https://git.lysator.liu.se/nettle/nettle/blob/nettle_3.1.1_release_20150424/testsuite/pbkdf2-test.c
|
||||
#[test]
|
||||
#[cfg(feature = "pkcs5_pbkdf2_hmac")]
|
||||
fn test_pbkdf2_hmac_sha256() {
|
||||
assert_eq!(
|
||||
super::pbkdf2_hmac_sha256(
|
||||
"passwd",
|
||||
"salt".as_bytes(),
|
||||
1,
|
||||
16
|
||||
),
|
||||
vec!(
|
||||
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!(
|
||||
super::pbkdf2_hmac_sha256(
|
||||
"Password",
|
||||
"NaCl".as_bytes(),
|
||||
80000,
|
||||
16
|
||||
),
|
||||
vec!(
|
||||
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
|
||||
// https://git.lysator.liu.se/nettle/nettle/blob/nettle_3.1.1_release_20150424/testsuite/pbkdf2-test.c
|
||||
#[test]
|
||||
#[cfg(feature = "pkcs5_pbkdf2_hmac")]
|
||||
fn test_pbkdf2_hmac_sha512() {
|
||||
assert_eq!(
|
||||
super::pbkdf2_hmac_sha512(
|
||||
"password",
|
||||
"NaCL".as_bytes(),
|
||||
1,
|
||||
64
|
||||
),
|
||||
vec!(
|
||||
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!(
|
||||
super::pbkdf2_hmac_sha512(
|
||||
"pass\0word",
|
||||
"sa\0lt".as_bytes(),
|
||||
1,
|
||||
64
|
||||
),
|
||||
vec!(
|
||||
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
|
||||
)
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
super::pbkdf2_hmac_sha512(
|
||||
"passwordPASSWORDpassword",
|
||||
"salt\0\0\0".as_bytes(),
|
||||
50,
|
||||
64
|
||||
),
|
||||
vec!(
|
||||
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 test_evp_bytes_to_key_pbkdf1_compatible() {
|
||||
let salt = [
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#![doc(html_root_url="https://sfackler.github.io/rust-openssl/doc/v0.7.1")]
|
||||
#![doc(html_root_url="https://sfackler.github.io/rust-openssl/doc/v0.7.2")]
|
||||
|
||||
#[macro_use]
|
||||
extern crate bitflags;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,162 @@
|
|||
use libc::{c_char, c_int, c_long, c_void, strlen};
|
||||
use ffi::{BIO, BIO_METHOD, BIO_CTRL_FLUSH, BIO_TYPE_NONE, BIO_new};
|
||||
use ffi_extras::{BIO_clear_retry_flags, BIO_set_retry_read, BIO_set_retry_write};
|
||||
use std::io;
|
||||
use std::io::prelude::*;
|
||||
use std::mem;
|
||||
use std::slice;
|
||||
use std::ptr;
|
||||
|
||||
use ssl::error::SslError;
|
||||
|
||||
// "rust"
|
||||
const NAME: [c_char; 5] = [114, 117, 115, 116, 0];
|
||||
|
||||
// we use this after removing the stream from the BIO so that we don't have to
|
||||
// worry about freeing the heap allocated BIO_METHOD after freeing the BIO.
|
||||
static DESTROY_METHOD: BIO_METHOD = BIO_METHOD {
|
||||
type_: BIO_TYPE_NONE,
|
||||
name: &NAME[0],
|
||||
bwrite: None,
|
||||
bread: None,
|
||||
bputs: None,
|
||||
bgets: None,
|
||||
ctrl: None,
|
||||
create: None,
|
||||
destroy: Some(destroy),
|
||||
callback_ctrl: None,
|
||||
};
|
||||
|
||||
pub struct StreamState<S> {
|
||||
pub stream: S,
|
||||
pub error: Option<io::Error>,
|
||||
}
|
||||
|
||||
pub fn new<S: Read + Write>(stream: S) -> Result<(*mut BIO, Box<BIO_METHOD>), SslError> {
|
||||
|
||||
let method = Box::new(BIO_METHOD {
|
||||
type_: BIO_TYPE_NONE,
|
||||
name: &NAME[0],
|
||||
bwrite: Some(bwrite::<S>),
|
||||
bread: Some(bread::<S>),
|
||||
bputs: Some(bputs::<S>),
|
||||
bgets: None,
|
||||
ctrl: Some(ctrl::<S>),
|
||||
create: Some(create),
|
||||
destroy: None, // covered in the replacement BIO_METHOD
|
||||
callback_ctrl: None,
|
||||
});
|
||||
|
||||
let state = Box::new(StreamState {
|
||||
stream: stream,
|
||||
error: None,
|
||||
});
|
||||
|
||||
unsafe {
|
||||
let bio = try_ssl_null!(BIO_new(&*method));
|
||||
(*bio).ptr = Box::into_raw(state) as *mut _;
|
||||
(*bio).init = 1;
|
||||
|
||||
return Ok((bio, method));
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn take_error<S>(bio: *mut BIO) -> Option<io::Error> {
|
||||
let state = state::<S>(bio);
|
||||
state.error.take()
|
||||
}
|
||||
|
||||
pub unsafe fn take_stream<S>(bio: *mut BIO) -> S {
|
||||
let state: Box<StreamState<S>> = Box::from_raw((*bio).ptr as *mut _);
|
||||
(*bio).ptr = ptr::null_mut();
|
||||
(*bio).method = &DESTROY_METHOD as *const _ as *mut _;
|
||||
(*bio).init = 0;
|
||||
state.stream
|
||||
}
|
||||
|
||||
pub unsafe fn get_ref<'a, S: 'a>(bio: *mut BIO) -> &'a S {
|
||||
let state: &'a StreamState<S> = mem::transmute((*bio).ptr);
|
||||
&state.stream
|
||||
}
|
||||
|
||||
pub unsafe fn get_mut<'a, S: 'a>(bio: *mut BIO) -> &'a mut S {
|
||||
&mut state(bio).stream
|
||||
}
|
||||
|
||||
unsafe fn state<'a, S: 'a>(bio: *mut BIO) -> &'a mut StreamState<S> {
|
||||
mem::transmute((*bio).ptr)
|
||||
}
|
||||
|
||||
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);
|
||||
let buf = slice::from_raw_parts(buf as *const _, len as usize);
|
||||
match state.stream.write(buf) {
|
||||
Ok(len) => len as c_int,
|
||||
Err(err) => {
|
||||
if err.kind() == io::ErrorKind::WouldBlock {
|
||||
BIO_set_retry_write(bio);
|
||||
}
|
||||
state.error = Some(err);
|
||||
-1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
let buf = slice::from_raw_parts_mut(buf as *mut _, len as usize);
|
||||
match state.stream.read(buf) {
|
||||
Ok(len) => len as c_int,
|
||||
Err(err) => {
|
||||
if err.kind() == io::ErrorKind::WouldBlock {
|
||||
BIO_set_retry_read(bio);
|
||||
}
|
||||
state.error = Some(err);
|
||||
-1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 "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);
|
||||
match state.stream.flush() {
|
||||
Ok(()) => 1,
|
||||
Err(err) => {
|
||||
state.error = Some(err);
|
||||
0
|
||||
}
|
||||
}
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
unsafe extern "C" fn create(bio: *mut BIO) -> c_int {
|
||||
(*bio).init = 0;
|
||||
(*bio).num = 0;
|
||||
(*bio).ptr = ptr::null_mut();
|
||||
(*bio).flags = 0;
|
||||
1
|
||||
}
|
||||
|
||||
unsafe extern "C" fn destroy(bio: *mut BIO) -> c_int {
|
||||
if bio.is_null() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
assert!((*bio).ptr.is_null());
|
||||
1
|
||||
}
|
||||
|
|
@ -3,12 +3,141 @@ pub use self::OpensslError::*;
|
|||
|
||||
use libc::c_ulong;
|
||||
use std::error;
|
||||
use std::error::Error as StdError;
|
||||
use std::fmt;
|
||||
use std::ffi::CStr;
|
||||
use std::io;
|
||||
use std::str;
|
||||
|
||||
use ffi;
|
||||
|
||||
/// An SSL error.
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
/// The SSL session has been closed by the other end
|
||||
ZeroReturn,
|
||||
/// An attempt to read data from the underlying socket returned
|
||||
/// `WouldBlock`. Wait for read readiness and reattempt the operation.
|
||||
WantRead(io::Error),
|
||||
/// An attempt to write data from the underlying socket returned
|
||||
/// `WouldBlock`. Wait for write readiness and reattempt the operation.
|
||||
WantWrite(io::Error),
|
||||
/// The client certificate callback requested to be called again.
|
||||
WantX509Lookup,
|
||||
/// An error reported by the underlying stream.
|
||||
Stream(io::Error),
|
||||
/// An error in the OpenSSL library.
|
||||
Ssl(Vec<OpenSslError>),
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
try!(fmt.write_str(self.description()));
|
||||
match *self {
|
||||
Error::Stream(ref err) => write!(fmt, ": {}", err),
|
||||
Error::WantRead(ref err) => write!(fmt, ": {}", err),
|
||||
Error::WantWrite(ref err) => write!(fmt, ": {}", err),
|
||||
Error::Ssl(ref errs) => {
|
||||
let mut first = true;
|
||||
for err in errs {
|
||||
if first {
|
||||
try!(fmt.write_str(": "));
|
||||
first = false;
|
||||
} else {
|
||||
try!(fmt.write_str(", "));
|
||||
}
|
||||
try!(fmt.write_str(&err.reason()))
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
_ => Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl error::Error for Error {
|
||||
fn description(&self) -> &str {
|
||||
match *self {
|
||||
Error::ZeroReturn => "The SSL session was closed by the other end",
|
||||
Error::WantRead(_) => "A read attempt returned a `WouldBlock` error",
|
||||
Error::WantWrite(_) => "A write attempt returned a `WouldBlock` error",
|
||||
Error::WantX509Lookup => "The client certificate callback requested to be called again",
|
||||
Error::Stream(_) => "The underlying stream reported an error",
|
||||
Error::Ssl(_) => "The OpenSSL library reported an error",
|
||||
}
|
||||
}
|
||||
|
||||
fn cause(&self) -> Option<&error::Error> {
|
||||
match *self {
|
||||
Error::WantRead(ref err) => Some(err),
|
||||
Error::WantWrite(ref err) => Some(err),
|
||||
Error::Stream(ref err) => Some(err),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An error reported from OpenSSL.
|
||||
pub struct OpenSslError(c_ulong);
|
||||
|
||||
impl OpenSslError {
|
||||
/// Returns the contents of the OpenSSL error stack.
|
||||
pub fn get_stack() -> Vec<OpenSslError> {
|
||||
ffi::init();
|
||||
|
||||
let mut errs = vec!();
|
||||
loop {
|
||||
match unsafe { ffi::ERR_get_error() } {
|
||||
0 => break,
|
||||
err => errs.push(OpenSslError(err))
|
||||
}
|
||||
}
|
||||
errs
|
||||
}
|
||||
|
||||
/// Returns the raw OpenSSL error code for this error.
|
||||
pub fn error_code(&self) -> c_ulong {
|
||||
self.0
|
||||
}
|
||||
|
||||
/// Returns the name of the library reporting the error.
|
||||
pub fn library(&self) -> &'static str {
|
||||
get_lib(self.0)
|
||||
}
|
||||
|
||||
/// Returns the name of the function reporting the error.
|
||||
pub fn function(&self) -> &'static str {
|
||||
get_func(self.0)
|
||||
}
|
||||
|
||||
/// Returns the reason for the error.
|
||||
pub fn reason(&self) -> &'static str {
|
||||
get_reason(self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for OpenSslError {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt.debug_struct("OpenSslError")
|
||||
.field("library", &self.library())
|
||||
.field("function", &self.function())
|
||||
.field("reason", &self.reason())
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for OpenSslError {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt.write_str(&self.reason())
|
||||
}
|
||||
}
|
||||
|
||||
impl error::Error for OpenSslError {
|
||||
fn description(&self) -> &str {
|
||||
"An OpenSSL error"
|
||||
}
|
||||
}
|
||||
|
||||
/// An SSL error
|
||||
#[derive(Debug)]
|
||||
pub enum SslError {
|
||||
|
|
@ -115,24 +244,38 @@ pub enum OpensslError {
|
|||
}
|
||||
}
|
||||
|
||||
fn get_lib(err: c_ulong) -> String {
|
||||
unsafe {
|
||||
let bytes = CStr::from_ptr(ffi::ERR_lib_error_string(err)).to_bytes().to_vec();
|
||||
String::from_utf8(bytes).unwrap()
|
||||
impl OpensslError {
|
||||
pub fn from_error_code(err: c_ulong) -> OpensslError {
|
||||
ffi::init();
|
||||
UnknownError {
|
||||
library: get_lib(err).to_owned(),
|
||||
function: get_func(err).to_owned(),
|
||||
reason: get_reason(err).to_owned()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_func(err: c_ulong) -> String {
|
||||
fn get_lib(err: c_ulong) -> &'static str {
|
||||
unsafe {
|
||||
let bytes = CStr::from_ptr(ffi::ERR_func_error_string(err)).to_bytes().to_vec();
|
||||
String::from_utf8(bytes).unwrap()
|
||||
let cstr = ffi::ERR_lib_error_string(err);
|
||||
let bytes = CStr::from_ptr(cstr as *const _).to_bytes();
|
||||
str::from_utf8(bytes).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
fn get_reason(err: c_ulong) -> String {
|
||||
fn get_func(err: c_ulong) -> &'static str {
|
||||
unsafe {
|
||||
let bytes = CStr::from_ptr(ffi::ERR_reason_error_string(err)).to_bytes().to_vec();
|
||||
String::from_utf8(bytes).unwrap()
|
||||
let cstr = ffi::ERR_func_error_string(err);
|
||||
let bytes = CStr::from_ptr(cstr as *const _).to_bytes();
|
||||
str::from_utf8(bytes).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
fn get_reason(err: c_ulong) -> &'static str {
|
||||
unsafe {
|
||||
let cstr = ffi::ERR_reason_error_string(err);
|
||||
let bytes = CStr::from_ptr(cstr as *const _).to_bytes();
|
||||
str::from_utf8(bytes).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -144,7 +287,7 @@ impl SslError {
|
|||
loop {
|
||||
match unsafe { ffi::ERR_get_error() } {
|
||||
0 => break,
|
||||
err => errs.push(SslError::from_error_code(err))
|
||||
err => errs.push(OpensslError::from_error_code(err))
|
||||
}
|
||||
}
|
||||
OpenSslErrors(errs)
|
||||
|
|
@ -152,16 +295,7 @@ impl SslError {
|
|||
|
||||
/// Creates an `SslError` from the raw numeric error code.
|
||||
pub fn from_error(err: c_ulong) -> SslError {
|
||||
OpenSslErrors(vec![SslError::from_error_code(err)])
|
||||
}
|
||||
|
||||
fn from_error_code(err: c_ulong) -> OpensslError {
|
||||
ffi::init();
|
||||
UnknownError {
|
||||
library: get_lib(err),
|
||||
function: get_func(err),
|
||||
reason: get_reason(err)
|
||||
}
|
||||
OpenSslErrors(vec![OpensslError::from_error_code(err)])
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -50,7 +50,7 @@ impl Deref for SslString {
|
|||
impl SslString {
|
||||
unsafe fn new(buf: *const c_char) -> SslString {
|
||||
SslString {
|
||||
s: str::from_utf8(CStr::from_ptr(buf).to_bytes()).unwrap()
|
||||
s: str::from_utf8(CStr::from_ptr(buf as *const _).to_bytes()).unwrap()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -275,8 +275,8 @@ impl X509Generator {
|
|||
lift_ssl!(unsafe {
|
||||
let key = CString::new(key.as_bytes()).unwrap();
|
||||
let value = CString::new(value.as_bytes()).unwrap();
|
||||
ffi::X509_NAME_add_entry_by_txt(name, key.as_ptr(), ffi::MBSTRING_UTF8,
|
||||
value.as_ptr(), value_len, -1, 0)
|
||||
ffi::X509_NAME_add_entry_by_txt(name, key.as_ptr() as *const _, ffi::MBSTRING_UTF8,
|
||||
value.as_ptr() as *const _, value_len, -1, 0)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ set -e
|
|||
|
||||
mkdir /tmp/openssl
|
||||
cd /tmp/openssl
|
||||
curl https://openssl.org/source/openssl-1.0.2d.tar.gz | tar --strip-components=1 -xzf -
|
||||
curl https://openssl.org/source/openssl-1.0.2e.tar.gz | tar --strip-components=1 -xzf -
|
||||
./config --prefix=$HOME/openssl shared
|
||||
make
|
||||
make install
|
||||
|
|
|
|||
Loading…
Reference in New Issue