Merge branch 'release-v0.7.2' into release
This commit is contained in:
commit
cf075d8e6b
|
|
@ -9,7 +9,7 @@ os:
|
||||||
- linux
|
- linux
|
||||||
env:
|
env:
|
||||||
global:
|
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:
|
before_install:
|
||||||
- (test $TRAVIS_OS_NAME == "osx" || ./openssl/test/build.sh)
|
- (test $TRAVIS_OS_NAME == "osx" || ./openssl/test/build.sh)
|
||||||
script:
|
script:
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
[](https://travis-ci.org/sfackler/rust-openssl)
|
[](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
|
## Building
|
||||||
|
|
||||||
|
|
@ -25,7 +25,9 @@ sudo pacman -S openssl
|
||||||
|
|
||||||
OpenSSL 0.9.8 is preinstalled on OSX. Some features are only available when
|
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
|
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
|
### Windows
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,10 @@ environment:
|
||||||
- TARGET: x86_64-pc-windows-msvc
|
- TARGET: x86_64-pc-windows-msvc
|
||||||
BITS: 64
|
BITS: 64
|
||||||
install:
|
install:
|
||||||
- ps: Start-FileDownload "http://slproweb.com/download/Win${env:BITS}OpenSSL-1_0_2d.exe"
|
- ps: Start-FileDownload "http://slproweb.com/download/Win${env:BITS}OpenSSL-1_0_2e.exe"
|
||||||
- Win%BITS%OpenSSL-1_0_2d.exe /SILENT /VERYSILENT /SP- /DIR="C:\OpenSSL"
|
- Win%BITS%OpenSSL-1_0_2e.exe /SILENT /VERYSILENT /SP- /DIR="C:\OpenSSL"
|
||||||
- ps: Start-FileDownload "https://static.rust-lang.org/dist/rust-nightly-${env:TARGET}.exe"
|
- ps: Start-FileDownload "https://static.rust-lang.org/dist/rust-1.5.0-${env:TARGET}.exe"
|
||||||
- rust-nightly-%TARGET%.exe /VERYSILENT /NORESTART /DIR="C:\Program Files (x86)\Rust"
|
- 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:\Program Files (x86)\Rust\bin
|
||||||
- SET PATH=%PATH%;C:\MinGW\bin
|
- SET PATH=%PATH%;C:\MinGW\bin
|
||||||
- rustc -V
|
- rustc -V
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,11 @@
|
||||||
[package]
|
[package]
|
||||||
name = "openssl-sys-extras"
|
name = "openssl-sys-extras"
|
||||||
version = "0.7.1"
|
version = "0.7.2"
|
||||||
authors = ["Steven Fackler <sfackler@gmail.com>"]
|
authors = ["Steven Fackler <sfackler@gmail.com>"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "Extra FFI bindings to OpenSSL that require a C shim"
|
description = "Extra FFI bindings to OpenSSL that require a C shim"
|
||||||
repository = "https://github.com/sfackler/rust-openssl"
|
repository = "https://github.com/sfackler/rust-openssl"
|
||||||
documentation = "https://sfackler.github.io/rust-openssl/doc/v0.7.1/openssl_sys_extras"
|
documentation = "https://sfackler.github.io/rust-openssl/doc/v0.7.2/openssl_sys_extras"
|
||||||
|
|
||||||
links = "openssl_shim"
|
|
||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
#![allow(non_upper_case_globals, non_snake_case)]
|
#![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 openssl_sys;
|
||||||
extern crate libc;
|
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};
|
use openssl_sys::{HMAC_CTX, EVP_MD, ENGINE, SSL_CTX, BIO, X509, stack_st_X509_EXTENSION, SSL, DH};
|
||||||
|
|
||||||
macro_rules! import_options {
|
macro_rules! import_options {
|
||||||
|
|
@ -49,6 +49,14 @@ extern {
|
||||||
pub fn BIO_set_nbio(b: *mut BIO, enabled: c_long) -> c_long;
|
pub fn BIO_set_nbio(b: *mut BIO, enabled: c_long) -> c_long;
|
||||||
#[link_name = "BIO_set_mem_eof_return_shim"]
|
#[link_name = "BIO_set_mem_eof_return_shim"]
|
||||||
pub fn BIO_set_mem_eof_return(b: *mut BIO, v: c_int);
|
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_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_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;
|
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;
|
pub fn SSL_CTX_set_tmp_dh(s: *mut SSL, dh: *const DH) -> c_long;
|
||||||
#[link_name = "X509_get_extensions_shim"]
|
#[link_name = "X509_get_extensions_shim"]
|
||||||
pub fn X509_get_extensions(x: *mut X509) -> *mut stack_st_X509_EXTENSION;
|
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);
|
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) {
|
long SSL_CTX_set_options_shim(SSL_CTX *ctx, long options) {
|
||||||
return SSL_CTX_set_options(ctx, 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);
|
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
|
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||||
int SSL_CTX_set_ecdh_auto_shim(SSL_CTX *ctx, int onoff) {
|
int SSL_CTX_set_ecdh_auto_shim(SSL_CTX *ctx, int onoff) {
|
||||||
return SSL_CTX_set_ecdh_auto(ctx, onoff);
|
return SSL_CTX_set_ecdh_auto(ctx, onoff);
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,12 @@
|
||||||
[package]
|
[package]
|
||||||
name = "openssl-sys"
|
name = "openssl-sys"
|
||||||
version = "0.7.1"
|
version = "0.7.2"
|
||||||
authors = ["Alex Crichton <alex@alexcrichton.com>",
|
authors = ["Alex Crichton <alex@alexcrichton.com>",
|
||||||
"Steven Fackler <sfackler@gmail.com>"]
|
"Steven Fackler <sfackler@gmail.com>"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "FFI bindings to OpenSSL"
|
description = "FFI bindings to OpenSSL"
|
||||||
repository = "https://github.com/sfackler/rust-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"
|
links = "openssl"
|
||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
|
|
||||||
|
|
@ -23,6 +22,7 @@ aes_ctr = []
|
||||||
npn = []
|
npn = []
|
||||||
alpn = []
|
alpn = []
|
||||||
rfc5114 = []
|
rfc5114 = []
|
||||||
|
pkcs5_pbkdf2_hmac = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#![allow(non_camel_case_types, non_upper_case_globals, non_snake_case)]
|
#![allow(non_camel_case_types, non_upper_case_globals, non_snake_case)]
|
||||||
#![allow(dead_code)]
|
#![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;
|
extern crate libc;
|
||||||
|
|
||||||
|
|
@ -15,11 +15,8 @@ use std::sync::{Once, ONCE_INIT};
|
||||||
pub type ASN1_INTEGER = c_void;
|
pub type ASN1_INTEGER = c_void;
|
||||||
pub type ASN1_STRING = c_void;
|
pub type ASN1_STRING = c_void;
|
||||||
pub type ASN1_TIME = 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 BN_CTX = c_void;
|
||||||
pub type COMP_METHOD = c_void;
|
pub type COMP_METHOD = c_void;
|
||||||
pub type CRYPTO_EX_DATA = c_void;
|
|
||||||
pub type DH = c_void;
|
pub type DH = c_void;
|
||||||
pub type ENGINE = c_void;
|
pub type ENGINE = c_void;
|
||||||
pub type EVP_CIPHER = 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_REQ = c_void;
|
||||||
pub type X509_STORE_CTX = c_void;
|
pub type X509_STORE_CTX = c_void;
|
||||||
pub type stack_st_X509_EXTENSION = 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)]
|
#[repr(C)]
|
||||||
pub struct EVP_MD_CTX {
|
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)
|
rwflag: c_int, user_data: *mut c_void)
|
||||||
-> c_int;
|
-> c_int;
|
||||||
|
|
||||||
|
pub const BIO_TYPE_NONE: c_int = 0;
|
||||||
|
|
||||||
pub const BIO_CTRL_EOF: c_int = 2;
|
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 BIO_C_SET_BUF_MEM_EOF_RETURN: c_int = 130;
|
||||||
|
|
||||||
pub const CRYPTO_LOCK: c_int = 1;
|
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_OPTIONS: c_int = 32;
|
||||||
pub const SSL_CTRL_CLEAR_OPTIONS: c_int = 77;
|
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_SET_TLSEXT_HOSTNAME: c_int = 55;
|
||||||
pub const SSL_CTRL_EXTRA_CHAIN_CERT: c_int = 14;
|
pub const SSL_CTRL_EXTRA_CHAIN_CERT: c_int = 14;
|
||||||
|
|
||||||
|
|
@ -478,7 +539,11 @@ extern "C" {
|
||||||
salt: *const u8, saltlen: c_int,
|
salt: *const u8, saltlen: c_int,
|
||||||
iter: c_int, keylen: c_int,
|
iter: c_int, keylen: c_int,
|
||||||
out: *mut u8) -> 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;
|
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_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_ex_data_X509_STORE_CTX_idx() -> c_int;
|
||||||
pub fn SSL_get_SSL_CTX(ssl: *mut SSL) -> *mut SSL_CTX;
|
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_current_compression(ssl: *mut SSL) -> *const COMP_METHOD;
|
||||||
pub fn SSL_get_peer_certificate(ssl: *mut SSL) -> *mut X509;
|
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_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(ssl: *mut SSL) -> *const c_char;
|
||||||
pub fn SSL_state_string_long(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_COMP_get_name(comp: *const COMP_METHOD) -> *const c_char;
|
||||||
|
|
||||||
pub fn SSL_CTX_new(method: *const SSL_METHOD) -> *mut SSL_CTX;
|
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_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")]
|
#[cfg(feature = "npn")]
|
||||||
pub fn SSL_CTX_set_next_protos_advertised_cb(ssl: *mut SSL_CTX,
|
pub fn SSL_CTX_set_next_protos_advertised_cb(ssl: *mut SSL_CTX,
|
||||||
cb: extern "C" fn(ssl: *mut SSL,
|
cb: extern "C" fn(ssl: *mut SSL,
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,14 @@
|
||||||
[package]
|
[package]
|
||||||
name = "openssl"
|
name = "openssl"
|
||||||
version = "0.7.1"
|
version = "0.7.2"
|
||||||
authors = ["Steven Fackler <sfackler@gmail.com>"]
|
authors = ["Steven Fackler <sfackler@gmail.com>"]
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
description = "OpenSSL bindings"
|
description = "OpenSSL bindings"
|
||||||
repository = "https://github.com/sfackler/rust-openssl"
|
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"
|
readme = "../README.md"
|
||||||
keywords = ["crypto", "tls", "ssl", "dtls"]
|
keywords = ["crypto", "tls", "ssl", "dtls"]
|
||||||
|
build = "build.rs"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
tlsv1_2 = ["openssl-sys/tlsv1_2"]
|
tlsv1_2 = ["openssl-sys/tlsv1_2"]
|
||||||
|
|
@ -22,6 +23,7 @@ npn = ["openssl-sys/npn"]
|
||||||
alpn = ["openssl-sys/alpn"]
|
alpn = ["openssl-sys/alpn"]
|
||||||
rfc5114 = ["openssl-sys/rfc5114"]
|
rfc5114 = ["openssl-sys/rfc5114"]
|
||||||
ecdh_auto = ["openssl-sys-extras/ecdh_auto"]
|
ecdh_auto = ["openssl-sys-extras/ecdh_auto"]
|
||||||
|
pkcs5_pbkdf2_hmac = ["openssl-sys/pkcs5_pbkdf2_hmac"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bitflags = ">= 0.2, < 0.4"
|
bitflags = ">= 0.2, < 0.4"
|
||||||
|
|
@ -30,6 +32,9 @@ libc = "0.2"
|
||||||
openssl-sys = { version = "0.7.1", path = "../openssl-sys" }
|
openssl-sys = { version = "0.7.1", path = "../openssl-sys" }
|
||||||
openssl-sys-extras = { version = "0.7.1", path = "../openssl-sys-extras" }
|
openssl-sys-extras = { version = "0.7.1", path = "../openssl-sys-extras" }
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
gcc = "0.3"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
rustc-serialize = "0.3"
|
rustc-serialize = "0.3"
|
||||||
net2 = "0.2.16"
|
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> {
|
pub fn from_dec_str(s: &str) -> Result<BigNum, SslError> {
|
||||||
BigNum::new().and_then(|v| unsafe {
|
BigNum::new().and_then(|v| unsafe {
|
||||||
let c_str = CString::new(s.as_bytes()).unwrap();
|
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)
|
Ok(v)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -97,7 +97,7 @@ impl BigNum {
|
||||||
pub fn from_hex_str(s: &str) -> Result<BigNum, SslError> {
|
pub fn from_hex_str(s: &str) -> Result<BigNum, SslError> {
|
||||||
BigNum::new().and_then(|v| unsafe {
|
BigNum::new().and_then(|v| unsafe {
|
||||||
let c_str = CString::new(s.as_bytes()).unwrap();
|
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)
|
Ok(v)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -421,7 +421,7 @@ impl BigNum {
|
||||||
unsafe {
|
unsafe {
|
||||||
let buf = ffi::BN_bn2dec(self.raw());
|
let buf = ffi::BN_bn2dec(self.raw());
|
||||||
assert!(!buf.is_null());
|
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);
|
ffi::CRYPTO_free(buf as *mut c_void);
|
||||||
str
|
str
|
||||||
}
|
}
|
||||||
|
|
@ -431,7 +431,7 @@ impl BigNum {
|
||||||
unsafe {
|
unsafe {
|
||||||
let buf = ffi::BN_bn2hex(self.raw());
|
let buf = ffi::BN_bn2hex(self.raw());
|
||||||
assert!(!buf.is_null());
|
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);
|
ffi::CRYPTO_free(buf as *mut c_void);
|
||||||
str
|
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)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crypto::hash;
|
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]
|
#[test]
|
||||||
fn test_evp_bytes_to_key_pbkdf1_compatible() {
|
fn test_evp_bytes_to_key_pbkdf1_compatible() {
|
||||||
let salt = [
|
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]
|
#[macro_use]
|
||||||
extern crate bitflags;
|
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 libc::c_ulong;
|
||||||
use std::error;
|
use std::error;
|
||||||
|
use std::error::Error as StdError;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
use std::str;
|
||||||
|
|
||||||
use ffi;
|
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
|
/// An SSL error
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum SslError {
|
pub enum SslError {
|
||||||
|
|
@ -115,24 +244,38 @@ pub enum OpensslError {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_lib(err: c_ulong) -> String {
|
impl OpensslError {
|
||||||
unsafe {
|
pub fn from_error_code(err: c_ulong) -> OpensslError {
|
||||||
let bytes = CStr::from_ptr(ffi::ERR_lib_error_string(err)).to_bytes().to_vec();
|
ffi::init();
|
||||||
String::from_utf8(bytes).unwrap()
|
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 {
|
unsafe {
|
||||||
let bytes = CStr::from_ptr(ffi::ERR_func_error_string(err)).to_bytes().to_vec();
|
let cstr = ffi::ERR_lib_error_string(err);
|
||||||
String::from_utf8(bytes).unwrap()
|
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 {
|
unsafe {
|
||||||
let bytes = CStr::from_ptr(ffi::ERR_reason_error_string(err)).to_bytes().to_vec();
|
let cstr = ffi::ERR_func_error_string(err);
|
||||||
String::from_utf8(bytes).unwrap()
|
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 {
|
loop {
|
||||||
match unsafe { ffi::ERR_get_error() } {
|
match unsafe { ffi::ERR_get_error() } {
|
||||||
0 => break,
|
0 => break,
|
||||||
err => errs.push(SslError::from_error_code(err))
|
err => errs.push(OpensslError::from_error_code(err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
OpenSslErrors(errs)
|
OpenSslErrors(errs)
|
||||||
|
|
@ -152,16 +295,7 @@ impl SslError {
|
||||||
|
|
||||||
/// Creates an `SslError` from the raw numeric error code.
|
/// Creates an `SslError` from the raw numeric error code.
|
||||||
pub fn from_error(err: c_ulong) -> SslError {
|
pub fn from_error(err: c_ulong) -> SslError {
|
||||||
OpenSslErrors(vec![SslError::from_error_code(err)])
|
OpenSslErrors(vec![OpensslError::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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -50,7 +50,7 @@ impl Deref for SslString {
|
||||||
impl SslString {
|
impl SslString {
|
||||||
unsafe fn new(buf: *const c_char) -> SslString {
|
unsafe fn new(buf: *const c_char) -> SslString {
|
||||||
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 {
|
lift_ssl!(unsafe {
|
||||||
let key = CString::new(key.as_bytes()).unwrap();
|
let key = CString::new(key.as_bytes()).unwrap();
|
||||||
let value = CString::new(value.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,
|
ffi::X509_NAME_add_entry_by_txt(name, key.as_ptr() as *const _, ffi::MBSTRING_UTF8,
|
||||||
value.as_ptr(), value_len, -1, 0)
|
value.as_ptr() as *const _, value_len, -1, 0)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ set -e
|
||||||
|
|
||||||
mkdir /tmp/openssl
|
mkdir /tmp/openssl
|
||||||
cd /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
|
./config --prefix=$HOME/openssl shared
|
||||||
make
|
make
|
||||||
make install
|
make install
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue